LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
JLINE.m
1classdef JLINE
2 % JLINE Conversion utilities for JLINE format models
3 %
4 % JLINE provides static methods to convert between LINE MATLAB models
5 % and JLINE Java/Kotlin models. This class serves as the primary interface
6 % for interoperability between the MATLAB and Java implementations of LINE.
7 %
8 % @brief JLINE format conversion and Java interoperability utilities
9 %
10 % Main functionality:
11 % - Convert LINE MATLAB models to JLINE Java models
12 % - Convert JLINE Java models back to LINE MATLAB format
13 % - Access JLINE solvers from MATLAB
14 % - Handle serialization between MATLAB and Java representations
15 %
16 % Example:
17 % @code
18 % % Convert a LINE model to JLINE format
19 % jnetwork = JLINE.from_model(network);
20 % % Get a JLINE solver
21 % jssa = JLINE.get_solver(jnetwork, 'ssa');
22 % @endcode
23
24 properties (Constant)
25 jar_loc = which('jline.jar');
26 end
27
28 methods(Static)
29
30 function model = from_line_layered_network(line_layered_network)
31 sn = line_layered_network.getStruct;
32
33 %% initialization
34 model = jline.lang.layered.LayeredNetwork(line_layered_network.getName);
35
36 %% host processors
37 P = cell(1,sn.nhosts);
38 for h=1:sn.nhosts
39 if isinf(sn.mult(h))
40 sn_mult_h = java.lang.Integer.MAX_VALUE;
41 else
42 sn_mult_h = sn.mult(h);
43 end
44 switch sn.sched(h)
45 case SchedStrategy.REF
46 P{h} = jline.lang.layered.Processor(model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.REF);
47 case SchedStrategy.INF
48 P{h} = jline.lang.layered.Processor(model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.INF);
49 case SchedStrategy.FCFS
50 P{h} = jline.lang.layered.Processor(model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.FCFS);
51 case SchedStrategy.LCFS
52 P{h} = jline.lang.layered.Processor(model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.LCFS);
53 case SchedStrategy.SIRO
54 P{h} = jline.lang.layered.Processor(model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.SIRO);
55 case SchedStrategy.SJF
56 P{h} = jline.lang.layered.Processor(model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.SJF);
57 case SchedStrategy.LJF
58 P{h} = jline.lang.layered.Processor(model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.LJF);
59 case SchedStrategy.PS
60 P{h} = jline.lang.layered.Processor(model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.PS);
61 case SchedStrategy.DPS
62 P{h} = jline.lang.layered.Processor(model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.DPS);
63 case SchedStrategy.GPS
64 P{h} = jline.lang.layered.Processor(model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.GPS);
65 case SchedStrategy.SEPT
66 P{h} = jline.lang.layered.Processor(model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.SEPT);
67 case SchedStrategy.LEPT
68 P{h} = jline.lang.layered.Processor(model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.LEPT);
69 case {SchedStrategy.HOL, SchedStrategy.FCFSPRIO}
70 P{h} = jline.lang.layered.Processor(model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.FCFSPRIO);
71 case SchedStrategy.FORK
72 P{h} = jline.lang.layered.Processor(model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.FORK);
73 case SchedStrategy.EXT
74 P{h} = jline.lang.layered.Processor(model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.EXT);
75 case SchedStrategy.LCFSPR
76 P{h} = jline.lang.layered.Processor(model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.LCFSPR);
77 case SchedStrategy.LCFSPI
78 P{h} = jline.lang.layered.Processor(model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.LCFSPI);
79 case SchedStrategy.LCFSPRIO
80 P{h} = jline.lang.layered.Processor(model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.LCFSPRIO);
81 case SchedStrategy.LCFSPRPRIO
82 P{h} = jline.lang.layered.Processor(model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.LCFSPRPRIO);
83 case SchedStrategy.LCFSPIPRIO
84 P{h} = jline.lang.layered.Processor(model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.LCFSPIPRIO);
85 case SchedStrategy.PSPRIO % todo
86 P{h} = jline.lang.layered.Processor(model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.PSPRIO);
87 case SchedStrategy.DPSPRIO % todo
88 P{h} = jline.lang.layered.Processor(model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.DPSPRIO);
89 case SchedStrategy.GPSPRIO % todo
90 P{h} = jline.lang.layered.Processor(model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.GPSPRIO);
91 end
92 if sn.repl(h)~=1
93 P{h}.setReplication(sn.repl(h));
94 end
95 end
96
97 %% tasks
98 T = cell(1,sn.ntasks);
99 for t=1:sn.ntasks
100 tidx = sn.tshift+t;
101 if isinf(sn.mult(tidx))
102 sn_mult_tidx = java.lang.Integer.MAX_VALUE;
103 else
104 sn_mult_tidx = sn.mult(tidx);
105 end
106 % Check if this is a CacheTask
107 if sn.iscache(tidx)
108 % Get replacement strategy from ordinal
109 switch sn.replacestrat(tidx)
110 case ReplacementStrategy.RR
111 jReplacestrat = jline.lang.constant.ReplacementStrategy.RR;
112 case ReplacementStrategy.FIFO
113 jReplacestrat = jline.lang.constant.ReplacementStrategy.FIFO;
114 case ReplacementStrategy.SFIFO
115 jReplacestrat = jline.lang.constant.ReplacementStrategy.SFIFO;
116 case ReplacementStrategy.LRU
117 jReplacestrat = jline.lang.constant.ReplacementStrategy.LRU;
118 otherwise
119 jReplacestrat = jline.lang.constant.ReplacementStrategy.FIFO;
120 end
121 T{t} = jline.lang.layered.CacheTask(model, sn.names{tidx}, sn.nitems(tidx), sn.itemcap{tidx}, jReplacestrat, sn_mult_tidx);
122 else
123 switch sn.sched(tidx)
124 case SchedStrategy.REF
125 T{t} = jline.lang.layered.Task(model, sn.names{tidx}, sn_mult_tidx, jline.lang.constant.SchedStrategy.REF);
126 case SchedStrategy.INF
127 T{t} = jline.lang.layered.Task(model, sn.names{tidx}, sn_mult_tidx, jline.lang.constant.SchedStrategy.INF);
128 case SchedStrategy.FCFS
129 T{t} = jline.lang.layered.Task(model, sn.names{tidx}, sn_mult_tidx, jline.lang.constant.SchedStrategy.FCFS);
130 case SchedStrategy.LCFS
131 T{t} = jline.lang.layered.Task(model, sn.names{tidx}, sn_mult_tidx, jline.lang.constant.SchedStrategy.LCFS);
132 case SchedStrategy.SIRO
133 T{t} = jline.lang.layered.Task(model, sn.names{tidx}, sn_mult_tidx, jline.lang.constant.SchedStrategy.SIRO);
134 case SchedStrategy.SJF
135 T{t} = jline.lang.layered.Task(model, sn.names{tidx}, sn_mult_tidx, jline.lang.constant.SchedStrategy.SJF);
136 case SchedStrategy.LJF
137 T{t} = jline.lang.layered.Task(model, sn.names{tidx}, sn_mult_tidx, jline.lang.constant.SchedStrategy.LJF);
138 case SchedStrategy.PS
139 T{t} = jline.lang.layered.Task(model, sn.names{tidx}, sn_mult_tidx, jline.lang.constant.SchedStrategy.PS);
140 case SchedStrategy.DPS
141 T{t} = jline.lang.layered.Task(model, sn.names{tidx}, sn_mult_tidx, jline.lang.constant.SchedStrategy.DPS);
142 case SchedStrategy.GPS
143 T{t} = jline.lang.layered.Task(model, sn.names{tidx}, sn_mult_tidx, jline.lang.constant.SchedStrategy.GPS);
144 case SchedStrategy.SEPT
145 T{t} = jline.lang.layered.Task(model, sn.names{tidx}, sn_mult_tidx, jline.lang.constant.SchedStrategy.SEPT);
146 case SchedStrategy.LEPT
147 T{t} = jline.lang.layered.Task(model, sn.names{tidx}, sn_mult_tidx, jline.lang.constant.SchedStrategy.LEPT);
148 case {SchedStrategy.HOL, SchedStrategy.FCFSPRIO}
149 T{t} = jline.lang.layered.Task(model, sn.names{tidx}, sn_mult_tidx, jline.lang.constant.SchedStrategy.FCFSPRIO);
150 case SchedStrategy.FORK
151 T{t} = jline.lang.layered.Task(model, sn.names{tidx}, sn_mult_tidx, jline.lang.constant.SchedStrategy.FORK);
152 case SchedStrategy.EXT
153 T{t} = jline.lang.layered.Task(model, sn.names{tidx}, sn_mult_tidx, jline.lang.constant.SchedStrategy.EXT);
154 case SchedStrategy.LCFSPR
155 T{t} = jline.lang.layered.Task(model, sn.names{tidx}, sn_mult_tidx, jline.lang.constant.SchedStrategy.LCFSPR);
156 case SchedStrategy.PSPRIO % todo
157 T{t} = jline.lang.layered.Task(model, sn.names{tidx}, sn_mult_tidx, jline.lang.constant.SchedStrategy.PSPRIO);
158 case SchedStrategy.DPSPRIO % todo
159 T{t} = jline.lang.layered.Task(model, sn.names{tidx}, sn_mult_tidx, jline.lang.constant.SchedStrategy.DPSPRIO);
160 case SchedStrategy.GPSPRIO % todo
161 T{t} = jline.lang.layered.Task(model, sn.names{tidx}, sn_mult_tidx, jline.lang.constant.SchedStrategy.GPSPRIO);
162 end
163 end
164 T{t}.on(P{sn.parent(tidx)});
165 if sn.repl(tidx)~=1
166 T{t}.setReplication(sn.repl(tidx));
167 end
168 if ~isempty(sn.think{tidx})
169 T{t}.setThinkTime(JLINE.from_line_distribution(sn.think{tidx}));
170 end
171 end
172 %% entries
173 E = cell(1,sn.nentries);
174 for e=1:sn.nentries
175 eidx = sn.eshift+e;
176 % Check if this is an ItemEntry (has nitems > 0)
177 if sn.nitems(eidx) > 0
178 % ItemEntry requires cardinality and popularity distribution
179 if ~isempty(sn.itemproc) && ~isempty(sn.itemproc{eidx})
180 jPopularity = JLINE.from_line_distribution(sn.itemproc{eidx});
181 else
182 % Default to uniform distribution
183 jPopularity = jline.lang.processes.DiscreteSampler(jline.util.matrix.Matrix.uniformDistribution(sn.nitems(eidx)));
184 end
185 E{e} = jline.lang.layered.ItemEntry(model, sn.names{eidx}, sn.nitems(eidx), jPopularity);
186 else
187 E{e} = jline.lang.layered.Entry(model, sn.names{eidx});
188 end
189 E{e}.on(T{sn.parent(eidx)-sn.tshift});
190 end
191
192 %% activities
193 A = cell(1,sn.nacts);
194 for a=1:sn.nacts
195 aidx = sn.ashift+a;
196 tidx = sn.parent(aidx);
197 onTask = tidx-sn.tshift;
198 A{a} = jline.lang.layered.Activity(model, sn.names{aidx}, JLINE.from_line_distribution(sn.hostdem{aidx}));
199 A{a}.on(T{onTask});
200
201 boundTo = find(sn.graph((sn.eshift+1):(sn.eshift+sn.nentries),aidx));
202
203 if ~isempty(boundTo)
204 A{a}.boundTo(E{boundTo});
205 end
206
207 if sn.sched(tidx) ~= SchedStrategy.REF % ref tasks don't reply
208 repliesTo = find(sn.replygraph(a,:)); % index of entry
209 if ~isempty(repliesTo)
210 if ~sn.isref(sn.parent(sn.eshift+repliesTo))
211 A{a}.repliesTo(E{repliesTo});
212 end
213 end
214 end
215
216 if ~isempty(sn.callpair)
217 cidxs = find(sn.callpair(:,1)==aidx);
218 calls = sn.callpair(:,2);
219 for c = cidxs(:)'
220 switch sn.calltype(c)
221 case CallType.SYNC
222 A{a}.synchCall(E{calls(c)-sn.eshift},sn.callproc{c}.getMean);
223 case CallType.ASYNC
224 A{a}.asynchCall(E{calls(c)-sn.eshift},sn.callproc{c}.getMean);
225 end
226 end
227 end
228
229 end
230
231 %% think times
232 for h=1:sn.nhosts
233 if ~isempty(sn.think{h})
234 switch sn.think{h}.name
235 case 'Immediate'
236 P{h}.setThinkTime(jline.lang.processes.Immediate);
237 case 'Exp'
238 P{h}.setThinkTime(jline.lang.processes.Exp(1/sn.hostdem{h}.getMean));
239 case 'Erlang'
240 P{h}.setThinkTime(jline.lang.processes.Erlang.fitMeanAndSCV(sn.hostdem{h}.getMean,sn.hostdem{h}.getSCV));
241 case 'HyperExp'
242 P{h}.setThinkTime(jline.lang.processes.HyperExp(sn.hostdem{h}.getParam(1).paramValue, sn.hostdem{h}.getParam(2).paramValue, sn.hostdem{h}.getParam(3).paramValue));
243 case 'Coxian'
244 P{h}.setThinkTime(jline.lang.processes.Coxian(sn.hostdem{h}.getParam(1).paramValue, sn.hostdem{h}.getParam(2).paramValue));
245 case 'APH'
246 P{h}.setThinkTime(jline.lang.processes.APH(sn.hostdem{h}.getParam(1).paramValue, sn.hostdem{h}.getParam(2).paramValue));
247 otherwise
248 line_error(mfilename,sprintf('JLINE conversion does not support the %d distribution yet.',sn.hostdem{h}.name));
249 end
250 end
251 end
252
253 %% Sequential precedences
254 for ai = 1:sn.nacts
255 aidx = sn.ashift + ai;
256 tidx = sn.parent(aidx);
257 % for all successors
258 for bidx=find(sn.graph(aidx,:))
259 if bidx > sn.ashift % ignore precedence between entries and activities
260 % Serial pattern (SEQ)
261 if full(sn.actpretype(aidx)) == ActivityPrecedenceType.PRE_SEQ && full(sn.actposttype(bidx)) == ActivityPrecedenceType.POST_SEQ
262 T{tidx-sn.tshift}.addPrecedence(jline.lang.layered.ActivityPrecedence.Serial(sn.names{aidx}, sn.names{bidx}));
263 end
264 end
265 end
266 end
267
268 %%%%%%%%%%%%%%%%%%%%%%%%%%% translated up to here
269
270 %% Loop precedences (POST_LOOP)
271 % Loop structure in sn.graph:
272 % - Entry activity (preAct) has edge to first loop body activity
273 % - Last loop body activity has back-edge to first loop body (weight = 1-1/counts)
274 % - Last loop body activity has edge to end activity (weight = 1/counts)
275 % - All loop body and end activities have POST_LOOP type
276 processedLoops = false(1, sn.nacts);
277 for ai = 1:sn.nacts
278 aidx = sn.ashift + ai;
279 tidx = sn.parent(aidx);
280 % Check if this activity starts a loop (has a successor with POST_LOOP type)
281 % and hasn't been processed as part of another loop
282 if processedLoops(ai)
283 continue;
284 end
285
286 successors = find(sn.graph(aidx,:));
287 for bidx = successors
288 if bidx > sn.ashift && full(sn.actposttype(bidx)) == ActivityPrecedenceType.POST_LOOP
289 % Skip if this loop body activity was already processed
290 if processedLoops(bidx - sn.ashift)
291 continue;
292 end
293 % Found start of a loop: aidx is the entry, bidx is first loop body activity
294 loopStart = bidx;
295 precActs = java.util.ArrayList();
296
297 % Follow the chain of POST_LOOP activities
298 curIdx = loopStart;
299 while true
300 precActs.add(sprintf("%s", sn.names{curIdx}));
301 processedLoops(curIdx - sn.ashift) = true;
302
303 % Find successors of current activity
304 curSuccessors = find(sn.graph(curIdx,:));
305 curSuccessors = curSuccessors(curSuccessors > sn.ashift);
306
307 % Check for loop termination: find the end activity
308 % End activity has weight = 1/counts (not the back-edge weight)
309 endIdx = 0;
310 nextIdx = 0;
311 for succIdx = curSuccessors
312 if full(sn.actposttype(succIdx)) == ActivityPrecedenceType.POST_LOOP
313 if succIdx == loopStart
314 % This is the back-edge, skip it
315 continue;
316 end
317 weight = full(sn.graph(curIdx, succIdx));
318 if weight > 0 && weight < 1
319 % This is the end activity (weight = 1/counts)
320 endIdx = succIdx;
321 else
322 % This is the next activity in the loop body (weight = 1.0)
323 nextIdx = succIdx;
324 end
325 end
326 end
327
328 if endIdx > 0
329 % Found end activity - calculate counts and output
330 weight = full(sn.graph(curIdx, endIdx));
331 if weight > 0
332 counts = 1/weight;
333 else
334 counts = 1; % Fallback to prevent division by zero
335 end
336 precActs.add(sprintf("%s", sn.names{endIdx}));
337 processedLoops(endIdx - sn.ashift) = true;
338
339 T{tidx-sn.tshift}.addPrecedence(jline.lang.layered.ActivityPrecedence.Loop(sn.names{aidx}, precActs, jline.util.matrix.Matrix(counts)));
340 break;
341 elseif nextIdx > 0
342 % Continue to next activity in loop body
343 curIdx = nextIdx;
344 else
345 % No more successors - shouldn't happen in valid loop
346 break;
347 end
348 end
349 break; % Only process one loop starting from this activity
350 end
351 end
352 end
353
354 %% OrFork precedences (POST_OR)
355 precMarker = 0;
356 for ai = 1:sn.nacts
357 probs = [];
358 aidx = sn.ashift + ai;
359 tidx = sn.parent(aidx);
360 prob_ctr = 0;
361 % for all successors
362 for bidx=find(sn.graph(aidx,:))
363 if bidx > sn.ashift % ignore precedence between entries and activities
364 % Or pattern (POST_OR)
365 if full(sn.actposttype(bidx)) == ActivityPrecedenceType.POST_OR
366 if precMarker == 0 % start a new orjoin
367 precActs = java.util.ArrayList();
368 precMarker = aidx-sn.ashift;
369 precActs.add(sprintf("%s", sn.names{bidx}));
370 probs=full(sn.graph(aidx,bidx));
371 else
372 precActs.add(sprintf("%s", sn.names{bidx}));
373 probs(end+1)=full(sn.graph(aidx,bidx));
374 end
375 end
376 end
377 end
378
379
380 if precMarker > 0
381 probsMatrix = jline.util.matrix.Matrix(1,length(probs));
382 for i=1:length(probs)
383 probsMatrix.set(0,i-1,probs(i));
384 end
385 T{tidx-sn.tshift}.addPrecedence(jline.lang.layered.ActivityPrecedence.OrFork(sn.names{precMarker+sn.ashift}, precActs, probsMatrix));
386 precMarker = 0;
387 end
388 end
389
390 %% AndFork precedences (POST_AND)
391 precMarker = 0;
392 postActs = '';
393 for ai = 1:sn.nacts
394 aidx = sn.ashift + ai;
395 tidx = sn.parent(aidx);
396 % for all successors
397 for bidx=find(sn.graph(aidx,:))
398 if bidx > sn.ashift % ignore precedence between entries and activities
399 % Or pattern (POST_AND)
400 if full(sn.actposttype(bidx)) == ActivityPrecedenceType.POST_AND
401 if isempty(postActs)
402 postActs = java.util.ArrayList();
403 postActs.add(sprintf("%s", sn.names{bidx}));
404 else
405 postActs.add(sprintf("%s", sn.names{bidx}));
406 end
407
408 if precMarker == 0 % start a new orjoin
409 precMarker = aidx-sn.ashift;
410 end
411 end
412 end
413 end
414 if precMarker > 0
415 T{tidx-sn.tshift}.addPrecedence(jline.lang.layered.ActivityPrecedence.AndFork(sn.names{precMarker+sn.ashift}, postActs));
416 precMarker = 0;
417 end
418 end
419
420 %% CacheAccess precedences (POST_CACHE)
421 precMarker = 0;
422 postActs = '';
423 for ai = 1:sn.nacts
424 aidx = sn.ashift + ai;
425 tidx = sn.parent(aidx);
426 % for all successors
427 for bidx=find(sn.graph(aidx,:))
428 if bidx > sn.ashift % ignore precedence between entries and activities
429 % CacheAccess pattern (POST_CACHE)
430 if full(sn.actposttype(bidx)) == ActivityPrecedenceType.POST_CACHE
431 if isempty(postActs)
432 postActs = java.util.ArrayList();
433 postActs.add(sprintf("%s", sn.names{bidx}));
434 else
435 postActs.add(sprintf("%s", sn.names{bidx}));
436 end
437
438 if precMarker == 0 % start a new cache access
439 precMarker = aidx-sn.ashift;
440 end
441 end
442 end
443 end
444 if precMarker > 0
445 T{tidx-sn.tshift}.addPrecedence(jline.lang.layered.ActivityPrecedence.CacheAccess(sn.names{precMarker+sn.ashift}, postActs));
446 precMarker = 0;
447 postActs = '';
448 end
449 end
450
451 %% OrJoin precedences (PRE_OR)
452 precMarker = 0;
453 for bi = sn.nacts:-1:1
454 bidx = sn.ashift + bi;
455 tidx = sn.parent(bidx);
456 % for all predecessors
457 for aidx=find(sn.graph(:,bidx))'
458 if aidx > sn.ashift % ignore precedence between entries and activities
459 % OrJoin pattern (PRE_OR)
460 if full(sn.actpretype(aidx)) == ActivityPrecedenceType.PRE_OR
461 if precMarker == 0 % start a new orjoin
462 precActs = java.util.ArrayList();
463 precMarker = bidx-sn.ashift;
464 precActs.add(sprintf("%s", sn.names{aidx}));
465 else
466 precActs.add(sprintf("%s", sn.names{aidx}));
467 end
468 end
469 end
470 end
471 if precMarker > 0
472 T{tidx-sn.tshift}.addPrecedence(jline.lang.layered.ActivityPrecedence.OrJoin(precActs, sn.names{precMarker+sn.ashift}));
473 precMarker = 0;
474 end
475 end
476
477 %% AndJoin precedences (PRE_AND)
478 precMarker = 0;
479 for bi = sn.nacts:-1:1
480 bidx = sn.ashift + bi;
481 tidx = sn.parent(bidx);
482 % for all predecessors
483 for aidx=find(sn.graph(:,bidx))'
484 if aidx > sn.ashift % ignore precedence between entries and activities
485 % OrJoin pattern (PRE_AND)
486 if full(sn.actpretype(aidx)) == ActivityPrecedenceType.PRE_AND
487 if precMarker == 0 % start a new orjoin
488 precActs = java.util.ArrayList();
489 precMarker = bidx-sn.ashift;
490 precActs.add(sprintf("%s", sn.names{aidx}));
491 else
492 precActs.add(sprintf("%s", sn.names{aidx}));
493 end
494 end
495 end
496 end
497 if precMarker > 0
498 % Find quorum parameter from original precedence structure
499 postActName = sn.names{precMarker+sn.ashift};
500 localTaskIdx = tidx - sn.tshift;
501 quorum = [];
502 for ap = 1:length(line_layered_network.tasks{localTaskIdx}.precedences)
503 precedence = line_layered_network.tasks{localTaskIdx}.precedences(ap);
504 if precedence.preType == ActivityPrecedenceType.PRE_AND
505 % Check if this precedence contains our post activity
506 if any(strcmp(precedence.postActs, postActName))
507 quorum = precedence.preParams;
508 break;
509 end
510 end
511 end
512
513 if isempty(quorum)
514 T{tidx-sn.tshift}.addPrecedence(jline.lang.layered.ActivityPrecedence.AndJoin(precActs, sn.names{precMarker+sn.ashift}));
515 else
516 T{tidx-sn.tshift}.addPrecedence(jline.lang.layered.ActivityPrecedence.AndJoin(precActs, sn.names{precMarker+sn.ashift}, quorum));
517 end
518 precMarker = 0;
519 end
520 end
521
522 end
523
524 function jdist = from_line_distribution(line_dist)
525 if isa(line_dist, 'Exp')
526 jdist = jline.lang.processes.Exp(line_dist.getParam(1).paramValue);
527 elseif isa(line_dist, "APH")
528 alpha = line_dist.getParam(1).paramValue;
529 T = line_dist.getParam(2).paramValue;
530 jline_alpha = java.util.ArrayList();
531 for i = 1:length(alpha)
532 jline_alpha.add(alpha(i));
533 end
534 jline_T = JLINE.from_line_matrix(T);
535 jdist = jline.lang.processes.APH(jline_alpha, jline_T);
536 elseif isa(line_dist, 'Coxian')
537 jline_mu = java.util.ArrayList();
538 jline_phi = java.util.ArrayList();
539 if length(line_dist.params) == 3
540 jline_mu.add(line_dist.getParam(1).paramValue);
541 jline_mu.add(line_dist.getParam(2).paramValue);
542 jline_phi.add(line_dist.getParam(3).paramValue);
543 else
544 mu = line_dist.getParam(1).paramValue;
545 phi = line_dist.getParam(2).paramValue;
546 for i = 1:length(mu)
547 jline_mu.add(mu(i));
548 end
549 for i = 1:length(phi)
550 jline_phi.add(phi(i));
551 end
552 end
553 jdist = jline.lang.processes.Coxian(jline_mu, jline_phi);
554 elseif isa(line_dist, 'Det')
555 jdist = jline.lang.processes.Det(line_dist.getParam(1).paramValue);
556 elseif isa(line_dist, 'DiscreteSampler')
557 popularity_p = JLINE.from_line_matrix(line_dist.getParam(1).paramValue);
558 popularity_val = JLINE.from_line_matrix(line_dist.getParam(2).paramValue);
559 jdist = jline.lang.processes.DiscreteSampler(popularity_p, popularity_val);
560 elseif isa(line_dist, 'Erlang')
561 jdist = jline.lang.processes.Erlang(line_dist.getParam(1).paramValue, line_dist.getParam(2).paramValue);
562 elseif isa(line_dist, 'Gamma')
563 jdist = jline.lang.processes.Gamma(line_dist.getParam(1).paramValue, line_dist.getParam(2).paramValue);
564 elseif isa(line_dist, "HyperExp")
565 jdist = jline.lang.processes.HyperExp(line_dist.getParam(1).paramValue, line_dist.getParam(2).paramValue, line_dist.getParam(3).paramValue);
566 elseif isa(line_dist, 'Lognormal')
567 jdist = jline.lang.processes.Lognormal(line_dist.getParam(1).paramValue, line_dist.getParam(2).paramValue);
568 elseif isa(line_dist, 'Pareto')
569 jdist = jline.lang.processes.Pareto(line_dist.getParam(1).paramValue, line_dist.getParam(2).paramValue);
570 elseif isa(line_dist, 'MAP')
571 D0 = line_dist.D(0);
572 D1 = line_dist.D(1);
573 jdist = jline.lang.processes.MAP(JLINE.from_line_matrix(D0), JLINE.from_line_matrix(D1));
574 elseif isa(line_dist, 'MMPP2')
575 lambda0 = line_dist.getParam(1).paramValue;
576 lambda1 = line_dist.getParam(2).paramValue;
577 sigma0 = line_dist.getParam(3).paramValue;
578 sigma1 = line_dist.getParam(4).paramValue;
579 jdist = jline.lang.processes.MMPP2(lambda0, lambda1, sigma0, sigma1);
580 elseif isa(line_dist, 'PH')
581 alpha = line_dist.getParam(1).paramValue;
582 T = line_dist.getParam(2).paramValue;
583 jdist = jline.lang.processes.PH(JLINE.from_line_matrix(alpha), JLINE.from_line_matrix(T));
584 elseif isa(line_dist, 'Uniform')
585 jdist = jline.lang.processes.Uniform(line_dist.getParam(1).paramValue, line_dist.getParam(2).paramValue);
586 elseif isa(line_dist, 'Weibull')
587 jdist = jline.lang.processes.Weibull(line_dist.getParam(1).paramValue, line_dist.getParam(2).paramValue);
588 elseif isa(line_dist, 'Zipf')
589 jdist = jline.lang.processes.Zipf(line_dist.getParam(3).paramValue, line_dist.getParam(2).paramValue);
590 elseif isa(line_dist, 'Immediate')
591 jdist = jline.lang.processes.Immediate();
592 elseif isempty(line_dist) || isa(line_dist, 'Disabled')
593 jdist = jline.lang.processes.Disabled();
594 return;
595 elseif isa(line_dist, 'Replayer')
596 jdist = jline.lang.processes.Replayer(line_dist.params{1}.paramValue);
597 elseif isa(line_dist, 'Trace')
598 jdist = jline.lang.processes.Trace(line_dist.params{1}.paramValue);
599 else
600 line_error(mfilename,'Distribution not supported by JLINE.');
601 end
602 end
603
604 function matlab_dist = from_jline_distribution(jdist)
605 if isa(jdist, 'jline.lang.processes.Exp')
606 matlab_dist = Exp(jdist.getRate());
607 elseif isa(jdist, 'jline.lang.processes.Det')
608 matlab_dist = Det(jdist.getParam(1).getValue);
609 elseif isa(jdist, 'jline.lang.processes.Erlang')
610 matlab_dist = Erlang(jdist.getRate(),jdist.getNumberOfPhases());
611 elseif isa(jdist, 'jline.lang.processes.Gamma')
612 matlab_dist = Gamma(jdist.getParam(1).getValue,jdist.getParam(2).getValue);
613 elseif isa(jdist, 'jline.lang.processes.HyperExp')
614 matlab_dist = HyperExp(jdist.getParam(1).getValue, jdist.getParam(2).getValue, jdist.getParam(3).getValue);
615 elseif isa(jdist, 'jline.lang.processes.Lognormal')
616 matlab_dist = Lognormal(jdist.getParam(1).getValue,jdist.getParam(2).getValue);
617 elseif isa(jdist, 'jline.lang.processes.Pareto')
618 matlab_dist = Pareto(jdist.getParam(1).getValue,jdist.getParam(2).getValue);
619 elseif isa(jdist, 'jline.lang.processes.Uniform')
620 matlab_dist = Uniform(jdist.getParam(1).getValue,jdist.getParam(2).getValue);
621 elseif isa(jdist, 'jline.lang.processes.Weibull')
622 matlab_dist = Weibull(jdist.getParam(1).getValue,jdist.getParam(2).getValue);
623 elseif isa(jdist, 'jline.lang.processes.APH')
624 jalpha = jdist.getParam(1).getValue;
625 alpha = zeros(1, jalpha.length);
626 for i = 1:jalpha.length
627 alpha(i) = jalpha.get(i-1);
628 end
629 matlab_dist = APH(alpha, JLINE.from_jline_matrix(jdist.getParam(2).getValue));
630 elseif isa(jdist, 'jline.lang.processes.PH')
631 jalpha = jdist.getParam(1).getValue;
632 alpha = zeros(1, jalpha.length);
633 for i = 1:jalpha.length
634 alpha(i) = jalpha.get(i-1);
635 end
636 matlab_dist = PH(alpha, JLINE.from_jline_matrix(jdist.getParam(2).getValue));
637 elseif isa(jdist, 'jline.lang.processes.Coxian')
638 if jdist.getNumberOfPhases == 2
639 matlab_dist = Coxian([jdist.getParam(1).getValue.get(0), jdist.getParam(1).getValue.get(1)], [jdist.getParam(2).getValue.get(0),1]);
640 else
641 jmu = jdist.getParam(1).getValue;
642 jphi = jdist.getParam(2).getValue;
643 mu = zeros(1, jmu.size);
644 phi = zeros(1, jphi.size);
645 for i = 1:jmu.size
646 mu(i) = jmu.get(i-1);
647 end
648 for i = 1:jphi.size
649 phi(i) = jphi.get(i-1);
650 end
651 matlab_dist = Coxian(mu, phi);
652 end
653 elseif isa(jdist, 'jline.lang.processes.Immediate')
654 matlab_dist = Immediate();
655 elseif isa(jdist, 'jline.lang.processes.Disabled')
656 matlab_dist = Disabled();
657 else
658 line_error(mfilename,'Distribution not supported by JLINE.');
659 end
660 end
661
662 function set_csMatrix(line_node, jnode, jclasses)
663 nClasses = length(line_node.model.classes);
664 csMatrix = jnode.initClassSwitchMatrix();
665 for i = 1:nClasses
666 for j = 1:nClasses
667 csMatrix.set(jclasses{i}, jclasses{j}, line_node.server.csFun(i,j,0,0));
668 end
669 end
670 jnode.setClassSwitchingMatrix(csMatrix);
671 end
672
673 function set_service(line_node, jnode, job_classes)
674 if (isa(line_node, 'Sink') || isa(line_node, 'Router') || isa(line_node, 'Cache') || isa(line_node, 'Logger') || isa(line_node, 'ClassSwitch') || isa(line_node, 'Fork') || isa(line_node, 'Join') || isa(line_node, 'Place') || isa(line_node, 'Transition'))
675 return;
676 end
677
678 for n = 1 : length(job_classes)
679 if (isa(line_node, 'Queue') || isa(line_node, 'Delay'))
680 matlab_dist = line_node.getService(job_classes{n});
681 elseif (isa(line_node, 'Source'))
682 matlab_dist = line_node.getArrivalProcess(job_classes{n});
683 else
684 line_error(mfilename,'Node not supported by JLINE.');
685 end
686 service_dist = JLINE.from_line_distribution(matlab_dist);
687
688 if (isa(line_node,'Queue') || isa(line_node, 'Delay'))
689 jnode.setService(jnode.getModel().getClasses().get(n-1), service_dist, line_node.schedStrategyPar(n));
690 elseif (isa(line_node, 'Source'))
691 jnode.setArrival(jnode.getModel().getClasses().get(n-1), service_dist);
692 end
693 end
694 end
695
696 function set_line_service(jline_node, line_node, job_classes, line_classes)
697 if (isa(line_node,'Sink')) || isa(line_node, 'ClassSwitch')
698 return;
699 end
700 for n = 1:job_classes.size()
701 if (isa(line_node, 'Queue') || isa(line_node, 'Delay'))
702 jdist = jline_node.getServiceProcess(job_classes.get(n-1));
703 matlab_dist = JLINE.from_jline_distribution(jdist);
704 line_node.setService(line_classes{n}, matlab_dist);
705 elseif (isa(line_node, 'Source'))
706 jdist = jline_node.getArrivalProcess(job_classes.get(n-1));
707 matlab_dist = JLINE.from_jline_distribution(jdist);
708 line_node.setArrival(line_classes{n}, matlab_dist);
709 elseif (isa(line_node, 'Router'))
710 % no-op
711 else
712 line_error(mfilename,'Node not supported by JLINE.');
713 end
714 end
715 end
716
717 function node_object = from_line_node(line_node, jnetwork, ~, forkNode)
718 if isa(line_node, 'Delay')
719 node_object = jline.lang.nodes.Delay(jnetwork, line_node.getName);
720 elseif isa(line_node, 'Queue')
721 switch line_node.schedStrategy
722 case SchedStrategy.INF
723 node_object = jline.lang.nodes.Queue(jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.INF);
724 case SchedStrategy.FCFS
725 node_object = jline.lang.nodes.Queue(jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.FCFS);
726 case SchedStrategy.LCFS
727 node_object = jline.lang.nodes.Queue(jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.LCFS);
728 case SchedStrategy.SIRO
729 node_object = jline.lang.nodes.Queue(jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.SIRO);
730 case SchedStrategy.SJF
731 node_object = jline.lang.nodes.Queue(jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.SJF);
732 case SchedStrategy.LJF
733 node_object = jline.lang.nodes.Queue(jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.LJF);
734 case SchedStrategy.PS
735 node_object = jline.lang.nodes.Queue(jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.PS);
736 case SchedStrategy.DPS
737 node_object = jline.lang.nodes.Queue(jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.DPS);
738 case SchedStrategy.GPS
739 node_object = jline.lang.nodes.Queue(jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.GPS);
740 case SchedStrategy.SEPT
741 node_object = jline.lang.nodes.Queue(jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.SEPT);
742 case SchedStrategy.LEPT
743 node_object = jline.lang.nodes.Queue(jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.LEPT);
744 case {SchedStrategy.HOL, SchedStrategy.FCFSPRIO}
745 node_object = jline.lang.nodes.Queue(jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.FCFSPRIO);
746 case SchedStrategy.FORK
747 node_object = jline.lang.nodes.Queue(jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.FORK);
748 case SchedStrategy.EXT
749 node_object = jline.lang.nodes.Queue(jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.EXT);
750 case SchedStrategy.REF
751 node_object = jline.lang.nodes.Queue(jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.REF);
752 case SchedStrategy.LCFSPR
753 node_object = jline.lang.nodes.Queue(jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.LCFSPR);
754 case SchedStrategy.LCFSPI
755 node_object = jline.lang.nodes.Queue(jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.LCFSPI);
756 case SchedStrategy.LCFSPRIO
757 node_object = jline.lang.nodes.Queue(jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.LCFSPRIO);
758 case SchedStrategy.LCFSPRPRIO
759 node_object = jline.lang.nodes.Queue(jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.LCFSPRPRIO);
760 case SchedStrategy.LCFSPIPRIO
761 node_object = jline.lang.nodes.Queue(jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.LCFSPIPRIO);
762 case SchedStrategy.FCFSPR
763 node_object = jline.lang.nodes.Queue(jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.FCFSPR);
764 case SchedStrategy.FCFSPI
765 node_object = jline.lang.nodes.Queue(jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.FCFSPI);
766 case SchedStrategy.FCFSPRPRIO
767 node_object = jline.lang.nodes.Queue(jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.FCFSPRPRIO);
768 case SchedStrategy.FCFSPIPRIO
769 node_object = jline.lang.nodes.Queue(jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.FCFSPIPRIO);
770 case SchedStrategy.PSPRIO
771 node_object = jline.lang.nodes.Queue(jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.PSPRIO);
772 case SchedStrategy.DPSPRIO
773 node_object = jline.lang.nodes.Queue(jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.DPSPRIO);
774 case SchedStrategy.GPSPRIO
775 node_object = jline.lang.nodes.Queue(jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.GPSPRIO);
776 end
777 nservers = line_node.getNumberOfServers;
778 if isinf(nservers)
779 node_object.setNumberOfServers(java.lang.Integer.MAX_VALUE);
780 elseif nservers > 1
781 node_object.setNumberOfServers(line_node.getNumberOfServers);
782 end
783 if ~isempty(line_node.lldScaling)
784 node_object.setLoadDependence(JLINE.from_line_matrix(line_node.lldScaling));
785 end
786 if ~isempty(line_node.lcdScaling)
787 node_object.setLimitedClassDependence(JLINE.handle_to_serializablefun(line_node.lcdScaling));
788 end
789 % Set queue capacity if finite
790 if ~isinf(line_node.cap)
791 node_object.setCapacity(line_node.cap);
792 end
793 elseif isa(line_node, 'Source')
794 node_object = jline.lang.nodes.Source(jnetwork, line_node.getName);
795 elseif isa(line_node, 'Sink')
796 node_object = jline.lang.nodes.Sink(jnetwork, line_node.getName);
797 elseif isa(line_node, 'Router')
798 node_object = jline.lang.nodes.Router(jnetwork, line_node.getName);
799 elseif isa(line_node, 'ClassSwitch')
800 node_object = jline.lang.nodes.ClassSwitch(jnetwork, line_node.getName);
801 elseif isa(line_node, 'Fork')
802 node_object = jline.lang.nodes.Fork(jnetwork, line_node.name);
803 node_object.setTasksPerLink(line_node.output.tasksPerLink);
804 elseif isa(line_node, 'Join')
805 node_object = jline.lang.nodes.Join(jnetwork, line_node.name, forkNode);
806 elseif isa(line_node, 'Logger')
807 node_object = jline.lang.nodes.Logger(jnetwork, line_node.name, [line_node.filePath,line_node.fileName]);
808 elseif isa(line_node, 'Cache')
809 nitems = line_node.items.nitems;
810 switch line_node.replacestrategy
811 case ReplacementStrategy.RR
812 repStrategy = jline.lang.constant.ReplacementStrategy.RR;
813 case ReplacementStrategy.FIFO
814 repStrategy = jline.lang.constant.ReplacementStrategy.FIFO;
815 case ReplacementStrategy.SFIFO
816 repStrategy = jline.lang.constant.ReplacementStrategy.SFIFO;
817 case ReplacementStrategy.LRU
818 repStrategy = jline.lang.constant.ReplacementStrategy.LRU;
819 end
820 if ~isempty(line_node.graph)
821 node_object = jline.lang.nodes.Cache(jnetwork, line_node.name, nitems, JLINE.from_line_matrix(line_node.itemLevelCap), repStrategy, JLINE.from_line_matrix(line_node.graph));
822 else
823 node_object = jline.lang.nodes.Cache(jnetwork, line_node.name, nitems, JLINE.from_line_matrix(line_node.itemLevelCap), repStrategy);
824 end
825 elseif isa(line_node, 'Place')
826 node_object = jline.lang.nodes.Place(jnetwork, line_node.getName);
827 elseif isa(line_node, 'Transition')
828 node_object = jline.lang.nodes.Transition(jnetwork, line_node.getName);
829 % Modes are added later in from_line_network after classes are created
830 else
831 line_error(mfilename,'Node not supported by JLINE.');
832 end
833 end
834
835 function node_object = from_jline_node(jline_node, model, job_classes)
836 if isa(jline_node, 'jline.lang.nodes.Delay')
837 node_object = Delay(model, jline_node.getName.toCharArray');
838 elseif isa(jline_node, 'jline.lang.nodes.Queue')
839 schedStrategy = jline_node.getSchedStrategy;
840 switch schedStrategy.name().toCharArray'
841 case 'INF'
842 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.INF);
843 case 'FCFS'
844 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.FCFS);
845 case 'LCFS'
846 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.LCFS);
847 case 'SIRO'
848 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.SIRO);
849 case 'SJF'
850 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.SJF);
851 case 'LJF'
852 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.LJF);
853 case 'PS'
854 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.PS);
855 case 'DPS'
856 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.DPS);
857 case 'GPS'
858 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.GPS);
859 case 'SEPT'
860 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.SEPT);
861 case 'LEPT'
862 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.LEPT);
863 case {'HOL', 'FCFSPRIO'}
864 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.FCFSPRIO);
865 case 'FORK'
866 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.FORK);
867 case 'EXT'
868 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.EXT);
869 case 'REF'
870 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.REF);
871 case 'LCFSPR'
872 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.LCFSPR);
873 end
874 node_object.setNumberOfServers(jline_node.getNumberOfServers);
875 if ~isempty(JLINE.from_jline_matrix(jline_node.getLimitedLoadDependence))
876 node_object.setLoadDependence(JLINE.from_jline_matrix(jline_node.getLimitedLoadDependence));
877 end
878 elseif isa(jline_node, 'jline.lang.nodes.Source')
879 node_object = Source(model, jline_node.getName.toCharArray');
880 elseif isa(jline_node, 'jline.lang.nodes.Sink')
881 node_object = Sink(model, jline_node.getName.toCharArray');
882 elseif isa(jline_node, 'jline.lang.nodes.Router')
883 node_object = Router(model, jline_node.getName.toCharArray');
884 elseif isa(jline_node, 'jline.lang.nodes.ClassSwitch')
885 nClasses = job_classes.size;
886 csMatrix = zeros(nClasses, nClasses);
887 for r = 1:nClasses
888 for s = 1:nClasses
889 csMatrix(r,s) = jline_node.getServer.applyCsFun(r-1,s-1);
890 end
891 end
892 node_object = ClassSwitch(model, jline_node.getName.toCharArray', csMatrix);
893 elseif isa(jline_node, 'jline.lang.nodes.Place')
894 node_object = Place(model, jline_node.getName.toCharArray');
895 elseif isa(jline_node, 'jline.lang.nodes.Transition')
896 node_object = Transition(model, jline_node.getName.toCharArray');
897 % Note: Mode configurations need to be set after classes are created
898 else
899 line_error(mfilename,'Node not supported by JLINE.');
900 end
901 end
902
903 function node_class = from_line_class(line_class, jnetwork)
904 % Check signal classes first (before their base classes)
905 if isa(line_class, 'ClosedSignal')
906 % ClosedSignal -> jline.lang.ClosedSignal
907 jSignalType = jline.lang.constant.SignalType.fromID(line_class.signalType);
908 node_class = jline.lang.ClosedSignal(jnetwork, line_class.getName, jSignalType, jnetwork.getNodeByName(line_class.refstat.getName), line_class.priority);
909 elseif isa(line_class, 'Signal') || isa(line_class, 'OpenSignal')
910 % Signal/OpenSignal -> jline.lang.Signal
911 jSignalType = jline.lang.constant.SignalType.fromID(line_class.signalType);
912 node_class = jline.lang.Signal(jnetwork, line_class.getName, jSignalType, line_class.priority);
913 elseif isa(line_class, 'OpenClass')
914 node_class = jline.lang.OpenClass(jnetwork, line_class.getName, line_class.priority);
915 elseif isa(line_class, 'SelfLoopingClass')
916 node_class = jline.lang.SelfLoopingClass(jnetwork, line_class.getName, line_class.population, jnetwork.getNodeByName(line_class.refstat.getName), line_class.priority);
917 elseif isa(line_class, 'ClosedClass')
918 node_class = jline.lang.ClosedClass(jnetwork, line_class.getName, line_class.population, jnetwork.getNodeByName(line_class.refstat.getName), line_class.priority);
919 else
920 line_error(mfilename,'Class type not supported by JLINE.');
921 end
922 if line_class.isReferenceClass()
923 node_class.setReferenceClass(true);
924 end
925 end
926
927 function node_class = from_jline_class(jclass, model)
928 if isa(jclass, 'jline.lang.OpenClass')
929 node_class = OpenClass(model, jclass.getName.toCharArray', jclass.getPriority);
930 elseif isa(jclass, 'jline.lang.SelfLoopingClass')
931 node_class = SelfLoopingClass(model, jclass.getName.toCharArray', jclass.getNumberOfJobs, model.getNodeByName(jclass.getReferenceStation.getName), jclass.getPriority);
932 elseif isa(jclass, 'jline.lang.ClosedClass')
933 node_class = ClosedClass(model, jclass.getName.toCharArray', jclass.getNumberOfJobs, model.getNodeByName(jclass.getReferenceStation.getName), jclass.getPriority);
934 else
935 line_error(mfilename,'Class type not supported by JLINE.');
936 end
937 end
938
939 function from_line_links(model, jmodel)
940 connections = model.getConnectionMatrix();
941 [m, ~] = size(connections);
942 jnodes = jmodel.getNodes();
943 jclasses = jmodel.getClasses();
944 njclasses = jclasses.size();
945 line_nodes = model.getNodes;
946 sn = model.getStruct;
947 %nodevisits = cellsum(sn.nodevisits);
948 % [ ] Update to consider different weights/routing for classes
949 if isempty(sn.rtorig)
950 useLinkMethod = false; % this model did not call link()
951 else
952 jrt_matrix = jmodel.initRoutingMatrix();
953 useLinkMethod = true;
954 end
955 for i = 1:m
956 line_node = line_nodes{i};
957 for k = 1:njclasses
958 output_strat = line_node.output.outputStrategy{k};
959 switch RoutingStrategy.fromText(output_strat{2})
960 case RoutingStrategy.DISABLED
961 jnodes.get(i-1).setRouting(jclasses.get(k-1),jline.lang.constant.RoutingStrategy.DISABLED);
962 case RoutingStrategy.RAND
963 jnodes.get(i-1).setRouting(jclasses.get(k-1),jline.lang.constant.RoutingStrategy.RAND);
964 outlinks_i=find(connections(i,:));
965 if ~useLinkMethod
966 for j= outlinks_i(:)'
967 jmodel.addLink(jnodes.get(i-1), jnodes.get(j-1));
968 end
969 end
970 case RoutingStrategy.RROBIN
971 jnodes.get(i-1).setRouting(jclasses.get(k-1),jline.lang.constant.RoutingStrategy.RROBIN);
972 outlinks_i=find(connections(i,:))';
973 if useLinkMethod
974 line_error(mfilename,'RROBIN cannot be used together with the link() command.');
975 end
976 for j= outlinks_i(:)'
977 jmodel.addLink(jnodes.get(i-1), jnodes.get(j-1));
978 end
979 case RoutingStrategy.WRROBIN
980 outlinks_i=find(connections(i,:))';
981 for j= outlinks_i(:)'
982 jmodel.addLink(jnodes.get(i-1), jnodes.get(j-1));
983 end
984 if useLinkMethod
985 line_error(mfilename,'RROBIN cannot be used together with the link() command.');
986 end
987 for j= 1:length(output_strat{3})
988 node_target = jmodel.getNodeByName(output_strat{3}{j}{1}.getName());
989 weight = output_strat{3}{j}{2};
990 jnodes.get(i-1).setRouting(jclasses.get(k-1),jline.lang.constant.RoutingStrategy.WRROBIN, node_target, weight);
991 end
992 case RoutingStrategy.PROB
993 outlinks_i=find(connections(i,:));
994 jnodes.get(i-1).setRouting(jclasses.get(k-1), jline.lang.constant.RoutingStrategy.PROB);
995 if ~useLinkMethod
996 for j= outlinks_i(:)'
997 jmodel.addLink(jnodes.get(i-1), jnodes.get(j-1));
998 end
999 end
1000 if length(output_strat) >= 3
1001 probabilities = output_strat{3};
1002 for j = 1:length(probabilities)
1003 dest_idx = probabilities{j}{1}.index;
1004 if (connections(i, dest_idx) ~= 0)
1005 if useLinkMethod
1006 jrt_matrix.set(jclasses.get(k-1), jclasses.get(k-1), jnodes.get(i-1), jnodes.get(dest_idx-1), probabilities{j}{2});
1007 else
1008 jnodes.get(i-1).setProbRouting(jclasses.get(k-1), jnodes.get(dest_idx-1), probabilities{j}{2});
1009 end
1010 end
1011 end
1012 end
1013 otherwise
1014 line_warning(mfilename, sprintf('''%s'' routing strategy not supported by JLINE, setting as Disabled.\n',output_strat{2}));
1015 jnodes.get(i-1).setRouting(jclasses.get(k-1),jline.lang.constant.RoutingStrategy.DISABLED);
1016 end
1017 end
1018 end
1019 if useLinkMethod
1020 jmodel.link(jrt_matrix);
1021 % Align the sn.rtorig be the same, treating artificial
1022 % ClassSwitch nodes as if they were explicitly specified
1023 jsn = jmodel.getStruct(true);
1024 rtorig = java.util.HashMap();
1025 if ~isempty(model.sn.rtorig)
1026 if iscell(model.sn.rtorig)
1027 for r = 1:njclasses
1028 sub_rtorig = java.util.HashMap();
1029 for s = 1:njclasses
1030 sub_rtorig.put(jclasses.get(s-1), JLINE.from_line_matrix(model.sn.rtorig{r,s}));
1031 end
1032 rtorig.put(jclasses.get(r-1), sub_rtorig);
1033 end
1034 end
1035 end
1036 jsn.rtorig = rtorig;
1037 end
1038 end
1039
1040 function model = from_jline_routing(model, jnetwork)
1041 jnodes = jnetwork.getNodes();
1042 jclasses = jnetwork.getClasses();
1043 %n_classes = jclasses.size();
1044 n_nodes = jnodes.size();
1045 network_nodes = model.getNodes;
1046 network_classes = model.getClasses;
1047
1048 connections = JLINE.from_jline_matrix(jnetwork.getConnectionMatrix());
1049 [row,col] = find(connections);
1050 for i=1:length(row)
1051 model.addLink(network_nodes{row(i)},network_nodes{col(i)});
1052 end
1053
1054 for n = 1 : n_nodes
1055 jnode = jnodes.get(n-1);
1056 output_strategies = jnode.getOutputStrategies();
1057 n_strategies = output_strategies.size();
1058 for m = 1 : n_strategies
1059 output_strat = output_strategies.get(m-1);
1060 routing_strat = output_strat.getRoutingStrategy;
1061 routing_strat_classidx = output_strat.getJobClass.getIndex();
1062 switch char(routing_strat)
1063 case 'RAND'
1064 network_nodes{n}.setRouting(network_classes{routing_strat_classidx}, RoutingStrategy.RAND);
1065 case 'RROBIN'
1066 network_nodes{n}.setRouting(network_classes{routing_strat_classidx}, RoutingStrategy.RROBIN);
1067 case 'DISABLED'
1068 network_nodes{n}.setRouting(network_classes{routing_strat_classidx}, RoutingStrategy.RROBIN);
1069 end
1070 end
1071 end
1072 end
1073
1074 function model = from_jline_links(model, jnetwork)
1075 P = model.initRoutingMatrix;
1076 jnodes = jnetwork.getNodes();
1077 jclasses = jnetwork.getClasses();
1078 n_classes = jclasses.size();
1079 n_nodes = jnodes.size();
1080
1081 for n = 1 : n_nodes
1082 jnode = jnodes.get(n-1);
1083 output_strategies = jnode.getOutputStrategies();
1084 n_strategies = output_strategies.size();
1085 for m = 1 : n_strategies
1086 output_strat = output_strategies.get(m-1);
1087 dest = output_strat.getDestination();
1088 if~isempty(dest) % disabled strategy
1089 in_idx = jnetwork.getNodeIndex(jnode)+1;
1090 out_idx = jnetwork.getNodeIndex(dest)+1;
1091 if n_classes == 1
1092 P{1}(in_idx,out_idx) = output_strat.getProbability();
1093 else
1094 strat_class = output_strat.getJobClass();
1095 class_idx = jnetwork.getJobClassIndex(strat_class)+1;
1096 P{class_idx,class_idx}(in_idx,out_idx) = output_strat.getProbability();
1097 end
1098 end
1099 end
1100 end
1101 model.link(P);
1102
1103 %Align the sn.rtorig be the same (Assume Java network is
1104 %created by calling Network.link)
1105 sn = jnetwork.getStruct;
1106 rtorig = cell(n_classes, n_classes);
1107 for r = 1:n_classes
1108 for s = 1:n_classes
1109 rtorig{r,s} = JLINE.from_jline_matrix(sn.rtorig.get(jclasses.get(r-1)).get(jclasses.get(s-1)));
1110 end
1111 end
1112 model.sn.rtorig = rtorig;
1113 end
1114
1115 function [jnetwork] = from_line_network(model)
1116 %w = warning;
1117 %warning('off');
1118 sn = model.getStruct;
1119
1120 jnetwork = jline.lang.Network(model.getName);
1121 line_nodes = model.getNodes;
1122 line_classes = model.getClasses;
1123
1124 jnodes = cell(1,length(line_nodes));
1125 jclasses = cell(1,length(line_classes));
1126
1127 for n = 1 : length(line_nodes)
1128 if isa(line_nodes{n}, 'Join')
1129 jnodes{n} = JLINE.from_line_node(line_nodes{n}, jnetwork, line_classes, jnodes{line_nodes{n}.joinOf.index});
1130 else
1131 jnodes{n} = JLINE.from_line_node(line_nodes{n}, jnetwork, line_classes);
1132 end
1133 end
1134
1135 for n = 1 : length(line_classes)
1136 jclasses{n} = JLINE.from_line_class(line_classes{n}, jnetwork);
1137 end
1138
1139 % Set up forJobClass associations for signal classes
1140 for n = 1 : length(line_classes)
1141 if (isa(line_classes{n}, 'Signal') || isa(line_classes{n}, 'OpenSignal') || isa(line_classes{n}, 'ClosedSignal'))
1142 if ~isempty(line_classes{n}.targetJobClass)
1143 targetIdx = line_classes{n}.targetJobClass.index;
1144 jclasses{n}.forJobClass(jclasses{targetIdx});
1145 end
1146 end
1147 end
1148
1149 for n = 1: length(jnodes)
1150 JLINE.set_service(line_nodes{n}, jnodes{n}, line_classes);
1151 end
1152
1153 for n = 1: length(jnodes)
1154 if isa(line_nodes{n},"ClassSwitch")
1155 JLINE.set_csMatrix(line_nodes{n}, jnodes{n}, jclasses);
1156 elseif isa(line_nodes{n},"Join")
1157 jnodes{n}.initJoinJobClasses();
1158 elseif isa(line_nodes{n},"Cache")
1159 for r = 1 : sn.nclasses
1160 if length(line_nodes{n}.server.hitClass) >= r && ~isempty(line_nodes{n}.server.hitClass(r))
1161 if ~isa(line_nodes{n}.popularity{r},'Disabled')
1162 jnodes{n}.setRead(jclasses{r}, JLINE.from_line_distribution(line_nodes{n}.popularity{r}));
1163 jnodes{n}.setHitClass(jclasses{r}, jclasses{line_nodes{n}.server.hitClass(r)});
1164 jnodes{n}.setMissClass(jclasses{r}, jclasses{line_nodes{n}.server.missClass(r)});
1165 end
1166 end
1167 end
1168 % Transfer accessProb from MATLAB to Java
1169 if ~isempty(line_nodes{n}.accessProb)
1170 accessProbMat = line_nodes{n}.accessProb;
1171 [K1, K2] = size(accessProbMat);
1172 jAccessProb = javaArray('jline.util.matrix.Matrix', K1, K2);
1173 for k1 = 1:K1
1174 for k2 = 1:K2
1175 if ~isempty(accessProbMat{k1, k2})
1176 jAccessProb(k1, k2) = JLINE.from_line_matrix(accessProbMat{k1, k2});
1177 end
1178 end
1179 end
1180 jnodes{n}.setAccessProb(jAccessProb);
1181 end
1182 elseif isa(line_nodes{n}, "Transition")
1183 % First, add modes (must be done after classes are created)
1184 for m = 1:line_nodes{n}.getNumberOfModes()
1185 modeName = line_nodes{n}.modeNames{m};
1186 jmode = jnodes{n}.addMode(modeName);
1187 % Set timing strategy
1188 switch line_nodes{n}.timingStrategies(m)
1189 case TimingStrategy.TIMED
1190 jnodes{n}.setTimingStrategy(jmode, jline.lang.constant.TimingStrategy.TIMED);
1191 case TimingStrategy.IMMEDIATE
1192 jnodes{n}.setTimingStrategy(jmode, jline.lang.constant.TimingStrategy.IMMEDIATE);
1193 end
1194 % Set distribution
1195 jnodes{n}.setDistribution(jmode, JLINE.from_line_distribution(line_nodes{n}.distributions{m}));
1196 % Set firing weights and priorities
1197 jnodes{n}.setFiringWeights(jmode, line_nodes{n}.firingWeights(m));
1198 jnodes{n}.setFiringPriorities(jmode, int32(line_nodes{n}.firingPriorities(m)));
1199 % Set number of servers
1200 jnodes{n}.setNumberOfServers(jmode, java.lang.Integer(line_nodes{n}.numberOfServers(m)));
1201 end
1202 % Now set enabling conditions, inhibiting conditions, and firing outcomes
1203 jmodes = jnodes{n}.getModes();
1204 for m = 1:line_nodes{n}.getNumberOfModes()
1205 jmode = jmodes.get(m-1);
1206 enabCond = line_nodes{n}.enablingConditions{m};
1207 inhibCond = line_nodes{n}.inhibitingConditions{m};
1208 firingOut = line_nodes{n}.firingOutcomes{m};
1209 for r = 1:sn.nclasses
1210 for i = 1:length(line_nodes)
1211 % Set enabling conditions
1212 if enabCond(i, r) > 0 && isa(line_nodes{i}, 'Place')
1213 jnodes{n}.setEnablingConditions(jmode, jclasses{r}, jnodes{i}, enabCond(i, r));
1214 end
1215 % Set inhibiting conditions
1216 if inhibCond(i, r) < Inf && isa(line_nodes{i}, 'Place')
1217 jnodes{n}.setInhibitingConditions(jmode, jclasses{r}, jnodes{i}, inhibCond(i, r));
1218 end
1219 % Set firing outcomes
1220 if firingOut(i, r) ~= 0
1221 jnodes{n}.setFiringOutcome(jmode, jclasses{r}, jnodes{i}, firingOut(i, r));
1222 end
1223 end
1224 end
1225 end
1226 end
1227 end
1228
1229 % Assume JLINE and LINE network are both created via link
1230 JLINE.from_line_links(model, jnetwork);
1231
1232 % Transfer finite capacity regions from MATLAB to Java
1233 if ~isempty(model.regions)
1234 for f = 1:length(model.regions)
1235 fcr = model.regions{f};
1236 % Convert MATLAB node list to Java list
1237 javaNodeList = java.util.ArrayList();
1238 for i = 1:length(fcr.nodes)
1239 matlabNode = fcr.nodes{i};
1240 % Find corresponding Java node by name
1241 nodeName = matlabNode.getName();
1242 for j = 1:length(line_nodes)
1243 if strcmp(line_nodes{j}.getName(), nodeName)
1244 javaNodeList.add(jnodes{j});
1245 break;
1246 end
1247 end
1248 end
1249 % Create Java FCR
1250 jfcr = jnetwork.addRegion(javaNodeList);
1251 % Set global max jobs
1252 if fcr.globalMaxJobs > 0 && ~isinf(fcr.globalMaxJobs)
1253 jfcr.setGlobalMaxJobs(fcr.globalMaxJobs);
1254 end
1255 % Set per-class max jobs and drop rules
1256 for r = 1:length(line_classes)
1257 if length(fcr.classMaxJobs) >= r && fcr.classMaxJobs(r) > 0 && ~isinf(fcr.classMaxJobs(r))
1258 jfcr.setClassMaxJobs(jclasses{r}, fcr.classMaxJobs(r));
1259 end
1260 if length(fcr.dropRule) >= r
1261 jfcr.setDropRule(jclasses{r}, fcr.dropRule(r));
1262 end
1263 end
1264 end
1265 end
1266
1267 jnetwork.initDefault;
1268 for n = 1: length(line_nodes)
1269 if line_nodes{n}.isStateful
1270 jnodes{n}.setState(JLINE.from_line_matrix(line_nodes{n}.getState));
1271 jnodes{n}.setStateSpace(JLINE.from_line_matrix(line_nodes{n}.getStateSpace));
1272 jnodes{n}.setStatePrior(JLINE.from_line_matrix(line_nodes{n}.getStatePrior));
1273 end
1274 end
1275 % Force struct refresh so sn.state reflects updated node states
1276 jnetwork.setHasStruct(false);
1277
1278 end
1279
1280 function jnetwork = line_to_jline(model)
1281 jnetwork = LINE2JLINE(model);
1282 end
1283
1284 function model = jline_to_line(jnetwork)
1285 if isa(jnetwork,'JNetwork')
1286 jnetwork = jnetwork.obj;
1287 end
1288 %javaaddpath(jar_loc);
1289 model = Network(char(jnetwork.getName));
1290 network_nodes = jnetwork.getNodes;
1291 job_classes = jnetwork.getClasses;
1292
1293 line_nodes = cell(network_nodes.size,1);
1294 line_classes = cell(job_classes.size,1);
1295
1296
1297 for n = 1 : network_nodes.size
1298 if ~isa(network_nodes.get(n-1), 'jline.lang.nodes.ClassSwitch')
1299 line_nodes{n} = JLINE.from_jline_node(network_nodes.get(n-1), model, job_classes);
1300 end
1301 end
1302
1303 for n = 1 : job_classes.size
1304 line_classes{n} = JLINE.from_jline_class(job_classes.get(n-1), model);
1305 end
1306
1307 for n = 1 : network_nodes.size
1308 if isa(network_nodes.get(n-1), 'jline.lang.nodes.ClassSwitch')
1309 line_nodes{n} = JLINE.from_jline_node(network_nodes.get(n-1), model, job_classes);
1310 end
1311 end
1312
1313 for n = 1 : network_nodes.size
1314 JLINE.set_line_service(network_nodes.get(n-1), line_nodes{n}, job_classes, line_classes);
1315 end
1316
1317 if ~isempty(jnetwork.getStruct.rtorig)
1318 % Use link() method
1319 model = JLINE.from_jline_links(model, jnetwork);
1320 else
1321 % Do not use link() method
1322 model = JLINE.from_jline_routing(model, jnetwork);
1323 end
1324 end
1325
1326 function matrix = arraylist_to_matrix(jline_matrix)
1327 if isempty(jline_matrix)
1328 matrix = [];
1329 else
1330 matrix = zeros(jline_matrix.size(), 1);
1331 for row = 1:jline_matrix.size()
1332 matrix(row, 1) = jline_matrix.get(row-1);
1333 end
1334 end
1335 end
1336
1337 function matrix = from_jline_matrix(jline_matrix)
1338 if isempty(jline_matrix)
1339 matrix = [];
1340 else
1341 matrix = zeros(jline_matrix.getNumRows(), jline_matrix.getNumCols());
1342 for row = 1:jline_matrix.getNumRows()
1343 for col = 1:jline_matrix.getNumCols()
1344 val = jline_matrix.get(row-1, col-1);
1345 if (val >= 33333333 && val <= 33333334)
1346 matrix(row, col) = GlobalConstants.Immediate;
1347 elseif (val >= -33333334 && val <= -33333333)
1348 matrix(row, col) = -GlobalConstants.Immediate;
1349 elseif (val >= 2147483647 - 1) % Integer.MAX_VALUE with -1 tolerance
1350 matrix(row, col) = Inf;
1351 elseif (val <= -2147483648 + 1) % Integer.MIN_VALUE with +1 tolerance
1352 matrix(row, col) = -Inf;
1353 else
1354 matrix(row, col) = val;
1355 end
1356 end
1357 end
1358 end
1359 end
1360
1361 function jline_matrix = from_line_matrix(matrix)
1362 [rows, cols] = size(matrix);
1363 jline_matrix = jline.util.matrix.Matrix(rows, cols);
1364 for row = 1:rows
1365 for col = 1:cols
1366 if matrix(row,col) ~= 0
1367 jline_matrix.set(row-1, col-1, matrix(row, col));
1368 end
1369 end
1370 end
1371 end
1372
1373 function lsn = from_jline_struct_layered(jlayerednetwork, jlsn)
1374 lsn = LayeredNetworkStruct();
1375 lsn.nidx= jlsn.nidx;
1376 lsn.nhosts= jlsn.nhosts;
1377 lsn.ntasks= jlsn.ntasks;
1378 lsn.nentries= jlsn.nentries;
1379 lsn.nacts= jlsn.nacts;
1380 lsn.ncalls= jlsn.ncalls;
1381 lsn.hshift= jlsn.hshift;
1382 lsn.tshift= jlsn.tshift;
1383 lsn.eshift= jlsn.eshift;
1384 lsn.ashift= jlsn.ashift;
1385 lsn.cshift= jlsn.cshift;
1386 for h=1:jlsn.nhosts
1387 lsn.tasksof{h,1} = JLINE.arraylist_to_matrix(jlsn.tasksof.get(uint32(h)))';
1388 end
1389 for t=1:jlsn.ntasks
1390 lsn.entriesof{lsn.tshift+t,1} = JLINE.arraylist_to_matrix(jlsn.entriesof.get(uint32(jlsn.tshift+t)))';
1391 end
1392 for t=1:(jlsn.ntasks+jlsn.nentries)
1393 lsn.actsof{lsn.tshift+t,1} = JLINE.arraylist_to_matrix(jlsn.actsof.get(uint32(jlsn.tshift+t)))';
1394 end
1395 for a=1:jlsn.nacts
1396 lsn.callsof{lsn.ashift+a,1} = JLINE.arraylist_to_matrix(jlsn.callsof.get(uint32(jlsn.ashift+a)))';
1397 end
1398 for i = 1:jlsn.sched.size
1399 lsn.sched(i,1) = SchedStrategy.(char(jlsn.sched.get(uint32(i))));
1400 end
1401 for i = 1:jlsn.names.size
1402 lsn.names{i,1} = jlsn.names.get(uint32(i));
1403 lsn.hashnames{i,1} = jlsn.hashnames.get(uint32(i));
1404 end
1405 lsn.mult = JLINE.from_jline_matrix(jlsn.mult);
1406 lsn.mult = lsn.mult(2:(lsn.eshift+1))'; % remove 0-padding
1407 lsn.maxmult = JLINE.from_jline_matrix(jlsn.maxmult);
1408 lsn.maxmult = lsn.maxmult(2:(lsn.eshift+1))'; % remove 0-padding
1409
1410 lsn.repl = JLINE.from_jline_matrix(jlsn.repl)';
1411 lsn.repl = lsn.repl(2:end); % remove 0-padding
1412 lsn.type = JLINE.from_jline_matrix(jlsn.type)';
1413 lsn.type = lsn.type(2:end); % remove 0-padding
1414 lsn.parent = JLINE.from_jline_matrix(jlsn.parent);
1415 lsn.parent = lsn.parent(2:end); % remove 0-padding
1416 lsn.nitems = JLINE.from_jline_matrix(jlsn.nitems);
1417 % Ensure proper column vector format matching MATLAB's (nhosts+ntasks+nentries) x 1
1418 if isrow(lsn.nitems)
1419 lsn.nitems = lsn.nitems(2:end)'; % remove 0-padding and transpose
1420 else
1421 lsn.nitems = lsn.nitems(2:end); % remove 0-padding (already column)
1422 end
1423 % Ensure correct size
1424 expectedSize = lsn.nhosts + lsn.ntasks + lsn.nentries;
1425 if length(lsn.nitems) < expectedSize
1426 lsn.nitems(expectedSize,1) = 0;
1427 elseif length(lsn.nitems) > expectedSize
1428 lsn.nitems = lsn.nitems(1:expectedSize);
1429 end
1430 lsn.replacestrat = JLINE.from_jline_matrix(jlsn.replacestrat);
1431 lsn.replacestrat = lsn.replacestrat(2:end)'; % remove 0-padding
1432 for i = 1:jlsn.callnames.size
1433 lsn.callnames{i,1} = jlsn.callnames.get(uint32(i));
1434 lsn.callhashnames{i,1} = jlsn.callhashnames.get(uint32(i));
1435 end
1436 for i = 1:jlsn.calltype.size % calltype may be made into a matrix in Java
1437 ct = char(jlsn.calltype.get(uint32(i)));
1438 lsn.calltype(i) = CallType.(ct);
1439 end
1440 lsn.calltype = sparse(lsn.calltype'); % remove 0-padding
1441 lsn.callpair = JLINE.from_jline_matrix(jlsn.callpair);
1442 lsn.callpair = lsn.callpair(2:end,2:end); % remove 0-paddings
1443 if isempty(lsn.callpair)
1444 lsn.callpair=[];
1445 end
1446 lsn.actpretype = sparse(JLINE.from_jline_matrix(jlsn.actpretype)');
1447 lsn.actpretype = lsn.actpretype(2:end); % remove 0-padding
1448 lsn.actposttype = sparse(JLINE.from_jline_matrix(jlsn.actposttype)');
1449 lsn.actposttype = lsn.actposttype(2:end); % remove 0-padding
1450 lsn.graph = JLINE.from_jline_matrix(jlsn.graph);
1451 lsn.graph = lsn.graph(2:end,2:end); % remove 0-paddings
1452 lsn.dag = JLINE.from_jline_matrix(jlsn.dag);
1453 lsn.dag = lsn.dag(2:end,2:end); % remove 0-paddings
1454 lsn.taskgraph = JLINE.from_jline_matrix(jlsn.taskgraph);
1455 lsn.taskgraph = sparse(lsn.taskgraph(2:end,2:end)); % remove 0-paddings
1456 lsn.replygraph = JLINE.from_jline_matrix(jlsn.replygraph);
1457 lsn.replygraph = logical(lsn.replygraph(2:end,2:end)); % remove 0-paddings
1458 lsn.iscache = JLINE.from_jline_matrix(jlsn.iscache);
1459 % Ensure proper column vector format matching MATLAB's (nhosts+ntasks) x 1
1460 expectedCacheSize = lsn.nhosts + lsn.ntasks;
1461 if isrow(lsn.iscache)
1462 if length(lsn.iscache) > expectedCacheSize
1463 lsn.iscache = lsn.iscache(2:(expectedCacheSize+1))'; % remove 0-padding and transpose
1464 else
1465 lsn.iscache = lsn.iscache'; % just transpose
1466 end
1467 end
1468 % Ensure correct size
1469 if length(lsn.iscache) < expectedCacheSize
1470 lsn.iscache(expectedCacheSize,1) = 0;
1471 elseif length(lsn.iscache) > expectedCacheSize
1472 lsn.iscache = lsn.iscache(1:expectedCacheSize);
1473 end
1474 lsn.iscaller = JLINE.from_jline_matrix(jlsn.iscaller);
1475 lsn.iscaller = full(lsn.iscaller(2:end,2:end)); % remove 0-paddings
1476 lsn.issynccaller = JLINE.from_jline_matrix(jlsn.issynccaller);
1477 lsn.issynccaller = full(lsn.issynccaller(2:end,2:end)); % remove 0-paddings
1478 lsn.isasynccaller = JLINE.from_jline_matrix(jlsn.isasynccaller);
1479 lsn.isasynccaller = full(lsn.isasynccaller(2:end,2:end)); % remove 0-paddings
1480 lsn.isref = JLINE.from_jline_matrix(jlsn.isref);
1481 lsn.isref = lsn.isref(2:end)'; % remove 0-paddings
1482 end
1483
1484 function sn = from_jline_struct(jnetwork, jsn)
1485 %lst, rtfun and cdscaling are not implemented
1486 %Due to the transformation of Java lambda to matlab function
1487 if nargin<2
1488 jsn = jnetwork.getStruct(false);
1489 end
1490 jclasses = jnetwork.getClasses();
1491 jnodes = jnetwork.getNodes();
1492 jstateful = jnetwork.getStatefulNodes();
1493 jstations = jnetwork.getStations();
1494 sn = NetworkStruct();
1495
1496 sn.nnodes = jsn.nnodes;
1497 sn.nclasses = jsn.nclasses;
1498 sn.nclosedjobs = jsn.nclosedjobs;
1499 sn.nstations = jsn.nstations;
1500 sn.nstateful = jsn.nstateful;
1501 sn.nchains = jsn.nchains;
1502
1503 sn.refstat = JLINE.from_jline_matrix(jsn.refstat) + 1;
1504 sn.njobs = JLINE.from_jline_matrix(jsn.njobs);
1505 sn.nservers = JLINE.from_jline_matrix(jsn.nservers);
1506 sn.connmatrix = JLINE.from_jline_matrix(jsn.connmatrix);
1507 % Fix for Java getConnectionMatrix bug: ensure connmatrix is nnodes x nnodes
1508 if size(sn.connmatrix,1) < sn.nnodes
1509 sn.connmatrix(sn.nnodes,1) = 0;
1510 end
1511 if size(sn.connmatrix,2) < sn.nnodes
1512 sn.connmatrix(1,sn.nnodes) = 0;
1513 end
1514 sn.scv = JLINE.from_jline_matrix(jsn.scv);
1515 sn.isstation = logical(JLINE.from_jline_matrix(jsn.isstation));
1516 sn.isstateful = logical(JLINE.from_jline_matrix(jsn.isstateful));
1517 sn.isstatedep = logical(JLINE.from_jline_matrix(jsn.isstatedep));
1518 sn.nodeToStateful = JLINE.from_jline_matrix(jsn.nodeToStateful)+1;
1519 sn.nodeToStateful(sn.nodeToStateful==0) = nan;
1520 sn.nodeToStation = JLINE.from_jline_matrix(jsn.nodeToStation)+1;
1521 sn.nodeToStation(sn.nodeToStation==0) = nan;
1522 sn.stationToNode = JLINE.from_jline_matrix(jsn.stationToNode)+1;
1523 sn.stationToNode(sn.stationToNode==0) = nan;
1524 sn.stationToStateful = JLINE.from_jline_matrix(jsn.stationToStateful)+1;
1525 sn.stationToStateful(sn.stationToStateful==0) = nan;
1526 sn.statefulToStation = JLINE.from_jline_matrix(jsn.statefulToStation)+1;
1527 sn.statefulToStation(sn.statefulToStation==0) = nan;
1528 sn.statefulToNode = JLINE.from_jline_matrix(jsn.statefulToNode)+1;
1529 sn.statefulToNode(sn.statefulToNode==0) = nan;
1530 sn.rates = JLINE.from_jline_matrix(jsn.rates);
1531 sn.fj = JLINE.from_jline_matrix(jsn.fj);
1532 sn.classprio = JLINE.from_jline_matrix(jsn.classprio);
1533 sn.phases = JLINE.from_jline_matrix(jsn.phases);
1534 sn.phasessz = JLINE.from_jline_matrix(jsn.phasessz);
1535 sn.phaseshift = JLINE.from_jline_matrix(jsn.phaseshift);
1536 sn.schedparam = JLINE.from_jline_matrix(jsn.schedparam);
1537 sn.chains = logical(JLINE.from_jline_matrix(jsn.chains));
1538 sn.rt = JLINE.from_jline_matrix(jsn.rt);
1539 sn.nvars = JLINE.from_jline_matrix(jsn.nvars);
1540 sn.rtnodes = JLINE.from_jline_matrix(jsn.rtnodes);
1541 sn.csmask = logical(JLINE.from_jline_matrix(jsn.csmask));
1542 sn.isslc = logical(JLINE.from_jline_matrix(jsn.isslc));
1543 sn.cap = JLINE.from_jline_matrix(jsn.cap);
1544 sn.classcap = JLINE.from_jline_matrix(jsn.classcap);
1545 sn.refclass = JLINE.from_jline_matrix(jsn.refclass)+1;
1546 sn.lldscaling = JLINE.from_jline_matrix(jsn.lldscaling);
1547
1548 if ~isempty(jsn.cdscaling)
1549 %Not implemented since related to lambda function
1550 else
1551 sn.cdscaling = cell(sn.nstations, 0);
1552 end
1553
1554 if ~isempty(jsn.nodetype)
1555 sn.nodetype = zeros(sn.nnodes, 1);
1556 for i = 1:jsn.nodetype.size
1557 nodetype = jsn.nodetype.get(i-1);
1558 switch nodetype.name().toCharArray'
1559 case 'Queue'
1560 sn.nodetype(i) = NodeType.Queue;
1561 case 'Delay'
1562 sn.nodetype(i) = NodeType.Delay;
1563 case 'Source'
1564 sn.nodetype(i) = NodeType.Source;
1565 case 'Sink'
1566 sn.nodetype(i) = NodeType.Sink;
1567 case 'Join'
1568 sn.nodetype(i) = NodeType.Join;
1569 case 'Fork'
1570 sn.nodetype(i) = NodeType.Fork;
1571 case 'ClassSwitch'
1572 sn.nodetype(i) = NodeType.ClassSwitch;
1573 case 'Logger'
1574 sn.nodetype(i) = NodeType.Logger;
1575 case 'Cache'
1576 sn.nodetype(i) = NodeType.Cache;
1577 case 'Place'
1578 sn.nodetype(i) = NodeType.Place;
1579 case 'Transition'
1580 sn.nodetype(i) = NodeType.Transition;
1581 case 'Router'
1582 sn.nodetype(i) = NodeType.Router;
1583 end
1584 end
1585 else
1586 sn.nodetype = [];
1587 end
1588
1589 if ~isempty(jsn.classnames)
1590 for i = 1:jsn.classnames.size
1591 sn.classnames(i,1) = jsn.classnames.get(i-1);
1592 end
1593 else
1594 sn.classnames = [];
1595 end
1596
1597 if ~isempty(jsn.nodenames)
1598 for i = 1:jsn.nodenames.size
1599 sn.nodenames(i,1) = jsn.nodenames.get(i-1);
1600 end
1601 else
1602 sn.nodenames = [];
1603 end
1604
1605 if ~isempty(jsn.rtorig) && jsn.rtorig.size()>0
1606 sn.rtorig = cell(sn.nclasses, sn.nclasses);
1607 for r = 1:sn.nclasses
1608 for s = 1:sn.nclasses
1609 sn.rtorig{r,s} = JLINE.from_jline_matrix(jsn.rtorig.get(jclasses.get(r-1)).get(jclasses.get(s-1)));
1610 end
1611 end
1612 else
1613 sn.rtorig = {};
1614 end
1615
1616 if ~isempty(jsn.state)
1617 sn.state = cell(sn.nstateful, 1);
1618 for i = 1:sn.nstateful
1619 sn.state{i} = JLINE.from_jline_matrix(jstateful.get(i-1).getState());
1620 end
1621 else
1622 sn.state = {};
1623 end
1624
1625 if ~isempty(jsn.stateprior)
1626 sn.stateprior = cell(sn.nstateful, 1);
1627 for i = 1:sn.nstateful
1628 sn.stateprior{i} = JLINE.from_jline_matrix(jstateful.get(i-1).getStatePrior());
1629 end
1630 else
1631 sn.stateprior = {};
1632 end
1633
1634 if ~isempty(jsn.space)
1635 sn.space = cell(sn.nstateful, 1);
1636 for i = 1:sn.nstateful
1637 sn.space{i} = JLINE.from_jline_matrix(jstateful.get(i-1).getStateSpace());
1638 end
1639 else
1640 sn.space = {};
1641 end
1642
1643 if ~isempty(jsn.routing)
1644 sn.routing = zeros(sn.nnodes, sn.nclasses);
1645 for i = 1:sn.nnodes
1646 for j = 1:sn.nclasses
1647 routingStrategy = jsn.routing.get(jnodes.get(i-1)).get(jclasses.get(j-1));
1648 switch routingStrategy.name().toCharArray'
1649 case 'PROB'
1650 sn.routing(i,j) = RoutingStrategy.PROB;
1651 case 'RAND'
1652 sn.routing(i,j) = RoutingStrategy.RAND;
1653 case 'RROBIN'
1654 sn.routing(i,j) = RoutingStrategy.RROBIN;
1655 case 'WRROBIN'
1656 sn.routing(i,j) = RoutingStrategy.WRROBIN;
1657 case 'JSQ'
1658 sn.routing(i,j) = RoutingStrategy.JSQ;
1659 case 'DISABLED'
1660 sn.routing(i,j) = RoutingStrategy.DISABLED;
1661 case 'FIRING'
1662 sn.routing(i,j) = RoutingStrategy.FIRING;
1663 case 'KCHOICES'
1664 sn.routing(i,j) = RoutingStrategy.KCHOICES;
1665 end
1666 end
1667 end
1668 else
1669 sn.routing = [];
1670 end
1671
1672 if ~isempty(jsn.proctype)
1673 sn.procid = zeros(sn.nstations, sn.nclasses);
1674 for i = 1:sn.nstations
1675 for j = 1:sn.nclasses
1676 processType = jsn.proctype.get(jstations.get(i-1)).get(jclasses.get(j-1));
1677 %Only EXP, ERLANG, HYPEREXP, APH, COXIAN, IMMEDIATE
1678 %DISABLED are implemented in JLINE.
1679 switch processType.name.toCharArray'
1680 case 'EXP'
1681 sn.procid(i,j) = ProcessType.EXP;
1682 case 'ERLANG'
1683 sn.procid(i,j) = ProcessType.ERLANG;
1684 case 'HYPEREXP'
1685 sn.procid(i,j) = ProcessType.HYPEREXP;
1686 case 'PH'
1687 sn.procid(i,j) = ProcessType.PH;
1688 case 'APH'
1689 sn.procid(i,j) = ProcessType.APH;
1690 case 'MAP'
1691 sn.procid(i,j) = ProcessType.MAP;
1692 case 'UNIFORM'
1693 sn.procid(i,j) = ProcessType.UNIFORM;
1694 case 'DET'
1695 sn.procid(i,j) = ProcessType.DET;
1696 case 'COXIAN'
1697 sn.procid(i,j) = ProcessType.COXIAN;
1698 case 'GAMMA'
1699 sn.procid(i,j) = ProcessType.GAMMA;
1700 case 'PARETO'
1701 sn.procid(i,j) = ProcessType.PARETO;
1702 case 'WEIBULL'
1703 sn.procid(i,j) = ProcessType.WEIBULL;
1704 case 'LOGNORMAL'
1705 sn.procid(i,j) = ProcessType.LOGNORMAL;
1706 case 'MMPP2'
1707 sn.procid(i,j) = ProcessType.MMPP2;
1708 case 'REPLAYER'
1709 sn.procid(i,j) = ProcessType.REPLAYER;
1710 case 'TRACE'
1711 sn.procid(i,j) = ProcessType.TRACE;
1712 case 'IMMEDIATE'
1713 sn.procid(i,j) = ProcessType.IMMEDIATE;
1714 case 'DISABLED'
1715 sn.procid(i,j) = ProcessType.DISABLED;
1716 case 'COX2'
1717 sn.procid(i,j) = ProcessType.COX2;
1718 end
1719 end
1720 end
1721 else
1722 sn.procid = [];
1723 end
1724
1725 if ~isempty(jsn.mu)
1726 sn.mu = cell(sn.nstations, 1);
1727 for i = 1:sn.nstations
1728 sn.mu{i} = cell(1, sn.nclasses);
1729 for j = 1:sn.nclasses
1730 sn.mu{i}{j} = JLINE.from_jline_matrix(jsn.mu.get(jstations.get(i-1)).get(jclasses.get(j-1)));
1731 end
1732 end
1733 else
1734 sn.mu = {};
1735 end
1736
1737 if ~isempty(jsn.phi)
1738 sn.phi = cell(sn.nstations, 1);
1739 for i = 1:sn.nstations
1740 sn.phi{i} = cell(1, sn.nclasses);
1741 for j = 1:sn.nclasses
1742 sn.phi{i}{j} = JLINE.from_jline_matrix(jsn.phi.get(jstations.get(i-1)).get(jclasses.get(j-1)));
1743 end
1744 end
1745 else
1746 sn.phi = {};
1747 end
1748
1749 if ~isempty(jsn.proc)
1750 sn.proc = cell(sn.nstations, 1);
1751 for i = 1:sn.nstations
1752 sn.proc{i} = cell(1, sn.nclasses);
1753 for j = 1:sn.nclasses
1754 proc_i_j = jsn.proc.get(jstations.get(i-1)).get(jclasses.get(j-1));
1755 sn.proc{i}{j} = cell(1, proc_i_j.size);
1756 for k = 1:proc_i_j.size
1757 sn.proc{i}{j}{k} = JLINE.from_jline_matrix(proc_i_j.get(uint32(k-1)));
1758 end
1759 end
1760 end
1761 else
1762 sn.proc = {};
1763 end
1764
1765 if ~isempty(jsn.pie)
1766 sn.pie = cell(sn.nstations, 1);
1767 for i = 1:sn.nstations
1768 sn.pie{i} = cell(1, sn.nclasses);
1769 for j = 1:sn.nclasses
1770 sn.pie{i}{j} = JLINE.from_jline_matrix(jsn.pie.get(jstations.get(i-1)).get(jclasses.get(j-1)));
1771 end
1772 end
1773 else
1774 sn.pie = {};
1775 end
1776
1777 if ~isempty(jsn.sched)
1778 sn.sched = zeros(sn.nstations, 1);
1779 for i = 1:sn.nstations
1780 schedStrategy = jsn.sched.get(jstations.get(i-1));
1781 switch schedStrategy.name.toCharArray'
1782 case 'INF'
1783 sn.sched(i) = SchedStrategy.INF;
1784 case 'FCFS'
1785 sn.sched(i) = SchedStrategy.FCFS;
1786 case 'LCFS'
1787 sn.sched(i) = SchedStrategy.LCFS;
1788 case 'LCFSPR'
1789 sn.sched(i) = SchedStrategy.LCFSPR;
1790 case 'SIRO'
1791 sn.sched(i) = SchedStrategy.SIRO;
1792 case 'SJF'
1793 sn.sched(i) = SchedStrategy.SJF;
1794 case 'LJF'
1795 sn.sched(i) = SchedStrategy.LJF;
1796 case 'PS'
1797 sn.sched(i) = SchedStrategy.PS;
1798 case 'DPS'
1799 sn.sched(i) = SchedStrategy.DPS;
1800 case 'GPS'
1801 sn.sched(i) = SchedStrategy.GPS;
1802 case 'PSPRIO'
1803 sn.sched(i) = SchedStrategy.PSPRIO;
1804 case 'DPSPRIO'
1805 sn.sched(i) = SchedStrategy.DPSPRIO;
1806 case 'GPSPRIO'
1807 sn.sched(i) = SchedStrategy.GPSPRIO;
1808 case 'SEPT'
1809 sn.sched(i) = SchedStrategy.SEPT;
1810 case 'LEPT'
1811 sn.sched(i) = SchedStrategy.LEPT;
1812 case {'HOL', 'FCFSPRIO'}
1813 sn.sched(i) = SchedStrategy.FCFSPRIO;
1814 case 'FORK'
1815 sn.sched(i) = SchedStrategy.FORK;
1816 case 'EXT'
1817 sn.sched(i) = SchedStrategy.EXT;
1818 case 'REF'
1819 sn.sched(i) = SchedStrategy.REF;
1820 end
1821 end
1822 else
1823 sn.sched = [];
1824 end
1825
1826 if ~isempty(jsn.inchain)
1827 sn.inchain = cell(1, sn.nchains);
1828 for i = 1:sn.nchains
1829 sn.inchain{1,i} = JLINE.from_jline_matrix(jsn.inchain.get(uint32(i-1)))+1;
1830 end
1831 else
1832 sn.inchain = {};
1833 end
1834
1835 if ~isempty(jsn.visits)
1836 sn.visits = cell(sn.nchains, 1);
1837 for i = 1:sn.nchains
1838 sn.visits{i,1} = JLINE.from_jline_matrix(jsn.visits.get(uint32(i-1)));
1839 end
1840 else
1841 sn.visits = {};
1842 end
1843
1844 if ~isempty(jsn.nodevisits)
1845 sn.nodevisits = cell(1, sn.nchains);
1846 for i = 1:sn.nchains
1847 sn.nodevisits{1,i} = JLINE.from_jline_matrix(jsn.nodevisits.get(uint32(i-1)));
1848 end
1849 else
1850 sn.nodevisits = {};
1851 end
1852
1853 if ~isempty(jsn.droprule)
1854 sn.droprule = zeros(sn.nstations, sn.nclasses);
1855 for i = 1:sn.nstations
1856 for j = 1:sn.nclasses
1857 dropStrategy = jsn.droprule.get(jstations.get(i-1)).get(jclasses.get(j-1));
1858 switch dropStrategy.name.toCharArray'
1859 case 'WaitingQueue'
1860 sn.droprule(i,j) = DropStrategy.WAITQ;
1861 case 'Drop'
1862 sn.droprule(i,j) = DropStrategy.DROP;
1863 case 'BlockingAfterService'
1864 sn.droprule(i,j) = DropStrategy.BAS;
1865 end
1866 end
1867 end
1868 else
1869 sn.droprule = [];
1870 end
1871
1872 if ~isempty(jsn.nodeparam)
1873 sn.nodeparam = cell(sn.nnodes, 1);
1874
1875 for i = 1:sn.nnodes
1876 jnode = jnodes.get(i-1);
1877 jparam = jsn.nodeparam.get(jnode);
1878
1879 %if jparam.isEmpty
1880 % sn.nodeparam{i} = [];
1881 % continue;
1882 %end
1883
1884 % StationNodeParam
1885 if isa(jparam, 'jline.lang.nodeparam.StationNodeParam')
1886 if ~isempty(jparam.fileName)
1887 sn.nodeparam{i}.fileName = cell(1, sn.nclasses);
1888 for r = 1:sn.nclasses
1889 fname = jparam.fileName.get(r-1);
1890 if ~isempty(fname)
1891 sn.nodeparam{i}.fileName{r} = char(fname);
1892 end
1893 end
1894 end
1895 end
1896
1897 % TransitionNodeParam
1898 if isa(jparam, 'jline.lang.nodeparam.TransitionNodeParam')
1899 if ~isempty(jparam.firingprocid)
1900 sn.nodeparam{i}.firingprocid = containers.Map('KeyType', 'char', 'ValueType', 'any');
1901 keys = jparam.firingprocid.keySet.iterator;
1902 while keys.hasNext
1903 key = keys.next;
1904 proc = jparam.firingprocid.get(key);
1905 sn.nodeparam{i}.firingprocid(char(key.toString)) = char(proc.toString);
1906 end
1907 end
1908 if ~isempty(jparam.firingphases)
1909 sn.nodeparam{i}.firingphases = JLINE.from_jline_matrix(jparam.firingphases);
1910 end
1911 if ~isempty(jparam.fireweight)
1912 sn.nodeparam{i}.fireweight = JLINE.from_jline_matrix(jparam.fireweight);
1913 end
1914 end
1915
1916 % JoinNodeParam
1917 if isa(jparam, 'jline.lang.nodeparam.JoinNodeParam')
1918 if ~isempty(jparam.joinStrategy)
1919 sn.nodeparam{i}.joinStrategy = cell(1, sn.nclasses);
1920 sn.nodeparam{i}.fanIn = cell(1, sn.nclasses);
1921 for r = 1:sn.nclasses
1922 jclass = jclasses.get(r-1);
1923 joinStrategy = jparam.joinStrategy.get(jclass);
1924 if ~isempty(joinStrategy)
1925 strategyStr = char(joinStrategy.name.toString);
1926 switch strategyStr
1927 case 'STD'
1928 sn.nodeparam{i}.joinStrategy{r} = JoinStrategy.STD;
1929 case 'PARTIAL'
1930 sn.nodeparam{i}.joinStrategy{r} = JoinStrategy.PARTIAL;
1931 otherwise
1932 sn.nodeparam{i}.joinStrategy{r} = strategyStr;
1933 end
1934 sn.nodeparam{i}.fanIn{r} = jparam.fanIn.get(jclass);
1935 end
1936 end
1937 end
1938 end
1939
1940 % RoutingNodeParam
1941 if isa(jparam, 'jline.lang.nodeparam.RoutingNodeParam')
1942 for r = 1:sn.nclasses
1943 jclass = jclasses.get(r-1);
1944
1945 if ~isempty(jparam.weights) && jparam.weights.containsKey(jclass)
1946 sn.nodeparam{i}.weights{r} = JLINE.from_jline_matrix(jparam.weights.get(jclass));
1947 end
1948
1949 if ~isempty(jparam.outlinks) && jparam.outlinks.containsKey(jclass)
1950 sn.nodeparam{i}.outlinks{r} = JLINE.from_jline_matrix(jparam.outlinks.get(jclass));
1951 end
1952 end
1953 end
1954
1955 % ForkNodeParam
1956 if isa(jparam, 'jline.lang.nodeparam.ForkNodeParam')
1957 if ~isnan(jparam.fanOut)
1958 sn.nodeparam{i}.fanOut = jparam.fanOut;
1959 end
1960 end
1961
1962 % CacheNodeParam
1963 if isa(jparam, 'jline.lang.nodeparam.CacheNodeParam')
1964 % nitems
1965 if ~isnan(jparam.nitems)
1966 sn.nodeparam{i}.nitems = jparam.nitems;
1967 end
1968
1969 % accost
1970 if ~isempty(jparam.accost)
1971 % For Java 2D arrays (Matrix[][]), size(arr,2) returns 1 in MATLAB
1972 % We need to get length of first row to get actual second dimension
1973 K1 = size(jparam.accost, 1);
1974 if K1 > 0
1975 firstRow = jparam.accost(1); % Get first row (Java array)
1976 K2 = length(firstRow);
1977 else
1978 K2 = 0;
1979 end
1980 sn.nodeparam{i}.accost = cell(K1, K2);
1981 for k1 = 1:K1
1982 for k2 = 1:K2
1983 mat = jparam.accost(k1, k2); % MATLAB handles Java array indexing
1984 if ~isempty(mat)
1985 sn.nodeparam{i}.accost{k1, k2} = JLINE.from_jline_matrix(mat);
1986 end
1987 end
1988 end
1989 end
1990
1991 % itemcap
1992 if ~isempty(jparam.itemcap)
1993 sn.nodeparam{i}.itemcap = JLINE.from_jline_matrix(jparam.itemcap);
1994 end
1995
1996 % pread - convert from Java Map<Integer, List<Double>> to MATLAB cell array {R}
1997 if ~isempty(jparam.pread)
1998 nclasses = sn.nclasses;
1999 sn.nodeparam{i}.pread = cell(1, nclasses);
2000 for r = 1:nclasses
2001 list = jparam.pread.get(int32(r-1)); % Java 0-based indexing
2002 if ~isempty(list)
2003 values = zeros(1, list.size);
2004 for j = 1:list.size
2005 values(j) = list.get(j-1);
2006 end
2007 sn.nodeparam{i}.pread{r} = values;
2008 else
2009 sn.nodeparam{i}.pread{r} = NaN;
2010 end
2011 end
2012 end
2013
2014 % replacestrat
2015 if ~isempty(jparam.replacestrat)
2016 switch char(jparam.replacestrat)
2017 case 'RR'
2018 sn.nodeparam{i}.replacestrat = ReplacementStrategy.RR;
2019 case 'FIFO'
2020 sn.nodeparam{i}.replacestrat = ReplacementStrategy.FIFO;
2021 case 'SFIFO'
2022 sn.nodeparam{i}.replacestrat = ReplacementStrategy.SFIFO;
2023 case 'LRU'
2024 sn.nodeparam{i}.replacestrat = ReplacementStrategy.LRU;
2025 end
2026 end
2027
2028 % hitclass
2029 if ~isempty(jparam.hitclass)
2030 sn.nodeparam{i}.hitclass = 1+JLINE.from_jline_matrix(jparam.hitclass);
2031 end
2032
2033 % missclass
2034 if ~isempty(jparam.missclass)
2035 sn.nodeparam{i}.missclass =1+ JLINE.from_jline_matrix(jparam.missclass);
2036 end
2037
2038 % actual hit/miss probabilities
2039 if ~isempty(jparam.actualhitprob)
2040 sn.nodeparam{i}.actualhitprob = JLINE.from_jline_matrix(jparam.actualhitprob);
2041 end
2042 if ~isempty(jparam.actualmissprob)
2043 sn.nodeparam{i}.actualmissprob = JLINE.from_jline_matrix(jparam.actualmissprob);
2044 end
2045 end
2046 end
2047 else
2048 sn.nodeparam = {};
2049 end
2050
2051 % if ~isempty(jsn.nodeparam)
2052 % sn.nodeparam = cell(sn.nnodes, 1);
2053 % % Note that JLINE only support node parameters related to
2054 % % Fork, Join, WWROBIN and RROBIN
2055 % for i = 1:sn.nnodes
2056 % if jsn.nodeparam.get(jnodes.get(i-1)).isEmpty
2057 % sn.nodeparam{i} = [];
2058 % else
2059 % if ~isnan(jsn.nodeparam.get(jnodes.get(i-1)).nitems)
2060 % sn.nodeparam{i}.nitems = jsn.nodeparam.get(jnodes.get(i-1)).nitems;
2061 % end
2062 % if ~isnan(jsn.nodeparam.get(jnodes.get(i-1)).fanOut)
2063 % sn.nodeparam{i}.fanOut = jsn.nodeparam.get(jnodes.get(i-1)).fanOut;
2064 % end
2065 % if ~isempty(jsn.nodeparam.get(jnodes.get(i-1)).joinStrategy)
2066 % if ~jsn.nodeparam.get(jnodes.get(i-1)).joinStrategy.isEmpty
2067 % sn.nodeparam{i}.joinStrategy = cell(1, sn.nclasses);
2068 % sn.nodeparam{i}.fanIn = cell(1, sn.nclasses);
2069 % for r = 1:sn.nclasses
2070 % joinStrategy = jsn.nodeparam.get(jnodes.get(i-1)).joinStrategy.get(jclasses.get(r-1));
2071 % switch joinStrategy.name.toCharArray'
2072 % case 'STD'
2073 % sn.nodeparam{i}.joinStrategy{r} = JoinStrategy.STD;
2074 % case 'PARTIAL'
2075 % sn.nodeparam{i}.joinStrategy{r} = JoinStrategy.PARTIAL;
2076 % end
2077 % sn.nodeparam{i}.fanIn{r} = jsn.nodeparam.get(jnodes.get(i-1)).fanIn.get(jclasses.get(r-1));
2078 % end
2079 % end
2080 % end
2081 %
2082 % if ~isempty(jsn.nodeparam.get(jnodes.get(i-1)).weights)
2083 % for r = 1:sn.nclasses
2084 % sn.nodeparam{i}{r}.weights = JLINE.from_jline_matrix(jsn.nodeparam.get(jnodes.get(i-1)).weights.get(jclasses.get(r-1)));
2085 % end
2086 % end
2087 %
2088 % if ~isempty(jsn.nodeparam.get(jnodes.get(i-1)).outlinks)
2089 % for r = 1:sn.nclasses
2090 % sn.nodeparam{i}{r}.outlinks = JLINE.from_jline_matrix(jsn.nodeparam.get(jnodes.get(i-1)).outlinks.get(jclasses.get(r-1)));
2091 % end
2092 % end
2093 % end
2094 % end
2095 % else
2096 % sn.nodeparam = {};
2097 % end
2098
2099 if ~isempty(jsn.sync)
2100 jsync = jsn.sync;
2101 sn.sync = cell(jsync.size, 1);
2102 for i = 1:jsync.size
2103 jsync_i = jsync.get(uint32(i-1));
2104 sn.sync{i,1} = struct('active',cell(1),'passive',cell(1));
2105
2106 jactive = jsync_i.active.get(uint32(0));
2107 jpassive = jsync_i.passive.get(uint32(0));
2108
2109 %Currently assume that prob would always be a value
2110 %instead of lambda function (No idea of how to convert
2111 %Java lambda function to matlab lambda function)
2112 switch jactive.getEvent.name.toCharArray'
2113 case 'INIT'
2114 sn.sync{i,1}.active{1} = Event(EventType.INIT, jactive.getNode+1, jactive.getJobClass+1, ...
2115 jactive.getProb, JLINE.from_jline_matrix(jactive.getState), ...
2116 jactive.getT, jactive.getJob);
2117 case 'LOCAL'
2118 sn.sync{i,1}.active{1} = Event(EventType.LOCAL, jactive.getNode+1, jactive.getJobClass+1, ...
2119 jactive.getProb, JLINE.from_jline_matrix(jactive.getState), ...
2120 jactive.getT, jactive.getJob);
2121 case 'ARV'
2122 sn.sync{i,1}.active{1} = Event(EventType.ARV, jactive.getNode+1, jactive.getJobClass+1, ...
2123 jactive.getProb, JLINE.from_jline_matrix(jactive.getState), ...
2124 jactive.getT, jactive.getJob);
2125 case 'DEP'
2126 sn.sync{i,1}.active{1} = Event(EventType.DEP, jactive.getNode+1, jactive.getJobClass+1, ...
2127 jactive.getProb, JLINE.from_jline_matrix(jactive.getState), ...
2128 jactive.getT, jactive.getJob);
2129 case 'PHASE'
2130 sn.sync{i,1}.active{1} = Event(EventType.PHASE, jactive.getNode+1, jactive.getJobClass+1, ...
2131 jactive.getProb, JLINE.from_jline_matrix(jactive.getState), ...
2132 jactive.getT, jactive.getJob);
2133 case 'READ'
2134 sn.sync{i,1}.active{1} = Event(EventType.READ, jactive.getNode+1, jactive.getJobClass+1, ...
2135 jactive.getProb, JLINE.from_jline_matrix(jactive.getState), ...
2136 jactive.getT, jactive.getJob);
2137 case 'STAGE'
2138 sn.sync{i,1}.active{1} = Event(EventType.STAGE, jactive.getNode+1, jactive.getJobClass+1, ...
2139 jactive.getProb, JLINE.from_jline_matrix(jactive.getState), ...
2140 jactive.getT, jactive.getJob);
2141 end
2142
2143 switch jpassive.getEvent.name.toCharArray'
2144 case 'INIT'
2145 sn.sync{i,1}.passive{1} = Event(EventType.INIT, jpassive.getNode+1, jpassive.getJobClass+1, ...
2146 jpassive.getProb, JLINE.from_jline_matrix(jpassive.getState), ...
2147 jpassive.getT, jpassive.getJob);
2148 case 'LOCAL'
2149 sn.sync{i,1}.passive{1} = Event(EventType.LOCAL, jpassive.getNode+1, jpassive.getJobClass+1, ...
2150 jpassive.getProb, JLINE.from_jline_matrix(jpassive.getState), ...
2151 jpassive.getT, jpassive.getJob);
2152 case 'ARV'
2153 sn.sync{i,1}.passive{1} = Event(EventType.ARV, jpassive.getNode+1, jpassive.getJobClass+1, ...
2154 jpassive.getProb, JLINE.from_jline_matrix(jpassive.getState), ...
2155 jpassive.getT, jpassive.getJob);
2156 case 'DEP'
2157 sn.sync{i,1}.passive{1} = Event(EventType.DEP, jpassive.getNode+1, jpassive.getJobClass+1, ...
2158 jpassive.getProb, JLINE.from_jline_matrix(jpassive.getState), ...
2159 jpassive.getT, jpassive.getJob);
2160 case 'PHASE'
2161 sn.sync{i,1}.passive{1} = Event(EventType.PHASE, jpassive.getNode+1, jpassive.getJobClass+1, ...
2162 jpassive.getProb, JLINE.from_jline_matrix(jpassive.getState), ...
2163 jpassive.getT, jpassive.getJob);
2164 case 'READ'
2165 sn.sync{i,1}.passive{1} = Event(EventType.READ, jpassive.getNode+1, jpassive.getJobClass+1, ...
2166 jpassive.getProb, JLINE.from_jline_matrix(jpassive.getState), ...
2167 jpassive.getT, jpassive.getJob);
2168 case 'STAGE'
2169 sn.sync{i,1}.passive{1} = Event(EventType.STAGE, jpassive.getNode+1, jpassive.getJobClass+1, ...
2170 jpassive.getProb, JLINE.from_jline_matrix(jpassive.getState), ...
2171 jpassive.getT, jpassive.getJob);
2172 end
2173 end
2174 else
2175 sn.sync = {};
2176 end
2177 end
2178
2179 function [QN,UN,RN,WN,AN,TN] = arrayListToResults(alist)
2180 switch class(alist)
2181 case 'jline.solvers.LayeredNetworkAvgTable'
2182 QN = JLINE.arraylist_to_matrix(alist.getQLen());
2183 UN = JLINE.arraylist_to_matrix(alist.getUtil());
2184 RN = JLINE.arraylist_to_matrix(alist.getRespT());
2185 WN = JLINE.arraylist_to_matrix(alist.getResidT());
2186 AN = NaN*JLINE.arraylist_to_matrix(alist.getTput()); % getArvR not yet available in JLINE
2187 TN = JLINE.arraylist_to_matrix(alist.getTput());
2188 otherwise
2189 QN = JLINE.arraylist_to_matrix(alist.getQLen());
2190 UN = JLINE.arraylist_to_matrix(alist.getUtil());
2191 RN = JLINE.arraylist_to_matrix(alist.getRespT());
2192 WN = JLINE.arraylist_to_matrix(alist.getResidT());
2193 AN = JLINE.arraylist_to_matrix(alist.getArvR());
2194 TN = JLINE.arraylist_to_matrix(alist.getTput());
2195 end
2196 end
2197
2198 function featSupported = getFeatureSet()
2199 % FEATSUPPORTED = GETFEATURESET()
2200
2201 featSupported = SolverFeatureSet;
2202 featSupported.setTrue({'Sink','Source',...
2203 'ClassSwitch','Delay','DelayStation','Queue',...
2204 'APH','Coxian','Erlang','Exp','HyperExp',...
2205 'StatelessClassSwitcher','InfiniteServer','SharedServer','Buffer','Dispatcher',...
2206 'Server','JobSink','RandomSource','ServiceTunnel',...
2207 'SchedStrategy_INF','SchedStrategy_PS',...
2208 'RoutingStrategy_PROB','RoutingStrategy_RAND',...
2209 'ClosedClass','OpenClass'});
2210 end
2211
2212 function [bool, featSupported] = supports(model)
2213 % [BOOL, FEATSUPPORTED] = SUPPORTS(MODEL)
2214
2215 featUsed = model.getUsedLangFeatures();
2216 featSupported = JLINE.getFeatureSet();
2217 bool = SolverFeatureSet.supports(featSupported, featUsed);
2218 end
2219
2220
2221 function solverOptions = parseSolverOptions(solverOptions, options)
2222 fn = fieldnames(options);
2223 fn2 = fieldnames(solverOptions);
2224 for f = 1:length(fn)
2225 found = 0;
2226 for j = 1:length(fn2)
2227 if strcmp(fn{f}, fn2{j})
2228 found = 1;
2229 switch fn{f}
2230 case 'seed'
2231 solverOptions.seed = options.seed;
2232 case 'method'
2233 solverOptions.method = options.method;
2234 case 'config' % SSA specific
2235 if isfield(options.config,'eventcache')
2236 solverOptions.config.eventcache = options.config.eventcache;
2237 end
2238 case 'verbose'
2239 switch options.(fn{f})
2240 case {VerboseLevel.SILENT}
2241 solverOptions.verbose = solverOptions.verbose.SILENT;
2242 case {VerboseLevel.STD}
2243 solverOptions.verbose = solverOptions.verbose.STD;
2244 case {VerboseLevel.DEBUG}
2245 solverOptions.verbose = solverOptions.verbose.DEBUG;
2246 end
2247 case 'init_sol'
2248 solverOptions.(fn{f}) = JLINE.from_line_matrix(options.init_sol);
2249 case 'cutoff'
2250 if isscalar(options.cutoff)
2251 solverOptions.(fn{f}) = jline.util.matrix.Matrix.singleton(options.cutoff);
2252 else
2253 solverOptions.(fn{f}) = JLINE.from_line_matrix(options.cutoff);
2254 end
2255 case 'odesolvers'
2256 case 'rewardIterations'
2257 solverOptions.rewardIterations = java.lang.Integer(options.rewardIterations);
2258 otherwise
2259 solverOptions.(fn{f}) = options.(fn{f});
2260 end
2261
2262 break;
2263 end
2264 end
2265 if ~found
2266 line_printf('Could not find option %s in the JLINE options.\n', fn{f});
2267 end
2268 end
2269 end
2270
2271 function [ssa] = SolverSSA(network_object, options)
2272 solverOptions = jline.solvers.SolverOptions(jline.lang.constant.SolverType.SSA);
2273 if nargin>1
2274 solverOptions = JLINE.parseSolverOptions(solverOptions, options);
2275 end
2276 jline.util.Maths.setRandomNumbersMatlab(true);
2277 ssa = jline.solvers.ssa.SolverSSA(network_object, solverOptions);
2278 end
2279
2280 function [mam] = SolverMAM(network_object, options)
2281 solverOptions = jline.solvers.SolverOptions(jline.lang.constant.SolverType.MAM);
2282 if nargin>1
2283 solverOptions = JLINE.parseSolverOptions(solverOptions, options);
2284 end
2285 mam = jline.solvers.mam.SolverMAM(network_object, solverOptions);
2286 end
2287
2288 function [jmt] = SolverJMT(network_object, options)
2289 solverOptions = jline.solvers.SolverOptions(jline.lang.constant.SolverType.JMT);
2290 if nargin>1
2291 solverOptions = JLINE.parseSolverOptions(solverOptions, options);
2292 end
2293 jmt = jline.solvers.jmt.SolverJMT(network_object, solverOptions);
2294 end
2295
2296 function [ctmc] = SolverCTMC(network_object, options)
2297 solverOptions = jline.solvers.SolverOptions(jline.lang.constant.SolverType.CTMC);
2298 if nargin>1
2299 solverOptions = JLINE.parseSolverOptions(solverOptions, options);
2300 end
2301 ctmc = jline.solvers.ctmc.SolverCTMC(network_object,solverOptions);
2302 end
2303
2304 function [fluid] = SolverFluid(network_object, options)
2305 solverOptions = jline.solvers.SolverOptions(jline.lang.constant.SolverType.FLUID);
2306 if nargin>1
2307 solverOptions = JLINE.parseSolverOptions(solverOptions, options);
2308 end
2309 fluid = jline.solvers.fluid.SolverFluid(network_object, solverOptions);
2310 end
2311
2312 function [des] = SolverDES(network_object, options)
2313 solverOptions = jline.solvers.SolverOptions(jline.lang.constant.SolverType.DES);
2314 if nargin>1
2315 solverOptions = JLINE.parseSolverOptions(solverOptions, options);
2316 end
2317 des = jline.solvers.des.SolverDES(network_object, solverOptions);
2318 end
2319
2320 function [mva] = SolverMVA(network_object, options)
2321 solverOptions = jline.solvers.SolverOptions(jline.lang.constant.SolverType.MVA);
2322 if nargin>1
2323 solverOptions = JLINE.parseSolverOptions(solverOptions, options);
2324 end
2325 mva = jline.solvers.mva.SolverMVA(network_object, solverOptions);
2326 end
2327
2328 function [nc] = SolverNC(network_object, options)
2329 solverOptions = jline.solvers.SolverOptions(jline.lang.constant.SolverType.NC);
2330 if nargin>1
2331 solverOptions = JLINE.parseSolverOptions(solverOptions, options);
2332 end
2333 nc = jline.solvers.nc.SolverNC(network_object, solverOptions);
2334 end
2335
2336 function streamOpts = StreamingOptions(varargin)
2337 % STREAMINGOPTIONS Create Java StreamingOptions for SSA/DES stream() method
2338 %
2339 % @brief Creates StreamingOptions for streaming simulation metrics
2340 %
2341 % @param varargin Name-value pairs for options:
2342 % 'endpoint' - OTLP receiver endpoint (default: '127.0.0.1:4317')
2343 % 'mode' - 'sampled' or 'time_window' (default: 'sampled')
2344 % 'sampleFrequency' - Push every N events in sampled mode (default: 100)
2345 % 'timeWindowSeconds' - Window duration in time_window mode (default: 1.0)
2346 % 'serviceName' - Service identifier (default: 'line-stream')
2347 % 'includeQueueLength' - Include queue length metrics (default: true)
2348 % 'includeUtilization' - Include utilization metrics (default: true)
2349 % 'includeThroughput' - Include throughput metrics (default: true)
2350 % 'includeResponseTime' - Include response time metrics (default: true)
2351 % 'includeArrivalRate' - Include arrival rate metrics (default: true)
2352 %
2353 % @return streamOpts Java StreamingOptions object
2354 %
2355 % Example:
2356 % @code
2357 % streamOpts = JLINE.StreamingOptions('mode', 'sampled', 'sampleFrequency', 50);
2358 % @endcode
2359
2360 streamOpts = jline.streaming.StreamingOptions();
2361
2362 % Parse optional arguments
2363 p = inputParser;
2364 addParameter(p, 'endpoint', '127.0.0.1:4317', @ischar);
2365 addParameter(p, 'mode', 'sampled', @ischar);
2366 addParameter(p, 'sampleFrequency', 100, @isnumeric);
2367 addParameter(p, 'timeWindowSeconds', 1.0, @isnumeric);
2368 addParameter(p, 'serviceName', 'line-stream', @ischar);
2369 addParameter(p, 'includeQueueLength', true, @islogical);
2370 addParameter(p, 'includeUtilization', true, @islogical);
2371 addParameter(p, 'includeThroughput', true, @islogical);
2372 addParameter(p, 'includeResponseTime', true, @islogical);
2373 addParameter(p, 'includeArrivalRate', true, @islogical);
2374 parse(p, varargin{:});
2375
2376 % Set endpoint
2377 streamOpts.endpoint = p.Results.endpoint;
2378
2379 % Set mode
2380 streamModes = javaMethod('values', 'jline.streaming.StreamingOptions$StreamMode');
2381 switch lower(p.Results.mode)
2382 case 'sampled'
2383 streamOpts.mode = streamModes(1); % SAMPLED
2384 case 'time_window'
2385 streamOpts.mode = streamModes(2); % TIME_WINDOW
2386 otherwise
2387 streamOpts.mode = streamModes(1); % Default to SAMPLED
2388 end
2389
2390 % Set other options
2391 streamOpts.sampleFrequency = p.Results.sampleFrequency;
2392 streamOpts.timeWindowSeconds = p.Results.timeWindowSeconds;
2393 streamOpts.serviceName = p.Results.serviceName;
2394 streamOpts.includeQueueLength = p.Results.includeQueueLength;
2395 streamOpts.includeUtilization = p.Results.includeUtilization;
2396 streamOpts.includeThroughput = p.Results.includeThroughput;
2397 streamOpts.includeResponseTime = p.Results.includeResponseTime;
2398 streamOpts.includeArrivalRate = p.Results.includeArrivalRate;
2399 end
2400
2401 function result = convertSampleResult(jresult)
2402 % CONVERTSAMPLERESULT Convert Java sample result to MATLAB struct
2403 %
2404 % @brief Converts Java SampleNodeState to MATLAB structure
2405 %
2406 % @param jresult Java SampleNodeState object
2407 % @return result MATLAB struct with fields: t, state, isaggregate
2408
2409 result = struct();
2410
2411 % Convert time matrix
2412 if ~isempty(jresult.t)
2413 result.t = JLINE.from_jline_matrix(jresult.t);
2414 else
2415 result.t = [];
2416 end
2417
2418 % Convert state matrix
2419 if ~isempty(jresult.state) && isa(jresult.state, 'jline.util.matrix.Matrix')
2420 result.state = JLINE.from_jline_matrix(jresult.state);
2421 else
2422 result.state = [];
2423 end
2424
2425 result.isaggregate = jresult.isaggregate;
2426 end
2427
2428 function [ln] = SolverLN(layered_network_object)
2429 solverOptions = jline.solvers.SolverOptions(jline.lang.constant.SolverType.LN);
2430 ln = jline.solvers.ln.SolverLN(layered_network_object, solverOptions);
2431 end
2432
2433 function serfun = handle_to_serializablefun(handle)
2434 line_error(mfilename, "Class-dependent models not supported in LINE MATLAB-to-JAVA translation.");
2435 end
2436
2437 end
2438end
Definition mmt.m:92