Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 60.6% 981 / 0 / 1618
Functions: -% 0 / 1 / 1
Branches: 57.1% 303 / 0 / 531

OMCompiler/Compiler/BackEnd/HpcOmTaskGraph.mo
Line Branch Exec Source
1 /*
2 * This file is part of OpenModelica.
3 *
4 * Copyright (c) 1998-2026, Open Source Modelica Consortium (OSMC),
5 * c/o Linköpings universitet, Department of Computer and Information Science,
6 * SE-58183 Linköping, Sweden.
7 *
8 * All rights reserved.
9 *
10 * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF AGPL VERSION 3 LICENSE OR
11 * THIS OSMC PUBLIC LICENSE (OSMC-PL) VERSION 1.8.
12 * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES
13 * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GNU AGPL
14 * VERSION 3, ACCORDING TO RECIPIENTS CHOICE.
15 *
16 * The OpenModelica software and the OSMC (Open Source Modelica Consortium)
17 * Public License (OSMC-PL) are obtained from OSMC, either from the above
18 * address, from the URLs:
19 * http://www.openmodelica.org or
20 * https://github.com/OpenModelica/ or
21 * http://www.ida.liu.se/projects/OpenModelica,
22 * and in the OpenModelica distribution.
23 *
24 * GNU AGPL version 3 is obtained from:
25 * https://www.gnu.org/licenses/licenses.html#GPL
26 *
27 * This program is distributed WITHOUT ANY WARRANTY; without
28 * even the implied warranty of MERCHANTABILITY or FITNESS
29 * FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH
30 * IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF OSMC-PL.
31 *
32 * See the full OSMC Public License conditions for more details.
33 *
34 */
35
36 encapsulated package HpcOmTaskGraph
37 " file: HpcOmTaskGraph.mo
38 package: HpcOmTaskGraph
39 description: HpcOmTaskGraph contains the whole logic to create a TaskGraph on BLT-Level
40
41 "
42 public import BackendDAE;
43 public import DAE;
44 public import GraphML;
45
46 protected
47 import AdjacencyMatrix;
48 import Array;
49 import BackendDAEOptimize;
50 import BackendDAEUtil;
51 import BackendDump;
52 import BackendEquation;
53 import BackendVariable;
54 import ComponentReference;
55 protected import ComponentReferenceBasics;
56 import DAEDumpTypes;
57 import Error;
58 import ExpandableArray;
59 import Expression;
60 import Flags;
61 import HpcOmBenchmark;
62 import HpcOmScheduler;
63 import HpcOmSimCode;
64 import List;
65 import SCode;
66 import SimCode;
67 import SimCodeUtil;
68 import SimCodeVar;
69 import System;
70 import Util;
71 import HpcOmCodegenUtil;
72
73
74 //----------------------------
75 // Graph Structure
76 //----------------------------
77
78 public type TaskGraph = array<list<Integer>>;
79
80 public type Communications = list<Communication>;
81
82 public uniontype Communication
83 record COMMUNICATION
84 //Variables that have to be transmitted
85 Integer numberOfVars; //sum of {numOfIntegers,numOfFloats,numOfBoolean, numOfStrings}
86 list<Integer> integerVars;
87 list<Integer> floatVars;
88 list<Integer> booleanVars;
89 list<Integer> stringVars;
90 //Other values
91 Integer childNode;
92 Real requiredTime;
93 end COMMUNICATION;
94 end Communication;
95
96 public uniontype ComponentInfo
97 record COMPONENTINFO
98 Boolean isPartOfODESystem; // true if the component belongs to the ode system
99 Boolean isPartOfZeroFuncSystem; // true if the component belongs to the event system
100 Boolean isRemovedComponent; // true if the component was added via appendRemovedEquations (e.g. it is a assert)
101 end COMPONENTINFO;
102 end ComponentInfo;
103
104 // TODO: Store compParamMapping, compNames and compDescs in ComponentInfo
105 // TODO: Change nodeMark to compMarks
106
107 public uniontype TaskGraphMeta // stores all the metadata for the TaskGraph
108 record TASKGRAPHMETA
109 array<list<Integer>> inComps; // all StrongComponents from the BLT that belong to the Nodes [nodeId = arrayIdx]
110 array<tuple<Integer,Integer,Integer>> varCompMapping; // maps each variable to <compIdx, eqSystemIdx, offset>. The offset is the sum of the varNumber of all eqSystems with a minor index.
111 array<tuple<Integer,Integer,Integer>> eqCompMapping; // maps each equation to <compIdx, eqSystemIdx, offset>. The offset is the sum of the eqNumber of all eqSystems with a minor index.
112 array<list<Integer>> compParamMapping; // maps each scc to a list of parameters that are required for calculation. The indices are related to the known-parameter object of SHARED.
113 array<String> compNames; // the name of the components (e.g. '{18:7}')
114 array<String> compDescs; // a description of the components (e.g. 'R5.R * R5.i = C2.vinternal FOR R5.i')
115 array<tuple<Integer,Real>> exeCosts; // the execution cost for the components <numberOfOperations, requiredCycles>
116 array<Communications> commCosts; // the communication cost tuple(_,numberOfVars,requiredCycles) for an edge from array[parentSCC] to tuple(childSCC,_,_)
117 array<Integer> nodeMark; // used for level informations -> this is currently not a nodeMark, its a componentMark
118 array<ComponentInfo> compInformations; // used to store additional informations about the components
119 end TASKGRAPHMETA;
120 end TaskGraphMeta;
121
122 type VariableType = enumeration(INTEGER, REAL, BOOLEAN, STRING);
123 type VariableList = tuple<list<Integer>, list<Integer>, list<Integer>, list<Integer>>; //variables <int, float, bool, string>
124
125 //----------------------------------------------------------
126 // Functions to build the task graph from the BLT structure
127 //----------------------------------------------------------
128
129 public function createTaskGraph "author: marcusw, waurich
130 Creates a task graph on scc-level."
131 input BackendDAE.BackendDAE iDAE;
132 input Boolean iAnalyzeParameters = false; //set this to true if the parameter information of task graph meta should be filled
133 output TaskGraph oGraph;
134 output TaskGraphMeta oGraphData;
135 protected
136 list<BackendDAE.EqSystem> systs;
137 BackendDAE.Shared shared;
138 TaskGraph graph;
139 TaskGraphMeta graphData;
140 algorithm
141 //Iterate over each system
142 8 BackendDAE.DAE(systs,shared) := iDAE;
143 8 (graph,graphData) := getEmptyTaskGraph(0,0,0);
144
2/4
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✓ Branch 6 taken 8 times.
✗ Branch 7 not taken.
16 (oGraph,oGraphData,_) := List.fold(systs, function createTaskGraph0(iShared=shared, iAnalyzeParameters=iAnalyzeParameters), (graph,graphData,1));
145 end createTaskGraph;
146
147 public function createTaskGraph0 "author: marcusw, waurich
148 Creates a task graph out of the given system."
149 input BackendDAE.EqSystem iSyst; //The input system which should be analysed
150 input BackendDAE.Shared iShared;
151 input Boolean iAnalyzeParameters;
152 input tuple<TaskGraph,TaskGraphMeta,Integer> iGraphInfo; //<_,_,eqSysIdx>
153 output tuple<TaskGraph,TaskGraphMeta,Integer> oGrapInfo;
154 protected
155 BackendDAE.StrongComponents comps;
156 BackendDAE.Variables vars;
157 BackendDAE.EquationArray orderedEqs;
158 AvlTreePathFunction.Tree sharedFuncs;
159 TaskGraphMeta iGraphData;
160 TaskGraphMeta tmpGraphData;
161 TaskGraph iGraph;
162 TaskGraph tmpGraph;
163
164 array<Communications> commCosts;
165 array<list<Integer>> inComps;
166 array<list<Integer>> compParamMapping;
167 array<tuple<Integer,Real>> exeCosts;
168 array<Integer> nodeMark;
169 array<tuple<Integer,Integer,Integer>> varCompMapping, eqCompMapping; //Map each variable to the scc that solves her
170 array<String> compNames;
171 array<String> compDescs;
172 Integer numberOfVars;
173 array<ComponentInfo> compInformations;
174
175 Integer eqSysIdx;
176
177 BackendDAE.Matching matching;
178 BackendDAE.AdjacencyMatrix adjacencyMatrix;
179 algorithm
180 21 BackendDAE.EQSYSTEM(matching=matching, orderedVars=vars, orderedEqs=orderedEqs) := iSyst;
181 21 comps := BackendDAEUtil.getCompsOfMatching(matching);
182 21 BackendDAE.SHARED(functionTree=sharedFuncs) := iShared;
183 21 (iGraph,iGraphData,eqSysIdx) := iGraphInfo;
184
185 42 (_,adjacencyMatrix,_) := BackendDAEUtil.getAdjacencyMatrix(iSyst, BackendDAE.NORMAL(), SOME(sharedFuncs), BackendDAEUtil.isInitializationDAE(iShared));
186 21 numberOfVars := BackendVariable.varsSize(vars);
187 21 (tmpGraph,tmpGraphData) := getEmptyTaskGraph(listLength(comps), numberOfVars, ExpandableArray.getNumberOfElements(orderedEqs));
188 21 TASKGRAPHMETA(inComps=inComps, compNames=compNames, exeCosts=exeCosts, commCosts=commCosts, nodeMark=nodeMark, varCompMapping=varCompMapping, eqCompMapping=eqCompMapping, compParamMapping=compParamMapping, compInformations=compInformations) := tmpGraphData;
189 //print("createTaskGraph0 try to get varCompMapping\n");
190 21 (varCompMapping,eqCompMapping) := getVarEqCompMapping(comps, eqSysIdx, 0, 0, varCompMapping, eqCompMapping);
191 //print("createTaskGraph0 varCompMapping created\n");
192 21 compDescs := getEquationStrings(comps,iSyst); //gets the description i.e. the whole equation, for every component
193
1/2
✓ Branch 3 taken 21 times.
✗ Branch 4 not taken.
42 (tmpGraph,inComps,compParamMapping,commCosts,compNames,nodeMark,_) := List.fold(comps, function createTaskGraph1(iSystInfo=(adjacencyMatrix,iSyst,iShared,listLength(comps)),iVarInfo=(varCompMapping,eqCompMapping,{}),iAnalyzeParameters=iAnalyzeParameters),(tmpGraph,inComps,compParamMapping,commCosts,compNames,nodeMark,1));
194 21 tmpGraph := Array.mapNoCopy(tmpGraph, function List.sort(inCompFunc = intGt));
195 // gather the metadata
196 21 tmpGraphData := TASKGRAPHMETA(inComps, varCompMapping, eqCompMapping, compParamMapping, compNames, compDescs, exeCosts, commCosts, nodeMark, compInformations);
197
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 12 times.
21 if(intGt(eqSysIdx,1)) then
198 9 (tmpGraph,tmpGraphData) := taskGraphAppend(iGraph,iGraphData,tmpGraph,tmpGraphData);
199 end if;
200 21 oGrapInfo := ((tmpGraph,tmpGraphData,eqSysIdx+1));
201 end createTaskGraph0;
202
203 public function getSystemComponents "author: marcusw
204 Returns all components of the given BackendDAE."
205 input BackendDAE.BackendDAE iDae;
206 output BackendDAE.StrongComponents oComps;
207 output array<tuple<BackendDAE.EqSystem, Integer>> oMapping; //Map each component to <eqSystem, eqSystemIdx>
208 protected
209 BackendDAE.EqSystems systs;
210 List<tuple<BackendDAE.EqSystem,Integer>> tmpSystems;
211 BackendDAE.StrongComponents tmpComps;
212 algorithm
213 (oComps,oMapping) := match iDae
214 case BackendDAE.DAE(eqs=systs)
215 algorithm
216 32 (tmpComps, tmpSystems,_) := List.fold(systs,getSystemComponents0,({},{},1));
217 32 then (tmpComps,listArray(tmpSystems));
218 else fail();
219 end match;
220 end getSystemComponents;
221
222 protected function getSystemComponents0 "author: marcusw
223 Adds the information for the given EqSystem to the system mapping structure."
224 input BackendDAE.EqSystem iSyst;
225 input tuple<BackendDAE.StrongComponents, list<tuple<BackendDAE.EqSystem,Integer>>, Integer> iSystMapping; //last Integer is idx of isyst
226 output tuple<BackendDAE.StrongComponents, list<tuple<BackendDAE.EqSystem,Integer>>, Integer> oSystMapping; //Map each component to <eqSystem, eqSystemIdx>
227 protected
228 BackendDAE.StrongComponents tmpComps, comps;
229 BackendDAE.Matching matching;
230 list<tuple<BackendDAE.EqSystem,Integer>> tmpSystMapping;
231 Integer currentIdx;
232 algorithm
233 oSystMapping := match(iSyst, iSystMapping)
234 case(BackendDAE.EQSYSTEM(matching=matching), (tmpComps,tmpSystMapping,currentIdx))
235 algorithm
236 68 comps := BackendDAEUtil.getCompsOfMatching(matching);
237 //print("--getSystemComponents0 begin\n");
238 68 tmpSystMapping := List.fold2(comps, getSystemComponents1, iSyst, currentIdx, tmpSystMapping);
239 //print(stringDelimitList(List.map(comps, BackendDump.printComponent),","));
240 68 comps := listAppend(tmpComps,comps);
241 //print("--getSystemComponents0 end (found " + intString(listLength(comps)) + " components in system " + intString(currentIdx) + ")\n");
242 68 then ((comps, tmpSystMapping, currentIdx+1));
243 else
244 algorithm
245 ✗ print("getSystemComponents0 failed\n");
246 ✗ then fail();
247 end match;
248 end getSystemComponents0;
249
250 protected function getSystemComponents1 "author: marcusw
251 Extends the mapping information for the given component and equation system."
252 input BackendDAE.StrongComponent icomp;
253 input BackendDAE.EqSystem isyst;
254 input Integer isystIdx;
255 input list<tuple<BackendDAE.EqSystem,Integer>> iMapping; //Map each component to the EqSystem
256 output list<tuple<BackendDAE.EqSystem,Integer>> oMapping; //Map each component to the EqSystem
257 algorithm
258 12248 oMapping := listAppend(iMapping,{(isyst,isystIdx)});
259 end getSystemComponents1;
260
261 protected function getNumberOfSystemComponents "author: marcusw
262 Returns the number of components stored in the BackendDAE."
263 input BackendDAE.BackendDAE iDae;
264 output Integer oNumOfComps;
265 protected
266 BackendDAE.EqSystems eqs;
267 algorithm
268 ✗ BackendDAE.DAE(eqs=eqs) := iDae;
269 ✗ oNumOfComps := List.fold(eqs, getNumberOfEqSystemComponents, 0);
270 end getNumberOfSystemComponents;
271
272 protected function getNumberOfEqSystemComponents "author: marcusw
273 Adds the number of components in the given eqSystem to the iNumOfComps."
274 input BackendDAE.EqSystem iEqSystem;
275 input Integer iNumOfComps;
276 output Integer oNumOfComps;
277 protected
278 BackendDAE.StrongComponents comps;
279 BackendDAE.Matching matching;
280 algorithm
281 ✗ BackendDAE.EQSYSTEM(matching=matching) := iEqSystem;
282 ✗ comps := BackendDAEUtil.getCompsOfMatching(matching);
283 ✗ oNumOfComps := iNumOfComps + listLength(comps);
284 end getNumberOfEqSystemComponents;
285
286 public function getEmptyTaskGraph "author: Waurich TUD 2013-06
287 generates an empty TaskGraph and empty TaskGraphMeta for a graph with numComps nodes."
288 input Integer numComps;
289 input Integer numVars;
290 input Integer numEqs;
291 output TaskGraph graph;
292 output TaskGraphMeta graphData;
293 protected
294 array<list<Integer>> inComps;
295 array<tuple<Integer,Integer,Integer>> varCompMapping;
296 array<tuple<Integer,Integer,Integer>> eqCompMapping;
297 array<String> compNames;
298 array<String> compDescs;
299 array<tuple<Integer,Real>> exeCosts;
300 array<Communications> commCosts;
301 array<list<Integer>> compParamMapping;
302 array<Integer> nodeMark;
303 array<ComponentInfo> compInformations;
304 algorithm
305 33 graph := arrayCreate(numComps,{});
306 33 inComps := arrayCreate(numComps,{});
307 33 compParamMapping := arrayCreate(numComps,{});
308 33 varCompMapping := arrayCreate(numVars,(0,0,0));
309 33 eqCompMapping := arrayCreate(numEqs,(0,0,0));
310 33 compNames := arrayCreate(numComps,"");
311 33 compDescs := arrayCreate(numComps,"");
312 33 exeCosts := arrayCreate(numComps,(-1,-1.0));
313 33 commCosts := arrayCreate(numComps,{});
314 33 nodeMark := arrayCreate(numComps,0);
315 33 compInformations := arrayCreate(numComps, COMPONENTINFO(false,false,false));
316 33 graphData := TASKGRAPHMETA(inComps,varCompMapping,eqCompMapping,compParamMapping,compNames,compDescs,exeCosts,commCosts,nodeMark,compInformations);
317 end getEmptyTaskGraph;
318
319 public function copyTaskGraphMeta "author: Waurich TUD 2013-07
320 Copies the metadata to avoid overwriting the arrays."
321 input TaskGraphMeta graphDataIn;
322 output TaskGraphMeta graphDataOut;
323 protected
324 array<list<Integer>> inComps, inComps1;
325 array<tuple<Integer, Integer, Integer>> varCompMapping, varCompMapping1;
326 array<tuple<Integer,Integer,Integer>> eqCompMapping, eqCompMapping1;
327 array<list<Integer>> compParamMapping, compParamMapping1;
328 array<String> compNames, compNames1;
329 array<String> compDescs, compDescs1;
330 array<tuple<Integer,Real>> exeCosts, exeCosts1;
331 array<Communications> commCosts, commCosts1;
332 array<Integer>nodeMark, nodeMark1;
333 array<ComponentInfo> compInformations, compInformations1;
334 algorithm
335 56 TASKGRAPHMETA(inComps=inComps, varCompMapping=varCompMapping, eqCompMapping=eqCompMapping, compParamMapping=compParamMapping, compNames=compNames, compDescs=compDescs, exeCosts=exeCosts, commCosts=commCosts, nodeMark=nodeMark, compInformations=compInformations) := graphDataIn;
336 56 inComps1 := arrayCopy(inComps);
337 56 varCompMapping1 := arrayCopy(varCompMapping);
338 56 eqCompMapping1 := arrayCopy(eqCompMapping);
339 56 compParamMapping1 := arrayCopy(compParamMapping);
340 56 compNames1 := arrayCopy(compNames);
341 56 compDescs1 := arrayCopy(compDescs);
342 56 exeCosts1 := arrayCopy(exeCosts);
343 56 commCosts1 := arrayCopy(commCosts);
344 56 nodeMark1 := arrayCopy(nodeMark);
345 56 compInformations1 := arrayCopy(compInformations);
346 56 graphDataOut := TASKGRAPHMETA(inComps1,varCompMapping1,eqCompMapping1,compParamMapping1,compNames1,compDescs1,exeCosts1,commCosts1,nodeMark1,compInformations1);
347 end copyTaskGraphMeta;
348
349 protected function taskGraphAppend "author:Waurich TUD 2013-06
350 Appends a taskGraph system to an other taskGraph system.all indices will be numbered continuously."
351 input TaskGraph graph1In;
352 input TaskGraphMeta graphData1In;
353 input TaskGraph graph2In;
354 input TaskGraphMeta graphData2In;
355 output TaskGraph graphOut;
356 output TaskGraphMeta graphDataOut;
357 protected
358 Integer eqOffset;
359 Integer idxOffset;
360 Integer varOffset;
361 array<Communications> commCosts1, commCosts2;
362 array<list<Integer>> inComps1, inComps2;
363 array<tuple<Integer,Integer,Integer>> eqCompMapping1, eqCompMapping2;
364 array<tuple<Integer,Real>> exeCosts1, exeCosts2;
365 array<Integer> nodeMark1, nodeMark2;
366 array<list<Integer>> compParamMapping1, compParamMapping2;
367 array<tuple<Integer,Integer,Integer>> varCompMapping1, varCompMapping2; //Map each variable to the scc which solves her
368 array<String> compNames1, compNames2;
369 array<String> compDescs1, compDescs2;
370 array<ComponentInfo> compInformations1, compInformations2;
371 TaskGraph graph2;
372 algorithm
373 9 TASKGRAPHMETA(inComps = inComps1 ,varCompMapping=varCompMapping1, eqCompMapping=eqCompMapping1, compParamMapping=compParamMapping1, compNames=compNames1, compDescs=compDescs1, exeCosts=exeCosts1, commCosts=commCosts1, nodeMark=nodeMark1, compInformations=compInformations1) := graphData1In;
374
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 TASKGRAPHMETA(inComps = inComps2 ,varCompMapping=varCompMapping2, eqCompMapping=eqCompMapping2, compParamMapping=compParamMapping2, compNames=compNames2, compDescs=compDescs2, exeCosts=exeCosts2, commCosts=commCosts2, nodeMark=nodeMark2, compInformations=compInformations2) := graphData2In;
375 eqOffset := arrayLength(eqCompMapping1);
376 idxOffset := arrayLength(graph1In);
377 varOffset := arrayLength(varCompMapping1);
378 eqOffset := arrayLength(eqCompMapping1);
379 9 graph2 := Array.map1(graph2In,updateTaskGraphSystem,idxOffset);
380 9 graphOut := arrayAppend(graph1In,graph2);
381 9 inComps2 := Array.map1(inComps2,updateTaskGraphSystem,idxOffset);
382 9 inComps2 := arrayAppend(inComps1,inComps2);
383 //varCompMapping2 := Array.map1(varCompMapping2,modifyMapping,varOffset);
384 9 varCompMapping2 := Array.map1(varCompMapping2,modifyMapping,idxOffset);
385 9 varCompMapping2 := arrayAppend(varCompMapping1,varCompMapping2);
386 //eqCompMapping2 := Array.map1(eqCompMapping2,modifyMapping,eqOffset);
387 9 eqCompMapping2 := Array.map1(eqCompMapping2,modifyMapping,idxOffset);
388 9 eqCompMapping2 := arrayAppend(eqCompMapping1,eqCompMapping2);
389 9 compParamMapping2 := arrayAppend(compParamMapping1,compParamMapping2);
390 9 compNames2 := Array.map1(compNames2,stringAppend," subsys"); //TODO: change this
391 9 compNames2 := arrayAppend(compNames1,compNames2);
392 9 compDescs2 := arrayAppend(compDescs1,compDescs2);
393 9 exeCosts2 := arrayAppend(exeCosts1,exeCosts2);
394 9 commCosts2 := Array.map1(commCosts2,updateCommCosts,idxOffset);
395 9 commCosts2 := arrayAppend(commCosts1,commCosts2);
396 9 nodeMark2 := arrayAppend(nodeMark1,nodeMark2);
397 9 compInformations2 := arrayAppend(compInformations1, compInformations2);
398 9 graphDataOut := TASKGRAPHMETA(inComps2,varCompMapping2,eqCompMapping2,compParamMapping2,compNames2,compDescs2,exeCosts2,commCosts2,nodeMark2,compInformations2);
399 end taskGraphAppend;
400
401 protected function modifyMapping "author: marcusw, waurich
402 Adds the given offset to the first and last tuple-element."
403 input tuple<Integer,Integer,Integer> iMappingTuple;
404 input Integer iOffset;
405 output tuple<Integer,Integer,Integer> oMappingTuple;
406 protected
407 Integer i1,i2,i3; //i1 = offset
408 algorithm
409 3005 (i1,i2,i3) := iMappingTuple;
410 3005 oMappingTuple := (i1+iOffset,i2,iOffset);
411 end modifyMapping;
412
413 protected function updateCommCosts "author: Waurich TUD 2013-07
414 updates the CommCosts to the enumerated indeces."
415 input Communications commCostsIn;
416 input Integer idxOffset;
417 output Communications commCostsOut;
418 algorithm
419 1292 commCostsOut := List.map1(commCostsIn,updateCommCosts1,idxOffset);
420 end updateCommCosts;
421
422 protected function updateCommCosts1 "author: Waurich TUD 2013-07
423 Adds the idxOffset to the child node index."
424 input Communication commCostsIn;
425 input Integer idxOffset;
426 output Communication commCostsOut;
427 protected
428 Integer numberOfVars, childNode;
429 list<Integer> integerVars,floatVars,booleanVars,stringVars;
430 Real requiredTime;
431 algorithm
432 2169 COMMUNICATION(numberOfVars=numberOfVars,integerVars=integerVars,floatVars=floatVars,booleanVars=booleanVars,stringVars=stringVars,childNode=childNode,requiredTime=requiredTime) := commCostsIn;
433 2169 childNode := childNode+idxOffset;
434 2169 commCostsOut := COMMUNICATION(numberOfVars,integerVars,floatVars,booleanVars,stringVars,childNode,requiredTime);
435 end updateCommCosts1;
436
437 protected function updateTaskGraphSystem "author: Waurich TUD 2013-07
438 map function to add the indices in the taskGraph system to the number of nodes of the previous system."
439 input list<Integer> graphRowIn;
440 input Integer idxOffset;
441 output list<Integer> graphRowOut;
442 algorithm
443 2584 graphRowOut := List.map1(graphRowIn,intAdd,idxOffset);
444 end updateTaskGraphSystem;
445
446 protected function createTaskGraph1 "author: marcusw, waurich
447 Appends the task-graph information for the given StrongComponent to the given graph."
448 input BackendDAE.StrongComponent iComponent;
449 input tuple<BackendDAE.AdjacencyMatrix,BackendDAE.EqSystem,BackendDAE.Shared,Integer> iSystInfo; //<adjacencyMatrix,isyst,iShared,numberOfComponents> in very compact form
450 input tuple<array<tuple<Integer,Integer,Integer>>,array<tuple<Integer,Integer,Integer>>,list<Integer>> iVarInfo; //<varCompMapping,eqCompMapping,eventVarLst
451 input Boolean iAnalyzeParameters;
452 input tuple<TaskGraph,array<list<Integer>>,array<list<Integer>>,array<Communications>,array<String>,array<Integer>,Integer> graphInfoIn;
453 //<taskGraph,inComps,compParamMapping,commCosts,compNames,nodeMark,componentIndex>
454 output tuple<TaskGraph,array<list<Integer>>,array<list<Integer>>,array<Communications>,array<String>,array<Integer>,Integer> graphInfoOut;
455 protected
456 BackendDAE.AdjacencyMatrix adjacencyMatrix;
457 BackendDAE.EqSystem isyst;
458 BackendDAE.Shared ishared;
459 BackendDAE.Variables orderedVars;
460 BackendDAE.Variables globalKnownVars, localKnownVars, knownVars;
461 BackendDAE.EquationArray orderedEqs;
462 TaskGraph graphIn;
463 TaskGraph graphTmp;
464 array<list<Integer>> inComps;
465 array<tuple<Integer,Integer,Integer>> varCompMapping; //<sccIdx, eqSysIdx, offset>
466 array<tuple<Integer,Integer,Integer>> eqCompMapping; //<sccIdx, eqSysIdx, offset>
467 array<String> compNames;
468 array<Communications> commCosts;
469 Communications commCostsOfNode;
470 array<Integer> nodeMark;
471 tuple<list<Integer>, list<tuple<Integer, Integer>>, list<Integer>, list<Integer>> unsolvedVars; //<intVarIdc, <floatVarIdx, [0 if derived, 1 if not]>, boolVarIdc,stringVarIdc>
472 list<Integer> eventVarLst;
473 Integer componentIndex, numberOfComps;
474 list<tuple<Integer,list<Integer>,list<Integer>,list<Integer>,list<Integer>>> requiredSccs_RefCount; //<sccIdx, refCountInt, refCountFloat, refCountBool, refCountString>
475 String compName;
476 list<Integer> paramVars;
477 array<list<Integer>> compParamMapping;
478 UnorderedMap<Integer, VariableList> requiredSccs;
479 algorithm
480 1736 (adjacencyMatrix,isyst,ishared,numberOfComps) := iSystInfo;
481 1736 BackendDAE.SHARED(globalKnownVars=globalKnownVars, localKnownVars=localKnownVars) := ishared;
482 1736 BackendDAE.EQSYSTEM(orderedVars=orderedVars,orderedEqs=orderedEqs) := isyst;
483 1736 (varCompMapping,eqCompMapping,eventVarLst) := iVarInfo;
484 1736 (graphIn,inComps,compParamMapping,commCosts,compNames,nodeMark,componentIndex) := graphInfoIn;
485 1736 inComps := arrayUpdate(inComps,componentIndex,{componentIndex});
486 1736 compName := BackendDump.strongComponentString(iComponent);
487 1736 compNames := arrayUpdate(compNames,componentIndex,compName);
488 1736 HpcOmBenchmark.benchSystem();
489
490 // The known vars are only used if iAnalyzeParameters is true, skip this
491 // potentially very expensive operation otherwise.
492
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1736 times.
1736 if iAnalyzeParameters then
493 ✗ knownVars := BackendVariable.addVariables(globalKnownVars, localKnownVars);
494 else
495 knownVars := globalKnownVars;
496 end if;
497
498 1736 (unsolvedVars,paramVars) := getUnsolvedVarsBySCC(iComponent,adjacencyMatrix,orderedVars,knownVars,orderedEqs,eventVarLst,iAnalyzeParameters);
499 1736 compParamMapping := arrayUpdate(compParamMapping, componentIndex, paramVars);
500
501 1736 requiredSccs := UnorderedMap.new<VariableList>(Util.id, intEq);
502
2/2
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 1736 times.
1737 for intVar in Util.tuple41(unsolvedVars) loop
503 1 fillRequiredSccs((intVar, 1), VariableType.INTEGER, varCompMapping, requiredSccs);
504 end for;
505
506
2/2
✓ Branch 1 taken 5392 times.
✓ Branch 2 taken 1736 times.
7128 for floatVar in Util.tuple42(unsolvedVars) loop
507 5392 fillRequiredSccs(floatVar, VariableType.REAL, varCompMapping, requiredSccs);
508 end for;
509
510
2/2
✓ Branch 1 taken 324 times.
✓ Branch 2 taken 1736 times.
2060 for boolVar in Util.tuple43(unsolvedVars) loop
511 324 fillRequiredSccs((boolVar, 1), VariableType.BOOLEAN, varCompMapping, requiredSccs);
512 end for;
513
514
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1736 times.
1736 for stringVar in Util.tuple44(unsolvedVars) loop
515 ✗ fillRequiredSccs((stringVar, 1), VariableType.STRING, varCompMapping, requiredSccs);
516 end for;
517
518 1736 requiredSccs_RefCount := createRequiredSccsRefCount(requiredSccs);
519 1736 (commCosts,commCostsOfNode) := updateCommCostBySccRef(requiredSccs_RefCount, componentIndex, commCosts);
520 1736 graphTmp := fillAdjacencyList(graphIn,componentIndex,commCostsOfNode,1);
521 1736 graphInfoOut := (graphTmp,inComps,compParamMapping,commCosts,compNames,nodeMark,componentIndex+1);
522 end createTaskGraph1;
523
524 protected function createRequiredSccsRefCount
525 input UnorderedMap<Integer, VariableList> requiredSccs;
526 output list<tuple<Integer,list<Integer>,list<Integer>,list<Integer>,list<Integer>>> requiredSccsRefCount = {};
527 protected
528 Integer scc_idx;
529 list<Integer> int_vars, float_vars, bool_vars, string_vars;
530 algorithm
531
2/2
✓ Branch 1 taken 2938 times.
✓ Branch 2 taken 1736 times.
4674 for e in UnorderedMap.toList(requiredSccs) loop
532 2938 (scc_idx, (int_vars, float_vars, bool_vars, string_vars)) := e;
533 2938 requiredSccsRefCount := (scc_idx, int_vars, float_vars, bool_vars, string_vars) :: requiredSccsRefCount;
534 end for;
535 end createRequiredSccsRefCount;
536
537 protected function updateCommCostBySccRef "author: marcusw
538 Updates the given commCosts-array with the values of the refCount-list."
539 input list<tuple<Integer,list<Integer>,list<Integer>,list<Integer>,list<Integer>>> requiredSccs_RefCount; //<sccIdx,refCountInt,refCountFloat,refCountBool,refCountString>
540 input Integer nodeIdx;
541 input array<Communications> iCommCosts;
542 output array<Communications> oCommCosts;
543 //the communications, created for the given node (nodeIdx) - the required time is set to -1.0, the childNode-idx is set the the parent-idx of the ref counter!
544 output Communications oNodeComms;
545 protected
546 Communications tmpComms;
547 algorithm
548 1736 tmpComms := List.map1(requiredSccs_RefCount, createCommunicationObject, -1.0);
549 1736 oCommCosts := List.fold1(tmpComms,updateCommCostBySccRef1,nodeIdx,iCommCosts);
550 oNodeComms := tmpComms;
551 end updateCommCostBySccRef;
552
553 protected function createCommunicationObject "author: marcusw
554 Helper function which converts a tuple<sccIdx,refCountInt,refCountFloat,refCountBool> to a Communictaion-object."
555 input tuple<Integer,list<Integer>,list<Integer>,list<Integer>,list<Integer>> iTuple;
556 input Real requiredTime;
557 output Communication oComm;
558 protected
559 list<Integer> integerVars,floatVars,booleanVars,stringVars;
560 Integer sccIdx,refCountSum;
561 algorithm
562 2938 (sccIdx,integerVars,floatVars,booleanVars,stringVars) := iTuple;
563 2938 refCountSum := listLength(integerVars) + listLength(floatVars) + listLength(booleanVars) + listLength(stringVars);
564 2938 oComm := COMMUNICATION(refCountSum,integerVars,floatVars,booleanVars,stringVars,sccIdx,requiredTime);
565 end createCommunicationObject;
566
567 protected function updateCommCostBySccRef1 "author: marcusw
568 Helper function which appends an edge from source to target with the given parameters."
569 input Communication iEdgeSource;
570 input Integer iEdgeTarget; //sccIdx
571 input array<Communications> iCommCosts; //<sccIdx,numberOfVars,requiredCycles>
572 output array<Communications> oCommCosts;
573 protected
574 Communications oldComms;
575 Integer sourceSccIdx;
576 list<Integer> integerVars,floatVars,booleanVars,stringVars;
577 Integer numberOfVars;
578 Real requiredTime;
579 Communication tmpComm;
580 algorithm
581 2938 COMMUNICATION(numberOfVars=numberOfVars,integerVars=integerVars,floatVars=floatVars,booleanVars=booleanVars,stringVars=stringVars,childNode=sourceSccIdx,requiredTime=requiredTime) := iEdgeSource;
582 2938 oldComms := arrayGet(iCommCosts, sourceSccIdx);
583 //print("updateCommCostBySccRef1 added edge from " + intString(sourceSccIdx) + " to " + intString(iEdgeTarget) + "\n");
584 2938 tmpComm := COMMUNICATION(numberOfVars,integerVars,floatVars,booleanVars,stringVars,iEdgeTarget,requiredTime);
585 2938 oCommCosts := arrayUpdate(iCommCosts, sourceSccIdx, tmpComm::oldComms);
586 end updateCommCostBySccRef1;
587
588 protected function fillAdjacencyList "author: waurich TUD 2013-06
589 Append the child index to the rows indexed by the parent list."
590 input array<list<Integer>> adjLstIn;
591 input Integer childNode;
592 input Communications parentLst; //Communication-objects, with childNode = parentNodeIdx
593 input Integer Idx; //current parent, starting with 1
594 output array<list<Integer>> adjLstOut;
595 algorithm
596 adjLstOut := matchcontinue Idx
597 local
598 Communication parentNode;
599 list<Integer> parentRow;
600 array<list<Integer>> adjLst;
601 Integer parentNodeIdx;
602 case _
603 algorithm
604
2/2
✓ Branch 1 taken 1736 times.
✓ Branch 2 taken 2938 times.
4674 true := listLength(parentLst) >= Idx;
605 2938 parentNode := listGet(parentLst,Idx);
606 2938 COMMUNICATION(childNode=parentNodeIdx) := parentNode;
607 2938 parentRow := arrayGet(adjLstIn,parentNodeIdx);
608 parentRow := childNode::parentRow;
609 2938 parentRow := List.removeOnTrue(parentNodeIdx,intEq,parentRow); // deletes the self-loops
610 2938 adjLst := arrayUpdate(adjLstIn,parentNodeIdx,parentRow);
611 2938 adjLst := fillAdjacencyList(adjLst,childNode,parentLst,Idx+1);
612 then
613 adjLst;
614 else adjLstIn;
615 end matchcontinue;
616 end fillAdjacencyList;
617
618 protected function getEquationStrings "author: Waurich TUD 2013-06
619 Gets the equation and the variable its solved for for every StrongComponent. index = component. entry = description"
620 input BackendDAE.StrongComponents iComps;
621 input BackendDAE.EqSystem iEqSystem;
622 output array<String> eqDescsOut;
623 protected
624 list<String> eqDescs;
625 algorithm
626 21 eqDescs := List.fold1(iComps,getEquationStrings2,iEqSystem,{});
627 21 eqDescs := listReverse(eqDescs);
628 21 eqDescsOut := listArray(eqDescs);
629 end getEquationStrings;
630
631 protected function getEquationStrings2 "author: Waurich TUD 2013-06
632 Implementation for getEquationStrings"
633 input BackendDAE.StrongComponent comp;
634 input BackendDAE.EqSystem iEqSystem;
635 input List<String> iEqDesc;
636 output List<String> oEqDesc;
637 algorithm
638 oEqDesc := matchcontinue(comp, iEqSystem)
639 local
640 Integer i;
641 Integer v;
642 List<BackendDAE.Var> varLst;
643 List<Integer> vs;
644 List<String> descLst;
645 String eqString;
646 String varString;
647 String desc;
648 Option<list<tuple<Integer, Integer, BackendDAE.Equation>>> jac;
649 BackendDAE.EquationArray orderedEqs;
650 BackendDAE.Variables orderedVars;
651 BackendDAE.Equation eqn;
652 BackendDAE.Var var;
653 case(BackendDAE.SINGLEEQUATION(eqn = i, var = v), BackendDAE.EQSYSTEM(orderedEqs = orderedEqs, orderedVars = orderedVars))
654 algorithm
655 //get the equation string
656 1627 eqString := BackendDump.equationString(BackendEquation.get(orderedEqs, i));
657 //get the variable string
658 1627 varString := getVarString(BackendVariable.getVarAt(orderedVars, v));
659 1627 desc := (eqString + " FOR " + varString);
660 descLst := desc::iEqDesc;
661 then
662 descLst;
663 case(BackendDAE.EQUATIONSYSTEM(jac = BackendDAE.FULL_JACOBIAN(_)), BackendDAE.EQSYSTEM())
664 algorithm
665 desc := ("Equation System");
666 descLst := desc::iEqDesc;
667 then
668 descLst;
669 case(BackendDAE.SINGLEARRAY(eqn = i, vars = vs), BackendDAE.EQSYSTEM(orderedEqs = orderedEqs, orderedVars = orderedVars, matching= BackendDAE.MATCHING()))
670 algorithm
671 //get the equation string
672 3 eqString := BackendDump.equationString(BackendEquation.get(orderedEqs, i));
673 //get the variable string
674 3 varLst := BackendVariable.varList(orderedVars);
675 //var = listGet(varLst,arrayGet(ass2,i));
676 //varString = getVarString(var);
677 //desc = ("ARRAY:"+eqString + " FOR " + varString);
678 3 desc := ("ARRAY:"+eqString + " FOR THE VARS: " + stringDelimitList(List.map1(vs,List.getIndexFirst,List.map(varLst,getVarString))," AND "));
679 descLst := desc::iEqDesc;
680 then
681 descLst;
682 case(BackendDAE.SINGLEALGORITHM(eqn = i, vars = vs), BackendDAE.EQSYSTEM(orderedEqs = orderedEqs, orderedVars = orderedVars, matching= BackendDAE.MATCHING()))
683 algorithm
684 //get the equation string
685 1 eqString := BackendDump.equationString(BackendEquation.get(orderedEqs, i));
686 //get the variable string
687 1 varLst := BackendVariable.varList(orderedVars);
688 //var = listGet(varLst,arrayGet(ass2,i));
689 //varString = getVarString(var);
690 //desc = ("ALGO:"+eqString + " FOR " + varString);
691 1 desc := ("ALGO: "+eqString + " FOR THE VARS: " + stringDelimitList(List.map1(vs,List.getIndexFirst,List.map(varLst,getVarString))," AND "));
692 descLst := desc::iEqDesc;
693 then
694 descLst;
695 case(BackendDAE.SINGLECOMPLEXEQUATION(eqn = i, vars = vs), BackendDAE.EQSYSTEM(orderedEqs = orderedEqs, orderedVars = orderedVars, matching= BackendDAE.MATCHING()))
696 algorithm
697 //get the equation string
698 ✗ eqString := BackendDump.equationString(BackendEquation.get(orderedEqs, i));
699 //get the variable string
700 ✗ varLst := BackendVariable.varList(orderedVars);
701 //var = listGet(varLst,arrayGet(ass2,i));
702 //varString = getVarString(var);
703 //desc = ("COMPLEX:"+eqString + " FOR " + varString);
704 ✗ desc := ("COMPLEX: "+eqString + " FOR THE VARS: " + stringDelimitList(List.map1(vs,List.getIndexFirst,List.map(varLst,getVarString))," AND "));
705 descLst := desc::iEqDesc;
706 then
707 descLst;
708 case(BackendDAE.SINGLEWHENEQUATION(eqn = i, vars = vs), BackendDAE.EQSYSTEM(orderedEqs = orderedEqs, orderedVars = orderedVars, matching= BackendDAE.MATCHING()))
709 algorithm
710 //get the equation string
711 27 eqString := BackendDump.equationString(BackendEquation.get(orderedEqs, i));
712 //get the variable string
713 27 varLst := BackendVariable.varList(orderedVars);
714 //var = listGet(varLst,arrayGet(ass2,i));
715 //varString = getVarString(var);
716 //desc = ("WHEN:"+eqString + " FOR " + varString);
717 27 desc := ("WHEN:"+eqString + " FOR THE VARS: " + stringDelimitList(List.map1(vs,List.getIndexFirst,List.map(varLst,getVarString))," AND "));
718 descLst := desc::iEqDesc;
719 then
720 descLst;
721 case(BackendDAE.SINGLEIFEQUATION(eqn = i, vars = vs), BackendDAE.EQSYSTEM(orderedEqs = orderedEqs, orderedVars = orderedVars, matching= BackendDAE.MATCHING()))
722 algorithm
723 //get the equation string
724 ✗ eqString := BackendDump.equationString(BackendEquation.get(orderedEqs, i));
725 //get the variable string
726 ✗ varLst := BackendVariable.varList(orderedVars);
727 //var = listGet(varLst,arrayGet(ass2,i));
728 //varString = getVarString(var);
729 //desc = ("IFEQ:"+eqString + " FOR " + varString);
730 ✗ desc := ("IFEQ:"+eqString + " FOR THE VARS: " + stringDelimitList(List.map1(vs,List.getIndexFirst,List.map(varLst,getVarString))," AND "));
731 descLst := desc::iEqDesc;
732 then
733 descLst;
734 case(BackendDAE.TORNSYSTEM(linear=true), BackendDAE.EQSYSTEM( matching= BackendDAE.MATCHING()))
735 algorithm
736 //get the equation string
737 desc := ("Torn linear System");
738 descLst := desc::iEqDesc;
739 then
740 descLst;
741 case(BackendDAE.TORNSYSTEM(linear=false), BackendDAE.EQSYSTEM( matching= BackendDAE.MATCHING()))
742 algorithm
743 //get the equation string
744 desc := ("Torn nonlinear System");
745 descLst := desc::iEqDesc;
746 then
747 descLst;
748 else
749 algorithm
750 desc := ("no singleEquation");
751 descLst := desc::iEqDesc;
752 then
753 descLst;
754 end matchcontinue;
755 end getEquationStrings2;
756
757 public function getVarString "author: waurich TUD 2013-06
758 Get the var string for a given variable. shortens the String. if necessary insert der operator."
759 input BackendDAE.Var inVar;
760 output String varString;
761 algorithm
762 varString := matchcontinue inVar
763 local
764 list<String> varDescLst;
765 case _
766 algorithm
767
2/2
✓ Branch 1 taken 441 times.
✓ Branch 2 taken 6135 times.
6576 true := BackendVariable.isNonStateVar(inVar);
768 6135 varString := BackendDump.varString(inVar);
769 6135 varDescLst := stringListStringChar(varString);
770 6135 varDescLst := shortenVarString(varDescLst);
771 6135 varString := stringCharListString(varDescLst);
772 then
773 varString;
774 case _
775 algorithm
776
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 441 times.
441 false := BackendVariable.isNonStateVar(inVar);
777 441 varString := BackendDump.varString(inVar);
778 441 varDescLst := stringListStringChar(varString);
779 441 varDescLst := shortenVarString(varDescLst);
780 441 varString := stringCharListString(varDescLst);
781 441 varString := (" der(" + varString + ")");
782 then
783 varString;
784 end matchcontinue;
785 end getVarString;
786
787 protected function shortenVarString "author: Waurich TUD 2013-06
788 Terminates var string at :"
789 input List<String> iString;
790 output List<String> oString;
791 protected
792 Integer pos;
793 algorithm
794 6576 pos := List.position(":",iString)-1;
795 6576 (oString,_) := List.split(iString,pos);
796 end shortenVarString;
797
798 protected function getEventNodes "author: Waurich TUD 2013-06
799 Gets the taskgraph nodes that are when-equations"
800 input BackendDAE.BackendDAE systIn;
801 input array<tuple<Integer,Integer,Integer>> eqCompMapping;
802 output list<Integer> eventNodes;
803 protected
804 list<Integer> eqLst;
805 BackendDAE.EqSystems systemsIn;
806 algorithm
807 16 BackendDAE.DAE(eqs=systemsIn) := systIn;
808 16 (eqLst,_) := List.fold(systemsIn, getEventNodeEqs,({},0));
809 16 eventNodes := getArrayTuple31(eqLst,eqCompMapping);
810 end getEventNodes;
811
812 protected function getEventNodeEqs "author: Waurich TUD 2013-06
813 Gets the equation for the When-nodes."
814 input BackendDAE.EqSystem systIn;
815 input tuple<list<Integer>,Integer> eventInfoIn;
816 output tuple<list<Integer>,Integer> eventInfoOut;
817 protected
818 BackendDAE.StrongComponents comps;
819 BackendDAE.Matching matching;
820 BackendDAE.EquationArray orderedEqs;
821 list<Integer> eventEqs;
822 list<Integer> eventEqsIn;
823 Integer offset;
824 algorithm
825 34 BackendDAE.EQSYSTEM(orderedEqs=orderedEqs,matching=matching) := systIn;
826 34 comps := BackendDAEUtil.getCompsOfMatching(matching);
827 34 (eventEqsIn,offset) := eventInfoIn;
828 34 eventEqs := getEventNodeEqs1(comps,offset,{});
829 34 offset := offset+ExpandableArray.getNumberOfElements(orderedEqs);
830 34 eventInfoOut := (listAppend(eventEqs,eventEqsIn), offset);
831 end getEventNodeEqs;
832
833 protected function getEventNodeEqs1 "author: Waurich TUD 2013-06
834 Fold-function for getEventNodeEqs to compute the when equation in an eqSystem."
835 input BackendDAE.StrongComponents comps;
836 input Integer offset;
837 input list<Integer> eventEqsIn;
838 output list<Integer> eventEqsOut;
839 algorithm
840 eventEqsOut := matchcontinue comps
841 local
842 Integer eqn;
843 list<Integer> eventEqs;
844 BackendDAE.StrongComponents rest;
845 BackendDAE.StrongComponent head;
846 case head::rest
847 algorithm
848
2/2
✓ Branch 1 taken 3008 times.
✓ Branch 2 taken 54 times.
3062 true := isWhenEquation(head);
849
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 54 times.
54 BackendDAE.SINGLEWHENEQUATION(eqn = eqn) := head;
850 54 eqn := eqn+offset;
851 54 eventEqs := getEventNodeEqs1(rest,offset,eqn::eventEqsIn);
852 then
853 eventEqs;
854 case head::rest
855 algorithm
856
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3008 times.
3008 false := isWhenEquation(head);
857 3008 eventEqs := getEventNodeEqs1(rest,offset,eventEqsIn);
858 then
859 eventEqs;
860 case {}
861 then
862 eventEqsIn;
863 end matchcontinue;
864 end getEventNodeEqs1;
865
866 protected function getArrayTuple31 "author: Waurich TUD 2013-06
867 Matches entries of list1 with the assigned values of assign to obtain the values."
868 input list<Integer> list1;
869 input array<tuple<Integer,Integer,Integer>> assign;
870 output list<Integer> list2Out;
871 protected
872 list<tuple<Integer,Integer,Integer>> tplLst;
873 algorithm
874 23 tplLst := List.map1(list1,Array.getIndexFirst,assign);
875 23 list2Out := List.map(tplLst,Util.tuple31);
876 end getArrayTuple31;
877
878 protected function isWhenEquation "author: Waurich TUD 2013-06
879 checks if the comp is of type SINGLEWHENEQUATION."
880 input BackendDAE.StrongComponent inComp;
881 output Boolean isWhenEq;
882 algorithm
883 isWhenEq := match inComp
884 local case BackendDAE.SINGLEWHENEQUATION()
885 then
886 true;
887 else false;
888 end match;
889 end isWhenEquation;
890
891 protected function fillRequiredSccs
892 input tuple<Integer, Integer> var; // <varIdx, [0 if derived, 1 if not]>
893 input VariableType varType;
894 input array<tuple<Integer, Integer, Integer>> varMapping;
895 input UnorderedMap<Integer, tuple<list<Integer>, list<Integer>, list<Integer>, list<Integer>>> requiredSccs;
896 protected
897 Integer var_idx, scc_idx, not_derived;
898 list<Integer> integerVars, floatVars, booleanVars, stringVars;
899 algorithm
900 5717 (var_idx, not_derived) := var;
901
902
2/2
✓ Branch 0 taken 1378 times.
✓ Branch 1 taken 4339 times.
5717 if not_derived == 1 then
903 4339 (scc_idx, _, _) := varMapping[var_idx];
904
3/5
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 4014 times.
✓ Branch 3 taken 324 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
4339 (integerVars, floatVars, booleanVars, stringVars) :=
905 UnorderedMap.getOrDefault(scc_idx, requiredSccs, ({}, {}, {}, {}));
906
907 () := match varType
908 case VariableType.INTEGER algorithm integerVars := var_idx::integerVars; then ();
909 case VariableType.REAL algorithm floatVars := var_idx::floatVars; then ();
910 case VariableType.BOOLEAN algorithm booleanVars := var_idx::booleanVars; then ();
911 case VariableType.STRING algorithm stringVars := var_idx::stringVars; then ();
912 end match;
913
914 4339 UnorderedMap.add(scc_idx, (integerVars, floatVars, booleanVars, stringVars), requiredSccs);
915 end if;
916 end fillRequiredSccs;
917
918 protected function getUnsolvedVarsBySCC "author: marcusw, waurich
919 Returns all required variables which are not solved inside the given component."
920 input BackendDAE.StrongComponent iComponent;
921 input BackendDAE.AdjacencyMatrix iAdjacencyMatrix;
922 input BackendDAE.Variables iOrderedVars;
923 input BackendDAE.Variables iKnownVars; //parameters and constants of SHARED-object
924 input BackendDAE.EquationArray iOrderedEquations;
925 input list<Integer> iEventVarLst;
926 input Boolean iAnalyzeParameters;
927 output tuple<list<Integer>,list<tuple<Integer,Integer>>,list<Integer>,list<Integer>> oUnsolvedVars; //<intVarIdc, <floatVarIdx, [0 if derived, 1 if not]>, boolVarIdc, stringVarIdc>
928 output list<Integer> oParamVars; //indices related to iKnownVars-object
929 algorithm
930 (oUnsolvedVars, oParamVars) := matchcontinue iComponent
931 local
932 Integer varIdx;
933 list<Integer> varIdc;
934 tuple<list<Integer>,list<tuple<Integer,Integer>>,list<Integer>,list<Integer>> tmpVars;
935 list<Integer> paramVars;
936 case BackendDAE.SINGLEEQUATION(var=varIdx)
937 algorithm
938 1627 (tmpVars, paramVars) := getUnsolvedVarsBySCC0(iComponent,iAdjacencyMatrix,iOrderedVars,iKnownVars,iOrderedEquations,{varIdx},iEventVarLst, iAnalyzeParameters);
939 then
940 (tmpVars, paramVars);
941 case BackendDAE.EQUATIONSYSTEM(vars=varIdc)
942 algorithm
943 25 (tmpVars, paramVars) := getUnsolvedVarsBySCC0(iComponent,iAdjacencyMatrix,iOrderedVars,iKnownVars,iOrderedEquations,varIdc,iEventVarLst, iAnalyzeParameters);
944 then
945 (tmpVars, paramVars);
946 case BackendDAE.SINGLEARRAY(vars=varIdc)
947 algorithm
948 3 (tmpVars, paramVars) := getUnsolvedVarsBySCC0(iComponent,iAdjacencyMatrix,iOrderedVars,iKnownVars,iOrderedEquations,varIdc,iEventVarLst, iAnalyzeParameters);
949 then
950 (tmpVars, paramVars);
951 case BackendDAE.SINGLEALGORITHM(vars=varIdc)
952 algorithm
953 1 (tmpVars, paramVars) := getUnsolvedVarsBySCC0(iComponent,iAdjacencyMatrix,iOrderedVars,iKnownVars,iOrderedEquations,varIdc,iEventVarLst, iAnalyzeParameters);
954 then
955 (tmpVars, paramVars);
956 case BackendDAE.SINGLECOMPLEXEQUATION(vars=varIdc)
957 algorithm
958 ✗ (tmpVars, paramVars) := getUnsolvedVarsBySCC0(iComponent,iAdjacencyMatrix,iOrderedVars,iKnownVars,iOrderedEquations,varIdc,iEventVarLst, iAnalyzeParameters);
959 then (tmpVars, paramVars);
960 case BackendDAE.SINGLEWHENEQUATION(vars=varIdc)
961 algorithm
962 27 (tmpVars, paramVars) := getUnsolvedVarsBySCC0(iComponent,iAdjacencyMatrix,iOrderedVars,iKnownVars,iOrderedEquations,varIdc,iEventVarLst, iAnalyzeParameters);
963 then (tmpVars, paramVars);
964 case BackendDAE.SINGLEIFEQUATION(vars=varIdc)
965 algorithm
966 ✗ (tmpVars, paramVars) := getUnsolvedVarsBySCC0(iComponent,iAdjacencyMatrix,iOrderedVars,iKnownVars,iOrderedEquations,varIdc,iEventVarLst, iAnalyzeParameters);
967 then
968 (tmpVars, paramVars);
969 case BackendDAE.TORNSYSTEM(BackendDAE.TEARINGSET(tearingvars=varIdc))
970 algorithm
971 53 (tmpVars, paramVars) := getUnsolvedVarsBySCC0(iComponent,iAdjacencyMatrix,iOrderedVars,iKnownVars,iOrderedEquations,varIdc,iEventVarLst, iAnalyzeParameters);
972 then
973 (tmpVars, paramVars);
974 else
975 algorithm
976 ✗ print("getUnsolvedVarsBySCC failed\n");
977 ✗ then fail();
978 end matchcontinue;
979 end getUnsolvedVarsBySCC;
980
981 protected function getUnsolvedVarsBySCC0 "author: marcusw
982 Returns all required variables which are not solved inside the given component."
983 input BackendDAE.StrongComponent iComponent;
984 input BackendDAE.AdjacencyMatrix iAdjacencyMatrix;
985 input BackendDAE.Variables iOrderedVars;
986 input BackendDAE.Variables iKnownVars; //parameters and constants of SHARED-object
987 input BackendDAE.EquationArray iOrderedEquations;
988 input list<Integer> iVarIdc; //variables that are solved by the component
989 input list<Integer> iEventVarLst;
990 input Boolean iAnalyzeParameters;
991 output tuple<list<Integer>,list<tuple<Integer,Integer>>,list<Integer>,list<Integer>> oUnsolvedVars; //<intVars, <floatVarIdx, [1 if derived, 0 if not]>, boolVars, stringVars>
992 output list<Integer> oParamVars; //indices related to iKnownVars-object
993 protected
994 list<tuple<Integer,Integer>> tmpVars;
995 algorithm
996 1736 (tmpVars,oParamVars) := getVarsBySCC(iComponent, iAdjacencyMatrix, iOrderedVars, iKnownVars, iOrderedEquations, iAnalyzeParameters);
997 1736 tmpVars := List.filter1OnTrue(tmpVars, isTupleMember, iVarIdc);
998 1736 tmpVars := removeEventVars(iEventVarLst,tmpVars,1);
999 1736 oUnsolvedVars := List.fold1(tmpVars, getUnsolvedVarsBySCC1, iOrderedVars, ({},{},{},{}));
1000 end getUnsolvedVarsBySCC0;
1001
1002 protected function getUnsolvedVarsBySCC1 "author: marcusw
1003 Append the given variable, regarding their type, to the list of required variables."
1004 input tuple<Integer,Integer> iVarIdx; //<varIdx, derived[0] | not derived [1]>
1005 input BackendDAE.Variables orderedVars;
1006 input tuple<list<Integer>,list<tuple<Integer,Integer>>,list<Integer>,list<Integer>> iUnsolvedVars; //<intVarIdc,realVarIdc,boolVarIdc,stringVarIdc>
1007 output tuple<list<Integer>,list<tuple<Integer,Integer>>,list<Integer>,list<Integer>> oUnsolvedVars;
1008 protected
1009 BackendDAE.Var var;
1010 BackendDAE.Type varType;
1011 algorithm
1012 5717 var := BackendVariable.getVarAt(orderedVars, Util.tuple21(iVarIdx));
1013 5717 varType := BackendVariable.getVarType(var);
1014 5717 oUnsolvedVars := getUnsolvedVarsBySCC2(varType, iVarIdx, iUnsolvedVars);
1015 end getUnsolvedVarsBySCC1;
1016
1017 protected function getUnsolvedVarsBySCC2 "author: marcusw
1018 Append the given variable, regarding their type, to the list of required variables."
1019 input DAE.Type iVarType;
1020 input tuple<Integer,Integer> iVarIdx;
1021 input tuple<list<Integer>,list<tuple<Integer,Integer>>,list<Integer>,list<Integer>> iUnsolvedVars; //<intVarIdc,realVarIdc,boolVarIdc,stringVarIdc>
1022 output tuple<list<Integer>,list<tuple<Integer,Integer>>,list<Integer>,list<Integer>> oUnsolvedVars;
1023 protected
1024 list<Integer> intVarIdc,boolVarIdc,stringVarIdc;
1025 list<tuple<Integer,Integer>> realVarIdc;
1026 Integer varIdx, derived;
1027 DAE.Type ty;
1028 algorithm
1029 oUnsolvedVars := match(iVarType, iVarIdx, iUnsolvedVars)
1030 case(DAE.T_INTEGER(),(varIdx,derived),(intVarIdc,realVarIdc,boolVarIdc,stringVarIdc))
1031 algorithm
1032 intVarIdc := varIdx::intVarIdc;
1033 1 then ((intVarIdc,realVarIdc,boolVarIdc,stringVarIdc));
1034 case(DAE.T_REAL(),(varIdx,derived),(intVarIdc,realVarIdc,boolVarIdc,stringVarIdc))
1035 algorithm
1036 5392 realVarIdc := (varIdx,derived)::realVarIdc;
1037 5392 then ((intVarIdc,realVarIdc,boolVarIdc,stringVarIdc));
1038 case(DAE.T_BOOL(),(varIdx,derived),(intVarIdc,realVarIdc,boolVarIdc,stringVarIdc))
1039 algorithm
1040 boolVarIdc := varIdx::boolVarIdc;
1041 324 then ((intVarIdc,realVarIdc,boolVarIdc,stringVarIdc));
1042 case(DAE.T_ARRAY(ty=ty),(varIdx,derived),(intVarIdc,realVarIdc,boolVarIdc,stringVarIdc))
1043 ✗ then getUnsolvedVarsBySCC2(ty,iVarIdx,iUnsolvedVars);
1044 case(DAE.T_ENUMERATION(),(varIdx,derived),(intVarIdc,realVarIdc,boolVarIdc,stringVarIdc))
1045 algorithm
1046 stringVarIdc := varIdx::stringVarIdc;
1047 ✗ then ((intVarIdc,realVarIdc,boolVarIdc,stringVarIdc));
1048 case(DAE.T_STRING(),(varIdx,derived),(intVarIdc,realVarIdc,boolVarIdc,stringVarIdc))
1049 algorithm
1050 stringVarIdc := varIdx::stringVarIdc;
1051 ✗ then ((intVarIdc,realVarIdc,boolVarIdc,stringVarIdc));
1052 else
1053 algorithm
1054 ✗ print("getUnsolvedVarsBySCC2: Warning, unknown varType for variable " + intString(Util.tuple21(iVarIdx)) +" !\n");
1055 then iUnsolvedVars;
1056 end match;
1057 end getUnsolvedVarsBySCC2;
1058
1059 protected function removeEventVars "author: Waurich TUD 2013-06
1060 Removes EventVars from the varList."
1061 input list<Integer> eventVarLst;
1062 input list<tuple<Integer,Integer>> varLstIn;
1063 input Integer varIdx;
1064 output list<tuple<Integer,Integer>> varLstOut;
1065 algorithm
1066 varLstOut := matchcontinue varIdx
1067 local
1068 tuple<Integer,Integer> varTpl;
1069 list<tuple<Integer,Integer>> varLst;
1070 Integer var;
1071 case _
1072 algorithm
1073
2/2
✓ Branch 1 taken 1736 times.
✓ Branch 2 taken 5717 times.
7453 true := intLe(varIdx,listLength(varLstIn));
1074 5717 varTpl := listGet(varLstIn,varIdx);
1075 5717 (var,_) := varTpl;
1076
1/2
✓ Branch 1 taken 5717 times.
✗ Branch 2 not taken.
5717 true := List.isMemberOnTrue(var,eventVarLst,intEq);
1077 ✗ varLst := listDelete(varLstIn,varIdx);
1078 ✗ varLst := removeEventVars(eventVarLst,varLst,varIdx);
1079 then
1080 varLst;
1081 case _
1082 algorithm
1083
2/2
✓ Branch 1 taken 1736 times.
✓ Branch 2 taken 5717 times.
7453 true := intLe(varIdx,listLength(varLstIn));
1084 5717 varTpl := listGet(varLstIn,varIdx);
1085 5717 (var,_) := varTpl;
1086
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 5717 times.
5717 false := List.isMemberOnTrue(var,eventVarLst,intEq);
1087 5717 varLst := removeEventVars(eventVarLst,varLstIn,varIdx+1);
1088 then
1089 varLst;
1090 else varLstIn;
1091 end matchcontinue;
1092 end removeEventVars;
1093
1094 protected function isTupleMember "author: marcusw
1095 Checks if the given variable (stored as tuple <id,state>) is part of the variable-list. This is only possible if the
1096 second tuple-argument is one - this means that the variable is not derived."
1097 input tuple<Integer,Integer> inTuple;
1098 input List<Integer> varIdc;
1099 output Boolean isNotMember;
1100 protected
1101 Integer varIdx, varState;
1102 Boolean returnValue;
1103 algorithm
1104 isNotMember := matchcontinue inTuple
1105 case (varIdx,varState)
1106 algorithm
1107
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8149 times.
8149 true := intGt(varIdx,0);
1108
2/2
✓ Branch 0 taken 1378 times.
✓ Branch 1 taken 6771 times.
8149 true := intEq(varState,1);
1109 6771 returnValue := List.isMemberOnTrue(varIdx, varIdc, intEq);
1110 6771 then not returnValue;
1111 else true;
1112 end matchcontinue;
1113 end isTupleMember;
1114
1115 protected function compareTupleByVarIdx "author: marcusw
1116 Checks if the given varIdx is the same as the first tuple-argument."
1117 input Integer varIdx;
1118 input tuple<Integer,Integer> var2Idx;
1119 output Boolean equal;
1120 algorithm
1121 ✗ equal := intEq(Util.tuple21(var2Idx),varIdx);
1122 end compareTupleByVarIdx;
1123
1124 public function compareTasksByExecTime "author: marcusw
1125 Compares two given tasks regarding their execution costs."
1126 input Integer iTask1;
1127 input Integer iTask2;
1128 input array<list<Integer>> iTaskComps;
1129 input array<tuple<Integer, Real>> iExeCosts;
1130 input Boolean iDescending; //true if the result list should be in descending order
1131 output Boolean oResult;
1132 protected
1133 Real exeCosts1, exeCosts2;
1134 list<Integer> taskComps1, taskComps2;
1135 algorithm
1136 275 taskComps1 := arrayGet(iTaskComps, iTask1);
1137 275 taskComps2 := arrayGet(iTaskComps, iTask2);
1138 275 exeCosts1 := addUpExeCostsForNode(taskComps1, iExeCosts, 0.0);
1139 275 exeCosts2 := addUpExeCostsForNode(taskComps2, iExeCosts, 0.0);
1140 //print("compareTasksByExecTime: Task '" + intString(iTask1) + "' with exeCost '" + realString(exeCosts1) + "' and Task '" + intString(iTask2) + "' with exeCost '" + realString(exeCosts2) + "'\n");
1141
1/2
✓ Branch 0 taken 275 times.
✗ Branch 1 not taken.
275 if(iDescending) then
1142 275 oResult := realLt(exeCosts1, exeCosts2);
1143 else
1144 ✗ oResult := realGt(exeCosts1, exeCosts2);
1145 end if;
1146 end compareTasksByExecTime;
1147
1148 protected function getVarsBySCC "author: marcusw, waurich
1149 Returns all variables of all equations which are part of the component."
1150 input BackendDAE.StrongComponent iComponent;
1151 input BackendDAE.AdjacencyMatrix iAdjacencyMatrix;
1152 input BackendDAE.Variables iOrderedVars;
1153 input BackendDAE.Variables iKnownVars; //parameters and constants of SHARED-object
1154 input BackendDAE.EquationArray iOrderedEquations;
1155 input Boolean iAnalyzeParameters;
1156 output list<tuple<Integer,Integer>> oVars; //common variables
1157 output list<Integer> oParamVars; //parameters (index related to iKnownVars)
1158 algorithm
1159 (oVars,oParamVars) := match iComponent
1160 local
1161 Integer eqnIdx; //For SINGLEEQUATION
1162 list<Integer> eqns; //For EQUATIONSYSTEM
1163 list<Integer> resEqns;
1164 list<tuple<Integer,Integer>> eqnVars;
1165 list<Integer> paramVars;
1166 BackendDAE.InnerEquations innerEquations;
1167 case BackendDAE.SINGLEEQUATION(eqn=eqnIdx)
1168 algorithm
1169 1627 (eqnVars, paramVars) := getVarsByEqns({eqnIdx}, iAdjacencyMatrix, iOrderedVars, iKnownVars, iOrderedEquations, iAnalyzeParameters);
1170 then
1171 (eqnVars, paramVars);
1172 case BackendDAE.EQUATIONSYSTEM(eqns=eqns)
1173 algorithm
1174 25 (eqnVars, paramVars) := getVarsByEqns(eqns, iAdjacencyMatrix, iOrderedVars, iKnownVars, iOrderedEquations, iAnalyzeParameters);
1175 then
1176 (eqnVars, paramVars);
1177 case BackendDAE.SINGLEARRAY(eqn=eqnIdx)
1178 algorithm
1179 3 (eqnVars, paramVars) := getVarsByEqns({eqnIdx}, iAdjacencyMatrix, iOrderedVars, iKnownVars, iOrderedEquations, iAnalyzeParameters);
1180 then
1181 (eqnVars, paramVars);
1182 case BackendDAE.SINGLEALGORITHM(eqn=eqnIdx)
1183 algorithm
1184 1 (eqnVars, paramVars) := getVarsByEqns({eqnIdx}, iAdjacencyMatrix, iOrderedVars, iKnownVars, iOrderedEquations, iAnalyzeParameters);
1185 then
1186 (eqnVars, paramVars);
1187 case BackendDAE.SINGLECOMPLEXEQUATION(eqn=eqnIdx)
1188 algorithm
1189 ✗ (eqnVars, paramVars) := getVarsByEqns({eqnIdx}, iAdjacencyMatrix, iOrderedVars, iKnownVars, iOrderedEquations, iAnalyzeParameters);
1190 then
1191 (eqnVars, paramVars);
1192 case BackendDAE.SINGLEWHENEQUATION(eqn=eqnIdx)
1193 algorithm
1194 27 (eqnVars, paramVars) := getVarsByEqns({eqnIdx}, iAdjacencyMatrix, iOrderedVars, iKnownVars, iOrderedEquations, iAnalyzeParameters);
1195 then
1196 (eqnVars, paramVars);
1197 case BackendDAE.SINGLEIFEQUATION(eqn=eqnIdx)
1198 algorithm
1199 ✗ (eqnVars, paramVars) := getVarsByEqns({eqnIdx}, iAdjacencyMatrix, iOrderedVars, iKnownVars, iOrderedEquations, iAnalyzeParameters);
1200 then
1201 (eqnVars, paramVars);
1202 case BackendDAE.TORNSYSTEM(BackendDAE.TEARINGSET(residualequations=resEqns,innerEquations = innerEquations))
1203 algorithm
1204 53 (eqns,_,_) := List.map_3(innerEquations, BackendDAEUtil.getEqnAndVarsFromInnerEquation);
1205 53 (eqnVars, paramVars) := getVarsByEqns(listAppend(resEqns,eqns), iAdjacencyMatrix, iOrderedVars, iKnownVars, iOrderedEquations, iAnalyzeParameters);
1206 then
1207 (eqnVars, paramVars);
1208 else
1209 algorithm
1210 ✗ print("Error in getVarsBySCC! Unsupported component-type \n");
1211 ✗ then fail();
1212 end match;
1213 end getVarsBySCC;
1214
1215 protected function tupleToString "author: marcusw
1216 Returns the given tuple as string."
1217 input tuple<Integer,Integer> inTuple;
1218 output String result;
1219 algorithm
1220 result := match inTuple
1221 local
1222 Integer int1,int2;
1223 case (int1,int2)
1224 ✗ then ("(" + intString(int1) + "," + intString(int2) + ")");
1225 end match;
1226 end tupleToString;
1227
1228 protected function tuple3ToString "author: marcusw
1229 Returns the given tuple as string."
1230 input tuple<Integer,Integer,Integer> inTuple;
1231 output String result;
1232 algorithm
1233 result := match inTuple
1234 local
1235 Integer int1,int2,int3;
1236 case (int1,int2,int3)
1237 ✗ then ("(" + intString(int1) + "," + intString(int2) + "," + intString(int3) + ")");
1238 end match;
1239 end tuple3ToString;
1240
1241 protected function getVarsByEqns "author: marcusw
1242 Returns all variables of the adjacency matrix for the given equation and, if iAnalyzeParameters is set to true,
1243 all parameters that are used by the equations."
1244 input list<Integer> iEqnIdc;
1245 input BackendDAE.AdjacencyMatrix iAdjacencyMatrix;
1246 input BackendDAE.Variables iOrderedVars;
1247 input BackendDAE.Variables iKnownVars; //parameters and constants of SHARED-object
1248 input BackendDAE.EquationArray iOrderedEquations;
1249 input Boolean iAnalyzeParameters;
1250 output list<tuple<Integer,Integer>> oAdjacencyVars;
1251 output list<Integer> oParamVars;
1252 protected
1253 list<Integer> adjacencyVars = {};
1254 list<BackendDAE.Var> paramVars = {};
1255 list<BackendDAE.Equation> eqs = {};
1256 algorithm
1257
2/2
✓ Branch 0 taken 2297 times.
✓ Branch 1 taken 1736 times.
4033 for eqIdx in iEqnIdc loop
1258 2297 adjacencyVars := listAppend(arrayGet(iAdjacencyMatrix,eqIdx), adjacencyVars);
1259 2297 eqs := BackendEquation.get(iOrderedEquations, eqIdx)::eqs;
1260 end for;
1261 1736 oAdjacencyVars := List.map(adjacencyVars, getVarTuple);
1262
1263
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1736 times.
1736 if(iAnalyzeParameters) then
1264 ✗ (paramVars,oParamVars) := BackendEquation.equationsParams(eqs,iKnownVars);
1265 //print("Found parameters: " + stringDelimitList(List.map(paramVars, BackendDump.varString), ",") + "\n");
1266 else
1267 1736 oParamVars := {};
1268 end if;
1269
1270 end getVarsByEqns;
1271
1272 protected function getVarTuple "author: marcusw
1273 Converts the given variable to tuple-notation.
1274 Example: varIdx = -4 --> (4,0)
1275 varIdx = 5 --> (5,1)"
1276 input Integer varIdx;
1277 output tuple<Integer,Integer> outIdx; //variable index and variable state
1278 algorithm
1279
2/2
✓ Branch 0 taken 6771 times.
✓ Branch 1 taken 1378 times.
8149 outIdx := if intLe(0,varIdx) then (varIdx, 1) else (-varIdx, 0);
1280 end getVarTuple;
1281
1282 protected function compareIntTuple2 "author: marcusw
1283 Compares the two given tuples. The result is true if the first and second elements are equal."
1284 input tuple<Integer,Integer> tuple1;
1285 input tuple<Integer,Integer> tuple2;
1286 output Boolean equals;
1287 algorithm
1288 equals := match (tuple1,tuple2)
1289 local
1290 Integer int1,int2,int3,int4;
1291 case((int1,int2),(int3,int4)) guard int1==int3 and int2==int4
1292 then true;
1293 else false;
1294 end match;
1295 end compareIntTuple2;
1296
1297 protected function getVarEqCompMapping "author: marcusw
1298 Create a mapping between variables / equations and strong-components. The returned array (one element for
1299 each variable) contains the scc-index which solves the variable."
1300 input BackendDAE.StrongComponents components;
1301 input Integer iEqSysIdx;
1302 input Integer iVarIdxOffset;
1303 input Integer iEqIdxOffset;
1304 input array<tuple<Integer,Integer,Integer>> ivarCompMapping;
1305 input array<tuple<Integer,Integer,Integer>> ieqCompMapping;
1306 output array<tuple<Integer,Integer,Integer>> ovarCompMapping;
1307 output array<tuple<Integer,Integer,Integer>> oeqCompMapping;
1308 algorithm
1309 21 List.fold4(components, getVarEqCompMapping0, ivarCompMapping, ieqCompMapping, iEqSysIdx, (iVarIdxOffset,iEqIdxOffset), 1);
1310 ovarCompMapping := ivarCompMapping;
1311 oeqCompMapping := ieqCompMapping;
1312 end getVarEqCompMapping;
1313
1314 protected function getVarEqCompMapping0 "author: marcusw, waurich
1315 Updates all array elements which are solved in the given component. The array-elements will be set to iSccIdx."
1316 input BackendDAE.StrongComponent component;
1317 input array<tuple<Integer,Integer,Integer>> varCompMapping;
1318 input array<tuple<Integer,Integer,Integer>> eqCompMapping;
1319 input Integer iEqSysIdx;
1320 input tuple<Integer,Integer> iVarEqOffset; //a offset that should be added to the <varIdx,eqIdx>
1321 input Integer iSccIdx;
1322 output Integer oSccIdx;
1323 algorithm
1324 oSccIdx := matchcontinue(component, iVarEqOffset)
1325 local
1326 Integer compVarIdx, iVarOffset, iEqOffset, eq;
1327 list<Integer> compVarIdc,eqns,residuals,othereqs,othervars;
1328 list<list<Integer>> othervarsLst;
1329 BackendDAE.InnerEquations innerEquations;
1330 String helperStr;
1331 case(BackendDAE.SINGLEEQUATION(var = compVarIdx, eqn = eq), (iVarOffset,iEqOffset))
1332 algorithm
1333 //print("HpcOmTaskGraph.getvarCompMapping0 for singleEquation varCompMapping-length:" + intString(arrayLength(varCompMapping)) + " varIdx: " + intString(compVarIdx) + " varOffset: " + intString(iVarOffset) + "\n");
1334 //print("HpcOmTaskGraph.getvarCompMapping0 for singleEquation eqCompMapping-length:" + intString(arrayLength(eqCompMapping)) + " eqIdx: " + intString(eq) + " eqOffset: " + intString(iEqOffset) + "\n");
1335 1627 arrayUpdate(varCompMapping,compVarIdx + iVarOffset,(iSccIdx,iEqSysIdx,iVarOffset));
1336 1627 arrayUpdate(eqCompMapping,eq + iEqOffset,(iSccIdx,iEqSysIdx,iEqOffset));
1337 1627 then iSccIdx+1;
1338 case(BackendDAE.EQUATIONSYSTEM(vars = compVarIdc, eqns=eqns), (iVarOffset,iEqOffset))
1339 algorithm
1340 25 List.fold3(compVarIdc,updateMappingTuple,iSccIdx,iEqSysIdx,iVarOffset,varCompMapping);
1341 25 List.fold3(eqns,updateMappingTuple,iSccIdx,iEqSysIdx,iEqOffset,eqCompMapping);
1342 25 then
1343 iSccIdx+1;
1344 case(BackendDAE.SINGLEWHENEQUATION(vars = compVarIdc,eqn = eq), (iVarOffset,iEqOffset))
1345 algorithm
1346 27 List.fold3(compVarIdc,updateMappingTuple,iSccIdx,iEqSysIdx,iVarOffset,varCompMapping);
1347 27 arrayUpdate(eqCompMapping,eq + iEqOffset,(iSccIdx,iEqSysIdx,iEqOffset));
1348 27 then
1349 iSccIdx+1;
1350 case(BackendDAE.SINGLEARRAY(vars = compVarIdc, eqn = eq), (iVarOffset,iEqOffset))
1351 algorithm
1352 3 List.fold3(compVarIdc,updateMappingTuple,iSccIdx,iEqSysIdx,iVarOffset,varCompMapping);
1353 3 arrayUpdate(eqCompMapping,eq + iEqOffset,(iSccIdx,iEqSysIdx,iEqOffset));
1354 3 then
1355 iSccIdx+1;
1356 case(BackendDAE.SINGLEALGORITHM(vars = compVarIdc,eqn = eq), (iVarOffset,iEqOffset))
1357 algorithm
1358 1 List.fold3(compVarIdc,updateMappingTuple,iSccIdx,iEqSysIdx,iVarOffset,varCompMapping);
1359 1 arrayUpdate(eqCompMapping,eq + iEqOffset,(iSccIdx,iEqSysIdx,iEqOffset));
1360 1 then
1361 iSccIdx+1;
1362 case(BackendDAE.SINGLECOMPLEXEQUATION(vars = compVarIdc, eqn = eq), (iVarOffset,iEqOffset))
1363 algorithm
1364 ✗ List.fold3(compVarIdc,updateMappingTuple,iSccIdx,iEqSysIdx,iVarOffset,varCompMapping);
1365 ✗ arrayUpdate(eqCompMapping,eq + iEqOffset,(iSccIdx,iEqSysIdx,iEqOffset));
1366 ✗ then
1367 iSccIdx+1;
1368 case(BackendDAE.TORNSYSTEM(BackendDAE.TEARINGSET(tearingvars = compVarIdc,residualequations = residuals, innerEquations = innerEquations)), (iVarOffset,iEqOffset))
1369 algorithm
1370 53 (othereqs,othervarsLst,_) := List.map_3(innerEquations, BackendDAEUtil.getEqnAndVarsFromInnerEquation);
1371 53 othervars := List.flatten(othervarsLst);
1372 53 compVarIdc := listAppend(othervars,compVarIdc);
1373 53 eqns := listAppend(othereqs,residuals);
1374 53 List.fold3(compVarIdc,updateMappingTuple,iSccIdx,iEqSysIdx,iVarOffset,varCompMapping);
1375 53 List.fold3(eqns,updateMappingTuple,iSccIdx,iEqSysIdx,iEqOffset,eqCompMapping);
1376 53 then
1377 iSccIdx+1;
1378 case(BackendDAE.SINGLEIFEQUATION(vars = compVarIdc, eqn = eq), (iVarOffset,iEqOffset))
1379 algorithm
1380 ✗ List.fold3(compVarIdc,updateMappingTuple,iSccIdx,iEqSysIdx,iVarOffset,varCompMapping);
1381 ✗ arrayUpdate(eqCompMapping,eq + iEqOffset,(iSccIdx,iEqSysIdx,iEqOffset));
1382 ✗ then
1383 iSccIdx+1;
1384 else
1385 algorithm
1386 ✗ helperStr := BackendDump.strongComponentString(component);
1387 ✗ print("getVarEqCompMapping0 - Unsupported component-type:\n" + helperStr + "\n");
1388 ✗ then fail();
1389 end matchcontinue;
1390 end getVarEqCompMapping0;
1391
1392 public function getSccNodeMapping "author: marcusw
1393 Create a mapping between the strong components and the graph nodes."
1394 input Integer iNumberOfSccs;
1395 input TaskGraphMeta iTaskGraphMeta;
1396 output array<Integer> oMapping; //each scc (arrayIdx) is mapped to exactly one node (value)
1397 protected
1398 array<Integer> tmpMappingArray;
1399 array<list<Integer>> inComps;
1400 array<Integer> nodeMark;
1401 algorithm
1402 16 tmpMappingArray := arrayCreate(iNumberOfSccs,-1);
1403 16 TASKGRAPHMETA(inComps=inComps,nodeMark=nodeMark) := iTaskGraphMeta;
1404 16 (oMapping,_) := Array.fold(inComps, function getSccNodeMapping0(iNodeMarks = nodeMark), (tmpMappingArray,1));
1405 end getSccNodeMapping;
1406
1407 protected function getSccNodeMapping0 "author: marcusw
1408 Set all array entries of the given scc-list to the node-idx."
1409 input list<Integer> iCompsOfNode;
1410 input array<Integer> iNodeMarks;
1411 input tuple<array<Integer>, Integer> iArrayNodeIdx;
1412 output tuple<array<Integer>, Integer> oArrayNodeIdx;
1413 protected
1414 array<Integer> tmpMappingArray;
1415 Integer nodeIdx;
1416 algorithm
1417 2041 (tmpMappingArray,nodeIdx) := List.fold1(iCompsOfNode, getSccNodeMapping1, iNodeMarks, iArrayNodeIdx);
1418 2041 oArrayNodeIdx := (tmpMappingArray,nodeIdx+1);
1419 end getSccNodeMapping0;
1420
1421 protected function getSccNodeMapping1 "author: marcusw
1422 Set all array entries of the given scc-list to the node-idx."
1423 input Integer iCompIdx;
1424 input array<Integer> iNodeMark;
1425 input tuple<array<Integer>, Integer> iArrayNodeIdx;
1426 output tuple<array<Integer>, Integer> oArrayNodeIdx;
1427 protected
1428 Integer iNodeIdx;
1429 Integer nodeMark;
1430 array<Integer> iMappingArray;
1431 algorithm
1432 oArrayNodeIdx := matchcontinue iArrayNodeIdx
1433 case (iMappingArray,iNodeIdx)
1434 algorithm
1435 2602 nodeMark := arrayGet(iNodeMark,iCompIdx);
1436
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2602 times.
2602 true := intNe(-1,nodeMark);
1437 2602 iMappingArray := arrayUpdate(iMappingArray, iCompIdx, iNodeIdx);
1438 2602 then ((iMappingArray,iNodeIdx));
1439 case (iMappingArray,iNodeIdx)
1440 ✗ then ((iMappingArray,iNodeIdx));
1441 end matchcontinue;
1442 end getSccNodeMapping1;
1443
1444 protected function othersInTearComp "author: Waurich TUD 2013-06
1445 Gets the remaining algebraic vars and equations from the torn block.
1446 Remark: there can be more than 1 var per equation."
1447 input tuple<Integer,list<Integer>> otherEqnVarTpl;
1448 input tuple<list<Integer>,list<Integer>> othersIn;
1449 output tuple<list<Integer>,list<Integer>> othersOut;
1450 algorithm
1451 othersOut := matchcontinue othersIn
1452 local
1453 Integer eq;
1454 list<Integer> eqLst;
1455 list<Integer> varTplLst;
1456 list<Integer> varLst;
1457 case _
1458 algorithm
1459 ✗ (eq,varTplLst):=otherEqnVarTpl;
1460 ✗ listGet(varTplLst,1);
1461 ✗ (eqLst,varLst) := othersIn;
1462 ✗ varLst := listAppend(varTplLst,varLst);
1463 eqLst := eq::eqLst;
1464 ✗ then
1465 ((eqLst,varLst));
1466 else
1467 algorithm
1468 ✗ print("check number of vars in relation to number of eqs in otherEqnVarTpl in the torn system\n");
1469 ✗ then
1470 fail();
1471 end matchcontinue;
1472 end othersInTearComp;
1473
1474 protected function updateMapping
1475 input Integer varIdx;
1476 input Integer sccIdx;
1477 input array<Integer> iMapping;
1478 output array<Integer> oMapping;
1479 algorithm
1480 ✗ oMapping := arrayUpdate(iMapping,varIdx,sccIdx);
1481 end updateMapping;
1482
1483 protected function updateMappingTuple
1484 input Integer varIdx;
1485 input Integer sccIdx;
1486 input Integer iEqSysIdx;
1487 input Integer iVarOffset; //a offset that should be added to the varIdx
1488 input array<tuple<Integer,Integer,Integer>> iMapping;
1489 output array<tuple<Integer,Integer,Integer>> oMapping;
1490 algorithm
1491 1336 oMapping := arrayUpdate(iMapping,varIdx+iVarOffset,(sccIdx,iEqSysIdx,iVarOffset));
1492 end updateMappingTuple;
1493
1494
1495 //--------------------------------------------------------
1496 // Functions to get the ODEsystem graph and adjacencyList
1497 //--------------------------------------------------------
1498
1499 public function getOdeSystem "author: Waurich TUD 2013-06
1500 Gets the graph and the adjacencyLst only for the ODEsystem. The der(states) and nodes that evaluate zerocrossings are
1501 the only branches of the task graph.
1502 Attention: This function will overwrite the values of graphIn and graphDataIn with new values. If you want to hold the
1503 values of graphIn and graphDataIn, you have to duplicate them first!"
1504 input TaskGraph graphIn;
1505 input TaskGraphMeta graphDataIn;
1506 input BackendDAE.BackendDAE systIn;
1507 output TaskGraph graphOdeOut;
1508 output TaskGraphMeta graphDataOdeOut;
1509 protected
1510 list<Integer> stateNodes, whenNodes, cutNodes, cutNodeChildren;
1511 array<tuple<Integer, Integer, Integer>> varCompMapping, eqCompMapping;
1512 array<list<Integer>> inComps;
1513 BackendDAE.EqSystems systs;
1514 TaskGraph graphTmp;
1515 algorithm
1516 8 TASKGRAPHMETA(varCompMapping=varCompMapping, eqCompMapping=eqCompMapping, inComps=inComps) := graphDataIn;
1517 8 BackendDAE.DAE(systs,_) := systIn;
1518 8 (stateNodes,_) := List.fold2(systs,getAllStateNodes,varCompMapping,inComps,({},0));
1519 8 whenNodes := getEventNodes(systIn,eqCompMapping);
1520 8 graphTmp := arrayCopy(graphIn);
1521 8 (graphOdeOut,cutNodes) := cutTaskGraph(graphTmp,stateNodes,whenNodes);
1522 8 cutNodeChildren := List.flatten(List.map1(listAppend(cutNodes,whenNodes),Array.getIndexFirst,graphIn)); // for computing new root-nodes when cutting out when-equations
1523 8 (_,cutNodeChildren,_) := List.intersection1OnTrue(cutNodeChildren,cutNodes,intEq);
1524 8 graphDataOdeOut := cutSystemData(graphDataIn,listAppend(cutNodes,{}),cutNodeChildren);
1525 end getOdeSystem;
1526
1527 protected function getAllStateNodes "author: Waurich TUD 2013-07
1528 Folding function for getOdeSystem to traverse the equationsystems in the BackendDAE."
1529 input BackendDAE.EqSystem systIn;
1530 input array<tuple<Integer, Integer, Integer>> varCompMapping;
1531 input array<list<Integer>> inComps;
1532 input tuple<list<Integer>,Integer> stateInfoIn;
1533 output tuple<list<Integer>,Integer> stateInfoOut;
1534 algorithm
1535 stateInfoOut := matchcontinue stateInfoIn
1536 local
1537 list<Integer> stateNodes, stateNodesIn, stateVars;
1538 Integer varOffset, varOffsetNew;
1539 BackendDAE.Variables orderedVars;
1540 list<BackendDAE.Var> varLst;
1541 case (stateNodesIn,varOffset)
1542 algorithm
1543 17 BackendDAE.EQSYSTEM(orderedVars=orderedVars) := systIn;
1544 17 varLst := BackendVariable.varList(orderedVars);
1545 17 stateVars := getStates(varLst,{},1);
1546 //print("stateVars: " + stringDelimitList(List.map(stateVars,intString),",") + " varOffset: " + intString(varOffset) + "\n");
1547 //print("varCompMapping: " + stringDelimitList(List.mapArray(varCompMapping, tuple3ToString),",") + "\n");
1548
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 7 times.
17 false := listEmpty(stateVars);
1549 7 stateVars := List.map1(stateVars,intAdd,varOffset);
1550 7 stateNodes := getArrayTuple31(stateVars,varCompMapping);
1551 //print("stateNodes: " + stringDelimitList(List.map(stateNodes,intString),",") + "\n");
1552 7 stateNodes := List.map3(stateNodes,getCompInComps,1,inComps,arrayCreate(arrayLength(inComps),0));
1553 7 stateNodes := listAppend(stateNodesIn,stateNodes);
1554 7 varOffsetNew := listLength(varLst)+varOffset;
1555 7 then
1556 ((stateNodes,varOffsetNew));
1557 case (stateNodesIn,varOffset)
1558 algorithm
1559 10 BackendDAE.EQSYSTEM(orderedVars=orderedVars) := systIn;
1560 10 varLst := BackendVariable.varList(orderedVars);
1561 10 stateVars := getStates(varLst,{},1);
1562
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 true := listEmpty(stateVars);
1563 10 varOffsetNew := listLength(varLst)+varOffset;
1564 10 then
1565 ((stateNodesIn,varOffsetNew));
1566 case (_,_)
1567 algorithm
1568 ✗ BackendDAE.EQSYSTEM(orderedVars=orderedVars) := systIn;
1569 ✗ varLst := BackendVariable.varList(orderedVars);
1570 ✗ stateVars := getStates(varLst,{},1);
1571 ✗ print("getAllStateNodes failed! StateVars-Count: " + intString(listLength(stateVars)) + "\n");
1572 ✗ then fail();
1573 end matchcontinue;
1574 end getAllStateNodes;
1575
1576 protected function getStates "author: Waurich TUD 2013-06
1577 Gets the stateVars from the list of vars."
1578 input list<BackendDAE.Var> inVarLst;
1579 input list<Integer> stateVarsIn;
1580 input Integer Idx;
1581 output list<Integer> stateVarsOut;
1582 algorithm
1583 stateVarsOut := matchcontinue inVarLst
1584 local
1585 BackendDAE.Var head;
1586 list<BackendDAE.Var> rest;
1587 list<Integer> stateVars;
1588 case head::rest
1589 algorithm
1590
2/2
✓ Branch 1 taken 133 times.
✓ Branch 2 taken 1895 times.
2028 false := BackendVariable.isStateVar(head);
1591 1895 stateVars := getStates(rest,stateVarsIn,Idx+1);
1592 then stateVars;
1593 case head::rest
1594 algorithm
1595
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 133 times.
133 true := BackendVariable.isStateVar(head);
1596 133 stateVars := getStates(rest,Idx::stateVarsIn,Idx+1);
1597 then stateVars;
1598 case {}
1599 then stateVarsIn;
1600 end matchcontinue;
1601 end getStates;
1602
1603 protected function cutTaskGraph "author: Waurich TUD 2013-06
1604 Cuts every branch of the taskGraph that leads not to exceptNode."
1605 input TaskGraph graphIn;
1606 input list<Integer> exceptNodes;// dont cut them and their predecessors
1607 input list<Integer> whenNodes;// these can be removed even if they are predecessors of the exceptNodes
1608 output TaskGraph graphOut;
1609 output list<Integer> cutNodesOut;
1610 algorithm
1611 (graphOut,cutNodesOut) := matchcontinue exceptNodes
1612 local
1613 Integer sizeDAE,sizeODE;
1614 TaskGraph graphT, graphODE;
1615 list<Integer> cutNodes,odeNodes;
1616 array<Integer> odeMap;
1617 case {-1}
1618 algorithm
1619 ✗ then (graphIn,{});
1620 case _
1621 algorithm
1622 // remove the algebraic branches
1623 sizeDAE := arrayLength(graphIn);
1624 8 graphT := AdjacencyMatrix.transposeAdjacencyMatrix(graphIn,sizeDAE);
1625 8 odeNodes := listAppend(exceptNodes,getAllSuccessors(exceptNodes,graphT));//the ODE-System
1626 8 (_,odeNodes,_) := List.intersection1OnTrue(odeNodes,whenNodes,intEq);
1627 8 (odeNodes,_,_) := List.intersection1OnTrue(List.intRange(sizeDAE),odeNodes,intEq);
1628
1629 8 odeNodes := List.sort(odeNodes,intGt);
1630 8 sizeODE := listLength(odeNodes);
1631 8 odeMap := arrayCreate(sizeDAE,-1);
1632 8 List.threadMap1_0(odeNodes,List.intRange(sizeODE),Array.updateIndexFirst,odeMap);
1633 8 graphODE := arrayCreate(sizeODE,{});
1634 8 (graphODE,cutNodes) := cutTaskGraph2(List.intRange(sizeDAE),graphODE,{},graphIn,odeMap);
1635 then (graphODE,cutNodes);
1636 else
1637 algorithm
1638 ✗ print("cutTaskGraph failed\n");
1639 ✗ then fail();
1640 end matchcontinue;
1641 end cutTaskGraph;
1642
1643 protected function cutTaskGraph2 "author: Waurich TUD 2013-04
1644 Uses a mapping between daeIdx and odeIdx (or for DAE-eqs -1) and builds up a new ode graph.
1645 The ode nodes are mapped to new indeces and the dae eqs are skipped."
1646 input list<Integer> daeNodes;
1647 input TaskGraph graphODE;
1648 input list<Integer> cutNodesIn;
1649 input TaskGraph graphDAE;
1650 input array<Integer> odeMap;
1651 output TaskGraph graphOut;
1652 output list<Integer> cutNodesOut;
1653 algorithm
1654 (graphOut,cutNodesOut) := matchcontinue daeNodes
1655 local
1656 Integer daeIdx,odeIdx;
1657 list<Integer> rest,row,cutNodes;
1658 case daeIdx::rest
1659 algorithm
1660 1531 odeIdx := arrayGet(odeMap,daeIdx);
1661
2/2
✓ Branch 0 taken 472 times.
✓ Branch 1 taken 1059 times.
1531 true := intGt(odeIdx,0); // this node is still in the ODE system
1662 1059 row := arrayGet(graphDAE,daeIdx);
1663 1059 row := List.map1(row,Array.getIndexFirst,odeMap);
1664 1059 row := List.filter1OnTrue(row,intGt,0);
1665 1059 arrayUpdate(graphODE,odeIdx,row);
1666 1059 (_,cutNodes) := cutTaskGraph2(rest,graphODE,cutNodesIn,graphDAE,odeMap);
1667 1059 then (graphODE,cutNodes);
1668 case daeIdx::rest
1669 algorithm
1670 472 odeIdx := arrayGet(odeMap,daeIdx);
1671
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 472 times.
472 true := intEq(odeIdx,-1); // this node ist not in the ODE system
1672 472 (_,cutNodes) := cutTaskGraph2(rest,graphODE,daeIdx::cutNodesIn,graphDAE,odeMap);
1673 472 then (graphODE,cutNodes);
1674 case {}
1675 then (graphODE,cutNodesIn);
1676 end matchcontinue;
1677 end cutTaskGraph2;
1678
1679 protected function cutSystemData "author: Waurich TUD 2013-07
1680 Updates the taskGraphMetaData regarding the removed nodes."
1681 input TaskGraphMeta graphDataIn;
1682 input list<Integer> cutNodes;
1683 input list<Integer> cutNodeChildren;
1684 output TaskGraphMeta graphDataOut;
1685 protected
1686 array<list<Integer>> inComps;
1687 array<tuple<Integer, Integer, Integer>> varCompMapping;
1688 array<tuple<Integer, Integer, Integer>> eqCompMapping;
1689 array<String> compNames;
1690 array<String> compDescs;
1691 array<tuple<Integer,Real>> exeCosts;
1692 array<Communications> commCosts;
1693 array<Integer> nodeMark;
1694 list<Integer> rangeLst;
1695 array<list<Integer>> compParamMapping;
1696 array<ComponentInfo> compInformations;
1697 algorithm
1698 8 TASKGRAPHMETA(inComps=inComps, varCompMapping=varCompMapping, eqCompMapping=eqCompMapping, compParamMapping=compParamMapping, compNames=compNames, compDescs=compDescs, exeCosts=exeCosts, commCosts=commCosts, nodeMark=nodeMark, compInformations=compInformations) := graphDataIn;
1699 8 inComps := listArray(List.deletePositions(arrayList(inComps),cutNodes));
1700 8 rangeLst := List.intRange(arrayLength(nodeMark));
1701 8 nodeMark := List.fold1(rangeLst, markRemovedNodes,cutNodes,nodeMark);
1702 8 graphDataOut :=TASKGRAPHMETA(inComps,varCompMapping,eqCompMapping,compParamMapping,compNames,compDescs,exeCosts,commCosts,nodeMark,compInformations);
1703 end cutSystemData;
1704
1705 protected function markRemovedNodes "author: Waurich TUD 2013-07
1706 Folding function to set the entries in nodeMark to -1 for a removed component."
1707 input Integer nodeMarkIdx;
1708 input list<Integer> removedNodes;
1709 input array<Integer> nodeMarkIn;
1710 output array<Integer> nodeMarkOut;
1711 algorithm
1712 nodeMarkOut := matchcontinue nodeMarkIn
1713 local
1714 array<Integer> nodeMarkTmp;
1715 case _
1716 algorithm
1717
1/2
✓ Branch 1 taken 1531 times.
✗ Branch 2 not taken.
1531 true := intEq(-2, arrayGet(nodeMarkIn,nodeMarkIdx));
1718 then nodeMarkIn;
1719 case _
1720 algorithm
1721
2/2
✓ Branch 1 taken 472 times.
✓ Branch 2 taken 1059 times.
1531 false := List.isMemberOnTrue(nodeMarkIdx,removedNodes,intEq);
1722 then
1723 nodeMarkIn;
1724 case _
1725 algorithm
1726
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 472 times.
472 true := List.isMemberOnTrue(nodeMarkIdx,removedNodes,intEq);
1727 472 nodeMarkTmp := Array.replaceAtWithFill(nodeMarkIdx,-1,999,nodeMarkIn);
1728 then
1729 nodeMarkTmp;
1730 end matchcontinue;
1731 end markRemovedNodes;
1732
1733 public function getCompInComps "author: Waurich TUD 2013-07
1734 Finds the node in the current task graph which contains that component(index from the original task graph).
1735 nodeMark is needed to check for deleted components."
1736 input Integer compIn;
1737 input Integer compIdx; // start idx for iteration
1738 input array<list<Integer>> inComps;
1739 input array<Integer> nodeMark;
1740 output Integer compOut;
1741 algorithm
1742 compOut := matchcontinue nodeMark
1743 local
1744 list<Integer> mergedComp;
1745 Integer compTmp;
1746 Integer nodeMarkEntry;
1747 case _
1748 algorithm
1749
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 73516 times.
73516 true := arrayLength(inComps) >= compIdx;
1750 73516 mergedComp := arrayGet(inComps,compIdx);
1751 //print("get comp for compIn "+intString(compIn)+" in the merged Comp "+ stringDelimitList(List.map(mergedComp,intString),",")+"\n");
1752
2/2
✓ Branch 1 taken 133 times.
✓ Branch 2 taken 73383 times.
73516 false := List.isMemberOnTrue(compIn,mergedComp,intEq);
1753 73383 compTmp := getCompInComps(compIn,compIdx+1,inComps,nodeMark);
1754 then
1755 compTmp;
1756 case _
1757 algorithm
1758
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 133 times.
133 true := arrayLength(inComps) >= compIdx;
1759 133 mergedComp := arrayGet(inComps,compIdx);
1760 //print("get comp for compIn "+intString(compIn)+" in the merged Comp "+ stringDelimitList(List.map(mergedComp,intString),",")+"\n");
1761
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 133 times.
133 true := List.isMemberOnTrue(compIn,mergedComp,intEq);
1762 then
1763 compIdx;
1764 case _
1765 algorithm
1766 ✗ nodeMarkEntry := arrayGet(nodeMark,compIn);
1767 ✗ true := intLt(nodeMarkEntry,0);
1768 then
1769 -1;
1770 else
1771 algorithm
1772 ✗ print("getCompInComps failed! CompIn idx: " + intString(compIn) + " | Component array-size: " + intString(arrayLength(inComps)) + "\n");
1773 ✗ then
1774 fail();
1775 end matchcontinue;
1776 end getCompInComps;
1777
1778 public function getAllSuccessors "author: Waurich TUD 2014-09
1779 Gets all successors including all childNodes of the childNodes..."
1780 input list<Integer> nodes;
1781 input TaskGraph graph;
1782 output list<Integer> successors;
1783 algorithm
1784 successors := matchcontinue graph
1785 local
1786 array<Boolean> alreadyVisited;
1787 list<Boolean> check;
1788 list<Integer> successors1;
1789 case _
1790 algorithm
1791 12 alreadyVisited := arrayCreate(arrayLength(graph),false);
1792 12 List.map2_0(nodes,Array.updateIndexFirst,true,alreadyVisited); // dont use the except nodes
1793 12 successors1 := List.flatten(List.map1(nodes,Array.getIndexFirst,graph));
1794 12 check := List.map1(successors1,Array.getIndexFirst,alreadyVisited); //check if it was already visited?
1795 12 (_,successors1) := List.filterOnTrueSync(check,boolNot,successors1);
1796 12 successors1 := List.unique(successors1);
1797 12 then getAllSuccessors2(successors1,graph,alreadyVisited,successors1);
1798 else
1799 algorithm
1800 ✗ print("getAllSuccessors failed!\n");
1801 ✗ then fail();
1802 end matchcontinue;
1803 end getAllSuccessors;
1804
1805 protected function getAllSuccessors2 "author: Waurich TUD 2014-09
1806 Gets all successors for the given nodes and repeats it for the successors until the end of the graph."
1807 input list<Integer> nodes;
1808 input TaskGraph graph;
1809 input array<Boolean> alreadyVisited;
1810 input list<Integer> successorsIn;
1811 output list<Integer> successorsOut;
1812 algorithm
1813 successorsOut := match nodes
1814 local
1815 list<Boolean> check;
1816 list<Integer> successors1;
1817 case {}
1818 12 then List.unique(successorsIn);
1819 case _
1820 algorithm
1821 41 successors1 := List.flatten(List.map1(nodes,Array.getIndexFirst,graph));
1822 41 check := List.map1(successors1,Array.getIndexFirst,alreadyVisited); //check if it was already visited?
1823 41 (_,successors1) := List.filterOnTrueSync(check,boolNot,successors1);
1824 41 successors1 := List.unique(successors1);
1825 //print("successors1: "+intLstString(successors1)+"\n");
1826 41 List.map2_0(successors1,Array.updateIndexFirst,true,alreadyVisited);
1827 41 then getAllSuccessors2(successors1,graph,alreadyVisited,listAppend(successors1,successorsIn));
1828 end match;
1829 end getAllSuccessors2;
1830
1831 protected function getChildNodes "author: waurich TUD 2013-06
1832 Gets the successor nodes for a list of parent nodes."
1833 input array<list<Integer>> adjacencyLstIn;
1834 input list<Integer> parents;
1835 input list<Integer> childLstTmp;
1836 input Integer Idx;
1837 output list<Integer> childLsts;
1838 algorithm
1839 childLsts := matchcontinue Idx
1840 local
1841 Integer parent;
1842 list<Integer> row;
1843 list<Integer> childLst;
1844 case _
1845 algorithm
1846 ✗ true := listLength(parents) >= Idx;
1847 ✗ parent := listGet(parents,Idx);
1848 ✗ row := arrayGet(adjacencyLstIn,parent);
1849 ✗ childLst := listAppend(childLstTmp,row);
1850 ✗ childLst := getChildNodes(adjacencyLstIn,parents,childLst,Idx+1);
1851 then
1852 childLst;
1853 else childLstTmp;
1854 end matchcontinue;
1855 end getChildNodes;
1856
1857 public function updateContinuousEntriesInList "author: Waurich TUD 2013-07
1858 Updates the entries in a list.
1859 The entries in the list belong to a continuous series.
1860 The deleteEntries have been previously removed from the array and the indices are adapted so that the new array consists
1861 again of continuous series of numbers. Therefore the indices have to be smallen
1862 e.g. updateContinuousEntriesInList({4,2,1,7,9},{3,6}) = {3,2,1,5,7};
1863 !! only for positive entries."
1864 input list<Integer> lstIn;
1865 input list<Integer> deleteEntriesIn;
1866 output list<Integer> lstOut;
1867 algorithm
1868 lstOut := match(lstIn,deleteEntriesIn)
1869 local
1870 Integer start;
1871 list<Integer> rest, lstTmp;
1872 array<Integer> deleteArr;
1873 case({},_)
1874 then {};
1875 case(_,{})
1876 then lstIn;
1877 case(start::rest,_)
1878 algorithm
1879 909 deleteArr := arrayCreate(List.fold(listAppend(rest,deleteEntriesIn),intMax,start),0);
1880 909 List.map2_0(deleteEntriesIn,Array.updateIndexFirst,1,deleteArr);
1881 909 (deleteArr,_) := Array.mapFold(deleteArr,setDeleteArr,0);
1882 909 lstTmp := List.map1(lstIn,removeContinuousEntries1,deleteArr);
1883 then lstTmp;
1884 end match;
1885 end updateContinuousEntriesInList;
1886
1887 protected function setDeleteArr
1888 input Integer entryIn;
1889 input Integer offsetIn;
1890 output Integer entryOut;
1891 output Integer offsetOut;
1892 algorithm
1893 (entryOut,offsetOut) := match entryIn
1894 case 0
1895 then (offsetIn,offsetIn);
1896 case 1
1897 335696 then (offsetIn+1,offsetIn+1);
1898 end match;
1899 end setDeleteArr;
1900
1901 protected function removeContinuousEntries1 "author: Waurich TUD 2013-07
1902 Map function for removeContinuousEntries to update the indices."
1903 input Integer entryIn;
1904 input array<Integer> deleteEntriesIn;
1905 output Integer entryOut;
1906 algorithm
1907 entryOut := matchcontinue deleteEntriesIn
1908 local
1909 Integer offset;
1910 case _
1911 algorithm
1912 2739 offset := arrayGet(deleteEntriesIn,entryIn);
1913 2739 then entryIn-offset;
1914 else
1915 algorithm
1916 ✗ print("removeContinuousEntries1 failed!\n");
1917 then entryIn;
1918 end matchcontinue;
1919 end removeContinuousEntries1;
1920
1921 protected function deleteRowInAdjLst "author: waurich TUD 2013-06
1922 Deletes rows indexed by the rowDel from the adjacencyLst."
1923 input array<list<Integer>> adjacencyLstIn;
1924 input list<Integer> rowsDel;
1925 output array<list<Integer>> adjacencyLstOut;
1926 output list<Integer> odeMapping;
1927 protected
1928 array<list<Integer>> adjLst;
1929 list<Integer> copiedRows;
1930 Integer size;
1931 algorithm
1932 ✗ size := arrayLength(adjacencyLstIn)-listLength(rowsDel);
1933 ✗ adjLst := arrayCreate(size,{});
1934 ✗ copiedRows := List.intRange(arrayLength(adjacencyLstIn));
1935 ✗ copiedRows := List.deletePositions(copiedRows,rowsDel);
1936 ✗ adjacencyLstOut := arrayCopyRows(adjacencyLstIn,adjLst,copiedRows,1);
1937 odeMapping := copiedRows;
1938 end deleteRowInAdjLst;
1939
1940 protected function arrayCopyRows "
1941 Copies entries given by copiedRows from inArray to newArray"
1942 input array<list<Integer>> inArray;
1943 input array<list<Integer>> newArray;
1944 input list<Integer> copiedRows;
1945 input Integer Idx;
1946 output array<list<Integer>> outArray;
1947 algorithm
1948 outArray := matchcontinue Idx
1949 local
1950 Integer copyRow;
1951 list<Integer> row;
1952 array<list<Integer>> arrayTmp;
1953 case _
1954 algorithm
1955 ✗ true := listLength(copiedRows) >= Idx;
1956 ✗ copyRow := listGet(copiedRows,Idx);
1957 ✗ row := arrayGet(inArray,copyRow);
1958 ✗ arrayTmp := Array.replaceAtWithFill(Idx, row, {111,222}, newArray);
1959 ✗ arrayTmp := arrayCopyRows(inArray,arrayTmp,copiedRows,Idx+1);
1960 then
1961 arrayTmp;
1962 else
1963 algorithm
1964 then
1965 newArray;
1966 end matchcontinue;
1967 end arrayCopyRows;
1968
1969 public function getRootNodes "author: marcusw, waurich
1970 Get all root nodes of the graph."
1971 input TaskGraph iTaskGraph; //the original graph
1972 output list<Integer> rootsOut;
1973 protected
1974 Integer size;
1975 TaskGraph taskGraphT;
1976 algorithm
1977 size := arrayLength(iTaskGraph);
1978 37 taskGraphT := AdjacencyMatrix.transposeAdjacencyMatrix(iTaskGraph,size);
1979 37 rootsOut := getLeafNodes(taskGraphT); // gets the leaf nodes of the transposed graph
1980 end getRootNodes;
1981
1982 public function getLeafNodes "author: marcusw
1983 Get all leaf-nodes of the given graph."
1984 input TaskGraph iTaskGraph;
1985 output list<Integer> oLeafNodes;
1986 protected
1987 list<Integer> tmpLeafNodes, nodeSuccessors;
1988 Integer nodeIdx;
1989 algorithm
1990 tmpLeafNodes := {};
1991
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 4 times.
4557 for nodeIdx in 1:arrayLength(iTaskGraph) loop
1992 4517 nodeSuccessors := arrayGet(iTaskGraph, nodeIdx);
1993
2/2
✓ Branch 0 taken 1229 times.
✓ Branch 1 taken 3288 times.
4517 if(listEmpty(nodeSuccessors)) then
1994 tmpLeafNodes := nodeIdx::tmpLeafNodes;
1995 end if;
1996 end for;
1997 oLeafNodes := tmpLeafNodes;
1998 end getLeafNodes;
1999
2000 public function getLevelNodes "author: marcusw
2001 Get all nodes that belong to the levels."
2002 input TaskGraph iTaskGraph;
2003 output list<list<Integer>> oLevelNodes; //list of nodes for each level
2004 protected
2005 array<Integer> refCounter;
2006 list<Integer> roots;
2007 algorithm
2008 6 refCounter := createRefCounter(iTaskGraph);
2009 6 roots := getNodesWithRefCountZero(refCounter);
2010 6 oLevelNodes := getLevelNodes0(iTaskGraph, refCounter, roots, {});
2011 end getLevelNodes;
2012
2013 protected function getLevelNodes0 "author: marcusw
2014 Adds all nodes in list iNodesWithRefZero as a new level to the result list. After that, the reference counter
2015 of all child nodes is decremented and the function is invoked again with the new referenceCount=0 nodes."
2016 input TaskGraph iTaskGraph;
2017 input array<Integer> iRefCounter;
2018 input list<Integer> iNodesWithRefZero;
2019 input list<list<Integer>> iLevelNodes; //list of nodes for each level
2020 output list<list<Integer>> oLevelNodes;
2021 protected
2022 list<list<Integer>> tmpLevelNodes;
2023 list<Integer> zeroRefNodes;
2024 algorithm
2025 oLevelNodes := match iNodesWithRefZero
2026 case {}
2027 algorithm //no nodes with refCount = 0 -> all nodes handled
2028 6 tmpLevelNodes := listReverse(iLevelNodes);
2029 then tmpLevelNodes;
2030 case zeroRefNodes
2031 algorithm
2032 //append all nodes with refCount = zero as new level
2033 tmpLevelNodes := zeroRefNodes :: iLevelNodes;
2034 13 zeroRefNodes := List.fold2(zeroRefNodes, getLevelNodes1, iTaskGraph, iRefCounter, {});
2035 13 tmpLevelNodes := getLevelNodes0(iTaskGraph, iRefCounter, zeroRefNodes, tmpLevelNodes);
2036 then tmpLevelNodes;
2037 end match;
2038 end getLevelNodes0;
2039
2040 protected function getLevelNodes1 "author: marcusw
2041 Decrements the reference counter of all child nodes of the node (iNodeIdx).
2042 If the child node has a reference counter of zero after decrementation, the child is added to the result list."
2043 input Integer iNodeIdx;
2044 input TaskGraph iTaskGraph;
2045 input array<Integer> iRefCounter; //updated through the arrayUpdate-command
2046 input list<Integer> iNodesWithRefZero;
2047 output list<Integer> oNodesWithRefZero;
2048 protected
2049 list<Integer> childNodes, tmpNodesWithRefZero;
2050 algorithm
2051 120 childNodes := arrayGet(iTaskGraph, iNodeIdx);
2052 120 tmpNodesWithRefZero := List.fold1(childNodes, getLevelNodes2, iRefCounter, {});
2053 120 oNodesWithRefZero := listAppend(tmpNodesWithRefZero, iNodesWithRefZero);
2054 end getLevelNodes1;
2055
2056 protected function getLevelNodes2 "author: marcusw
2057 Decrement the reference counter of node (iNodeIdx) and add it to the result-list if the reference-counter is zero."
2058 input Integer iNodeIdx;
2059 input array<Integer> iRefCounter; //updated through the arrayUpdate-command
2060 input list<Integer> iNodesWithRefZero;
2061 output list<Integer> oNodesWithRefZero;
2062 protected
2063 list<Integer> tmpNodesWithRefZero;
2064 Integer refCounter;
2065 algorithm
2066 oNodesWithRefZero := matchcontinue iNodesWithRefZero
2067 case tmpNodesWithRefZero
2068 algorithm
2069 99 refCounter := arrayGet(iRefCounter, iNodeIdx) - 1;
2070 99 arrayUpdate(iRefCounter, iNodeIdx, refCounter);
2071
2/2
✓ Branch 0 taken 31 times.
✓ Branch 1 taken 68 times.
99 true := intEq(refCounter, 0);
2072 tmpNodesWithRefZero := iNodeIdx::tmpNodesWithRefZero;
2073 then tmpNodesWithRefZero;
2074 else iNodesWithRefZero;
2075 end matchcontinue;
2076 end getLevelNodes2;
2077
2078 protected function createRefCounter "author: marcusw
2079 Setup a reference counter (number of incoming edges) for each node (array-index)."
2080 input TaskGraph iTaskGraph;
2081 output array<Integer> oRefCounter;
2082 protected
2083 array<Integer> tmpRefCounter;
2084 algorithm
2085 6 tmpRefCounter := arrayCreate(arrayLength(iTaskGraph), 0);
2086 6 tmpRefCounter := Array.fold(iTaskGraph, createRefCounter0, tmpRefCounter);
2087 oRefCounter := tmpRefCounter;
2088 end createRefCounter;
2089
2090 protected function createRefCounter0 "author: marcusw
2091 Increment the ref-counter of all child tasks of the given node."
2092 input list<Integer> iChildNodes;
2093 input array<Integer> iRefCounter;
2094 output array<Integer> oRefCounter;
2095 protected
2096 array<Integer> tmpRefCounter;
2097 Integer counter, head;
2098 list<Integer> tail;
2099 algorithm
2100 oRefCounter := match iChildNodes
2101 case {} then iRefCounter;
2102 case head::tail
2103 algorithm
2104 99 counter := arrayGet(iRefCounter,head) + 1;
2105 99 tmpRefCounter := arrayUpdate(iRefCounter,head,counter);
2106 99 tmpRefCounter := createRefCounter0(tail,tmpRefCounter);
2107 then tmpRefCounter;
2108 end match;
2109 end createRefCounter0;
2110
2111 protected function getNodesWithRefCountZero "author: marcusw
2112 Return the nodes of the ref-counter-array that have a reference-count of zero."
2113 input array<Integer> iRefCounter;
2114 output list<Integer> oZeroIdc; //list of all indices with reference counter == zero
2115 algorithm
2116 6 (oZeroIdc,_) := Array.fold(iRefCounter, getNodesWithRefCountZero0, ({},1));
2117 end getNodesWithRefCountZero;
2118
2119 protected function getNodesWithRefCountZero0 "author: marcusw
2120 Add the currentNodeIdx to the result-list if the iRefCount-value is zero."
2121 input Integer iRefCount;
2122 input tuple<list<Integer>,Integer> iZeroIdc; //<resultList, currentNodeIdx>
2123 output tuple<list<Integer>,Integer> oZeroIdc;
2124 protected
2125 list<Integer> resultList;
2126 Integer currentNodeIdx;
2127 algorithm
2128 oZeroIdc := match(iRefCount, iZeroIdc)
2129 case(0,(resultList,currentNodeIdx))
2130 algorithm
2131 resultList := currentNodeIdx :: resultList;
2132 52 then ((resultList, currentNodeIdx+1));
2133 case(_,(resultList,currentNodeIdx))
2134 68 then ((resultList, currentNodeIdx+1));
2135 end match;
2136 end getNodesWithRefCountZero0;
2137
2138
2139 //----------------------------------
2140 // Functions to get the event-graph
2141 //----------------------------------
2142
2143 public function getZeroFuncsSystem "author: marcusw
2144 Gets the graph containing all zero funcs. This graph is important for event handling. This function does not
2145 support nodes with more than one inComp!"
2146 input TaskGraph iTaskGraph;
2147 input TaskGraphMeta iTaskGraphMeta;
2148 input BackendDAE.BackendDAE iBackendDAE;
2149 input Integer iNumberOfSccs;
2150 input list<Integer> iZeroCrossingEquationIdc;
2151 input array<Integer> iSimCodeEqCompMapping;
2152 output TaskGraph oTaskGraph;
2153 output TaskGraphMeta oTaskGraphMeta;
2154 protected
2155 list<Integer> nodeList, newNodeList, predecessors, successors, successorsTmp, predecessorsTmp;
2156 array<Integer> zeroFuncNodeMarks; //value < 0 : All successors are not part of the zero funcs system ; value > 0 : Node is part of zero funcs system
2157 array<Integer> sccNodeMapping;
2158 array<Boolean> handledNodes, whenNodeMarks;
2159 TaskGraph iTaskGraphTCopy, iTaskGraphCopy;
2160 TaskGraph zeroFuncTaskGraph;
2161 TaskGraphMeta zeroFuncTaskGraphMeta;
2162 list<Integer> whenNodes;
2163 array<list<Integer>> zeroFuncInComps, inComps;
2164 array<tuple<Integer, Integer, Integer>> eqCompMapping;
2165 Integer eqIdx, compIdx, nodeIdx, successor, predecessor, zeroFuncNodeMark, successorMark, zeroFuncNodeCount, zeroFuncNodeIdx;
2166 array<Integer> nodeToZeroFuncNodeMapping; //mapping for each task graph node idx to zero func graph node idx
2167 Boolean stop;
2168 algorithm
2169 //print("Zero crossing equations: " + stringDelimitList(List.map(iZeroCrossingEquationIdc, intString), ",") + "\n");
2170
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 TASKGRAPHMETA(inComps=inComps, eqCompMapping=eqCompMapping) := iTaskGraphMeta;
2171 8 zeroFuncNodeMarks := arrayCreate(arrayLength(iTaskGraph), 0);
2172 8 handledNodes := arrayCreate(arrayLength(iTaskGraph), false);
2173 8 nodeToZeroFuncNodeMapping := arrayCreate(arrayLength(iTaskGraph), -1);
2174 8 whenNodes := getEventNodes(iBackendDAE,eqCompMapping);
2175 //print("Got when nodes " + stringDelimitList(List.map(whenNodes, intString), ",") + "\n");
2176 8 whenNodeMarks := arrayCreate(arrayLength(iTaskGraph), false);
2177 8 sccNodeMapping := getSccNodeMapping(iNumberOfSccs, iTaskGraphMeta);
2178 8 iTaskGraphCopy := arrayCopy(iTaskGraph);
2179 8 iTaskGraphTCopy := AdjacencyMatrix.transposeAdjacencyMatrix(iTaskGraph,arrayLength(iTaskGraph));
2180
2181 //Mark all nodes that are part of the zero funcs system
2182
2/2
✓ Branch 0 taken 89 times.
✓ Branch 1 taken 8 times.
97 for eqIdx in iZeroCrossingEquationIdc loop
2183 89 compIdx := arrayGet(iSimCodeEqCompMapping, eqIdx);
2184 89 nodeIdx := arrayGet(sccNodeMapping, compIdx);
2185 89 zeroFuncNodeMarks := arrayUpdate(zeroFuncNodeMarks, nodeIdx, 1);
2186 //print("Setting node mark of node " + intString(nodeIdx) + " to 1\n");
2187 end for;
2188
2189 //Mark all nodes that contains when equations
2190
2/2
✓ Branch 1 taken 27 times.
✓ Branch 2 taken 8 times.
35 for nodeIdx in whenNodes loop
2191 27 whenNodeMarks := arrayUpdate(whenNodeMarks, nodeIdx, true);
2192 end for;
2193
2194 //Traverse graph, start with leaf nodes - mark all nodes that have no successor which belongs to the zero funcs system
2195 8 nodeList := getRootNodes(iTaskGraphTCopy);
2196 zeroFuncNodeCount := 0;
2197 zeroFuncNodeIdx := 1;
2198
2/2
✓ Branch 0 taken 46 times.
✓ Branch 1 taken 8 times.
54 while boolNot(listEmpty(nodeList)) loop
2199 newNodeList := {};
2200
2/2
✓ Branch 0 taken 2906 times.
✓ Branch 1 taken 46 times.
2952 for nodeIdx in nodeList loop //breath first search
2201 //print("Handling node " + intString(nodeIdx) + "\n");
2202
2/2
✓ Branch 1 taken 1543 times.
✓ Branch 2 taken 1363 times.
2906 if(boolNot(arrayGet(handledNodes, nodeIdx))) then //check if we have already handled the node
2203 //print("\tNode was not already handled\n");
2204 1543 handledNodes := arrayUpdate(handledNodes, nodeIdx, true);
2205 1543 predecessors := arrayGet(iTaskGraphTCopy, nodeIdx);
2206 //print("\tPredecessors: " + stringDelimitList(List.map(predecessors, intString), ",") + "\n");
2207 1543 successors := arrayGet(iTaskGraphCopy, nodeIdx);
2208 //print("\tSuccessors: " + stringDelimitList(List.map(successors, intString), ",") + "\n");
2209 zeroFuncNodeMark := -1;
2210
2211
2/2
✓ Branch 1 taken 27 times.
✓ Branch 2 taken 1516 times.
1543 if(arrayGet(whenNodeMarks, nodeIdx)) then //Check if node contains when equation -> remove if true
2212
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 27 times.
56 for predecessor in predecessors loop
2213 29 successorsTmp := arrayGet(iTaskGraphCopy, predecessor);
2214 29 arrayUpdate(iTaskGraphCopy, predecessor, listAppend(successorsTmp, successors));
2215 end for;
2216
2/2
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 27 times.
53 for successor in successors loop
2217 26 predecessorsTmp := arrayGet(iTaskGraphTCopy, successor);
2218 26 arrayUpdate(iTaskGraphTCopy, successor, listAppend(predecessorsTmp, predecessors));
2219 end for;
2220 else
2221
2/2
✓ Branch 1 taken 1427 times.
✓ Branch 2 taken 89 times.
1516 if(intGt(arrayGet(zeroFuncNodeMarks, nodeIdx), 0)) then
2222 zeroFuncNodeMark := zeroFuncNodeIdx;
2223 else
2224 stop := false;
2225
3/4
✓ Branch 0 taken 3683 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2256 times.
✓ Branch 3 taken 1427 times.
3683 while(boolAnd(boolNot(stop), boolNot(listEmpty(successors)))) loop
2226 //print("\tSuccessor list not empty\n");
2227 2256 successor::successors := successors;
2228 2256 successorMark := arrayGet(zeroFuncNodeMarks, successor);
2229
1/2
✓ Branch 0 taken 2256 times.
✗ Branch 1 not taken.
2256 if(intGt(successorMark, 0)) then
2230 zeroFuncNodeMark := zeroFuncNodeIdx;
2231 stop := true;
2232 end if;
2233 end while;
2234 end if;
2235
2236
2/2
✓ Branch 0 taken 89 times.
✓ Branch 1 taken 1427 times.
1516 if(intGt(zeroFuncNodeMark, 0)) then
2237 89 zeroFuncNodeCount := zeroFuncNodeCount + 1;
2238 89 nodeToZeroFuncNodeMapping := arrayUpdate(nodeToZeroFuncNodeMapping, nodeIdx, zeroFuncNodeCount);
2239 89 zeroFuncNodeIdx := zeroFuncNodeIdx + 1;
2240 end if;
2241 //print("\tSetting node mark to " + intString(zeroFuncNodeMark) + "\n");
2242 end if;
2243 1543 zeroFuncNodeMarks := arrayUpdate(zeroFuncNodeMarks, nodeIdx, zeroFuncNodeMark);
2244 1543 newNodeList := List.append_reverse(predecessors, newNodeList); //add all nodes of previous level
2245 end if;
2246 end for;
2247 46 nodeList := listReverse(newNodeList);
2248 end while;
2249
2250 //Setup a new graph that contains only nodes which are part of the event system
2251 8 zeroFuncTaskGraph := arrayCreate(zeroFuncNodeCount, {});
2252 8 zeroFuncInComps := arrayCreate(zeroFuncNodeCount, {});
2253
2254 //Setup the adjacence list for the new graph
2255 nodeIdx := arrayLength(zeroFuncNodeMarks);
2256
2/2
✓ Branch 0 taken 1543 times.
✓ Branch 1 taken 8 times.
1551 while (intGt(nodeIdx, 0)) loop
2257 1543 zeroFuncNodeIdx := arrayGet(zeroFuncNodeMarks, nodeIdx);
2258
2/2
✓ Branch 0 taken 89 times.
✓ Branch 1 taken 1454 times.
1543 if(intGt(zeroFuncNodeIdx, 0)) then //node is part of zero func system
2259 89 successors := arrayGet(iTaskGraphCopy, nodeIdx);
2260 //print("Node " + intString(nodeIdx) + " is part of zero func system\n");
2261 //print("Components are: " + stringDelimitList(List.map(arrayGet(inComps, nodeIdx), intString), ",") + "\n");
2262 89 zeroFuncInComps := arrayUpdate(zeroFuncInComps, zeroFuncNodeIdx, arrayGet(inComps, nodeIdx));
2263 newNodeList := {};
2264
2/2
✓ Branch 0 taken 168 times.
✓ Branch 1 taken 89 times.
257 while(boolNot(listEmpty(successors))) loop
2265 168 successor::successors := successors;
2266 168 successor := arrayGet(zeroFuncNodeMarks, successor);
2267
2/2
✓ Branch 0 taken 88 times.
✓ Branch 1 taken 80 times.
168 if(intGt(successor, 0)) then //successor is part of zero func system
2268 newNodeList := successor::newNodeList;
2269 end if;
2270 end while;
2271 89 newNodeList := List.sort(newNodeList, intGt);
2272 89 newNodeList := List.sortedUnique(newNodeList, intEq);
2273 89 zeroFuncTaskGraph := arrayUpdate(zeroFuncTaskGraph, zeroFuncNodeIdx, newNodeList);
2274 end if;
2275 1543 nodeIdx := nodeIdx - 1;
2276 end while;
2277
2278 8 zeroFuncTaskGraphMeta := copyTaskGraphMeta(iTaskGraphMeta);
2279 8 zeroFuncTaskGraphMeta := setInCompsInMeta(zeroFuncInComps, zeroFuncTaskGraphMeta);
2280
2281 //reverse indexes
2282 8 (oTaskGraph,oTaskGraphMeta) := reverseTaskGraphIndices(zeroFuncTaskGraph,zeroFuncTaskGraphMeta);
2283 end getZeroFuncsSystem;
2284
2285 protected function reverseTaskGraphIndices "author Waurich TUD 07-2015
2286 Reverse the task ids in the task grah and accordingly in the inComps."
2287 input TaskGraph iTaskGraph;
2288 input TaskGraphMeta iTaskGraphMeta;
2289 output TaskGraph oTaskGraph;
2290 output TaskGraphMeta oTaskGraphMeta;
2291 protected
2292 Integer nTasks;
2293 array<Integer> idxMap;
2294
2295 array<list<Integer>> inComps;
2296 array<tuple<Integer, Integer, Integer>> varCompMapping;
2297 array<tuple<Integer,Integer,Integer>> eqCompMapping;
2298 array<list<Integer>> compParamMapping;
2299 array<String> compNames;
2300 array<String> compDescs;
2301 array<tuple<Integer,Real>> exeCosts;
2302 array<Communications> commCosts;
2303 array<Integer>nodeMark;
2304 array<ComponentInfo> compInformations;
2305 algorithm
2306 nTasks := arrayLength(iTaskGraph);
2307 8 idxMap := arrayCreate(nTasks,-1);
2308 8 TASKGRAPHMETA(inComps=inComps, varCompMapping=varCompMapping, eqCompMapping=eqCompMapping, compParamMapping=compParamMapping, compNames=compNames, compDescs=compDescs, exeCosts=exeCosts, commCosts=commCosts, nodeMark=nodeMark, compInformations=compInformations) := iTaskGraphMeta;
2309 // set an index mapping
2310
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
97 for i in 1:nTasks loop
2311 89 idxMap := arrayUpdate(idxMap,i,nTasks-i+1);
2312 end for;
2313 //map childNodes in taskgraph
2314 8 oTaskGraph := Array.mapNoCopy_1(iTaskGraph,mapIntegers,idxMap);
2315 8 oTaskGraph := Array.reverse(oTaskGraph);
2316 8 inComps := Array.reverse(inComps);
2317 8 oTaskGraphMeta := TASKGRAPHMETA(inComps, varCompMapping, eqCompMapping, compParamMapping, compNames, compDescs, exeCosts, commCosts, nodeMark, compInformations);
2318 end reverseTaskGraphIndices;
2319
2320 protected function mapIntegers "author Waurich TUD 07-2015
2321 Array.mapNoCopy_1 - function to replace integers with their mapping integer."
2322 input tuple<list<Integer>,array<Integer>> iTpl;
2323 output tuple<list<Integer>,array<Integer>> oTpl;
2324 protected
2325 array<Integer> map;
2326 list<Integer> iLst,oLst={};
2327 algorithm
2328 89 (iLst,map) := iTpl;
2329
2/2
✓ Branch 0 taken 79 times.
✓ Branch 1 taken 89 times.
168 for i in iLst loop
2330 79 oLst := arrayGet(map,i)::oLst;
2331 end for;
2332 89 oLst := listReverse(oLst);
2333 89 oTpl := (oLst,map);
2334 end mapIntegers;
2335
2336 protected function getEventSystem "author: marcusw
2337 Gets the graph and the adjacencyLst only for the EventSystem. This means that all branches which leads to a node solving
2338 a whencondition or another boolean condition will remain."
2339 input TaskGraph iTaskGraph;
2340 input TaskGraphMeta iTaskGraphMeta;
2341 input BackendDAE.BackendDAE iSyst;
2342 input list<BackendDAE.ZeroCrossing> iZeroCrossings;
2343 input array<Integer> iSimCodeEqCompMapping;
2344 output TaskGraph oTaskGraph;
2345 output TaskGraphMeta oTaskGraphMeta;
2346 protected
2347 array<tuple<Integer, Integer, Integer>> varCompMapping, eqCompMapping;
2348 array<list<Integer>> inComps;
2349 list<Integer> discreteNodes, cutNodes, cutNodeChildren, zeroCrossingNodes;
2350 list<Integer> sccsContainingTime;
2351 BackendDAE.EqSystems systs;
2352 BackendDAE.Shared shared;
2353 TaskGraph graphTmp;
2354 algorithm
2355 ✗ TASKGRAPHMETA(varCompMapping=varCompMapping, eqCompMapping=eqCompMapping, inComps=inComps) := iTaskGraphMeta;
2356 BackendDAE.DAE(systs,shared) := iSyst;
2357 ✗ discreteNodes := getDiscreteNodes(iSyst,eqCompMapping);
2358 ✗ zeroCrossingNodes := List.flatten(List.map1(iZeroCrossings, getComponentsOfZeroCrossing, iSimCodeEqCompMapping));
2359 //((_,sccsContainingTime)) := List.fold1(systs, getComponentsIncludingTime, eqCompMapping, (0,{}));
2360 sccsContainingTime := {};
2361 //print("Nodes containing time as variable: " + stringDelimitList(List.map(sccsContainingTime, intString), ",") + " (len: " + intString(listLength(sccsContainingTime)) + ")\n");
2362 ✗ discreteNodes := List.flatten({discreteNodes, sccsContainingTime, zeroCrossingNodes});
2363 //print("Discrete nodes: " + stringDelimitList(List.map(discreteNodes, intString), ",") + " (len: " + intString(listLength(discreteNodes)) + ")\n");
2364 graphTmp := iTaskGraph; //arrayCopy(graphIn);
2365 ✗ (graphTmp,cutNodes) := cutTaskGraph(graphTmp,discreteNodes,{});
2366 ✗ cutNodeChildren := List.flatten(List.map1(cutNodes,Array.getIndexFirst,iTaskGraph)); // for computing new root-nodes when cutting out nodes
2367 ✗ (_,cutNodeChildren,_) := List.intersection1OnTrue(cutNodeChildren,cutNodes,intEq);
2368 ✗ oTaskGraphMeta := cutSystemData(iTaskGraphMeta,cutNodes,cutNodeChildren);
2369 oTaskGraph := graphTmp;
2370 end getEventSystem;
2371
2372 protected function getComponentsOfZeroCrossing "author: marcusw
2373 Get the scc-idc that use the given zero crossing."
2374 input BackendDAE.ZeroCrossing iZeroCrossing;
2375 input array<Integer> iSimCodeEqCompMapping;
2376 output list<Integer> oCompIdc;
2377 protected
2378 list<Integer> occurEquLst, tmpCompIdc;
2379 algorithm
2380 oCompIdc := matchcontinue iZeroCrossing
2381 case BackendDAE.ZERO_CROSSING(occurEquLst=occurEquLst)
2382 algorithm
2383 ✗ occurEquLst := List.filter1OnTrue(occurEquLst, intGt, 0);
2384 ✗ print("getComponentsOfZeroCrossing: simEqs: " + stringDelimitList(List.map(occurEquLst, intString), ",") + "\n");
2385 ✗ tmpCompIdc := List.map1(occurEquLst, Array.getIndexFirst, iSimCodeEqCompMapping);
2386 ✗ tmpCompIdc := List.filter1OnTrue(tmpCompIdc, intGt, 0);
2387 ✗ print("getComponentsOfZeroCrossing: components: " + stringDelimitList(List.map(tmpCompIdc, intString), ",") + "\n");
2388 then tmpCompIdc;
2389 else {};
2390 end matchcontinue;
2391 end getComponentsOfZeroCrossing;
2392
2393 protected function getComponentsIncludingTime "author: marcusw
2394 Get the scc-idc that have an equation containing 'time' as variable."
2395 input BackendDAE.EqSystem iSystem;
2396 input array<tuple<Integer,Integer,Integer>> iEqCompMapping;
2397 input tuple<Integer,list<Integer>> iOffsetResList; //<offset, resultList>
2398 output tuple<Integer,list<Integer>> oOffsetResList;
2399 protected
2400 BackendDAE.EquationArray orderedEqs;
2401 Integer offset;
2402 list<Integer> resultList;
2403 algorithm
2404 ✗ BackendDAE.EQSYSTEM(orderedEqs=orderedEqs) := iSystem;
2405 ✗ (offset, resultList) := iOffsetResList;
2406 ✗ (offset, resultList, _, _) := BackendEquation.traverseEquationArray(orderedEqs, getComponentsIncludingTime0, (offset, resultList, iEqCompMapping, 1));
2407 ✗ oOffsetResList := (offset, resultList);
2408 end getComponentsIncludingTime;
2409
2410 protected function getComponentsIncludingTime0 "author: marcusw
2411 Get the scc-idc that have an equation containing 'time' as variable."
2412 input BackendDAE.Equation inEq;
2413 input tuple<Integer, list<Integer>, array<tuple<Integer,Integer,Integer>>, Integer> iOffsetResList; //<equation, <offset, resultList, eqCompMapping, eqIdx>>
2414 output BackendDAE.Equation outEq;
2415 output tuple<Integer, list<Integer>, array<tuple<Integer,Integer,Integer>>, Integer> oOffsetResList;
2416 protected
2417 BackendDAE.Equation eq;
2418 Integer offset, eqIdx, sccIdx;
2419 list<Integer> resultList;
2420 array<tuple<Integer, Integer, Integer>> eqCompMapping;
2421 algorithm
2422 (outEq,oOffsetResList) := matchcontinue(inEq,iOffsetResList)
2423 case (eq, (offset,resultList,eqCompMapping,eqIdx))
2424 algorithm
2425 ✗ (sccIdx,_,_) := arrayGet(eqCompMapping, eqIdx+offset);
2426 //print("Component " + intString(sccIdx) + "\n");
2427 ✗ true := BackendDAEUtil.traverseBackendDAEExpsOptEqn(SOME(eq), getComponentsIncludingTime1, false);
2428 resultList := sccIdx::resultList;
2429 ✗ then (eq, (offset,resultList,eqCompMapping,eqIdx+1));
2430 case (eq, (offset,resultList,eqCompMapping,eqIdx))
2431 ✗ then (eq, (offset,resultList,eqCompMapping,eqIdx+1));
2432 end matchcontinue;
2433 end getComponentsIncludingTime0;
2434
2435 protected function getComponentsIncludingTime1
2436 input DAE.Exp inExp;
2437 input Boolean inB;
2438 output DAE.Exp e;
2439 output Boolean res;
2440 algorithm
2441 (e,res) := match (inExp,inB)
2442 case (e,false)
2443 algorithm
2444 ✗ res := Expression.traverseCrefsFromExp(e, getComponentsIncludingTime2, false);
2445 then (e,res);
2446 else (inExp,inB);
2447 end match;
2448 end getComponentsIncludingTime1;
2449
2450 protected function getComponentsIncludingTime2
2451 input DAE.ComponentRef iRef;
2452 input Boolean iIncludingTime;
2453 output Boolean oIncludingTime;
2454 algorithm
2455 oIncludingTime := match iRef
2456 case DAE.CREF_IDENT(ident="time")
2457 algorithm
2458 //BackendDump.debugCrefStr((iRef, "\n"));
2459 then true;
2460 else
2461 algorithm
2462 //BackendDump.debugCrefStr((iRef, "\n"));
2463 then (false or iIncludingTime);
2464 end match;
2465 end getComponentsIncludingTime2;
2466
2467 protected function getDiscreteNodes "author: marcusw
2468 Get the taskgraph nodes that solves discrete values."
2469 input BackendDAE.BackendDAE systIn;
2470 input array<tuple<Integer,Integer,Integer>> eqCompMapping;
2471 output list<Integer> eventNodes;
2472 protected
2473 list<Integer> eqLst;
2474 BackendDAE.EqSystems systemsIn;
2475 algorithm
2476 ✗ BackendDAE.DAE(eqs=systemsIn) := systIn;
2477 ✗ (eqLst,_) := List.fold(systemsIn, getDiscreteNodesEqs,({},0));
2478 ✗ eventNodes := getArrayTuple31(eqLst,eqCompMapping);
2479 end getDiscreteNodes;
2480
2481 protected function getDiscreteNodesEqs
2482 input BackendDAE.EqSystem systIn;
2483 input tuple<list<Integer>,Integer> eventInfoIn;
2484 output tuple<list<Integer>,Integer> eventInfoOut;
2485 protected
2486 BackendDAE.StrongComponents comps;
2487 BackendDAE.Variables orderedVars;
2488 BackendDAE.Matching matching;
2489 BackendDAE.EquationArray orderedEqs;
2490 list<Integer> eventEqs;
2491 list<Integer> eventEqsIn;
2492 Integer offset;
2493 algorithm
2494 ✗ BackendDAE.EQSYSTEM(orderedEqs=orderedEqs,orderedVars=orderedVars,matching=matching) := systIn;
2495 ✗ comps := BackendDAEUtil.getCompsOfMatching(matching);
2496 ✗ (eventEqsIn,offset) := eventInfoIn;
2497 ✗ eventEqs := getDiscreteNodesEqs1(comps,offset,orderedVars,{});
2498 ✗ offset := offset+ExpandableArray.getNumberOfElements(orderedEqs);
2499 ✗ eventInfoOut := (listAppend(eventEqs,eventEqsIn),offset);
2500 end getDiscreteNodesEqs;
2501
2502 protected function getDiscreteNodesEqs1
2503 input BackendDAE.StrongComponents comps;
2504 input Integer offset;
2505 input BackendDAE.Variables iOrderedVars;
2506 input list<Integer> discreteEqsIn;
2507 output list<Integer> discreteEqsOut;
2508 algorithm
2509 discreteEqsOut := matchcontinue comps
2510 local
2511 Integer eqn;
2512 list<Integer> eventEqs;
2513 BackendDAE.StrongComponents rest;
2514 BackendDAE.StrongComponent head;
2515 case head::rest
2516 algorithm
2517 ✗ (true,eqn) := solvesDiscreteValue(head, iOrderedVars);
2518 ✗ eqn := eqn+offset;
2519 ✗ eventEqs := getDiscreteNodesEqs1(rest,offset,iOrderedVars,eqn::discreteEqsIn);
2520 then
2521 eventEqs;
2522 case _::rest
2523 algorithm
2524 ✗ eventEqs := getDiscreteNodesEqs1(rest,offset,iOrderedVars,discreteEqsIn);
2525 then
2526 eventEqs;
2527 case {}
2528 then
2529 discreteEqsIn;
2530 end matchcontinue;
2531 end getDiscreteNodesEqs1;
2532
2533 protected function solvesDiscreteValue
2534 input BackendDAE.StrongComponent inComp;
2535 input BackendDAE.Variables iOrderedVars;
2536 output Boolean oSolvesDiscreteValue;
2537 output Integer oFirstEqIdx;
2538 algorithm
2539 (oSolvesDiscreteValue,oFirstEqIdx) := matchcontinue inComp
2540 local
2541 Integer eqn, var;
2542 list<Integer> vars, eqns;
2543 list<BackendDAE.Var> backendVars;
2544 BackendDAE.Var backendVar;
2545 Boolean solvesDiscreteValue;
2546 case BackendDAE.SINGLEEQUATION(var=var,eqn=eqn)
2547 algorithm
2548 //print("Var of single equation: " + intString(var) + "\n");
2549 ✗ backendVar := BackendVariable.getVarAt(iOrderedVars, var);
2550 ✗ solvesDiscreteValue := BackendVariable.isVarDiscrete(backendVar);
2551 then (solvesDiscreteValue,eqn);
2552 case BackendDAE.EQUATIONSYSTEM(vars=vars,eqns=eqns)
2553 algorithm
2554 //print("Vars of single equation system: " + stringDelimitList(List.map(vars, intString), ",") + "\n");
2555 ✗ backendVars := List.map1r(vars, BackendVariable.getVarAt, iOrderedVars);
2556 ✗ solvesDiscreteValue := BackendVariable.hasDiscreteVar(backendVars);
2557 ✗ eqn := listHead(eqns);
2558 then (solvesDiscreteValue,eqn);
2559 case BackendDAE.SINGLEARRAY(vars=vars,eqn=eqn)
2560 algorithm
2561 //print("Vars of single array: " + stringDelimitList(List.map(vars, intString), ",") + "\n");
2562 ✗ backendVars := List.map1r(vars, BackendVariable.getVarAt, iOrderedVars);
2563 ✗ solvesDiscreteValue := BackendVariable.hasDiscreteVar(backendVars);
2564 then (solvesDiscreteValue,eqn);
2565 case BackendDAE.SINGLEWHENEQUATION(vars=vars,eqn=eqn)
2566 algorithm
2567 //print("Vars of single when equation: " + stringDelimitList(List.map(vars, intString), ",") + "\n");
2568 ✗ backendVars := List.map1r(vars, BackendVariable.getVarAt, iOrderedVars);
2569 ✗ solvesDiscreteValue := BackendVariable.hasDiscreteVar(backendVars);
2570 then (solvesDiscreteValue,eqn);
2571 case BackendDAE.SINGLECOMPLEXEQUATION(vars=vars,eqn=eqn)
2572 algorithm
2573 //print("Vars of single complex equation: " + stringDelimitList(List.map(vars, intString), ",") + "\n");
2574 ✗ backendVars := List.map1r(vars, BackendVariable.getVarAt, iOrderedVars);
2575 ✗ solvesDiscreteValue := BackendVariable.hasDiscreteVar(backendVars);
2576 then (solvesDiscreteValue,eqn);
2577 case BackendDAE.SINGLEALGORITHM(vars=vars,eqn=eqn)
2578 algorithm
2579 //print("Vars of single algorithm: " + stringDelimitList(List.map(vars, intString), ",") + "\n");
2580 ✗ backendVars := List.map1r(vars, BackendVariable.getVarAt, iOrderedVars);
2581 ✗ solvesDiscreteValue := BackendVariable.hasDiscreteVar(backendVars);
2582 then (solvesDiscreteValue,eqn);
2583 case BackendDAE.SINGLEIFEQUATION(vars=vars,eqn=eqn)
2584 algorithm
2585 //print("Vars of single if equation: " + stringDelimitList(List.map(vars, intString), ",") + "\n");
2586 ✗ backendVars := List.map1r(vars, BackendVariable.getVarAt, iOrderedVars);
2587 ✗ solvesDiscreteValue := BackendVariable.hasDiscreteVar(backendVars);
2588 then (solvesDiscreteValue,eqn);
2589 else (false,-1);
2590 end matchcontinue;
2591 end solvesDiscreteValue;
2592
2593
2594 //------------------------------------------
2595 //Methods to write blt-structure as xml-file
2596 //------------------------------------------
2597 public uniontype GraphDumpOptions
2598 record GRAPHDUMPOPTIONS
2599 Boolean visualizeCriticalPath;
2600 Boolean visualizeTaskStartAndFinishTime;
2601 Boolean visualizeTaskCalcTime;
2602 Boolean visualizeCommTime;
2603 end GRAPHDUMPOPTIONS;
2604 end GraphDumpOptions;
2605
2606 public function dumpTaskGraph
2607 input BackendDAE.BackendDAE dae;
2608 input String fileName;
2609 protected
2610 String name;
2611 TaskGraph taskGraph;
2612 TaskGraphMeta taskGraphData;
2613 array<tuple<Integer,Integer,Real>> schedulerInfo;
2614 array<list<Integer>> sccSimEqMapping;
2615 algorithm
2616 ✗ (taskGraph,taskGraphData) := HpcOmTaskGraph.createTaskGraph(dae);
2617 ✗ name := ("TaskGraph_"+fileName+".graphml");
2618 ✗ schedulerInfo := arrayCreate(arrayLength(taskGraph), (-1,-1,-1.0));
2619 ✗ sccSimEqMapping := arrayCreate(arrayLength(taskGraph),{-1});
2620 ✗ dumpAsGraphMLSccLevel(taskGraph, taskGraphData, name, "", {}, {}, sccSimEqMapping, schedulerInfo, HpcOmTaskGraph.GRAPHDUMPOPTIONS(false,false,true,true));
2621 end dumpTaskGraph;
2622
2623 public function dumpAsGraphMLSccLevel "author: marcusw, waurich
2624 Write out the given graph as a graphml file."
2625 input TaskGraph iGraph;
2626 input TaskGraphMeta iGraphData;
2627 input String iFileName;
2628 input String iCriticalPathInfo; //Critical path as String
2629 input list<tuple<Integer,Integer>> iCriticalPath; //Critical path as list of edges
2630 input list<tuple<Integer,Integer>> iCriticalPathWoC; //Critical path without communciation as list of edges
2631 input array<list<Integer>> iSccSimEqMapping; //maps each scc to simEqSystems
2632 input array<tuple<Integer,Integer,Real>> iSchedulerInfo; //maps each Task to <threadId, orderId, startCalcTime>
2633 input GraphDumpOptions iGraphDumpOptions; //Options to specify the output
2634 protected
2635 GraphML.GraphInfo graphInfo;
2636 algorithm
2637 40 graphInfo := convertToGraphMLSccLevel(iGraph,iGraphData,iCriticalPathInfo,iCriticalPath,iCriticalPathWoC,iSccSimEqMapping,iSchedulerInfo,iGraphDumpOptions);
2638 40 GraphML.dumpGraph(graphInfo, iFileName);
2639 end dumpAsGraphMLSccLevel;
2640
2641 public function convertToGraphMLSccLevel "author: marcusw, waurich
2642 Convert the given graph into a graphml-structure."
2643 input TaskGraph iGraph;
2644 input TaskGraphMeta iGraphData;
2645 input String iCriticalPathInfo; //Critical path as String
2646 input list<tuple<Integer,Integer>> iCriticalPath; //Critical path as list of edges
2647 input list<tuple<Integer,Integer>> iCriticalPathWoC; //Critical path without communciation as list of edges
2648 input array<list<Integer>> iSccSimEqMapping; //maps each scc to simEqSystems
2649 input array<tuple<Integer,Integer,Real>> iSchedulerInfo; //maps each Task to <threadId, orderId, startCalcTime>
2650 input GraphDumpOptions iGraphDumpOptions; //Options to specify the output
2651 output GraphML.GraphInfo oGraphInfo;
2652 protected
2653 Integer graphIdx;
2654 array<String> annotationInfo;
2655 GraphML.GraphInfo graphInfo;
2656 algorithm
2657 40 graphInfo := GraphML.createGraphInfo();
2658
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 40 times.
40 (graphInfo, (_,graphIdx)) := GraphML.addGraph("TaskGraph", true, graphInfo);
2659 40 annotationInfo := arrayCreate(arrayLength(iGraph),"uncomment in HpcOmTaskGraph and +showAnnotations");
2660 //annotationInfo := setAnnotationsForTasks(iGraphData,backendDAE,annotationInfo);
2661 40 oGraphInfo := convertToGraphMLSccLevelSubgraph(iGraph,iGraphData,iCriticalPathInfo,iCriticalPath,iCriticalPathWoC,iSccSimEqMapping,iSchedulerInfo,annotationInfo,graphIdx,iGraphDumpOptions,graphInfo);
2662 end convertToGraphMLSccLevel;
2663
2664 public function convertToGraphMLSccLevelSubgraph "author: marcusw, waurich
2665 Convert the given graph into a subgraph of the graphml-structure."
2666 input TaskGraph iGraph;
2667 input TaskGraphMeta iGraphData;
2668 input String iCriticalPathInfo; //Critical path as String
2669 input list<tuple<Integer,Integer>> iCriticalPath; //Critical path as list of edges
2670 input list<tuple<Integer,Integer>> iCriticalPathWoC; //Critical path without communciation as list of edges
2671 input array<list<Integer>> iSccSimEqMapping; //maps each scc to simEqSystems
2672 input array<tuple<Integer,Integer,Real>> iSchedulerInfo; //maps each Task to <threadId, orderId, startCalcTime>
2673 input array<String> iAnnotationInfo; //annotations for the variables in a task
2674 input Integer iGraphIdx;
2675 input GraphDumpOptions iGraphDumpOptions; //Options to specify the output
2676 input GraphML.GraphInfo iGraphInfo;
2677 output GraphML.GraphInfo oGraphInfo;
2678 protected
2679 GraphML.GraphInfo graphInfo;
2680 Integer nameAttIdx, calcTimeAttIdx, opCountAttIdx, yCoordAttIdx, taskIdAttIdx, commCostAttIdx,
2681 commVarsAttIdx, commVarsIntAttIdx, commVarsFloatAttIdx, commVarsBoolAttIdx, critPathAttIdx,
2682 simCodeEqAttIdx, threadIdAttIdx, taskNumberAttIdx, annotAttIdx, compsIdAttIdx, partOfEventAttIdx, partOfOdeAttIdx, removedCompAttIdx;
2683 list<Integer> nodeIdc;
2684 algorithm
2685 oGraphInfo := match iGraphInfo
2686 case _
2687 algorithm
2688 56 (graphInfo,(_,nameAttIdx)) := GraphML.addAttribute("", "Name", GraphML.TYPE_STRING(), GraphML.TARGET_NODE(), iGraphInfo);
2689 56 (graphInfo,(_,opCountAttIdx)) := GraphML.addAttribute("-1", "Operations", GraphML.TYPE_INTEGER(), GraphML.TARGET_NODE(), graphInfo);
2690 56 (graphInfo,(_,calcTimeAttIdx)) := GraphML.addAttribute("-1", "CalcTime", GraphML.TYPE_DOUBLE(), GraphML.TARGET_NODE(), graphInfo);
2691 56 (graphInfo,(_,taskIdAttIdx)) := GraphML.addAttribute("", "TaskID", GraphML.TYPE_STRING(), GraphML.TARGET_NODE(), graphInfo);
2692 56 (graphInfo,(_,compsIdAttIdx)) := GraphML.addAttribute("", "Components", GraphML.TYPE_STRING(), GraphML.TARGET_NODE(), graphInfo);
2693 56 (graphInfo,(_,yCoordAttIdx)) := GraphML.addAttribute("17", "yCoord", GraphML.TYPE_INTEGER(), GraphML.TARGET_NODE(), graphInfo);
2694 56 (graphInfo,(_,simCodeEqAttIdx)) := GraphML.addAttribute("", "SimCodeEqs", GraphML.TYPE_STRING(), GraphML.TARGET_NODE(), graphInfo);
2695 56 (graphInfo,(_,threadIdAttIdx)) := GraphML.addAttribute("", "ThreadId", GraphML.TYPE_STRING(), GraphML.TARGET_NODE(), graphInfo);
2696 56 (graphInfo,(_,taskNumberAttIdx)) := GraphML.addAttribute("-1", "TaskNumber", GraphML.TYPE_INTEGER(), GraphML.TARGET_NODE(), graphInfo);
2697 56 (graphInfo,(_,commCostAttIdx)) := GraphML.addAttribute("-1", "CommCost", GraphML.TYPE_DOUBLE(), GraphML.TARGET_EDGE(), graphInfo);
2698 56 (graphInfo,(_,commVarsAttIdx)) := GraphML.addAttribute("-1", "CommVars", GraphML.TYPE_INTEGER(), GraphML.TARGET_EDGE(), graphInfo);
2699 56 (graphInfo,(_,commVarsIntAttIdx)) := GraphML.addAttribute("-1", "CommVarsInt", GraphML.TYPE_INTEGER(), GraphML.TARGET_EDGE(), graphInfo);
2700 56 (graphInfo,(_,commVarsFloatAttIdx)) := GraphML.addAttribute("-1", "CommVarsFloat", GraphML.TYPE_INTEGER(), GraphML.TARGET_EDGE(), graphInfo);
2701 56 (graphInfo,(_,commVarsBoolAttIdx)) := GraphML.addAttribute("-1", "CommVarsBool", GraphML.TYPE_INTEGER(), GraphML.TARGET_EDGE(), graphInfo);
2702 56 (graphInfo,(_,annotAttIdx)) := GraphML.addAttribute("annotation", "Annotations", GraphML.TYPE_STRING(), GraphML.TARGET_NODE(), graphInfo);
2703 56 (graphInfo,(_,critPathAttIdx)) := GraphML.addAttribute("", "CriticalPath", GraphML.TYPE_STRING(), GraphML.TARGET_GRAPH(), graphInfo);
2704 56 (graphInfo,(_,partOfEventAttIdx)) := GraphML.addAttribute("false", "isPartOfZeroFuncSystem", GraphML.TYPE_BOOLEAN(), GraphML.TARGET_NODE(), graphInfo);
2705 56 (graphInfo,(_,partOfOdeAttIdx)) := GraphML.addAttribute("false", "IsPartOfOdeSystem", GraphML.TYPE_BOOLEAN(), GraphML.TARGET_NODE(), graphInfo);
2706 56 (graphInfo,(_,removedCompAttIdx)) := GraphML.addAttribute("false", "IsRemovedComponent", GraphML.TYPE_BOOLEAN(), GraphML.TARGET_NODE(), graphInfo);
2707 56 graphInfo := GraphML.addGraphAttributeValue((critPathAttIdx, iCriticalPathInfo), iGraphIdx, graphInfo);
2708 56 nodeIdc := List.intRange(arrayLength(iGraph));
2709 56 (graphInfo,_) := List.fold(nodeIdc, function addNodeToGraphML(
2710 tGraphDataTuple=(iGraph, iGraphData),
2711 attIdc=(nameAttIdx,opCountAttIdx,calcTimeAttIdx,taskIdAttIdx,compsIdAttIdx,yCoordAttIdx,commCostAttIdx,commVarsAttIdx,
2712 commVarsIntAttIdx,commVarsFloatAttIdx,commVarsBoolAttIdx,simCodeEqAttIdx,threadIdAttIdx,taskNumberAttIdx,annotAttIdx,
2713 partOfEventAttIdx, partOfOdeAttIdx, removedCompAttIdx),
2714 sccSimEqMapping=iSccSimEqMapping,
2715 iSchedulerInfoCritPath=(iCriticalPath,iCriticalPathWoC,iSchedulerInfo, iAnnotationInfo),
2716 iGraphDumpOptions=iGraphDumpOptions),
2717 (graphInfo,iGraphIdx));
2718 then graphInfo;
2719 end match;
2720 end convertToGraphMLSccLevelSubgraph;
2721
2722 protected function addNodeToGraphML "author: marcusw, waurich
2723 Adds the given node to the given graph."
2724 input Integer nodeIdx;
2725 input tuple<TaskGraph, TaskGraphMeta> tGraphDataTuple;
2726 input tuple<Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer> attIdc;
2727 //Attribute index for <nameAttIdx,opCountAttIdx, calcTimeAttIdx, taskIdAttIdx, compsIdAttIdx, yCoordAttIdx, commCostAttIdx, commVarsAttIdx, commVarsAttIntIdx,
2728 // commVarsAttFloatIdx, commVarsAttBoolIdx, simCodeEqAttIdx, threadIdAttIdx, taskNumberAttIdx, annotationAttIdx, partOfEventAttIdx, partOfOdeAttIdx, removedCompAttIdx>
2729 input array<list<Integer>> sccSimEqMapping;
2730 input tuple<list<tuple<Integer,Integer>>,list<tuple<Integer,Integer>>,array<tuple<Integer,Integer,Real>>,array<String>> iSchedulerInfoCritPath; //<criticalPath,criticalPathWoC,schedulerInfo,annotationInfo>
2731 input GraphDumpOptions iGraphDumpOptions; //Options to specify the output
2732 input tuple<GraphML.GraphInfo,Integer> iGraph;
2733 output tuple<GraphML.GraphInfo,Integer> oGraph; //<GraphInfo, GraphIdx>
2734 protected
2735 TaskGraph tGraphIn;
2736 TaskGraphMeta tGraphDataIn;
2737 GraphML.GraphInfo tmpGraph;
2738 Integer graphIdx;
2739 Integer opCount, nameAttIdx, calcTimeAttIdx, opCountAttIdx, taskIdAttIdx, compsIdAttIdx, yCoordAttIdx, commCostAttIdx, commVarsAttIdx, commVarsAttIntIdx;
2740 Integer commVarsAttFloatIdx, commVarsAttBoolIdx, yCoord, simCodeEqAttIdx, threadIdAttIdx, taskNumberAttIdx, annotationAttIdx;
2741 Integer partOfEventAttIdx, partOfOdeAttIdx, removedCompAttIdx;
2742 Real calcTime, taskFinishTime, taskStartTime;
2743 Integer primalComp;
2744 list<Integer> childNodes;
2745 list<Integer> components;
2746 list<Integer> simCodeEqs;
2747 array<tuple<Integer,Real>> exeCosts;
2748 array<Integer> nodeMark;
2749 array<list<Integer>> inComps;
2750 array<String> compNames;
2751 array<String> compDescs;
2752 array<String> annotationInfo;
2753 String calcTimeString, opCountString, yCoordString, taskFinishTimeString, taskStartTimeString;
2754 String compText;
2755 String compsText;
2756 String nodeDesc;
2757 String componentsString;
2758 String simCodeEqString;
2759 String threadIdxString, taskNumberString;
2760 String annotationString;
2761 Integer schedulerThreadId, schedulerTaskNumber;
2762 list<GraphML.NodeLabel> nodeLabels;
2763 array<tuple<Integer,Integer,Real>> schedulerInfo;
2764 list<tuple<Integer,Integer>> criticalPath, criticalPathWoC;
2765 Boolean visualizeTaskStartAndFinishTime;
2766 Boolean visualizeTaskCalcTime;
2767 Boolean isPartOfODESystem, isPartOfZeroFuncSystem, isRemovedComponent;
2768 array<ComponentInfo> compInformations;
2769 algorithm
2770 4683 (tmpGraph,graphIdx) := iGraph;
2771
1/2
✓ Branch 0 taken 4683 times.
✗ Branch 1 not taken.
4683 if(intGt(nodeIdx, 0)) then
2772 4683 (tGraphIn, tGraphDataIn) := tGraphDataTuple;
2773 4683 TASKGRAPHMETA(inComps=inComps, compNames=compNames, compDescs=compDescs, exeCosts=exeCosts, nodeMark=nodeMark, compInformations=compInformations) := tGraphDataIn;
2774 4683 (nameAttIdx, opCountAttIdx, calcTimeAttIdx, taskIdAttIdx, compsIdAttIdx, yCoordAttIdx, commCostAttIdx, commVarsAttIdx, commVarsAttIntIdx, commVarsAttFloatIdx, commVarsAttBoolIdx, simCodeEqAttIdx, threadIdAttIdx, taskNumberAttIdx, annotationAttIdx, partOfEventAttIdx, partOfOdeAttIdx, removedCompAttIdx) := attIdc;
2775 4683 (criticalPath,criticalPathWoC,schedulerInfo,annotationInfo) := iSchedulerInfoCritPath;
2776 4683 GRAPHDUMPOPTIONS(visualizeTaskStartAndFinishTime=visualizeTaskStartAndFinishTime, visualizeTaskCalcTime=visualizeTaskCalcTime) := iGraphDumpOptions;
2777 4683 components := arrayGet(inComps,nodeIdx);
2778 4683 (isPartOfODESystem, isPartOfZeroFuncSystem, isRemovedComponent) := getNodeMembershipByComponents(components, compInformations);
2779
2780
2/2
✓ Branch 1 taken 408 times.
✓ Branch 2 taken 4275 times.
4683 if(intNe(listLength(components), 1)) then
2781 408 primalComp := List.last(components);
2782 408 simCodeEqs := List.flatten(List.map1(components, Array.getIndexFirst, sccSimEqMapping));
2783 408 nodeDesc := stringDelimitList(List.map1(components, Array.getIndexFirst, compDescs), "\n");// arrayGet(compDescs,primalComp);
2784 408 (opCount,calcTime) := List.fold1(components, addNodeToGraphML1, exeCosts, (0,0.0));
2785 else
2786 4275 primalComp := listGet(components,1);
2787 4275 simCodeEqs := arrayGet(sccSimEqMapping,primalComp);
2788 4275 nodeDesc := arrayGet(compDescs,primalComp);
2789 4275 (_,calcTime) := arrayGet(exeCosts,primalComp);
2790 4275 (opCount,calcTime) := arrayGet(exeCosts,primalComp);
2791 end if;
2792
2793 4683 compText := arrayGet(compNames,primalComp);
2794 4683 compsText := "{" + stringDelimitList(List.map(components, intString), ",") + "}";
2795 4683 annotationString := arrayGet(annotationInfo,nodeIdx);
2796 4683 calcTimeString := realString(calcTime);
2797 4683 yCoord := arrayGet(nodeMark,nodeIdx)*100;
2798 4683 opCountString := intString(opCount);
2799 4683 yCoordString := intString(yCoord);
2800 4683 childNodes := arrayGet(tGraphIn,nodeIdx);
2801 4683 simCodeEqString := stringDelimitList(List.map(simCodeEqs,intString),", ");
2802 //componentsString := List.fold(components, addNodeToGraphML2, " ");
2803 4683 componentsString := (" "+intString(nodeIdx)+" ");
2804 4683 (schedulerThreadId,schedulerTaskNumber,taskFinishTime) := arrayGet(schedulerInfo,nodeIdx);
2805 4683 taskStartTime := realSub(taskFinishTime,calcTime);
2806 4683 threadIdxString := "Th " + intString(schedulerThreadId);
2807 4683 taskNumberString := intString(schedulerTaskNumber);
2808 4683 calcTimeString := System.snprintff("%.0f", 25, calcTime);
2809 4683 taskFinishTimeString := System.snprintff("%.0f", 25, taskFinishTime);
2810 4683 taskStartTimeString := System.snprintff("%.0f", 25, taskStartTime);
2811 4683 nodeLabels := {GraphML.NODELABEL_INTERNAL(componentsString, NONE(), GraphML.FONTPLAIN())};
2812
1/2
✓ Branch 0 taken 4683 times.
✗ Branch 1 not taken.
4683 nodeLabels := if visualizeTaskCalcTime then GraphML.NODELABEL_CORNER(calcTimeString, SOME(GraphML.COLOR_YELLOW), GraphML.FONTBOLD(), "se")::nodeLabels else nodeLabels;
2813
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4683 times.
4683 nodeLabels := if visualizeTaskStartAndFinishTime then listAppend(nodeLabels, {GraphML.NODELABEL_CORNER(taskStartTimeString, SOME(GraphML.COLOR_CYAN), GraphML.FONTBOLD(), "nw"), GraphML.NODELABEL_CORNER(taskFinishTimeString, SOME(GraphML.COLOR_PINK), GraphML.FONTBOLD(), "sw")}) else nodeLabels;
2814
6/6
✓ Branch 12 taken 4594 times.
✓ Branch 13 taken 89 times.
✓ Branch 15 taken 3543 times.
✓ Branch 16 taken 1140 times.
✓ Branch 18 taken 4671 times.
✓ Branch 19 taken 12 times.
22174 (tmpGraph,_) := GraphML.addNode("Node" + intString(nodeIdx),
2815 GraphML.COLOR_ORANGE,
2816 GraphML.BORDERWIDTH_STANDARD,
2817 nodeLabels,
2818 GraphML.RECTANGLE(),
2819 SOME(nodeDesc),
2820 {
2821 ((nameAttIdx,compText)),((calcTimeAttIdx,calcTimeString)),((opCountAttIdx, opCountString)),((taskIdAttIdx,componentsString)),((compsIdAttIdx,compsText)),
2822 ((yCoordAttIdx,yCoordString)),((simCodeEqAttIdx,simCodeEqString)),((threadIdAttIdx,threadIdxString)),((taskNumberAttIdx,taskNumberString)),
2823 ((annotationAttIdx,annotationString)), ((partOfEventAttIdx, boolString(isPartOfODESystem))), ((partOfOdeAttIdx, boolString(isPartOfZeroFuncSystem))), ((removedCompAttIdx, boolString(isRemovedComponent)))
2824 },
2825 graphIdx,
2826 tmpGraph);
2827 4683 tmpGraph := List.fold(childNodes, function addDepToGraph(
2828 parentIdx=nodeIdx,
2829 tGraphDataIn=tGraphDataIn,
2830 iCommAttIdc=(commCostAttIdx, commVarsAttIdx, commVarsAttIntIdx, commVarsAttFloatIdx, commVarsAttBoolIdx),
2831 iCriticalPathEdges=(criticalPath,criticalPathWoC),
2832 iGraphDumpOptions=iGraphDumpOptions),
2833 tmpGraph);
2834 else
2835 ✗ Error.addMessage(Error.INTERNAL_ERROR, {"function addNodeToGraphML failed."});
2836 end if;
2837 4683 oGraph := ((tmpGraph,graphIdx));
2838 end addNodeToGraphML;
2839
2840 protected function addNodeToGraphML1 "author: marcusw
2841 Adds the execution costs of the given scc to the exeCostsIn-values."
2842 input Integer compIdx;
2843 input array<tuple<Integer,Real>> exeCosts;
2844 input tuple<Integer,Real> exeCostsIn;
2845 output tuple<Integer,Real> exeCostsOut;
2846 protected
2847 Integer opCount, opCountIn;
2848 Real exeTimeIn, exeTime;
2849 algorithm
2850 2652 (opCountIn,exeTimeIn) := exeCostsIn;
2851 2652 (opCount,exeTime) := arrayGet(exeCosts,compIdx);
2852 2652 exeCostsOut := ((opCountIn+opCount,realAdd(exeTimeIn,exeTime)));
2853 end addNodeToGraphML1;
2854
2855 protected function addDepToGraph "author: marcusw
2856 Adds a new edge between the component-nodes with index comp1Idx and comp2Idx to the graph."
2857 input Integer childIdx;
2858 input Integer parentIdx;
2859 input TaskGraphMeta tGraphDataIn;
2860 input tuple<Integer,Integer, Integer, Integer, Integer> iCommAttIdc; //<%(commCostAttIdx, commVarsAttIdx, commVarsAttIntIdx, commVarsAttFloatIdx, commVarsAttBoolIdx)%>
2861 input tuple<list<tuple<Integer,Integer>>,list<tuple<Integer,Integer>>> iCriticalPathEdges; //<%criticalPathEdges, criticalPathEdgesWoC%>
2862 input GraphDumpOptions iGraphDumpOptions; //Options to specify the output
2863 input GraphML.GraphInfo iGraph;
2864 output GraphML.GraphInfo oGraph;
2865 protected
2866 array<Communications> commCosts;
2867 list<Integer> integerVars,floatVars,booleanVars;
2868 Integer commCostAttIdx, commVarsAttIdx, commVarsAttIntIdx, commVarsAttFloatIdx, commVarsAttBoolIdx;
2869 Integer numOfCommVars;
2870 Real commCost;
2871 String commCostString, numOfCommVarsString, numOfCommVarsIntString, numOfCommVarsFloatString, numOfCommVarsBoolString;
2872 array<list<Integer>> inComps;
2873 array<Integer> nodeMark;
2874 GraphML.GraphInfo tmpGraph;
2875 list<tuple<Integer,Integer>> criticalPathEdges, criticalPathEdgesWoC;
2876 String edgeColor = GraphML.COLOR_BLACK;
2877 Boolean visualizeCriticalPath;
2878 Boolean visualizeCommTime;
2879 list<GraphML.EdgeLabel> edgeLabels;
2880 Real lineWidth;
2881 algorithm
2882 TASKGRAPHMETA(commCosts=commCosts, nodeMark=nodeMark, inComps=inComps) := tGraphDataIn;
2883 8535 (commCostAttIdx, commVarsAttIdx, commVarsAttIntIdx, commVarsAttFloatIdx, commVarsAttBoolIdx) := iCommAttIdc;
2884 8535 (criticalPathEdges, criticalPathEdgesWoC) := iCriticalPathEdges;
2885 8535 GRAPHDUMPOPTIONS(visualizeCriticalPath=visualizeCriticalPath,visualizeCommTime=visualizeCommTime) := iGraphDumpOptions;
2886
2887
2/2
✓ Branch 2 taken 41 times.
✓ Branch 3 taken 8494 times.
8535 if(List.exist1(criticalPathEdges, compareIntTuple2, (parentIdx, childIdx))) then
2888 lineWidth := GraphML.LINEWIDTH_BOLD;
2889
2/2
✓ Branch 0 taken 39 times.
✓ Branch 1 taken 2 times.
41 edgeColor := if visualizeCriticalPath then GraphML.COLOR_GRAY else edgeColor;
2890 else
2891 lineWidth := GraphML.LINEWIDTH_STANDARD;
2892 end if;
2893
2894 8535 COMMUNICATION(numberOfVars=numOfCommVars,integerVars=integerVars,floatVars=floatVars,booleanVars=booleanVars,requiredTime=commCost) := getCommCostBetweenNodes(parentIdx,childIdx,tGraphDataIn);
2895 8535 numOfCommVarsString := intString(numOfCommVars);
2896 8535 numOfCommVarsIntString := intString(listLength(integerVars));
2897 8535 numOfCommVarsFloatString := intString(listLength(floatVars));
2898 8535 numOfCommVarsBoolString := intString(listLength(booleanVars));
2899 8535 commCostString := System.snprintff("%.0f", 25, commCost);
2900
1/2
✓ Branch 0 taken 8535 times.
✗ Branch 1 not taken.
17070 edgeLabels := if visualizeCommTime then {GraphML.EDGELABEL(commCostString, SOME(edgeColor), GraphML.FONTSIZE_STANDARD)} else {};
2901 17070 (tmpGraph,_) := GraphML.addEdge("Edge" + intString(parentIdx) + intString(childIdx),
2902 "Node" + intString(childIdx), "Node" + intString(parentIdx),
2903 edgeColor,
2904 GraphML.LINE(),
2905 lineWidth,
2906 false,
2907 edgeLabels,
2908 (GraphML.ARROWNONE(),GraphML.ARROWSTANDART()),
2909 {(commCostAttIdx, commCostString),(commVarsAttIdx, numOfCommVarsString),(commVarsAttIntIdx,numOfCommVarsIntString),(commVarsAttFloatIdx,numOfCommVarsFloatString),(commVarsAttBoolIdx,numOfCommVarsBoolString)},
2910 iGraph);
2911 oGraph := tmpGraph;
2912 end addDepToGraph;
2913
2914 protected function getNodeMembershipByComponents "author: marcusw
2915 Get the information of a node was removed or belongs to the ode or event-system."
2916 input list<Integer> iNodeComponents;
2917 input array<ComponentInfo> iCompInformations;
2918 output tuple<Boolean, Boolean, Boolean> oMembership; //<isPartOfODESystem, isPartOfZeroFuncSystem, isRemovedComponent>
2919 protected
2920 Boolean isPartOfODESystem, isPartOfZeroFuncSystem, isRemovedComponent;
2921 Integer compIdx;
2922 ComponentInfo tmpComponentInformation;
2923 algorithm
2924 tmpComponentInformation := COMPONENTINFO(false, false, false);
2925
2/2
✓ Branch 0 taken 6927 times.
✓ Branch 1 taken 4683 times.
11610 for compIdx in iNodeComponents loop
2926 6927 tmpComponentInformation := combineComponentInformations(arrayGet(iCompInformations, compIdx), tmpComponentInformation);
2927 end for;
2928 4683 COMPONENTINFO(isPartOfODESystem, isPartOfZeroFuncSystem, isRemovedComponent) := tmpComponentInformation;
2929
6/6
✓ Branch 0 taken 4671 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 3543 times.
✓ Branch 3 taken 1140 times.
✓ Branch 4 taken 4594 times.
✓ Branch 5 taken 89 times.
17491 oMembership := (isPartOfODESystem, isPartOfZeroFuncSystem, isRemovedComponent);
2930 end getNodeMembershipByComponents;
2931
2932
2933 //-----------------
2934 // Print functions
2935 //-----------------
2936
2937 public function printTaskGraph "author: Waurich TUD 2013-07
2938 Prints the adjacencylist of the TaskGraph."
2939 input TaskGraph graphIn;
2940 protected
2941 list<list<Integer>> graphLst;
2942 algorithm
2943 ✗ print("\n");
2944 ✗ print("--------------------------------\n");
2945 ✗ print("TASKGRAPH\n");
2946 ✗ print("--------------------------------\n");
2947 ✗ graphLst := arrayList(graphIn);
2948 ✗ dumpAdjacencyLst(graphLst,1);
2949 ✗ print("\n");
2950 end printTaskGraph;
2951
2952 protected function dumpAdjacencyLst "author: Waurich TUD 2013-07
2953 Prints the adjacencyLst."
2954 input list<list<Integer>> inIntegerLstLst;
2955 input Integer rowIndex;
2956 algorithm
2957 () := match inIntegerLstLst
2958 local
2959 list<Integer> row;
2960 list<list<Integer>> rows;
2961 case {} then ();
2962 case row :: rows
2963 algorithm
2964 ✗ print(intString(rowIndex));print(":");
2965 ✗ dumpAdjacencyRow(row);
2966 ✗ dumpAdjacencyLst(rows,rowIndex+1);
2967 then
2968 ();
2969 end match;
2970 end dumpAdjacencyLst;
2971
2972 protected function dumpAdjacencyRow "author: PA
2973 Helper function to dumpAdjacencyMatrix2."
2974 input list<Integer> inIntegerLst;
2975 algorithm
2976 () := match inIntegerLst
2977 local
2978 String s;
2979 Integer x;
2980 list<Integer> xs;
2981 case {}
2982 algorithm
2983 ✗ print("\n");
2984 then
2985 ();
2986 case x :: xs
2987 algorithm
2988 ✗ s := intString(x);
2989 ✗ print(s);
2990 ✗ print(" ");
2991 ✗ dumpAdjacencyRow(xs);
2992 then
2993 ();
2994 end match;
2995 end dumpAdjacencyRow;
2996
2997 public function printTaskGraphMeta "author: Waurich TUD 2013-06
2998 Prints all data from TaskGraphMeta."
2999 input TaskGraphMeta metaDataIn;
3000 protected
3001 array<list<Integer>> inComps;
3002 array<tuple<Integer, Integer, Integer>> varCompMapping;
3003 array<tuple<Integer,Integer,Integer>> eqCompMapping;
3004 array<String> compNames;
3005 array<String> compDescs;
3006 array<tuple<Integer,Real>> exeCosts;
3007 array<Communications> commCosts;
3008 array<Integer> nodeMark;
3009 array<list<Integer>> compParamMapping;
3010 array<ComponentInfo> compInformations;
3011 algorithm
3012 ✗ TASKGRAPHMETA(inComps=inComps, varCompMapping=varCompMapping, eqCompMapping=eqCompMapping, compParamMapping=compParamMapping, compNames=compNames, compDescs=compDescs, exeCosts=exeCosts, commCosts=commCosts, nodeMark=nodeMark, compInformations=compInformations) := metaDataIn;
3013 ✗ print("\n");
3014 ✗ print("--------------------------------\n");
3015 ✗ print("TASKGRAPH METADATA\n");
3016 ✗ print("--------------------------------\n");
3017 ✗ print(intString(arrayLength(inComps))+" nodes include components:\n");
3018 ✗ printInComps(inComps);
3019 ✗ print(intString(arrayLength(varCompMapping))+" vars are solved in the nodes \n");
3020 ✗ printVarCompMapping(varCompMapping);
3021 ✗ print(intString(arrayLength(eqCompMapping))+" equations are computed in the nodes \n");
3022 ✗ printEqCompMapping(eqCompMapping);
3023 ✗ print(intString(arrayLength(compParamMapping))+" parameters are part of the components \n");
3024 ✗ printCompParamMapping(compParamMapping);
3025 ✗ print("the names of the components \n");
3026 ✗ printComponentNames(compNames);
3027 ✗ print("the description of the node\n");
3028 ✗ printCompDescs(compDescs);
3029 ✗ print("the execution costs of the nodes\n");
3030 ✗ printExeCosts(exeCosts);
3031 ✗ print("the communication costs of the nodes\n");
3032 ✗ printCommCosts(commCosts);
3033 ✗ print("the nodeMark of the nodes\n");
3034 ✗ printNodeMarks(nodeMark);
3035 ✗ print("the component informations are\n");
3036 ✗ printComponentInformations(compInformations);
3037 ✗ print("\n");
3038 end printTaskGraphMeta;
3039
3040 protected function printInComps "author:Waurich TUD 2013-06
3041 Prints the information about the assigned components to a taskgraph node."
3042 input array<list<Integer>> iInComps;
3043 protected
3044 Integer nodeIdx;
3045 list<Integer> compRow;
3046 algorithm
3047 ✗ for nodeIdx in 1:arrayLength(iInComps) loop
3048 ✗ compRow := arrayGet(iInComps,nodeIdx);
3049 ✗ print("node " + intString(nodeIdx) + " solves components: " + stringDelimitList(List.map(compRow,intString),", ") + "\n");
3050 end for;
3051 ✗ print("--------------------------------\n");
3052 end printInComps;
3053
3054 protected function printVarCompMapping "author: Waurich TUD 2013-07 / marcusw
3055 Prints the information about how the vars are assigned to the graph nodes."
3056 input array<tuple<Integer, Integer, Integer>> iVarCompMapping;
3057 protected
3058 Integer varIdx, comp, eqSysIdx, varOffset;
3059 algorithm
3060 ✗ for varIdx in 1:arrayLength(iVarCompMapping) loop
3061 ✗ (comp,eqSysIdx,varOffset) := arrayGet(iVarCompMapping,varIdx);
3062 ✗ print("variable " + intString(varIdx-varOffset) + " (offset: " + intString(varOffset) + ") of equation system "
3063 + intString(eqSysIdx) + " is solved in component: " + intString(comp) + "\n");
3064 end for;
3065 ✗ print("--------------------------------\n");
3066 end printVarCompMapping;
3067
3068 protected function printEqCompMapping "author: Waurich TUD 2013-07 / marcusw
3069 Prints the information about which equations are assigned to the graph nodes."
3070 input array<tuple<Integer,Integer,Integer>> iEqCompMapping;
3071 protected
3072 Integer eqIdx, comp, eqSysIdx, eqOffset;
3073 algorithm
3074 ✗ for eqIdx in 1:arrayLength(iEqCompMapping) loop
3075 ✗ (comp,eqSysIdx,eqOffset) := arrayGet(iEqCompMapping,eqIdx);
3076 ✗ print("equation " + intString(eqIdx) + " (offset: " + intString(eqOffset) + ") of equation system "
3077 + intString(eqSysIdx) + " is computed in component: " + intString(comp) + "\n");
3078 end for;
3079 ✗ print("--------------------------------\n");
3080 end printEqCompMapping;
3081
3082 protected function printCompParamMapping "author: marcusw
3083 Prints the information which components contains which parameters."
3084 input array<list<Integer>> iCompParamMapping;
3085 protected
3086 Integer compIdx;
3087 list<Integer> params;
3088 algorithm
3089 ✗ for compIdx in 1:arrayLength(iCompParamMapping) loop
3090 ✗ params := arrayGet(iCompParamMapping,compIdx);
3091 ✗ print("component " + intString(compIdx) + " needs the parameters: " + stringDelimitList(List.map(params, intString), ",") + "\n");
3092 end for;
3093 ✗ print("--------------------------------\n");
3094 end printCompParamMapping;
3095
3096 protected function printComponentNames "author: Waurich TUD 2013-07 / marcusw
3097 Prints the component names of the taskgraph components."
3098 input array<String> iCompNames;
3099 protected
3100 Integer compIdx;
3101 String compName;
3102 algorithm
3103 ✗ for compIdx in 1:arrayLength(iCompNames) loop
3104 ✗ compName := arrayGet(iCompNames,compIdx);
3105 ✗ print("component " + intString(compIdx) + " is named " + compName + "\n");
3106 end for;
3107 ✗ print("--------------------------------\n");
3108 end printComponentNames;
3109
3110 protected function printCompDescs "author: Waurich TUD 2013-07 / marcusw
3111 Prints the information about the description of the taskgraph nodes for the .graphml file."
3112 input array<String> iCompDescs;
3113 protected
3114 Integer compIdx;
3115 String compDesc;
3116 algorithm
3117 ✗ for compIdx in 1:arrayLength(iCompDescs) loop
3118 ✗ compDesc := arrayGet(iCompDescs,compIdx);
3119 ✗ print("component " + intString(compIdx) + " is described with: " + compDesc + "\n");
3120 end for;
3121 ✗ print("--------------------------------\n");
3122 end printCompDescs;
3123
3124 protected function printExeCosts "author: Waurich TUD 2013-07 / marcusw
3125 Prints the information about the execution costs of every component in task graph meta."
3126 input array<tuple<Integer,Real>> iExeCosts;
3127 protected
3128 Integer compIdx;
3129 Integer opCount;
3130 Real execTime;
3131 algorithm
3132 ✗ for compIdx in 1:arrayLength(iExeCosts) loop
3133 ✗ (opCount,execTime) := arrayGet(iExeCosts,compIdx);
3134 ✗ print("component " + intString(compIdx) + " has execution cost of: (" + intString(opCount) + "," + realString(execTime) + ")\n");
3135 end for;
3136 ✗ print("--------------------------------\n");
3137 end printExeCosts;
3138
3139 protected function printCommCosts "author: Waurich TUD 2013-06 / marcusw
3140 Prints the information about the the communication costs of every edge."
3141 input array<Communications> iCommCosts;
3142 protected
3143 Integer nodeIdx;
3144 Communications nodeComms;
3145 algorithm
3146 ✗ for nodeIdx in 1:arrayLength(iCommCosts) loop
3147 ✗ nodeComms := arrayGet(iCommCosts,nodeIdx);
3148 ✗ print("edges from node " + intString(nodeIdx) + ": with the communication costs " + stringDelimitList(List.map(nodeComms,printCommCost), ", ") + "\n");
3149 end for;
3150 ✗ print("--------------------------------\n");
3151 end printCommCosts;
3152
3153 protected function printCommCost "author: marcusw
3154 Prints the information about the the communication costs of one edge."
3155 input Communication iComm;
3156 output String oCommString;
3157 protected
3158 Integer numberOfVars,numberOfIntegers,numberOfFloats,numberOfBooleans,childNode;
3159 list<Integer> integerVars,floatVars,booleanVars;
3160 Real requiredTime;
3161 algorithm
3162 ✗ COMMUNICATION(numberOfVars=numberOfVars,integerVars=integerVars,floatVars=floatVars,booleanVars=booleanVars,childNode=childNode,requiredTime=requiredTime) := iComm;
3163 ✗ numberOfIntegers := listLength(integerVars);
3164 ✗ numberOfFloats := listLength(floatVars);
3165 ✗ numberOfBooleans := listLength(booleanVars);
3166 ✗ oCommString := "(target node: " + intString(childNode) + " ints: " + intString(numberOfIntegers) + " floats: " + intString(numberOfFloats) + " booleans: " + intString(numberOfBooleans) + " [requiredTime: " + realString(requiredTime) + " for " + intString(numberOfVars) + " variables)";
3167 end printCommCost;
3168
3169 protected function printNodeMarks "author: Waurich TUD 2013-07 / marcusw
3170 Prints the information about additional NodeMark."
3171 input array<Integer> iNodeMarks;
3172 protected
3173 Integer compIdx, mark;
3174 algorithm
3175 ✗ for compIdx in 1:arrayLength(iNodeMarks) loop
3176 ✗ mark := arrayGet(iNodeMarks,compIdx);
3177 ✗ print("component " + intString(compIdx) + " has the nodeMark : " + intString(mark) + "\n");
3178 end for;
3179 ✗ print("--------------------------------\n");
3180 end printNodeMarks;
3181
3182 protected function printComponentInformations "author: marcusw
3183 Function to print the component information of task graph meta."
3184 input array<ComponentInfo> iComponentInformations;
3185 protected
3186 Integer compIdx;
3187 Boolean isPartOfODESystem;
3188 Boolean isPartOfZeroFuncSystem;
3189 Boolean isRemovedComponent;
3190 algorithm
3191 ✗ for compIdx in 1:arrayLength(iComponentInformations) loop
3192 ✗ COMPONENTINFO(isPartOfODESystem=isPartOfODESystem,isPartOfZeroFuncSystem=isPartOfZeroFuncSystem,isRemovedComponent=isRemovedComponent) := arrayGet(iComponentInformations, compIdx);
3193 ✗ print("component " + intString(compIdx) + " has component information:\n");
3194 ✗ print(" Is part of ODE-System: " + boolString(isPartOfODESystem) + "\n");
3195 ✗ print(" Is part of Event-System: " + boolString(isPartOfZeroFuncSystem) + "\n");
3196 ✗ print(" Is removed component: " + boolString(isRemovedComponent) + "\n");
3197 end for;
3198 ✗ print("--------------------------------\n");
3199 end printComponentInformations;
3200
3201 public function intLstString "author: Waurich TUD 2013-07
3202 Converts a list<Integer> into a string which than can be used for printing."
3203 input list<Integer> lstIn;
3204 output String strOut;
3205 protected
3206 String str;
3207 algorithm
3208 32 str := stringDelimitList(List.map(lstIn,intString),",");
3209
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 28 times.
32 strOut := if listEmpty(lstIn) then "---" else str;
3210 end intLstString;
3211
3212 public function dumpCriticalPathInfo "author: marcusw
3213 Dump the criticalPath and the costs to a string."
3214 input tuple<list<list<Integer>>,Real> iCriticalPaths; //<%criticalPath, criticalPathOpCost%>
3215 input tuple<list<list<Integer>>,Real> iCriticalPathsWoC; //<%criticalPath, criticalPathOpCost%>
3216 output String oString;
3217 protected
3218 String tmpString;
3219 list<list<Integer>> critPath, critPathWoC;
3220 Real costPath, costPathWoC;
3221 algorithm
3222 oString := match(iCriticalPaths,iCriticalPathsWoC)
3223 case(({},_),_)
3224 algorithm
3225 then
3226 "";
3227 case((critPath,costPath),(critPathWoC,costPathWoC))
3228 algorithm
3229 16 tmpString := "critical path with costs of "+realString(costPath)+" cycles -- ";
3230 16 tmpString := tmpString + dumpCriticalPathInfo1(critPath,1);
3231 16 tmpString := " ;; " + tmpString + "critical path' with costs of "+realString(costPathWoC)+" cycles -- ";
3232 16 tmpString := tmpString + dumpCriticalPathInfo1(critPathWoC,1);
3233 then
3234 tmpString;
3235 end match;
3236 end dumpCriticalPathInfo;
3237
3238 protected function dumpCriticalPathInfo1 "author: marcusw
3239 Helper function of dumpCriticalPathInfo. Dump one critical path."
3240 input list<list<Integer>> criticalPathsIn;
3241 input Integer cpIdx;
3242 output String oString;
3243 algorithm
3244 32 oString := intLstString(listGet(criticalPathsIn,cpIdx))+"";
3245 end dumpCriticalPathInfo1;
3246
3247 protected function printCriticalPathInfo "author: Waurich TUD 2013-07
3248 Prints the criticalPath and the costs."
3249 input list<list<Integer>> criticalPathsIn;
3250 input Real cpCosts;
3251 algorithm
3252 () := match criticalPathsIn
3253 case {}
3254 algorithm
3255 then
3256 ();
3257 else
3258 algorithm
3259 ✗ print("--------------------------------\n");
3260 ✗ print(" CRITICAL PATH INFO\n");
3261 ✗ print("--------------------------------\n");
3262 ✗ print("found "+intString(listLength(criticalPathsIn))+" critical paths with costs of "+realString(cpCosts)+" sec\n");
3263 ✗ printCriticalPathInfo1(criticalPathsIn,1);
3264 then
3265 ();
3266 end match;
3267 end printCriticalPathInfo;
3268
3269 protected function printCriticalPathInfo1 "author: Waurich TUD 2013-07
3270 Prints one criticalPath."
3271 input list<list<Integer>> criticalPathsIn;
3272 input Integer cpIdx;
3273 algorithm
3274 ✗ print(intString(cpIdx)+". path: "+intLstString(listGet(criticalPathsIn,cpIdx))+"\n");
3275 end printCriticalPathInfo1;
3276
3277
3278 //--------------------------
3279 // Functions to merge nodes
3280 //--------------------------
3281
3282 protected function mergeSingleNodes "
3283 Merges all single nodes. The max number of remaining single nodes is numProc."
3284 input TaskGraph iTaskGraph;
3285 input TaskGraphMeta iTaskGraphMeta;
3286 input list<Integer> doNotMergeIn;
3287 output TaskGraph oTaskGraph;
3288 output TaskGraphMeta oTaskGraphMeta;
3289 output Boolean changed;
3290 algorithm
3291 (oTaskGraph,oTaskGraphMeta,changed) := matchcontinue doNotMergeIn
3292 local
3293 Integer numProc;
3294 list<Integer> singleNodes,singleNodes1,pos;
3295 list<Real> exeCosts;
3296 TaskGraph taskGraphT;
3297 case _
3298 algorithm
3299 ✗ numProc := Flags.getConfigInt(Flags.NUM_PROC);
3300 ✗ taskGraphT := AdjacencyMatrix.transposeAdjacencyMatrix(iTaskGraph,arrayLength(iTaskGraph));
3301 //get the single nodes, sort them according to their exeCosts in decreasing order
3302 ✗ (_,singleNodes) := List.filterOnTrueSync(arrayList(iTaskGraph),listEmpty,List.intRange(arrayLength(iTaskGraph))); //nodes without successor
3303 ✗ (_,singleNodes1) := List.filterOnTrueSync(arrayList(taskGraphT),listEmpty,List.intRange(arrayLength(taskGraphT))); //nodes without predecessor
3304 ✗ (singleNodes,_,_) := List.intersection1OnTrue(singleNodes,singleNodes1,intEq);
3305 ✗ (_,singleNodes,_) := List.intersection1OnTrue(singleNodes,doNotMergeIn,intEq);
3306 ✗ exeCosts := List.map1(singleNodes,getExeCostReqCycles,iTaskGraphMeta);
3307 ✗ (exeCosts,pos) := HpcOmScheduler.quicksortWithOrder(exeCosts);
3308 ✗ singleNodes := List.map1(pos,List.getIndexFirst,singleNodes);
3309 ✗ singleNodes := listReverse(singleNodes);
3310 //print("singleNodes "+stringDelimitList(List.map(singleNodes,intString),"\n")+"\n");
3311 ✗ exeCosts := listReverse(exeCosts);
3312 // cluster these singleNodes
3313 ✗ distributeToClusters(singleNodes,exeCosts,numProc);
3314 //print("cluster "+stringDelimitList(List.mapArray(cluster, intLstString),"\n")+"\n");
3315 //update taskgraph and taskgraphMeta
3316 //(oTaskGraph,oTaskGraphMeta) = contractNodesInGraph(clusterLst,iTaskGraph,iTaskGraphMeta);
3317 ✗ changed := intGt(listLength(singleNodes),numProc);
3318 then (iTaskGraph,iTaskGraphMeta,changed);
3319 else (iTaskGraph,iTaskGraphMeta,false);
3320 end matchcontinue;
3321 end mergeSingleNodes;
3322
3323 public function distributeToClusters "author: Waurich TUD 2014-06
3324 Takes a list of items and corresponding values and clusters the items. The clusters are supposed to have an
3325 most equal distribution of accumulated values. If the items list is shorter than the numProc, a cluster list
3326 containing empty lists will be returned."
3327 input list<Integer> items;
3328 input list<Real> values;
3329 input Integer numClusters;
3330 output array<list<Integer>> clustersOut;
3331 output array<Real> clusterValuesOut;
3332 protected
3333 Boolean b;
3334 array<Integer> itemArr;
3335 array<list<Integer>> itemsCopy, clusters;
3336 array<Real> clusterValues;
3337 algorithm
3338 ✗ b := intGt(listLength(items),numClusters);
3339 ✗ clusters := listArray(List.map(List.intRange(listLength(items)),List.create));
3340 ✗ clusterValues := listArray(values);
3341 ✗ itemArr := listArray(items);
3342 ✗ itemsCopy := Array.map(itemArr,List.create);
3343 ✗ clusters := if true then Array.copy(itemsCopy,clusters) else clusters;
3344 ✗ clusterValues := if not b then Array.copy(listArray(values),clusterValues) else clusterValues;
3345 ✗ if b then
3346 ✗ (clustersOut,clusterValuesOut) := distributeToClusters1((items,values),(clusters,clusterValues),numClusters);
3347 else
3348 ✗ (clustersOut,clusterValuesOut) := (clusters,clusterValues);
3349 end if;
3350 end distributeToClusters;
3351
3352 protected function distributeToClusters1
3353 input tuple<list<Integer>,list<Real>> tplIn; //<items,values>
3354 input tuple<array<list<Integer>>,array<Real>> tplFold; // <<a item mapping :item-> included items>, <item: added costs of all included items>>
3355 input Integer numClusters;
3356 output array<list<Integer>> clustersOut;
3357 output array<Real> clusterValuesOut;
3358 algorithm
3359 (clustersOut,clusterValuesOut) := matchcontinue(tplIn, tplFold)
3360 local
3361 Integer numCl, diff;
3362 list<Integer> itemsIn,lst1,idcsLst1_2,idcsLst2,idcsLst1;
3363 list<list<Integer>> entries,entries2;
3364 list<Real> valuesIn,values,addValues;
3365 array<list<Integer>> clusters, clustersFinal;
3366 array<Real> clusterValues, clusterValuesFinal;
3367 case((itemsIn,_), (clusters,clusterValues))
3368 algorithm
3369 ✗ true := listLength(itemsIn) <= numClusters;
3370 ✗ idcsLst1 := List.intRange(numClusters);
3371 ✗ clustersFinal := Array.select(clusters,idcsLst1);
3372 ✗ clusterValuesFinal := Array.select(clusterValues,idcsLst1);
3373 ✗ then (clustersFinal,clusterValuesFinal);
3374 case((itemsIn,valuesIn), (clusters,clusterValues))
3375 algorithm
3376 ✗ true := listLength(itemsIn) > numClusters;
3377 ✗ true := listLength(itemsIn)/2 < numClusters;
3378 ✗ (lst1,_) := List.split(itemsIn,numClusters); // split the list of items+dummies in the middle
3379 ✗ diff := listLength(itemsIn) - numClusters;
3380 ✗ idcsLst1 := List.intRange2(numClusters-diff+1,numClusters);
3381 ✗ idcsLst2 := List.intRange2(numClusters+1,listLength(itemsIn));
3382 // update the clusters array
3383 ✗ entries := List.map1(idcsLst2,Array.getIndexFirst,clusters);
3384 ✗ entries := listReverse(entries);
3385 ✗ entries2 := List.map1(idcsLst1,Array.getIndexFirst,clusters);
3386 ✗ entries := List.threadMap(entries,entries2,listAppend);
3387 ✗ List.threadMap1_0(idcsLst1,entries,Array.updateIndexFirst,clusters);
3388 // update the clusterValues array
3389 ✗ values := List.map1(idcsLst1,Array.getIndexFirst,clusterValues);
3390 ✗ addValues := List.map1(idcsLst2,Array.getIndexFirst,clusterValues);
3391 ✗ values := List.threadMap(values,addValues,realAdd);
3392 ✗ List.threadMap1_0(idcsLst1,values,Array.updateIndexFirst,clusterValues);
3393 // finish
3394 ✗ (clusters,clusterValues) := distributeToClusters1((lst1,valuesIn),(clusters,clusterValues),numClusters);
3395 then (clusters,clusterValues);
3396 case((itemsIn,valuesIn), (clusters,clusterValues))
3397 algorithm
3398 ✗ true := listLength(itemsIn) > numClusters;
3399 ✗ true := listLength(itemsIn)/2 >= numClusters;
3400 ✗ numCl := nextGreaterPowerOf2(intReal(listLength(itemsIn)));
3401 ✗ (lst1,_) := List.split(itemsIn,intDiv(numCl,2)); // split the list of items+dummies in the middle
3402 // update the clusters array
3403 ✗ idcsLst2 := List.intRange2(intDiv(numCl,2)+1,listLength(itemsIn));
3404 ✗ idcsLst1_2 := List.intRange2(intDiv(numCl,2)-listLength(idcsLst2)+1, intDiv(numCl,2));
3405 ✗ entries := List.map1(idcsLst2,Array.getIndexFirst,clusters); // the clustered task from the second list
3406 ✗ entries := listReverse(entries);
3407 ✗ entries2 := List.map1(idcsLst1_2,Array.getIndexFirst,clusters);
3408 ✗ entries := List.threadMap(entries,entries2,listAppend);
3409 ✗ List.threadMap1_0(idcsLst1_2,entries,Array.updateIndexFirst,clusters);
3410 // update the clusterValues array
3411 ✗ values := List.map1(idcsLst1_2,Array.getIndexFirst,clusterValues);
3412 ✗ addValues := List.map1(idcsLst2,Array.getIndexFirst,clusterValues);
3413 ✗ values := List.threadMap(values,addValues,realAdd);
3414 ✗ List.threadMap1_0(idcsLst1_2,values,Array.updateIndexFirst,clusterValues);
3415 // again
3416 ✗ (clusters,clusterValues) := distributeToClusters1((lst1,valuesIn),(clusters,clusterValues),numClusters);
3417 then (clusters,clusterValues);
3418 else
3419 algorithm
3420 ✗ print("distributeToClusters failed!\n");
3421 ✗ then fail();
3422 end matchcontinue;
3423 end distributeToClusters1;
3424
3425 protected function nextGreaterPowerOf2 "author: Waurich TUD 2014-06
3426 Finds the next greater power of 2."
3427 input Real n;
3428 output Integer powOf2;
3429 algorithm
3430 ✗ powOf2 := nextGreaterPowerOf2_impl(n,1);
3431 end nextGreaterPowerOf2;
3432
3433 protected function nextGreaterPowerOf2_impl
3434 input Real n;
3435 input Integer pow;
3436 output Integer powOf2;
3437 protected
3438 Real p;
3439 algorithm
3440 ✗ p := realPow(2.0,intReal(pow));
3441 ✗ powOf2 := if n <= p then realInt(p) else nextGreaterPowerOf2_impl(n,pow+1);
3442 end nextGreaterPowerOf2_impl;
3443
3444 public function mergeSimpleNodes "author: Waurich TUD 2013-07
3445 Merges all nodes in the graph that have only one predecessor and one successor."
3446 input TaskGraph graphIn;
3447 input TaskGraph graphTIn;
3448 input TaskGraphMeta graphDataIn;
3449 input array<Integer> contractedTasksIn;
3450 output TaskGraph graphOut; //TaskGraph-Edges are updated on the fly
3451 output TaskGraph graphTOut;
3452 output TaskGraphMeta graphDataOut;
3453 output array<Integer> contractedTasksOut; //removed task has value -1; not touched task has value 0
3454 output Boolean changed;
3455 protected
3456 list<Integer> allNodes;
3457 list<list<Integer>> oneChildren;
3458 algorithm
3459 65 allNodes := List.intRange(arrayLength(graphIn)); // to traverse the node indeces
3460 65 oneChildren := findOneChildParents(allNodes,graphIn,{},{{}},0,contractedTasksIn); // paths of nodes with just one successor per node (extended: and endnodes with just one parent node)
3461 //for child in oneChildren loop
3462 // print("oneChildren " + stringDelimitList(List.map(child, intString), ",") + "\n");
3463 //end for;
3464 65 oneChildren := listDelete(oneChildren,listLength(oneChildren)); // remove the empty startValue {}
3465 65 oneChildren := List.removeOnTrue(1,compareListLengthOnTrue,oneChildren); // remove paths of length 1
3466 //print("oneChildren "+stringDelimitList(List.map(oneChildren,intLstString),"\n")+"\n");
3467 65 (graphOut,graphTOut,graphDataOut,contractedTasksOut) := contractNodesInGraph(oneChildren,graphIn,graphTIn,graphDataIn,contractedTasksIn);
3468
1/2
✓ Branch 0 taken 65 times.
✗ Branch 1 not taken.
65 changed := not listEmpty(oneChildren);
3469 //print("contractedTasksOut "+stringDelimitList(List.mapArray(contractedTasksOut, intString),"\n")+"\n");
3470 end mergeSimpleNodes;
3471
3472 public function mergeParentNodes "author: marcusw, waurich
3473 Merges parent nodes into child if this produces a shorter execution time due to omitted communication costs."
3474 input TaskGraph graphIn;
3475 input TaskGraph graphTIn;
3476 input TaskGraphMeta graphDataIn;
3477 input array<Integer> contractedTasksIn;
3478 output TaskGraph graphOut;
3479 output TaskGraph graphTOut;
3480 output TaskGraphMeta graphDataOut;
3481 output array<Integer> contractedTasksOut;
3482 output Boolean changed;
3483 protected
3484 array<Integer> alreadyMerged;
3485 list<list<Integer>> mergedNodes;
3486 algorithm
3487 65 alreadyMerged := arrayCreate(arrayLength(graphIn),0);
3488 65 mergedNodes := mergeParentNodes0(graphIn, graphTIn, graphDataIn, contractedTasksIn, alreadyMerged, 1, {});
3489 //print("mergedNodes "+stringDelimitList(List.map(mergedNodes,intLstString),"\n")+"\n");
3490 65 (graphOut,graphTOut,graphDataOut,contractedTasksOut) := contractNodesInGraph(mergedNodes,graphIn,graphTIn,graphDataIn,contractedTasksIn);
3491
1/2
✓ Branch 0 taken 65 times.
✗ Branch 1 not taken.
65 changed := not listEmpty(mergedNodes);
3492 //print("contractedTasksOut "+stringDelimitList(List.mapArray(contractedTasksOut,intString),"\n")+"\n");
3493 end mergeParentNodes;
3494
3495 protected function mergeParentNodes0
3496 input TaskGraph iGraph;
3497 input TaskGraph iGraphT;
3498 input TaskGraphMeta iGraphData;
3499 input array<Integer> contractedTasksIn;
3500 input array<Integer> alreadyMerged;
3501 input Integer iNodeIdx;
3502 input list<list<Integer>> iMergedNodes;
3503 output list<list<Integer>> oMergedNodes;
3504 protected
3505 Real highestParentExeCost, sumParentExeCosts;
3506 list<Integer> parentNodes, mergeNodeList;
3507 Real highestCommCost;
3508 array<tuple<Integer, Real>> exeCosts;
3509 list<tuple<Integer, Real>> parentExeCosts;
3510 array<Communications> commCosts;
3511 Communications parentCommCosts;
3512 list<list<Integer>> parentChilds;
3513 list<list<Integer>> tmpMergedNodes;
3514 algorithm
3515 oMergedNodes := matchcontinue iGraphData
3516 case TASKGRAPHMETA(exeCosts=exeCosts, commCosts=commCosts)
3517 algorithm
3518
2/2
✓ Branch 0 taken 65 times.
✓ Branch 1 taken 15310 times.
15375 true := intLe(iNodeIdx, arrayLength(iGraphT)); //Current index is in range
3519
2/2
✓ Branch 1 taken 76 times.
✓ Branch 2 taken 15234 times.
15310 true := intNe(arrayGet(contractedTasksIn,iNodeIdx),-1);
3520
2/2
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 15233 times.
15234 true := intNe(arrayGet(alreadyMerged,iNodeIdx),-1); // is not already in a merged task group
3521 //print("HpcOmTaskGraph.mergeParentNodes0: looking at node " + intString(iNodeIdx) + "\n");
3522 15233 parentNodes := arrayGet(iGraphT, iNodeIdx);
3523 15233 parentNodes := filterContractedNodes(parentNodes,contractedTasksIn);
3524
2/2
✓ Branch 1 taken 120 times.
✓ Branch 2 taken 15113 times.
15233 false := List.exist1(parentNodes,isNodeContracted,alreadyMerged);// dont consider nodes that are already merged in this iteration
3525 //print("with the parents "+stringDelimitList(List.map(parentNodes,intString),", ")+"\n");
3526 15113 parentCommCosts := List.map2(parentNodes, getCommCostBetweenNodes, iNodeIdx, iGraphData);
3527 15113 COMMUNICATION(requiredTime=highestCommCost) := getHighestCommCost(parentCommCosts, COMMUNICATION(0,{},{},{},{},-1,-1.0));
3528 15113 parentExeCosts := List.map1(parentNodes, getExeCost, iGraphData);
3529 15113 (_,sumParentExeCosts) := List.fold(parentExeCosts, addUpExeCosts, (0,0.0));
3530
2/2
✓ Branch 1 taken 10802 times.
✓ Branch 2 taken 4311 times.
15113 (_,highestParentExeCost) := getHighestExecCost(parentExeCosts, (0,0.0));
3531
2/2
✓ Branch 0 taken 10802 times.
✓ Branch 1 taken 4311 times.
15113 true := realGt(realAdd(highestCommCost, highestParentExeCost), sumParentExeCosts);
3532 //We can only merge the parents if they have no other child-nodes -> check this
3533 4311 parentChilds := List.map1(parentNodes, Array.getIndexFirst, iGraph);
3534
2/2
✓ Branch 2 taken 4214 times.
✓ Branch 3 taken 97 times.
4311 true := listEmpty(List.removeOnTrue(1, intEq, List.map(parentChilds, listLength)));
3535 mergeNodeList := iNodeIdx :: parentNodes;
3536 //print("HpcOmTaskGraph.mergeParentNodes0: mergeNodeList " + stringDelimitList(List.map(mergeNodeList,intString), ", ") + "\n");
3537 //print("HpcOmTaskGraph.mergeParentNodes0: Merging " + intString(iNodeIdx) + " with " + stringDelimitList(List.map(parentNodes,intString), ", ") + "\n");
3538 tmpMergedNodes := mergeNodeList :: iMergedNodes;
3539 97 List.map_0(mergeNodeList,function Array.updateIndexFirst(inValue=-1,inArray=alreadyMerged));
3540 97 tmpMergedNodes := mergeParentNodes0(iGraph,iGraphT,iGraphData,contractedTasksIn,alreadyMerged,iNodeIdx+1,tmpMergedNodes);
3541 then tmpMergedNodes;
3542 case _
3543 algorithm
3544
2/2
✓ Branch 0 taken 65 times.
✓ Branch 1 taken 15213 times.
15278 true := intLe(iNodeIdx, arrayLength(iGraphT)); //Current index is in range
3545 15213 tmpMergedNodes := mergeParentNodes0(iGraph,iGraphT,iGraphData,contractedTasksIn,alreadyMerged,iNodeIdx+1,iMergedNodes);
3546 then tmpMergedNodes;
3547 else iMergedNodes;
3548 end matchcontinue;
3549 end mergeParentNodes0;
3550
3551 protected function mergeSinkNodes "author: mflehmig
3552 Nodes that have a only one dependency to the very same node are merged with this 'sink' node."
3553 input TaskGraph graphIn;
3554 input TaskGraph graphTIn;
3555 input TaskGraphMeta graphDataIn;
3556 input array<Integer> contractedTasksIn;
3557 output TaskGraph graphOut;
3558 output TaskGraph graphTOut;
3559 output TaskGraphMeta graphDataOut;
3560 output array<Integer> contractedTasksOut;
3561 output Boolean changed;
3562 protected
3563 array<Integer> alreadyMerged;
3564 list<list<Integer>> mergedNodes;
3565 algorithm
3566 ✗ alreadyMerged := arrayCreate(arrayLength(graphIn),0);
3567 ✗ mergedNodes := mergeParentNodes0(graphIn, graphTIn, graphDataIn, contractedTasksIn, alreadyMerged, 1, {});
3568 //print("mergedNodes "+stringDelimitList(List.map(mergedNodes,intLstString),"\n")+"\n");
3569 ✗ (graphOut,graphTOut,graphDataOut,contractedTasksOut) := contractNodesInGraph(mergedNodes,graphIn,graphTIn,graphDataIn,contractedTasksIn);
3570 ✗ changed := not listEmpty(mergedNodes);
3571 //print("contractedTasksOut "+stringDelimitList(List.mapArray(contractedTasksOut, intString),"\n")+"\n");
3572 end mergeSinkNodes;
3573
3574 public function markSystemComponents "author: marcusw
3575 Mark all components that are part of the given Task Graph in the target task graph meta with (ComponentInfo OR iComponentInfo)."
3576 input TaskGraph iTaskGraph;
3577 input TaskGraphMeta iTaskGraphMeta;
3578 input tuple<Boolean, Boolean, Boolean> iComponentMarks; //<isPartOfODESystem, isPartOfZeroFuncSystem, isRemovedComponent>
3579 input TaskGraphMeta iTargetTaskGraphMeta;
3580 output TaskGraphMeta oTargetTaskGraphMeta;
3581 protected
3582 array<list<Integer>> odeInComps;
3583 list<Integer> nodeComps;
3584 Integer nodeIdx, compIdx;
3585 array<list<Integer>> inComps;
3586 array<tuple<Integer,Integer,Integer>> varCompMapping;
3587 array<tuple<Integer,Integer,Integer>> eqCompMapping;
3588 array<list<Integer>> compParamMapping;
3589 array<String> compNames;
3590 array<String> compDescs;
3591 array<tuple<Integer,Real>> exeCosts;
3592 array<Communications> commCosts;
3593 array<Integer> nodeMark;
3594 array<ComponentInfo> compInformations;
3595 ComponentInfo componentInformation, iComponentInformation;
3596 algorithm
3597 16 iComponentInformation := COMPONENTINFO(Util.tuple31(iComponentMarks), Util.tuple32(iComponentMarks), Util.tuple33(iComponentMarks));
3598 16 TASKGRAPHMETA(inComps=odeInComps) := iTaskGraphMeta;
3599
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 TASKGRAPHMETA(inComps,varCompMapping,eqCompMapping,compParamMapping,compNames,compDescs,exeCosts,commCosts,nodeMark,compInformations) := iTargetTaskGraphMeta;
3600
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 5 times.
1164 for nodeIdx in 1:arrayLength(iTaskGraph) loop
3601 1148 nodeComps := arrayGet(odeInComps, nodeIdx);
3602 //print("markSystemComponents: Marking components '" + stringDelimitList(List.map(nodeComps, intString), ",") + "'\n");
3603
2/2
✓ Branch 0 taken 1148 times.
✓ Branch 1 taken 1148 times.
2296 for compIdx in nodeComps loop
3604 1148 componentInformation := combineComponentInformations(arrayGet(compInformations, compIdx), iComponentInformation);
3605 1148 compInformations := arrayUpdate(compInformations, compIdx, componentInformation);
3606 end for;
3607 end for;
3608 16 oTargetTaskGraphMeta := TASKGRAPHMETA(inComps,varCompMapping,eqCompMapping,compParamMapping,compNames,compDescs,exeCosts,commCosts,nodeMark,compInformations);
3609 end markSystemComponents;
3610
3611 protected function combineComponentInformations "author: marcusw
3612 Return all boolean values of iComponentInfo OR iComponentInfo2"
3613 input ComponentInfo iComponentInfo;
3614 input ComponentInfo iComponentInfo2;
3615 output ComponentInfo oComponentInfo;
3616 protected
3617 Boolean isPartOfODESystem, iIsPartOfODESystem;
3618 Boolean isPartOfZeroFuncSystem, iisPartOfZeroFuncSystem;
3619 Boolean isRemovedComponent, iIsRemovedComponent;
3620 algorithm
3621 8075 COMPONENTINFO(isPartOfODESystem, isPartOfZeroFuncSystem, isRemovedComponent) := iComponentInfo;
3622 8075 COMPONENTINFO(iIsPartOfODESystem, iisPartOfZeroFuncSystem, iIsRemovedComponent) := iComponentInfo2;
3623
6/6
✓ Branch 0 taken 8063 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 5795 times.
✓ Branch 3 taken 2280 times.
✓ Branch 4 taken 7897 times.
✓ Branch 5 taken 178 times.
29830 oComponentInfo := COMPONENTINFO(boolOr(isPartOfODESystem, iIsPartOfODESystem), boolOr(isPartOfZeroFuncSystem, iisPartOfZeroFuncSystem), boolOr(isRemovedComponent, iIsRemovedComponent));
3624 end combineComponentInformations;
3625
3626 protected function addUpExeCosts
3627 input tuple<Integer,Real> iExeCost1;
3628 input tuple<Integer,Real> iExeCost2;
3629 output tuple<Integer,Real> oExeCost;
3630 protected
3631 Real ex1,ex2;
3632 Integer op1,op2;
3633 algorithm
3634 17587 (op1,ex1) := iExeCost1;
3635 17587 (op2,ex2) := iExeCost2;
3636 17587 oExeCost := ((op1+op2,realAdd(ex1,ex2)));
3637 end addUpExeCosts;
3638
3639 public function getExeCostReqCycles "author: waurich
3640 Gets the execution cost of the node in cycles."
3641 input Integer iNodeIdx;
3642 input TaskGraphMeta iGraphData;
3643 output Real oExeCost;
3644 algorithm
3645 179 oExeCost := Util.tuple22(getExeCost(iNodeIdx, iGraphData));
3646 end getExeCostReqCycles;
3647
3648 public function getExeCost "author: marcusw
3649 Gets the execution cost of the node."
3650 input Integer iNodeIdx;
3651 input TaskGraphMeta iGraphData;
3652 output tuple<Integer,Real> oExeCost;
3653 protected
3654 Integer comp, opCount, opCount1;
3655 Real exeCost, exeCost1;
3656 array<list<Integer>> inComps;
3657 list<Integer> comps;
3658 array<tuple<Integer, Real>> exeCosts;
3659 algorithm
3660 19951 TASKGRAPHMETA(inComps=inComps, exeCosts=exeCosts) := iGraphData;
3661 exeCost := 0.0;
3662 opCount := 0;
3663 19951 comps := arrayGet(inComps, iNodeIdx);
3664
2/2
✓ Branch 0 taken 26800 times.
✓ Branch 1 taken 19951 times.
46751 for comp in comps loop
3665 26800 (opCount1,exeCost1) := arrayGet(exeCosts, comp);
3666 26800 opCount := intAdd(opCount, opCount1);
3667 26800 exeCost := realAdd(exeCost, exeCost1);
3668 end for;
3669 19951 oExeCost := ((opCount,exeCost));
3670 end getExeCost;
3671
3672 protected function getHighestExecCost "author: marcusw
3673 Get the communication with highest costs out of the given list."
3674 input list<tuple<Integer, Real>> iExecCosts;
3675 input tuple<Integer, Real> iHighestTuple;
3676 output tuple<Integer, Real> oHighestTuple;
3677 protected
3678 Real highestCost, currentCost;
3679 tuple<Integer, Real> head;
3680 list<tuple<Integer, Real>> rest;
3681 algorithm
3682 oHighestTuple := match(iExecCosts, iHighestTuple)
3683 case((head as (_,currentCost))::rest, (_,highestCost)) guard realGt(currentCost, highestCost)
3684 8764 then getHighestExecCost(rest, head);
3685 case(_::rest, _)
3686 8823 then getHighestExecCost(rest, iHighestTuple);
3687 else iHighestTuple;
3688 end match;
3689 end getHighestExecCost;
3690
3691 public function contractNodesInGraph "author: marcusw
3692 Contract the nodes given in the list to one node. Take care that the lists are disjoint."
3693 input list<list<Integer>> iContractNodes; //a list containing a list with nodes you want to merge
3694 input TaskGraph iTaskGraph;
3695 input TaskGraph iTaskGraphT;
3696 input TaskGraphMeta iTaskGraphMeta;
3697 input array<Integer> iContractedTasks;
3698 output TaskGraph oTaskGraph;
3699 output TaskGraph oTaskGraphT;
3700 output TaskGraphMeta oTaskGraphMeta;
3701 output array<Integer> oContractedTasks;
3702 protected
3703 //TaskGraph Meta
3704 array<list<Integer>> inComps;
3705 TaskGraph tmpTaskGraph = iTaskGraph;
3706 TaskGraph tmpTaskGraphT = iTaskGraphT;
3707 array<Integer> tmpContractedTasks = iContractedTasks;
3708 Integer nodeListHeadIdx, negNodeListHeadIdx, nodeIdx, parentChild, parentChildContractionValue;
3709 list<Integer> nodeListRestIdc, nodeCompIdc, headCompIdc;
3710 list<Integer> parentNodeChildList, parentNodeChildListNew; //all children of a parent node
3711 list<Integer> outgoingEdges, incomingEdges; //edges from 'nodeListHeadIdx' to all nodes that are not part of the merging cluster
3712 array<Integer> nodeMarks;
3713 array<Integer> nodeMarksT;
3714 list<Integer> iNodeList, nodeList;
3715 list<Integer> childNodes; //all nodes that are at least "below" one node of the node list
3716 list<Integer> parentNodes; //all nodes that have at least one node of the merged cluster as children
3717 algorithm
3718
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 130 times.
130 TASKGRAPHMETA(inComps=inComps) := iTaskGraphMeta;
3719
3720 130 nodeMarks := arrayCreate(arrayLength(iTaskGraph), 0);
3721 130 nodeMarksT := arrayCreate(arrayLength(iTaskGraph), 0);
3722
3723 //print("contractNodesInGraph: Merging " + intString(listLength(iContractNodes)) + " groups of nodes at once\n");
3724
2/2
✓ Branch 0 taken 1056 times.
✓ Branch 1 taken 130 times.
1186 for iNodeList in iContractNodes loop
3725 //print("contractNodesInGraph: Merging nodes in " + stringDelimitList(List.map(iNodeList,intString),",") + "\n");
3726 //print("Task Graph:");
3727 //printTaskGraph(tmpTaskGraph);
3728 //print("Transposed Task Graph:");
3729 //printTaskGraph(tmpTaskGraphT);
3730 nodeList := {};
3731
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1056 times.
1056 nodeListHeadIdx::nodeListRestIdc := iNodeList; //O(1)
3732
2/2
✓ Branch 0 taken 2210 times.
✓ Branch 1 taken 1056 times.
3266 for nodeIdx in iNodeList loop
3733 2210 nodeIdx := getRealTaskIdxOfTask(nodeIdx, tmpContractedTasks); //O(1)
3734 //Detect already merged groups
3735
1/2
✓ Branch 1 taken 2210 times.
✗ Branch 2 not taken.
2210 if(intNe(arrayGet(nodeMarks, nodeIdx), nodeListHeadIdx)) then
3736 2210 nodeMarks := arrayUpdate(nodeMarks, nodeIdx, nodeListHeadIdx);
3737 nodeList := nodeIdx::nodeList;
3738 end if;
3739 end for;
3740
3741 //print("contractNodesInGraph: Merging nodes " + stringDelimitList(List.map(nodeList,intString),",") + "\n");
3742
3743 //Get the index of the merged node
3744
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1056 times.
1056 nodeListHeadIdx::nodeListRestIdc := nodeList; //O(1)
3745 1056 nodeListHeadIdx := getRealTaskIdxOfTask(nodeListHeadIdx, tmpContractedTasks);
3746
3747 1056 negNodeListHeadIdx := intMul(-1, nodeListHeadIdx);
3748
3749 //Set the nodeMark-value of all 'nodeListRestIdc' to nodeListHeadIdx and set the contracted value O(n)
3750
2/2
✓ Branch 1 taken 1154 times.
✓ Branch 2 taken 1056 times.
2210 for nodeIdx in nodeListRestIdc loop
3751 1154 nodeMarks := arrayUpdate(nodeMarks, nodeIdx, nodeListHeadIdx);
3752 1154 nodeMarksT := arrayUpdate(nodeMarksT, nodeIdx, nodeListHeadIdx);
3753 1154 tmpContractedTasks := arrayUpdate(tmpContractedTasks, nodeIdx, negNodeListHeadIdx);
3754 end for;
3755
3756 //Set the mark of all nodeList-nodes to 'nodeListHeadIdx'
3757 1056 nodeMarks := arrayUpdate(nodeMarks, nodeListHeadIdx, nodeListHeadIdx);
3758 1056 nodeMarksT := arrayUpdate(nodeMarksT, nodeListHeadIdx, nodeListHeadIdx);
3759 //print("contractNodesInGraph: Node marks " + stringDelimitList(List.mapArray(nodeMarks,intString),",") + "\n");
3760 //print("contractNodesInGraph: Contracted nodes " + stringDelimitList(List.mapArray(tmpContractedTasks,intString),",") + "\n");
3761
3762 //Set the mark of all nodes connected with 'nodeListHeadIdx' to 'nodeListHeadIdx'
3763 1056 outgoingEdges := arrayGet(tmpTaskGraph, nodeListHeadIdx);
3764 1056 outgoingEdges := List.deleteMemberOnTrue(negNodeListHeadIdx,outgoingEdges,function checkIfNodeBelongsToCluster(iContractedTasks=tmpContractedTasks)); //O(n)
3765
3766 1056 incomingEdges := arrayGet(tmpTaskGraphT, nodeListHeadIdx);
3767
3768 1056 List.map_0(outgoingEdges, function Array.updateIndexFirst(inValue=nodeListHeadIdx, inArray=nodeMarks)); //O(n)
3769 1056 List.map_0(incomingEdges, function Array.updateIndexFirst(inValue=nodeListHeadIdx, inArray=nodeMarksT)); //O(n)
3770
3771 //print("contractNodesInGraph: Node marks " + stringDelimitList(List.mapArray(nodeMarks,intString),",") + "\n");
3772
3773 //Get all child-nodes (parent-nodes) of the nodes in the node-list and remove the nodes that are part of the node-list itself or connected to 'nodeListHeadIdx'
3774 1056 childNodes := List.flatten(List.map(nodeListRestIdc,function getContractedNodeChildren(iRefValue=nodeListHeadIdx,iTaskGraph=tmpTaskGraph,iContractedTasks=tmpContractedTasks,iNodeMarks=nodeMarks))); //O(e)
3775 1056 parentNodes := List.flatten(List.map(nodeList,function getContractedNodeChildren(iRefValue=nodeListHeadIdx,iTaskGraph=iTaskGraphT,iContractedTasks=tmpContractedTasks,iNodeMarks=nodeMarks))); //O(e)
3776
3777 //print("contractNodesInGraph: Child nodes " + stringDelimitList(List.map(childNodes,intString),",") + "\n");
3778 //print("contractNodesInGraph: Parent nodes " + stringDelimitList(List.map(parentNodes,intString),",") + "\n");
3779
3780 1056 headCompIdc := arrayGet(inComps, nodeListHeadIdx);
3781 //Delete all outgoing edges of 'nodeListRestIdc' O(n)
3782
2/2
✓ Branch 0 taken 1154 times.
✓ Branch 1 taken 1056 times.
2210 for nodeIdx in nodeListRestIdc loop
3783 1154 tmpTaskGraph := arrayUpdate(tmpTaskGraph, nodeIdx, {});
3784 1154 tmpTaskGraphT := arrayUpdate(tmpTaskGraphT, nodeIdx, {});
3785 1154 nodeCompIdc := arrayGet(inComps, nodeIdx);
3786 1154 inComps := arrayUpdate(inComps, nodeIdx, {});
3787 1154 headCompIdc := List.insertListSorted(headCompIdc, nodeCompIdc, intLt);
3788 end for;
3789
3790 //print("contractNodesInGraph: Components for head-node '" + intString(nodeListHeadIdx) + "' are '{" + stringDelimitList(List.map(headCompIdc, intString), ",") + "}'\n");
3791 1056 arrayUpdate(inComps, nodeListHeadIdx, headCompIdc);
3792
3793 // Update transposed Task Graph
3794 // Handle all parent nodes first
3795
2/2
✓ Branch 0 taken 7054 times.
✓ Branch 1 taken 1056 times.
8110 for nodeIdx in parentNodes loop
3796
2/2
✓ Branch 1 taken 4840 times.
✓ Branch 2 taken 2214 times.
7054 if(intNe(arrayGet(nodeMarksT, nodeIdx), nodeListHeadIdx)) then
3797 incomingEdges := nodeIdx::incomingEdges;
3798 end if;
3799 end for;
3800 //print("contractNodesInGraph: Set incomming edges to '" + stringDelimitList(List.map(incomingEdges, intString), ",") + "'\n");
3801 1056 tmpTaskGraphT := arrayUpdate(tmpTaskGraphT, nodeListHeadIdx, incomingEdges);
3802
3803
2/2
✓ Branch 0 taken 1305 times.
✓ Branch 1 taken 1056 times.
2361 for nodeIdx in childNodes loop
3804 1305 parentNodeChildList := arrayGet(tmpTaskGraphT, nodeIdx);
3805 //print("contractNodesInGraph: Handle parents of node '" + intString(nodeIdx) + "' = '{" + stringDelimitList(List.map(parentNodeChildList, intString), ",") + "}'\n");
3806 //remove all child nodes that are marked with a node mark == 'nodeListHeadidx'
3807 parentNodeChildListNew := {};
3808
2/2
✓ Branch 0 taken 4905 times.
✓ Branch 1 taken 1305 times.
6210 for parentChild in parentNodeChildList loop
3809 4905 parentChildContractionValue := arrayGet(tmpContractedTasks, parentChild);
3810 4905 parentChild := getRealTaskIdxOfTask(parentChild, tmpContractedTasks);
3811
3812 //print("contractNodesInGraph: Children '" + intString(parentChild) + "' has mark '" + intString(arrayGet(nodeMarksT, parentChild)) + "'\n");
3813
3/4
✓ Branch 0 taken 3600 times.
✓ Branch 1 taken 1305 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3600 times.
4905 if(intEq(parentChild, nodeListHeadIdx) or intEq(parentChildContractionValue, negNodeListHeadIdx)) then //Check if child belongs to cluster
3814 //print("contractNodesInGraph: Node '" + intString(nodeIdx) + "' has mark '" + intString(arrayGet(nodeMarksT, nodeIdx)) + "'\n");
3815
1/2
✓ Branch 1 taken 1305 times.
✗ Branch 2 not taken.
1305 if(intNe(arrayGet(nodeMarksT, parentChild), nodeIdx)) then //Check if edge from 'nodeListHeadIdx' to 'nodeIdx' was already added
3816 parentNodeChildListNew := nodeListHeadIdx::parentNodeChildListNew;
3817 1305 arrayUpdate(nodeMarksT, parentChild, nodeIdx);
3818 end if;
3819 else
3820 parentNodeChildListNew := parentChild::parentNodeChildListNew;
3821 end if;
3822 end for;
3823 //print("contractNodesInGraph: Handle parents of node '" + intString(nodeIdx) + "' = '{" + stringDelimitList(List.map(parentNodeChildListNew, intString), ",") + "}'\n");
3824 1305 tmpTaskGraphT := arrayUpdate(tmpTaskGraphT, nodeIdx, parentNodeChildListNew);
3825 end for;
3826
3827 1056 outgoingEdges := listAppend(outgoingEdges, childNodes) annotation(__OpenModelica_DisableListAppendWarning=true);
3828
3829 1056 nodeMarks := arrayUpdate(nodeMarks, nodeListHeadIdx, 0);
3830 // Update Task Graph
3831
2/2
✓ Branch 0 taken 7054 times.
✓ Branch 1 taken 1056 times.
8110 for nodeIdx in parentNodes loop
3832 7054 parentNodeChildList := arrayGet(tmpTaskGraph, nodeIdx);
3833 //print("contractNodesInGraph: Handle children of node '" + intString(nodeIdx) + "' = '{" + stringDelimitList(List.map(parentNodeChildList, intString), ",") + "}'\n");
3834 //remove all child nodes that are marked with a node mark == 'nodeListHeadidx'
3835 parentNodeChildListNew := {};
3836
2/2
✓ Branch 0 taken 21912 times.
✓ Branch 1 taken 7054 times.
28966 for parentChild in parentNodeChildList loop
3837 21912 parentChildContractionValue := arrayGet(tmpContractedTasks, parentChild);
3838 21912 parentChild := getRealTaskIdxOfTask(parentChild, tmpContractedTasks);
3839
3840 //print("contractNodesInGraph: Children '" + intString(parentChild) + "' has mark '" + intString(arrayGet(nodeMarks, parentChild)) + "'\n");
3841
3/4
✓ Branch 0 taken 14396 times.
✓ Branch 1 taken 7516 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 14396 times.
21912 if(intEq(parentChild, nodeListHeadIdx) or intEq(parentChildContractionValue, negNodeListHeadIdx)) then //Check if child belongs to cluster
3842 //print("contractNodesInGraph: Node '" + intString(nodeIdx) + "' has mark '" + intString(arrayGet(nodeMarks, nodeIdx)) + "'\n");
3843
2/2
✓ Branch 1 taken 7054 times.
✓ Branch 2 taken 462 times.
7516 if(intNe(arrayGet(nodeMarks, parentChild), nodeIdx)) then //Check if edge from 'nodeListHeadIdx' to 'nodeIdx' was already added
3844 parentNodeChildListNew := nodeListHeadIdx::parentNodeChildListNew;
3845 7054 arrayUpdate(nodeMarks, parentChild, nodeIdx);
3846 end if;
3847 else
3848 parentNodeChildListNew := parentChild::parentNodeChildListNew;
3849 end if;
3850 end for;
3851 //print("contractNodesInGraph: Handle children of node '" + intString(nodeIdx) + "' = '{" + stringDelimitList(List.map(parentNodeChildListNew, intString), ",") + "}'\n");
3852 7054 tmpTaskGraph := arrayUpdate(tmpTaskGraph, nodeIdx, parentNodeChildListNew);
3853 end for;
3854 //print("contractNodesInGraph: finished cluster\n");
3855 //print("contractNodesInGraph: Outgoing edges " + stringDelimitList(List.map(outgoingEdges,intString),",") + "\n");
3856 1056 tmpTaskGraph := arrayUpdate(tmpTaskGraph, nodeListHeadIdx, outgoingEdges);
3857 end for;
3858 oTaskGraph := tmpTaskGraph;
3859 oTaskGraphT := tmpTaskGraphT;
3860 oTaskGraphMeta := iTaskGraphMeta;
3861 oContractedTasks := iContractedTasks;
3862 end contractNodesInGraph;
3863
3864 protected function checkIfNodeBelongsToCluster "author: marcusw
3865 Returns true if the node mark of the given iNodeIdx is equal to the reference value."
3866 input Integer iNegativeRefValue; //the negative reference-value to check
3867 input Integer iNodeIdx;
3868 input array<Integer> iContractedTasks;
3869 output Boolean oIsNodePartOfCluster;
3870 algorithm
3871 //print("checkIfNodeBelongsToCluster: Checking iNodeIdx '" + intString(iNodeIdx) + "' is equal to reference value '" + intString(iRefValue) + "'\n");
3872 1056 oIsNodePartOfCluster := intEq(iNegativeRefValue, arrayGet(iContractedTasks, iNodeIdx));
3873 end checkIfNodeBelongsToCluster;
3874
3875 protected function getContractedNodeChildren "author: marcusw
3876 Get the child-nodes of the given parent task. If a children has a negativ contracted mark, the real node is searched."
3877 input Integer iParentTask;
3878 input Integer iRefValue;
3879 input TaskGraph iTaskGraph;
3880 input array<Integer> iContractedTasks;
3881 input array<Integer> iNodeMarks;
3882 output list<Integer> oChildTasks;
3883 protected
3884 Integer task, taskMark;
3885 list<Integer> childTasks;
3886 list<Integer> resultTasks = {};
3887 algorithm
3888 3364 childTasks := arrayGet(iTaskGraph, iParentTask);
3889 //print("getContractedNodeChildren: iParentTask '" + intString(iParentTask) + "' with children " + stringDelimitList(List.map(resultTasks, intString), ",") + "\n");
3890
2/2
✓ Branch 0 taken 10198 times.
✓ Branch 1 taken 3364 times.
13562 for task in childTasks loop
3891 10198 task := getRealTaskIdxOfTask(task, iContractedTasks);
3892
3893 10198 taskMark := arrayGet(iNodeMarks, task);
3894
3/4
✓ Branch 0 taken 8359 times.
✓ Branch 1 taken 1839 times.
✓ Branch 2 taken 8359 times.
✗ Branch 3 not taken.
10198 if(boolAnd(intNe(taskMark, iRefValue), intNe(task, iRefValue))) then
3895 resultTasks:=task::resultTasks;
3896 8359 arrayUpdate(iNodeMarks, task, iRefValue);
3897 else
3898 //print("getContractedNodeChildren: Skipping task " + intString(task) + " with taskMark " + intString(taskMark) + " and reference value " + intString(iRefValue) + "\n");
3899 end if;
3900 end for;
3901 //print("getContractedNodeChildren: iParentTask '" + intString(iParentTask) + "' with children " + stringDelimitList(List.map(resultTasks, intString), ",") + "\n");
3902 oChildTasks := resultTasks;
3903 end getContractedNodeChildren;
3904
3905 protected function getRealTaskIdxOfTask "author: marcusw
3906 Get the real task-index of the given task. If the task has a negativ contracted mark, the real node is searched."
3907 input Integer iTaskIdx;
3908 input array<Integer> iContractedTasks;
3909 output Integer oTaskIdx;
3910 protected
3911 Integer contractionMark;
3912 algorithm
3913 47558 contractionMark := arrayGet(iContractedTasks, iTaskIdx);
3914 //print("getRealTaskIdxOfTask: Task-Index='" + intString(iTaskIdx) + "' with contraction mark='" + intString(contractionMark) + "'\n");
3915
2/2
✓ Branch 0 taken 7277 times.
✓ Branch 1 taken 40281 times.
47558 if(intLt(contractionMark, 0)) then
3916 7277 oTaskIdx := getRealTaskIdxOfTask(intMul(contractionMark, -1), iContractedTasks);
3917 else
3918 oTaskIdx := iTaskIdx;
3919 end if;
3920 end getRealTaskIdxOfTask;
3921
3922 public function setInCompsInMeta "author: Waurich TUD 2014-11
3923 Replaces the inComps in the taskGraphMeta."
3924 input array<list<Integer>> inComps;
3925 input TaskGraphMeta metaIn;
3926 output TaskGraphMeta metaOut;
3927 protected
3928 array<tuple<Integer, Integer, Integer>> varCompMapping;
3929 array<tuple<Integer,Integer,Integer>> eqCompMapping;
3930 array<String> compNames;
3931 array<String> compDescs;
3932 array<tuple<Integer,Real>> exeCosts;
3933 array<Communications> commCosts;
3934 array<list<Integer>> compParamMapping;
3935 array<Integer> nodeMark;
3936 array<ComponentInfo> compInformations;
3937 algorithm
3938 32 TASKGRAPHMETA(varCompMapping=varCompMapping, eqCompMapping=eqCompMapping, compParamMapping=compParamMapping, compNames=compNames, compDescs=compDescs, exeCosts=exeCosts, commCosts=commCosts, nodeMark=nodeMark, compInformations=compInformations) := metaIn;
3939 32 metaOut := TASKGRAPHMETA(inComps,varCompMapping,eqCompMapping,compParamMapping,compNames,compDescs,exeCosts,commCosts,nodeMark,compInformations);
3940 end setInCompsInMeta;
3941
3942 protected function updateInCompsInfo "author: Waurich TUD 2014-11
3943 Updates the inComps for the contracted nodes."
3944 input Integer contrNode;
3945 input list<Integer> removedNodes;
3946 input array<list<Integer>> inComps;
3947 protected
3948 list<Integer> comps, contrComps;
3949 algorithm
3950 //print("contrNode "+intString(contrNode)+"\n");
3951 ✗ comps := arrayGet(inComps,contrNode);
3952 ✗ contrComps := List.flatten(List.map(removedNodes,function Array.getIndexFirst(inArray=inComps)));
3953 ✗ comps := List.unique(listAppend(contrComps,comps));
3954 //print("comps "+stringDelimitList(List.map(comps,intString),", ")+"\n");
3955 ✗ arrayUpdate(inComps,contrNode,comps);
3956 end updateInCompsInfo;
3957
3958 public function filterContractedNodes "author: Waurich TUD 2014-11
3959 Selects only Nodes that are not already contracted."
3960 input list<Integer> nodesIn;
3961 input array<Integer> contrNodes;
3962 output list<Integer> nodesOut;
3963 algorithm
3964 37362 nodesOut := List.filterOnFalse(nodesIn,function isNodeContracted(iContrNodes=contrNodes));
3965 end filterContractedNodes;
3966
3967 public function filterNonContractedNodes "author: Waurich TUD 2014-11
3968 Selects only Nodes that are already contracted."
3969 input list<Integer> nodesIn;
3970 input array<Integer> contrNodes;
3971 output list<Integer> nodesOut;
3972 algorithm
3973 24 nodesOut := List.filterOnTrue(nodesIn,function isNodeContracted(iContrNodes=contrNodes));
3974 end filterNonContractedNodes;
3975
3976 public function isNodeContracted "
3977 Ouputs true if the given node is already contracted"
3978 input Integer iNode;
3979 input array<Integer> iContrNodes;
3980 output Boolean oIsContracted;
3981 algorithm
3982
1/2
✓ Branch 0 taken 78652 times.
✗ Branch 1 not taken.
78652 if intLe(iNode,arrayLength(iContrNodes)) then
3983 78652 oIsContracted := intLt(arrayGet(iContrNodes,iNode),0);
3984 else oIsContracted := false;
3985 end if;
3986 end isNodeContracted;
3987
3988 protected function contractNodesInGraph1 "author: Waurich TUD 2013-07
3989 Function to contract the nodes given in the list to one node, without deleting the rows in the adjacencyLst."
3990 input list<Integer> contractNodes;
3991 input TaskGraph graphIn;
3992 output TaskGraph graphOut;
3993 protected
3994 TaskGraph graphInT;
3995 Integer endNode;
3996 Integer startNode;
3997 list<Integer> deleteEntries;
3998 list<Integer> startNodeChildren;
3999 list<Integer> endChildren;
4000 list<Integer> deleteNodesParents; //all parents of deleted nodes
4001 TaskGraph graphTmp;
4002 algorithm
4003 //This function contracts all nodes into the startNode
4004 ✗ graphInT := AdjacencyMatrix.transposeAdjacencyMatrix(graphIn,arrayLength(graphIn));
4005 //print("HpcOmTaskGraph.contractNodesInGraph1 contractNodes: " + stringDelimitList(List.map(contractNodes,intString),",") + "\n");
4006 //print("HpcOmTaskGraph.contractNodesInGraph1 startNode: " + intString(List.last(contractNodes)) + "\n");
4007 ✗ startNode := List.last(contractNodes);
4008 ✗ deleteEntries := List.deleteMemberOnTrue(startNode,contractNodes,intEq); //all nodes which should be deleted
4009 //print("HpcOmTaskGraph.contractNodesInGraph1 deleteEntries: " + stringDelimitList(List.map(deleteEntries,intString),",") + "\n");
4010 ✗ deleteNodesParents := List.flatten(List.map1(deleteEntries, Array.getIndexFirst, graphInT));
4011 //print("HpcOmTaskGraph.contractNodesInGraph1 deleteNodesParents: " + stringDelimitList(List.map(deleteNodesParents,intString),",") + "\n");
4012 ✗ deleteNodesParents := List.sortedUnique(List.sort(deleteNodesParents, intGt),intEq);
4013 ✗ deleteNodesParents := List.setDifferenceOnTrue(deleteNodesParents, contractNodes, intEq);
4014 //print("HpcOmTaskGraph.contractNodesInGraph1 deleteNodesParents: " + stringDelimitList(List.map(deleteNodesParents,intString),",") + "\n");
4015 ✗ endNode := listHead(contractNodes);
4016 ✗ endChildren := arrayGet(graphIn,endNode); //all child-nodes of the end node
4017 //print("HpcOmTaskGraph.contractNodesInGraph1 endChildren: " + stringDelimitList(List.map(endChildren,intString),",") + "\n");
4018 ✗ startNodeChildren := arrayGet(graphIn, startNode);
4019 //print("HpcOmTaskGraph.contractNodesInGraph1 startNodeChildren_pre: " + stringDelimitList(List.map(startNodeChildren,intString),",") + "\n");
4020 ✗ startNodeChildren := List.setDifferenceOnTrue(startNodeChildren, deleteEntries, intEq);
4021 ✗ graphTmp := arrayUpdate(graphIn, startNode, startNodeChildren);
4022 //print("HpcOmTaskGraph.contractNodesInGraph1 startNodeChildren_post: " + stringDelimitList(List.map(startNodeChildren,intString),",") + "\n");
4023 ✗ graphTmp := List.fold2(deleteNodesParents, contractNodesInGraph2, deleteEntries, startNode, graphTmp);
4024 //print("HpcOmTaskGraph.contractNodesInGraph1 startnode: " + intString(startNode) + " endChildren: " + stringDelimitList(List.map(endChildren,intString),",") + "\n");
4025 ✗ graphTmp := arrayUpdate(graphIn,startNode,endChildren);
4026 graphOut := graphTmp;
4027 end contractNodesInGraph1;
4028
4029 protected function contractNodesInGraph2
4030 input Integer iParentNode;
4031 input list<Integer> iDeletedNodes;
4032 input Integer iNewNodeIdx;
4033 input TaskGraph iGraph;
4034 output TaskGraph oGraph;
4035 protected
4036 list<Integer> adjLstEntry;
4037 algorithm
4038 ✗ adjLstEntry := arrayGet(iGraph,iParentNode);
4039 //print("contractNodesInGraph2 ParentNode: " + intString(iParentNode) + " adjLstEntry_Pre: " + stringDelimitList(List.map(adjLstEntry,intString),",") + "\n");
4040 ✗ adjLstEntry := List.setDifferenceOnTrue(adjLstEntry, iDeletedNodes, intEq);
4041 adjLstEntry := iNewNodeIdx :: adjLstEntry;
4042 ✗ adjLstEntry := List.sortedUnique(List.sort(adjLstEntry, intGt),intEq);
4043 //print("contractNodesInGraph2 ParentNode: " + intString(iParentNode) + " adjLstEntry_Post: " + stringDelimitList(List.map(adjLstEntry,intString),",") + "\n");
4044 ✗ oGraph := arrayUpdate(iGraph, iParentNode, adjLstEntry);
4045 end contractNodesInGraph2;
4046
4047 protected function compareListLengthOnTrue "author: Waurich TUD 2013-07
4048 Is true if given list has a length of inValue, otherwise false."
4049 input Integer inValue;
4050 input list<Integer> inLst;
4051 output Boolean equalLength;
4052 algorithm
4053 961 equalLength := intEq(inValue,listLength(inLst));
4054 end compareListLengthOnTrue;
4055
4056 protected function getMergedSystemData "author: Waurich TUD 2013-07
4057 Updates the taskgraphmetadata for the merged system."
4058 input TaskGraphMeta graphDataIn;
4059 input list<list<Integer>> contractNodes;
4060 output TaskGraphMeta graphDataOut;
4061 protected
4062 array<list<Integer>> inComps;
4063 array<tuple<Integer, Integer, Integer>> varCompMapping;
4064 array<tuple<Integer,Integer,Integer>> eqCompMapping;
4065 array<list<Integer>> compParamMapping;
4066 array<String> compNames;
4067 array<String> compDescs;
4068 array<tuple<Integer,Real>> exeCosts;
4069 array<Communications> commCosts;
4070 array<Integer> nodeMark;
4071 array<ComponentInfo> compInformations;
4072 algorithm
4073 ✗ TASKGRAPHMETA(inComps=inComps, varCompMapping=varCompMapping, eqCompMapping=eqCompMapping, compParamMapping=compParamMapping, compNames=compNames, compDescs=compDescs, exeCosts=exeCosts, commCosts=commCosts, nodeMark=nodeMark, compInformations=compInformations) := graphDataIn;
4074 ✗ inComps := updateInCompsForMerging(inComps,contractNodes);
4075 ✗ compNames := List.fold2(List.intRange(arrayLength(compNames)),updateCompNamesForMerging,inComps,nodeMark,compNames);
4076 ✗ graphDataOut := TASKGRAPHMETA(inComps,varCompMapping,eqCompMapping,compParamMapping,compNames,compDescs,exeCosts,commCosts,nodeMark,compInformations);
4077 end getMergedSystemData;
4078
4079 protected function updateCompNamesForMerging "author: Waurich TUD 2013-07
4080 Updates the compNames with the merging information."
4081 input Integer compIdx;
4082 input array<list<Integer>> inComps;
4083 input array<Integer> nodeMark;
4084 input array<String> compNamesIn;
4085 output array<String> compNamesOut;
4086 algorithm
4087 compNamesOut := matchcontinue compNamesIn
4088 local
4089 Integer unionNode;
4090 list<Integer> mergedComps;
4091 array<String> compNamesTmp;
4092 String compName;
4093 case _
4094 algorithm
4095 ✗ true := compIdx <= arrayLength(compNamesIn);
4096 ✗ unionNode := getCompInComps(compIdx,1,inComps,nodeMark); //TODO: that seems to be expensive, can we iterate over the nodes instead of the components?
4097 ✗ true := unionNode <> -1;
4098 ✗ mergedComps := arrayGet(inComps,unionNode);
4099 ✗ true := listLength(mergedComps) == 1;
4100 then
4101 compNamesIn;
4102 case _
4103 algorithm
4104 ✗ true := compIdx <= arrayLength(compNamesIn);
4105 ✗ unionNode := getCompInComps(compIdx,1,inComps,nodeMark);
4106 ✗ true := unionNode <> -1;
4107 ✗ mergedComps := arrayGet(inComps,unionNode);
4108 ✗ false := listLength(mergedComps) == 1;
4109 ✗ compName := "contracted comps "+stringDelimitList(List.map(mergedComps,intString),",");
4110 ✗ compNamesTmp := arrayUpdate(compNamesIn,compIdx,compName);
4111 then
4112 compNamesTmp;
4113 case _
4114 algorithm
4115 ✗ true := compIdx <= arrayLength(compNamesIn);
4116 ✗ unionNode := getCompInComps(compIdx,1,inComps,nodeMark);
4117 ✗ true := unionNode == -1;
4118 then
4119 compNamesIn;
4120 else
4121 algorithm
4122 ✗ print("updateCompNamesForMerging failed!\n");
4123 ✗ then fail();
4124 end matchcontinue;
4125 end updateCompNamesForMerging;
4126
4127 protected function updateInCompsForMerging "author: waurich TUD 2013-07
4128 Updates the inComps with the merging information."
4129 input array<list<Integer>> inCompsIn;
4130 input list<list<Integer>> mergedPaths; //nodes to contract
4131 output array<list<Integer>> inCompsOut;
4132 protected
4133 list<list<Integer>> inCompsLst;
4134 list<Integer> deleteNodes;
4135 list<Integer> startNodes;
4136 algorithm
4137 //mergedPaths := List.map1(mergedPaths,List.sort,intGt);
4138 ✗ startNodes := List.map(mergedPaths,List.last);
4139 //startNodes := List.map(mergedPaths,listHead);
4140 ✗ (_,deleteNodes,_) := List.intersection1OnTrue(List.flatten(mergedPaths),startNodes,intEq);
4141 //deleteNodes := List.map(mergedPaths,List.rest);
4142 ✗ inCompsLst := arrayList(inCompsIn);
4143 ✗ inCompsLst := List.fold2(List.intRange(arrayLength(inCompsIn)),updateInComps1,(startNodes,deleteNodes,mergedPaths),inCompsIn,inCompsLst);
4144 ✗ inCompsLst := List.removeOnTrue({},equalLists,inCompsLst);
4145 //inCompsLst := List.map3(inCompsLst,getCompInComps,1,inComps,arrayCreate(arrayLength(inComps),0));
4146 ✗ inCompsOut := listArray(inCompsLst);
4147 end updateInCompsForMerging;
4148
4149 protected function updateInComps1 "author: waurich TUD 2013-07
4150 Folding function for updateInComps."
4151 input Integer nodeIdx;
4152 input tuple<list<Integer>,list<Integer>,list<list<Integer>>> mergeInfo; //<%startNodes,deleteNodes,mergedPaths%>
4153 input array<list<Integer>> primInComps;
4154 input list<list<Integer>> inCompLstIn;
4155 output list<list<Integer>> inCompLstOut;
4156 algorithm
4157 inCompLstOut := matchcontinue inCompLstIn
4158 local
4159 Integer mergeGroupIdx;
4160 list<Integer> inComps;
4161 list<Integer> mergedSet, mergedNodes;
4162 list<Integer> startNodes;
4163 list<list<Integer>> mergedPaths;
4164 list<list<Integer>> inCompLstTmp;
4165 case _
4166 // the given node is a startNode
4167 algorithm
4168 ✗ (startNodes,_,mergedPaths) := mergeInfo;
4169 //print("updateInComps1 startNodes:" + stringDelimitList(List.map(startNodes,intString),",") + "\n");
4170 //print("updateInComps1 deleteNodes:" + stringDelimitList(List.map(deleteNodes,intString),",") + "\n");
4171 //print("updateInComps1 first mergedPath:" + stringDelimitList(List.map(listHead(mergedPaths),intString),",") + "\n");
4172 ✗ inComps := listGet(inCompLstIn,nodeIdx);
4173 //print("updateInComps1 inComps:" + stringDelimitList(List.map(inComps,intString),",") + "\n");
4174 //true = listLength(inComps) == 1;
4175 ✗ listGet(inComps,1);
4176 //print("updateInComps1 inComp:" + intString(inComp) + "\n");
4177 ✗ true := List.isMemberOnTrue(nodeIdx,startNodes,intEq);
4178 ✗ mergeGroupIdx := List.position(nodeIdx,startNodes);
4179 ✗ mergedNodes := listGet(mergedPaths,mergeGroupIdx);
4180 //print("updateInComps1 mergedNodes:" + stringDelimitList(List.map(mergedNodes,intString),",") + "\n");
4181 ✗ mergedSet := List.flatten(List.map1(mergedNodes,Array.getIndexFirst,primInComps));
4182 //print("updateInComps1 mergedSet:" + stringDelimitList(List.map(mergedSet,intString),",") + "\n");
4183 ✗ inCompLstTmp := List.fold(mergedNodes, updateInComps2, inCompLstIn);
4184 ✗ inCompLstTmp := List.replaceAt(mergedSet, nodeIdx, inCompLstTmp);
4185 then
4186 inCompLstTmp;
4187 else inCompLstIn;
4188 end matchcontinue;
4189 end updateInComps1;
4190
4191 protected function updateInComps2 "
4192 Replaces the entry <%iNodeIdx - 1%> in inCompListIn with an empty set."
4193 input Integer iNodeIdx;
4194 input list<list<Integer>> inCompLstIn;
4195 output list<list<Integer>> inCompLstOut;
4196 algorithm
4197 ✗ inCompLstOut := List.replaceAt({}, iNodeIdx, inCompLstIn);
4198 end updateInComps2;
4199
4200 public function equalLists "author: Waurich TUD 2013-07
4201 compares two lists and sets true if they are equal."
4202 input list<Integer> inList1;
4203 input list<Integer> inList2;
4204 output Boolean outIsEqual;
4205 algorithm
4206 outIsEqual := match(inList1, inList2)
4207 local
4208 Integer e1, e2;
4209 list<Integer> rest1, rest2;
4210
4211 case ({}, {}) then true;
4212 case ({}, _) then false;
4213 case (_, {}) then false;
4214 case (e1 :: rest1, e2 :: rest2) guard intEq(e1,e2)
4215 3068 then
4216 equalLists(rest1, rest2);
4217 else false;
4218 end match;
4219 end equalLists;
4220
4221 protected function findOneChildParents "author: Waurich TUD 2013-07
4222 Fold function to find nodes or paths in the taskGraph with just one successor per node.
4223 Extended: adds endnodes without successor as well."
4224 input list<Integer> allNodes;
4225 input TaskGraph graphIn;
4226 input list<Integer> doNotMerge; // these nodes cannot be chosen
4227 input list<list<Integer>> lstIn;
4228 input Integer inPath; // the current nodeIndex in a path of only cildren. if no path then 0.
4229 input array<Integer> contrNodes;
4230 output list<list<Integer>> lstOut;
4231 algorithm
4232 lstOut := matchcontinue allNodes
4233 local
4234 Integer child;
4235 Integer head;
4236 list<Integer> nodeChildren;
4237 list<Integer> parents;
4238 list<Integer> pathLst;
4239 list<Integer> rest;
4240 list<list<Integer>> lstTmp;
4241 case {}
4242 //checked all nodes
4243 algorithm
4244 then
4245 lstIn;
4246 case head::rest
4247 //check new node that has several children
4248 algorithm
4249
2/2
✓ Branch 0 taken 1057 times.
✓ Branch 1 taken 14614 times.
15671 true := intEq(inPath,0);
4250 14614 nodeChildren := arrayGet(graphIn,head);
4251 14614 nodeChildren := filterContractedNodes(nodeChildren,contrNodes);
4252 //print("findOneChildParents: " + stringDelimitList(List.map(nodeChildren, intString), ",") + "\n");
4253
2/2
✓ Branch 1 taken 961 times.
✓ Branch 2 taken 13653 times.
14614 false := listLength(nodeChildren) == 1;
4254 //print("findOneChildParents case 1 for task " + intString(head) + ". Node children: " + stringDelimitList(List.map(nodeChildren, intString), ",") + "\n");
4255 13653 lstTmp := findOneChildParents(rest,graphIn,doNotMerge,lstIn,0,contrNodes);
4256 then
4257 lstTmp;
4258 case head::rest
4259 //check new node that is excluded
4260 algorithm
4261
2/2
✓ Branch 0 taken 1057 times.
✓ Branch 1 taken 961 times.
2018 true := intEq(inPath,0);
4262
1/2
✓ Branch 1 taken 961 times.
✗ Branch 2 not taken.
961 true := listMember(head,doNotMerge);
4263 //print("findOneChildParents case 2 for task " + intString(head) + "\n");
4264 ✗ lstTmp := findOneChildParents(rest,graphIn,doNotMerge,lstIn,0,contrNodes);
4265 then
4266 lstTmp;
4267 case head::rest
4268 // check new node that has only one child but this is excluded
4269 algorithm
4270
2/2
✓ Branch 0 taken 1057 times.
✓ Branch 1 taken 961 times.
2018 true := intEq(inPath,0);
4271 961 nodeChildren := arrayGet(graphIn,head);
4272 961 nodeChildren := filterContractedNodes(nodeChildren,contrNodes);
4273
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 961 times.
961 true := listLength(nodeChildren) == 1;
4274 961 child := listGet(nodeChildren,1);
4275
1/2
✓ Branch 1 taken 961 times.
✗ Branch 2 not taken.
961 true := listMember(child,doNotMerge);
4276 //print("findOneChildParents case 3 for task " + intString(head) + "\n");
4277 ✗ lstTmp := findOneChildParents(rest,graphIn,doNotMerge,lstIn,child,contrNodes);
4278 then
4279 lstTmp;
4280 case head::rest
4281 // check new node that has only one child , follow the path
4282 algorithm
4283
2/2
✓ Branch 0 taken 1057 times.
✓ Branch 1 taken 961 times.
2018 true := intEq(inPath,0);
4284 961 nodeChildren := arrayGet(graphIn,head);
4285 961 nodeChildren := filterContractedNodes(nodeChildren,contrNodes);
4286
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 961 times.
961 true := listLength(nodeChildren) == 1;
4287 961 child := listGet(nodeChildren,1);
4288 lstTmp := {head}::lstIn;
4289 961 lstTmp := findOneChildParents(rest,graphIn,doNotMerge,lstTmp,child,contrNodes);
4290 //print("findOneChildParents case 4 for task " + intString(head) + ". Node children: " + stringDelimitList(List.map(nodeChildren, intString), ",") + "\n");
4291 then
4292 lstTmp;
4293 case _::_
4294 // dont follow because the path contains excluded nodes
4295 algorithm
4296
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1057 times.
1057 false := intEq(inPath,0);
4297
1/2
✓ Branch 1 taken 1057 times.
✗ Branch 2 not taken.
1057 true := listMember(inPath,doNotMerge);
4298 //print("findOneChildParents case 5 for task " + intString(head) + "\n");
4299 ✗ lstTmp := findOneChildParents(allNodes,graphIn,doNotMerge,lstIn,0,contrNodes);
4300 then
4301 lstTmp;
4302 case _::rest
4303 // follow path and check that there is still only one child with just one parent
4304 algorithm
4305
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1057 times.
1057 false := intEq(inPath,0);
4306 1057 nodeChildren := arrayGet(graphIn,inPath);
4307 1057 nodeChildren := filterContractedNodes(nodeChildren,contrNodes);
4308 1057 parents := getParentNodes(inPath,graphIn);
4309 1057 parents := filterContractedNodes(parents,contrNodes);
4310
5/6
✓ Branch 1 taken 496 times.
✓ Branch 2 taken 561 times.
✓ Branch 3 taken 496 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 98 times.
✓ Branch 7 taken 398 times.
1057 true := listLength(nodeChildren) == 1 and not listEmpty(nodeChildren) and listLength(parents) == 1;
4311 //print("findOneChildParents case 6 for task " + intString(head) + "\n");
4312 98 child := listGet(nodeChildren,1);
4313 98 pathLst := listHead(lstIn);
4314 pathLst := inPath::pathLst;
4315 98 lstTmp := List.replaceAt(pathLst, 1, lstIn);
4316 98 rest := List.deleteMemberOnTrue(inPath,allNodes,intEq);
4317 98 lstTmp := findOneChildParents(rest,graphIn,doNotMerge,lstTmp,child,contrNodes);
4318 then
4319 lstTmp;
4320 case _::rest
4321 // follow path and check that there is an endnode without successor that will be added to the path
4322 algorithm
4323
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 959 times.
959 false := intEq(inPath,0);
4324 959 nodeChildren := arrayGet(graphIn,inPath);
4325 959 nodeChildren := filterContractedNodes(nodeChildren,contrNodes);
4326 959 parents := getParentNodes(inPath,graphIn);
4327 959 parents := filterContractedNodes(parents,contrNodes);
4328 //true = listEmpty(nodeChildren) and listLength(parents) == 1;
4329 //print("findOneChildParents case 7 for task " + intString(head) + "\n");
4330 959 pathLst := listHead(lstIn);
4331 pathLst := inPath::pathLst;
4332 959 lstTmp := List.replaceAt(pathLst, 1, lstIn);
4333 959 rest := List.deleteMemberOnTrue(inPath,allNodes,intEq);
4334 959 lstTmp := findOneChildParents(rest,graphIn,doNotMerge,lstTmp,0,contrNodes);
4335 then
4336 lstTmp;
4337 /* case((head::rest),_,_,_,_,_)
4338 // follow path and check that there are more children or a child with more parents. end path before this node
4339 algorithm
4340 false = intEq(inPath,0);
4341 print("findOneChildParents case 8 for task " + intString(head) + "\n");
4342 lstTmp = findOneChildParents(allNodes,graphIn,doNotMerge,lstIn,0,contrNodes);
4343 then
4344 lstTmp; */
4345 else
4346 algorithm
4347 ✗ print("findOneChildParents failed\n");
4348 ✗ then
4349 fail();
4350 end matchcontinue;
4351 end findOneChildParents;
4352
4353 protected function getParentNodes "author: Waurich TUD 2013-07
4354 Function to get the parent nodes of a node."
4355 input Integer nodeIdx;
4356 input TaskGraph graphIn;
4357 output list<Integer> parentNodes;
4358 protected
4359 TaskGraph graphInT;
4360 algorithm
4361 2016 graphInT := AdjacencyMatrix.transposeAdjacencyMatrix(graphIn,arrayLength(graphIn));
4362 2016 parentNodes := arrayGet(graphInT, nodeIdx);
4363 end getParentNodes;
4364
4365 protected function checkParentNode "author: Waurich TUD 2013-06
4366 Fold function to check the first element in the child path for the number of parent nodes. If the number
4367 is 1 the parent will be added."
4368 input Integer lstIdx;
4369 input TaskGraph graphIn;
4370 input list<list<Integer>> lstIn;
4371 output list<list<Integer>> lstOut;
4372 algorithm
4373 lstOut := matchcontinue lstIn
4374 local
4375 list<Integer> childLst;
4376 Integer child;
4377 Integer parent;
4378 list<Integer> parents;
4379 list<list<Integer>> lstTmp;
4380 case _
4381 algorithm
4382 ✗ childLst := listGet(lstIn,lstIdx);
4383 ✗ child := List.last(childLst);
4384 ✗ parents := getParentNodes(child,graphIn);
4385 ✗ true := intEq(listLength(parents),1);
4386 ✗ parent := listGet(parents,1);
4387 ✗ childLst := listReverse(childLst);
4388 childLst := parent :: childLst;
4389 ✗ childLst := listReverse(childLst);
4390 ✗ lstTmp := List.replaceAt(childLst, lstIdx, lstIn);
4391 then
4392 lstTmp;
4393 case _
4394 algorithm
4395 ✗ childLst := listGet(lstIn,lstIdx);
4396 ✗ child := List.last(childLst);
4397 ✗ parents := getParentNodes(child,graphIn);
4398 ✗ false := intEq(listLength(parents),1);
4399 then
4400 lstIn;
4401 end matchcontinue;
4402 end checkParentNode;
4403
4404
4405 //-----------------------------
4406 // Functions to generate costs
4407 //-----------------------------
4408
4409 public function createCosts "author: marcusw
4410 Updates the given TaskGraphMeta-Structure with the calculated execution und communication costs."
4411 input BackendDAE.BackendDAE iDae;
4412 input String iBenchFilePrefix; //The prefix of the xml or json profiling-file
4413 input array<Integer> iSimEqCompMapping; //Map each simEq to the scc
4414 input TaskGraphMeta iTaskGraphMeta;
4415 output TaskGraphMeta oTaskGraphMeta;
4416 protected
4417 array<BackendDAE.EqSystem> compMapping;
4418 array<tuple<BackendDAE.EqSystem,Integer>> compMapping_withIdx;
4419 BackendDAE.Shared shared;
4420 BackendDAE.StrongComponents comps;
4421 tuple<Integer,Integer> reqTimeCom;
4422 //These mappings are for simEqSystems
4423 list<tuple<Integer,Integer,Real>> reqTimeOpLstSimCode; //<simEqIdx,numberOfCalcs,calcTimeSum>
4424 array<tuple<Integer,Real>> reqTimeOpSimCode; //<simEqIdx,calcTime>
4425 TaskGraphMeta tmpTaskGraphMeta;
4426 array<Real> reqTimeOp; //Calculation time for each scc
4427 array<list<Integer>> inComps;
4428 array<Communications> commCosts;
4429 algorithm
4430 oTaskGraphMeta := matchcontinue(iDae, iTaskGraphMeta)
4431 case(BackendDAE.DAE(shared=shared), TASKGRAPHMETA(inComps=inComps, commCosts=commCosts))
4432 algorithm
4433 8 (comps,compMapping_withIdx) := getSystemComponents(iDae);
4434 8 compMapping := Array.map(compMapping_withIdx, Util.tuple21);
4435 8 (_,reqTimeCom) := HpcOmBenchmark.benchSystem();
4436 8 reqTimeOpLstSimCode := HpcOmBenchmark.readCalcTimesFromFile(iBenchFilePrefix);
4437 //print("createCosts: read files\n");
4438 //print("createCosts: read values: " + stringDelimitList(List.map(List.map(reqTimeOpLstSimCode, Util.tuple33), realString), ",") + "\n");
4439 ✗ reqTimeOpSimCode := arrayCreate(listLength(reqTimeOpLstSimCode),(-1,-1.0));
4440 ✗ reqTimeOpSimCode := List.fold(reqTimeOpLstSimCode, createCosts1, reqTimeOpSimCode);
4441 //print("createCosts: reqTimeOpSimCode created\n");
4442 ✗ reqTimeOp := arrayCreate(listLength(comps),-1.0);
4443 ✗ reqTimeOp := convertSimEqToSccCosts(reqTimeOpSimCode, iSimEqCompMapping, reqTimeOp);
4444 //print("createCosts: scc costs converted\n");
4445 ✗ commCosts := createCommCosts(commCosts,1,reqTimeCom);
4446 ✗ (_, tmpTaskGraphMeta) := Array.fold(inComps, function createCosts0(iComps_shared = (comps,shared), iCompMapping = compMapping, reqTimeOp = reqTimeOp, reqTimeCom = reqTimeCom), (1,iTaskGraphMeta));
4447 then tmpTaskGraphMeta;
4448 else
4449 algorithm
4450 8 tmpTaskGraphMeta := estimateCosts(iDae,iTaskGraphMeta);
4451 8 print("Warning: The costs have been estimated. Maybe " + iBenchFilePrefix + "-file is missing.\n");
4452 then tmpTaskGraphMeta;
4453 end matchcontinue;
4454 end createCosts;
4455
4456 protected function estimateCosts "author: Waurich TUD 09-2013
4457 Estimates the communication and execution costs very roughly so hpcom can work with something when there is no prof_xml file."
4458 input BackendDAE.BackendDAE daeIn;
4459 input TaskGraphMeta taskGraphMetaIn;
4460 output TaskGraphMeta taskGraphMetaOut;
4461 protected
4462 array<list<Integer>> inComps;
4463 array<tuple<Integer, Integer, Integer>> varCompMapping;
4464 array<tuple<Integer,Integer,Integer>> eqCompMapping;
4465 array<String> compNames;
4466 array<String> compDescs;
4467 array<tuple<Integer,Real>> exeCosts;
4468 array<Communications> commCosts;
4469 array<Integer> nodeMark;
4470 list<Integer> comNumLst;
4471 list<tuple<Integer,Real>> exeCostsLst;
4472 BackendDAE.EqSystems eqSystems;
4473 BackendDAE.Shared shared;
4474 list<BackendDAE.StrongComponents> compsLst;
4475 array<list<Integer>> compParamMapping;
4476 array<ComponentInfo> compInformations;
4477 Integer compIdx;
4478 algorithm
4479 8 BackendDAE.DAE(eqs=eqSystems, shared=shared) := daeIn;
4480 8 compsLst := List.map(eqSystems,BackendDAEUtil.getStrongComponents);
4481 8 comNumLst := List.map(compsLst,listLength);
4482 8 TASKGRAPHMETA(inComps=inComps,varCompMapping=varCompMapping,eqCompMapping=eqCompMapping,compParamMapping=compParamMapping,compNames=compNames,compDescs=compDescs,exeCosts=exeCosts,commCosts=commCosts,nodeMark=nodeMark,compInformations=compInformations) := taskGraphMetaIn;
4483 // get the communication costs
4484 8 commCosts := getCommCostsOnly(commCosts);
4485 // estimate the executionCosts
4486 8 exeCostsLst := List.flatten(List.map3(List.intRange(listLength(compsLst)),estimateCosts0,compsLst,eqSystems,shared));
4487
4488 //overwrite old values
4489 compIdx := 1;
4490
2/2
✓ Branch 1 taken 1531 times.
✓ Branch 2 taken 8 times.
1539 for exeCost in exeCostsLst loop
4491 1531 arrayUpdate(exeCosts, compIdx, exeCost);
4492 1531 compIdx := compIdx + 1;
4493 end for;
4494
4495 8 taskGraphMetaOut := TASKGRAPHMETA(inComps,varCompMapping,eqCompMapping,compParamMapping,compNames,compDescs,exeCosts,commCosts,nodeMark,compInformations);
4496 end estimateCosts;
4497
4498 protected function estimateCosts0 "author: Waurich TUD 2013-09
4499 Estimates the execution costs for StrongComponents."
4500 input Integer systIdx;
4501 input list<BackendDAE.StrongComponents> compsLstIn;
4502 input BackendDAE.EqSystems eqSystemsIn;
4503 input BackendDAE.Shared sharedIn;
4504 output list<tuple<Integer,Real>> exeCostsOut;
4505 protected
4506 BackendDAE.StrongComponents comps;
4507 BackendDAE.EqSystem eqSys;
4508 list<BackendDAE.CompInfo> compsInfos;
4509 algorithm
4510 17 comps := listGet(compsLstIn,systIdx);
4511 17 eqSys := listGet(eqSystemsIn,systIdx);
4512 17 compsInfos := listReverse(BackendDAEOptimize.countOperationstraverseComps(comps,eqSys,sharedIn,{}));
4513 17 exeCostsOut := List.map(compsInfos,calculateCosts);
4514 end estimateCosts0;
4515
4516 public function calculateCosts "author: Waurich TUD 2014-12
4517 Calculates the estimated costs for a compInfo. This has been benchmarked using the Cpp runtime."
4518 input BackendDAE.CompInfo compInfo;
4519 output tuple<Integer,Real> exeCost;
4520 algorithm
4521 exeCost := match compInfo
4522 local
4523 Integer numAdds,numMul,numDiv,numOth,numTrig,numRel,numLog,numFuncs, costs, ops,ops1, offset,size;
4524 Real allOpCosts,tornCosts,otherCosts,dens;
4525 BackendDAE.StrongComponent comp;
4526 BackendDAE.CompInfo torn, other;
4527
4528 case BackendDAE.COUNTER(comp=comp,numAdds=numAdds,numMul=numMul,numDiv=numDiv,numTrig=numTrig,numRelations=numRel,numLog=numLog,numOth=numOth,funcCalls=numFuncs)
4529 algorithm
4530 1562 ops := numAdds+numMul+numOth+numTrig+numRel+numLog;
4531
2/2
✓ Branch 1 taken 134 times.
✓ Branch 2 taken 1428 times.
1562 if BackendDAEUtil.isSingleEquationComp(comp) then offset:=35;
4532 elseif BackendDAEUtil.isWhenComp(comp) then offset:=113;
4533 elseif BackendDAEUtil.isArrayComp(comp) then offset:=100;
4534 else offset := 0;
4535 end if;
4536 1562 costs := offset + 12*numAdds + 32*numMul + 37*numDiv + 236*numTrig + 2*numRel + 4*numLog + 110*numOth + 375*numFuncs;
4537 1562 then (ops,intReal(costs));
4538
4539 case BackendDAE.SYSTEM(size=size,density=dens)// density is in procent
4540 algorithm
4541 22 allOpCosts := realMul(0.049, realPow(realMul(intReal(size),(realAdd(1.0,realMul(dens,19.0)))),3.0));
4542 22 then (1, allOpCosts);
4543
4544 case BackendDAE.TORN_ANALYSE(tornEqs=torn,otherEqs=other,tornSize=size)
4545 algorithm
4546 53 (ops,tornCosts) := calculateCosts(torn);
4547 53 (ops1,otherCosts) := calculateCosts(other);
4548 53 allOpCosts := realAdd(realAdd(3000.0,realMul(7.62,realPow(intReal(size),3.0))),realAdd(realMul(2.0,tornCosts),realMul(1.4,otherCosts)));
4549 53 then (ops+ops1,allOpCosts);
4550
4551 case BackendDAE.NO_COMP(numAdds=numAdds,numMul=numMul,numDiv=numDiv,numTrig=numTrig,numRelations=numRel,numLog=numLog,numOth=numOth,funcCalls=numFuncs)
4552 algorithm
4553 12 ops := numAdds+numMul+numOth+numTrig+numRel+numLog;
4554 offset := 50; // this was just estimated, not benchmarked
4555 12 costs := offset + 12*numAdds + 32*numMul + 37*numDiv + 236*numTrig + 2*numRel + 4*numLog + 110*numOth + 375*numFuncs;
4556 12 then (ops,intReal(costs));
4557
4558 else
4559 algorithm
4560 ✗ print("calculate costs failed!\n");
4561 then (-1,-1.0);
4562 end match;
4563 end calculateCosts;
4564
4565 public function copyCosts "author: marcusw
4566 Copy the execution costs from the source to the target task graph data. The communcation costs are recalculated."
4567 input TaskGraphMeta iSourceTaskGraphData;
4568 input TaskGraphMeta iTargetTaskGraphData;
4569 output TaskGraphMeta oTaskGraphData;
4570 protected
4571 array<list<Integer>> inCompsSource, inCompsTarget;
4572 array<tuple<Integer, Real>> exeCostsSource, exeCostsTarget;
4573 Integer compIdx;
4574 array<Communications> commCostsTarget;
4575 tuple<Integer, Integer> reqTimeCom;
4576 algorithm
4577 8 TASKGRAPHMETA(inComps=inCompsSource, exeCosts=exeCostsSource) := iSourceTaskGraphData;
4578
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 TASKGRAPHMETA(inComps=inCompsTarget, exeCosts=exeCostsTarget, commCosts=commCostsTarget) := iTargetTaskGraphData;
4579
4580 compIdx := intMin(arrayLength(exeCostsSource), arrayLength(exeCostsTarget));
4581
2/2
✓ Branch 0 taken 1531 times.
✓ Branch 1 taken 8 times.
1539 while(intGt(compIdx, 0)) loop
4582 1531 exeCostsTarget := arrayUpdate(exeCostsTarget, compIdx, arrayGet(exeCostsSource, compIdx));
4583 1531 compIdx := compIdx - 1;
4584 end while;
4585
4586 8 (_,reqTimeCom) := HpcOmBenchmark.benchSystem();
4587 8 commCostsTarget := createCommCosts(commCostsTarget,1,reqTimeCom);
4588 oTaskGraphData := iTargetTaskGraphData;
4589 end copyCosts;
4590
4591 protected function getCommCostsOnly "author: Waurich TUD 2013-09
4592 Function to compute the communication costs."
4593 input array<Communications> commCostsIn;
4594 output array<Communications> commCostsOut;
4595 protected
4596 tuple<Integer,Integer> reqTimeCom;
4597 algorithm
4598 8 (_,reqTimeCom) := HpcOmBenchmark.benchSystem();
4599 8 commCostsOut := createCommCosts(commCostsIn,1,reqTimeCom);
4600 end getCommCostsOnly;
4601
4602 protected function checkForExecutionCosts "
4603 Checks if every entry in the array exeCosts is > 0.0"
4604 input TaskGraphMeta dataIn;
4605 output Boolean isFine;
4606 protected
4607 array<list<Integer>> inComps;
4608 array<tuple<Integer,Real>> exeCosts;
4609 algorithm
4610 8 TASKGRAPHMETA(inComps=inComps, exeCosts=exeCosts) := dataIn;
4611 8 isFine := checkForExecutionCosts1(exeCosts,inComps,1);
4612
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 if not isFine then
4613 ✗ print("There are execution costs with value 0.0!\n");
4614 end if;
4615 end checkForExecutionCosts;
4616
4617 protected function checkForExecutionCosts1 "author: Waurich TUD 2013-09
4618 Checks if for the given comps the relation 'executionCost > 0.0' is true."
4619 input array<tuple<Integer,Real>> exeCosts;
4620 input array<list<Integer>> inComps;
4621 input Integer nodeIdx;
4622 output Boolean bOut;
4623 algorithm
4624 bOut := matchcontinue nodeIdx
4625 local
4626 Boolean b, isZero;
4627 list<Integer> comps;
4628 case _
4629 algorithm
4630
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 1059 times.
1067 true := arrayLength(inComps) >= nodeIdx;
4631 1059 comps := arrayGet(inComps,nodeIdx);
4632 1059 isZero := List.fold1(comps,checkTpl2ForZero,exeCosts,false);
4633
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1059 times.
1059 false := isZero;
4634 1059 b := checkForExecutionCosts1(exeCosts,inComps,nodeIdx+1);
4635 then
4636 b;
4637 case _
4638 algorithm
4639
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 true := arrayLength(inComps) < nodeIdx;
4640 then
4641 true;
4642 else
4643 algorithm
4644 then
4645 false;
4646 end matchcontinue;
4647 end checkForExecutionCosts1;
4648
4649 protected function checkTpl2ForZero "author: Waurich TUD 2013-09
4650 Folding function for checkForExecutionCosts1."
4651 input Integer comp;
4652 input array<tuple<Integer,Real>> exeCosts;
4653 input Boolean bIn;
4654 output Boolean bOut;
4655 protected
4656 Boolean b;
4657 Real value;
4658 tuple<Integer,Real> tpl;
4659 algorithm
4660 1059 tpl := arrayGet(exeCosts,comp);
4661 1059 (_,value) := tpl;
4662 1059 b := realEq(value,0.0);
4663 1059 bOut := b or bIn;
4664 end checkTpl2ForZero;
4665
4666 public function convertNodeListToEdgeTuples "author: marcusw
4667 Convert a list of nodes to a list of edge tuples. E.g. {1,2,5} -> {(1,2),(2,5)}"
4668 input list<Integer> iNodeList;
4669 output list<tuple<Integer,Integer>> oEdgeList;
4670 algorithm
4671 80 oEdgeList := convertNodeListToEdgeTuples0(iNodeList, listLength(iNodeList), {});
4672 end convertNodeListToEdgeTuples;
4673
4674 protected function convertNodeListToEdgeTuples0 "author: marcusw
4675 Helper function of convertNodeListToEdgeTuples."
4676 input list<Integer> iNodeList;
4677 input Integer iNodeIdx;
4678 input list<tuple<Integer,Integer>> iEdgeList;
4679 output list<tuple<Integer,Integer>> oEdgeList;
4680 protected
4681 list<tuple<Integer,Integer>> tmpEdgeList;
4682 Integer elem, preElem;
4683 algorithm
4684 oEdgeList := matchcontinue iEdgeList
4685 case tmpEdgeList
4686 algorithm
4687
2/2
✓ Branch 0 taken 80 times.
✓ Branch 1 taken 370 times.
450 true := intGt(iNodeIdx, 1);
4688 370 elem := listGet(iNodeList, iNodeIdx);
4689 370 preElem := listGet(iNodeList, iNodeIdx-1);
4690 370 tmpEdgeList := (preElem,elem)::tmpEdgeList;
4691 370 tmpEdgeList := convertNodeListToEdgeTuples0(iNodeList, iNodeIdx-1,tmpEdgeList);
4692 then tmpEdgeList;
4693 else iEdgeList;
4694 end matchcontinue;
4695 end convertNodeListToEdgeTuples0;
4696
4697 protected function convertSimEqToSccCosts
4698 input array<tuple<Integer,Real>> iReqTimeOpSimCode;
4699 input array<Integer> iSimeqCompMapping; //Map each simEq to the scc
4700 input array<Real> iReqTimeOp;
4701 output array<Real> oReqTimeOp; //calcTime for each scc
4702 algorithm
4703 ✗ (_,oReqTimeOp) := Array.fold(iReqTimeOpSimCode, function convertSimEqToSccCosts1(iSimeqCompMapping = iSimeqCompMapping), (1,iReqTimeOp));
4704 end convertSimEqToSccCosts;
4705
4706 protected function convertSimEqToSccCosts1
4707 input tuple<Integer,Real> iReqTimeOpSimCode;
4708 input array<Integer> iSimeqCompMapping; //Map each simEq to the scc
4709 input tuple<Integer,array<Real>> iReqTimeOp;
4710 output tuple<Integer,array<Real>> oReqTimeOp; //<simEqIdx, calcTime>
4711 protected
4712 Integer simEqCalcCount, simEqIdx;
4713 Real simEqCalcTime, realSimEqCalcCount;
4714 array<Real> reqTime;
4715 algorithm
4716 oReqTimeOp := matchcontinue(iReqTimeOpSimCode, iReqTimeOp)
4717 case((simEqCalcCount, simEqCalcTime), (simEqIdx,reqTime))
4718 algorithm
4719 ✗ realSimEqCalcCount := intReal(simEqCalcCount);
4720 ✗ true := realNe(realSimEqCalcCount,0.0);
4721 ✗ reqTime := convertSimEqToSccCosts2(reqTime, realDiv(simEqCalcTime,realSimEqCalcCount), simEqIdx, iSimeqCompMapping);
4722 ✗ then ((simEqIdx+1,reqTime));
4723 case((simEqCalcCount, simEqCalcTime), (simEqIdx,reqTime))
4724 algorithm
4725 realSimEqCalcCount := intReal(simEqCalcCount);
4726 ✗ reqTime := convertSimEqToSccCosts2(reqTime, 0.0, simEqIdx, iSimeqCompMapping);
4727 ✗ then ((simEqIdx+1,reqTime));
4728 else
4729 algorithm
4730 ✗ print("convertSimEqToSccCosts1 failed!\n");
4731 ✗ then fail();
4732 end matchcontinue;
4733 end convertSimEqToSccCosts1;
4734
4735 protected function convertSimEqToSccCosts2
4736 input array<Real> iReqTime;
4737 input Real iSimEqCalcTime;
4738 input Integer iSimEqIdx;
4739 input array<Integer> iSimeqCompMapping; //Map each simEq to the scc
4740 output array<Real> oReqTime;
4741 protected
4742 array<Real> reqTime;
4743 Integer sccIdx;
4744 algorithm
4745 oReqTime := matchcontinue iReqTime
4746 case reqTime
4747 algorithm
4748 ✗ true := intGe(arrayLength(iSimeqCompMapping),iSimEqIdx);
4749 ✗ sccIdx := arrayGet(iSimeqCompMapping, iSimEqIdx);
4750 ✗ true := intGt(sccIdx,0);
4751 ✗ reqTime := arrayUpdate(reqTime,sccIdx, iSimEqCalcTime);
4752 //print("convertSimEqToSccCosts2 sccIdx: " + intString(sccIdx) + " simEqIdx: " + intString(iSimEqIdx) + " reqTime: " + realString(iSimEqCalcTime) + "\n");
4753 then
4754 reqTime;
4755 else iReqTime;
4756 end matchcontinue;
4757 end convertSimEqToSccCosts2;
4758
4759 protected function createCosts0 "author: marcusw
4760 Updates the given TaskGraphMeta-Structure with the calculated execution und communication costs."
4761 input list<Integer> iNode; //Node to sccs mapping
4762 input tuple<BackendDAE.StrongComponents,BackendDAE.Shared> iComps_shared;
4763 input array<BackendDAE.EqSystem> iCompMapping;
4764 input array<Real> reqTimeOp;
4765 input tuple<Integer,Integer> reqTimeCom;
4766 input tuple<Integer,TaskGraphMeta> iTaskGraphMeta; //Node number and task graph meta
4767 output tuple<Integer,TaskGraphMeta> oTaskGraphMeta;
4768 protected
4769 array<tuple<Integer, Integer, Integer>> varCompMapping;
4770 array<tuple<Integer,Integer,Integer>> eqCompMapping;
4771 array<list<Integer>> compParamMapping;
4772 array<Integer> nodeRefCount;
4773 array<tuple<Integer,Real>> execCosts;
4774 array<String> compNames, compDescs;
4775 array<list<Integer>> inComps;
4776 array<Communications> commCosts;
4777 Integer nodeNumber;
4778 TaskGraphMeta taskGraphMeta;
4779 array<ComponentInfo> compInformations;
4780 algorithm
4781 ✗ (nodeNumber,taskGraphMeta) := iTaskGraphMeta;
4782 ✗ TASKGRAPHMETA(inComps=inComps,varCompMapping=varCompMapping,eqCompMapping=eqCompMapping,compParamMapping=compParamMapping,compNames=compNames,compDescs=compDescs,exeCosts=execCosts,commCosts=commCosts,nodeMark=nodeRefCount,compInformations=compInformations) := taskGraphMeta;
4783 ✗ createExecCost(iNode, iComps_shared, reqTimeOp, execCosts, iCompMapping, nodeNumber);
4784 ✗ oTaskGraphMeta := ((nodeNumber+1, TASKGRAPHMETA(inComps,varCompMapping,eqCompMapping,compParamMapping,compNames,compDescs,execCosts,commCosts,nodeRefCount,compInformations)));
4785 end createCosts0;
4786
4787 protected function createCosts1 "author: marcusw
4788 Updates the requiredTime-array at the simEq-Position with the given calc-values."
4789 input tuple<Integer,Integer,Real> iTuple; //<simEqIdx,numberOfCalcs,calcTimeSum>
4790 input array<tuple<Integer,Real>> iReqTime;
4791 output array<tuple<Integer,Real>> oReqTime;
4792 protected
4793 array<tuple<Integer,Real>> tmpArray;
4794 Integer simEqIdx,calcTimeCount;
4795 Real calcTime;
4796 algorithm
4797 oReqTime := match(iTuple, iReqTime)
4798 case((0,calcTimeCount,calcTime),_)
4799 then iReqTime;
4800 case((simEqIdx,calcTimeCount,calcTime),tmpArray)
4801 algorithm
4802 //print("createCosts1: simEqIdx: " + intString(simEqIdx) + " calc-time: " + realString(calcTime) + " array-length: " + intString(arrayLength(iReqTime)) + "\n");
4803 ✗ tmpArray := arrayUpdate(iReqTime, simEqIdx,(calcTimeCount,calcTime));
4804 then tmpArray;
4805 end match;
4806 end createCosts1;
4807
4808 protected function createExecCost "author: marcusw
4809 This method fills the iExecCosts array with the execution cost of each scc."
4810 input list<Integer> iNodeSccs; //Sccs of the current node
4811 input tuple<BackendDAE.StrongComponents, BackendDAE.Shared> icomps_shared; //input components and shared
4812 input array<Real> iRequiredTime; //required time for op
4813 input array<tuple<Integer,Real>> iExecCosts; //<numberOfOperations, requiredCycles>
4814 input array<BackendDAE.EqSystem> compMapping;
4815 input Integer iNodeIdx;
4816 algorithm
4817 () := matchcontinue iNodeIdx
4818 local
4819 tuple<Integer,Real> execCost;
4820 case _
4821 algorithm
4822 //print("\tcreateExecCost: sccs: " + stringDelimitList(List.map(iNodeSccs, intString), ",") + "\n");
4823 ✗ execCost := List.fold3(iNodeSccs, createExecCost0, icomps_shared, compMapping, iRequiredTime, (0,0.0));
4824 ✗ arrayUpdate(iExecCosts,iNodeIdx,execCost);
4825 then ();
4826 else ();
4827 end matchcontinue;
4828 end createExecCost;
4829
4830 protected function createExecCost0 "author: marcusw
4831 Helper function for createExecCosts. It calculates the execution costs for the given scc and adds it to the iCosts parameter."
4832 input Integer sccIndex;
4833 input tuple<BackendDAE.StrongComponents, BackendDAE.Shared> icomps_shared; //input system and shared
4834 input array<BackendDAE.EqSystem> compMapping;
4835 input array<Real> iRequiredTime; //required time for op
4836 input tuple<Integer,Real> iCosts; //<numberOfOperations, requiredCycles>
4837 output tuple<Integer,Real> oCosts; //<numberOfOperations, requiredCycles>
4838 protected
4839 Integer iCosts_op;
4840 Real iCosts_cyc;
4841 BackendDAE.StrongComponent comp;
4842 BackendDAE.StrongComponents comps;
4843 BackendDAE.EqSystem syst;
4844 BackendDAE.Shared shared;
4845 Real reqTime;
4846 algorithm
4847 ✗ (comps,shared) := icomps_shared;
4848 ✗ (iCosts_op, iCosts_cyc) := iCosts;
4849 ✗ comp := listGet(comps,sccIndex);
4850 ✗ syst := arrayGet(compMapping,sccIndex);
4851 ✗ reqTime := arrayGet(iRequiredTime, sccIndex);
4852 //print("createExecCost0: Handling scc " + intString(sccIndex) + " with cost " + realString(reqTime) + "\n");
4853 //((costAdd,costMul,costTrig)) := countOperations(comp, syst, shared);
4854 ✗ oCosts := (-100 + iCosts_op, realAdd(iCosts_cyc,reqTime));
4855 end createExecCost0;
4856
4857 protected function createCommCosts "author: marcusw
4858 Extend the given commCost values with a concrete cycle-count."
4859 input array<Communications> iCosts;
4860 input Integer iCurrentIndex;
4861 input tuple<Integer,Integer> iReqTimeCom; //the required cycles to share x-values between two cores. The number of cycles is described as linear function y=m*x+1 (first value is m, second n).
4862 output array<Communications> oCosts;
4863 protected
4864 array<Communications> tmpCosts;
4865 Communications currentCom;
4866 algorithm
4867 oCosts := matchcontinue iCosts
4868 case tmpCosts
4869 algorithm
4870
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 3062 times.
3078 true := intLe(iCurrentIndex, arrayLength(iCosts));
4871 3062 currentCom := arrayGet(tmpCosts,iCurrentIndex);
4872 3062 currentCom := List.map1(currentCom,createCommCosts0,iReqTimeCom);
4873 3062 tmpCosts := arrayUpdate(tmpCosts,iCurrentIndex,currentCom);
4874 3062 tmpCosts := createCommCosts(tmpCosts, iCurrentIndex+1,iReqTimeCom);
4875 then tmpCosts;
4876 else iCosts;
4877 end matchcontinue;
4878 end createCommCosts;
4879
4880 protected function createCommCosts0 "author: marcusw
4881 Helper function for createCommCosts to add the concrete cycle-count to the given communication."
4882 input Communication iComm;
4883 input tuple<Integer,Integer> iReqTimeCom;
4884 output Communication oComm;
4885 protected
4886 Integer childNode,reqTimeM,reqTimeN;
4887 Integer numberOfVars;
4888 Real requiredTime;
4889 list<Integer> integerVars,floatVars,booleanVars,stringVars;
4890 algorithm
4891 4950 COMMUNICATION(numberOfVars=numberOfVars,integerVars=integerVars,floatVars=floatVars,booleanVars=booleanVars,stringVars=stringVars,childNode=childNode,requiredTime=requiredTime) := iComm;
4892 4950 (reqTimeM,reqTimeN) := iReqTimeCom;
4893 4950 requiredTime := intReal(reqTimeN + numberOfVars*reqTimeM);
4894 4950 oComm := COMMUNICATION(numberOfVars,integerVars,floatVars,booleanVars,stringVars,childNode,requiredTime);
4895 end createCommCosts0;
4896
4897
4898 //---------------------------------
4899 // Functions to validate the graph
4900 //---------------------------------
4901
4902 public function validateTaskGraphMeta "author: marcusw
4903 Check if the given TaskGraphMeta-object has a valid structure."
4904 input TaskGraphMeta iMeta;
4905 input BackendDAE.BackendDAE iDae;
4906 output Boolean valid;
4907 algorithm
4908 valid := matchcontinue iDae
4909 local
4910 BackendDAE.StrongComponents systComps, graphComps;
4911 array<BackendDAE.StrongComponent> systCompsArray;
4912 array<tuple<BackendDAE.EqSystem,Integer>> systCompEqSysMapping, graphCompEqSysMapping; //Map each component to the EqSystem
4913 list<tuple<BackendDAE.StrongComponent,Integer>> systCompEqSysMappingIdx, graphCompEqSysMappingIdx;
4914 case _
4915 algorithm
4916 //Check if all StrongComponents are in the graph
4917 8 (systComps,systCompEqSysMapping) := getSystemComponents(iDae);
4918 8 systCompsArray := listArray(systComps);
4919 8 (graphComps,graphCompEqSysMapping) := getGraphComponents(iMeta,systCompsArray,systCompEqSysMapping);
4920 //print("validateTaskGraphMeta: graph components are " + stringDelimitList(List.map(graphComps, BackendDump.printComponent), ",") + "\n");
4921 //print("validateTaskGraphMeta: system components are " + stringDelimitList(List.map(systComps, BackendDump.printComponent), ",") + "\n");
4922 8 (_,_,systCompEqSysMappingIdx) := validateTaskGraphMeta0(systCompEqSysMapping,(1,systComps,{}));
4923 8 (_,_,graphCompEqSysMappingIdx) := validateTaskGraphMeta0(graphCompEqSysMapping,(1,graphComps,{}));
4924
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
8 true := validateComponents(graphCompEqSysMappingIdx,systCompEqSysMappingIdx);
4925 //Check if no component was connected twice
4926
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
8 true := checkForDuplicates(graphCompEqSysMappingIdx);
4927 //Check if compNames,compDescs and exeCosts-array have the right size
4928
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
8 true := checkForExecutionCosts(iMeta);
4929 // Check if every node has an execution cost > 0.
4930 then true;
4931 else false;
4932 end matchcontinue;
4933 end validateTaskGraphMeta;
4934
4935 protected function validateTaskGraphMeta0 "author: marcusw
4936 Implementation of validateTaskGraphMeta."
4937 input array<tuple<BackendDAE.EqSystem,Integer>> iEqSysMapping;
4938 input tuple<Integer,BackendDAE.StrongComponents,list<tuple<BackendDAE.StrongComponent,Integer>>> iCompsTpl; //<current Index, list of remaining strong components, result>
4939 output tuple<Integer,BackendDAE.StrongComponents,list<tuple<BackendDAE.StrongComponent,Integer>>> oCompsTpl;
4940 protected
4941 Integer currentIdx, eqSysIdx;
4942 BackendDAE.StrongComponents rest;
4943 BackendDAE.StrongComponent head;
4944 list<tuple<BackendDAE.StrongComponent,Integer>> iCompEqSysMapping, oCompEqSysMapping;
4945 tuple<Integer,BackendDAE.StrongComponents,list<tuple<BackendDAE.StrongComponent,Integer>>> tmpCompsTpl;
4946 algorithm
4947 oCompsTpl := match iCompsTpl
4948 case (currentIdx,(head::rest),iCompEqSysMapping)
4949 algorithm
4950 3062 (_,eqSysIdx) := arrayGet(iEqSysMapping,currentIdx);
4951 3062 oCompEqSysMapping := (head,eqSysIdx)::iCompEqSysMapping;
4952 //print("validateTaskGraphMeta0: Adding head " + BackendDump.printComponent(head) + " with equation system index " + intString(eqSysIdx) + "\n");
4953 3062 tmpCompsTpl := validateTaskGraphMeta0(iEqSysMapping,(currentIdx+1,rest,oCompEqSysMapping));
4954 then tmpCompsTpl;
4955 else iCompsTpl;
4956 end match;
4957 end validateTaskGraphMeta0;
4958
4959 protected function validateComponents "author: marcusw
4960 Checks if the given component-lists are equal."
4961 input list<tuple<BackendDAE.StrongComponent,Integer>> graphComps; //<component, eqSysIdx>
4962 input list<tuple<BackendDAE.StrongComponent,Integer>> systComps;
4963 output Boolean res;
4964 protected
4965 Boolean isEqual;
4966 Integer i1,i2;
4967 BackendDAE.StrongComponent comp1,comp2;
4968 tuple<BackendDAE.StrongComponent,Integer> tpl1,tpl2;
4969 list<tuple<BackendDAE.StrongComponent,Integer>> sortedGraphComps, sortedSystComps;
4970 algorithm
4971 res := matchcontinue systComps
4972 case _
4973 algorithm
4974 8 sortedGraphComps := List.sort(graphComps,compareComponents);
4975 8 sortedSystComps := List.sort(systComps,compareComponents);
4976
4977 //print("validateTaskGraphMeta: sorted graph components are \n" + stringDelimitList(List.map(List.map(sortedGraphComps, Util.tuple21), BackendDump.printComponent), ",") + "\n");
4978 //print("validateTaskGraphMeta: sorted system components are \n" + stringDelimitList(List.map(List.map(sortedSystComps, Util.tuple21), BackendDump.printComponent), ",") + "\n");
4979
4980
1/2
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
8 if intNe(listLength(sortedSystComps),listLength(sortedGraphComps)) then print("the graph and the system have a difference number of components.\n"); end if;
4981 isEqual := true;
4982
3/4
✓ Branch 0 taken 1539 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1531 times.
✓ Branch 3 taken 8 times.
1539 while isEqual and not listEmpty(sortedGraphComps) loop
4983 1531 tpl1::sortedGraphComps := sortedGraphComps;
4984
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1531 times.
1531 tpl2::sortedSystComps := sortedSystComps;
4985 1531 (comp1,i1) := tpl1;
4986 1531 (comp2,i2) := tpl2;
4987
1/2
✓ Branch 1 taken 1531 times.
✗ Branch 2 not taken.
1531 if componentsEqual(tpl1, tpl2) then isEqual:= true;
4988 else
4989 isEqual := false;
4990 ✗ print("comp " + intString(i1) + BackendDump.printComponent(comp1) + " is not equal to " + "comp"
4991 + intString(i2) + BackendDump.printComponent(comp2) + "\n");
4992 end if;
4993 end while;
4994 then true;
4995 else
4996 algorithm
4997 ✗ print("Different components in graph and system\n");
4998 then false;
4999 end matchcontinue;
5000 end validateComponents;
5001
5002 protected function checkForDuplicates "author: marcusw
5003 Returns true if every component is unique in the list."
5004 input list<tuple<BackendDAE.StrongComponent,Integer>> iComps; //<component, eqSysIdx>
5005 output Boolean res;
5006 protected
5007 list<tuple<BackendDAE.StrongComponent,Integer>> sortedComps;
5008 algorithm
5009 8 sortedComps := List.sort(iComps,compareComponents);
5010 //print("checkForDuplicates Components: " + stringDelimitList(List.map(sortedComps,BackendDump.printComponent), ";") + "\n");
5011 8 (res,_) := List.fold(sortedComps,checkForDuplicates0,(true,NONE()));
5012 end checkForDuplicates;
5013
5014 protected function checkForDuplicates0 "author: marcusw
5015 Implementation of checkForDuplicates."
5016 input tuple<BackendDAE.StrongComponent,Integer> currentComp_idx;
5017 input tuple<Boolean,Option<tuple<BackendDAE.StrongComponent,Integer>>> iLastComp; //<result,lastComp>
5018 output tuple<Boolean,Option<tuple<BackendDAE.StrongComponent,Integer>>> oLastComp; //<result,lastComp>
5019 protected
5020 BackendDAE.StrongComponent lastComp,currentComp;
5021 tuple<BackendDAE.StrongComponent,Integer> lastComp_idx;
5022 Integer idxLast, idxCurrent;
5023 algorithm
5024 oLastComp := matchcontinue(currentComp_idx,iLastComp)
5025 ✗ case(_,(false,_)) then ((false,SOME(currentComp_idx)));
5026 8 case(_,(_,NONE())) then ((true,SOME(currentComp_idx)));
5027 case((currentComp,idxCurrent),(_,SOME(lastComp_idx as (lastComp, idxLast))))
5028 algorithm
5029
1/2
✓ Branch 1 taken 1523 times.
✗ Branch 2 not taken.
1523 true := componentsEqual(currentComp_idx,lastComp_idx);
5030 ✗ print("Component duplicate detected: current: " + BackendDump.printComponent(currentComp) + " (eqSystem "
5031 + intString(idxCurrent) + ") last " + BackendDump.printComponent(lastComp) + " (eqSystem " + intString(idxLast) + ").\n");
5032 ✗ then ((false,SOME(currentComp_idx)));
5033 1523 else ((true, SOME(currentComp_idx)));
5034 end matchcontinue;
5035 end checkForDuplicates0;
5036
5037 protected function getGraphComponents "author: marcusw
5038 Returns all StrongComponents of the TaskGraphMeta-structure."
5039 input TaskGraphMeta iTaskGraphMeta;
5040 input array<BackendDAE.StrongComponent> iSystComps;
5041 input array<tuple<BackendDAE.EqSystem,Integer>> iCompEqSysMapping; //maps each iSystComps to <eqsystem,eqSystemIdx>
5042 output BackendDAE.StrongComponents oComps;
5043 output array<tuple<BackendDAE.EqSystem,Integer>> oCompEqGraphMapping;
5044 protected
5045 BackendDAE.StrongComponents tmpComps;
5046 list<tuple<BackendDAE.EqSystem,Integer>> tmpMapping;
5047 array<list<Integer>> inComps;
5048 array<Integer> nodeMarks;
5049 algorithm
5050 tmpComps := {};
5051 tmpMapping := {};
5052 8 TASKGRAPHMETA(inComps=inComps, nodeMark=nodeMarks) := iTaskGraphMeta;
5053 8 (tmpComps,tmpMapping) := Array.fold(inComps, function getGraphComponents0(systComps = iSystComps, iCompEqSysMapping = iCompEqSysMapping),(tmpComps,tmpMapping));
5054 8 (_,(tmpComps,tmpMapping)) := Array.fold(nodeMarks, function getGraphComponents2(systComps = iSystComps, iCompEqSysMapping = iCompEqSysMapping), (1,(tmpComps,tmpMapping)));
5055 oComps := tmpComps;
5056 8 oCompEqGraphMapping := listArray(tmpMapping);
5057 end getGraphComponents;
5058
5059 protected function getGraphComponents0 "author: marcusw
5060 Helper function of getGraphComponents. Returns all components which are not marked with -1 (all components that are part of the graph)."
5061 input list<Integer> inComp;
5062 input array<BackendDAE.StrongComponent> systComps;
5063 input array<tuple<BackendDAE.EqSystem,Integer>> iCompEqSysMapping;
5064 input tuple<BackendDAE.StrongComponents, list<tuple<BackendDAE.EqSystem,Integer>>> iNodeComps_Mapping; //list of components and list of mapping
5065 output tuple<BackendDAE.StrongComponents, list<tuple<BackendDAE.EqSystem,Integer>>> oNodeComps_Mapping;
5066 protected
5067 BackendDAE.StrongComponents iNodeComps, tmpNodeComps;
5068 list<tuple<BackendDAE.EqSystem,Integer>> iCompsMapping, tmpCompsMapping;
5069 algorithm
5070 1059 (iNodeComps,iCompsMapping) := iNodeComps_Mapping;
5071 1059 (tmpNodeComps,tmpCompsMapping) := List.fold2(inComp, getGraphComponents1, systComps, iCompEqSysMapping, ({},{}));
5072 1059 tmpNodeComps := listAppend(iNodeComps,tmpNodeComps);
5073 1059 tmpCompsMapping := listAppend(iCompsMapping,tmpCompsMapping);
5074 1059 oNodeComps_Mapping := (tmpNodeComps,tmpCompsMapping);
5075 end getGraphComponents0;
5076
5077 protected function getGraphComponents1
5078 input Integer compIdx;
5079 input array<BackendDAE.StrongComponent> systComps;
5080 input array<tuple<BackendDAE.EqSystem,Integer>> iCompEqSysMapping;
5081 input tuple<BackendDAE.StrongComponents, list<tuple<BackendDAE.EqSystem,Integer>>> iNodeComps_Mapping;
5082 output tuple<BackendDAE.StrongComponents, list<tuple<BackendDAE.EqSystem,Integer>>> oNodeComps_Mapping;
5083 protected
5084 BackendDAE.StrongComponent comp;
5085 tuple<BackendDAE.EqSystem,Integer> eqSyst;
5086 BackendDAE.StrongComponents tmpComps;
5087 list<tuple<BackendDAE.EqSystem,Integer>> tmpSysts;
5088 algorithm
5089 1059 (tmpComps,tmpSysts) := iNodeComps_Mapping;
5090 1059 comp := arrayGet(systComps,compIdx);
5091 1059 eqSyst := arrayGet(iCompEqSysMapping,compIdx);
5092 tmpComps := comp::tmpComps;
5093 tmpSysts := eqSyst::tmpSysts;
5094 1059 oNodeComps_Mapping := (tmpComps,tmpSysts);
5095 end getGraphComponents1;
5096
5097 protected function getGraphComponents2 "author: marcusw
5098 Append all components with mark -1 to the componentlist."
5099 input Integer nodeMark;
5100 input array<BackendDAE.StrongComponent> systComps;
5101 input array<tuple<BackendDAE.EqSystem,Integer>> iCompEqSysMapping;
5102 input tuple<Integer,tuple<BackendDAE.StrongComponents, list<tuple<BackendDAE.EqSystem,Integer>>>> iNodeComps_Mapping; //<nodeIdx, <components,eqSystems>>
5103 output tuple<Integer,tuple<BackendDAE.StrongComponents, list<tuple<BackendDAE.EqSystem,Integer>>>> oNodeComps_Mapping;
5104 protected
5105 Integer nodeIdx;
5106 BackendDAE.StrongComponent comp;
5107 tuple<BackendDAE.EqSystem,Integer> eqSyst;
5108 BackendDAE.StrongComponents comps;
5109 list<tuple<BackendDAE.EqSystem,Integer>> eqSysts;
5110 algorithm
5111 1531 (nodeIdx,(comps,eqSysts)) := iNodeComps_Mapping;
5112
2/2
✓ Branch 0 taken 472 times.
✓ Branch 1 taken 1059 times.
1531 if not (intGe(nodeMark,0) or intEq(nodeMark,-2)) then
5113 472 comp := arrayGet(systComps,nodeIdx);
5114 472 eqSyst := arrayGet(iCompEqSysMapping,nodeIdx);
5115 comps := comp :: comps;
5116 eqSysts := eqSyst :: eqSysts;
5117 end if;
5118 1531 oNodeComps_Mapping := ((nodeIdx+1,(comps,eqSysts)));
5119 end getGraphComponents2;
5120
5121 protected function componentsEqual "author: marcusw
5122 Compares the given components and returns true if they are equal."
5123 input tuple<BackendDAE.StrongComponent,Integer> iComp1;
5124 input tuple<BackendDAE.StrongComponent,Integer> iComp2; //<component, eqSystIdx>
5125 output Boolean res;
5126 protected
5127 String comp1Str,comp2Str;
5128 Integer comp1Idx, comp2Idx;
5129 BackendDAE.StrongComponent comp1, comp2;
5130 algorithm
5131 36717 (comp1, comp1Idx) := iComp1;
5132 36717 (comp2, comp2Idx) := iComp2;
5133 36717 comp1Str := BackendDump.printComponent(comp1) + "_" + intString(comp1Idx);
5134 36717 comp2Str := BackendDump.printComponent(comp2) + "_" + intString(comp2Idx);
5135
2/2
✓ Branch 0 taken 19253 times.
✓ Branch 1 taken 17464 times.
36717 if(intNe(stringLength(comp1Str),stringLength(comp2Str))) then
5136 res := false;
5137 else
5138 19253 res := intEq(System.strncmp(comp1Str, comp2Str, stringLength(comp1Str)), 0);
5139 end if;
5140 end componentsEqual;
5141
5142 protected function compareComponents "author: marcusw
5143 Compares the given components and returns true if the name of the first component is lower."
5144 input tuple<BackendDAE.StrongComponent,Integer> iComp1;
5145 input tuple<BackendDAE.StrongComponent,Integer> iComp2; //<component, eqSystIdx>
5146 output Boolean res;
5147 protected
5148 String comp1Str,comp2Str;
5149 Integer minLength, compRes, comp1Idx, comp2Idx;
5150 BackendDAE.StrongComponent comp1, comp2;
5151 algorithm
5152
1/2
✓ Branch 1 taken 33663 times.
✗ Branch 2 not taken.
33663 if(componentsEqual(iComp1, iComp2)) then
5153 res := false;
5154 else
5155 33663 (comp1, comp1Idx) := iComp1;
5156 33663 (comp2, comp2Idx) := iComp2;
5157 33663 comp1Str := BackendDump.printComponent(comp1) + "_" + intString(comp1Idx);
5158 33663 comp2Str := BackendDump.printComponent(comp2) + "_" + intString(comp2Idx);
5159 33663 minLength := intMin(stringLength(comp1Str), stringLength(comp2Str));
5160 33663 compRes := System.strncmp(comp1Str, comp2Str, minLength);
5161
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 33663 times.
33663 if(intEq(compRes, 0)) then
5162 ✗ res := intLt(stringLength(comp1Str), stringLength(comp2Str));
5163 else
5164 33663 res := intLt(compRes, 0);
5165 end if;
5166 end if;
5167 end compareComponents;
5168
5169
5170 //------------------------------------
5171 // Evaluation and analysing functions
5172 //------------------------------------
5173
5174 public function getCriticalPaths "author: Waurich TUD 2013-07
5175 Function to assign levels to the nodes of a graph and compute the criticalPath."
5176 input TaskGraph graphIn;
5177 input TaskGraphMeta graphDataIn;
5178 output tuple<list<list<Integer>>,Real> criticalPathOut; //criticalPath with communication costs <%paths, opCost%>
5179 output tuple<list<list<Integer>>,Real> criticalPathOutWoC; //criticalPath without communication costs <%paths, opCost%>
5180 algorithm
5181 (criticalPathOut,criticalPathOutWoC) := matchcontinue graphDataIn
5182 local
5183 list<Integer> rootNodes;
5184 list<list<Integer>> cpWCpaths,CpWoCpaths;
5185 Real cpWCcosts,cpWoCcosts;
5186 case TASKGRAPHMETA()
5187 algorithm
5188
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 14 times.
16 true := arrayLength(graphIn) <> 0;
5189 14 rootNodes := getRootNodes(graphIn);
5190
5191 14 (cpWCpaths,cpWCcosts) := getCriticalPath(graphIn,graphDataIn,rootNodes,true);
5192 14 (CpWoCpaths,cpWoCcosts) := getCriticalPath(graphIn,graphDataIn,rootNodes,false);
5193 14 cpWCcosts := roundReal(cpWCcosts,2);
5194 14 cpWoCcosts := roundReal(cpWoCcosts,2);
5195 14 then
5196 ((cpWCpaths,cpWCcosts),(CpWoCpaths,cpWoCcosts));
5197 case _
5198 algorithm
5199
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 true := arrayLength(graphIn) == 0;
5200 then
5201 (({{}},0.0),({{}},0.0));
5202 else
5203 algorithm
5204 ✗ print("getCriticalPaths failed!\n");
5205 then
5206 (({{}},0.0),({{}},0.0));
5207 end matchcontinue;
5208 end getCriticalPaths;
5209
5210 protected function getCriticalPath "author: marcusw
5211 Get the critical path of the graph."
5212 input TaskGraph iGraph;
5213 input TaskGraphMeta iGraphData;
5214 input list<Integer> iRootNodes;
5215 input Boolean iHandleCommCosts; //true if the communication costs should be handled
5216 output list<list<Integer>> oCriticalPathsOut; //The list of critical paths -> has only one element
5217 output Real oCpCosts;
5218 protected
5219 array<tuple<Real,list<Integer>>> nodeCriticalPaths; //<criticalPath,criticalPathSuccessor> for each node <%idx%>
5220 list<tuple<Real,list<Integer>>> criticalPaths;
5221 Integer criticalPathIdx;
5222 list<Integer> criticalPath;
5223 algorithm
5224 28 nodeCriticalPaths := arrayCreate(arrayLength(iGraph), (-1.0,{}));
5225
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 14 times.
42 criticalPaths := List.map4(iRootNodes, getCriticalPath1, iGraph, iGraphData, iHandleCommCosts, nodeCriticalPaths);
5226 28 criticalPathIdx := getCriticalPath2(criticalPaths, 1, -1.0, -1);
5227 28 (oCpCosts, criticalPath) := listGet(criticalPaths, criticalPathIdx);
5228 //print("getCriticalPath: critical path " + stringDelimitList(List.map(criticalPath, intString), ",") + " with cost of: " + realString(oCpCosts) + ". Including communication costs: " + boolString(iHandleCommCosts) + "\n");
5229 oCriticalPathsOut := {criticalPath};
5230 end getCriticalPath;
5231
5232 protected function getCriticalPath1 "author: marcusw
5233 Get the critical path of the given node (iNode). If the node was already visited, the result will be read from the iNodeCriticalPaths.
5234 If the node is visited the first time, then the critical path is calculated and stored into the iNodeCriticalPaths-array."
5235 input Integer iNode;
5236 input TaskGraph iGraph;
5237 input TaskGraphMeta iGraphData;
5238 input Boolean iHandleCommCosts; //true if the communication costs should be handled
5239 input array<tuple<Real,list<Integer>>> iNodeCriticalPaths;
5240 output tuple<Real,list<Integer>> criticalPathOut;
5241 protected
5242 Real cpCalcTime, calcTime, commTime;
5243 Integer criticalPathIdx;
5244 Communication commCost;
5245 list<Integer> childNodes, criticalPathChild, criticalPath, nodeComps;
5246 list<tuple<Real,list<Integer>>> criticalPaths;
5247 array<tuple<Integer,Real>> exeCosts;
5248 array<list<Integer>> inComps;
5249 algorithm
5250 criticalPathOut := matchcontinue iGraphData
5251 case TASKGRAPHMETA(inComps=inComps,exeCosts=exeCosts)
5252 algorithm //In this case, the node was already visited
5253
2/2
✓ Branch 1 taken 3114 times.
✓ Branch 2 taken 3372 times.
6486 (cpCalcTime,criticalPath) := arrayGet(iNodeCriticalPaths, iNode);
5254
2/2
✓ Branch 0 taken 3114 times.
✓ Branch 1 taken 3372 times.
6486 true := realGe(cpCalcTime, 0.0);
5255 3372 then ((cpCalcTime, criticalPath));
5256 case TASKGRAPHMETA(inComps=inComps,exeCosts=exeCosts)
5257 algorithm //critical path of node is currently unknown -> calculate it
5258 3114 childNodes := arrayGet(iGraph, iNode);
5259
2/2
✓ Branch 0 taken 444 times.
✓ Branch 1 taken 2670 times.
3114 false := listEmpty(childNodes); //has children
5260
2/2
✓ Branch 0 taken 1335 times.
✓ Branch 1 taken 1335 times.
4005 criticalPaths := List.map4(childNodes, getCriticalPath1, iGraph, iGraphData, iHandleCommCosts, iNodeCriticalPaths);
5261 2670 criticalPathIdx := getCriticalPath2(criticalPaths, 1, -1.0, -1);
5262 2670 (cpCalcTime, criticalPathChild) := listGet(criticalPaths, criticalPathIdx);
5263 criticalPath := iNode :: criticalPathChild;
5264
2/2
✓ Branch 0 taken 1335 times.
✓ Branch 1 taken 1335 times.
2670 commCost := if iHandleCommCosts then getCommCostBetweenNodes(iNode, listHead(criticalPathChild), iGraphData) else COMMUNICATION(0,{},{},{},{},-1,0.0);
5265 //print("Comm cost from node " + intString(iNode) + " to " + intString(listHead(criticalPathChild)) + " with costs " + intString(Util.tuple33(commCost)) + "\n");
5266 2670 nodeComps := arrayGet(inComps, iNode);
5267 2670 calcTime := addUpExeCostsForNode(nodeComps, exeCosts, 0.0); //sum up calc times of all components
5268 2670 calcTime := realAdd(cpCalcTime,calcTime);
5269 2670 COMMUNICATION(requiredTime=commTime) := commCost;
5270 //print("getCriticalPath1: " + " (" + realString(calcTime) + "+" + realString(commTime) + ")\n");
5271 2670 calcTime := realAdd(calcTime, commTime);
5272 2670 arrayUpdate(iNodeCriticalPaths, iNode, (calcTime, criticalPath));
5273 //print("getCriticalPath1: Critical path of node " + intString(iNode) + " is " + realString(calcTime) + "\n");
5274 2670 then ((calcTime, criticalPath));
5275 case TASKGRAPHMETA(inComps=inComps,exeCosts=exeCosts)
5276 algorithm //critical path of node is currently unknown -> calculate it
5277 444 childNodes := arrayGet(iGraph, iNode);
5278
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 444 times.
444 true := listEmpty(childNodes); //has no children
5279 criticalPath := iNode :: {};
5280 444 nodeComps := arrayGet(inComps, iNode);
5281 444 calcTime := addUpExeCostsForNode(nodeComps, exeCosts, 0.0); //sum up calc times of all components
5282 444 arrayUpdate(iNodeCriticalPaths, iNode, (calcTime, criticalPath));
5283 444 then ((calcTime, criticalPath));
5284 else
5285 algorithm
5286 ✗ print("HpcOmTaskGraph.getCriticalPath_1 failed\n");
5287 ✗ then fail();
5288 end matchcontinue;
5289 end getCriticalPath1;
5290
5291 protected function getCriticalPath2 "author: marcusw
5292 Find the list-index of the longest path. The paths which should be compared have to be stored in the iCriticalPaths-list."
5293 input list<tuple<Real,list<Integer>>> iCriticalPaths;
5294 input Integer iListIdx;
5295 input Real iLongestPath;
5296 input Integer iLongestPathIndex;
5297 output Integer oLongestPathIndex;
5298 protected
5299 Real cpCost;
5300 list<Integer> criticalPath;
5301 list<tuple<Real,list<Integer>>> rest;
5302 algorithm
5303 oLongestPathIndex := match iCriticalPaths
5304 case (cpCost, criticalPath)::rest guard realGt(cpCost, iLongestPath)
5305 3695 then getCriticalPath2(rest, iListIdx+1, cpCost, iListIdx);
5306 case (cpCost, criticalPath)::rest
5307 2791 then getCriticalPath2(rest, iListIdx+1, iLongestPath, iLongestPathIndex);
5308 else iLongestPathIndex;
5309 end match;
5310 end getCriticalPath2;
5311
5312 protected function addUpExeCostsForNode "author: marcusw
5313 This function adds up all execution costs of the given component list (iNodeComps)."
5314 input list<Integer> iNodeComps;
5315 input array<tuple<Integer,Real>> iExeCosts;
5316 input Real iExeCost;
5317 output Real oExeCost;
5318 protected
5319 Integer head;
5320 list<Integer> rest;
5321 Real cost;
5322 algorithm
5323 oExeCost := match iNodeComps
5324 case head::rest
5325 algorithm
5326 5119 (_,cost) := arrayGet(iExeCosts, head);
5327 5119 cost := realAdd(cost, iExeCost);
5328 5119 cost := addUpExeCostsForNode(rest, iExeCosts, cost);
5329 then cost;
5330 else iExeCost;
5331 end match;
5332 end addUpExeCostsForNode;
5333
5334 protected function gatherParallelSets "author: Waurich TUD 2013-07
5335 Gathers all nodes of the same level in a list."
5336 input array<tuple<Integer,Real,Integer>> nodeInfo;
5337 output list<list<Integer>> parallelSetsOut;
5338 protected
5339 Integer numLevels;
5340 algorithm
5341 ✗ numLevels := Array.fold(nodeInfo,numberOfLevels,0);
5342 ✗ parallelSetsOut := List.fold1(List.intRange(arrayLength(nodeInfo)),gatherParallelSets1,nodeInfo,List.fill({},numLevels));
5343 end gatherParallelSets;
5344
5345 protected function numberOfLevels "author: Waurich TUD 2013-07
5346 Gets the number of values."
5347 input tuple<Integer,Real,Integer> nodeInfoEntry;
5348 input Integer numLevelsIn;
5349 output Integer numLevelsOut;
5350 protected
5351 Integer levelIn;
5352 algorithm
5353 ✗ (levelIn,_,_) := nodeInfoEntry;
5354 numLevelsOut := intMax(levelIn,numLevelsIn);
5355 end numberOfLevels;
5356
5357 protected function gatherParallelSets1 "author: Waurich TUD 2013-07
5358 Folding function for gatherParallelSets."
5359 input Integer idx;
5360 input array<tuple<Integer,Real,Integer>> nodeInfo;
5361 input list<list<Integer>> parallelSetIn;
5362 output list<list<Integer>> parallelSetOut;
5363 protected
5364 Integer level;
5365 list<Integer> pSet;
5366 algorithm
5367 ✗ (level,_,_) := arrayGet(nodeInfo,idx);
5368 ✗ pSet := listGet(parallelSetIn,level);
5369 pSet := idx :: pSet;
5370 ✗ parallelSetOut := List.replaceAt(pSet, level, parallelSetIn);
5371 end gatherParallelSets1;
5372
5373 protected function getCostsForNode "author: Waurich TUD 2013-07
5374 Function to compute the costs for the next node (including the execution costs and the communication costs).
5375 The given nodeIndeces are from the current graph and will be transformed to original indeces via inComps by this function."
5376 input Integer parentNode;
5377 input Integer childNode;
5378 input array<list<Integer>> inComps;
5379 input array<tuple<Integer,Real>> exeCosts;
5380 input array<Communications> commCosts;
5381 output Real costsOut;
5382 algorithm
5383 costsOut := matchcontinue parentNode
5384 local
5385 Real costs;
5386 Real commCost;
5387 Integer primalChild;
5388 Integer primalParent;
5389 list<Integer> primalChildLst;
5390 list<Integer> primalParentLst;
5391 case 0
5392 algorithm
5393 // the root node is not contracted
5394 ✗ primalChildLst := arrayGet(inComps,childNode);
5395 ✗ true := listLength(primalChildLst) == 1;
5396 ✗ primalChild := listGet(primalChildLst,1);
5397 ✗ (_,costs) := arrayGet(exeCosts,primalChild);
5398 then
5399 costs;
5400 case 0
5401 algorithm
5402 // the root node is contracted
5403 ✗ primalChildLst := arrayGet(inComps,childNode);
5404 ✗ true := listLength(primalChildLst) > 1;
5405 ✗ listGet(primalChildLst,1);
5406 ✗ costs := getCostsForContractedNodes(primalChildLst,exeCosts);
5407 then
5408 costs;
5409 case _
5410 algorithm
5411 // the childNode is not contracted
5412 ✗ primalChildLst := arrayGet(inComps,childNode);
5413 ✗ primalParentLst := arrayGet(inComps,parentNode);
5414 ✗ true := listLength(primalChildLst) == 1;
5415 ✗ primalChild := listGet(primalChildLst,1);
5416 ✗ primalParent := listGet(primalParentLst,1);
5417 ✗ (_,costs) := arrayGet(exeCosts,primalChild);
5418 ✗ COMMUNICATION(requiredTime=commCost) := getCommunicationCost(primalChild, primalParent ,commCosts);
5419 ✗ costs := costs + commCost;
5420 then
5421 costs;
5422 case _
5423 algorithm
5424 // the childNode is contracted
5425 ✗ primalChildLst := arrayGet(inComps,childNode);
5426 ✗ arrayGet(inComps,parentNode);
5427 ✗ true := listLength(primalChildLst) > 1;
5428 ✗ costs := getCostsForContractedNodes(primalChildLst,exeCosts);
5429 then
5430 costs;
5431 else
5432 algorithm
5433 ✗ print("getCostsForNode failed! \n");
5434 ✗ then
5435 fail();
5436 end matchcontinue;
5437 end getCostsForNode;
5438
5439 public function getCostsForContractedNodes "author: Waurich TUD 2013-10
5440 Sums up alle execution costs for a contracted node."
5441 input list<Integer> nodeList;
5442 input array<tuple<Integer,Real>> exeCosts;
5443 output Real costsOut;
5444 algorithm
5445 7 costsOut := List.fold1(nodeList,getCostsForContractedNodes1,exeCosts,0.0);
5446 end getCostsForContractedNodes;
5447
5448 protected function getCostsForContractedNodes1 "author:Waurich TUD 2013-10
5449 Gets exeCosts for one node and add it to the foldType."
5450 input Integer node;
5451 input array<tuple<Integer,Real>> exeCosts;
5452 input Real costsIn;
5453 output Real costsOut;
5454 protected
5455 Real exeCost;
5456 algorithm
5457 102 (_,exeCost) := arrayGet(exeCosts,node);
5458 102 costsOut := realAdd(costsIn,exeCost);
5459 end getCostsForContractedNodes1;
5460
5461 protected function getNodeCoords "author: Waurich TUD 2013-07
5462 Computes the location of the nodes in the .graphml with regard to the parallel sets."
5463 input list<list<Integer>> parallelSets;
5464 input TaskGraph graphIn;
5465 output array<tuple<Integer,Integer>> nodeCoordsOut;
5466 protected
5467 array<tuple<Integer,Integer>> nodeCoords;
5468 Integer size;
5469 algorithm
5470 size := arrayLength(graphIn);
5471 ✗ nodeCoords := arrayCreate(size,((0,0)));
5472 ✗ nodeCoords := List.fold1(List.intRange(size),getYCoordForNode,parallelSets,nodeCoords);
5473 nodeCoordsOut := nodeCoords;
5474 //print("nodeCoords"+stringDelimitList(List.mapArray(nodeCoords, tupleToString),",")+"\n");
5475 end getNodeCoords;
5476
5477 protected function getYCoordForNode "author: Waurich TUD 2013-07
5478 Fold function to compute the y-coordinate for the graph."
5479 input Integer compIdx;
5480 input list<list<Integer>> parallelSets;
5481 input array<tuple<Integer,Integer>> nodeCoordsIn;
5482 output array<tuple<Integer,Integer>> nodeCoordsOut;
5483 protected
5484 Integer parallelSetIdx;
5485 Integer xCoord;
5486 Integer yCoord;
5487 tuple<Integer,Integer> coords;
5488 algorithm
5489 //levelInterval := 80;
5490 ✗ parallelSetIdx := getParallelSetForComp(compIdx,1,parallelSets);
5491 ✗ (xCoord,yCoord) := arrayGet(nodeCoordsIn,compIdx);
5492 //coords := ((xCoord,parallelSetIdx*levelInterval));
5493 ✗ coords := ((xCoord,parallelSetIdx));
5494 ✗ nodeCoordsOut := arrayUpdate(nodeCoordsIn,compIdx,coords);
5495 end getYCoordForNode;
5496
5497 protected function getParallelSetForComp "author: Waurich TUD 2013-07
5498 Find the parallelSet the inComp belongs to."
5499 input Integer compIn;
5500 input Integer setIdx;
5501 input list<list<Integer>> parallelSets;
5502 output Integer parallelSetOut;
5503 algorithm
5504 parallelSetOut := matchcontinue parallelSets
5505 local
5506 list<Integer> parallelSet;
5507 Integer parallelSetTmp;
5508 case _
5509 algorithm
5510 ✗ true := setIdx <= listLength(parallelSets);
5511 ✗ parallelSet := listGet(parallelSets,setIdx);
5512 //print("is "+intString(compIn)+" member of set "+intString(setIdx)+" with the nodes "+stringDelimitList(List.map(parallelSet,intString),",")+"\n");
5513 ✗ true := List.isMemberOnTrue(compIn,parallelSet,intEq);
5514 //print("true \n");
5515 then
5516 setIdx;
5517 case _
5518 algorithm
5519 ✗ true := setIdx <= listLength(parallelSets);
5520 ✗ parallelSet := listGet(parallelSets,setIdx);
5521 //print("is "+intString(compIn)+" member of set "+intString(setIdx)+" with the nodes "+stringDelimitList(List.map(parallelSet,intString),",")+"\n");
5522 ✗ false := List.isMemberOnTrue(compIn,parallelSet,intEq);
5523 //print("false \n");
5524 ✗ parallelSetTmp := getParallelSetForComp(compIn,setIdx+1,parallelSets);
5525 then
5526 parallelSetTmp;
5527 else
5528 algorithm
5529 ✗ print("getParallelSetForComp failed!\n");
5530 ✗ then
5531 fail();
5532 end matchcontinue;
5533 end getParallelSetForComp;
5534
5535 protected function setLevelInNodeMark "author: wauricht TUD 2013-07
5536 Sets the parallelSetIndex as a nodeMark."
5537 input Integer nodeIdx;
5538 input array<list<Integer>> inComps;
5539 input array<tuple<Integer,Integer>> nodeCoords;
5540 input array<Integer> nodeMarkIn;
5541 output array<Integer> nodeMarkOut;
5542 algorithm
5543 nodeMarkOut := matchcontinue nodeMarkIn
5544 local
5545 array<Integer> nodeMarkTmp;
5546 list<Integer> components;
5547 Integer primalComp;
5548 Integer nodeMarkEntry;
5549 Integer yCoord;
5550 case _
5551 algorithm
5552 ✗ nodeMarkEntry := arrayGet(nodeMarkIn,nodeIdx);
5553 ✗ components := arrayGet(inComps,nodeIdx);
5554 ✗ primalComp := List.last(components);
5555 ✗ nodeMarkEntry := arrayGet(nodeMarkIn,primalComp);
5556 ✗ true := intEq(-1,nodeMarkEntry);
5557 then
5558 nodeMarkIn;
5559 case _
5560 algorithm
5561 ✗ nodeMarkEntry := arrayGet(nodeMarkIn,nodeIdx);
5562 ✗ components := arrayGet(inComps,nodeIdx);
5563 ✗ primalComp := List.last(components);
5564 ✗ nodeMarkEntry := arrayGet(nodeMarkIn,primalComp);
5565 ✗ false := intEq(-1,nodeMarkEntry);
5566 ✗ (_,yCoord) := arrayGet(nodeCoords,nodeIdx);
5567 ✗ nodeMarkTmp := arrayUpdate(nodeMarkIn,primalComp,yCoord);
5568 then
5569 nodeMarkTmp;
5570 end matchcontinue;
5571 end setLevelInNodeMark;
5572
5573 protected function tupleToStringIntRealInt "author: Waurich TUD 2013-07
5574 Returns the given tuple as string."
5575 input tuple<Integer,Real,Integer> inTuple;
5576 output String result;
5577 algorithm
5578 result := match inTuple
5579 local
5580 Integer int1,int2;
5581 Real real1;
5582 case (int1,real1,int2)
5583 ✗ then ("(" + intString(int1) + "," + realString(real1) +" , "+ intString(int2) + ")");
5584 end match;
5585 end tupleToStringIntRealInt;
5586
5587 public function transposeCommCosts "author: marcusw
5588 Returns the given communication costs as transposed version."
5589 input array<Communications> iCommCosts;
5590 output array<Communications> oCommCosts;
5591 protected
5592 array<Communications> tmpCommCosts;
5593 algorithm
5594 ✗ tmpCommCosts := arrayCreate(arrayLength(iCommCosts), {});
5595 ✗ (_,tmpCommCosts) := Array.fold(iCommCosts, transposeCommCosts0, (1,tmpCommCosts));
5596 oCommCosts := tmpCommCosts;
5597 end transposeCommCosts;
5598
5599 protected function transposeCommCosts0 "author: marcusw
5600 Helper function for transposeCommCosts."
5601 input Communications iCosts; //costs for all edges from <%parentComp%> to children
5602 input tuple<Integer,array<Communications>> iCommCosts; //<parentCompIdx, commCosts>
5603 output tuple<Integer,array<Communications>> oCommCosts;
5604 protected
5605 Integer iParentCompIdx;
5606 array<Communications> tmpCommCosts;
5607 algorithm
5608 ✗ (iParentCompIdx, tmpCommCosts) := iCommCosts;
5609 ✗ tmpCommCosts := List.fold1(iCosts, transposeCommCosts1, iParentCompIdx, tmpCommCosts);
5610 ✗ oCommCosts := (iParentCompIdx+1, tmpCommCosts);
5611 end transposeCommCosts0;
5612
5613 protected function transposeCommCosts1 "author: marcusw
5614 Helper function for transposeCommCosts0."
5615 input Communication iCost;
5616 input Integer iParentCompIdx;
5617 input array<Communications> iCommCosts;
5618 output array<Communications> oCommCosts;
5619 protected
5620 array<Communications> tmpCommCosts;
5621 Communications costs;
5622 Integer numberOfVars,nodeIdx;
5623 list<Integer> integerVars,floatVars,booleanVars,stringVars;
5624 Real requiredTime;
5625 algorithm
5626 oCommCosts := matchcontinue iCost
5627 case COMMUNICATION(numberOfVars=numberOfVars,integerVars=integerVars,floatVars=floatVars,booleanVars=booleanVars,stringVars=stringVars,childNode=nodeIdx,requiredTime=requiredTime)
5628 algorithm
5629 ✗ true := intLe(nodeIdx, arrayLength(iCommCosts));
5630 ✗ costs := arrayGet(iCommCosts, nodeIdx);
5631 ✗ costs := COMMUNICATION(numberOfVars,integerVars,floatVars,booleanVars,stringVars,iParentCompIdx,requiredTime) :: costs;
5632 ✗ tmpCommCosts := arrayUpdate(iCommCosts, nodeIdx, costs);
5633 then tmpCommCosts;
5634 else iCommCosts;
5635 end matchcontinue;
5636 end transposeCommCosts1;
5637
5638 //TODO: Can this be merged with getCommCostBetweenNodes?
5639 protected function getCommunicationCost "author: waurich TUD 2013-06.
5640 Gets the communication cost for an edge from parent node to child node.
5641 REMARK: use the primal indeces!!!!!!"
5642 input Integer childIdx;
5643 input Integer parentIdx;
5644 input array<Communications> commCosts;
5645 output Communication oComm;
5646 protected
5647 Communications commRow;
5648 Communication commEntry;
5649 algorithm
5650 //print("Try to get comm cost for edge from " + intString(parentIdx) + " to " + intString(childIdx) + "\n");
5651 ✗ commRow := arrayGet(commCosts,parentIdx);
5652 ✗ commEntry := getCommunicationByChildIdx(commRow,childIdx);
5653 //(_,numOfVars,cost) := commEntry;
5654 oComm := commEntry;
5655 end getCommunicationCost;
5656
5657 protected function getCommunicationByChildIdx "author: marcusw
5658 Gets the communication with the given child idx out of the communications list."
5659 input Communications iComms;
5660 input Integer iChildIdx;
5661 output Communication oComm;
5662 algorithm
5663 oComm := matchcontinue iComms
5664 local
5665 Integer currentCommChild;
5666 Communication head, tmpComm;
5667 Communications rest;
5668 case COMMUNICATION(childNode=currentCommChild)::rest
5669 algorithm
5670 ✗ false := intEq(currentCommChild,iChildIdx);
5671 ✗ tmpComm := getCommunicationByChildIdx(rest,iChildIdx);
5672 then tmpComm;
5673 case (head as COMMUNICATION(childNode=currentCommChild))::_
5674 algorithm
5675 ✗ true := intEq(currentCommChild,iChildIdx);
5676 then head;
5677 case {}
5678 algorithm
5679 ✗ print("getCommunicationByChildIdx failed! - the child idx "+intString(iChildIdx)+" can not be found in the list of edges\n");
5680 ✗ then
5681 fail();
5682 end matchcontinue;
5683 end getCommunicationByChildIdx;
5684
5685 public function getCommCostTimeBetweenNodes "author: waurich TUD 2014-05
5686 Get the required time of the highest communication costs between the given nodes."
5687 input Integer iParentNodeIdx;
5688 input Integer iChildNodeIdx;
5689 input TaskGraphMeta iTaskGraphMeta;
5690 output Real oCommCost;
5691 protected
5692 Real requiredTime;
5693 algorithm
5694 428 COMMUNICATION(requiredTime=requiredTime) := getCommCostBetweenNodes(iParentNodeIdx,iChildNodeIdx,iTaskGraphMeta);
5695 oCommCost := requiredTime;
5696 end getCommCostTimeBetweenNodes;
5697
5698 protected function getCommCostBetweenNodes "author: marcusw
5699 Get the edge with highest communication costs between the given nodes."
5700 input Integer iParentNodeIdx;
5701 input Integer iChildNodeIdx;
5702 input TaskGraphMeta iTaskGraphMeta;
5703 output Communication oCommCost;
5704 protected
5705 list<Integer> childComps, parentComps;
5706 array<list<Integer>> inComps;
5707 array<Communications> commCosts;
5708 list<Option<Communication>> concreteCommCostsOpt;
5709 Communications concreteCommCosts;
5710 algorithm
5711 27885 TASKGRAPHMETA(inComps=inComps,commCosts=commCosts) := iTaskGraphMeta;
5712 27885 parentComps := arrayGet(inComps, iParentNodeIdx);
5713 27885 childComps := arrayGet(inComps, iChildNodeIdx);
5714 27885 concreteCommCostsOpt := List.map2(parentComps, getCommCostBetweenNodes0, childComps, commCosts);
5715
7/8
✗ Branch 0 not taken.
✓ Branch 1 taken 34506 times.
✓ Branch 2 taken 6624 times.
✓ Branch 3 taken 27882 times.
✓ Branch 4 taken 34506 times.
✓ Branch 5 taken 27885 times.
✓ Branch 6 taken 27882 times.
✓ Branch 7 taken 27885 times.
62391 concreteCommCosts := list(Util.getOption(c) for c guard isSome(c) in concreteCommCostsOpt);
5716 27885 oCommCost := getHighestCommCost(concreteCommCosts, COMMUNICATION(0,{},{},{},{},-1,-1.0));
5717 end getCommCostBetweenNodes;
5718
5719 protected function getCommCostBetweenNodes0
5720 input Integer iParentComp;
5721 input list<Integer> iChildComps;
5722 input array<Communications> iCommCosts;
5723 output Option<Communication> oHighestComm; //the communication with the highest costs
5724 protected
5725 Communications commCosts, filteredCommCosts;
5726 Communication highestCommCost;
5727 algorithm
5728 oHighestComm := matchcontinue iCommCosts
5729 case _
5730 algorithm
5731 34506 commCosts := arrayGet(iCommCosts, iParentComp);
5732 34506 filteredCommCosts := List.filter1OnTrue(commCosts, getCommCostBetweenNodes1, iChildComps);
5733
2/2
✓ Branch 0 taken 6624 times.
✓ Branch 1 taken 27882 times.
34506 false := listEmpty(filteredCommCosts);
5734 27882 highestCommCost := getHighestCommCost(filteredCommCosts, COMMUNICATION(0,{},{},{},{},-1,-1.0));
5735 then SOME(highestCommCost);
5736 else NONE();
5737 end matchcontinue;
5738 end getCommCostBetweenNodes0;
5739
5740 protected function getCommCostBetweenNodes1 "author: marcusw
5741 Checks if the communication component is part of the child component list."
5742 input Communication iCommCost;
5743 input list<Integer> iChildComps;
5744 output Boolean oResult;
5745 protected
5746 Integer compIdx;
5747 algorithm
5748 128229 COMMUNICATION(childNode=compIdx) := iCommCost;
5749 128229 oResult := List.exist1(iChildComps, intEq, compIdx);
5750 end getCommCostBetweenNodes1;
5751
5752 protected function getHighestCommCost "author: marcusw
5753 Get the communication with highest costs out of the given list."
5754 input Communications iCommCosts;
5755 input Communication iHighestTuple;
5756 output Communication oHighestTuple;
5757 protected
5758 Real highestCost, currentCost;
5759 Communication head;
5760 Communications rest;
5761 algorithm
5762 oHighestTuple := match(iCommCosts, iHighestTuple)
5763 case((head as COMMUNICATION(requiredTime=currentCost))::rest, COMMUNICATION(requiredTime=highestCost)) guard realGt(currentCost, highestCost)
5764 62751 then getHighestCommCost(rest, head);
5765 case(head::rest,_)
5766 12467 then getHighestCommCost(rest, iHighestTuple);
5767 else iHighestTuple;
5768 end match;
5769 end getHighestCommCost;
5770
5771 public function sumUpExeCosts "author: Waurich TUD 2014-07
5772 Accumulates the execution costs of all tasks in the graph."
5773 input TaskGraph iGraph;
5774 input TaskGraphMeta iMeta;
5775 output tuple<Integer,Real> execCosts;
5776 protected
5777 Integer cost1;
5778 Real cost2;
5779 list<Integer> comps;
5780 array<list<Integer>> inComps;
5781 array<tuple<Integer,Real>> exeCosts;
5782 list<tuple<Integer,Real>> exeCostLst;
5783 algorithm
5784 execCosts := match iMeta
5785 case TASKGRAPHMETA(inComps=inComps, exeCosts=exeCosts)
5786 algorithm
5787 8 comps := List.flatten(List.map1(List.intRange(arrayLength(iGraph)),Array.getIndexFirst,inComps));
5788 8 exeCostLst := List.map1(comps,Array.getIndexFirst,exeCosts);
5789 8 cost1 := List.fold(List.map(exeCostLst,Util.tuple21),intAdd,0);
5790 8 cost2 := List.fold(List.map(exeCostLst,Util.tuple22),realAdd,0.0);
5791 8 then ((cost1,cost2));
5792 else ((0,0.0));
5793 end match;
5794 end sumUpExeCosts;
5795
5796 public function getAllSCCsOfGraph "author: marcusw
5797 Get all SCC-indices that are part of the graph."
5798 input TaskGraphMeta iTaskGraphMeta;
5799 output list<Integer> oSccs;
5800 protected
5801 Integer taskIdx;
5802 array<list<Integer>> inComps;
5803 list<Integer> comps;
5804 array<Integer> nodeMark;
5805 list<Integer> tmpSccs;
5806 algorithm
5807 tmpSccs := {};
5808
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 TASKGRAPHMETA(inComps=inComps, nodeMark=nodeMark) := iTaskGraphMeta;
5809
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 1 time.
506 for taskIdx in 1:arrayLength(inComps) loop
5810 //print("getAllSCCsOfGraph: Try to get component mark for task " + intString(taskIdx) + " out of marks with size '" + intString(arrayLength(nodeMark)) + "'\n");
5811 //mark := arrayGet(nodeMark, taskIdx);
5812 //print("getAllSCCsOfGraph: mark is '" + intString(mark) + "'\n");
5813 //if(intGe(mark, 0)) then
5814 498 comps := arrayGet(inComps, taskIdx);
5815 //print("getAllSCCsOfGraph: components are '" + stringDelimitList(List.map(comps, intString), ",") + "'\n");
5816 498 tmpSccs := List.append_reverse(comps, tmpSccs);
5817 //end if;
5818 end for;
5819 8 oSccs := listReverse(tmpSccs);
5820 end getAllSCCsOfGraph;
5821
5822 //TODO: Remove
5823 public function roundReal "author: Waurich TUD 2014-01
5824 Rounds a real to the nth decimal."
5825 input Real inReal;
5826 input Integer nIn;
5827 output Real outReal;
5828 protected
5829 Real real;
5830 algorithm
5831
2/4
✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 60 times.
60 real := inReal * (10.0 ^ nIn);
5832 60 real := floor(real);
5833
3/6
✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 60 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 60 times.
60 outReal := real / (10.0 ^ nIn);
5834 end roundReal;
5835
5836
5837 //--------------------------------------------------------
5838 // Get annotations from backendDAE and display in graphML
5839 //--------------------------------------------------------
5840
5841 protected function setAnnotationsForTasks "author: Waurich TUD 2014-05
5842 Sets annotations of variables and equations for every task in the array (index: task idx)."
5843 input TaskGraphMeta taskGraphInfo;
5844 input BackendDAE.BackendDAE backendDAE;
5845 input array<String> annotInfoIn;
5846 output array<String> annotInfoOut;
5847 protected
5848 BackendDAE.EqSystems systs;
5849 algorithm
5850 ✗ BackendDAE.DAE(eqs=systs) := backendDAE;
5851 ✗ (_,annotInfoOut) := List.fold1(systs,setAnnotationsForTasks1,taskGraphInfo,(0,annotInfoIn));
5852 end setAnnotationsForTasks;
5853
5854 protected function setAnnotationsForTasks1 "author: Waurich TUD 2014-05
5855 Sets annotations for a task of vars and equations of an equationsystem."
5856 input BackendDAE.EqSystem syst;
5857 input TaskGraphMeta taskGraphInfo;
5858 input tuple<Integer,array<String>> infoIn;
5859 output tuple<Integer,array<String>> infoOut;
5860 protected
5861 Integer idx;
5862 array<String> annots;
5863 BackendDAE.Variables vars;
5864 BackendDAE.EquationArray eqs;
5865 algorithm
5866 ✗ (idx,annots) := infoIn;
5867 ✗ BackendDAE.EQSYSTEM(orderedVars=vars,orderedEqs=eqs) := syst;
5868 //set annotations of variables
5869 ✗ annots := List.fold3(List.intRange(BackendVariable.varsSize(vars)),setAnnotationsForVar,vars,taskGraphInfo,idx,annots);
5870 ✗ infoOut := (BackendVariable.varsSize(vars)+idx,annots);
5871 end setAnnotationsForTasks1;
5872
5873 protected function setAnnotationsForVar "
5874 Sets the annotations of a variable in the annotArray."
5875 input Integer backendVarIdx;
5876 input BackendDAE.Variables vars;
5877 input TaskGraphMeta taskGraphInfo;
5878 input Integer eqSysOffset;
5879 input array<String> annotInfoIn;
5880 output array<String> annotInfoOut;
5881 algorithm
5882 annotInfoOut := matchcontinue taskGraphInfo
5883 local
5884 Integer compIdx, taskIdx;
5885 String annotString;
5886 BackendDAE.Var var;
5887 DAE.ComponentRef cr;
5888 Option<SCode.Comment> annot;
5889 array<list<Integer>> inComps;
5890 array<tuple<Integer,Integer,Integer>> varCompMapping;
5891 array<Integer> nodeMark;
5892 case TASKGRAPHMETA(inComps=inComps, varCompMapping=varCompMapping, nodeMark=nodeMark)
5893 algorithm
5894 ✗ var := BackendVariable.getVarAt(vars,backendVarIdx);
5895 ✗ BackendDump.printVar(var);
5896 ✗ true := BackendVariable.hasAnnotation(var);
5897 ✗ (compIdx,_,_) := arrayGet(varCompMapping,backendVarIdx+eqSysOffset);
5898 ✗ taskIdx := getCompInComps(compIdx,1,inComps,nodeMark);
5899 ✗ annot := BackendVariable.getAnnotationComment(var);
5900 ✗ annotString := arrayGet(annotInfoIn,taskIdx);
5901 ✗ cr := BackendVariable.varCref(var);
5902 ✗ annotString := annotString + "("+ComponentReferenceBasics.printComponentRefStr(cr)+": "+DAEDumpTypes.dumpCommentAnnotationStr(annot)+") ";
5903 ✗ arrayUpdate(annotInfoIn,taskIdx,annotString);
5904 then
5905 annotInfoIn;
5906 else annotInfoIn;
5907 end matchcontinue;
5908 end setAnnotationsForVar;
5909
5910
5911 //--------------------------------------------------------
5912 // Append removed equations like asserts to the DAE graph
5913 //--------------------------------------------------------
5914
5915 public function appendRemovedEquations "author: Waurich TUD 2014-07
5916 Appends to the graph (DAE-onlySCCs) all removed equations i.e. asserts..."
5917 input BackendDAE.BackendDAE dae;
5918 input TaskGraph graphIn;
5919 input TaskGraphMeta graphDataIn;
5920 output TaskGraph graphOut;
5921 output TaskGraphMeta graphDataOut;
5922 algorithm
5923 (graphOut,graphDataOut) := matchcontinue graphDataIn
5924 local
5925 Integer numNewComps;
5926 list<Integer> newComps;
5927 list<list<tuple<Integer,Integer>>> nodeVarLst;
5928 array<tuple<Integer,Integer,Integer>> varCompMap;
5929 TaskGraph graph;
5930 TaskGraphMeta graphData;
5931 BackendDAE.EquationArray remEqs;
5932 BackendDAE.Shared shared;
5933 list<BackendDAE.Equation> eqLst;
5934 list<list<DAE.ComponentRef>> crefsLst;
5935 array<list<Integer>> inComps1,inComps2;
5936 array<tuple<Integer,Integer,Integer>> varCompMapping1;
5937 array<tuple<Integer,Integer,Integer>> eqCompMapping1;
5938 array<list<Integer>> compParamMapping1;
5939 array<String> compNames1,compNames2;
5940 array<String> compDescs1,compDescs2;
5941 array<tuple<Integer,Real>> exeCosts1,exeCosts2;
5942 array<Communications> commCosts1;
5943 array<Integer> nodeMark1,nodeMark2;
5944 array<ComponentInfo> compInformations1, compInformations2;
5945 case _
5946 algorithm
5947 8 BackendDAE.DAE(shared = shared) := dae;
5948 8 remEqs := BackendDAEUtil.collapseRemovedEqs(dae);
5949 8 TASKGRAPHMETA(varCompMapping=varCompMap) := graphDataIn;
5950 8 eqLst := BackendEquation.equationList(remEqs);
5951 8 numNewComps := listLength(eqLst);
5952
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
8 true := intNe(numNewComps,0);
5953 6 crefsLst := List.map(eqLst,BackendEquation.equationCrefs);
5954 //print("crefs \n");List.map_0(crefsLst,ComponentReference.printComponentRefList);
5955 6 nodeVarLst := List.map2(crefsLst,getNodeForCrefLst,dae,varCompMap);
5956 //print("nodeVarLst"+stringDelimitList(List.map(nodeVarLst,printNodeVars),"\n")+"\n");
5957
5958 6 TASKGRAPHMETA(inComps=inComps1, varCompMapping=varCompMapping1, eqCompMapping=eqCompMapping1, compParamMapping=compParamMapping1, compNames=compNames1, compDescs=compDescs1, exeCosts=exeCosts1, commCosts=commCosts1, nodeMark=nodeMark1, compInformations=compInformations1) := graphDataIn;
5959 6 graph := arrayAppend(graphIn,arrayCreate(numNewComps,{}));
5960 6 newComps := List.intRange2(arrayLength(graphIn)+1,arrayLength(graphIn)+numNewComps);
5961 //print("newComps: "+stringDelimitList(List.map(newComps,intString)," | ")+"\n");
5962 6 graph := List.threadFold(nodeVarLst,newComps,addEdgesToGraph,graph);
5963
5964 5 inComps2 := listArray(List.map(newComps,List.create));
5965 5 compNames2 := arrayCreate(numNewComps,"assert");
5966 5 compDescs2 := listArray(List.map(eqLst,BackendDump.equationString));
5967 5 nodeMark2 := arrayCreate(numNewComps,-2);
5968 5 exeCosts2 := listArray(List.map1(eqLst,estimateEquationCosts,shared));
5969 5 compInformations2 := arrayCreate(numNewComps, COMPONENTINFO(false, false, true));
5970 5 inComps1 := arrayAppend(inComps1,inComps2);
5971 5 compNames1 := arrayAppend(compNames1,compNames2);
5972 5 compDescs1 := arrayAppend(compDescs1,compDescs2);
5973 5 nodeMark1 := arrayAppend(nodeMark1,nodeMark2);
5974 5 exeCosts1 := arrayAppend(exeCosts1,exeCosts2);
5975 5 compInformations1 := arrayAppend(compInformations1, compInformations2);
5976 5 commCosts1 := List.threadFold1(nodeVarLst,newComps,setCommCostsToParent,74.0,commCosts1);
5977 5 graphData := TASKGRAPHMETA(inComps1,varCompMapping1,eqCompMapping1,compParamMapping1,compNames1,compDescs1,exeCosts1,commCosts1,nodeMark1,compInformations1);
5978 then (graph,graphData);
5979 else (graphIn,graphDataIn);
5980 end matchcontinue;
5981 end appendRemovedEquations;
5982
5983 protected function estimateEquationCosts "author: Waurich TUD 2015-04
5984 Estimates costs for equations."
5985 input BackendDAE.Equation eqIn;
5986 input BackendDAE.Shared sharedIn;
5987 output tuple<Integer,Real> tplOut; //<Operations,Costs>
5988 protected
5989 Integer numAdd,numMul,numDiv,numTrig,numRel,numOth, numFuncs, numLog;
5990 BackendDAE.CompInfo compInfo;
5991 algorithm
5992 12 (_,(numAdd,numMul,numDiv,numTrig,numRel,numLog,numOth,numFuncs)) := BackendEquation.traverseExpsOfEquation(eqIn,function BackendDAEOptimize.countOperationsExp(shared=sharedIn),(0,0,0,0,0,0,0,0));
5993 12 compInfo := BackendDAE.NO_COMP(numAdd,numMul,numDiv,numTrig,numRel,numLog,numOth,numFuncs);
5994 12 tplOut := calculateCosts(compInfo);
5995 end estimateEquationCosts;
5996
5997 protected function printNodeVars
5998 input list<tuple<Integer,Integer>> nodes;
5999 output String s;
6000 algorithm
6001 ✗ s := ":" + stringDelimitList(List.map(nodes,printNodeVars1)," | ");
6002 end printNodeVars;
6003
6004 protected function printNodeVars1
6005 input tuple<Integer,Integer> node;
6006 output String s;
6007 algorithm
6008 ✗ s := "("+intString(Util.tuple21(node))+","+intString(Util.tuple22(node))+")";
6009 end printNodeVars1;
6010
6011 protected function setCommCostsToParent "author: Waurich TUD 2014-07
6012 Sets/updated the communication costs for the list of parents to the child node."
6013 input list<tuple<Integer,Integer>> parents; //<parentNodeIdx,varIdx>
6014 input Integer child;
6015 input Real reqCycles;
6016 input array<Communications> commCostsIn;
6017 output array<Communications> commCostsOut;
6018 algorithm
6019 12 commCostsOut := List.fold2(parents,setCommCosts,child,reqCycles,commCostsIn);
6020 end setCommCostsToParent;
6021
6022 protected function setCommCosts "author: Waurich TUD 2014-07
6023 Sets/updated the communication costs for the edge from parent to child node."
6024 input tuple<Integer,Integer> parent; //<parentNodeIdx,varIdx>
6025 input Integer child;
6026 input Real reqCycles;
6027 input array<Communications> commCostsIn;
6028 output array<Communications> commCostsOut;
6029 protected
6030 Communications row;
6031 Integer parentNodeIdx, varIdx;
6032 algorithm
6033 ✗ (parentNodeIdx,varIdx) := parent;
6034 ✗ row := arrayGet(commCostsIn,parentNodeIdx);
6035 ✗ row := List.filter1OnTrue(row,isCommunicationChildEqualToIdx,child);
6036 ✗ row := COMMUNICATION(1,{},{varIdx},{},{},child,reqCycles)::row;
6037 ✗ commCostsOut := arrayUpdate(commCostsIn,parentNodeIdx,row);
6038 end setCommCosts;
6039
6040 protected function isCommunicationChildEqualToIdx "author: marcusw
6041 Returns true if the child, stored in the iComm-object, is equals to the iIdx."
6042 input Communication iComm;
6043 input Integer iIdx;
6044 output Boolean isEq;
6045 protected
6046 Integer childNode;
6047 algorithm
6048 ✗ COMMUNICATION(childNode=childNode) := iComm;
6049 ✗ isEq := intNe(childNode,iIdx);
6050 end isCommunicationChildEqualToIdx;
6051
6052 protected function addEdgesToGraph "author: Waurich TUD 2014-07
6053 Adds several edges from the list of parent to child to the task graph."
6054 input list<tuple<Integer,Integer>> parents; //<nodeIdx, varIdx>
6055 input Integer child;
6056 input TaskGraph graphIn;
6057 output TaskGraph graphOut;
6058 algorithm
6059 24 graphOut := List.fold1(List.map(parents,Util.tuple21),addEdgeToGraph,child,graphIn);
6060 end addEdgesToGraph;
6061
6062 protected function addEdgeToGraph "author: Waurich TUD 2014-07
6063 Adds an edge from parent to child to the task graph."
6064 input Integer parent;
6065 input Integer child;
6066 input TaskGraph graphIn;
6067 output TaskGraph graphOut;
6068 protected
6069 list<Integer> row;
6070 algorithm
6071 2 row := arrayGet(graphIn,parent);
6072 1 row := List.unique(child::row);
6073 1 graphOut := arrayUpdate(graphIn,parent,row);
6074 end addEdgeToGraph;
6075
6076 protected function getNodeForCrefLst "author: Waurich TUD 2014-07
6077 Gets the node in which the var for the given cref is solved."
6078 input list<DAE.ComponentRef> iCrefs;
6079 input BackendDAE.BackendDAE iDae;
6080 input array<tuple<Integer,Integer,Integer>> iVarCompMap;
6081 output list<tuple<Integer,Integer>> oNodeVarLst; //<nodeIdx, varIdx>
6082 protected
6083 list<tuple<Integer,Integer>> tmpNodeVarLst;
6084 algorithm
6085 102 tmpNodeVarLst := List.map2(iCrefs,getNodeForCref,iDae,iVarCompMap);
6086 102 oNodeVarLst := List.filterOnTrue(tmpNodeVarLst,nodeIsDependent);
6087 //print("tmpNodeVarLst1 "+printNodeVars(tmpNodeVarLst)+"\n");
6088 end getNodeForCrefLst;
6089
6090 protected function nodeIsDependent "author: waurich
6091 If this node has no parent, it is independent."
6092 input tuple<Integer,Integer> node;
6093 output Boolean dep;
6094 protected
6095 Integer tpl1;
6096 algorithm
6097 130 (tpl1,_) := node;
6098 130 dep := intNe(tpl1,-1);
6099 end nodeIsDependent;
6100
6101 protected function getNodeForCref "author: Waurich TUD 2014-07
6102 Get the node- and var-idx for the given cref."
6103 input DAE.ComponentRef iCref;
6104 input BackendDAE.BackendDAE iDae;
6105 input array<tuple<Integer,Integer,Integer>> iVarCompMapping;
6106 output tuple<Integer,Integer> oNodeVarIdx; //<nodeIdx, varIdx>
6107 protected
6108 Integer eqSysIdx,varIdx,nodeIdx;
6109 BackendDAE.EqSystems eqSystems;
6110 algorithm
6111 //print("get Cref "+ComponentReference.crefStr(iCref)+"\n");
6112 130 BackendDAE.DAE(eqs=eqSystems) := iDae;
6113 130 (eqSysIdx,varIdx,_) := getNodeForCref1(eqSystems,iCref,1);
6114 //print("got var "+intString(varIdx)+" in eqSys "+intString(eqSysIdx)+"\n");
6115 130 nodeIdx := getNodeForVarIdx(varIdx,eqSysIdx,iVarCompMapping,varIdx);
6116 //print("got nodeIdx "+intString(nodeIdx)+"\n");
6117 130 oNodeVarIdx := (nodeIdx,varIdx);
6118 end getNodeForCref;
6119
6120 protected function getNodeForCref1
6121 input BackendDAE.EqSystems eqSystems;
6122 input DAE.ComponentRef cref;
6123 input Integer eqSysIdxIn;
6124 output Integer eqSysIdx;
6125 output Integer varIdx;
6126 output Boolean found;
6127 algorithm
6128 (eqSysIdx,varIdx,found) := matchcontinue eqSystems
6129 local
6130 Boolean b;
6131 Integer esIdx,vIdx;
6132 list<Integer> lst;
6133 BackendDAE.EqSystems rest;
6134 BackendDAE.Variables vars;
6135 list<BackendDAE.Var> varLst;
6136 case BackendDAE.EQSYSTEM(orderedVars = vars)::_
6137 algorithm
6138 //print("check cref: "+ComponentReferenceBasics.printComponentRefStr(cref)+"\n");
6139 589 (varLst,lst) := BackendVariable.getVar(cref,vars);
6140
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 101 times.
101 if intNe(listLength(lst),1) then
6141 ✗ print("Check if there is a assert or something that is dependent of arrayEquations");
6142 end if;
6143
2/2
✓ Branch 2 taken 21 times.
✓ Branch 3 taken 80 times.
101 if BackendVariable.isStateVar(listHead(varLst)) then // if its dependent on a state --> no edge in the task graph
6144 (esIdx,vIdx,b) := (-1,-1,false);
6145 else
6146 21 (esIdx,vIdx,b) := (eqSysIdxIn,listHead(lst),true);
6147 end if;
6148 101 then (esIdx,vIdx,b);
6149 case BackendDAE.EQSYSTEM()::rest
6150 algorithm
6151 488 (esIdx,vIdx,b) := getNodeForCref1(rest,cref,eqSysIdxIn+1);
6152 then (esIdx,vIdx,b);
6153 case {}
6154 29 then (-1,-1,false);
6155 end matchcontinue;
6156 end getNodeForCref1;
6157
6158 protected function getNodeForVarIdx"traverse the whole varCompMapping from eqSystem to eqSystem until we get the correct eqSystem."
6159 input Integer varIdx;
6160 input Integer eqSysIdx;
6161 input array<tuple<Integer,Integer,Integer>> varCompMapping;
6162 input Integer inTryThisIndex;
6163 output Integer node;
6164 protected
6165 Integer offset,eqSys,tryThisIndex=inTryThisIndex,n=0,arrayLengthVarCompMapping;
6166 algorithm
6167 arrayLengthVarCompMapping := arrayLength(varCompMapping);
6168 while true loop
6169
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 109 times.
130 if tryThisIndex >= 1 and tryThisIndex <= arrayLengthVarCompMapping then
6170 21 (node,eqSys,offset) := arrayGet(varCompMapping,tryThisIndex);
6171
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 if eqSys == eqSysIdx then
6172 21 node := node+varIdx-1;
6173 21 return;
6174 else
6175 ✗ tryThisIndex := offset+2;
6176 end if;
6177 elseif varIdx==-1 and eqSysIdx==-1 then
6178 node := -1;
6179 109 return;
6180 else
6181 ✗ print("HpcOmTaskGraph.getNodeForVarIdx failed\n");
6182 end if;
6183 ✗ n := n+1;
6184 ✗ if n>arrayLengthVarCompMapping then
6185 ✗ Error.addInternalError(getInstanceName() + " failed (there is a loop somewhere)", sourceInfo());
6186 ✗ fail();
6187 end if;
6188 end while;
6189 end getNodeForVarIdx;
6190
6191
6192 //----------------------------
6193 // MULTIRATE PARTITIONING
6194 //----------------------------
6195
6196 public function multirate_partitioning"partitions the task-graph so that every partition has a unique set of states which activate it.
6197 author: Waurich TUD 2016-01"
6198 input TaskGraph odeGraph;
6199 input TaskGraphMeta odeGraphData;
6200 input BackendDAE.BackendDAE backendDAE;
6201 input SimCode.SimCode simCode;
6202 input array<list<Integer>> sccSimEqMapping;
6203 output SimCode.PartitionData partitionDataOut;
6204 protected
6205 array<list<Integer>> stateTaskAssign;
6206 list<Integer> stateTasks;
6207 list<list<Integer>> tasksPerLevel, partitions;
6208 TaskGraph odeGraphT;
6209 Integer numPartitions;
6210 list<list<Integer>> activatorsForPartitions;
6211 list<Integer> stateToActivators;
6212 algorithm
6213 //get the levels of the taskgraph
6214 ✗ tasksPerLevel := HpcOmTaskGraph.getLevelNodes(odeGraph);
6215 ✗ print("tasksPerLevel "+stringDelimitList(List.map(tasksPerLevel,intLstString),"\n")+"\n");
6216
6217 //get the state tasks
6218 ✗ stateTasks := getLeafNodes(odeGraph);
6219 //!!We have to set up a simVar-task mapping somewhere. This function is only fine for the first try!!//
6220 ✗ stateTasks := multirate_orderStateTasksInSimVarStateOrder(stateTasks, odeGraphData, backendDAE, simCode); //so that the first activator corresponds to the first state ettc.
6221 ✗ print("stateTasks "+intLstString(stateTasks)+"\n");
6222
6223 //traverse levels top down and colour according to the states
6224 ✗ odeGraphT := AdjacencyMatrix.transposeAdjacencyMatrix(odeGraph,arrayLength(odeGraph));
6225 ✗ stateTaskAssign := multirate_assignTasksToStates(tasksPerLevel,stateTasks,odeGraphT);
6226 ✗ dumpStateAssign(stateTaskAssign);
6227
6228 //traverse tasks, group nodes of same partitions
6229 ✗ partitions := multirate_getPartitions(stateTaskAssign,stateTasks,odeGraphT);
6230 ✗ print("PARTITIONS :\n"+stringDelimitList(List.map(partitions,intLstString),"\n")+"\n");
6231
6232 //build the simcode.partitionData
6233 ✗ activatorsForPartitions := List.mapMap(partitions,listHead,function Array.getIndexFirst(inArray = stateTaskAssign));
6234 ✗ partitions := List.map1(partitions,getSimEqsIdxLstForSCCIdxLst,sccSimEqMapping); // convert to simEqSys indexes
6235 ✗ numPartitions := listLength(partitions);
6236 ✗ stateToActivators := List.intRange(listLength(stateTasks)); //if every state gets its own activator
6237 //print("PARTITIONS2 :\n"+stringDelimitList(List.map(partitions,intLstString),"\n")+"\n");
6238
6239 //fill partition data
6240 ✗ partitionDataOut := SimCode.PARTITIONDATA(numPartitions,partitions,activatorsForPartitions,stateToActivators);
6241 ✗ dumpPartitionData(partitionDataOut);
6242 end multirate_partitioning;
6243
6244
6245 protected function multirate_orderStateTasksInSimVarStateOrder"each activator maps one or more states.
6246 The order in the state-vector in simcode has to be the same as in the taskgraph"
6247 input list<Integer> stateTasks;
6248 input TaskGraphMeta taskGraphData;
6249 input BackendDAE.BackendDAE dae;
6250 input SimCode.SimCode simCode;
6251 output list<Integer> orderedTasks;
6252 protected
6253 Integer state,compIdx,eqSysIdx,offset,varIdx,simVarIdx;
6254 list<Integer> simVarIdxs, order;
6255 array<tuple<Integer,Integer,Integer>> varCompMapping;
6256 BackendDAE.Var var;
6257 BackendDAE.EqSystem eqSys;
6258 DAE.ComponentRef cref;
6259 SimCodeVar.SimVar simVar;
6260 list<BackendDAE.EqSystem> eqSystems;
6261 algorithm
6262 ✗ BackendDAE.DAE(eqs=eqSystems) := dae;
6263 simVarIdxs := {};
6264 ✗ for state in stateTasks loop
6265 ✗ compIdx := listHead(arrayGet(taskGraphData.inComps,state));
6266 ✗ (SOME((compIdx,eqSysIdx,offset)),varIdx) := Array.findFirstOnTrueWithIdx(taskGraphData.varCompMapping, function varMappingTupleCompEqual(compIdx=compIdx));
6267 ✗ eqSys := listGet(eqSystems,eqSysIdx);
6268 ✗ varIdx := varIdx-offset;
6269 ✗ var := BackendVariable.getVarAt(eqSys.orderedVars,varIdx);
6270 ✗ cref := var.varName;
6271 ✗ {simVar} := SimCodeUtil.getSimVars2Crefs({cref},simCode.crefToSimVarHT);
6272 ✗ simVarIdx := simVar.index;
6273 simVarIdxs := simVarIdx::simVarIdxs;
6274 end for;
6275 ✗ (_,order) := HpcOmScheduler.quicksortWithOrder(List.map(listReverse(simVarIdxs),intReal));
6276 ✗ orderedTasks := List.map1(order,List.getIndexFirst,stateTasks);
6277 end multirate_orderStateTasksInSimVarStateOrder;
6278
6279
6280 protected function varMappingTupleCompEqual
6281 input tuple<Integer,Integer,Integer> tpl;
6282 input Integer compIdx;
6283 output Boolean compEqual;
6284 algorithm
6285 ✗ compEqual := intEq(compIdx,Util.tuple31(tpl));
6286 end varMappingTupleCompEqual;
6287
6288
6289 protected function getSimEqIdxForSCCIdx"get the simEqSystem-index for a scc-index. if the scc is equation-system, only the first simEqsystem-index is returned.
6290 author:Waurich TUD 2016-01"
6291 input Integer sccIdx;
6292 input array<list<Integer>> sccSimEqMapping;
6293 output Integer simEqIdx;
6294 algorithm
6295 ✗ simEqIdx := listHead(arrayGet(sccSimEqMapping,sccIdx));
6296 end getSimEqIdxForSCCIdx;
6297
6298 protected function getSimEqsIdxLstForSCCIdxLst"getSimEqIdxForSCCIdx for a list of scc-indexes
6299 author:Waurich TUD 2016-01"
6300 input list<Integer> sccIdxs;
6301 input array<list<Integer>> sccSimEqMapping;
6302 output list<Integer> simEqIdxs;
6303 algorithm
6304 ✗ simEqIdxs := List.map1(sccIdxs,getSimEqIdxForSCCIdx,sccSimEqMapping);
6305 end getSimEqsIdxLstForSCCIdxLst;
6306
6307 protected function multirate_getPartitions "traverse all leave nodes and group tasks with same stateTaskAssign.
6308 repeat till there are no.
6309 author: Waurich TUD 2016-01"
6310 input array<list<Integer>> stateTaskAssign;
6311 input list<Integer> stateTasks;
6312 input TaskGraph odeGraphT;
6313 output list<list<Integer>> partitions = {};
6314 protected
6315 Integer numStates, numAssigns;
6316 list<Integer> leaveNodes, samePartTasks, partition, otherPartTasks, stateAss;
6317 array<Integer> visitedTasks;
6318 array<list<Integer>> leaveNodesWithNassigns;
6319 algorithm
6320 //which tasks have already been visited
6321 ✗ visitedTasks := arrayCreate(arrayLength(odeGraphT),-1);
6322
6323 //leave nodes with <arrayIdx> stateAssigns, in the first run, only states with one stateAssign are leaveNodes
6324 ✗ numStates := listLength(stateTasks);
6325 ✗ leaveNodesWithNassigns := arrayCreate(numStates, {});
6326 ✗ arrayUpdate(leaveNodesWithNassigns, 1, stateTasks);
6327
6328 //traverse the leave nodes with a certain number of stateAssigns
6329 ✗ for numAssigns in List.intRange(numStates) loop
6330 ✗ leaveNodes := arrayGet(leaveNodesWithNassigns,numAssigns);
6331 ✗ leaveNodes := List.unique(leaveNodes);
6332 //print("\nleaveNodes with "+intString(numAssigns)+" stateAssigns\n");
6333 //print("leaveNodes "+intLstString(leaveNodes)+"\n");
6334
6335 //traverse all these leaveNodes
6336 ✗ while not listEmpty(leaveNodes) loop
6337 ✗ stateAss := arrayGet(stateTaskAssign,listHead(leaveNodes));
6338
6339 // get the leave nodes of the same partition
6340 ✗ (samePartTasks,leaveNodes) := List.separateOnTrue(leaveNodes,function hasSameStateAssign(stateTaskAssign=stateTaskAssign,refStateAssign=stateAss));
6341
6342 // predecessorTasks
6343 ✗ (partition, otherPartTasks) := multirate_getPartitionPredecessors(samePartTasks,odeGraphT,stateTaskAssign,stateAss,visitedTasks);
6344 ✗ partition := List.sort(partition,intGt);
6345 //print("partition "+intLstString(partition)+"\n");
6346 //print("otherPartTasks "+intLstString(otherPartTasks)+"\n");
6347
6348 //dispatch the otherPartTasks to the lists of new leaveNodes in leaveNodesWithNassigns
6349 ✗ multirate_dispatchLeaveNodes(otherPartTasks, stateTaskAssign, leaveNodesWithNassigns);
6350
6351 partitions := partition::partitions;
6352 end while;
6353 end for;
6354 end multirate_getPartitions;
6355
6356 protected function multirate_dispatchLeaveNodes"dispatches the given tasks to the lists of leaveNodes with a certain number of stateAss"
6357 input list<Integer> tasksIn;
6358 input array<list<Integer>> stateTaskAssign;
6359 input array<list<Integer>> leaveNodesWithNassigns;
6360 protected
6361 Integer numAss;
6362 list<Integer> stateAss, leaveNodes;
6363 algorithm
6364 ✗ for task in tasksIn loop
6365 ✗ stateAss := arrayGet(stateTaskAssign,task);
6366 ✗ numAss := listLength(stateAss);
6367 ✗ leaveNodes := arrayGet(leaveNodesWithNassigns, numAss);
6368 leaveNodes := task::leaveNodes;
6369 ✗ arrayUpdate(leaveNodesWithNassigns,numAss,leaveNodes);
6370 end for;
6371 end multirate_dispatchLeaveNodes;
6372
6373
6374 protected function multirate_getPartitionPredecessors"gets all predecessors with the same stateAssign for the given leave nodes.
6375 All predecessors which have different stateAssigns are collected in otherLeaveNodes.
6376 author: Waurich TUD 2016-01"
6377 input list<Integer> leavesIn; // all leaves with the same partition
6378 input TaskGraph odeGraphT;
6379 input array<list<Integer>> stateTaskAssign;
6380 input list<Integer> refStateAssign;
6381 input array<Integer> visitedTasks;
6382 output list<Integer> partitionTasks = {};
6383 output list<Integer> otherLeaveNodes = {};
6384 protected
6385 Boolean cont;
6386 Integer task;
6387 list<Integer> tasks, predecessors, samePartTasks, otherLeaves;
6388 algorithm
6389 // BFS to find all predecessors of same partition
6390 cont := true;
6391 tasks := leavesIn;
6392 ✗ while cont loop
6393 ✗ task::tasks := tasks;
6394 //print("check task "+intString(task)+"\n");
6395 ✗ predecessors := arrayGet(odeGraphT,task);
6396 ✗ predecessors := List.filter1OnTrue(predecessors, taskIsNotVisited, visitedTasks);
6397 ✗ (samePartTasks,otherLeaves) := List.separateOnTrue(predecessors,function hasSameStateAssign(stateTaskAssign=stateTaskAssign,refStateAssign=refStateAssign));
6398 //print("samePartTasks "+intLstString(samePartTasks)+"\n");
6399 //print("otherLeaves "+intLstString(otherLeaves)+"\n");
6400
6401 // add the tasks to the corresponding lists
6402 partitionTasks := task::partitionTasks;
6403 ✗ partitionTasks := listAppend(samePartTasks,partitionTasks);
6404 ✗ tasks := listAppend(samePartTasks,tasks);
6405 ✗ otherLeaveNodes := listAppend(otherLeaves,otherLeaveNodes);
6406
6407 // update the visitedTasks
6408 ✗ arrayUpdate(visitedTasks,task,0);
6409 ✗ List.map2_0(samePartTasks, Array.updateIndexFirst, 0, visitedTasks);
6410 ✗ List.map2_0(otherLeaves, Array.updateIndexFirst, 0, visitedTasks);
6411
6412 ✗ if listEmpty(tasks) then cont := false; end if;
6413 end while;
6414 ✗ partitionTasks := List.unique(partitionTasks); // this can be removed if we consider a bit more in the taskVisited
6415 ✗ otherLeaveNodes := List.unique(otherLeaveNodes); // ...
6416 end multirate_getPartitionPredecessors;
6417
6418 protected function taskIsNotVisited
6419 input Integer task;
6420 input array<Integer> visitedTasks;
6421 output Boolean isNotVisited;
6422 algorithm
6423 ✗ isNotVisited := intEq(-1,arrayGet(visitedTasks,task));
6424 end taskIsNotVisited;
6425
6426 protected function hasSameStateAssign"gets the assigned states for a task and compares with the refStateAssign"
6427 input Integer task;
6428 input array<list<Integer>> stateTaskAssign;
6429 input list<Integer> refStateAssign;
6430 output Boolean sameStateAssign;
6431 algorithm
6432 ✗ sameStateAssign := List.isEqual(arrayGet(stateTaskAssign,task),refStateAssign,true);
6433 end hasSameStateAssign;
6434
6435 protected function multirate_assignTasksToStates"which task is evident for which state"
6436 input list<list<Integer>> tasksPerLevel;
6437 input list<Integer> stateTasks;
6438 input TaskGraph odeGraphT;
6439 output array<list<Integer>> stateTaskAssignOut;
6440 protected
6441 Integer taskIdx;
6442 list<Integer> assignments, predecessors;
6443 algorithm
6444 // create stateTaskAssignArray
6445 ✗ stateTaskAssignOut := arrayCreate(arrayLength(odeGraphT),{});
6446
6447 // assign the tasks for the states
6448 taskIdx := 1;
6449 ✗ for task in stateTasks loop
6450 ✗ stateTaskAssignOut := arrayUpdate(stateTaskAssignOut,task,{taskIdx});
6451 ✗ taskIdx := taskIdx+1;
6452 end for;
6453
6454 //traverse all levels top down and assign the predecessors with the same state assignment
6455 ✗ for levelTasks in listReverse(tasksPerLevel) loop
6456 ✗ for task in levelTasks loop
6457 //print("task: "+intString(task)+"\n");
6458 ✗ assignments := arrayGet(stateTaskAssignOut,task);
6459 ✗ predecessors := arrayGet(odeGraphT,task);
6460 ✗ stateTaskAssignOut := List.fold1(predecessors,appendToElementUnique,assignments,stateTaskAssignOut);
6461 end for;
6462 end for;
6463 ✗ stateTaskAssignOut := Array.map1(stateTaskAssignOut,List.sort,intGt);
6464 end multirate_assignTasksToStates;
6465
6466 protected function appendToElementUnique<T>
6467 "Appends a list to a list element of an array and applies List.unique."
6468 input Integer inIndex;
6469 input list<T> inElements;
6470 input array<list<T>> inArray;
6471 output array<list<T>> outArray;
6472 algorithm
6473 ✗ outArray := arrayUpdate(inArray, inIndex, List.unique(listAppend(inArray[inIndex], inElements)));
6474 end appendToElementUnique;
6475
6476 protected function dumpStateAssign
6477 input array<list<Integer>> stateAssign;
6478 algorithm
6479 ✗ print("stateAssign "+stringDelimitList(List.mapArray(stateAssign, intLstString),"\n")+"\n");
6480 end dumpStateAssign;
6481
6482 protected function dumpPartitionData"dumps the partitiondata info.
6483 author: Waurich TUD 2016-01"
6484 input SimCode.PartitionData partData;
6485 protected
6486 Integer numPartitions, act, part, state;
6487 list<list<Integer>> activatorsForPartitions, partitions;
6488 list<Integer> stateToActivators;
6489 algorithm
6490 ✗ SimCode.PARTITIONDATA(numPartitions=numPartitions, partitions=partitions, activatorsForPartitions=activatorsForPartitions, stateToActivators=stateToActivators) := partData;
6491 ✗ print("Multirate Partition Data\n");
6492 ✗ print(intString(numPartitions)+" partitions:\n");
6493 act := 1;
6494 ✗ for state in stateToActivators loop
6495 ✗ print("activator "+intString(act)+" is state "+intString(state)+"\n");
6496 ✗ act := act+1;
6497 end for;
6498 ✗ print("\n");
6499 ✗ for part in 1:numPartitions loop
6500 //print("activators: "+intLstString(listGet(activatorsForPartitions,part))+"\t\t\t\tnodes: \t"+intLstString(listGet(partitions,part))+"\n\n");
6501 ✗ print("activators: "+intLstString(listGet(activatorsForPartitions,part))+"\t\t\t\tderStateTasks: "+intLstString(List.map1(listGet(activatorsForPartitions,part),List.getIndexFirst,stateToActivators))+"\t\t\t\tnodes: \t"+intLstString(listGet(partitions,part))+"\n");
6502 end for;
6503 end dumpPartitionData;
6504
6505 //----------------------------
6506 // MAPPING FUNCTIONS
6507 //----------------------------
6508
6509 public function setUpHpcOmMapping "author: waurich 12-2015
6510 Creates mappings between simcode and backendDAE for the hpcom module."
6511 input BackendDAE.BackendDAE daeIn;
6512 input SimCode.SimCode simCodeIn;
6513 input Integer lastEqMappingIdx;
6514 input list<tuple<Integer,Integer>> equationSccMappingIn; //Maps each simEq to the scc
6515 output array<Integer> simeqCompMapping; //Maps each simEq to the scc
6516 output array<list<Integer>> sccSimEqMapping; //Maps each scc to a list of simEqs
6517 output array<list<Integer>> daeSccSimEqMapping; //Maps each scc to a list of simEqs, including removed equations like asserts
6518 protected
6519 Integer highestSccIdx, compCountPlusDummy;
6520 list<tuple<Integer,Integer>> equationSccMapping,equationSccMapping1;
6521 BackendDAE.StrongComponents allComps;
6522 algorithm
6523 8 (allComps,_) := getSystemComponents(daeIn);
6524 8 highestSccIdx := findHighestSccIdxInMapping(equationSccMappingIn,-1);
6525 8 compCountPlusDummy := listLength(allComps)+1;
6526 8 equationSccMapping1 := removeDummyStateFromMapping(equationSccMappingIn);
6527 //the mapping can contain a dummy state as first scc
6528
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 equationSccMapping := if intEq(highestSccIdx, compCountPlusDummy) then equationSccMapping1 else equationSccMappingIn;
6529 8 sccSimEqMapping := convertToSccSimEqMapping(equationSccMapping, listLength(allComps));
6530 8 simeqCompMapping := convertToSimeqCompMapping(equationSccMapping, lastEqMappingIdx);
6531 //for the dae-system
6532 8 daeSccSimEqMapping := listArray(List.map(SimCodeUtil.getRemovedEquationSimEqSysIdxes(simCodeIn),List.create));
6533 8 daeSccSimEqMapping := arrayAppend(sccSimEqMapping,daeSccSimEqMapping);
6534
6535 //_ = getSimEqIdxSimEqMapping(simCode.allEquations, arrayLength(simeqCompMapping)); // CAN WE REMOVE IT????
6536 //dumpSimEqSCCMapping(simeqCompMapping);
6537 //dumpSccSimEqMapping(sccSimEqMapping);
6538 end setUpHpcOmMapping;
6539
6540 protected function findHighestSccIdxInMapping "author: marcusw
6541 Find the highest scc-index in the mapping list."
6542 input list<tuple<Integer,Integer>> iEquationSccMapping; //<simEqIdx,sccIdx>
6543 input Integer iHighestIndex;
6544 output Integer oIndex;
6545 protected
6546 Integer eqIdx, sccIdx;
6547 list<tuple<Integer,Integer>> rest;
6548 algorithm
6549 oIndex := match iEquationSccMapping
6550 case (eqIdx,sccIdx)::rest guard intGt(sccIdx,iHighestIndex)
6551 8 then findHighestSccIdxInMapping(rest,sccIdx);
6552 case (eqIdx,sccIdx)::rest
6553 1523 then findHighestSccIdxInMapping(rest,iHighestIndex);
6554 else iHighestIndex;
6555 end match;
6556 end findHighestSccIdxInMapping;
6557
6558 protected function removeDummyStateFromMapping "author: marcusw
6559 Removes all mappings with sccIdx=1 from the list and decrements all other scc-indices by 1."
6560 input list<tuple<Integer,Integer>> iEquationSccMapping;
6561 output list<tuple<Integer,Integer>> oEquationSccMapping;
6562 algorithm
6563 8 oEquationSccMapping := List.fold(iEquationSccMapping, removeDummyStateFromMapping1, {});
6564 end removeDummyStateFromMapping;
6565
6566 protected function removeDummyStateFromMapping1 "author: marcusw
6567 Helper function of removeDummyStateFromMapping. Handles one list element."
6568 input tuple<Integer,Integer> iTuple; //<eqIdx,sccIdx>
6569 input list<tuple<Integer,Integer>> iNewList;
6570 output list<tuple<Integer,Integer>> oNewList;
6571 protected
6572 Integer eqIdx,sccIdx;
6573 tuple<Integer,Integer> newElem;
6574 algorithm
6575 oNewList := match iTuple
6576 case (eqIdx,sccIdx) guard intEq(sccIdx,1)
6577 then iNewList;
6578 case (eqIdx,sccIdx)
6579 algorithm
6580 1523 newElem := (eqIdx,sccIdx-1);
6581 then newElem::iNewList;
6582 else
6583 algorithm
6584 ✗ print("removeDummyStateFromMapping1 failed\n");
6585 then iNewList;
6586 end match;
6587 end removeDummyStateFromMapping1;
6588
6589 protected function convertToSccSimEqMapping "author: marcusw
6590 Converts the given mapping (simEqIndex -> sccIndex) to the inverse mapping (sccIndex->simEqIndex)."
6591 input list<tuple<Integer,Integer>> iMapping; //the mapping (simEqIndex -> sccIndex)
6592 input Integer numOfSccs; //important for arrayCreate
6593 output array<list<Integer>> oMapping; //the created mapping (sccIndex->simEqIndex)
6594 protected
6595 array<list<Integer>> tmpMapping;
6596 algorithm
6597 8 tmpMapping := arrayCreate(numOfSccs,{});
6598 //print("convertToSccSimEqMapping with " + intString(numOfSccs) + " sccs.\n");
6599 8 List.fold(iMapping, convertToSccSimEqMapping1, tmpMapping);
6600 oMapping := tmpMapping;
6601 end convertToSccSimEqMapping;
6602
6603 protected function convertToSccSimEqMapping1 "author: marcusw
6604 Helper function for convertToSccSimEqMapping. It will update the arrayIndex of the given mapping value."
6605 input tuple<Integer,Integer> iMapping; //<simEqIdx,sccIdx>
6606 input array<list<Integer>> iSccMapping;
6607 output array<list<Integer>> oSccMapping;
6608 protected
6609 Integer i1,i2;
6610 List<Integer> tmpList;
6611 algorithm
6612 1531 (i1,i2) := iMapping;
6613 //print("convertToSccSimEqMapping1 accessing index " + intString(i2) + ".\n");
6614 1531 tmpList := arrayGet(iSccMapping,i2);
6615 tmpList := i1 :: tmpList;
6616 1531 oSccMapping := arrayUpdate(iSccMapping,i2,tmpList);
6617 end convertToSccSimEqMapping1;
6618
6619 protected function convertToSimeqCompMapping "author: marcusw
6620 Converts the given mapping (simEqIndex -> sccIndex) bases on tuples to an array mapping."
6621 input list<tuple<Integer,Integer>> iMapping; //<simEqIdx,sccIdx>
6622 input Integer numOfSimEqs;
6623 output array<Integer> oMapping; //maps each simEq to the scc
6624 protected
6625 array<Integer> tmpMapping;
6626 algorithm
6627 8 tmpMapping := arrayCreate(numOfSimEqs, -1);
6628 8 oMapping := List.fold(iMapping, convertToSimeqCompMapping1, tmpMapping);
6629 end convertToSimeqCompMapping;
6630
6631 protected function convertToSimeqCompMapping1 "author: marcusw
6632 Helper function for convertToSimeqCompMapping. It will update the array at the given index."
6633 input tuple<Integer,Integer> iSimEqTuple; //<simEqIdx,sccIdx>
6634 input array<Integer> iMapping;
6635 output array<Integer> oMapping;
6636 protected
6637 Integer simEqIdx,sccIdx;
6638 algorithm
6639 1531 (simEqIdx,sccIdx) := iSimEqTuple;
6640 //print("convertToSimeqCompMapping1 " + intString(simEqIdx) + " .. " + intString(sccIdx) + " iMapping_len: " + intString(arrayLength(iMapping)) + "\n");
6641 1531 oMapping := arrayUpdate(iMapping,simEqIdx,sccIdx);
6642 end convertToSimeqCompMapping1;
6643
6644 protected function getSimEqIdxSimEqMapping "author: marcusw
6645 Get a mapping from simEqIdx -> option(simEq)."
6646 input list<SimCode.SimEqSystem> iAllEquations;
6647 input Integer iSimEqSystemHighestIdx;
6648 output array<Option<SimCode.SimEqSystem>> oMapping;
6649 protected
6650 array<Option<SimCode.SimEqSystem>> tmpMapping;
6651 algorithm
6652 ✗ tmpMapping := arrayCreate(iSimEqSystemHighestIdx, NONE());
6653 ✗ oMapping := List.fold(iAllEquations, getSimEqIdxSimEqMapping1, tmpMapping);
6654 end getSimEqIdxSimEqMapping;
6655
6656 protected function getSimEqIdxSimEqMapping1 "author: marcusw
6657 Helper function that adds the index of the given equation to the mapping."
6658 input SimCode.SimEqSystem iEquation;
6659 input array<Option<SimCode.SimEqSystem>> iMapping;
6660 output array<Option<SimCode.SimEqSystem>> oMapping;
6661 protected
6662 Integer simEqIdx;
6663 array<Option<SimCode.SimEqSystem>> tmpMapping;
6664 algorithm
6665 oMapping := matchcontinue iMapping
6666 case _
6667 algorithm
6668 ✗ (simEqIdx,_) := HpcOmCodegenUtil.getIndexBySimCodeEq(iEquation);
6669 ✗ tmpMapping := arrayUpdate(iMapping, simEqIdx, SOME(iEquation));
6670 then tmpMapping;
6671 else
6672 algorithm
6673 ✗ (simEqIdx,_) := HpcOmCodegenUtil.getIndexBySimCodeEq(iEquation);
6674 //print("getSimEqIdxSimEqMapping1: Can't access idx " + intString(simEqIdx) + "\n");
6675 then iMapping;
6676 end matchcontinue;
6677 end getSimEqIdxSimEqMapping1;
6678
6679 protected function getSimCodeEqByIndexAndMapping "author: marcusw
6680 Returns the SimEqSystem which has the given Index."
6681 input array<Option<SimCode.SimEqSystem>> iSimEqIdxSimEqMapping; //All SimEqSystems
6682 input Integer iIdx; //The index of the required system
6683 output SimCode.SimEqSystem oSimEqSystem;
6684 protected
6685 Option<SimCode.SimEqSystem> tmpSimEqSystem;
6686 algorithm
6687 ✗ tmpSimEqSystem := arrayGet(iSimEqIdxSimEqMapping, iIdx);
6688 ✗ oSimEqSystem := getSimCodeEqByIndexAndMapping1(tmpSimEqSystem, iIdx);
6689 end getSimCodeEqByIndexAndMapping;
6690
6691 protected function getSimCodeEqByIndexAndMapping1 "author: marcusw
6692 Returns the SimEqSystem if it's not NONE()."
6693 input Option<SimCode.SimEqSystem> iSimEqSystem;
6694 input Integer iIdx;
6695 output SimCode.SimEqSystem oSimEqSystem;
6696 protected
6697 SimCode.SimEqSystem tmpSys;
6698 algorithm
6699 oSimEqSystem := match iSimEqSystem
6700 case SOME(tmpSys)
6701 then tmpSys;
6702 else
6703 algorithm
6704 ✗ print("getSimCodeEqByIndexAndMapping1 failed. Looking for Index " + intString(iIdx) + "\n");
6705 //print(" -- available indices: " + stringDelimitList(List.map(List.map(iEqs,getIndexBySimCodeEq), intString), ",") + "\n");
6706 ✗ then fail();
6707 end match;
6708 end getSimCodeEqByIndexAndMapping1;
6709
6710 protected function getSimCodeEqsByTaskList "author: marcusw
6711 Get the simCode.SimEqSystem - objects references by the given tasks."
6712 input list<HpcOmSimCode.Task> iTaskList;
6713 input array<Option<SimCode.SimEqSystem>> iSimEqIdxSimEqMapping;
6714 output list<SimCode.SimEqSystem> oSimEqs;
6715 protected
6716 list<list<SimCode.SimEqSystem>> tmpSimEqs;
6717 algorithm
6718 ✗ tmpSimEqs := List.map1(iTaskList, getSimCodeEqsByTaskList0, iSimEqIdxSimEqMapping);
6719 ✗ oSimEqs := List.flatten(tmpSimEqs);
6720 end getSimCodeEqsByTaskList;
6721
6722 protected function getSimCodeEqsByTaskList0 "author: marcusw
6723 Get the simCode.SimEqSystem - objects references by the given task."
6724 input HpcOmSimCode.Task iTask;
6725 input array<Option<SimCode.SimEqSystem>> iSimEqIdxSimEqMapping;
6726 output list<SimCode.SimEqSystem> oSimEqs;
6727 protected
6728 list<Integer> eqIdc;
6729 list<SimCode.SimEqSystem> tmpSimEqs;
6730 algorithm
6731 oSimEqs := match iTask
6732 case HpcOmSimCode.CALCTASK(eqIdc=eqIdc)
6733 algorithm
6734 ✗ tmpSimEqs := List.map1r(eqIdc, getSimCodeEqByIndexAndMapping, iSimEqIdxSimEqMapping);
6735 then tmpSimEqs;
6736 case HpcOmSimCode.CALCTASK_LEVEL(eqIdc=eqIdc)
6737 algorithm
6738 ✗ tmpSimEqs := List.map1r(eqIdc, getSimCodeEqByIndexAndMapping, iSimEqIdxSimEqMapping);
6739 then tmpSimEqs;
6740 else {};
6741 end match;
6742 end getSimCodeEqsByTaskList0;
6743
6744 protected function dumpSimEqSCCMapping "author: marcusw
6745 Prints the given mapping out to the console."
6746 input array<Integer> iSccMapping;
6747 protected
6748 String text;
6749 algorithm
6750 text := "SimEqToSCCMapping";
6751 ✗ (_,text) := Array.fold(iSccMapping, dumpSimEqSCCMapping1, (1,text));
6752 ✗ print(text + "\n");
6753 end dumpSimEqSCCMapping;
6754
6755 protected function dumpSimEqSCCMapping1 "author: marcusw
6756 Helper function of dumpSimEqSCCMapping to print one mapping entry."
6757 input Integer iMapping;
6758 input tuple<Integer,String> iIndexText;
6759 output tuple<Integer,String> oIndexText;
6760 protected
6761 Integer iIndex;
6762 String text, iText;
6763 algorithm
6764 ✗ (iIndex,iText) := iIndexText;
6765 ✗ text := intString(iMapping);
6766 ✗ text := iText + "\nSimEq " + intString(iIndex) + ": {" + text + "}";
6767 ✗ oIndexText := (iIndex+1,text);
6768 end dumpSimEqSCCMapping1;
6769
6770 protected function dumpSccSimEqMapping "author: marcusw
6771 Prints the given mapping out to the console."
6772 input array<list<Integer>> iSccMapping;
6773 protected
6774 String text;
6775 algorithm
6776 text := "SccToSimEqMapping";
6777 ✗ (_,text) := Array.fold(iSccMapping, dumpSccSimEqMapping1, (1,text));
6778 ✗ print(text + "\n");
6779 end dumpSccSimEqMapping;
6780
6781 protected function dumpSccSimEqMapping1 "author: marcusw
6782 Helper function of dumpSccSimEqMapping to print one mapping list."
6783 input list<Integer> iMapping;
6784 input tuple<Integer,String> iIndexText;
6785 output tuple<Integer,String> oIndexText;
6786 protected
6787 Integer iIndex;
6788 String text, iText;
6789 algorithm
6790 ✗ (iIndex,iText) := iIndexText;
6791 ✗ text := List.fold(iMapping, dumpSccSimEqMapping2, " ");
6792 ✗ text := iText + "\nSCC " + intString(iIndex) + ": {" + text + "}";
6793 ✗ oIndexText := (iIndex+1,text);
6794 end dumpSccSimEqMapping1;
6795
6796 protected function dumpSccSimEqMapping2 "author: marcusw
6797 Helper function of dumpSccSimEqMapping1 to print one mapping element."
6798 input Integer iIndex;
6799 input String iText;
6800 output String oText;
6801 algorithm
6802 ✗ oText := iText + intString(iIndex) + " ";
6803 end dumpSccSimEqMapping2;
6804
6805
6806 annotation(__OpenModelica_Interface="backend");
6807 end HpcOmTaskGraph;
6808