LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
cache_retrieval_inputs.m
1%{ @file cache_retrieval_inputs.m
2 % @brief Extract delayed-hit retrieval kernel inputs from a NetworkStruct
3 %
4 % @author LINE Development Team
5%}
6
7%{
8 % @brief Builds the inputs of the retrieval (delayed-hit) analytic kernels from a model
9 %
10 % @details
11 % Given the NetworkStruct of a cache equipped with a retrieval system
12 % (Cache.setRetrievalSystem), reconstructs the inputs required by the
13 % retrieval_* kernels (retrieval_nc, retrieval_metrics, retrieval_fpi,
14 % retrieval_fpi_latency):
15 %
16 % m cache list capacities (1 x h)
17 % lambda per-item arrival rates (1 x n) = sourceRate * pread
18 % gamma access factors gamma_{i,j} (n x h) via cache_gamma_lp
19 % eta fetching demands eta_{s,i} (n x (r+1)) col 1 = IS, cols 2.. = PS
20 % alpha cell(1,S); alpha{s}(1,:,i) PH entry vector of item i at station s
21 % T cell(1,S); T{s}(:,:,i) PH subgenerator of item i at station s
22 % R (S+1) x (S+1) x n routing matrices (index 1 = cache/outside,
23 % 2..S+1 = retrieval stations), R(a,b,i) probability a->b for item i
24 % station_type (1 x S) string per retrieval station, one of "IS", "PS",
25 % "SIRO", "FCFS", "LCFSPR" (mapped from sn.sched)
26 %
27 % The retrieval system is single-class (IRM): exactly one read class may route
28 % into the retrieval system. Supported retrieval scheduling policies are IS,
29 % PS, SIRO, FCFS and LCFSPR. IS is independent; PS, SIRO, FCFS and LCFSPR use
30 % the mean-field sharing slowdown. PS and LCFSPR (symmetric/insensitive BCMP
31 % disciplines) admit general phase-type service and class-dependent rates;
32 % SIRO and FCFS require exponential service with identical per-class rates.
33 % Any other scheduling policy raises an error, matching retrieval_fpi_latency.
34 %
35 % @par Syntax:
36 % @code
37 % [m,lambda,gamma,eta,alpha,T,R,station_type] = cache_retrieval_inputs(sn)
38 % @endcode
39%}
40function [m,lambda,gamma,eta,alpha,T,R,station_type] = cache_retrieval_inputs(sn)
41
42ci = find(sn.nodetype == NodeType.Cache);
43if numel(ci) ~= 1
44 line_error(mfilename, 'Retrieval analysis requires exactly one Cache node.');
45end
46ch = sn.nodeparam{ci};
47if ~isfield(ch, 'retrievalSystemCapacity') || ch.retrievalSystemCapacity <= 0
48 line_error(mfilename, 'The Cache node has no retrieval system (call setRetrievalSystem).');
49end
50
51m = ch.itemcap(:).';
52n = ch.nitems;
53h = numel(m);
54K = sn.nclasses;
55
56% --- read class (single-class IRM) ---
57rk = keys(ch.retrievalSystemQueueIndices);
58if numel(rk) ~= 1
59 line_error(mfilename, 'Retrieval analysis supports a single read class.');
60end
61jobinClass = double(rk{1}) + 1; % stored 0-indexed
62queueNodes = ch.retrievalSystemQueueIndices(rk{1});
63queueNodes = double(queueNodes(:).');
64S = numel(queueNodes);
65if S == 0
66 line_error(mfilename, 'The retrieval system has no stations.');
67end
68
69% --- per-item arrival rates lambda(i) = sourceRate * pread(i) ---
70source_ist = sn.nodeToStation(sn.nodetype == NodeType.Source);
71sourceRate = sn.rates(source_ist, jobinClass);
72if isnan(sourceRate), sourceRate = 0; end
73pread = ch.pread{jobinClass};
74lambda = sourceRate * pread(:).'; % 1 x n
75
76% --- gamma via the existing plain-cache utility (n x h) ---
77lambda3d = zeros(1, n, h);
78for k = 1:n
79 for l = 1:(h+1)
80 lambda3d(1, k, l) = lambda(k);
81 end
82end
83Rcost = ch.accost;
84if isempty(Rcost)
85 % Default linear cache routing: item flows from list l to list l+1.
86 Rcost = cell(1, n);
87 for k = 1:n
88 Rmat = diag(ones(1, h), 1);
89 Rmat(h+1, h+1) = 1;
90 Rcost{1, k} = Rmat;
91 end
92end
93gamma = cache_gamma_lp(lambda3d, Rcost); % n x h
94
95% --- station types (IS / PS / SIRO / FCFS) ---
96% SIRO and FCFS are treated as PS: for exponential service the tagged-job sojourn
97% is Exp(mu/(1+phitilde)), identical to PS (see retrieval_fpi_latency). The
98% exponential requirement is enforced below once phase sizes are known; FCFS also
99% requires class-independent rates (checked below).
100station_type = strings(1, S);
101for s = 1:S
102 sst = sn.nodeToStation(queueNodes(s));
103 if sn.sched(sst) == SchedStrategy.INF
104 station_type(s) = "IS";
105 elseif sn.sched(sst) == SchedStrategy.PS
106 station_type(s) = "PS";
107 elseif sn.sched(sst) == SchedStrategy.SIRO
108 station_type(s) = "SIRO";
109 elseif sn.sched(sst) == SchedStrategy.FCFS
110 station_type(s) = "FCFS";
111 elseif sn.sched(sst) == SchedStrategy.LCFSPR
112 station_type(s) = "LCFSPR";
113 else
114 line_error(mfilename, ['Retrieval analysis supports only IS, PS, SIRO, FCFS and LCFSPR ' ...
115 'retrieval stations; station %d uses an unsupported scheduling policy.'], queueNodes(s));
116 end
117end
118
119% --- per-item PH service (alpha,T) per station, routing R ---
120alpha = cell(1, S);
121T = cell(1, S);
122fsz = zeros(1, S);
123for s = 1:S
124 sst = sn.nodeToStation(queueNodes(s));
125 rcls0 = ch.retrievalClasses(1, jobinClass);
126 fsz(s) = size(sn.proc{sst}{rcls0}{1}, 1);
127 if (station_type(s) == "SIRO" || station_type(s) == "FCFS") && fsz(s) > 1
128 line_error(mfilename, ['Retrieval analysis supports SIRO/FCFS retrieval stations only with ' ...
129 'exponential (single-phase) service; station %d has phase-type service.'], queueNodes(s));
130 end
131 alpha{s} = zeros(1, fsz(s), n);
132 T{s} = zeros(fsz(s), fsz(s), n);
133end
134R = zeros(S+1, S+1, n);
135lin = @(node, cls) (node-1)*K + cls; % rtnodes flat index
136for i = 1:n
137 rcls = ch.retrievalClasses(i, jobinClass);
138 for s = 1:S
139 sst = sn.nodeToStation(queueNodes(s));
140 alpha{s}(1, :, i) = sn.pie{sst}{rcls}(:).';
141 T{s}(:, :, i) = sn.proc{sst}{rcls}{1};
142 end
143 % routing: index 1 = cache (outside), 2..S+1 = retrieval stations
144 for s = 1:S
145 R(1, s+1, i) = sn.rtnodes(lin(ci, rcls), lin(queueNodes(s), rcls)); % cache -> queue s
146 R(s+1, 1, i) = sn.rtnodes(lin(queueNodes(s), rcls), lin(ci, rcls)); % queue s -> cache
147 for sp = 1:S
148 R(s+1, sp+1, i) = sn.rtnodes(lin(queueNodes(s), rcls), lin(queueNodes(sp), rcls));
149 end
150 end
151end
152
153% --- eta(i,1) = sum of IS visits*mean; eta(i,1+p) = PS station p ---
154% SIRO and FCFS reduce to PS only with class-independent service rates; LCFSPR
155% is insensitive and exempt.
156for s = find(station_type == "FCFS" | station_type == "SIRO")
157 taus = zeros(1, n);
158 for i = 1:n
159 taus(i) = -alpha{s}(:, :, i) / T{s}(:, :, i) * ones(fsz(s), 1);
160 end
161 if max(taus) - min(taus) > 1e-9 * max(taus)
162 line_error(mfilename, ['Retrieval analysis requires class-independent (identical) mean ' ...
163 'service rates at SIRO/FCFS station %d.'], queueNodes(s));
164 end
165end
166
167isIdx = find(station_type == "IS");
168psIdx = find(station_type == "PS" | station_type == "SIRO" | station_type == "FCFS" | station_type == "LCFSPR"); % SIRO/FCFS/LCFSPR as PS
169r = numel(psIdx);
170eta = zeros(n, r+1);
171for i = 1:n
172 Ri = R(:, :, i);
173 a = Ri(1, 2:S+1); % outside -> station entry probs
174 Pmat = Ri(2:S+1, 2:S+1); % station -> station
175 visits = a / (eye(S) - Pmat); % expected visits per fetch
176 tau = zeros(1, S);
177 for s = 1:S
178 tau(s) = -alpha{s}(:, :, i) / T{s}(:, :, i) * ones(fsz(s), 1);
179 end
180 eta_s = visits .* tau;
181 eta(i, 1) = sum(eta_s(isIdx));
182 for p = 1:r
183 eta(i, 1+p) = eta_s(psIdx(p));
184 end
185end
186end