LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
runAnalyzer.m
1
2function [runtime, tranSysState, tranSync] = runAnalyzer(self, options)
3% [RUNTIME, TRANSYSSTATE] = RUN()
4
5T0=tic;
6if nargin<2 %~exist('options','var')
7 options = self.getOptions;
8end
9% Wall-clock time-budget launch marker (see options.timeout / lineTimeoutExceeded)
10options.timeout_tic = T0;
11
12% options.events (DES event budget) overrides options.samples when set;
13% samples remains accepted as a deprecated alias for the event budget.
14if isfield(options,'events') && ~isempty(options.events) && isfinite(options.events) && options.events > 0
15 options.samples = round(options.events);
16end
17
18[pyHandled, options, pyRuntime] = self.runAnalyzerPreamble(options, 'SSA');
19if pyHandled
20 runtime = pyRuntime;
21 return
22end
23
24self.runAnalyzerChecks(options);
25Solver.resetRandomGeneratorSeed(options.seed);
26
27
28% Check if confidence intervals are requested
29[confintEnabled, confintLevel] = Solver.parseConfInt(options.confint);
30
31%options.lang = 'java';
32
33sn = getStruct(self);
34% see _kb/06-solver-catalog.md for rationale (SSA FCR)
35
36% Native fork-join support: simulate the tag-augmented copy and fold the
37% auxiliary sibling classes back into the original classes at the end
38isFJ = any(sn.nodetype == NodeType.Fork) || any(sn.nodetype == NodeType.Join);
39if isFJ
40 if strcmp(options.lang,'java')
41 line_warning(mfilename,'Fork-join models are not supported by the JLINE SSA backend, switching to lang=matlab.\n');
42 options.lang = 'matlab';
43 end
44 if strcmp(options.method,'parallel')
45 line_warning(mfilename,'The parallel method does not support fork-join models, switching to the serial method.\n');
46 end
47 options.method = 'serial';
48 sn_orig = sn;
49 Korig = sn.nclasses;
50 [~, fjsn, fjclassmap] = ModelAdapter.fjtag(self.model);
51 sn = fjsn;
52 line_debug(options, 'SSA: fork-join tag augmentation, %d classes (%d auxiliary), %d fork firings', sn.nclasses, sn.nclasses-Korig, length(sn.fjsync));
53end
54
55switch options.lang
56 case 'java'
57 line_debug(options, 'SSA: using lang=java, delegating to JLINE');
58 % see _kb/06-solver-catalog.md for rationale (SSA lang=java transient trajectory)
59 if nargout > 1
60 options.method = 'serial';
61 end
62 switch options.method
63 case {'default','serial','parallel'}
64 switch options.method
65 case 'default'
66 options.verbose = VerboseLevel.SILENT;
67 actualmethod = 'parallel';
68 end
69 jmodel = LINE2JLINE(self.model);
70 M = jmodel.getNumberOfStations;
71 R = jmodel.getNumberOfClasses;
72 tic;
73 jsolver = JLINE.SolverSSA(jmodel, options);
74 [QN,UN,RN,WN,AN,TN] = JLINE.arrayListToResults(jsolver.getAvgTable);
75
76 % see _kb/06-solver-catalog.md for rationale (SSA lang=java transient trajectory)
77 if nargout > 1
78 jres = jsolver.result;
79 if isempty(jres.tranSysState)
80 line_error(mfilename,'SSA transient trajectory unavailable from JLINE (serial analyzer required).');
81 end
82 tranSysState = cell(1, sn.nstateful + 1);
83 tranSysState{1} = JLINE.from_jline_matrix(jres.tranSysState.get(java.lang.Integer(0)));
84 for isf = 1:sn.nstateful
85 tranSysState{1+isf} = JLINE.from_jline_matrix(jres.tranSysState.get(java.lang.Integer(isf)));
86 end
87 tranSync = JLINE.from_jline_matrix(jres.tranSync);
88 tranSync = tranSync(:)';
89 % see _kb/06-solver-catalog.md for rationale (SSA lang=java transient trajectory)
90 runtime = jsolver.result.runtime;
91 return;
92 end
93 CN = JLINE.from_jline_matrix(jsolver.getAvgSysRespT());
94 XN = JLINE.from_jline_matrix(jsolver.getAvgSysTput());
95 runtime = jsolver.result.runtime;
96 QN = reshape(QN',R,M)';
97 UN = reshape(UN',R,M)';
98 RN = reshape(RN',R,M)';
99 TN = reshape(TN',R,M)';
100 WN = reshape(WN',R,M)';
101 AN = reshape(AN',R,M)';
102 % Extract cache hit/miss probabilities from Java model
103 for ind = 1:sn.nnodes
104 if sn.nodetype(ind) == NodeType.Cache
105 hitRatioVec = JLINE.from_jline_matrix(jmodel.getNodeByIndex(ind-1).getHitRatio());
106 missRatioVec = JLINE.from_jline_matrix(jmodel.getNodeByIndex(ind-1).getMissRatio());
107 hitClass = self.model.nodes{ind}.getHitClass;
108 nk = length(hitClass);
109 hitprob = zeros(1, nk);
110 missprob = zeros(1, nk);
111 for k = 1:nk
112 if hitClass(k) > 0 && k <= length(hitRatioVec)
113 hitprob(k) = hitRatioVec(k);
114 missprob(k) = missRatioVec(k);
115 end
116 end
117 self.model.nodes{ind}.setResultHitProb(hitprob);
118 self.model.nodes{ind}.setResultMissProb(missprob);
119 end
120 end
121 if any(sn.nodetype == NodeType.Cache)
122 self.model.refreshStruct(true);
123 end
124 self.setAvgResults(QN,UN,RN,TN,AN,WN,CN,XN,runtime);
125
126 % Extract confidence intervals from Java solver results
127 if confintEnabled
128 result = jsolver.result;
129 % Helper to check for non-null Java objects
130 isValidMatrix = @(x) ~isempty(x) && isa(x, 'jline.util.matrix.Matrix');
131 if isValidMatrix(result.QNCI)
132 QNCI = JLINE.from_jline_matrix(result.QNCI);
133 QNCI = reshape(QNCI', R, M)';
134 else
135 QNCI = [];
136 end
137 if isValidMatrix(result.UNCI)
138 UNCI = JLINE.from_jline_matrix(result.UNCI);
139 UNCI = reshape(UNCI', R, M)';
140 else
141 UNCI = [];
142 end
143 if isValidMatrix(result.RNCI)
144 RNCI = JLINE.from_jline_matrix(result.RNCI);
145 RNCI = reshape(RNCI', R, M)';
146 else
147 RNCI = [];
148 end
149 if isValidMatrix(result.TNCI)
150 TNCI = JLINE.from_jline_matrix(result.TNCI);
151 TNCI = reshape(TNCI', R, M)';
152 else
153 TNCI = [];
154 end
155 if isValidMatrix(result.ANCI)
156 ANCI = JLINE.from_jline_matrix(result.ANCI);
157 ANCI = reshape(ANCI', R, M)';
158 else
159 ANCI = [];
160 end
161 if isValidMatrix(result.WNCI)
162 WNCI = JLINE.from_jline_matrix(result.WNCI);
163 WNCI = reshape(WNCI', R, M)';
164 else
165 WNCI = [];
166 end
167 % Store CI results
168 self.setAvgResultsCI(QNCI, UNCI, RNCI, TNCI, ANCI, WNCI, [], []);
169 end
170 otherwise
171 line_error(mfilename, ['the ',options.method',' method is not available.']);
172 end
173 case 'matlab'
174 line_debug(options, 'SSA: using lang=matlab');
175 [QN,UN,RN,TN,CN,XN,~,actualmethod,tranSysState, tranSync, sn, QNCI, UNCI, RNCI, TNCI, ANCI, WNCI] = solver_ssa_analyzer(sn, options);
176
177 for isf=1:sn.nstateful
178 ind = sn.statefulToNode(isf);
179 switch sn.nodetype(sn.statefulToNode(isf))
180 case NodeType.Cache
181 self.model.nodes{sn.statefulToNode(isf)}.setResultHitProb(sn.nodeparam{ind}.actualhitprob);
182 self.model.nodes{sn.statefulToNode(isf)}.setResultMissProb(sn.nodeparam{ind}.actualmissprob);
183 if isfield(sn.nodeparam{ind}, 'actualresidt')
184 self.model.nodes{sn.statefulToNode(isf)}.setResultResidT(sn.nodeparam{ind}.actualresidt);
185 end
186 self.model.refreshChains();
187 end
188 end
189 line_debug(options, 'SSA analysis complete: extracting results (nstations=%d, nclasses=%d)', sn.nstations, sn.nclasses);
190 runtime = toc(T0);
191 T = getAvgTputHandles(self);
192 if isFJ
193 [QN,UN,RN,TN,CN,XN] = sn_fj_foldback(QN,UN,RN,TN,CN,XN,fjclassmap,Korig);
194 self.result.fjclassmap = fjclassmap;
195 [TN,~,RN] = sn_pn_avg_rates(sn_orig, QN, TN, [], RN);
196 AN = sn_get_arvr_from_tput(sn_orig, TN, T);
197 % Join stations report the per-sibling waiting time (JMT
198 % convention): QLen over the sibling arrival rate
199 for ist=1:sn_orig.nstations
200 if sn_orig.nodetype(sn_orig.stationToNode(ist)) == NodeType.Join
201 for r=1:Korig
202 if AN(ist,r) > 0
203 RN(ist,r) = QN(ist,r)/AN(ist,r);
204 end
205 end
206 end
207 end
208 else
209 [TN,~,RN] = sn_pn_avg_rates(sn, QN, TN, [], RN);
210 AN = sn_get_arvr_from_tput(sn, TN, T);
211 end
212 if strcmp(options.method,'default') && exist('actualmethod','var')
213 self.setAvgResults(QN,UN,RN,TN,AN,[],CN,XN,runtime,['default/' actualmethod]);
214 else
215 self.setAvgResults(QN,UN,RN,TN,AN,[],CN,XN,runtime,options.method);
216 end
217 self.result.space = sn.space;
218
219 % Store CI data if computed
220 if confintEnabled && ~isempty(QNCI)
221 self.setAvgResultsCI(QNCI, UNCI, RNCI, TNCI, ANCI, WNCI, [], []);
222 end
223 if lineTimeoutExceeded(options)
224 self.result.Avg.timedOut = true;
225 line_warning(mfilename,'Solver stopped after the wall-clock time budget (options.timeout=%gs) was exceeded; returning the interim solution.\n', options.timeout);
226 end
227end
228end
Definition fjtag.m:161