![]() |
LINE Solver (C++)
Templated C++ port of the LINE queueing solver
|
Port of solver_mam_fj.m, the fork-join route of SolverMAM. More...
#include <cmath>#include <cstddef>#include <string>#include <type_traits>#include <vector>#include "line/api/fj/fj_codes.h"#include "line/api/fj/fj_dist2fj.h"#include "line/api/sn/sn_join_droprate.h"#include "line/api/mam/map_moment.h"#include "line/lang/distribution.h"#include "line/lang/qn/network_struct.h"#include "line/solvers/mam/mam_types.h"#include "line/util/error.h"Go to the source code of this file.
Classes | |
| struct | line::mam::MamFjInfo |
| What fj_is_homogeneous.m returns: the fork-join pair, or why there is none. More... | |
| struct | line::mam::MamFjParams< T > |
| What fj_extract_params.m returns: one arrival and one service per class. More... | |
Namespaces | |
| namespace | line |
| namespace | line::mam |
Functions | |
| template<class T> | |
| MamFjInfo | line::mam::mam_fj_is_homogeneous (const qn::NetworkStruct< T > &L) |
| Port of fj_is_homogeneous.m. | |
| template<class T> | |
| MamFjParams< T > | line::mam::mam_fj_extract_params (const qn::NetworkStruct< T > &L, const MamFjInfo &info) |
| Port of fj_extract_params.m: the arrival descriptor from the Source and the service descriptor from the first branch, per class. | |
| const std::vector< double > & | line::mam::mam_fj_stored_percentiles () |
| The four percentiles solver_mam_fj.m stores for getPerctRespT. | |
| const std::vector< double > & | line::mam::mam_fj_dense_percentiles () |
| The 21-point grid solver_mam_fj.m inverts for the MEAN, [0.01:0.05:0.95,
0.99, 0.999]. | |
| template<class T> | |
| mva::MvaSolution< T > | line::mam::solver_mam_fj (const qn::NetworkStruct< T > &L, const MamOptions &opt, std::vector< std::vector< T > > *percentiles_out) |
| Port of solver_mam_fj.m. | |
| template<class T> | |
| mva::MvaSolution< T > | line::mam::solver_mam_fj (const qn::NetworkStruct< T > &L, const MamOptions &opt) |
| solver_mam_fj.m without the percentile side channel. | |
| template<class T> | |
| std::vector< std::vector< T > > | line::mam::solver_mam_fj_percentiles (const qn::NetworkStruct< T > &L, const MamOptions &opt, const std::vector< double > &percentiles) |
| @@SolverMAM/getPerctRespT.m's fork-join path: the percentiles solver_mam_fj.m stores in percResults.RT, one row per class, at the four levels mam_fj_stored_percentiles() names. | |
Port of solver_mam_fj.m, the fork-join route of SolverMAM.
The reference analyzer is a THIN WRAPPER around one third-party engine: mainFJ of matlab/lib/thirdparty/FJ_codes, the response-time-tail approximation of Z. Qiu, J. F. Perez and P. Harrison, "Beyond the Mean in Fork-Join Queues: Efficient Approximation for Response-Time Tails" (IFIP Performance 2015). Everything solver_mam_fj.m computes on its own is either a topology check or an M/M/1 closed form; the one quantity that makes it a FORK-JOIN analyzer – the synchronisation delay charged at the Join – is mainFJ's mean response time minus the branch response time.
WHAT IS PORTED HERE: the gate, the parameter extraction and the wrapper, i.e. fj_is_homogeneous.m, fj_extract_params.m (on top of the already- ported api/fj/fj_dist2fj.h) and solver_mam_fj.m itself. mam_fj_is_homogeneous is the 2a predicate of solver_mam_analyzer.m and is what separates the fork-join models this analyzer claims from the ones that go to solver_mam_basic_mmap.
THE ENGINE IS api/fj/fj_codes.h and api/fj/fj_codes_matrices.h: mainFJ and the chain it drives – returnRT1, returnRT2, computeT, computeT_NARE, constructSRK, build_SA, computePi, returnWait, returnPer, generateService. It is double only, because the T matrix is the stable invariant subspace of a Riccati pencil (ordered real Schur) and the two Sylvester equations are of order (C + 1) m^2 ma; this file refuses by name at any other arithmetic.
WHY THE MMT TRANSFORM IS NOT SUBSTITUTED FOR IT. mva/fj_mmt.h plus mva/fj_driver.h do solve fork-join models, and driving them with solver_mam_basic as the inner solve would produce a full metric tuple. It would not be this analyzer's tuple, and on this analyzer's models it would not be sound either: fj_mmt REUSES the model's own Source and Sink when it has them and adds a pair only for a closed layer, so on an open model the auxiliary stream is injected at the SAME Source that carries the real open chain – the transform then reports one merged arrival stream where this analyzer's decomposition keeps the branch streams apart. The transform is exercised by SolverMVA and SolverNC on CLOSED layers, which is the case it was written for. Reporting its output as solver_mam_fj would be a different algorithm on a corrupted struct, under the reference's method name.
WHAT THE api/fj/ FAMILY IS NOT. This codebase does carry ported fork-join approximations – fj_synch_delay, fj_respt_2way, fj_respt_nt, fj_respt_varki, fj_respt_vm, fj_rmax, fj_order_stat. They are DIFFERENT published approximations. Substituting one of them for mainFJ would answer the model under a method name that promises the Qiu-Perez- Harrison tail estimate, which is precisely the substitution solver_mam_runner.h refuses to make for non-Markovian service.
REFERENCE DEFECTS in solver_mam_fj.m. 1, 2 and 4 are reproduced – they are what the reference reports and changing them would answer differently under its method name; 3 is not, see solver_mam_fj for why that is not a change of result:
ARITHMETIC. fj_dist2fj needs one linear solve per process and stays in the field, so the GATE and the EXTRACTION hold at every instantiation and an unsupported topology or distribution is still named exactly at Rational. The ENGINE is double only and solver_mam_fj refuses past that point, which is why the two checks run before the arithmetic gate rather than after it.
Definition in file solver_mam_fj.h.