LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
runAnalyzer.m
1function runtime = runAnalyzer(self, options)
2% RUNTIME = RUN()
3% Run the solver
4if nargin<2
5 options = self.getOptions;
6end
7
8iter = NaN;
9self.runAnalyzerChecks(options);
10Solver.resetRandomGeneratorSeed(options.seed);
11
12% Show library attribution if verbose and not yet shown
13if options.verbose ~= VerboseLevel.SILENT && ~GlobalConstants.isLibraryAttributionShown()
14 sn = self.getStruct();
15 libs = SolverNC.getLibrariesUsed(sn, options);
16 if ~isempty(libs)
17 line_printf('The solver will leverage %s.\n', strjoin(libs, ', '));
18 GlobalConstants.setLibraryAttributionShown(true);
19 end
20end
21
22origmethod = options.method;
23
24%options.lang = 'java';
25
26switch options.lang
27 case 'java'
28 sn = self.getStruct;
29 jmodel = LINE2JLINE(self.model);
30 %M = jmodel.getNumberOfStatefulNodes;
31 M = jmodel.getNumberOfStations;
32 R = jmodel.getNumberOfClasses;
33 jsolver = JLINE.SolverNC(jmodel, options);
34 [QN,UN,RN,WN,AN,TN] = JLINE.arrayListToResults(jsolver.getAvgTable);
35 runtime = jsolver.result.runtime;
36 CN = [];
37 XN = [];
38 QN = reshape(QN',R,M)';
39 UN = reshape(UN',R,M)';
40 RN = reshape(RN',R,M)';
41 TN = reshape(TN',R,M)';
42 WN = reshape(WN',R,M)';
43 AN = reshape(AN',R,M)';
44 lG = NaN;
45 lastiter = NaN;
46 for ind = 1:sn.nnodes
47 if sn.nodetype(ind) == NodeType.Cache
48 self.model.nodes{ind}.setResultHitProb(JLINE.from_jline_matrix(jmodel.getNodeByIndex(ind-1).getHitRatio()));
49 self.model.nodes{ind}.setResultMissProb(JLINE.from_jline_matrix(jmodel.getNodeByIndex(ind-1).getMissRatio()));
50 end
51 end
52 %self.model.refreshChains();
53 self.model.refreshStruct(true);
54 self.setAvgResults(QN,UN,RN,TN,AN,WN,CN,XN,runtime,options.method,lastiter);
55 self.result.Prob.logNormConstAggr = lG;
56 return
57 case 'matlab'
58 sn = getStruct(self); % doesn't need initial state
59
60 switch options.method
61 case 'default'
62 if sn.nstations == 2 && ~any(sn.nodetype == NodeType.Cache) && any(sn.nodetype == NodeType.Delay) && any(sn.nservers(isfinite(sn.nservers))>1)
63 options.method = 'comomld'; % default for multi-server models
64 end
65 case 'exact'
66 if ~self.model.hasProductFormSolution
67 line_error(mfilename,'The exact method requires the model to have a product-form solution. This model does not have one. You can use Network.hasProductFormSolution() to check before running the solver.');
68 elseif isempty(sn.lldscaling)
69 % if exact is requested and does not override a lldscaling assigment
70 Nt = sum(sn.njobs);
71 if isfinite(Nt)
72 % trasform multi-server nodes into lld nodes
73 sn.lldscaling = ones(sn.nstations,Nt);
74 for i=1:sn.nstations
75 if sn.nservers(i) > 1 && isfinite(sn.nservers(i))
76 sn.lldscaling(i,:) = min(1:Nt,sn.nservers(i));
77 sn.nservers(i) = 1;
78 end
79 end
80 end
81 end
82 end
83
84 if self.enableChecks && ~self.supports(self.model)
85 line_error(mfilename,'This model contains features not supported by the solver.');
86 end
87
88 Solver.resetRandomGeneratorSeed(options.seed);
89
90 if sn.nclosedjobs == 0 && length(sn.nodetype)==3 && all(sort(sn.nodetype)' == sort([NodeType.Source,NodeType.Cache,NodeType.Sink])) % is a non-rentrant cache
91 % random initialization
92 for ind = 1:sn.nnodes
93 if sn.nodetype(ind) == NodeType.Cache
94 prob = self.model.nodes{ind}.server.hitClass;
95 prob(prob>0) = 0.5;
96 self.model.nodes{ind}.setResultHitProb(prob);
97 self.model.nodes{ind}.setResultMissProb(1-prob);
98 end
99 end
100 self.model.refreshChains();
101 % start iteration
102 [QN,UN,RN,TN,CN,XN,lG,pij,runtime,actualmethod] = solver_nc_cache_analyzer(sn, options);
103 self.result.Prob.itemProb = pij;
104 for ind = 1:sn.nnodes
105 if sn.nodetype(ind) == NodeType.Cache
106 %prob = self.model.nodes{ind}.server.hitClass;
107 %prob(prob>0) = 0.5;
108 hitClass = self.model.nodes{ind}.getHitClass;
109 missClass = self.model.nodes{ind}.getMissClass;
110 hitprob = zeros(1,length(hitClass));
111 for k=1:length(self.model.nodes{ind}.getHitClass)
112 % for k=1:length(self.model.nodes{ind}.server.hitClass)
113 chain_k = sn.chains(:,k)>0;
114 inchain = sn.chains(chain_k,:)>0;
115 h = hitClass(k);
116 m = missClass(k);
117 if h>0 && m>0
118 hitprob(k) = XN(h) / sum(XN(inchain),"omitnan");
119 end
120 end
121 self.model.nodes{ind}.setResultHitProb(hitprob);
122 self.model.nodes{ind}.setResultMissProb(1-hitprob);
123 end
124 end
125 self.model.refreshChains;
126 else % queueing network
127 if any(sn.nodetype == NodeType.Cache) % if integrated caching-queueing
128 [QN,UN,RN,TN,CN,XN,lG,hitprob,missprob,runtime,iter,actualmethod] = solver_nc_cacheqn_analyzer(self, options);
129 for ind = 1:sn.nnodes
130 if sn.nodetype(ind) == NodeType.Cache
131 self.model.nodes{ind}.setResultHitProb(hitprob(ind,:));
132 self.model.nodes{ind}.setResultMissProb(missprob(ind,:));
133 end
134 end
135 self.model.refreshStruct(true); % Force refresh to get updated actualhitprob/actualmissprob
136 sn = self.model.sn;
137 else % ordinary queueing network
138 % Check for open model with single FCR containing single Delay (loss network)
139 if ~sn_has_closed_classes(sn) && sn.nregions == 1
140 regionMatrix = sn.region{1};
141 % Find stations in FCR (those with non-negative constraints)
142 stationsInFCR = find(any(regionMatrix(:,1:end-1) >= 0, 2) | regionMatrix(:,end) >= 0);
143 if length(stationsInFCR) == 1 && isinf(sn.nservers(stationsInFCR(1)))
144 % Single delay node in FCR - check drop rule
145 if all(sn.regionrule(1,:) == DropStrategy.DROP)
146 % Use loss network solver
147 [QN,UN,RN,TN,CN,XN,lG,runtime,iter,actualmethod] = solver_nc_lossn_analyzer(sn, options);
148 AN = sn_get_arvr_from_tput(sn, TN, self.getAvgTputHandles());
149 if strcmp(origmethod,'default') && exist('actualmethod','var') && ~strcmp(actualmethod,'default')
150 self.setAvgResults(QN,UN,RN,TN,AN,[],CN,XN,runtime,['default/' actualmethod],iter);
151 else
152 self.setAvgResults(QN,UN,RN,TN,AN,[],CN,XN,runtime,actualmethod,iter);
153 end
154 self.result.Prob.logNormConstAggr = real(lG);
155 return
156 else
157 % WAITQ (blocking) not supported - error and stop
158 line_error(mfilename, 'SolverNC does not support finite capacity regions with WAITQ (blocking) policy. Use DROP policy instead.');
159 end
160 end
161 end
162 if ~isempty(sn.lldscaling) || ~isempty(sn.cdscaling)
163 [QN,UN,RN,TN,CN,XN,lG,runtime,iter,actualmethod] = solver_ncld_analyzer(sn, options);
164 else
165 switch options.method
166 case 'exact'
167 if ~sn_has_open_classes(sn)
168 % multi-servers have already been transformed before
169 [QN,UN,RN,TN,CN,XN,lG,runtime,iter,actualmethod] = solver_ncld_analyzer(sn, options);
170 else%if ~snHasClosedClasses(sn)
171 [QN,UN,RN,TN,CN,XN,lG,runtime,iter,actualmethod] = solver_nc_analyzer(sn, options);
172 end
173 case {'rd','nrp','nrl','comomld'}
174 [QN,UN,RN,TN,CN,XN,lG,runtime,iter,actualmethod] = solver_ncld_analyzer(sn, options);
175 otherwise
176 [QN,UN,RN,TN,CN,XN,lG,runtime,iter,actualmethod] = solver_nc_analyzer(sn, options);
177 end
178 end
179 end
180 end
181 % Compute average arrival rate at steady-state
182 AN = sn_get_arvr_from_tput(sn, TN, self.getAvgTputHandles());
183end
184if strcmp(origmethod,'default') && exist('actualmethod','var') && ~strcmp(actualmethod,'default')
185 self.setAvgResults(QN,UN,RN,TN,AN,[],CN,XN,runtime,['default/' actualmethod],iter);
186else
187 self.setAvgResults(QN,UN,RN,TN,AN,[],CN,XN,runtime,actualmethod,iter);
188end
189
190self.result.Prob.logNormConstAggr = real(lG);
191end
Definition mmt.m:92