67 double lambda_override = -1.0) {
71 for (
const auto& kv :
sn.nodeparam)
72 if (
sn.nodes[kv.first - 1].nodetype == qn::NodeType::Cache) {
73 if (ci != 0)
throw InputError(
"cache_retrieval_inputs: more than one Cache node");
76 if (ci == 0)
throw InputError(
"cache_retrieval_inputs: no Cache node");
79 throw InputError(
"cache_retrieval_inputs: the Cache has no retrieval system");
81 throw UnsupportedError(
"cache_retrieval_inputs: a single read class is supported");
85 const std::size_t n = ch.
nitems, h = ch.
itemcap.size(), K =
sn.nclasses;
88 const std::size_t jobin = rd0 + 1;
92 const std::size_t S =
qn.size();
93 if (S == 0)
throw InputError(
"cache_retrieval_inputs: the retrieval system has no stations");
97 if (lambda_override >= 0.0) {
100 const std::size_t src_st =
sn.stations[
sn.sourceIdx - 1].nodetype == qn::NodeType::Source
103 if (src_st == 0)
throw InputError(
"cache_retrieval_inputs: open model needs a Source");
104 readRate =
sn.disabled[src_st - 1][jobin - 1] ? zero :
sn.rates(src_st - 1, jobin - 1);
106 const std::vector<T>& pread = ch.
pread[jobin - 1];
107 out.
lambda.assign(n, zero);
108 for (std::size_t i = 0; i < n; ++i) out.
lambda[i] = T(readRate * pread[i]);
112 for (std::size_t i = 0; i < n; ++i)
113 for (std::size_t l = 0; l <= h; ++l) lam3d(i, l) = out.
lambda[i];
114 std::vector<std::vector<Matrix<T> > > Rcost(1, std::vector<
Matrix<T> >());
115 if (!ch.
accost.empty() && !ch.
accost[jobin - 1].empty()) {
116 Rcost[0] = ch.
accost[jobin - 1];
119 Rcost[0].resize(n,
Matrix<T>(h + 1, h + 1, zero));
120 for (std::size_t k = 0; k < n; ++k) {
128 std::vector<RetrievalStationType> stype(S);
129 for (std::size_t s = 0; s < S; ++s) {
130 const std::size_t st =
sn.nodes[
qn[s] - 1].station;
131 switch (
sn.stations[st - 1].sched) {
139 "cache_retrieval_inputs: a retrieval station uses an unsupported scheduling "
140 "policy (only IS/PS/SIRO/FCFS/LCFSPR)");
146 for (std::size_t s = 0; s < S; ++s) out.
station[s].type = stype[s];
147 std::vector<std::size_t> fsz(S, 0);
148 for (std::size_t s = 0; s < S; ++s) {
149 const std::size_t st =
sn.nodes[
qn[s] - 1].station;
156 "cache_retrieval_inputs: SIRO/FCFS retrieval stations need exponential service");
161 out.
R.assign(n,
Matrix<T>(S + 1, S + 1, zero));
162 auto lin = [&](std::size_t node, std::size_t cls) {
return (node - 1) * K + (cls - 1); };
163 for (std::size_t i = 0; i < n; ++i) {
165 for (std::size_t s = 0; s < S; ++s) {
166 const std::size_t st =
sn.nodes[
qn[s] - 1].station;
170 for (std::size_t a = 0; a < fsz[s]; ++a) {
171 out.
station[s].alpha(i, a) = pie[a];
172 for (std::size_t b = 0; b < fsz[s]; ++b) out.
station[s].sub[i](a, b) = D0(a, b);
175 for (std::size_t s = 0; s < S; ++s) {
176 out.
R[i](0, s + 1) =
sn.rtnodes(lin(ci, rcls), lin(
qn[s], rcls));
177 out.
R[i](s + 1, 0) =
sn.rtnodes(lin(
qn[s], rcls), lin(ci, rcls));
178 for (std::size_t sp = 0; sp < S; ++sp)
179 out.
R[i](s + 1, sp + 1) =
sn.rtnodes(lin(
qn[s], rcls), lin(
qn[sp], rcls));
184 std::vector<std::size_t> isIdx, psIdx;
185 for (std::size_t s = 0; s < S; ++s)
187 const std::size_t r = psIdx.size();
189 for (std::size_t i = 0; i < n; ++i) {
192 std::vector<T> a(S, zero);
193 for (std::size_t s = 0; s < S; ++s) {
194 a[s] = out.
R[i](0, s + 1);
195 for (std::size_t sp = 0; sp < S; ++sp)
199 std::vector<T> visits(S, zero);
200 for (std::size_t s = 0; s < S; ++s) {
202 for (std::size_t sp = 0; sp < S; ++sp) acc = T(acc + a[sp] * F(sp, s));
205 std::vector<T> tau(S, zero);
206 for (std::size_t s = 0; s < S; ++s) {
208 for (std::size_t a = 0; a < fsz[s]; ++a) arow(0, a) = out.
station[s].alpha(i, a);
209 tau[s] = detail::ph_mean(arow, out.
station[s].sub[i]);
212 for (std::size_t s : isIdx) is_sum = T(is_sum + visits[s] * tau[s]);
213 out.
eta(i, 0) = is_sum;
214 for (std::size_t p = 0; p < r; ++p) out.
eta(i, 1 + p) = T(visits[psIdx[p]] * tau[psIdx[p]]);