LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Loading...
Searching...
No Matches
solver_mva_cacheqn_retrieval.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_SOLVERS_MVA_SOLVER_MVA_CACHEQN_RETRIEVAL_H
6#define LINE_SOLVERS_MVA_SOLVER_MVA_CACHEQN_RETRIEVAL_H
7
8/**
9 * @file
10 * @ingroup line_solvers
11 * Port of `solver_mva_cacheqn_retrieval_analyzer.m`: a CLOSED integrated
12 * cache-queueing model whose Cache carries a delayed-hit retrieval system.
13 *
14 * THIS FILE IS GLUE, and the twin of `solver_nc_cacheqn_retrieval.h`. All the
15 * work is in `da_cacheqn_retrieval`, which alternates the isolated-cache solve
16 * with the network solve; this supplies only the NETWORK SOLVER and unpacks the
17 * result. The two analyzers differ in that one line and in nothing else, which
18 * is why the driver takes `netfun` as its only handle: the isolated-cache miss
19 * algorithm is `cache_miss_fpi` in both, and both report `method = 'fpi'`.
20 *
21 * THE LOAD-DEPENDENT BRANCH IS NOT OPTIONAL. The driver installs a
22 * coupon-collector `lldscaling` on the fetch station before the first sweep, so
23 * `netsolve`'s scaling test is true on every call and the network solve is
24 * always `solver_mvald_analyzer`. The `solver_mva_analyzer` arm is kept because
25 * the reference keeps it -- it is what runs if a future driver stops installing
26 * the scaling -- not because a model reaches it today.
27 *
28 * THE THREE-WAY SPLIT COLLAPSES ON THIS PATH, deliberately. The reference
29 * reports `hitprob` as P(item cached) and folds the delayed-hit fraction into
30 * `missprob`, returning `delayedprob = 0`. Only the OPEN analyzer
31 * (`solver_mva_retrieval.h`) separates true hits from delayed hits. That is why
32 * `hitproblist` and `latency` are NaN here and there is no `itemprob`: they are
33 * quantities this path does not compute, and reporting a number for them would
34 * be inventing one.
35 *
36 * EXPERIMENTAL, in the reference's own words (`da_cacheqn_retrieval.m`,
37 * LIMITATIONS): the coalescing throughput benefit is captured in DIRECTION and
38 * understated in magnitude, and no closed retrieval example ships in the suite.
39 * The port reproduces the method rather than repairing it, so a closed model
40 * should be validated against LDES before its absolute numbers are trusted.
41 *
42 * ARITHMETIC: transcendental. The fixed point stops on a tolerance and the
43 * coupon-collector rate is a real power, so this refuses under Rational by name.
44 */
45
46#include <cstddef>
47#include <functional>
48#include <limits>
49#include <vector>
50
55#include "line/util/error.h"
56#include "line/util/matrix.h"
57
58namespace line {
59namespace mva {
60
61/** What the closed delayed-hit analyzer returns. */
62template <class T>
65 std::vector<T> hitprob; ///< (K) P(item cached), read class only
66 std::vector<T> missprob; ///< (K) the delayed fraction is folded in here
67 std::vector<T> delayedprob; ///< (K) zero on this path, by the reference's convention
68 std::vector<T> latency; ///< (K) NaN: not computed on this path
69 Matrix<T> hitproblist; ///< (K x h) NaN: not computed on this path
70};
71
72/**
73 * Port of `solver_mva_cacheqn_retrieval_analyzer.m`.
74 *
75 * @param L the refreshed struct; one Cache with a retrieval system, closed
76 * @param opt solver controls
77 */
78template <class T>
80 const MvaOptions& opt) {
82 if constexpr (!num_traits<T>::has_transcendental) {
83 (void)L;
84 (void)opt;
85 throw UnsupportedError(
86 "solver_mva_cacheqn_retrieval_analyzer: the closed delayed-hit decomposition alternates "
87 "two tolerance-stopped solves and needs transcendental arithmetic; rerun with --arith "
88 "double or --arith real");
89 } else {
90 const T nanT = num_traits<T>::from_double(std::numeric_limits<double>::quiet_NaN());
91 const std::size_t K = L.nclasses;
92 const MvaOptions netopt = opt;
93
94 // `netsolve` of the reference: the load-dependent analyzer whenever the
95 // struct carries scaling, which after the driver's first mutation it
96 // always does. The call is resolved by ADL at instantiation, as in
97 // solver_mva_cacheqn.h, so that this header does not have to include
98 // mva_dispatch.h and close a cycle with it.
99 std::function<MvaSolution<T>(const qn::NetworkStruct<T>&)> netfun =
100 [netopt](const qn::NetworkStruct<T>& snit) -> MvaSolution<T> {
101 bool has_scaling = false;
102 for (const auto& st : snit.stations)
103 if (!st.lldscaling.empty() || st.cdscaling) has_scaling = true;
104 MvaOptions o = netopt;
105 if (has_scaling) return solver_mvald_analyzer(snit, o, Matrix<T>()).sol;
106 return solver_mva_analyzer(snit, o, Matrix<T>());
107 };
108
110
111 out.sol = r.res;
112 out.sol.iter = static_cast<int>(r.iter);
113 // The reference reports 'fpi' here: the isolated-cache miss is
114 // cache_miss_fpi on this path in BOTH solvers, so the name records the
115 // algorithm that decided the split rather than the network method.
116 out.sol.method = "fpi";
117 out.hitprob = r.hitprob;
118 out.missprob = r.missprob;
119 out.delayedprob = r.delayedprob;
120 out.latency.assign(K, nanT);
121 std::size_t h = 0;
122 for (const auto& kv : L.nodeparam)
123 if (kv.second.itemcap.size() > h) h = kv.second.itemcap.size();
124 out.hitproblist = Matrix<T>(K, h, nanT);
125 return out;
126 }
127}
128
129} // namespace mva
130} // namespace line
131
132#endif // LINE_SOLVERS_MVA_SOLVER_MVA_CACHEQN_RETRIEVAL_H
UnsupportedError(const std::string &what)
Definition error.h:51
A network plus its refreshed NetworkStruct.
std::map< std::size_t, CacheParam< T > > nodeparam
Cache parameters by 1-based NODE index; only Cache nodes have an entry.
Decomposition-aggregation driver for a CLOSED integrated cache-queueing model whose Cache carries a d...
The exception types the port throws.
Dense matrix and non-owning view.
The option and result types every MVA analyzer shares.
CacheqnRetrievalResult< T > da_cacheqn_retrieval(qn::NetworkStruct< T > sn, const std::function< mva::MvaSolution< T >(const qn::NetworkStruct< T > &)> &netfun, const mva::MvaOptions &opt)
Port of da_cacheqn_retrieval.
DispatchResult< T > solver_mvald_analyzer(const qn::NetworkStruct< T > &L, const MvaOptions &opt, const Matrix< T > &init_sol)
Port of solver_mvald_analyzer.m: the load-dependent branch.
MvaCacheqnRetrievalSolution< T > solver_mva_cacheqn_retrieval_analyzer(const qn::NetworkStruct< T > &L, const MvaOptions &opt)
Port of solver_mva_cacheqn_retrieval_analyzer.m.
MvaSolution< T > solver_mva_analyzer(const qn::NetworkStruct< T > &L, const MvaOptions &opt, const Matrix< T > &init_sol)
Port of solver_mva_analyzer.m, default and the explicit method names.
A queueing network and its refreshed NetworkStruct.
SolverMVA over a SolverLN layer.
What the delayed-hit decomposition returns.
std::vector< T > hitprob
(K) P(item cached), read class only
std::vector< T > delayedprob
(K) zero on this path; see the header
What the closed delayed-hit analyzer returns.
std::vector< T > delayedprob
(K) zero on this path, by the reference's convention
Matrix< T > hitproblist
(K x h) NaN: not computed on this path
std::vector< T > missprob
(K) the delayed fraction is folded in here
std::vector< T > latency
(K) NaN: not computed on this path
std::vector< T > hitprob
(K) P(item cached), read class only
The options SolverMVA reads.
Definition mva_types.h:31
Class-level results, the [Q,U,R,T,C,X] of the MATLAB analyzers.
Definition mva_types.h:96