LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Loading...
Searching...
No Matches
ctmc_memory_gate.h File Reference

Host-aware memory pre-gate for SolverCTMC. More...

#include <chrono>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <fstream>
#include <mutex>
#include <sstream>
#include <string>
#include <thread>
#include <vector>
#include "json.hpp"
#include "line/util/error.h"
Include dependency graph for ctmc_memory_gate.h:

Go to the source code of this file.

Classes

struct  line::mc::CtmcGateResult
 The gate verdict, plus the message the caller reports either way. More...
struct  line::mc::CtmcCalibration
 The per-host power-law fit, the reference's calib struct. More...

Namespaces

namespace  line
 Conservation laws of a layered queueing network, enumerated from its structure.
namespace  line::mc
namespace  line::mc::gate_detail

Functions

double line::mc::ctmc_available_memory_bytes ()
 Available physical memory in bytes.
std::string line::mc::gate_detail::machine_signature ()
 The reference's ctmc_machine_signature: arch | cores | platform.
std::string line::mc::gate_detail::cache_file ()
 The reference's cache file, fullfile(tempdir, 'line_ctmc_calib_<lang>.json').
void line::mc::gate_detail::profile_point (int g, double bytes_per_nz, std::size_t &n, double &bytes, double &secs)
 The reference's ctmc_profile_point: sparse LU of the (g^2 - 1)-state lattice generator, returning n, the fill-in bytes and the elapsed seconds.
bool line::mc::gate_detail::fit_power_law (double x1, double y1, double x2, double y2, double &alpha, double &beta)
 The reference's ctmc_fit_power_law; false on a degenerate pair.
double line::mc::gate_detail::now_posix ()
const CtmcCalibration & line::mc::ctmc_get_calibration (bool verbose=false)
 The reference's ctmc_get_calibration: the cached per-host fit, profiled once when the cache is missing or belongs to another machine, and the fallback coefficients when the profile fails.
CtmcGateResult line::mc::ctmc_memory_gate (double log_nstates, bool force=false, double safety_fraction=CTMC_DEFAULT_SAFETY_FRACTION, bool verbose=false)
 Decide whether a state space of log-size log_nstates can be solved here.

Variables

constexpr double line::mc::CTMC_BYTES_PER_NZ = 16.0
 8 bytes of value plus 8 amortized for the index, per stored nonzero.
constexpr double line::mc::CTMC_DEFAULT_SAFETY_FRACTION = 0.6
 Fraction of available memory the solver may target.
constexpr double line::mc::CTMC_FALLBACK_ALPHA = CTMC_BYTES_PER_NZ * 8.0
 Fallback power-law coefficients, identical to MATLAB and Python.
constexpr double line::mc::CTMC_FALLBACK_BETA = 1.3
constexpr double line::mc::CTMC_FALLBACK_AVAIL_BYTES = 1.0 * 1024.0 * 1024.0 * 1024.0
 Conservative available-memory default when the host probe fails.
constexpr int line::mc::CTMC_CALIB_G1 = 40
 The two lattice sides the reference profiles (G1, G2 of ctmc_get_calibration).
constexpr int line::mc::CTMC_CALIB_G2 = 80

Detailed Description

Host-aware memory pre-gate for SolverCTMC.

Port of matlab/src/api/mc/ctmc_memory_gate.m, mirrored by the JAR (MemoryGuard.gate) and native Python (ctmc_memory_gate).

THE POLICY IS REFUSAL, NOT A WARNING. When the predicted peak exceeds the safe budget the solve is REFUSED with an error naming the two numbers, and only an explicit force downgrades that to a warning. A warning the caller can walk past is the wrong contract here: the failure mode it precedes is the OOM killer taking the whole process, which produces no diagnostic at all and, observed on 2026-08-01, took down five sessions and the terminal hosting them. Refusing costs the caller a re-run with another solver; not refusing costs it everything running on the machine.

MDD IS NEVER GATED. It is served by its own analyzer and returns before any explicit-generator path, so the gate is not on its route. That exemption is load-bearing rather than incidental: mdd holds the reachable set in a decision diagram whose size is governed by the diagram's compression, not by the state count, so it routinely solves models this estimator scores at exp(200). Gating on explicit size would clamp exactly the method that exists to beat it. Keep any new non-explicit method on the same side of the gate.

The predictor is the power law of the reference, bytes = alpha * N^beta, evaluated in log space. As in the reference, alpha and beta are CALIBRATED once per host (ctmc_get_calibration): the sparse LU of two lattice generators (40x40 and 80x80) is profiled for its fill-in bytes and its time, a power law is fitted through the two points, and the fit is cached in a JSON file in the temporary directory keyed by a machine signature. When the profile cannot run the reference's FALLBACK coefficients (alpha = 128, beta = 1.3) are used instead, which is the same branch the reference takes then. The factorization here is a banded sparse LU in natural order, which is deterministic across hosts; only the timing coefficients depend on the machine, and the gate does not read those.

Definition in file ctmc_memory_gate.h.