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

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 dependency graph for ssa_dispatch.h:

Go to the source code of this file.

Namespaces

namespace  line
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)
 solver_ssa_analyzer_nrm.m: run the NRM and return the metric table.
template<class T>
SsaSolution line::ssa::solver_ssa (const qn::NetworkStruct< T > &sn, const SsaOptions &opt, std::vector< SsaCacheRatio > *cache=nullptr)
 solver_ssa_analyzer.m: choose the method.
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.

Detailed Description

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: almost everything it rejects, the serial engine now runs (a Cache access, an SPN firing, a Fork, a finite capacity region under either rule, PAS / OI, POLLING, the priority shares, class-dependent scaling), 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. The three-way split below therefore classifies what the NRM lacks, not what SolverSSA lacks:

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. REPRESENTABLE, NOT PORTED IN THE NRM the struct carries the parameters and the C++ NRM sub-engine is not written (Cache access with its replacement policies and retrieval system, PAS / OI pass-and-swap, POLLING with its switchover controller, the stochastic Petri net path, Fork/Join, finite capacity regions). The *PRIO scheduling family LEFT this list on 2026-08-15: psprioshare, dpsprioshare and gpsprioshare are ported, so the NRM runs those stations itself. EVERY ONE OF THESE IS ANSWERED BY THE SERIAL ENGINE, which is what makes the refusals below a routing decision rather than a capability boundary. Retrial orbits (retrialparam) and G-network signals (issignal and friends) are representable too; they are refused downstream, by the engines that would have to simulate them, not by this gate. REPRESENTABLE, NOT MEANINGFUL class-dependent scaling. The NRM builds its reaction rates without ever evaluating the handle, so the sample path would run at the UNSCALED rates while the utilization column, normalized by the declared peak (sn.cdscalingpeak), still looked consistent. The serial engine evaluates it and answers the model.

Nothing falls through silently: a cache model simulated as an ordinary queueing network returns numbers, they are simply not the model's. That is why the gate stays even where the serial engine can answer – the NRM's reaction table would run such a model to completion and report it.

Definition in file ssa_dispatch.h.