LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Loading...
Searching...
No Matches
lqn_struct.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2012-2026, QORE Lab, Imperial College London
3 * All rights reserved.
4 */
5#ifndef LINE_LANG_LQN_LQN_STRUCT_H
6#define LINE_LANG_LQN_LQN_STRUCT_H
7
8/**
9 * @file
10 * @ingroup line_lang
11 * LayeredNetworkStruct, the flattened description of a layered queueing network.
12 *
13 * Port of matlab/src/lang/layered/LayeredNetworkStruct.m and of the fields that
14 * matlab/src/lang/layered/@@LayeredNetwork/getStruct.m populates. Only the
15 * fields SolverLN and SolverMVA read are carried; the process-descriptor
16 * families (hostdem_proc, itemproc, setuptime, delayofftime) exist in MATLAB to
17 * serve solvers this port does not have and are omitted rather than filled with
18 * placeholders.
19 *
20 * INDEXING. Element indices are 1-based and live in one flat space shared by
21 * the four element kinds, exactly as in MATLAB:
22 *
23 * hosts 1 .. nhosts (hshift = 0)
24 * tasks tshift+1 .. tshift+ntasks (tshift = nhosts)
25 * entries eshift+1 .. eshift+nentries (eshift = nhosts+ntasks)
26 * activities ashift+1 .. ashift+nacts (ashift = eshift+nentries)
27 *
28 * with nidx = ashift + nacts and cshift = nidx, so a call index cidx is
29 * addressed as nidx+cidx inside the entry-service matrix. Calls are numbered
30 * separately, 1..ncalls. Vectors are sized nidx+1 (or ncalls+1) and slot 0 is
31 * unused; this keeps every index expression identical to the reference, which
32 * is worth more here than the one wasted slot, because the arithmetic on these
33 * indices (parent-of-parent to reach a host, aidx-ashift to reach a phase) is
34 * dense and a systematic off-by-one would be silent.
35 *
36 * ARITHMETIC. Means, think times and call multiplicities are T. Element
37 * multiplicities, replication counts and job populations are `double`, matching
38 * MATLAB: they are counts, they can be infinite (an inf-scheduled task), and
39 * they enter the solvers as integer populations, so nothing is gained by
40 * carrying them in the exact type and the infinity would have to be emulated.
41 */
42
43#include <cmath>
44#include <map>
45#include <string>
46#include <unordered_map>
47#include <utility>
48#include <vector>
49
51#include "line/num/number.h"
52#include "line/util/error.h"
53#include "line/util/matrix.h"
54
55namespace line {
56namespace lqn {
57
58using lang::CallType;
59using lang::CdScaling;
60using lang::Distrib;
65
66/**
67 * Heterogeneous server pools declared on a layer server, the twin of the
68 * `nservertypes` / `servertypenames` / `serverspertype` / `servercompat` /
69 * `heterorates` block a Network carries in `sn.nodeparam{i}`.
70 *
71 * `compat(t, j)` is nonzero when pool t may serve OPERAND j -- task j of a host,
72 * entry j of a task, in declaration order, the same operand space the
73 * class- and joint-dependence handles read. SolverLN lowers the pools to the
74 * activated-server rate mu(n) = sum_t counts(t)*rates(t)*[pool t compatible with
75 * some operand present], which is order-independent, and hands it to the layer
76 * station as a joint dependence; see _kb/06-solver-catalog.md (LN section).
77 */
78template <class T>
80 std::vector<std::string> names; ///< (npools) declared pool name
81 std::vector<double> counts; ///< (npools) servers held by each pool
82 std::vector<T> rates; ///< (npools) per-pool rate multiplier
83 Matrix<T> compat; ///< (npools x noperands), nonzero = eligible
84
85 bool empty() const { return names.empty(); }
86 std::size_t npools() const { return names.size(); }
87};
88
89/**
90 * A sparse square matrix over element indices, held as a dense vector of rows
91 * with an explicit nonzero list per row.
92 *
93 * The LQN graph is very sparse (each activity has one or two successors) and
94 * the algorithms walk it by "successors of i", never by column, except for
95 * `find(graph(:,j))` in the reply search and `find(taskgraph(:,t))` in the
96 * multiplicity correction. Both column queries are rare, so they scan.
97 */
98template <class T>
100 std::size_t n = 0;
101 std::vector<std::vector<std::pair<std::size_t, T>>> row; ///< 1-based, row[0] unused
102
103 void resize(std::size_t nn) {
104 n = nn;
105 row.assign(nn + 1, {});
106 }
107 void set(std::size_t i, std::size_t j, const T& v) {
108 for (auto& e : row[i])
109 if (e.first == j) {
110 e.second = v;
111 return;
112 }
113 row[i].emplace_back(j, v);
114 }
115 T get(std::size_t i, std::size_t j) const {
116 for (const auto& e : row[i])
117 if (e.first == j) return e.second;
118 return num_traits<T>::from_int(0);
119 }
120 /** Successors of i in ascending index order, as MATLAB's find() returns them. */
121 std::vector<std::size_t> succ(std::size_t i) const {
122 std::vector<std::size_t> out;
123 const T zero = num_traits<T>::from_int(0);
124 for (const auto& e : row[i])
125 if (e.second != zero) out.push_back(e.first);
126 std::sort(out.begin(), out.end());
127 return out;
128 }
129 /** Predecessors of j in ascending index order. */
130 std::vector<std::size_t> pred(std::size_t j) const {
131 std::vector<std::size_t> out;
132 const T zero = num_traits<T>::from_int(0);
133 for (std::size_t i = 1; i <= n; ++i)
134 for (const auto& e : row[i])
135 if (e.first == j && e.second != zero) {
136 out.push_back(i);
137 break;
138 }
139 return out;
140 }
141 void erase(std::size_t i, std::size_t j) {
142 for (std::size_t k = 0; k < row[i].size(); ++k)
143 if (row[i][k].first == j) {
144 row[i].erase(row[i].begin() + k);
145 return;
146 }
147 }
148};
149
150/** A boolean sparse relation over element indices, e.g. iscaller. */
151struct BoolGraph {
152 std::size_t n = 0;
153 std::vector<std::vector<std::size_t>> row;
154
155 void resize(std::size_t nn) {
156 n = nn;
157 row.assign(nn + 1, {});
158 }
159 void set(std::size_t i, std::size_t j) {
160 for (std::size_t v : row[i])
161 if (v == j) return;
162 row[i].push_back(j);
163 }
164 bool get(std::size_t i, std::size_t j) const {
165 for (std::size_t v : row[i])
166 if (v == j) return true;
167 return false;
168 }
169 bool any_row(std::size_t i) const { return !row[i].empty(); }
170 bool any_col(std::size_t j) const {
171 for (std::size_t i = 1; i <= n; ++i)
172 if (get(i, j)) return true;
173 return false;
174 }
175 std::vector<std::size_t> col(std::size_t j) const {
176 std::vector<std::size_t> out;
177 for (std::size_t i = 1; i <= n; ++i)
178 if (get(i, j)) out.push_back(i);
179 return out;
180 }
181};
182
183/** One activity precedence of a task, with its activities resolved to indices. */
184template <class T>
186 PrecedenceType pretype = PrecedenceType::PRE_SEQ;
187 PrecedenceType posttype = PrecedenceType::POST_SEQ;
188 std::vector<std::size_t> preacts; ///< absolute activity indices
189 std::vector<std::size_t> postacts; ///< absolute activity indices
190 std::vector<T> preparams; ///< PRE_OR shares, or a PRE_AND quorum
191 std::vector<T> postparams; ///< POST_OR probabilities or the POST_LOOP count
192};
193
194/**
195 * One routed call group: an activity, the strategy that picks among its
196 * targets, and the target ENTRIES in declaration order.
197 *
198 * Not a template: it holds no numeric parameter, the per-target call means
199 * living on the member calls in `callproc` as usual.
200 */
202 std::size_t caller = 0; ///< absolute index of the dispatching activity
204 std::vector<std::size_t> targets; ///< absolute entry indices, in declaration order
205};
206
207template <class T>
208struct LqnStruct {
209 std::size_t nidx = 0, nhosts = 0, ntasks = 0, nentries = 0, nacts = 0, ncalls = 0;
210 std::size_t hshift = 0, tshift = 0, eshift = 0, ashift = 0, cshift = 0;
211
212 std::vector<std::string> names; ///< (nidx+1) declared name
213 std::vector<std::string> hashnames; ///< (nidx+1) name prefixed by kind: P:/T:/R:/E:/A:
214 std::vector<LqnElement> type; ///< (nidx+1)
215 std::vector<std::size_t> parent; ///< (nidx+1) host of a task, task of an entry/activity
216 std::vector<SchedStrategy> sched; ///< (tshift+ntasks+1)
217 std::vector<double> mult; ///< (tshift+ntasks+1) declared multiplicity, may be Inf
218 std::vector<double> maxmult; ///< (tshift+ntasks+1) sustainable multiplicity
219 std::vector<double> repl; ///< (tshift+ntasks+1) replication
220
221 /**
222 * Queue-dependent service rates declared on a layer server (a host or a
223 * task), by element index, empty where absent.
224 *
225 * `lldscaling[i]` is the vector alpha(n) applied at total population n;
226 * `cdscaling[i]` and `jdscaling[i]` are the per-OPERAND handles beta(n) and
227 * eta(n), whose argument counts the jobs the layer station holds on behalf
228 * of task j of a host or entry j of a task, in declaration order. The peak
229 * vectors are required beside the handles, since utilization at such a
230 * station is reported as U = T*S/peak. `pools` carries a compatibility
231 * declaration, which SolverLN lowers to a jdscaling of its own.
232 *
233 * Only the class-switching layer builders emit these; the composed
234 * phase-type law replaces the station by an entry law and so refuses them
235 * by name -- see _kb/04-networkstruct.md and _kb/06-solver-catalog.md.
236 */
237 std::vector<std::vector<T>> lldscaling; ///< (tshift+ntasks+1)
238 std::vector<CdScaling<T>> cdscaling; ///< (tshift+ntasks+1)
239 std::vector<std::vector<T>> cdscalingpeak; ///< (tshift+ntasks+1)
240 std::vector<CdScaling<T>> jdscaling; ///< (tshift+ntasks+1)
241 std::vector<std::vector<T>> jdscalingpeak; ///< (tshift+ntasks+1)
242 std::vector<ServerPools<T>> pools; ///< (tshift+ntasks+1)
243
244 /**
245 * Fan-out and fan-in, keyed by task element index, absent = 0.
246 *
247 * `fanout[{caller, callee}]` is how many callee replicas one caller replica
248 * addresses, and is read by SolverLN to decide whether a replicated task
249 * layer can be pooled into a single station instead of materialised once
250 * per replica (`getStruct.m` builds the same matrix as `lsn.fanout`).
251 * `fanin` is the mirror declaration and is carried for round-trip fidelity
252 * only: no analyzer in ANY codebase reads it, MATLAB and the JAR likewise
253 * park it on the Task and never consult it.
254 */
255 std::map<std::pair<std::size_t, std::size_t>, double> fanout;
256 std::map<std::pair<std::size_t, std::size_t>, double> fanin;
257
258 /** fan-out from caller task `i` to callee task `j`; 0 when undeclared. */
259 double fanout_at(std::size_t i, std::size_t j) const {
260 const std::map<std::pair<std::size_t, std::size_t>, double>::const_iterator it =
261 fanout.find(std::make_pair(i, j));
262 return it == fanout.end() ? 0.0 : it->second;
263 }
264
265 std::vector<bool> isref; ///< (tshift+ntasks+1)
266 std::vector<bool> iscache; ///< (tshift+ntasks+1)
267 std::vector<bool> hassetup; ///< (tshift+ntasks+1)
268
269 /**
270 * Cache tasks and item entries.
271 *
272 * `nitems` is indexed by ELEMENT and carries the item population on BOTH
273 * the cache task and each of its item entries, which is how getStruct.m
274 * writes it (`iscache` is the nitems>0 test, over hosts+tasks only).
275 * `itemcap` is the capacity of each cache list, so a plain single-level
276 * cache has one entry. `itemproc` is the item POPULARITY of an item entry,
277 * as an explicit pmf over its `nitems`: the reference stores a discrete
278 * Distribution (a Zipf, typically) and only ever reads its pmf, and this
279 * port has no discrete-distribution type to put there.
280 */
281 std::vector<std::size_t> nitems; ///< (nidx+1)
282 std::vector<std::vector<int>> itemcap; ///< (tshift+ntasks+1)
283 std::vector<ReplacementStrategy> replacestrat; ///< (tshift+ntasks+1)
284 std::vector<std::vector<T>> itemproc; ///< (nidx+1) popularity pmf
285
286 /**
287 * Setup tasks: the server powers down when idle and pays to restart.
288 *
289 * (tshift+ntasks+1); `hassetup` is the "a setup time is declared and is
290 * neither Immediate nor sub-tolerance" test, matching how the reference
291 * gates the feature in LQN2QN's functionTimesOf rather than the bare
292 * ~isempty of getStruct.
293 */
294 std::vector<Distrib<T>> setuptime;
295 std::vector<Distrib<T>> delayofftime;
296
297 std::vector<Distrib<T>> hostdem; ///< (nidx+1) host demand per activity (Immediate elsewhere)
298 std::vector<Distrib<T>> think; ///< (nidx+1) task think time
299 std::vector<Distrib<T>> actthink; ///< (nidx+1) activity think time
300 std::vector<bool> has_arrival; ///< (nidx+1) entry with an open arrival
301 std::vector<Distrib<T>> arrival; ///< (nidx+1) open arrival process of an entry
302
303 std::vector<std::vector<std::size_t>> tasksof; ///< (nhosts+1)
304 std::vector<std::vector<std::size_t>> entriesof; ///< (tshift+ntasks+1)
305 std::vector<std::vector<std::size_t>> actsof; ///< (ashift+1) by task and by entry
306 std::vector<std::vector<std::size_t>> callsof; ///< (nidx+1) call indices issued by an activity
307
308 std::vector<std::size_t> callpair_src; ///< (ncalls+1) calling activity (entry for FWD)
309 std::vector<std::size_t> callpair_dst; ///< (ncalls+1) called entry
310 std::vector<CallType> calltype; ///< (ncalls+1)
311 std::vector<T> callproc_mean; ///< (ncalls+1) mean number of calls
312 std::vector<std::string> callnames; ///< (ncalls+1)
313 std::vector<std::string> callhashnames; ///< (ncalls+1)
314
315 SparseGraph<T> graph; ///< element call/precedence graph, edge weights are branch shares
316 SparseGraph<T> dag; ///< graph with entry-task edges reversed and loop back-edges removed
317 SparseGraph<T> taskgraph; ///< task-to-task calls
319
320 /**
321 * Admission constraint `A n <= b` on the layer station of a host or task.
322 *
323 * (tshift+ntasks+1); an empty A means unconstrained. The COLUMNS are that
324 * host's tasks (`tasksof`) or that task's entries (`entriesof`), in that
325 * order -- element space, not class space. SolverLN::build_layer expands
326 * them into the layer's own classes and emits a Region on the server, an
327 * entry column becoming the CALL classes that target it and a task column
328 * the ACTIVITY classes of that task. Carried by the JSON interchange as
329 * `admissionConstraints`, NOT by .lqnx. See _kb/04-networkstruct.md.
330 */
331 std::vector<Matrix<T>> lincon_A;
332 std::vector<std::vector<T>> lincon_b;
333
334 /**
335 * Activity precedences of each task, as DECLARED, indexed by the task's
336 * absolute index.
337 *
338 * `graph` is the same information after the reader has expanded it into
339 * arcs, and that expansion is lossy for a loop: the back edge carries the
340 * branch PROBABILITY 1 - 1/count, so recovering the count from it inverts a
341 * division and loses the distinction between a loop and an ordinary cycle.
342 * SolverLN method 'srvn.ph' composes the activity graph into a phase-type law
343 * instead of routing it, and needs the count, so it reads this. Every other
344 * consumer reads `graph`.
345 */
346 std::vector<std::vector<LqnPrecedence<T>>> precedences; ///< (tshift+ntasks+1)
347
348 /**
349 * Synchronous calls DISPATCHED AS A GROUP, `lsn.callgroups`.
350 *
351 * `synchCallRoundRobin` / `synchCallJSQ` issue one call per invocation whose
352 * destination cycles over, or is chosen among, several target entries. The
353 * members are ordinary SYNC calls of mean `total/n` and are already in
354 * `callpair`; what this adds is that they are ONE dispatch decision rather
355 * than n independent Bernoulli draws, which is the whole point -- the mean
356 * call rate is the same and the variance is not.
357 *
358 * Representable only under the squashed layering, since the targets must
359 * share a submodel for a dispatch among them to mean anything, and only
360 * under a layer solver that resolves the strategy from the state.
361 */
362 std::vector<LqnCallGroup> callgroups;
363
364 std::vector<PrecedenceType> actpretype; ///< (nidx+1)
365 std::vector<PrecedenceType> actposttype; ///< (nidx+1)
366 std::vector<std::size_t> actquorum; ///< (nidx+1) AND-join quorum, on the join target
367 std::vector<int> actphase; ///< (nacts+1) phase of each activity, 1-based by act
368
369 /** Index of the host of the element, for a task or anything owned by one. */
370 std::size_t host_of(std::size_t idx) const {
371 if (type[idx] == LqnElement::HOST) return idx;
372 if (type[idx] == LqnElement::TASK) return parent[idx];
373 return parent[parent[idx]];
374 }
375};
376
377} // namespace lqn
378} // namespace line
379
380#endif // LINE_LANG_LQN_LQN_STRUCT_H
The exception types the port throws.
Enumerations and the minimal distribution descriptor shared by the model layer of the C++ port.
Dense matrix and non-owning view.
SchedStrategy
Scheduling disciplines, with the values of MATLAB SchedStrategy.
Definition lang_types.h:181
PrecedenceType
Activity precedence kinds, with the values of MATLAB ActivityPrecedenceType.
Definition lang_types.h:470
LqnElement
LQN element kinds, with the values of MATLAB LayeredNetworkElement.
Definition lang_types.h:464
RoutingStrategy
Routing strategies, with the values of MATLAB RoutingStrategy.
Definition lang_types.h:389
CallType
Call kinds, with the values of MATLAB CallType.
Definition lang_types.h:467
std::function< std::vector< T >(const std::vector< T > &)> CdScaling
A class-dependent scaling map, sn.cdscaling.
Definition lang_types.h:639
ReplacementStrategy
Cache replacement policies, with the values of MATLAB ReplacementStrategy.
Definition lang_types.h:378
Number-type abstraction for the templated API port.
A boolean sparse relation over element indices, e.g.
Definition lqn_struct.h:151
void set(std::size_t i, std::size_t j)
Definition lqn_struct.h:159
bool any_row(std::size_t i) const
Definition lqn_struct.h:169
std::vector< std::size_t > col(std::size_t j) const
Definition lqn_struct.h:175
bool any_col(std::size_t j) const
Definition lqn_struct.h:170
bool get(std::size_t i, std::size_t j) const
Definition lqn_struct.h:164
void resize(std::size_t nn)
Definition lqn_struct.h:155
std::vector< std::vector< std::size_t > > row
Definition lqn_struct.h:153
One routed call group: an activity, the strategy that picks among its targets, and the target ENTRIES...
Definition lqn_struct.h:201
std::vector< std::size_t > targets
absolute entry indices, in declaration order
Definition lqn_struct.h:204
lang::RoutingStrategy strategy
Definition lqn_struct.h:203
std::size_t caller
absolute index of the dispatching activity
Definition lqn_struct.h:202
One activity precedence of a task, with its activities resolved to indices.
Definition lqn_struct.h:185
std::vector< std::size_t > preacts
absolute activity indices
Definition lqn_struct.h:188
std::vector< T > preparams
PRE_OR shares, or a PRE_AND quorum.
Definition lqn_struct.h:190
std::vector< T > postparams
POST_OR probabilities or the POST_LOOP count.
Definition lqn_struct.h:191
PrecedenceType pretype
Definition lqn_struct.h:186
std::vector< std::size_t > postacts
absolute activity indices
Definition lqn_struct.h:189
PrecedenceType posttype
Definition lqn_struct.h:187
BoolGraph isasynccaller
Definition lqn_struct.h:318
std::vector< Distrib< T > > hostdem
(nidx+1) host demand per activity (Immediate elsewhere)
Definition lqn_struct.h:297
std::vector< std::vector< T > > jdscalingpeak
(tshift+ntasks+1)
Definition lqn_struct.h:241
std::vector< int > actphase
(nacts+1) phase of each activity, 1-based by act
Definition lqn_struct.h:367
std::vector< CallType > calltype
(ncalls+1)
Definition lqn_struct.h:310
std::vector< std::size_t > callpair_dst
(ncalls+1) called entry
Definition lqn_struct.h:309
std::vector< std::vector< LqnPrecedence< T > > > precedences
Activity precedences of each task, as DECLARED, indexed by the task's absolute index.
Definition lqn_struct.h:346
std::size_t host_of(std::size_t idx) const
Index of the host of the element, for a task or anything owned by one.
Definition lqn_struct.h:370
std::vector< std::string > callhashnames
(ncalls+1)
Definition lqn_struct.h:313
std::vector< Distrib< T > > setuptime
Setup tasks: the server powers down when idle and pays to restart.
Definition lqn_struct.h:294
std::map< std::pair< std::size_t, std::size_t >, double > fanout
Fan-out and fan-in, keyed by task element index, absent = 0.
Definition lqn_struct.h:255
std::vector< bool > hassetup
(tshift+ntasks+1)
Definition lqn_struct.h:267
std::vector< LqnElement > type
(nidx+1)
Definition lqn_struct.h:214
std::vector< std::size_t > nitems
Cache tasks and item entries.
Definition lqn_struct.h:281
std::vector< Distrib< T > > actthink
(nidx+1) activity think time
Definition lqn_struct.h:299
std::vector< std::vector< T > > lldscaling
Queue-dependent service rates declared on a layer server (a host or a task), by element index,...
Definition lqn_struct.h:237
std::vector< double > mult
(tshift+ntasks+1) declared multiplicity, may be Inf
Definition lqn_struct.h:217
std::vector< SchedStrategy > sched
(tshift+ntasks+1)
Definition lqn_struct.h:216
std::vector< std::size_t > callpair_src
(ncalls+1) calling activity (entry for FWD)
Definition lqn_struct.h:308
std::vector< std::size_t > parent
(nidx+1) host of a task, task of an entry/activity
Definition lqn_struct.h:215
std::vector< std::vector< T > > lincon_b
Definition lqn_struct.h:332
std::vector< ServerPools< T > > pools
(tshift+ntasks+1)
Definition lqn_struct.h:242
std::vector< T > callproc_mean
(ncalls+1) mean number of calls
Definition lqn_struct.h:311
std::vector< std::size_t > actquorum
(nidx+1) AND-join quorum, on the join target
Definition lqn_struct.h:366
std::vector< bool > iscache
(tshift+ntasks+1)
Definition lqn_struct.h:266
std::vector< bool > has_arrival
(nidx+1) entry with an open arrival
Definition lqn_struct.h:300
std::vector< std::vector< std::size_t > > callsof
(nidx+1) call indices issued by an activity
Definition lqn_struct.h:306
std::size_t nentries
Definition lqn_struct.h:209
std::vector< std::string > hashnames
(nidx+1) name prefixed by kind: P:/T:/R:/E:/A:
Definition lqn_struct.h:213
std::vector< std::string > callnames
(ncalls+1)
Definition lqn_struct.h:312
std::vector< CdScaling< T > > cdscaling
(tshift+ntasks+1)
Definition lqn_struct.h:238
std::vector< std::vector< int > > itemcap
(tshift+ntasks+1)
Definition lqn_struct.h:282
std::vector< std::vector< std::size_t > > entriesof
(tshift+ntasks+1)
Definition lqn_struct.h:304
double fanout_at(std::size_t i, std::size_t j) const
fan-out from caller task i to callee task j; 0 when undeclared.
Definition lqn_struct.h:259
std::vector< double > repl
(tshift+ntasks+1) replication
Definition lqn_struct.h:219
std::vector< std::string > names
(nidx+1) declared name
Definition lqn_struct.h:212
std::vector< Matrix< T > > lincon_A
Admission constraint A n <= b on the layer station of a host or task.
Definition lqn_struct.h:331
SparseGraph< T > dag
graph with entry-task edges reversed and loop back-edges removed
Definition lqn_struct.h:316
std::vector< Distrib< T > > think
(nidx+1) task think time
Definition lqn_struct.h:298
std::vector< std::vector< std::size_t > > tasksof
(nhosts+1)
Definition lqn_struct.h:303
std::vector< bool > isref
(tshift+ntasks+1)
Definition lqn_struct.h:265
std::vector< PrecedenceType > actpretype
(nidx+1)
Definition lqn_struct.h:364
std::vector< std::vector< std::size_t > > actsof
(ashift+1) by task and by entry
Definition lqn_struct.h:305
std::map< std::pair< std::size_t, std::size_t >, double > fanin
Definition lqn_struct.h:256
std::vector< PrecedenceType > actposttype
(nidx+1)
Definition lqn_struct.h:365
std::vector< LqnCallGroup > callgroups
Synchronous calls DISPATCHED AS A GROUP, lsn.callgroups.
Definition lqn_struct.h:362
std::vector< std::vector< T > > cdscalingpeak
(tshift+ntasks+1)
Definition lqn_struct.h:239
std::vector< Distrib< T > > delayofftime
Definition lqn_struct.h:295
std::vector< Distrib< T > > arrival
(nidx+1) open arrival process of an entry
Definition lqn_struct.h:301
std::vector< std::vector< T > > itemproc
(nidx+1) popularity pmf
Definition lqn_struct.h:284
std::vector< CdScaling< T > > jdscaling
(tshift+ntasks+1)
Definition lqn_struct.h:240
std::vector< ReplacementStrategy > replacestrat
(tshift+ntasks+1)
Definition lqn_struct.h:283
std::vector< double > maxmult
(tshift+ntasks+1) sustainable multiplicity
Definition lqn_struct.h:218
SparseGraph< T > graph
element call/precedence graph, edge weights are branch shares
Definition lqn_struct.h:315
SparseGraph< T > taskgraph
task-to-task calls
Definition lqn_struct.h:317
Heterogeneous server pools declared on a layer server, the twin of the nservertypes / servertypenames...
Definition lqn_struct.h:79
Matrix< T > compat
(npools x noperands), nonzero = eligible
Definition lqn_struct.h:83
std::vector< double > counts
(npools) servers held by each pool
Definition lqn_struct.h:81
std::vector< std::string > names
(npools) declared pool name
Definition lqn_struct.h:80
std::vector< T > rates
(npools) per-pool rate multiplier
Definition lqn_struct.h:82
std::size_t npools() const
Definition lqn_struct.h:86
A sparse square matrix over element indices, held as a dense vector of rows with an explicit nonzero ...
Definition lqn_struct.h:99
std::vector< std::size_t > succ(std::size_t i) const
Successors of i in ascending index order, as MATLAB's find() returns them.
Definition lqn_struct.h:121
void erase(std::size_t i, std::size_t j)
Definition lqn_struct.h:141
std::vector< std::vector< std::pair< std::size_t, T > > > row
1-based, row[0] unused
Definition lqn_struct.h:101
void resize(std::size_t nn)
Definition lqn_struct.h:103
T get(std::size_t i, std::size_t j) const
Definition lqn_struct.h:115
void set(std::size_t i, std::size_t j, const T &v)
Definition lqn_struct.h:107
std::vector< std::size_t > pred(std::size_t j) const
Predecessors of j in ascending index order.
Definition lqn_struct.h:130