Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 70.6% 36 / 0 / 51
Functions: -% 0 / 1 / 1
Branches: 54.5% 12 / 0 / 22

OMCompiler/Compiler/SimCode/HpcOmCodegenUtil.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 HpcOmCodegenUtil
37 "The HpcOm schedule and task-graph queries the code generators need."
38
39 import HpcOmSimCode;
40 import SimCode;
41
42 protected
43 import Error;
44 import List;
45
46 public
47
48 public function getTasksOfTaskList
49 input HpcOmSimCode.TaskList iTaskList;
50 output list<HpcOmSimCode.Task> oTasks;
51 protected
52 list<HpcOmSimCode.Task> tasks;
53 algorithm
54 oTasks := match iTaskList
55 case HpcOmSimCode.PARALLELTASKLIST(tasks=tasks)
56 then tasks;
57 case HpcOmSimCode.SERIALTASKLIST(tasks=tasks)
58 then tasks;
59 else
60 algorithm
61 ✗ print("getTasksOfTaskList failed! Unsupported task list.\n");
62 then {};
63 end match;
64 end getTasksOfTaskList;
65
66 public function convertFixedLevelScheduleToLevelThreadLists
67 "Convert the given LevelSchedule to an array of thread-tasks for each level.
68 author:marcusw"
69 input HpcOmSimCode.Schedule iSchedule;
70 input Integer iNumOfThreads;
71 output list<array<list<HpcOmSimCode.Task>>> oLevelThreadLists;
72 protected
73 list<HpcOmSimCode.TaskList> tasksOfLevels;
74 list<array<list<HpcOmSimCode.Task>>> tmpLevelThreadLists;
75 algorithm
76 oLevelThreadLists := match iSchedule
77 case HpcOmSimCode.LEVELSCHEDULE(tasksOfLevels=tasksOfLevels,useFixedAssignments=true)
78 algorithm
79 ✗ tmpLevelThreadLists := List.map(tasksOfLevels, function convertFixedLevelScheduleToLevelThreadLists0(iNumOfThreads=iNumOfThreads));
80 then tmpLevelThreadLists;
81 else
82 then {};
83 end match;
84 end convertFixedLevelScheduleToLevelThreadLists;
85
86 protected function convertFixedLevelScheduleToLevelThreadLists0
87 input HpcOmSimCode.TaskList iTasksOfLevel;
88 input Integer iNumOfThreads;
89 output array<list<HpcOmSimCode.Task>> oLevelThreadLists;
90 protected
91 list<HpcOmSimCode.Task> tasks;
92 HpcOmSimCode.Task task;
93 Integer threadIdx;
94 array<list<HpcOmSimCode.Task>> tmpLevelThreadLists;
95 algorithm
96 ✗ tasks := getTasksOfTaskList(iTasksOfLevel);
97 ✗ tmpLevelThreadLists := arrayCreate(iNumOfThreads, {});
98 ✗ for task in listReverse(tasks) loop
99 ✗ HpcOmSimCode.CALCTASK_LEVEL(threadIdx=SOME(threadIdx)) := task;
100 ✗ tmpLevelThreadLists := arrayUpdate(tmpLevelThreadLists, threadIdx, task::arrayGet(tmpLevelThreadLists, threadIdx));
101 end for;
102 oLevelThreadLists := tmpLevelThreadLists;
103 end convertFixedLevelScheduleToLevelThreadLists0;
104
105 public function convertFixedLevelScheduleToTaskLists
106 "Convert the given LevelSchedule to an list of task for each level and each thread.
107 author:marcusw"
108 input HpcOmSimCode.Schedule iOdeSchedule; //mapping level -> tasks
109 input HpcOmSimCode.Schedule iDaeSchedule;
110 input HpcOmSimCode.Schedule iZeroFuncSchedule;
111 input Integer iNumOfThreads;
112 output array<tuple<list<list<HpcOmSimCode.Task>>,list<list<HpcOmSimCode.Task>>,list<list<HpcOmSimCode.Task>>>> oThreadLevelTasks; //mapping thread -> (level -> tasks ODE, level -> tasks DAE, level -> tasks ZeroFunc)
113 protected
114 list<HpcOmSimCode.TaskList> tasksOfLevelsOde, tasksOfLevelsDae, tasksOfLevelsZeroFunc;
115 list<array<list<HpcOmSimCode.Task>>> tmpThreadLevelTasksDae, tmpThreadLevelTasksOde, tmpThreadLevelTasksZeroFunc; //level -> thread -> tasklist
116 array<tuple<list<list<HpcOmSimCode.Task>>, list<list<HpcOmSimCode.Task>>, list<list<HpcOmSimCode.Task>>>> tmpResultLists;
117 algorithm
118 oThreadLevelTasks := match(iOdeSchedule, iDaeSchedule, iZeroFuncSchedule)
119 case(HpcOmSimCode.LEVELSCHEDULE(tasksOfLevels=tasksOfLevelsOde,useFixedAssignments=true), HpcOmSimCode.LEVELSCHEDULE(tasksOfLevels=tasksOfLevelsDae,useFixedAssignments=true), HpcOmSimCode.LEVELSCHEDULE(tasksOfLevels=tasksOfLevelsZeroFunc,useFixedAssignments=true))
120 algorithm
121 1 tmpResultLists := arrayCreate(iNumOfThreads, ({},{},{}));
122 1 tmpThreadLevelTasksOde := List.map1(tasksOfLevelsOde, convertFixedLevelScheduleToTaskListsForLevel, iNumOfThreads);
123 1 tmpThreadLevelTasksDae := List.map1(tasksOfLevelsDae, convertFixedLevelScheduleToTaskListsForLevel, iNumOfThreads);
124 1 tmpThreadLevelTasksZeroFunc := List.map1(tasksOfLevelsZeroFunc, convertFixedLevelScheduleToTaskListsForLevel, iNumOfThreads);
125 //print("convertFixedLevelScheduleToTaskLists: len of tmpThreadLevelTasksOde=" + intString(listLength(tmpThreadLevelTasksOde)) + "\n");
126 1 tmpResultLists := List.fold(tmpThreadLevelTasksOde, function convertFixedLevelScheduleToTaskLists1(iCurrentThreadIdx=1, iModifiedSystemIdx=0), tmpResultLists);
127 1 tmpResultLists := List.fold(tmpThreadLevelTasksDae, function convertFixedLevelScheduleToTaskLists1(iCurrentThreadIdx=1, iModifiedSystemIdx=1), tmpResultLists);
128 1 tmpResultLists := List.fold(tmpThreadLevelTasksZeroFunc, function convertFixedLevelScheduleToTaskLists1(iCurrentThreadIdx=1, iModifiedSystemIdx=2), tmpResultLists);
129 //print("convertFixedLevelScheduleToTaskLists: len of tmpResultLists[0]=" + intString(listLength(Util.tuple21(arrayGet(tmpResultLists, 1)))) + "\n");
130 1 tmpResultLists := revertTaskLists(1, tmpResultLists);
131 //print("convertFixedLevelScheduleToTaskLists: len of tmpResultLists[0]=" + intString(listLength(Util.tuple21(arrayGet(tmpResultLists, 1)))) + "\n");
132 then tmpResultLists;
133 else
134 algorithm
135 ✗ tmpResultLists := arrayCreate(iNumOfThreads, ({},{},{}));
136 then tmpResultLists;
137 end match;
138 end convertFixedLevelScheduleToTaskLists;
139
140 protected function convertFixedLevelScheduleToTaskLists1
141 "Add the task list of the given array-index to the result list.
142 author:marcusw"
143 input array<list<HpcOmSimCode.Task>> iLevelTasks;
144 input Integer iCurrentThreadIdx;
145 input Integer iModifiedSystemIdx; //0 = ODE, 1 = DAE, 2 = ZeroFunc
146 input array<tuple<list<list<HpcOmSimCode.Task>>, list<list<HpcOmSimCode.Task>>, list<list<HpcOmSimCode.Task>>>> iResultList;
147 output array<tuple<list<list<HpcOmSimCode.Task>>, list<list<HpcOmSimCode.Task>>, list<list<HpcOmSimCode.Task>>>> oResultList;
148 protected
149 array<tuple<list<list<HpcOmSimCode.Task>>, list<list<HpcOmSimCode.Task>>, list<list<HpcOmSimCode.Task>>>> tmpResultList;
150 list<list<HpcOmSimCode.Task>> entryOde, entryDae, entryZeroFunc;
151 algorithm
152 oResultList := matchcontinue iResultList
153 case _
154 algorithm
155
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 7 times.
14 true := intLe(iCurrentThreadIdx, arrayLength(iLevelTasks));
156 7 (entryOde, entryDae, entryZeroFunc) := arrayGet(iResultList, iCurrentThreadIdx);
157
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 5 times.
7 if(intEq(iModifiedSystemIdx,0)) then
158 2 entryOde := arrayGet(iLevelTasks, iCurrentThreadIdx)::entryOde;
159 else
160
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1 time.
5 if(intEq(iModifiedSystemIdx, 1)) then
161 4 entryDae := arrayGet(iLevelTasks, iCurrentThreadIdx)::entryDae;
162 else
163 1 entryZeroFunc := arrayGet(iLevelTasks, iCurrentThreadIdx)::entryZeroFunc;
164 end if;
165 end if;
166 7 tmpResultList := arrayUpdate(iResultList, iCurrentThreadIdx, (entryOde, entryDae, entryZeroFunc));
167 7 tmpResultList := convertFixedLevelScheduleToTaskLists1(iLevelTasks, iCurrentThreadIdx+1, iModifiedSystemIdx, tmpResultList);
168 then tmpResultList;
169 else iResultList;
170 end matchcontinue;
171 end convertFixedLevelScheduleToTaskLists1;
172
173 protected function revertTaskLists
174 input Integer iCurrentArrayIdx;
175 input array<tuple<list<list<HpcOmSimCode.Task>>, list<list<HpcOmSimCode.Task>>, list<list<HpcOmSimCode.Task>>>> iResultList;
176 output array<tuple<list<list<HpcOmSimCode.Task>>, list<list<HpcOmSimCode.Task>>, list<list<HpcOmSimCode.Task>>>> oResultList;
177 protected
178 list<list<HpcOmSimCode.Task>> entryOde, entryDae, entryZeroFunc;
179 array<tuple<list<list<HpcOmSimCode.Task>>, list<list<HpcOmSimCode.Task>>, list<list<HpcOmSimCode.Task>>>> tmpResultList;
180 algorithm
181 oResultList := matchcontinue iResultList
182 case _
183 algorithm
184
2/2
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 1 time.
2 true := intLe(iCurrentArrayIdx, arrayLength(iResultList));
185 1 (entryOde,entryDae,entryZeroFunc) := arrayGet(iResultList, iCurrentArrayIdx);
186 1 entryOde := listReverse(entryOde);
187 1 entryDae := listReverse(entryDae);
188 1 entryZeroFunc := listReverse(entryZeroFunc);
189 1 tmpResultList := arrayUpdate(iResultList, iCurrentArrayIdx, (entryOde,entryDae,entryZeroFunc));
190 1 tmpResultList := revertTaskLists(iCurrentArrayIdx+1, tmpResultList);
191 then tmpResultList;
192 else iResultList;
193 end matchcontinue;
194 end revertTaskLists;
195
196 protected function revertTaskList
197 input Integer iCurrentArrayIdx;
198 input array<list<HpcOmSimCode.Task>> iResultList;
199 output array<list<HpcOmSimCode.Task>> oResultList;
200 protected
201 list<HpcOmSimCode.Task> entry;
202 array<list<HpcOmSimCode.Task>> tmpResultList;
203 algorithm
204 oResultList := matchcontinue iResultList
205 case _
206 algorithm
207
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 true := intLe(iCurrentArrayIdx, arrayLength(iResultList));
208 7 entry := arrayGet(iResultList, iCurrentArrayIdx);
209 7 entry := listReverse(entry);
210 7 tmpResultList := arrayUpdate(iResultList, iCurrentArrayIdx, entry);
211 //tmpResultList = revertTaskList(iCurrentArrayIdx+1, tmpResultList);
212 then tmpResultList;
213 else iResultList;
214 end matchcontinue;
215 end revertTaskList;
216
217 protected function convertFixedLevelScheduleToTaskListsForLevel
218 "Convert a level task list into a task list for each thread.
219 author:marcusw"
220 input HpcOmSimCode.TaskList iTasksOfLevel;
221 input Integer iThreadCount;
222 output array<list<HpcOmSimCode.Task>> oThreadTasks; //mapping thread -> task list
223 protected
224 array<list<HpcOmSimCode.Task>> tmpTaskLists;
225 list<HpcOmSimCode.Task> tasks;
226 algorithm
227 oThreadTasks := match iTasksOfLevel
228 case HpcOmSimCode.PARALLELTASKLIST(tasks=tasks)
229 algorithm
230 7 tmpTaskLists := arrayCreate(iThreadCount, {});
231 7 tmpTaskLists := List.fold(tasks, convertFixedLevelScheduleToTaskListsForTask, tmpTaskLists);
232 7 tmpTaskLists := revertTaskList(1, tmpTaskLists);
233 then tmpTaskLists;
234 case HpcOmSimCode.SERIALTASKLIST(tasks=tasks)
235 algorithm
236 ✗ tmpTaskLists := arrayCreate(iThreadCount, {});
237 ✗ tmpTaskLists := arrayUpdate(tmpTaskLists, 1, tasks);
238 then tmpTaskLists;
239 end match;
240 end convertFixedLevelScheduleToTaskListsForLevel;
241
242 protected function convertFixedLevelScheduleToTaskListsForTask
243 "Insert the given Task into the task list of the given thread advice (threadIdx).
244 author:marcusw"
245 input HpcOmSimCode.Task iTask;
246 input array<list<HpcOmSimCode.Task>> iThreadTasks;
247 output array<list<HpcOmSimCode.Task>> oThreadTasks;
248 protected
249 array<list<HpcOmSimCode.Task>> tmpTaskLists;
250 Integer threadIdx;
251 list<HpcOmSimCode.Task> oldTaskList;
252 algorithm
253 oThreadTasks := match iTask
254 case HpcOmSimCode.CALCTASK_LEVEL(threadIdx=SOME(threadIdx))
255 algorithm
256 102 oldTaskList := arrayGet(iThreadTasks, threadIdx);
257 102 tmpTaskLists := arrayUpdate(iThreadTasks, threadIdx, iTask::oldTaskList);
258 then tmpTaskLists;
259 case _
260 algorithm
261 ✗ print("ConvertFixedLevelScheduleToTaskListsForTask can just handle CALCTASK_LEVEL with defined thread idx!\n");
262 then iThreadTasks;
263 end match;
264 end convertFixedLevelScheduleToTaskListsForTask;
265
266 public function getSimCodeEqByIndex "author: marcusw
267 Returns the SimEqSystem which has the given Index. This method is called from susan."
268 input list<SimCode.SimEqSystem> iEqs; //All SimEqSystems
269 input Integer iIdx; //The index of the required system
270 output SimCode.SimEqSystem oEq;
271 protected
272 list<SimCode.SimEqSystem> rest;
273 SimCode.SimEqSystem head;
274 Integer headIdx,headIdx2;
275 algorithm
276 oEq := matchcontinue iEqs
277 case head::rest
278 algorithm
279 735920 (headIdx,headIdx2) := getIndexBySimCodeEq(head);
280 //print("getSimCodeEqByIndex listLength: " + intString(listLength(iEqs)) + " head idx: " + intString(headIdx) + "\n");
281
3/4
✓ Branch 0 taken 733753 times.
✓ Branch 1 taken 2167 times.
✓ Branch 2 taken 733753 times.
✗ Branch 3 not taken.
735920 true := intEq(headIdx,iIdx) or intEq(headIdx2,iIdx);
282 then head;
283 733753 case head::rest then getSimCodeEqByIndex(rest,iIdx);
284 else
285 algorithm
286 ✗ print("getSimCodeEqByIndex failed. Looking for Index " + intString(iIdx) + "\n");
287 //print(" -- available indices: " + stringDelimitList(List.map(List.map(iEqs,getIndexBySimCodeEq), intString), ",") + "\n");
288 ✗ then fail();
289 end matchcontinue;
290 end getSimCodeEqByIndex;
291
292 public function getIndexBySimCodeEq "author: marcusw
293 Just a small helper function to get the index of a SimEqSystem."
294 input SimCode.SimEqSystem iEq;
295 output Integer oIdx;
296 output Integer oIdx2;
297 protected
298 Integer index,index2;
299 algorithm
300 (oIdx,oIdx2) := match iEq
301 case SimCode.SES_RESIDUAL(index=index) then (index,0);
302 case SimCode.SES_SIMPLE_ASSIGN(index=index) then (index,0);
303 case SimCode.SES_SIMPLE_ASSIGN_CONSTRAINTS(index=index) then (index,0);
304 case SimCode.SES_ARRAY_CALL_ASSIGN(index=index) then (index,0);
305 case SimCode.SES_IFEQUATION(index=index) then (index,0);
306 case SimCode.SES_ALGORITHM(index=index) then (index,0);
307 // no dynamic tearing
308 case SimCode.SES_LINEAR(SimCode.LINEARSYSTEM(index=index), NONE()) then (index,0);
309 case SimCode.SES_NONLINEAR(SimCode.NONLINEARSYSTEM(index=index), NONE()) then (index,0);
310 // dynamic tearing
311 case SimCode.SES_LINEAR(SimCode.LINEARSYSTEM(index=index), SOME(SimCode.LINEARSYSTEM(index=index2))) then (index,index2);
312 case SimCode.SES_NONLINEAR(SimCode.NONLINEARSYSTEM(index=index), SOME(SimCode.NONLINEARSYSTEM(index=index2))) then (index,index2);
313 case SimCode.SES_MIXED(index=index) then (index,0);
314 case SimCode.SES_WHEN(index=index) then (index,0);
315 case SimCode.SES_ALIAS(aliasOf=index) then (index,0);
316 else
317 algorithm
318 ✗ Error.addInternalError(getInstanceName()+" failed", sourceInfo());
319 ✗ then fail();
320 end match;
321 end getIndexBySimCodeEq;
322
323 annotation(__OpenModelica_Interface="codegen_util");
324 end HpcOmCodegenUtil;
325