LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
parseXML.m
1function myLN = parseXML(filename, verbose)
2% MYLN = PARSEXML(FILENAME, VERBOSE)
3
4% Copyright (c) 2012-2026, Imperial College London
5% All rights reserved.
6
7
8import javax.xml.parsers.DocumentBuilderFactory;
9import javax.xml.parsers.DocumentBuilder;
10import org.w3c.dom.Document;
11import org.w3c.dom.NodeList;
12import org.w3c.dom.Node;
13import org.w3c.dom.Element;
14import java.io.File;
15
16import LayeredNetwork.*;
17
18% LQN
19myLN = LayeredNetwork(strrep(filename,'_','\_'));
20
21if nargin<2%~exist('verbose','var')
22 verbose = 0;
23end
24
25% init Java XML parser and load file
26dbFactory = DocumentBuilderFactory.newInstance();
27dBuilder = dbFactory.newDocumentBuilder();
28
29fid=fopen(filename,'r');
30if fid==-1
31 line_error(mfilename,'File cannot be found. Verify the current directory and the specified filename.');
32else
33 fclose(fid);
34end
35
36if isempty(fileparts(filename))
37 doc = dBuilder.parse(which(filename));
38else
39 doc = dBuilder.parse(filename);
40end
41doc.getDocumentElement().normalize();
42if verbose > 0
43 line_printf(['Parsing LQN file: ',filename]);
44 line_printf(['Root element :',char(doc.getDocumentElement().getNodeName())]);
45end
46
47hosts = cell(0); %list of hosts - Proc
48tasks = cell(0); %list of tasks - Task, ProcID
49entries = cell(0); %list of entries - Entry, TaskID, ProcID
50activities = cell(0); %list of activities - Act, TaskID, ProcID
51procID = 1;
52taskID = 1;
53entryID = 1;
54actID = 1;
55procObj = cell(0);
56taskObj = cell(0);
57entryObj = cell(0);
58actObj = cell(0);
59
60procList = doc.getElementsByTagName('processor');
61for i = 0:procList.getLength()-1
62 %Element - Host
63 procElement = procList.item(i);
64 name = char(procElement.getAttribute('name'));
65 scheduling = char(procElement.getAttribute('scheduling'));
66 multiplicity = str2double(char(procElement.getAttribute('multiplicity')));
67 replication = str2double(char(procElement.getAttribute('replication')));
68
69 if isnan(replication)
70 replication=1;
71 end
72 if strcmp(scheduling, 'inf')
73 if isfinite(multiplicity)
74 line_warning(mfilename,'A finite multiplicity is specified for a host processor with INF scheduling. Remove it or set it to "inf".\n');
75 end
76 multiplicity = Inf;
77 elseif isnan(multiplicity)
78 multiplicity = 1;
79 end
80 quantum = str2double(char(procElement.getAttribute('quantum')));
81 if isnan(quantum)
82 quantum = 0.001;
83 end
84 speedFactor = str2double(char(procElement.getAttribute('speed-factor')));
85 if isnan(speedFactor)
86 speedFactor = 1.0;
87 end
88 newProc = Processor(myLN, name, multiplicity, SchedStrategy.fromText(scheduling), quantum, speedFactor);
89 newProc.setReplication(replication);
90 procObj{end+1,1} = newProc;
91
92 taskList = procElement.getElementsByTagName('task');
93 for j = 0:taskList.getLength()-1
94 %Element - Task
95 taskElement = taskList.item(j);
96 name = char(taskElement.getAttribute('name'));
97 scheduling = char(taskElement.getAttribute('scheduling'));
98 replication = str2double(char(taskElement.getAttribute('replication')));
99 if isnan(replication)
100 replication=1;
101 end
102
103 multiplicity = str2double(char(taskElement.getAttribute('multiplicity')));
104 if strcmp(scheduling, 'inf')
105 if isfinite(multiplicity)
106 line_warning(mfilename,'A finite multiplicity is specified for a task with inf scheduling. Remove it or set it to inf.\n');
107 end
108 multiplicity = Inf;
109 elseif isnan(multiplicity)
110 multiplicity = 1;
111 end
112 thinkTimeMean = str2double(char(taskElement.getAttribute('think-time')));
113 if isnan(thinkTimeMean)
114 thinkTimeMean = 0.0;
115 end
116 if thinkTimeMean <= 0.0
117 thinkTime = Immediate.getInstance();
118 else
119 thinkTime = Exp.fitMean(thinkTimeMean);
120 end
121 newTask = Task(myLN, name, multiplicity, SchedStrategy.fromText(scheduling), thinkTime);
122 newTask.setReplication(replication);
123
124 % Parse priority attribute if present
125 priorityStr = char(taskElement.getAttribute('priority'));
126 if ~isempty(priorityStr)
127 priority = str2double(priorityStr);
128 if ~isnan(priority)
129 newTask.setPriority(priority);
130 end
131 end
132
133 % Parse fan-in element if present (used for replication load distribution)
134 fanInList = taskElement.getElementsByTagName('fan-in');
135 if fanInList.getLength() > 0
136 fanInElement = fanInList.item(0);
137 source = char(fanInElement.getAttribute('source'));
138 valueStr = char(fanInElement.getAttribute('value'));
139 if ~isempty(source) && ~isempty(valueStr)
140 value = str2double(valueStr);
141 if ~isnan(value)
142 newTask.setFanIn(source, value);
143 end
144 end
145 end
146
147 % Parse fan-out elements if present (used for replication load distribution)
148 fanOutList = taskElement.getElementsByTagName('fan-out');
149 for fo = 0:fanOutList.getLength()-1
150 fanOutElement = fanOutList.item(fo);
151 dest = char(fanOutElement.getAttribute('dest'));
152 valueStr = char(fanOutElement.getAttribute('value'));
153 if ~isempty(dest) && ~isempty(valueStr)
154 value = str2double(valueStr);
155 if ~isnan(value)
156 newTask.setFanOut(dest, value);
157 end
158 end
159 end
160
161 taskObj{end+1,1} = newTask;
162
163 entryList = taskElement.getElementsByTagName('entry');
164 for k = 0:entryList.getLength()-1
165 %Element - Entry
166 entryElement = entryList.item(k);
167 name = char(entryElement.getAttribute('name'));
168 newEntry = Entry(myLN, name);
169 openArrivalRate = str2double(char(entryElement.getAttribute('open-arrival-rate')));
170 if ~isnan(openArrivalRate)
171 newEntry.openArrivalRate = openArrivalRate;
172 end
173
174 % Parse entry type attribute
175 eType = char(entryElement.getAttribute('type'));
176 if ~isempty(eType)
177 newEntry.setType(eType);
178 end
179
180 entryObj{end+1,1} = newEntry;
181
182 % Parse forwarding calls
183 forwardingList = entryElement.getElementsByTagName('forwarding');
184 for fw = 0:forwardingList.getLength()-1
185 fwdElement = forwardingList.item(fw);
186 destName = char(fwdElement.getAttribute('dest'));
187 probStr = char(fwdElement.getAttribute('prob'));
188 if isempty(probStr)
189 prob = 1.0;
190 else
191 prob = str2double(probStr);
192 end
193 newEntry.forward(destName, prob);
194 end
195
196 %entry-phase-activities
197 entryPhaseActsList = entryElement.getElementsByTagName('entry-phase-activities');
198 if entryPhaseActsList.getLength > 0
199 entryPhaseActsElement = entryPhaseActsList.item(0);
200 actList = entryPhaseActsElement.getElementsByTagName('activity');
201 name = cell(actList.getLength(),1);
202 for l = 0:actList.getLength()-1
203 %Element - Activity
204 actElement = actList.item(l);
205 phase = str2double(char(actElement.getAttribute('phase')));
206 name{phase} = char(actElement.getAttribute('name'));
207 hostDemandMean = str2double(char(actElement.getAttribute('host-demand-mean')));
208 hostDemandSCV = str2double(char(actElement.getAttribute('host-demand-cvsq')));
209 if isnan(hostDemandSCV)
210 hostDemandSCV = 1.0;
211 end
212 if hostDemandMean <= 0.0
213 hostDemand = Immediate.getInstance();
214 else
215 if hostDemandSCV <= 0.0
216 hostDemand = Det(hostDemandMean);
217 elseif hostDemandSCV == 1.0
218 hostDemand = Exp.fitMean(hostDemandMean);
219 else
220 hostDemand = APH.fitMeanAndSCV(hostDemandMean, hostDemandSCV);
221 end
222 end
223 if phase == 1
224 boundToEntry = newEntry.name;
225 else
226 boundToEntry = '';
227 end
228 callOrder = char(actElement.getAttribute('call-order'));
229 newAct = Activity(myLN, name{phase}, hostDemand, boundToEntry, callOrder);
230 newAct.phase = phase; % Store the phase number
231
232 % Parse activity think-time
233 actThinkTimeMean = str2double(char(actElement.getAttribute('think-time')));
234 if ~isnan(actThinkTimeMean) && actThinkTimeMean > 0.0
235 newAct.setThinkTime(actThinkTimeMean);
236 end
237
238 actObj{end+1,1} = newAct;
239
240 %synch-call
241 synchCalls = actElement.getElementsByTagName('synch-call');
242 for m = 0:synchCalls.getLength()-1
243 callElement = synchCalls.item(m);
244 dest = char(callElement.getAttribute('dest'));
245 mean = str2double(char(callElement.getAttribute('calls-mean')));
246 newAct = newAct.synchCall(dest,mean);
247 end
248
249 %asynch-call
250 asynchCalls = actElement.getElementsByTagName('asynch-call');
251 for m = 0:asynchCalls.getLength()-1
252 callElement = asynchCalls.item(m);
253 dest = char(callElement.getAttribute('dest'));
254 mean = str2double(char(callElement.getAttribute('calls-mean')));
255 newAct = newAct.asynchCall(dest,mean);
256 end
257
258 activities{end+1,1} = newAct.name;
259 activities{end,2} = taskID;
260 activities{end,3} = procID;
261 newTask = newTask.addActivity(newAct);
262 newAct.parent = newTask;
263 actID = actID+1;
264 end
265
266 %precedence
267 for l = 1:length(name)-1
268 newPrec = ActivityPrecedence(name(l), name(l+1));
269 newTask = newTask.addPrecedence(newPrec);
270 end
271
272 %reply-entry: For entry-phase-activities, phase-1 activities reply implicitly
273 % Find the last phase-1 activity and set it as the reply activity
274 if ~isempty(name) && ~isempty(name{1})
275 % The last phase-1 activity (name{1}) should reply to the entry
276 newEntry.replyActivity{end+1} = name{1};
277 end
278 end
279
280 entries{end+1,1} = newEntry.name;
281 entries{end,2} = taskID;
282 entries{end,3} = procID;
283 newTask = newTask.addEntry(newEntry);
284 newEntry.parent = newTask;
285 entryID = entryID+1;
286 end
287
288 %task-activities
289 taskActsList = taskElement.getElementsByTagName('task-activities');
290 if taskActsList.getLength > 0
291 taskActsElement = taskActsList.item(0);
292 actList = taskActsElement.getElementsByTagName('activity');
293 for l = 0:actList.getLength()-1
294 %Element - Activity
295 actElement = actList.item(l);
296 if strcmp(char(actElement.getParentNode().getNodeName()),'task-activities')
297 name = char(actElement.getAttribute('name'));
298 hostDemandMean = str2double(char(actElement.getAttribute('host-demand-mean')));
299 hostDemandSCV = str2double(char(actElement.getAttribute('host-demand-cvsq')));
300 if isnan(hostDemandSCV)
301 hostDemandSCV = 1.0;
302 end
303 if hostDemandMean <= 0.0
304 hostDemand = Immediate.getInstance();
305 else
306 if hostDemandSCV <= 0.0
307 hostDemand = Det(hostDemandMean);
308 elseif hostDemandSCV < 1.0
309 hostDemand = APH.fitMeanAndSCV(hostDemandMean, hostDemandSCV);
310 elseif hostDemandSCV == 1.0
311 hostDemand = Exp.fitMeanAndSCV(hostDemandMean, hostDemandSCV);
312 else
313 hostDemand = HyperExp.fitMeanAndSCV(hostDemandMean, hostDemandSCV);
314 end
315 end
316 boundToEntry = char(actElement.getAttribute('bound-to-entry'));
317 callOrder = char(actElement.getAttribute('call-order'));
318 newAct = Activity(myLN, name, hostDemand, boundToEntry, callOrder);
319
320 % Parse activity think-time
321 actThinkTimeMean = str2double(char(actElement.getAttribute('think-time')));
322 if ~isnan(actThinkTimeMean) && actThinkTimeMean > 0.0
323 newAct.setThinkTime(actThinkTimeMean);
324 end
325
326 actObj{end+1,1} = newAct;
327
328 %synch-call
329 synchCalls = actElement.getElementsByTagName('synch-call');
330 for m = 0:synchCalls.getLength()-1
331 callElement = synchCalls.item(m);
332 dest = char(callElement.getAttribute('dest'));
333 mean = str2double(char(callElement.getAttribute('calls-mean')));
334 newAct = newAct.synchCall(dest,mean);
335 end
336
337 %asynch-call
338 asynchCalls = actElement.getElementsByTagName('asynch-call');
339 for m = 0:asynchCalls.getLength()-1
340 callElement = asynchCalls.item(m);
341 dest = char(callElement.getAttribute('dest'));
342 mean = str2double(char(callElement.getAttribute('calls-mean')));
343 newAct = newAct.asynchCall(dest,mean);
344 end
345
346 activities{end+1,1} = newAct.name;
347 activities{end,2} = taskID;
348 activities{end,3} = procID;
349 newTask = newTask.addActivity(newAct);
350 newAct.parent = newTask;
351 actID = actID+1;
352 end
353 end
354
355 %precedence
356 precList = taskActsElement.getElementsByTagName('precedence');
357 for l = 0:precList.getLength()-1
358 precElement = precList.item(l);
359
360 %pre
361 preTypes = {ActivityPrecedenceType.PRE_SEQ,ActivityPrecedenceType.PRE_AND,ActivityPrecedenceType.PRE_OR};
362 for m = 1:length(preTypes)
363 preType = preTypes{m};
364 preList = precElement.getElementsByTagName(ActivityPrecedenceType.toText(preType));
365 if preList.getLength() > 0
366 break
367 end
368 end
369 preElement = preList.item(0);
370 preParams = [];
371 preActList = preElement.getElementsByTagName('activity');
372
373 % assumes that preType is a numeric precedence ID
374 % if strcmp(preType,ActivityPrecedenceType.toText(ActivityPrecedenceType.PRE_OR))
375 if preType == ActivityPrecedenceType.PRE_OR
376 preActs = cell(preActList.getLength(),1);
377 preParams = zeros(postActList.getLength(),1);
378 for m = 0:preActList.getLength()-1
379 preActElement = preActList.item(m);
380 preActs{m+1} = char(preActElement.getAttribute('name'));
381 preParams(m+1) = str2double(char(preActElement.getAttribute('prob')));
382 end
383 % elseif strcmp(preType,ActivityPrecedenceType.toText(ActivityPrecedenceType.PRE_AND))
384 elseif preType == ActivityPrecedenceType.PRE_AND
385 preActs = cell(preActList.getLength(),1);
386 for m = 0:preActList.getLength()-1
387 preActElement = preActList.item(m);
388 preActs{m+1} = char(preActElement.getAttribute('name'));
389 end
390 preParams = str2double(char(preElement.getAttribute('quorum')));
391 else % simple PRE
392 preActs = cell(1,1);
393 preActElement = preActList.item(0);
394 preActs{1} = char(preActElement.getAttribute('name'));
395 end
396 if isnan(preParams)
397 preParams = [];
398 end
399
400 %post
401 postTypes = {ActivityPrecedenceType.POST_SEQ, ActivityPrecedenceType.POST_AND, ActivityPrecedenceType.POST_OR, ActivityPrecedenceType.POST_LOOP, ActivityPrecedenceType.POST_CACHE};
402 for m = 1:length(postTypes)
403 postType = postTypes{m};
404 postList = precElement.getElementsByTagName(ActivityPrecedenceType.toText(postType));
405 if postList.getLength() > 0
406 break
407 end
408 end
409
410 postElement = postList.item(0);
411 postActList = postElement.getElementsByTagName('activity');
412
413 % assumes that postType is a numeric precedence ID
414 % if strcmp(postType,ActivityPrecedenceType.toText(ActivityPrecedenceType.POST_OR))
415 if postType == ActivityPrecedenceType.POST_OR
416 postActs = cell(postActList.getLength(),1);
417 postParams = zeros(postActList.getLength(),1);
418 for m = 0:postActList.getLength()-1
419 postActElement = postActList.item(m);
420 postActs{m+1} = char(postActElement.getAttribute('name'));
421 postParams(m+1) = str2double(char(postActElement.getAttribute('prob')));
422 end
423 %elseif strcmp(postType,ActivityPrecedenceType.toText(ActivityPrecedenceType.POST_LOOP))
424 elseif postType == ActivityPrecedenceType.POST_LOOP
425 postActs = cell(postActList.getLength()+1,1);
426 postParams = zeros(postActList.getLength(),1);
427 for m = 0:postActList.getLength()-1
428 postActElement = postActList.item(m);
429 postActs{m+1} = char(postActElement.getAttribute('name'));
430 postParams(m+1) = str2double(char(postActElement.getAttribute('count')));
431
432 end
433 postActs{end} = char(postElement.getAttribute('end'));
434 else
435 postActs = cell(postActList.getLength(),1);
436 postParams = [];
437 for m = 0:postActList.getLength()-1
438 postActElement = postActList.item(m);
439 postActs{m+1} = char(postActElement.getAttribute('name'));
440 end
441 end
442 newPrec = ActivityPrecedence(preActs, postActs, preType, postType, preParams, postParams);
443 newTask = newTask.addPrecedence(newPrec);
444 end
445
446 %reply-entry
447 replyList = taskActsElement.getElementsByTagName('reply-entry');
448 for l = 0:replyList.getLength()-1
449 replyElement = replyList.item(l);
450 replyName = char(replyElement.getAttribute('name'));
451 replyIdx = findstring(entries(:,1), replyName);
452 replyActList = replyElement.getElementsByTagName('reply-activity');
453 for m = 0:replyActList.getLength()-1
454 replyActElement = replyActList.item(m);
455 replyActName = char(replyActElement.getAttribute('name'));
456 entryObj{replyIdx}.replyActivity{end+1} = replyActName;
457 end
458 end
459 end
460
461 tasks{end+1,1} = newTask.name;
462 tasks{end,2} = procID;
463 newProc = newProc.addTask(newTask);
464 taskID = taskID+1;
465 end
466
467 hosts{end+1,1} = newProc.name;
468 procID = procID+1;
469end
470end