LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
QN2LQN.m
1function lqn=QN2LQN(model)
2
3lqn = LayeredNetwork(model.getName());
4sn = model.getStruct;
5
6PH = Host(lqn, model.getName(), Inf, SchedStrategy.INF); % pseudo host
7for c=1:sn.nchains
8 inchain = sn.inchain{c};
9 RT{c} = Task(lqn,['RefTask_',num2str(c)], sum(sn.njobs(inchain)), SchedStrategy.REF).on(PH); % reference task for chain c
10 RE{c} = Entry(lqn,['Chain_',num2str(c)]).on(RT{c}); % entry on reference task for chain c
11end
12
13for i=1:sn.nnodes
14 switch sn.nodetype(i)
15 case {NodeType.Queue, NodeType.Delay}
16 P{i} = Host(lqn, sn.nodenames{i}, sn.nservers(sn.nodeToStation(i)), SchedStrategy.fromId(sn.sched(sn.nodeToStation(i))));
17 T{i} = Task(lqn,['T_',sn.nodenames{i}], Inf, SchedStrategy.INF).on(P{i});
18 for r=1:sn.nclasses
19 c = find(sn.chains(:,r)); % chain of class r
20 if sn.visits{c}(i,r)>0
21 E{i,r} = Entry(lqn, ['E',num2str(i),'_',num2str(r)]).on(T{i});
22 A{i,r} = Activity(lqn, ['Q',num2str(i),'_',num2str(r)], model.nodes{i}.getServiceProcess(model.classes{r})).on(T{i}).boundTo(E{i,r}).repliesTo(E{i,r});
23 end
24 end
25 case {NodeType.ClassSwitch, NodeType.Router, NodeType.Logger}
26 % no-op: passthrough routing nodes
27 case {NodeType.Source, NodeType.Sink}
28 % no-op: chain boundary nodes
29 case {NodeType.Fork, NodeType.Join}
30 % no-op: synchronization nodes, precedences added later
31 end
32end
33
34PA = cell(sn.nchains, sn.nnodes, sn.nclasses);
35boundToRE = cell(1,sn.nchains);
36for i=1:sn.nnodes
37 switch sn.nodetype(i)
38 case {NodeType.ClassSwitch, NodeType.Router, NodeType.Logger}
39 for r=1:sn.nclasses
40 c = find(sn.chains(:,r)); % chain of class r
41 if any(sn.rtnodes(:, ((i-1)*sn.nclasses + r))>0)
42 PA{c,i,r} = Activity(lqn, ['CS','_',num2str(c),'_',num2str(i),'_',num2str(r)], Immediate()).on(RT{c}); % pseudo-activity in ref task
43 end
44 end
45 case {NodeType.Fork, NodeType.Join}
46 for r=1:sn.nclasses
47 c = find(sn.chains(:,r)); % chain of class r
48 if any(sn.rtnodes(:, ((i-1)*sn.nclasses + r))>0)
49 PA{c,i,r} = Activity(lqn, ['FJ','_',num2str(c),'_',num2str(i),'_',num2str(r)], Immediate()).on(RT{c}); % pseudo-activity for fork/join
50 end
51 end
52 case {NodeType.Queue, NodeType.Delay}
53 for r=1:sn.nclasses
54 c = find(sn.chains(:,r)); % chain of class r
55 if sn.visits{c}(i,r)>0
56 inchain = sn.inchain{c};
57 if i == sn.refstat(inchain(1)) && r == inchain(1)
58 PA{c,i,r} = Activity(lqn, ['A',num2str(i),'_',num2str(r)], Immediate()).on(RT{c}).boundTo(RE{c}).synchCall(E{i,r}); % pseudo-activity in ref task
59 boundToRE{c} = [i,r];
60 else
61 PA{c,i,r} = Activity(lqn, ['A',num2str(i),'_',num2str(r)], Immediate()).on(RT{c}).synchCall(E{i,r}); % pseudo-activity in ref task
62 end
63 %RT{c}.addPrecedence(ActivityPrecedence.Serial(PN{c,i},PA{i,r}));
64 end
65 end
66 case {NodeType.Source, NodeType.Sink}
67 % no-op: chain boundary nodes
68 end
69end
70
71usedInORFork = zeros(sn.nnodes,sn.nclasses);
72routingNodeTypes = [NodeType.Queue, NodeType.Delay, NodeType.ClassSwitch, NodeType.Router, NodeType.Logger, NodeType.Fork, NodeType.Join];
73for c=1:sn.nchains
74 inchain = sn.inchain{c};
75 %refstat = sn.refstat(inchain(1));
76 for i=1:sn.nnodes
77 if ~ismember(sn.nodetype(i), routingNodeTypes)
78 continue;
79 end
80 for r=inchain
81 orfork_prec = {};
82 orfork_prob = [];
83 for j=1:sn.nnodes
84 if ~ismember(sn.nodetype(j), routingNodeTypes)
85 continue;
86 end
87 % Skip Join destinations - handled by AND-Join precedences below
88 if sn.nodetype(j) == NodeType.Join
89 continue;
90 end
91 for s=inchain
92 pr = sn.rtnodes((i-1)*sn.nclasses + r, (j-1)*sn.nclasses + s);
93 if pr>0 && any(sn.rtnodes(:, ((i-1)*sn.nclasses + r))>0)
94 if ~isempty(boundToRE{c})
95 if boundToRE{c}(1)==j && boundToRE{c}(2)==s
96 if ~isempty(PA{c,i,r})
97 orfork_prec{end+1} = Activity(lqn, ['End_',num2str(c),'_',num2str(i),'_',num2str(r)], Immediate()).on(RT{c});
98 orfork_prob(end+1)= pr;
99 end
100 else
101 orfork_prec{end+1} = PA{c,j,s};
102 orfork_prob(end+1) = pr;
103 end
104 end
105 end
106 end
107 end
108 if ~isempty(orfork_prec)
109 if ~isempty(PA{c,i,r})
110 if sn.nodetype(i) == NodeType.Fork
111 % Fork node: AND-Fork (all branches taken simultaneously)
112 RT{c}.addPrecedence(ActivityPrecedence.AndFork(PA{c,i,r}, orfork_prec));
113 else
114 RT{c}.addPrecedence(ActivityPrecedence.OrFork(PA{c,i,r}, orfork_prec, orfork_prob));
115 end
116 usedInORFork(i,r) = usedInORFork(i,r) + 1;
117 end
118 end
119 end
120 end
121end
122
123% AND-Join precedences for Join nodes
124for c=1:sn.nchains
125 inchain = sn.inchain{c};
126 for j=1:sn.nnodes
127 if sn.nodetype(j) ~= NodeType.Join
128 continue;
129 end
130 for s=inchain
131 if isempty(PA{c,j,s})
132 continue;
133 end
134 join_pre = {};
135 for i=1:sn.nnodes
136 if ~ismember(sn.nodetype(i), routingNodeTypes)
137 continue;
138 end
139 for r=inchain
140 pr = sn.rtnodes((i-1)*sn.nclasses + r, (j-1)*sn.nclasses + s);
141 if pr > 0 && ~isempty(PA{c,i,r})
142 join_pre{end+1} = PA{c,i,r};
143 end
144 end
145 end
146 if length(join_pre) > 1
147 RT{c}.addPrecedence(ActivityPrecedence.AndJoin(join_pre, PA{c,j,s}));
148 elseif length(join_pre) == 1
149 RT{c}.addPrecedence(ActivityPrecedence({join_pre{1}.getName},{PA{c,j,s}.getName}));
150 end
151 end
152 end
153end
154
155end
Definition mmt.m:93