![]() |
LINE Solver (C++)
Templated C++ port of the LINE queueing solver
|
The SolverSSA entry surface: a port of @@SolverSSA/runAnalyzer.m's method whitelist, of solver_ssa_analyzer.m's eligibility gate (isNrmEligible and the per-feature *NrmOK predicates) and of solver_ssa_analyzer_nrm.m's own scheduling validation. More...
#include <string>#include <vector>#include "line/api/sn/sn_pn_firing_rates.h"#include "line/lang/qn/network_struct.h"#include "line/solvers/cache_metrics.h"#include "line/solvers/ssa/solver_ssa_nrm.h"#include "line/solvers/ssa/solver_ssa_nrm_space.h"#include "line/solvers/ssa/solver_ssa_nrm_spn.h"#include "line/solvers/ssa/solver_ssa_parallel.h"#include "line/solvers/ssa/solver_ssa_serial.h"#include "line/solvers/ssa/ssa_types.h"#include "line/util/error.h"Go to the source code of this file.
Namespaces | |
| namespace | line |
| Conservation laws of a layered queueing network, enumerated from its structure. | |
| namespace | line::ssa |
Functions | |
| std::vector< std::string > | line::ssa::list_valid_methods () |
| Port of SolverSSA.listValidMethods. | |
| template<class T> | |
| SsaSolution | line::ssa::solver_ssa_nrm_analyzer (const qn::NetworkStruct< T > &sn, const SsaOptions &opt, std::vector< SsaCacheRatio > *cache=nullptr) |
| solver_ssa_analyzer_nrm.m: run the NRM and return the metric table. | |
| template<class T> | |
| SsaSolution | line::ssa::solver_ssa_engine (const qn::NetworkStruct< T > &sn, const SsaOptions &opt, std::vector< SsaCacheRatio > *cache) |
| solver_ssa_analyzer.m: choose the method. | |
| template<class T> | |
| SsaSolution | line::ssa::solver_ssa (const qn::NetworkStruct< T > &sn, const SsaOptions &opt, std::vector< SsaCacheRatio > *cache=nullptr) |
| @@SolverSSA/runAnalyzer itself: the engine the method selects, then the result assembly the reference does before it hands the table to a caller. | |
| template<class T> | |
| solvers::CacheMetrics< T > | line::ssa::cache_metrics_of_ssa (const qn::NetworkStruct< T > &sn, const std::vector< SsaCacheRatio > &cache) |
| CacheMetrics from the serial engine's cache write-back. | |
| template<class T> | |
| qn::NetworkStruct< T > | line::ssa::sn_with_ssa_cache_split (const qn::NetworkStruct< T > &base, const std::vector< SsaCacheRatio > &cache) |
| The struct with the cache split the SIMULATION MEASURED, visits rebuilt. | |
The SolverSSA entry surface: a port of @@SolverSSA/runAnalyzer.m's method whitelist, of solver_ssa_analyzer.m's eligibility gate (isNrmEligible and the per-feature *NrmOK predicates) and of solver_ssa_analyzer_nrm.m's own scheduling validation.
EVERY METHOD THE REFERENCE OFFERS IS REACHED FROM HERE. SolverSSA.m line 55 lists default, ssa, serial, para/parallel and nrm; the JAR's SolverSSA.listValidMethods and native Python's list the same set. All five resolve to one of the three ported engines: the NRM of solver_ssa_nrm.h, the event-driven engine of solver_ssa_serial.h, and the replica mean of solver_ssa_parallel.h. para/parallel prefers the NRM whenever the model is eligible and replicates the serial engine otherwise, exactly as the reference does; ssa is the reference's alias for serial, NOT for the NRM; default is the reference's ladder – the NRM when eligible, the serial engine otherwise – as solver_ssa sets out below. solver_ssa returns the metric table alone, so a caller who needs the sample path, the per-replica tables or their standard errors calls the engine's own entry.
WITHIN nrm THERE ARE TWO ENGINES, and both are reached from here. The reference picks between them on options.config.state_space_gen (solver_ssa_analyzer_nrm.m lines 52-68): none and default take the plain engine of solver_ssa_nrm.m, which integrates the metrics along the sample path, and any other value takes the tabulating engine of solver_ssa_nrm_space.m, which records the distinct states visited and forms the means as pi * A. SsaOptions::state_space_gen is that switch, and the eligibility gate below runs before it, exactly as the reference's does: it is the NRM's gate, not one engine's. The space engine then applies its OWN further refusals (an open model, a phase-type service, a space above the cap), each by name, in NrmSpaceEngine::check.
WHY THE GATE IS SO LONG, AND WHAT IT IS FOR. It is isNrmEligible (solver_ssa_analyzer.m lines 365-386) and it answers ONE question: can the NRM run this model? Under method='nrm' a no is a refusal BY NAME, because a caller who spelled out the estimator asked for that estimator; under default and parallel the same no is a fallback to the serial engine, as the reference's is. The two share a body (raise), so they cannot drift.
WHAT THE GATE MEANS SINCE THE FALLBACK WAS RESTORED. It is the NRM's reach and NOT SolverSSA's: everything it rejects, the serial engine runs (a Fork, a BLOCKING region rule, global dependence), so a rejection under default costs the caller the NRM's SPEED and not the answer. Under method='nrm' it is still a refusal by name, because an estimator that was asked for by name must be the one that runs. What the NRM lacks falls in two groups:
NOT REPRESENTABLE the struct has no field at all, so a model using the feature cannot be built (balking, reneging patience, SelfLoopingClass – JobClassType is OPEN or CLOSED only). WRROBIN / JSQ / SQ / RL routing belongs here too by a different route: the enumerators exist, but NetworkStruct::refresh_routing refuses those state-dependent strategies when the struct is built, so the gate's own test is reached only by a caller who filled routing by hand. RROBIN is the exception: the refresh now EXPANDS it uniformly, for QNA/MNA, which recover the determinism from the split degree. An RROBIN model therefore reaches this gate for real, and the refusal below is what keeps the NRM from simulating it as random routing. REFUSED IN EVERY CODEBASE'S NRM Fork/Join, the blocking region rules BAS / BBS / RSRD, and global (Whittle) dependence; the reference's isNrmEligible excludes the same set. Retrial orbits (retrialparam) and G-network signals (issignal and friends) are refused downstream, by the engines that would have to simulate them.
The sub-engines that have LEFT the refusal list, all in solver_ssa_nrm.h unless named: the *PRIO shares on 2026-08-15; the stochastic Petri net path on 2026-09-13 (solver_ssa_nrm_spn.h, which still refuses the four firing laws spn_nrm_supported names); and on 2026-09-24 class- and joint-dependent scaling (cdfac), finite capacity regions under DROP and WAITQ (fcr_outcome / fcr_release_cascade), PAS / OI (pas_rate / pas_depart), POLLING (PollCtrl and one switchover reaction per station) and the Cache (cache_fire, drawing each READ from after_event_cache). The tabulating engine of solver_ssa_nrm_space.h does not carry those five and refuses them itself, by name.
Nothing falls through silently: a model with a construct the reaction table does not model would run to completion and return numbers that are simply not the model's, which is why the gate stays even where the serial engine can answer.
Definition in file ssa_dispatch.h.