72 const std::string& jobclass)
const {
73 for (std::size_t i = 0; i <
Station.size(); ++i) {
75 if (col ==
"QLen")
return QLen[i];
76 if (col ==
"Util")
return Util[i];
77 if (col ==
"RespT")
return RespT[i];
78 if (col ==
"ResidT")
return ResidT[i];
79 if (col ==
"ArvR")
return ArvR[i];
80 if (col ==
"Tput")
return Tput[i];
81 const std::vector<double>& ci =
column(col);
82 return i < ci.size() ? ci[i] : std::numeric_limits<double>::quiet_NaN();
84 return std::numeric_limits<double>::quiet_NaN();
88 if (col ==
"QLen")
return QLen;
89 if (col ==
"Util")
return Util;
90 if (col ==
"RespT")
return RespT;
91 if (col ==
"ResidT")
return ResidT;
92 if (col ==
"ArvR")
return ArvR;
93 if (col ==
"Tput")
return Tput;
94 if (col ==
"QLenCI")
return QLenCI;
95 if (col ==
"UtilCI")
return UtilCI;
96 if (col ==
"RespTCI")
return RespTCI;
97 if (col ==
"ResidTCI")
return ResidTCI;
98 if (col ==
"ArvRCI")
return ArvRCI;
99 if (col ==
"TputCI")
return TputCI;
100 throw InputError(
"AvgTable::column: unknown column '" + col +
"'");
118 for (std::size_t i = 0; i < source.
Station.size(); ++i) {
119 if (!keep(i))
continue;
128 if (!source.
has_ci())
continue;
142 return filter_avg_table(*
this, [&](std::size_t i) {
148 return filter_avg_table(*
this, [&](std::size_t i) {
154 return filter_avg_table(*
this, [&](std::size_t i) {
160 return filter_avg_table(*
this, [&](std::size_t i) {
161 return JobClass[i] == jobclass.get_name();
201 const std::ios::fmtflags flags = out.flags();
202 const std::streamsize precision = out.precision();
205 const auto cell = [](
double m,
double h) {
206 std::ostringstream c;
207 c << std::setprecision(6) << m <<
" +- " << std::setprecision(3) << h;
210 out << std::left << std::setw(16) <<
"Station" << std::setw(14) <<
"JobClass" << std::right;
211 for (
const char* h : {
"QLen",
"Util",
"RespT",
"ResidT",
"ArvR",
"Tput"}) out << std::setw(22) << h;
213 for (std::size_t i = 0; i <
Station.size(); ++i)
214 out << std::left << std::setw(16) <<
Station[i] << std::setw(14) <<
JobClass[i]
215 << std::right << std::setw(22) << cell(
QLen[i],
QLenCI[i])
218 << std::setw(22) << cell(
Tput[i],
TputCI[i]) <<
'\n';
222 out << std::left << std::setw(16) <<
"Station" << std::setw(14) <<
"JobClass"
223 << std::right << std::setw(12) <<
"QLen" << std::setw(12) <<
"Util"
224 << std::setw(12) <<
"RespT" << std::setw(12) <<
"ResidT"
225 << std::setw(12) <<
"ArvR" << std::setw(12) <<
"Tput" <<
'\n';
226 out << std::setprecision(6);
227 for (std::size_t i = 0; i <
Station.size(); ++i)
228 out << std::left << std::setw(16) <<
Station[i] << std::setw(14) <<
JobClass[i]
229 << std::right << std::setw(12) <<
QLen[i] << std::setw(12) <<
Util[i]
230 << std::setw(12) <<
RespT[i] << std::setw(12) <<
ResidT[i]
231 << std::setw(12) <<
ArvR[i] << std::setw(12) <<
Tput[i] <<
'\n';
233 out.precision(precision);
244 const std::ios::fmtflags flags = out.flags();
245 const std::streamsize precision = out.precision();
247 for (
const std::string& s :
JobClasses) w = std::max(w, s.size() + 2);
248 out << std::left << std::setw(10) <<
"Chain" << std::setw(
int(w)) <<
"JobClasses" << std::right
249 << std::setw(12) <<
"SysRespT" << std::setw(12) <<
"SysTput" <<
'\n';
250 out << std::setprecision(6);
251 for (std::size_t c = 0; c <
Chain.size(); ++c)
252 out << std::left << std::setw(10) <<
Chain[c] << std::setw(
int(w)) <<
JobClasses[c] << std::right
253 << std::setw(12) <<
SysRespT[c] << std::setw(12) <<
SysTput[c] <<
'\n';
255 out.precision(precision);
266 const std::ios::fmtflags flags = out.flags();
267 const std::streamsize precision = out.precision();
268 std::size_t
ws = 10, wj = 12;
269 for (std::size_t i = 0; i <
Station.size(); ++i) {
273 out << std::left << std::setw(
int(
ws)) <<
"Station" << std::setw(10) <<
"Chain" << std::setw(
int(wj))
274 <<
"JobClasses" << std::right;
275 for (
const char* c : {
"QLen",
"Util",
"RespT",
"ResidT",
"ArvR",
"Tput"}) out << std::setw(12) << c;
276 out <<
'\n' << std::setprecision(6);
277 for (std::size_t i = 0; i <
Station.size(); ++i)
278 out << std::left << std::setw(
int(
ws)) <<
Station[i] << std::setw(10) <<
Chain[i] << std::setw(
int(wj))
279 <<
JobClasses[i] << std::right << std::setw(12) <<
QLen[i] << std::setw(12) <<
Util[i]
280 << std::setw(12) <<
RespT[i] << std::setw(12) <<
ResidT[i] << std::setw(12) <<
ArvR[i]
281 << std::setw(12) <<
Tput[i] <<
'\n';
283 out.precision(precision);
294 const std::ios::fmtflags flags = out.flags();
295 const std::streamsize precision = out.precision();
296 std::size_t
wf = 6, wj = 6, wc = 10;
297 for (std::size_t i = 0; i <
Fork.size(); ++i) {
299 wj = std::max(wj,
Join[i].
size() + 2);
302 out << std::left << std::setw(
int(
wf)) <<
"Fork" << std::setw(
int(wj)) <<
"Join" << std::setw(
int(wc))
303 <<
"JobClass" << std::right << std::setw(14) <<
"FJQLen" << std::setw(14) <<
"FJRespT" << std::setw(14)
305 out << std::setprecision(6);
306 for (std::size_t i = 0; i <
Fork.size(); ++i)
307 out << std::left << std::setw(
int(
wf)) <<
Fork[i] << std::setw(
int(wj)) <<
Join[i] << std::setw(
int(wc))
309 << std::setw(14) <<
FJTput[i] <<
'\n';
311 out.precision(precision);
324void fill_table(AvgTable& t,
const qn::NetworkStruct<double>& sn,
const mva::AvgResult<double>& r) {
325 for (std::size_t i = 0; i < sn.nstations; ++i)
326 for (std::size_t c = 0; c < sn.nclasses; ++c) {
327 const double q = r.QN(i, c), u = r.UN(i, c), rt = r.RN(i, c);
328 const double w = r.WN(i, c), a = r.AN(i, c), x = r.TN(i, c);
329 if (q == 0.0 && u == 0.0 && rt == 0.0 && w == 0.0 && a == 0.0 && x == 0.0)
continue;
330 t.Station.push_back(sn.stations[i].name);
331 t.JobClass.push_back(sn.classes[c].name);
334 t.RespT.push_back(rt);
335 t.ResidT.push_back(w);
339 for (std::size_t c = 0; c <
sn.nclasses && c < r.CN.size(); ++c) {
340 t.SysClass.push_back(
sn.classes[c].name);
341 t.SysRespT.push_back(r.CN[c]);
342 t.SysTput.push_back(c < r.XN.size() ? r.XN[c] : 0.0);
345 t.warning = r.warning;
346 t.ListCost = r.listcost;
347 if (r.lognormconst.has_value()) {
348 t.has_lognormconst =
true;
349 t.lognormconst = r.lognormconst.value();
367 const std::size_t M =
sn.nstations, K =
sn.nclasses;
369 for (std::size_t i = 0; i < M; ++i)
370 for (std::size_t c = 0; c < K; ++c) {
371 RN(i, c) = r.RN(i, c);
372 TN(i, c) = r.TN(i, c);
376 for (std::size_t i = 0; i < M; ++i)
377 for (std::size_t c = 0; c < K; ++c) {
378 const double q = r.QN(i, c), u = r.UN(i, c), rt = r.RN(i, c), x = r.TN(i, c);
380 const double w = WN(i, c), a = is_source ? 0.0 : AN(i, c);
383 if (q == 0.0 && u == 0.0 && rt == 0.0 && w == 0.0 && a == 0.0 && x == 0.0)
continue;
384 t.Station.push_back(
sn.stations[i].name);
385 t.JobClass.push_back(
sn.classes[c].name);
388 t.RespT.push_back(rt);
389 t.ResidT.push_back(w);
393 for (std::size_t c = 0; c <
sn.nclasses && c < r.CN.size(); ++c) {
394 t.SysClass.push_back(
sn.classes[c].name);
395 t.SysRespT.push_back(r.CN[c]);
396 t.SysTput.push_back(c < r.XN.size() ? r.XN[c] : 0.0);
413 for (std::size_t i = 0; i <
sn.nstations; ++i)
414 for (std::size_t c = 0; c <
sn.nclasses; ++c) {
415 const double q = r.QN(i, c), u = r.UN(i, c), rt = r.RN(i, c);
416 const double w = WNfix(i, c), a = r.AN(i, c), x = r.TN(i, c);
417 if (q == 0.0 && u == 0.0 && rt == 0.0 && w == 0.0 && a == 0.0 && x == 0.0)
continue;
418 t.Station.push_back(
sn.stations[i].name);
419 t.JobClass.push_back(
sn.classes[c].name);
422 t.RespT.push_back(rt);
423 t.ResidT.push_back(w);
427 for (std::size_t c = 0; c <
sn.nclasses && c < r.CN.cols(); ++c) {
428 t.SysClass.push_back(
sn.classes[c].name);
429 t.SysRespT.push_back(r.CN(0, c));
430 t.SysTput.push_back(c < r.XN.cols() ? r.XN(0, c) : 0.0);
446 const auto at = [](
const Matrix<double>& m, std::size_t i, std::size_t c) {
447 return i < m.rows() && c < m.cols() ? m(i, c) : 0.0;
449 for (std::size_t i = 0; i <
sn.nstations; ++i)
450 for (std::size_t c = 0; c <
sn.nclasses; ++c) {
451 const double q =
QN(i, c), u =
UN(i, c), rt = RN(i, c), w = WN(i, c), a = AN(i, c), x = TN(i, c);
452 if (q == 0.0 && u == 0.0 && rt == 0.0 && w == 0.0 && a == 0.0 && x == 0.0)
continue;
453 t.QLenCI.push_back(at(QCI, i, c));
454 t.UtilCI.push_back(at(UCI, i, c));
455 t.RespTCI.push_back(at(RCI, i, c));
456 t.ResidTCI.push_back(rt > 0.0 ? at(RCI, i, c) * w / rt : 0.0);
457 t.ArvRCI.push_back(at(ACI, i, c));
458 t.TputCI.push_back(at(TCI, i, c));
472 if (!o.map_env.empty()) c.
mode = o.map_env;
473 if (!o.map_env_method.empty()) c.method = o.map_env_method;
474 if (o.map_env_maxstages) c.max_stages = o.map_env_maxstages;
480 if (!o.method.empty()) c.
method = o.method;
481 if (o.cutoff > 0.0) c.cutoff = o.cutoff;
482 if (!o.cutoff_vec.empty()) c.cutoff_vec = o.cutoff_vec;
483 if (o.state_max) c.state_max = o.state_max;
484 if (o.timestep > 0.0) c.timestep = o.timestep;
497 if (!o.symbolic.empty()) s.
backend = o.symbolic;
498 if (o.symbolic_timeout > 0) s.timeout_s = o.symbolic_timeout;
504 if (!o.method.empty()) f.
method = o.method;
505 if (o.tol >= 0.0) f.tol = o.tol;
506 if (o.iter_tol >= 0.0) f.iter_tol = o.iter_tol;
507 if (o.iter_max >= 0) f.iter_max =
static_cast<std::size_t
>(o.iter_max);
508 if (o.timespan_end > 0.0) f.timespan_end = o.timespan_end;
509 if (!o.init_sol.empty()) f.init_sol = o.init_sol;
510 if (o.seed) f.seed = o.seed;
511 if (!o.highvar.empty()) f.highvar = o.highvar;
512 if (o.timestep > 0.0) f.timestep = o.timestep;
526 if (!o.method.empty()) j.
method = o.method;
527 if (o.samples) j.samples =
static_cast<double>(o.samples);
528 if (o.seed) j.seed =
static_cast<long>(o.seed);
529 if (o.replications > 0) j.replications = o.replications;
530 if (o.timespan_end > 0.0) j.max_simulated_time = o.timespan_end;
531 j.confint = o.confint;
533 j.verbose = o.verbose;
540 if (!o.method.empty())
opt.method = o.method;
541 if (o.samples)
opt.samples = o.samples;
542 if (o.events)
opt.events = o.events;
543 if (o.seed)
opt.seed =
static_cast<long>(o.seed);
544 if (o.timeout > 0.0)
opt.timeout = o.timeout;
545 if (o.confint > 0.0)
opt.confint = o.confint;
546 if (!o.cimethod.empty())
opt.cimethod = o.cimethod;
547 if (o.ciminbatch >= 0)
opt.ciminbatch = o.ciminbatch;
548 if (o.ciminobs >= 0)
opt.ciminobs = o.ciminobs;
549 if (o.obmoverlap >= 0.0)
opt.obmoverlap = o.obmoverlap;
550 if (o.spectral_low_freq_frac > 0.0)
opt.spectral_low_freq_frac = o.spectral_low_freq_frac;
551 if (!o.tranfilter.empty())
opt.tranfilter = o.tranfilter;
552 if (o.mserbatch > 0)
opt.mserbatch = o.mserbatch;
553 if (o.warmupfrac >= 0.0)
opt.warmupfrac = o.warmupfrac;
554 opt.cnvgon = o.cnvgon;
555 if (o.cnvgtol > 0.0)
opt.cnvgtol = o.cnvgtol;
556 if (o.cnvgbatch > 0)
opt.cnvgbatch = o.cnvgbatch;
557 if (o.cnvgchk >= 0)
opt.cnvgchk = o.cnvgchk;
558 if (!o.init_sol.empty())
opt.init_sol = o.init_sol;
559 if (o.init_jobs.rows() > 0)
opt.init_jobs = o.init_jobs;
560 opt.track_jobs = o.track_jobs;
561 opt.verbose = o.verbose;
571std::string facade_name_of_family(
const std::string& fam) {
572 if (fam ==
"mva" || fam ==
"nc" || fam ==
"ctmc" || fam ==
"mam" || fam ==
"ag" ||
573 fam ==
"ba" || fam ==
"ssa" || fam ==
"jmt" || fam ==
"lqns") {
574 std::string up = fam;
575 std::transform(up.begin(), up.end(), up.begin(), ::toupper);
578 if (fam ==
"fld")
return "FLD";
582 "SolverAUTO: method family 'ldes' names the discrete-event engine, and none was "
583 "found (common/ldes or common/ldes.jar, or $LINE_LDES_DIR); 'ssa' is the simulator "
584 "this port builds in process");
589 "SolverAUTO: method family 'ln' names the layered solver, which takes a "
590 "LayeredNetwork rather than a Network");
593 "SolverAUTO: method family 'env' names the random-environment solver, which takes an "
594 "Environment rather than a Network");
597 "SolverAUTO: method family 'uq' names the uncertainty-quantification solver, which "
598 "this facade does not wrap");
599 throw InputError(
"SolverAUTO: no engine stands behind method family '" + fam +
"'");
604 std::vector<double> v;
606 for (std::size_t c = 0; c < m.cols(); ++c) v.push_back(m(0, c));
619 const std::map<std::size_t, std::vector<double> >& hit) {
621 for (std::size_t c = 0; c < out.caches.size(); ++c) {
623 const std::map<std::size_t, std::vector<double> >::const_iterator it = hit.find(m.node);
624 if (it == hit.end())
continue;
626 for (std::size_t r = 0; r < m.hitprob.size(); ++r) m.missprob.push_back(1.0 - m.hitprob[r]);
634 const std::map<std::string, ldes::LdesCacheMetrics>& cm) {
636 for (std::size_t c = 0; c < out.caches.size(); ++c) {
638 const std::map<std::string, ldes::LdesCacheMetrics>::const_iterator it = cm.find(m.name);
639 if (it == cm.end())
continue;
640 m.hitprob = row_of(it->second.hit);
641 m.missprob = row_of(it->second.miss);
642 m.delayedprob = row_of(it->second.delayed);
643 m.latency = row_of(it->second.latency);
644 m.hitproblist = it->second.hitList;
645 m.itemprob = it->second.itemProb;
646 m.listcost = row_of(it->second.listCost);
656void solve_named(
const std::string& name,
const SolverOptions& o,
662 if (o.confint < 0.0 || o.confint >= 1.0)
663 throw InputError(
"SolverOptions: confint must be a confidence level in (0,1), or 0 to disable; got " +
664 std::to_string(o.confint));
667 if (!o.method.empty())
opt.method = o.method;
668 if (o.tol >= 0.0)
opt.tol = o.tol;
669 if (o.iter_tol >= 0.0)
opt.iter_tol = o.iter_tol;
670 if (o.iter_max >= 0)
opt.iter_max = o.iter_max;
671 if (!o.multiserver.empty())
opt.multiserver = o.multiserver;
672 if (!o.highvar.empty())
opt.highvar = o.highvar;
673 if (!o.np_priority.empty())
opt.np_priority = o.np_priority;
674 if (!o.fork_join.empty())
opt.fork_join = o.fork_join;
683 t.
method = r.actualmethod;
684 fill_table(t,
sn, r);
687 }
else if (name ==
"NC") {
689 if (!o.method.empty())
opt.method = o.method;
690 if (o.tol >= 0.0)
opt.tol = o.tol;
691 if (o.iter_tol >= 0.0)
opt.iter_tol = o.iter_tol;
692 if (o.iter_max >= 0)
opt.iter_max = o.iter_max;
693 if (!o.highvar.empty())
opt.highvar = o.highvar;
694 if (!o.multiserver.empty())
opt.multiserver = o.multiserver;
695 if (!o.fork_join.empty())
opt.fork_join = o.fork_join;
696 if (o.samples)
opt.samples = o.samples;
697 if (o.seed)
opt.seed = o.seed;
702 t.
method = r.actualmethod;
703 fill_table(t,
sn, r);
706 }
else if (name ==
"CTMC") {
712 t.method = r.actualmethod;
713 fill_table(t,
sn, r);
715 }
else if (name ==
"MAM") {
717 if (!o.method.empty())
opt.method = o.method;
718 if (o.tol >= 0.0)
opt.tol = o.tol;
719 if (o.iter_max >= 0)
opt.iter_max = o.iter_max;
721 t.method = r.actualmethod;
722 fill_table(t,
sn, r);
724 }
else if (name ==
"BA") {
732 if (!o.method.empty())
opt.method = o.method;
735 t.method = r.actualmethod;
736 fill_table(t,
sn, r);
738 }
else if (name ==
"SSA") {
740 if (!o.method.empty())
opt.method = o.method;
741 if (o.samples)
opt.samples = o.samples;
742 if (o.events)
opt.samples = o.events;
743 if (o.seed)
opt.seed = o.seed;
744 if (o.cutoff > 0.0)
opt.cutoff = o.cutoff;
745 if (o.warmupfrac >= 0.0)
opt.warmupfrac = o.warmupfrac;
746 if (!o.state_space_gen.empty())
opt.state_space_gen = o.state_space_gen;
747 opt.verbose = o.verbose;
751 std::vector<ssa::SsaCacheRatio> cacheratio;
756 }
else if (name ==
"FLD" || name ==
"FLUID") {
768 t.method = r.actualmethod;
769 fill_table(t,
sn, r);
779 t.iter =
static_cast<int>(r.iters);
780 t.warning = r.warning;
782 const bool has_ref = refreshed.nstations ==
sn.nstations && refreshed.nclasses ==
sn.nclasses;
783 fill_table_sim(t, has_ref ? refreshed :
sn, r);
785 }
else if (name ==
"JMT") {
788 t.method = r.avg.actualmethod;
789 fill_table(t,
sn, r.avg);
790 cache = r.cache_hit_prob.empty() ? r.avg.cache : cache_metrics_of_jmt(
sn, r.cache_hit_prob);
791 if (
fj) *
fj = r.avg.fj;
792 if (o.confint > 0.0 && !r.QCI.empty())
793 fill_table_ci(t,
sn, r.avg.QN, r.avg.UN, r.avg.RN, r.avg.WN, r.avg.AN, r.avg.TN, r.QCI,
794 r.UCI, r.RCI, r.ACI, r.TCI);
795 }
else if (name ==
"LDES") {
798 t.method =
opt.method;
799 fill_table_ldes(t,
sn, r);
800 cache = cache_metrics_of_ldes(
sn, r.cache_metrics);
802 if (o.confint > 0.0 && !r.QNCI.empty())
804 r.TN, r.QNCI, r.UNCI, r.RNCI, r.ANCI, r.TNCI);
805 }
else if (name ==
"AG") {
807 if (!o.method.empty() && o.method !=
"default")
opt.method = o.method;
808 if (o.tol >= 0.0)
opt.tol = o.tol;
809 if (o.iter_max >= 0)
opt.iter_max = o.iter_max;
811 t.method = r.actualmethod;
812 fill_table(t,
sn, r);
814 }
else if (name ==
"LQNS") {
817 if (!o.method.empty())
opt.method = o.method;
818 if (!o.multiserver.empty())
opt.multiserver = o.multiserver;
821 t.method = r.actualmethod;
822 fill_table(t,
sn, r);
842 if (!tok.is_intent) {
843 oo.method = tok.submethod;
844 solve_named(facade_name_of_family(tok.family), oo,
sn, t,
cache,
fj);
848 const std::vector<autosolver::AutoSolver> order =
850 std::string first_error, first_category, first_kind;
851 for (std::size_t i = 0; i < order.size(); ++i) {
853 std::transform(
name.begin(),
name.end(),
name.begin(), ::toupper);
854 if (name ==
"FLUID")
name =
"FLD";
855 oo.method = (i == 0 && !c.method.empty()) ? c.method : std::string(
"default");
860 solve_named(name, oo,
sn, attempt, attempt_cache, &attempt_fj);
862 cache = attempt_cache;
863 if (
fj) *
fj = attempt_fj;
865 }
catch (
const Error& e) {
866 const std::string cat = e.category();
867 if (cat ==
"input" || cat ==
"internal")
throw;
868 if (first_error.empty()) {
869 first_error =
name +
": " + e.what();
870 first_category = cat;
871 first_kind = e.kind();
873 }
catch (
const std::exception& e) {
874 if (first_error.empty()) first_error =
name +
": " + e.what();
877 const std::string all_failed =
878 "SolverAUTO: every candidate refused this run. The chosen engine reported -- " + first_error;
886void solve_zero_capacity(
const std::string& name,
const SolverOptions& o,
903 for (
const auto& st :
sn.stations)
904 for (
const auto& row : st.switchover_pair)
906 return !d.disabled && d.type != lang::ProcessType::IMMEDIATE;
908 std::cerr <<
"[LINE] Warning: Station " << st.name <<
" declares class-to-class switchover "
909 <<
"times, which no LINE solver simulates at a non-polling queue: every solver "
910 <<
"answers as if they were zero. Only POLLING switchovers are solved." << std::endl;
922 else if (
name_ ==
"AUTO")
942 const std::size_t M =
sn.nstations, K =
sn.nclasses;
950 for (std::size_t row = 0; row < t.
size(); ++row)
951 for (std::size_t i = 0; i < M; ++i) {
952 if (
sn.stations[i].name != t.
Station[row])
continue;
953 for (std::size_t c = 0; c < K; ++c) {
954 if (
sn.classes[c].name != t.
JobClass[row])
continue;
981void solve_zero_capacity(
const std::string& name,
const SolverOptions& o,
985 const std::size_t M =
sn.nstations, K =
sn.nclasses;
986 const double inf = std::numeric_limits<double>::infinity();
987 std::vector<bool> trappedcls(K,
false);
988 std::size_t ntrapped = 0;
989 for (std::size_t c = 0; c <
sn.nchains; ++c)
990 if (zc.deadstat[c] > 0)
991 for (std::size_t r = 0; r < K; ++r)
992 if (
sn.chains[c][r] && !trappedcls[r]) {
993 trappedcls[r] =
true;
1005 solved.solver =
name;
1006 solved.method = o.method.empty() ? std::string(
"default") : o.method;
1011 for (std::size_t k = 0; k < K; ++k)
1012 if (trappedcls[k]) reduced.classes[k].population = 0.0;
1013 for (std::size_t c = 0; c <
sn.nchains; ++c) {
1014 const std::size_t i = zc.deadstat[c];
1015 if (i > 0 &&
sn.stations[i - 1].nservers == 0.0) reduced.stations[i - 1].nservers = 1.0;
1017 reduced.refresh_struct();
1020 solve_auto(o, reduced, solved,
cache,
fj);
1022 solve_named(name, o, reduced, solved,
cache,
fj);
1023 r = avg_result_of_table(
sn, solved);
1025 std::vector<double> CN(K, 0.0), XN(K, 0.0);
1026 for (std::size_t row = 0; row < solved.SysClass.size(); ++row)
1027 for (std::size_t k = 0; k < K; ++k)
1028 if (
sn.classes[k].name == solved.SysClass[row]) {
1029 CN[k] = solved.SysRespT[row];
1030 XN[k] = solved.SysTput[row];
1032 const std::vector<double> st2sf =
sn.station_to_stateful();
1033 const std::vector<double> njobs =
sn.njobs();
1034 for (std::size_t c = 0; c <
sn.nchains; ++c) {
1035 if (zc.deadstat[c] == 0)
continue;
1036 const std::size_t i = zc.deadstat[c] - 1;
1037 const std::size_t sf =
static_cast<std::size_t
>(st2sf[i]) - 1;
1038 double pop = 0.0, vtot = 0.0;
1039 for (std::size_t k = 0; k < K; ++k)
1040 if (
sn.chains[c][k]) {
1042 vtot +=
sn.visits[c](sf, k);
1044 for (std::size_t k = 0; k < K; ++k) {
1045 if (!
sn.chains[c][k])
continue;
1046 for (std::size_t j = 0; j < M; ++j) {
1054 const double v =
sn.visits[c](sf, k);
1055 r.QN(i, k) = pop * v / vtot;
1066 r.iter = solved.iter;
1067 r.warning = solved.warning;
1068 r.listcost = solved.ListCost;
1069 if (solved.has_lognormconst) r.lognormconst = solved.lognormconst;
1071 t.solver = solved.solver;
1072 t.method = solved.method;
1073 fill_table(t,
sn, r);
1112 for (std::size_t i = 0; i <
sn.nstations; ++i)
1113 for (std::size_t k = 0; k <
sn.nchains; ++k) {
1114 out.
Station.push_back(
sn.stations[i].name);
1115 out.
Chain.push_back(chains[k]);
1117 out.
QLen.push_back(c.
QN(i, k));
1118 out.
Util.push_back(c.
UN(i, k));
1119 out.
RespT.push_back(c.
RN(i, k));
1121 out.
ArvR.push_back(c.
AN(i, k));
1122 out.
Tput.push_back(c.
TN(i, k));
1140 if (
fj.empty())
return out;
1142 for (std::size_t p = 0; p <
fj.npairs(); ++p)
1143 for (std::size_t r = 0; r <
fj.QLen.cols(); ++r) {
1144 const double q =
fj.QLen(p, r), rt =
fj.RespT(p, r), x =
fj.Tput(p, r);
1145 if (!(q > 0.0 || rt > 0.0 || x > 0.0))
continue;
1146 out.
Fork.push_back(
sn.nodes[
fj.forks[p] - 1].name);
1147 out.
Join.push_back(
sn.nodes[
fj.joins[p] - 1].name);
1160 const std::string&
cache,
bool hit) {
1161 for (std::size_t c = 0; c < cm.
caches.size(); ++c) {
1163 const std::vector<double>& v = hit ? cm.
caches[c].hitprob : cm.
caches[c].missprob;
1166 "Solver" + solver +
" measured no " + (hit ?
"hit" :
"miss") +
1167 " ratio at Cache '" + cache +
"' with this method");
1170 throw InputError(
"'" +
cache +
"' is not a Cache node of this model");
1221 opt.keep_filtration =
true;
1230 const std::size_t ist =
sn.nodes[node - 1].station;
1231 if (ist == 0)
throw InputError(
"prob_aggr: the node is not a station");
1232 const std::size_t K =
sn.nclasses;
1233 if (state.size() != K)
throw InputError(
"prob_aggr: the state must have one entry per class");
1235 for (std::size_t s = 0; s < A.
rows(); ++s) {
1237 for (std::size_t k = 0; k < K && hit; ++k) hit = A(s, (ist - 1) * K + k) == state[k];
1238 if (hit) p += d.
pi[s];
1247 const std::size_t ist =
sn.nodes[node - 1].station;
1248 if (ist == 0)
throw InputError(
"marg_aggr: the node is not a station");
1249 const std::size_t K =
sn.nclasses;
1250 std::size_t nmax = 0;
1251 for (std::size_t s = 0; s < A.
rows(); ++s) {
1253 for (std::size_t k = 0; k < K; ++k) tot += A(s, (ist - 1) * K + k);
1254 nmax = std::max(nmax,
static_cast<std::size_t
>(tot));
1256 std::vector<double> pmf(nmax + 1, 0.0);
1257 for (std::size_t s = 0; s < A.
rows(); ++s) {
1259 for (std::size_t k = 0; k < K; ++k) tot += A(s, (ist - 1) * K + k);
1260 pmf[
static_cast<std::size_t
>(tot)] += d.
pi[s];
1267 std::vector<std::vector<CdfCurve> > out(
sn.nstations, std::vector<CdfCurve>(
sn.nclasses));
1268 const std::vector<std::vector<ctmc::CdfCurve<double> > > R =
1270 for (std::size_t i = 0; i < R.size() && i < out.size(); ++i)
1271 for (std::size_t c = 0; c < R[i].size() && c < out[i].size(); ++c) {
1272 out[i][c].t = R[i][c].t;
1273 out[i][c].F = R[i][c].F;
1284std::size_t StateView::column(std::size_t node, std::size_t cls)
const {
1285 if (node == 0 || node > sn_->
nodes.size())
1286 throw InputError(
"StateView: node index " + std::to_string(node) +
" does not exist");
1287 const std::size_t ist = sn_->
nodes[node - 1].station;
1290 "' is not a station, so the aggregate state holds no count for it");
1291 if (cls == 0 || cls > sn_->
nclasses)
1292 throw InputError(
"StateView: class index " + std::to_string(cls) +
" does not exist");
1293 return (ist - 1) * sn_->
nclasses + (cls - 1);
1297 return (*row_)[column(node, cls)];
1302 for (std::size_t k = 1; k <= sn_->nclasses; ++k) tot += (*row_)[column(node, k)];
1316 if (aggr.
rows() != n)
1317 throw InputError(std::string(
"The aggregated state space has ") +
1318 std::to_string(aggr.
rows()) +
" rows where the generator has " +
1319 std::to_string(n) +
", so the predicate for set " + name +
1320 " cannot be resolved state by state.");
1321 std::vector<double> hit;
1322 std::vector<double> row(aggr.
cols());
1323 for (std::size_t s = 0; s < n; ++s) {
1324 for (std::size_t c = 0; c < aggr.
cols(); ++c) row[c] = aggr(s, c);
1325 if (fn(
StateView(row,
sn))) hit.push_back(
static_cast<double>(s + 1));
1327 Matrix<double> out(hit.size(), hit.empty() ? 0 : 1);
1328 for (std::size_t i = 0; i < hit.size(); ++i) out(i, 0) = hit[i];
1337 out.reachprob = r.reachprob;
1338 out.tabooprob = r.tabooprob;
1339 out.source = r.source;
1340 out.target = r.target;
1341 out.taboo = r.taboo;
1350 out.source = r.source;
1351 out.target = r.target;
1352 out.taboo = r.taboo;
1360 const std::vector<double>& tset) {
1368 const std::vector<double>& tset) {
1373 const std::size_t n = d.
chain.Q.rows();
1375 sn, d, predicate_states(A, ssn, aggr, n,
"A"), predicate_states(B, ssn, aggr, n,
"B"),
1376 predicate_states(C, ssn, aggr, n,
"C"), tset));
1394 const std::size_t n = d.
chain.Q.rows();
1396 sn, d, predicate_states(A, ssn, aggr, n,
"A"), predicate_states(B, ssn, aggr, n,
"B"),
1397 nmax, predicate_states(C, ssn, aggr, n,
"C")));
1415 std::printf(
"%8s %-28s %s\n",
"State",
"Marking",
"Rates (to: rate)");
1416 for (std::size_t i = 0; i < Q.
rows(); ++i) {
1418 if (i < space.
rows()) {
1419 std::ostringstream os;
1421 for (std::size_t c = 0; c < space.
cols(); ++c) os << (c ?
" " :
"") << space(i, c);
1425 std::printf(
"%8zu %-28s", i + 1, mark.c_str());
1426 for (std::size_t j = 0; j < Q.
cols(); ++j)
1427 if (i != j && Q(i, j) != 0.0) std::printf(
" %zu: %.6g", j + 1, Q(i, j));
1438 const std::vector<fluid::FluidTranPoint> pts =
1441 for (std::size_t i = 0; i <
sn.nstations; ++i)
1442 for (std::size_t c = 0; c <
sn.nclasses; ++c)
1443 out.
label.push_back(
sn.stations[i].name +
"/" +
sn.classes[c].name);
1444 for (std::size_t s = 0; s < pts.size(); ++s) {
1445 out.
t.push_back(pts[s].t);
1446 std::vector<double> row;
1447 for (std::size_t i = 0; i <
sn.nstations; ++i)
1448 for (std::size_t c = 0; c <
sn.nclasses; ++c) row.push_back(pts[s].QN(i, c));
1449 out.
QNt.push_back(row);
1456 std::vector<std::vector<CdfCurve> > out(
sn.nstations, std::vector<CdfCurve>(
sn.nclasses));
1457 const std::vector<std::vector<fluid::FluidPassage> > R =
1459 for (std::size_t i = 0; i < R.size() && i < out.size(); ++i)
1460 for (std::size_t c = 0; c < R[i].size() && c < out[i].size(); ++c) {
1461 out[i][c].t = R[i][c].t;
1462 out[i][c].F = R[i][c].cdf;
1477 "SolverLDES::cdf_respt needs the per-job response times the engine records under "
1478 "--respt-samples and the run returned none; raise the samples so completions are observed");
1479 std::vector<std::vector<CdfCurve> > out(
sn.nstations, std::vector<CdfCurve>(
sn.nclasses));
1480 for (std::size_t i = 0; i <
sn.nstations; ++i)
1481 for (std::size_t c = 0; c <
sn.nclasses; ++c) {
1483 for (std::size_t j = 0; j < m.
rows(); ++j) {
1484 out[i][c].F.push_back(m(j, 0));
1485 out[i][c].t.push_back(m(j, 1));
1493 const std::size_t M =
sn.nstations, K =
sn.nclasses;
1501 for (std::size_t row = 0; row < t.
QLen.size(); ++row)
1502 for (std::size_t i = 0; i < M; ++i)
1503 for (std::size_t c = 0; c < K; ++c)
1505 QN(i, c) = t.
QLen[row];
1510 for (std::size_t i = 1; i <= M; ++i) {
1512 std::vector<std::size_t> n(K, 0), ph(K, 1);
1513 for (std::size_t c = 0; c < K; ++c) {
1514 n[c] =
static_cast<std::size_t
>(P(i - 1, c) + 0.5);
1515 ph[c] =
sn.phases_of(i, c + 1);
1519 throw InputError(
"SolverLDES::init_from_solver: station '" +
sn.stations[i - 1].name +
1520 "' admits no state with the warm-start placement");
1522 for (std::size_t r = 0; r < rows.size(); ++r)
1523 for (std::size_t c = 0; c < rows[r].size(); ++c) space(r, c) = rows[r][c];
1524 std::vector<double> prior(rows.size(), 0.0);
1531 jobs_ready_ =
false;
1536 if (jobs.
rows() == 0 || jobs.
cols() < 7)
1537 throw InputError(
"SolverLDES::init_from_jobs needs one row per job with the columns [station, class, "
1538 "remaining, elapsed, qage, sage, order, id], id optional");
1542 jobs_ready_ =
false;
1546void SolverLDES::run_tracked() {
1550 opt.track_jobs =
true;
1564 return job_departures_;
1573 std::vector<std::vector<CdfCurve> > out(
sn.nstations, std::vector<CdfCurve>(
sn.nclasses));
1578 const std::map<std::pair<std::size_t, std::size_t>, std::vector<std::pair<double, double> > >
1580 for (std::map<std::pair<std::size_t, std::size_t>,
1581 std::vector<std::pair<double, double> > >::const_iterator it = rd.begin();
1582 it != rd.end(); ++it) {
1583 const std::size_t i = it->first.first, c = it->first.second;
1584 if (i == 0 || i > out.size() || c == 0 || c >
sn.nclasses)
continue;
1588 for (std::size_t j = 0; j < it->second.size(); ++j) {
1589 out[i - 1][c - 1].F.push_back(it->second[j].first);
1590 out[i - 1][c - 1].t.push_back(it->second[j].second);
1600 for (std::size_t i = 0; i <
sn.nstations; ++i)
1601 for (std::size_t c = 0; c <
sn.nclasses; ++c)
1602 out.
label.push_back(
sn.stations[i].name +
"/" +
sn.classes[c].name);
1604 for (std::size_t g = 0; g < r.
t.size(); ++g) {
1605 std::vector<double> row;
1606 for (std::size_t i = 0; i <
sn.nstations; ++i)
1607 for (std::size_t c = 0; c <
sn.nclasses; ++c)
1608 row.push_back(i < r.
QNt.size() && c < r.
QNt[i].size() && g < r.
QNt[i][c].size()
1611 out.
QNt.push_back(row);
1618 if (node == 0 || node >
sn.nodes.size())
throw InputError(
"prob_aggr: node index out of range");
1619 const std::size_t ist =
sn.nodes[node - 1].station;
1620 if (ist == 0)
throw InputError(
"prob_aggr: the node is not a station");
1630 if (node >
sn.nodes.size() ||
sn.nodes[node - 1].station == 0)
1631 throw InputError(
"sample: the node is not a station, so nothing is logged for it");
1633 for (std::size_t c = 0; c <
sn.nclasses; ++c) out.
label.push_back(
sn.classes[c].name);
1639 for (std::size_t i = 0; i <
sn.nstations; ++i)
1640 for (std::size_t c = 0; c <
sn.nclasses; ++c)
1641 out.
label.push_back(
sn.stations[i].name +
"/" +
sn.classes[c].name);
1643 for (std::size_t g = 0; g <
tr.t.size(); ++g) {
1644 std::vector<double> row;
1645 for (std::size_t i = 0; i <
sn.nstations; ++i)
1646 for (std::size_t c = 0; c <
sn.nclasses; ++c)
1647 row.push_back(i <
tr.state.size() && g <
tr.state[i].size() &&
1648 c <
tr.state[i][g].size()
1651 out.
state.push_back(row);
1668 for (std::size_t i = 0; i <
sn.nstations; ++i)
1669 for (std::size_t c = 0; c <
sn.nclasses; ++c) {
1670 if (i < b.
keep.size() && c < b.
keep[i].size() && !b.
keep[i][c])
continue;
1671 t.
Station.push_back(
sn.stations[i].name);
1690 std::transform(name.begin(), name.end(), name.begin(), ::toupper);
1695std::string family_of_facade_name(
const std::string& tag) {
1696 std::string fam = tag;
1697 std::transform(fam.begin(), fam.end(), fam.begin(), ::tolower);
1706struct AutoDelegatePlan {
1707 bool family =
false;
1708 std::string family_name;
1709 std::vector<std::string> tags;
1710 std::string first_method;
1714 const std::string& getter) {
1715 AutoDelegatePlan plan;
1717 if (!tok.is_intent) {
1719 plan.family_name = tok.family;
1720 plan.tags.push_back(facade_name_of_family(tok.family));
1721 plan.first_method = tok.submethod;
1726 for (std::size_t i = 0; i < order.size(); ++i) plan.tags.push_back(facade_name_of_slot(order[i]));
1727 plan.first_method = c.method.empty() ? std::string(
"default") : c.method;
1737template <
class R,
class Call>
1739 const std::set<std::string>& answers, Call call, std::string& last) {
1741 const AutoDelegatePlan plan = auto_delegate_plan(
sn, o.method, getter);
1742 std::string last_error, last_cat, last_kind, proposed;
1744 for (std::size_t i = 0; i < plan.tags.size(); ++i) {
1745 const std::string& tag = plan.tags[i];
1746 proposed += (proposed.empty() ?
"" :
", ") + tag;
1747 if (!answers.count(tag))
continue;
1750 oo.
method = i == 0 ? plan.first_method : std::string(
"default");
1752 R r = call(tag, model, oo);
1755 }
catch (
const Error& e) {
1756 const std::string cat = e.category();
1757 if (cat ==
"input" || cat ==
"internal")
throw;
1758 last_error = tag +
": " + e.what();
1760 last_kind = e.kind();
1766 "SolverAUTO: method family '" + plan.family_name +
"' does not answer " + getter +
1769 "SolverAUTO: none of the solvers proposed for " + getter +
" (" + proposed +
1770 ") answers it in this port");
1772 const std::string msg =
"SolverAUTO: All candidate solvers failed to execute method '" + getter +
1773 "'. Last error: " + last_error;
1780bool facade_is_stochastic(
const std::string& tag,
const std::string& method) {
1781 if (tag ==
"SSA" || tag ==
"LDES")
return true;
1782 if (tag ==
"JMT")
return method.compare(0, 4,
"jmva") != 0;
1803 if (!last_.empty())
return last_;
1807 }
catch (
const Error&) {
1809 return std::string();
1815 return tag.empty() ? std::string() : family_of_facade_name(tag);
1819 std::vector<std::string> out;
1821 for (std::size_t i = 0; i < c.size(); ++i) out.push_back(facade_name_of_slot(c[i]));
1834 if (!last_.empty())
return facade_is_stochastic(last_, std::string());
1837 for (std::size_t i = 0; i < c.size(); ++i)
1838 if (facade_is_stochastic(c[i], std::string()))
return true;
1844 out.push_back(
"auto");
1846 for (std::size_t f = 0; f < fams.size(); ++f) {
1851 tag = facade_name_of_family(fams[f]);
1852 }
catch (
const Error&) {
1856 out.push_back(fams[f]);
1857 std::string key = fams[f];
1858 std::transform(key.begin(), key.end(), key.begin(), ::toupper);
1860 for (std::size_t m = 0; m < declared.size(); ++m) out.push_back(fams[f] +
"." + declared[m]);
1862 std::sort(out.begin(), out.end());
1863 out.erase(std::unique(out.begin(), out.end()), out.end());
1868 const std::vector<autosolver::SolverCandidate> rows =
1870 std::vector<AutoCandidate> out;
1871 for (std::size_t i = 0; i < rows.size(); ++i) {
1873 c.
solver = rows[i].solver;
1874 c.
method = rows[i].method;
1878 c.
reason = rows[i].reason;
1885 std::set<std::string> answers;
1886 answers.insert(
"CTMC");
1887 answers.insert(
"FLD");
1888 answers.insert(
"LDES");
1889 answers.insert(
"JMT");
1890 return auto_delegate<std::vector<std::vector<CdfCurve> > >(
1893 if (tag ==
"CTMC")
return SolverCTMC(m, oo).cdf_respt();
1894 if (tag ==
"FLD")
return SolverFLD(m, oo).cdf_respt();
1895 if (tag ==
"LDES")
return SolverLDES(m, oo).cdf_respt();
1902 std::set<std::string> answers;
1903 answers.insert(
"FLD");
1904 answers.insert(
"JMT");
1905 return auto_delegate<TranAvg>(
1908 if (tag ==
"FLD")
return SolverFLD(m, oo).tran_avg();
1915 std::set<std::string> answers;
1916 answers.insert(
"CTMC");
1917 answers.insert(
"JMT");
1918 return auto_delegate<double>(
1921 if (tag ==
"CTMC")
return SolverCTMC(m, oo).prob_aggr(node, state);
1922 return SolverJMT(m, oo).prob_aggr(node, state);
1934 const std::string& fallback) {
1936 const std::size_t dot = o.
method.find(
'.');
1937 const std::string head = dot == std::string::npos ? o.
method : o.
method.substr(0, dot);
1956 return SolverNC(*
model_, family_solver_options(
opts_,
"nc",
"default"));
1965 return {
"default",
"heur",
"sim",
"exact",
"fast",
"accurate",
"bound"};
1969 return {
"mva",
"nc",
"ctmc",
"fld",
"mam",
"ag",
"ba",
"ssa",
"ldes",
"jmt",
"ln",
"env",
"lqns",
"uq"};
1990 for (std::size_t s = 0; s <
sizeof(sets) /
sizeof(*sets); ++s) {
1991 const std::vector<qn::Feature> fs = sets[s].
list();
1992 for (std::size_t i = 0; i < fs.size(); ++i) out.set(fs[i]);
2000 const std::vector<qn::Feature> fs = auto_feature_union().list();
2001 std::vector<std::string> out;
2002 for (std::size_t i = 0; i < fs.size(); ++i) out.push_back(
qn::feature_name(fs[i]));
The -s ag entry point: gates, fixed point, mean measures.
SolverAUTO.listValidMethods: the method names THIS MODEL can actually run.
Base error for the multiprecision C++ port.
ExternalError(const std::string &what)
const SolverOptions & options() const
The options this solver was built with.
const solvers::CacheMetrics< double > & cache_metrics()
What the same solve observed at each Cache node, the data behind getAvgCacheTable() and getAvgItemTab...
std::vector< double > miss_ratio(const std::string &cache)
cache.getMissRatio() after the solve, with hit_ratio's conventions.
AvgFJTable avg_fj_table()
getAvgFJTable() (aliases getAvgFJT, fjAvgT, aFJT): the same metrics as a labelled table.
const solvers::FjMetrics< double > & avg_fj()
getAvgFJ(): the fork-join section metrics of the same solve, one row per Fork/Join pair (fj_sorted_pa...
solvers::FjMetrics< double > fj_
const std::string & get_name() const
getName(): the solver's own name, e.g.
AvgChain avg_chain()
getAvgChain(): the station table of the same solve aggregated by chain, (nstations x nchains).
solvers::CacheMetrics< double > cache_
std::string method_used()
getMethodUsed(): the method the solve actually resolved to.
AvgSysTable avg_sys_table()
getAvgSysTable(): per-chain system response time and throughput of the same solve.
std::vector< std::string > list_valid_methods() const
listValidMethods(): the methods this solver advertises on this model.
const AvgTable & avg_table()
getAvgTable(): the average table, solving on first demand.
std::vector< double > hit_ratio(const std::string &cache)
cache.getHitRatio() after the solve: the per-class hit probability at the named Cache,...
Network & model() const
The model this solver was built on.
void reset()
reset(): discard the cached solve.
NetworkSolver(Network &m, const std::string &name, const SolverOptions &o)
AvgChainTable avg_chain_table()
getAvgChainTable(): avg_chain() as a labelled table, one row per (station, chain).
A node of the model: the index it was given, and the model that owns it.
const std::string & get_name() const
getName().
NumericError(const std::string &what)
std::vector< std::string > proposed_solver_names(const std::string &getter="getAvg") const
delegate's retry order for that getter, as facade names; the chosen solver comes first.
static std::vector< std::string > family_names()
familyNames(): the method families, in the order a bare method name is looked up.
std::string choose_solver(const std::string &getter="getAvg") const
chooseSolver(getter): the facade name the configured method picks for that getter.
SolverBA ba_solver() const
baSolver(): the SolverBA the bound calls go to, method 'auto' unless a bound method was named.
static std::vector< std::string > metric_groups()
metricGroups(), metricGroupOf(name) and familyMetrics(family).
std::vector< std::string > list_all_methods() const
listAllMethods(): every method name the constructor accepts, independent of the model.
std::vector< std::vector< CdfCurve > > cdf_respt()
getCdfRespT(), delegated through the 'getCdfRespT' ranking.
static bool supports(Network &model)
supports(model): whether the model uses only features some family declares.
std::vector< std::string > candidate_solver_names() const
getCandidateSolverNames(): the facade names of the feasible candidates, in slot order.
SolverNC nc_solver() const
ncSolver(): the SolverNC the normalizing-constant calls go to.
SolverFLD fld_solver() const
fldSolver(): the SolverFLD the fluid-only calls go to.
std::string selected_solver_name()
getSelectedSolverName(): the facade name ("MVA", "FLD", ...) of the delegate that answered the last r...
SolverCTMC ctmc_solver() const
ctmcSolver(): the SolverCTMC the generator and state-space calls go to, with these options.
static std::vector< std::string > family_metrics(const std::string &family)
static std::string metric_group_of(const std::string &name)
static std::vector< std::string > feature_set()
getFeatureSet(): the union of the feature sets of SolverMVA, NC, CTMC, FLD, MAM, SSA,...
std::vector< AutoCandidate > find_solver(const std::string &metric=std::string(), bool show_all=false) const
findSolver(metric, showAll): which (family, method) pairs answer metric on this model.
std::string selected_method()
getSelectedMethod(): the method FAMILY of that delegate, lowercase ("mva", "fld").
bool is_stochastic()
isStochastic(): by the delegate that ran, else whether any candidate is a simulator.
TranAvg tran_avg()
getTranAvg(), delegated through the 'getTranAvg' ranking.
SolverAUTO(Network &m, const SolverOptions &o=SolverOptions())
double prob_aggr(std::size_t node, const std::vector< double > &state)
getProbAggr(node, state), delegated through the 'getProbAggr' ranking.
static std::vector< std::string > selection_intents()
selectionIntents().
SolverBA: the bounding solver, whose result is a bounds table.
BoundsTable bounds_table()
getBoundsTable(): the per-class queue-length and throughput bounds.
SolverBA(Network &m, const SolverOptions &o=SolverOptions())
SolverCTMC: the average table plus the chain it was computed from.
static void print_inf_gen(const Matrix< double > &Q, const Matrix< double > &space)
CTMC.printInfGen(Q, SS): the generator beside the state it belongs to.
Matrix< double > generator()
getGenerator(): the infinitesimal generator over that space.
double prob_aggr(std::size_t node, const std::vector< double > &state)
getProbAggr(node, state): the aggregate marginal of one state.
Matrix< double > state_space()
getStateSpace(): the aggregate state space, one row per state.
FirstPassage cdf_first_passt(const Matrix< double > &A, const Matrix< double > &B, const Matrix< double > &C=Matrix< double >(), const std::vector< double > &tset=std::vector< double >())
getCdfFirstPassT(A, B, C, tset): the FIRST PASSAGE TIME from the state set A into the state set B.
SolverCTMC(Network &m, const SolverOptions &o=SolverOptions())
SymbolicSolution symbolic_solution()
getSymbolicSolution(): the stationary law over the rate symbols x1..xE.
FirstPassageMoments first_passt_moments(const Matrix< double > &A, const Matrix< double > &B, std::size_t nmax=3, const Matrix< double > &C=Matrix< double >())
getFirstPassTMoments(A, B, nmax, C): moments of order 1..nmax of the same passage,...
std::vector< double > marg_aggr(std::size_t node)
getProbStateAggr(node): the marginal over every state of one station.
std::vector< std::vector< CdfCurve > > cdf_respt()
getCdfRespT(): the response-time CDF per (station, class).
Matrix< double > state_space_aggr()
getStateSpaceAggr(): per-(station, class) job counts of every state, in (ist-1)*K + k column order,...
SolverFLD: the fluid solver, which also answers a transient.
std::vector< std::vector< CdfCurve > > cdf_respt()
getCdfRespT(): the response-time CDF per (station, class).
TranAvg tran_avg()
getTranAvg(): the transient mean queue length per station.
SolverFLD(Network &m, const SolverOptions &o=SolverOptions())
TranAvg tran_avg()
getTranAvg(): E[N](t), averaged over options.config.replications (SolverOptions::replications,...
SolverJMT(Network &m, const SolverOptions &o=SolverOptions())
SamplePath sample(std::size_t events=0, std::size_t node=0)
sampleSysAggr(events), or sampleAggr(node, events) when node is given: one logged trajectory.
std::vector< std::vector< CdfCurve > > cdf_respt()
getCdfRespT(): the EMPIRICAL response-time CDF per (station, class).
double prob_aggr(std::size_t node, const std::vector< double > &state)
getProbAggr(node, state): the time the declared state is held for.
SolverLDES(Network &m, const SolverOptions &o=SolverOptions())
SolverLDES & init_from_jobs(const Matrix< double > &jobs)
initFromJobs(jobs): start from a job-level initial state, one row per job [station,...
std::vector< std::vector< CdfCurve > > cdf_respt()
getCdfRespT(): the EMPIRICAL response-time CDF per (station, class), from the per-job samples.
const Matrix< double > & job_departures()
The [id, station, class, time] of every departure of a tagged job, from the same run.
const Matrix< double > & final_jobs()
getFinalJobs(): the jobs present at the end of the run, in the init_from_jobs layout.
SolverLDES & init_from_solver(NetworkSolver &aux)
initFromSolver(initSolver): warm-start from an auxiliary solver's steady state.
double total(std::size_t node) const
s.at(node).total(): jobs of every class at a station node; a handle converts.
double at(std::size_t node, std::size_t cls) const
s.at(node, cls): jobs of class cls (1-based; a handle converts) at a station node.
StateView(const std::vector< double > &row, const qn::NetworkStruct< double > &sn)
UnsupportedError(const std::string &what)
std::vector< NodeDef > nodes
every node, in creation order
A subset of the registry: MATLAB's SolverFeatureSet, whose list is a flag per field.
std::vector< Feature > list() const
The features held, in registry order.
A network plus its refreshed NetworkStruct.
void set_state_prior(std::size_t node, const Matrix< T > &space, const std::vector< T > &prior)
StatefulNode.setStatePrior(space, prior): a distribution over the rows of a DECLARED state space.
const NetworkStruct< T > & get_struct()
The refreshed struct, MATLAB's model.getStruct().
The fluid solver's outermost entry point: @@SolverFLD/runAnalyzer.m's method resolution over solver_f...
The log-driven half of SolverJMT: linkAndLog, parseLogs, parseTranState, parseTranRespT,...
The LDES warm start: SolverLDES(model, initSolver) / initFromSolver.
The flat-Network path of @@SolverLQNS: its qns methods, served by qnsolver of the RADS/LQNS distribut...
Port of @NetworkSolver/mapEnvApprox.m: the solver-agnostic random-environment approximation of a netw...
The stage solvers map_env_approx injects, one per runner that can be a caller.
The method names of each solver, in listing order.
mva::AvgResult< T > solver_ag_run_analyzer(const qn::NetworkStruct< T > &L, const AgOptions &opt)
SolverAG.runAnalyzer: the converged agents as mean measures.
void sn_fj_nodevisits_mmt(qn::NetworkStruct< T > &sn)
Rewrite sn.nodevisits with the MMT correction.
ZeroCapacity sn_zero_capacity(const qn::NetworkStruct< T > &sn)
AutoSolver
The Network candidate slots, in the reference's slot order (SolverAUTO.m:41-50), which is also the or...
std::string auto_metric_group_of(const std::string &name)
The measure group an accessor belongs to, "" when the name belongs to none.
std::string auto_family_alias(const std::string &name)
SolverAUTO.familyAlias: the canonical family of a method name, or "" when the method name names none.
std::vector< std::string > auto_family_metrics(const std::string &family)
The measure groups a method family can answer.
std::vector< std::string > auto_metric_groups()
The measure groups auto_find_solver reports on, in report order.
const char * auto_solver_name(AutoSolver s)
AutoToken auto_resolve_token(const std::string &raw, const qn::NetworkStruct< T > &sn)
resolveMethodToken with its third arm: an intent, a family[.submethod], or else a BARE method name,...
std::vector< AutoSolver > auto_candidates(const qn::NetworkStruct< T > &sn)
The candidate pool in slot order, filtered by supports: what the delegate retries through after the c...
std::vector< AutoSolver > auto_proposed_solvers(const qn::NetworkStruct< T > &sn, const std::string &method, AutoMode mode)
delegate's proposed order: the chosen solver, then every feasible candidate in slot order.
AutoChoice auto_choose_solver_mode(const qn::NetworkStruct< T > &sn, const std::string &method, AutoMode mode)
chooseSolver: the selection mode picks the ranking, and every mode but the two learned ones keeps the...
std::vector< SolverCandidate > auto_find_solver(const qn::NetworkStruct< T > &sn, const std::string &metric=std::string(), bool show_all=false)
SolverAUTO.findSolver: which solvers and solver methods can analyze this model, and for the ones that...
std::vector< std::string > auto_list_valid_methods(const qn::NetworkStruct< T > &sn)
SolverAUTO.listValidMethods: every method name this model can be asked for.
BaBounds< T > ba_bounds(const qn::NetworkStruct< T > &L, const BaOptions &opt)
Port of SolverBA.getBounds.
mva::AvgResult< T > solver_ba_run_analyzer(const qn::NetworkStruct< T > &L, const BaOptions &opt_in)
Port of @@SolverBA/runAnalyzer.m for the lang='matlab' path.
std::vector< std::string > list_valid_methods()
Port of SolverBA.listValidMethods.
std::vector< std::string > list_valid_methods()
Port of SolverCTMC.listValidMethods.
CtmcGenerator< T > ctmc_get_infgen(const NetworkStruct< T > &sn, const CtmcSolution< T > &d)
@@SolverCTMC/getInfGen.m, a pure alias of getGenerator in the reference.
std::vector< std::vector< CdfCurve< T > > > solver_ctmc_cdf_respt(const NetworkStruct< T > &sn, const CtmcOptions &opt)
Port of @@SolverCTMC/getCdfRespT.m: the per-(station, class) response-time CDF, indexed [ist-1][r-1].
CtmcStateSpace< T > ctmc_get_state_space(const NetworkStruct< T > &, const CtmcSolution< T > &d)
Port of @@SolverCTMC/getStateSpace.m.
CtmcFirstPassageMoments< T > ctmc_firstpasst_moments(const NetworkStruct< T > &, const CtmcSolution< T > &d, const Matrix< double > &A, const Matrix< double > &B, std::size_t nmax, const Matrix< double > &C)
Port of @@SolverCTMC/getFirstPassTMoments.m: moments of order 1..nmax of the first passage time from ...
Matrix< T > ctmc_get_state_space_aggr(const NetworkStruct< T > &sn, const CtmcOptions &opt)
Port of @@SolverCTMC/getStateSpaceAggr.m: the per-(station, class) job counts of every state,...
CtmcFirstPassage ctmc_cdf_firstpasst(const NetworkStruct< T > &, const CtmcSolution< T > &d, const Matrix< double > &A, const Matrix< double > &B, const Matrix< double > &C, std::vector< double > tset, const std::string &method="expm")
Port of @@SolverCTMC/getCdfFirstPassT.m: the distribution of the FIRST PASSAGE TIME from state set A ...
CtmcSolution< T > solver_ctmc_analyzer(const NetworkStruct< T > &sn_in, const CtmcOptions &opt)
Port of solver_ctmc_analyzer.m plus the fork-join wrapper of @@SolverCTMC/runAnalyzer....
mva::AvgResult< T > solver_ctmc_mdd_run_analyzer(const NetworkStruct< T > &sn, const CtmcOptions &opt, const mdd::MddMcdOptions &mcdopt=mdd::MddMcdOptions())
Solve with mdd and format, so a caller with no use for the diagram has one call.
CtmcSymbolicSolution< T > ctmc_symbolic_solution(const NetworkStruct< T > &sn, const CtmcOptions &opt, const CtmcSymbolicOptions &symopt=CtmcSymbolicOptions())
Port of @@SolverCTMC/getSymbolicSolution.m: pi Q = 0 with sum(pi) = 1 over the field of rational func...
bool is_stateless_method(const std::string &method)
True for a method whose analyzer is not the explicit-generator one.
mva::AvgResult< T > solver_ctmc_run_analyzer_any(const NetworkStruct< T > &sn, const CtmcOptions &opt)
Solve on whichever path applies and format, mirroring solver_ctmc_run_analyzer.
std::vector< std::string > fluid_list_valid_methods()
Port of SolverFLD.listValidMethods.
std::vector< FluidTranPoint > solver_fluid_tran_avg(const qn::NetworkStruct< T > &sn, const FluidOptions &opt, std::size_t points=101)
getTranAvg on the first-order closing drift, over that horizon.
FluidSolution solver_fluid_run_analyzer(const qn::NetworkStruct< T > &sn, const FluidOptions &opt, qn::NetworkStruct< T > *sn_out=nullptr, qn::NetworkStruct< T > *refreshed_out=nullptr, solvers::CacheMetrics< T > *cache_out=nullptr)
Port of @@SolverFLD/runAnalyzer.m: resolve the method, route to the function the reference routes to,...
std::vector< std::vector< FluidPassage > > solver_fluid_cdf_respt(const qn::NetworkStruct< T > &sn, const FluidOptions &opt, std::size_t points=201)
Port of @@SolverFLD/getCdfRespT: the response-time law of every (station, class) pair,...
JmtReplication< T > jmt_transient_replications(const qn::NetworkStruct< T > &sn, const JmtOptions &opt)
Port of the transient ensemble of @@SolverJMT/runAnalyzer.m (default over a finite timespan).
JmtSysTrace< T > jmt_sample_sys_aggr(const qn::NetworkStruct< T > &sn, std::size_t num_events, const JmtOptions &opt)
Port of sampleSysAggr: every station's trajectory on one time grid.
JmtNodeTrace< T > jmt_sample_aggr(const qn::NetworkStruct< T > &sn, std::size_t node, std::size_t num_events, const JmtOptions &opt)
Port of sampleAggr: the queue-length trajectory of one node.
std::vector< std::string > jmt_list_valid_methods()
Port of SolverJMT.listValidMethods.
JmtResult< T > solver_jmt_run_analyzer(const qn::NetworkStruct< T > &sn, const JmtOptions &opt_in)
Port of @@SolverJMT/runAnalyzer.m, the jsim and jmva arms.
std::map< std::pair< std::size_t, std::size_t >, std::vector< std::pair< double, double > > > jmt_get_cdf_resp_t(const qn::NetworkStruct< T > &sn, const JmtOptions &opt, bool seed_from_steady=true)
Port of getCdfRespT: the empirical response-time distribution per (station, class),...
JmtProbAggr jmt_prob_aggr(const qn::NetworkStruct< T > &sn, const JmtOptions &opt, std::size_t target_station=0, const std::vector< double > &target=std::vector< double >())
Port of getProbAggr and getProbSysAggr, both off ONE instrumented run.
solvers::FjMetrics< double > ldes_fj_metrics(const qn::NetworkStruct< T > &sn, const LdesResult &r)
ldesParseForkJoin: the engine's "forkJoin" rows mapped onto the Fork/Join pairs of sn by (fork name,...
bool ldes_is_available()
True when this machine can run the engine at all, by either image.
std::vector< std::string > list_valid_methods()
Port of SolverLDES.listValidMethods.
Matrix< double > warm_start_placement_from_qlen(const qn::NetworkStruct< T > &sn, const Matrix< T > &QN)
Port of placementFromMeanQLen: an integer placement from mean queue lengths.
Matrix< double > ldes_cdf_respt(const LdesResult &r, std::size_t station, std::size_t job_class)
Port of getCdfRespT: the EMPIRICAL response time CDF of one (station, class) pair,...
Matrix< double > warm_start_placement_from_ctmc(const qn::NetworkStruct< T > &sn, const ctmc::CtmcOptions &opt)
Port of placementFromCtmcSteadyState: the mode of the aggregate stationary law.
LdesResult solver_ldes(const qn::NetworkStruct< T > &sn, const LdesOptions &o, const std::vector< std::string > &extra_flags=std::vector< std::string >())
std::string name(const Element *el, const std::string &key="name")
mva::AvgResult< T > solve_network_run_analyzer(const qn::NetworkStruct< T > &L, const QnsOptions &opt)
Port of @@SolverLQNS/runAnalyzerNetwork.m and solver_qns.m: SolverLQNS on a flat Network.
bool qnsolver_is_available()
Port of SolverLQNS.hasQnsolver: a native qnsolver binary on the PATH.
std::vector< std::string > list_valid_methods()
Port of SolverMAM.listValidMethods.
mva::AvgResult< T > solver_mam_run_analyzer(const qn::NetworkStruct< T > &L, const MamOptions &opt)
Port of @@SolverMAM/runAnalyzer.m for the lang='matlab' path: solve, then apply the metric filter @@N...
std::vector< std::string > methods(const std::string &solver)
Every method name the solver can be asked for, in listing order.
Matrix< T > sn_get_residt_from_respt(const qn::NetworkStruct< T > &L, const Matrix< T > &RN)
Port of sn_get_residt_from_respt: the per-JOB residence time.
std::string resolve_method(const qn::NetworkStruct< T > &L, const std::string &method)
Port of SolverMVA.resolveMethod: the feature-driven default -> rqna upgrade for a bursty single-class...
std::vector< std::string > list_valid_methods(const qn::NetworkStruct< T > &L)
Port of SolverMVA.listValidMethods.
Matrix< T > sn_get_arvr_from_tput(const qn::NetworkStruct< T > &L, const Matrix< T > &TN)
Port of sn_get_arvr_from_tput: the arrival rate each station sees, from the throughputs and the class...
AvgResult< T > solver_mva_run_analyzer(const qn::NetworkStruct< T > &L, const MvaOptions &opt_in, const Matrix< T > &init_sol)
Port of @@SolverMVA/runAnalyzer.m for the lang='matlab' path: gate, solve, convert,...
mva::AvgResult< T > solver_nc_run_analyzer(const qn::NetworkStruct< T > &L_in, const NcSolverOptions &opt_in)
std::vector< std::string > list_valid_methods()
Port of SolverNC.listValidMethods.
std::vector< std::vector< T > > from_marginal(const NetworkStruct< T > &sn, std::size_t ist, const std::vector< std::size_t > &n, const std::vector< std::size_t > &phases)
FeatureSet ldes_feature_set(const std::string &)
SolverLDES.getFeatureSet, transcribed WHOLE.
FeatureSet fluid_feature_set(const std::string &method)
FeatureSet ssa_feature_set(const std::string &method)
FeatureSet jmt_feature_set(const std::string &method)
Port of SolverJMT.getFeatureSet (@@SolverJMT/SolverJMT.m:180-290).
FeatureSet used_lang_features(const NetworkStruct< T > &sn)
FeatureSet nc_feature_set(const std::string &method)
SolverNC.getFeatureSet, 48 names, transcribed unchanged.
FeatureSet fluid_class_feature_set()
SolverFLD.getFeatureSet, transcribed, MINUS what the requested method cannot evaluate – the port of @...
FeatureSet ctmc_feature_set(const std::string &method)
SolverCTMC.getFeatureSet, the reference's 104 MATLAB names in full.
SupportResult feature_set_supports(const std::string &solver, const FeatureSet &declared, const FeatureSet &used)
SolverFeatureSet.supports: is every feature the model uses declared?
FeatureSet mam_feature_set(const std::string &method)
SolverMAM.getFeatureSet, the union of its four setTrue calls: 55 MATLAB names, WIDENED for 'default'/...
FeatureSet mva_feature_set(const std::string &raw_method)
SolverMVA.getFeatureSet, plus getMethodFeatureSet's per-method deltas.
const char * feature_name(Feature f)
The canonical registry name, byte for byte the MATLAB field name.
MapEnvDecision needs_map_env(const qn::FeatureSet &declared, const qn::NetworkStruct< T > &sn, const MapEnvConfig &cfg=MapEnvConfig())
needsMapEnv: does this model need the environment image, and would the image make it solvable?
CacheMetrics< T > cache_metrics_of(const qn::NetworkStruct< T > &sn, const std::vector< T > &hitprob, const std::vector< T > &missprob, const std::vector< T > &delayedprob, const std::vector< T > &latency, const Matrix< T > &hitproblist, const Matrix< T > &itemprob, const std::vector< T > &listcost)
Assemble CacheMetrics from what a cache analyzer returned.
void cache_mark_nonreading(const qn::NetworkStruct< T > &sn, CacheNodeMetrics< T > &m)
A CLASS THAT DOES NOT READ THE CACHE READS NaN, in every solver and every codebase (BUG-101): NaN is ...
std::vector< std::string > chain_class_labels(const qn::NetworkStruct< T > &sn)
(ClassA ClassB), the JobClasses column: which classes a chain holds.
env::EnvStageAvgFn< double > nc_stage_fn(const nc::NcSolverOptions &opt)
NC stages, bound to the caller's own NcSolverOptions.
SysResult< T > solver_get_avg_sys(const qn::NetworkStruct< T > &sn, const mva::AvgResult< T > &r)
Port of @@NetworkSolver/getAvgSys.m.
mva::AvgResult< T > run_avg(const qn::NetworkStruct< T > &sn, const std::string &solver, const qn::FeatureSet &declared, const MapEnvConfig &cfg, Run run, StageFn stage_fn, const std::string &requested_method="default")
The getAvg funnel: run the model, or its environment image when the ONLY thing in the way is a non-re...
ChainResult< T > solver_get_avg_chain(const qn::NetworkStruct< T > &sn, const mva::AvgResult< T > &r)
Port of @@NetworkSolver/getAvgChain.m: the station table aggregated by chain.
mva::AvgResult< T > map_env_approx(const qn::NetworkStruct< T > &sn, const std::string &solver, const MapEnvConfig &cfg, StageFn stage_fn, const std::string &requested_method="default")
mapEnvApprox: solve the model through the random-environment image of its non-renewal processes.
std::vector< std::string > chain_names(std::size_t nchains)
Chain1, Chain2, ... – the reference's own chain labels.
env::EnvStageAvgFn< double > fluid_stage_fn(const fluid::FluidOptions &opt)
Fluid stages, bound to the caller's own FluidOptions.
env::EnvStageAvgFn< double > mva_stage_fn(const mva::MvaOptions &opt)
MVA stages, bound to the caller's own MvaOptions.
std::vector< std::string > list_valid_methods()
Port of SolverSSA.listValidMethods.
SsaSolution solver_ssa(const qn::NetworkStruct< T > &sn, const SsaOptions &opt, std::vector< SsaCacheRatio > *cache=nullptr)
qn::NetworkStruct< T > sn_with_ssa_cache_split(const qn::NetworkStruct< T > &base, const std::vector< SsaCacheRatio > &cache)
@@SolverSSA/runAnalyzer itself: the engine the method selects, then the result assembly the reference...
solvers::CacheMetrics< T > cache_metrics_of_ssa(const qn::NetworkStruct< T > &sn, const std::vector< SsaCacheRatio > &cache)
CacheMetrics from the serial engine's cache write-back.
Conservation laws of a layered queueing network, enumerated from its structure.
qn::Network< double > Network
Network as a user names it: the double model, Python's Network.
std::ostream & operator<<(std::ostream &out, const AvgTable &table)
std::function< bool(const StateView &)> StatePredicate
A STATE SET named by a predicate, the reference's function-handle form, e.g.
The model API a user writes, spelled as its Python twin.
Post-MMT node visits of a fork-join model.
Port of matlab/src/api/sn/sn_zero_capacity.m: the closed chains trapped at a zero-capacity station.
The solver API a user writes, spelled as its Python twin.
The SolverAUTO chooser: which solver a model is handed to.
The SolverBA class surface: @@SolverBA/runAnalyzer.m, listValidMethods, getBounds and getBoundsTable.
The CHAIN-level and SYSTEM-level views of a solved model.
Port of solver_ctmc_analyzer.m and the parts of @@SolverCTMC/runAnalyzer.m that surround one solve: t...
Port of @@SolverCTMC/getCdfRespT.m and @@SolverCTMC/getCdfSysRespT.m: the exact distribution of the r...
The remaining @@SolverCTMC accessors: getGenerator / getInfGen, getStateSpace / getStateSpaceAggr and...
The mdd method of SolverCTMC: stationary analysis of a closed single-class network whose state space ...
The SolverCTMC probability family: solver_ctmc_joint, _jointaggr, _marg, _margaggr,...
Port of @@SolverCTMC/getSymbolicGenerator and getSymbolicSolution.
Port of solver_ctmc_fcr_waitq.m: the reachability-built generator of a model whose finite capacity re...
SolverFluid: the closing method, a port of solver_fluid.m, solver_fluid_iteration....
Port of SolverJMT, the Java Modelling Tools client.
Port of SolverLDES, the discrete-event simulator, as its C++ client.
The SolverMAM class surface: @@SolverMAM/runAnalyzer.m and the gates around it.
The SolverMVA class surface: @@SolverMVA/runAnalyzer.m and the gates around it.
The SolverNC class surface: @@SolverNC/runAnalyzer.m and the gates around it.
The SolverSSA entry surface: a port of @@SolverSSA/runAnalyzer.m's method whitelist,...
Port of the MATLAB +State package: the encoding that turns a station's state row into marginal job co...
One row of SolverAUTO::find_solver: a (family, method) pair and whether this model can run it.
bool runnable
the model passes this method's own support gate
std::string solver
the method family: "mva", "ctmc", "ldes", ...
std::string method
the qualified method name to pass, "mva.exact"
std::string method_class
"exact", "approx", "bound" or "simulation"
std::string reason
why a refused pair was refused, "" when runnable
std::string metrics
the measure groups the family answers, comma-joined
getAvgChainTable: the station table aggregated by CHAIN, one row per (station, chain),...
std::vector< double > QLen
std::vector< double > ArvR
std::vector< double > RespT
std::vector< double > Util
std::vector< double > ResidT
void print(std::ostream &out) const
Print the station-chain table.
std::vector< std::string > Chain
std::vector< std::string > JobClasses
std::vector< std::string > Station
std::vector< double > Tput
getAvgChain(): the station x chain matrices, @NetworkSolver/getAvgChain.m's outputs.
getAvgFJTable(): one row per (Fork/Join pair, class) with a nonzero metric, the fork-join SECTION met...
std::vector< std::string > Fork
void print(std::ostream &out) const
Print the labelled pair-class table.
std::vector< double > FJTput
std::vector< std::string > JobClass
std::vector< double > FJRespT
std::vector< double > FJQLen
std::vector< std::string > Join
getAvgSysTable(): one row per CHAIN, the cycle time and the completing throughput at the chain's refe...
std::vector< double > SysRespT
void print(std::ostream &out) const
Print the chain table.
std::vector< std::string > JobClasses
std::vector< double > SysTput
std::vector< std::string > Chain
getAvgTable, one row per (station, class) that carries a metric.
std::vector< double > ArvR
std::vector< double > TputCI
std::vector< double > UtilCI
std::vector< double > Tput
std::vector< double > ResidT
void print(std::ostream &out) const
Print the labelled station-class table.
std::vector< double > RespT
std::size_t size() const
The number of rows the table carries.
std::vector< double > Util
std::vector< std::string > Station
std::vector< double > column(const std::string &column) const
A complete metric column.
std::vector< double > SysTput
bool has_ci() const
Whether the half-width columns are filled.
std::vector< double > ResidTCI
std::vector< std::string > JobClass
std::string warning
The reference's own warning text, empty when it did not warn.
double get(const std::string &column, const std::string &station, const std::string &jobclass) const
One cell of the table, by station and class NAME; NaN when absent.
std::vector< double > QLenCI
Confidence half-widths of the six metric columns, row for row; EMPTY unless SolverOptions::confint as...
AvgTable tget(const Node &node) const
AvgTable filter_by(const std::string &name) const
Rows whose station or class has name, MATLAB's one-argument filterBy.
std::vector< double > RespTCI
std::vector< double > ArvRCI
AvgTable operator()(const Node &node) const
Direct object indexing: table(queue, jobs).
std::vector< double > ListCost
getAvgCacheTable's ListCost column; empty on a model without item sizes.
std::vector< double > SysRespT
std::vector< std::string > SysClass
getAvgSysTable: system response time and throughput, per class.
std::vector< double > QLen
SolverBA(model, method).getBoundsTable().
std::vector< double > Tlower
std::vector< double > Qupper
std::vector< std::string > Station
std::vector< double > Qlower
std::vector< std::string > JobClass
std::vector< double > Tupper
The <kind> part of a LINE:<category>:<kind> identifier (see _kb/17-error-vocabulary....
getFirstPassTMoments(A, B, nmax, C): [m, mall, p] with the resolved sets.
std::vector< double > m
moments 1..nmax from A (conditional on B before C)
getCdfFirstPassT(A, B, C, tset): the curve, the reach probabilities and the resolved sets.
std::vector< double > t
the grid: the caller's, else 1000 points to the horizon
sampleSysAggr / sampleAggr: ONE simulated trajectory, not a mean.
std::vector< std::vector< double > > state
[step][column]
std::vector< std::string > label
what each column counts
std::vector< double > t
event times, ascending
The knobs a solver reads; a negative or empty field keeps the engine default.
double warmupfrac
options.warmupfrac, in [0,1): LDES under tranfilter=fixed, and SSA's discarded prefix.
Matrix< double > init_jobs
LDES options.init_jobs: one row per job, [station, class, remaining, elapsed, qage,...
int level
SolverBA options.level.
bool track_jobs
LDES options.track_jobs: return the end-of-run job state; implied by init_jobs.
bool cache
options.cache: reuse the solved tables on later calls to the same solver object.
std::string tranfilter
LDES options.tranfilter: mser5 | fixed | none; empty keeps mser5.
getSymbolicSolution: the stationary law as a function of the rate symbols.
std::vector< double > rate0
nominal value of each symbol
std::string den
common denominator of the vector
std::vector< std::string > pi
stationary probability of each state
std::vector< std::string > symbols
x1..xE, empty where an event has no positive rate
std::string engine
backend that answered, e.g. "sage"
std::vector< std::string > num
numerator of each entry over den
getTranAvg: the transient mean queue length per (station, class).
std::vector< std::string > label
the (station, class) of each column
std::vector< std::vector< double > > QNt
[step][station*class]
std::vector< double > t
the time axis
What sn_zero_capacity reports.
std::string reason
Non-empty when the model has no steady state of this form: an open class reaches a zero-capacity stat...
bool any() const
True when some chain is trapped.
What a ranking resolved to, and what it had to skip to get there.
resolveMethodToken, minus the unqualified-algorithm-name arm.
Port of SolverBA.getBounds: the {lower,upper} bracket of a family.
std::vector< std::vector< bool > > keep
getBoundsTable's row filter, (M x K): whether the (station, class) pair earns a row.
Matrix< T > Qupper
(M x K), all-NaN on a side the family lacks
The options SolverBA reads.
The answer of @@SolverCTMC/getFirstPassTMoments.m.
The answer of @@SolverCTMC/getCdfFirstPassT.m: the [F(t), t] curve with its grid, density and resolve...
The SolverCTMC knobs this port honours.
Everything one CTMC solve produces.
std::shared_ptr< const NetworkStruct< T > > solved_sn
The struct the chain was built on, when it differs from the caller's in its state LAYOUT: set when he...
std::vector< T > pi
stationary distribution over chain.space
Backend selection, mirroring options.config.symbolic and its timeout.
std::string backend
auto to search, a URL, an image name, or none to stay local.
What @@SolverCTMC/getSymbolicSolution.m returns, plus the engine that answered.
std::string engine
backend that solved it, e.g. sage
std::vector< T > rate0
Nominal value of each symbol, i.e.
std::vector< std::string > symbols
x1..xE, empty for an event with no positive rate.
std::vector< std::string > num
numerator of each entry over den
std::vector< std::string > pi
stationary probability of each state
std::string den
common denominator of the vector
Controls, defaulting to SolverOptions('Fluid') in the reference.
What the analyzer returns, in the same shape as the MVA solver's result.
The per-class queue-length trajectory of one node, plus its event stream.
The options of one JMT solve, SolverOptions('JMT') restricted to what is read.
std::string method
default | jsim | jmva | jmva.<alg>
What jmt_prob_aggr reports: the system probability and the per-station ones.
std::vector< double > station
P(station i holds its declared per-class counts).
Transient averages over independent replications, on one time grid.
std::vector< std::vector< std::vector< double > > > QNt
QNt[ist-1][r] over t.
The result of a JMT solve: the shared AvgResult plus what only JMT reports.
The system trajectory: one per-class block per station, on a common grid.
The knobs of one LDES run.
One ldes-result document, parsed.
std::vector< std::vector< std::vector< double > > > respTimeSamples
[station][class] -> the per-job response times the engine recorded.
Matrix< double > jobDepartures
[id, station, class, time] of every departure of a tagged init_jobs job (track_jobs).
Matrix< double > finalJobs
The jobs present at the end of the run, in the init_jobs layout (track_jobs).
SolverLQNS.defaultOptions on a flat Network plus the knobs the JMVA document carries.
The options SolverMAM reads.
The metrics getAvg returns, after filtering.
Matrix< T > RN
response time, per visit
Matrix< T > UN
utilization
Matrix< T > WN
residence time, per job
std::string method
the method asked for
Matrix< T > QN
queue length
Matrix< T > AN
arrival rate
The options SolverMVA reads.
Controls, defaulting to SolverOptions('NC') in the reference.
Every Cache node of the model, in node order; empty on a model with none.
std::vector< CacheNodeMetrics< T > > caches
One Cache node's measured behaviour.
std::vector< T > hitprob
(K) TRUE hit fraction, EMPTY = not computed
The station- or node-level table aggregated by chain.
Matrix< T > TN
(rows x nchains), rows = stations or nodes
self.result.FJ: one row per Fork/Join pair, one column per class.
The caller-facing map_env knobs, options.config.map_env and friends.
What the gate decided, and what it decided it about.
@@NetworkSolver/getAvgSys: one response time and one throughput per chain.
std::vector< T > XN
(nchains) system throughput at the reference station
std::vector< T > CN
(nchains) system response time, i.e. the cycle time
Controls, defaulting to SolverOptions('SSA') in the reference.
What the analyzer returns, in the same shape as the MVA and fluid results.