Skip to content

Commit 2f79736

Browse files
author
Volker Waurich
committed
- addded proper ordering for metis scheduler
- added messages if parallel simulation isn't worth git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@25352 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
1 parent 3a4f448 commit 2f79736

File tree

2 files changed

+144
-11
lines changed

2 files changed

+144
-11
lines changed

Compiler/BackEnd/HpcOmScheduler.mo

Lines changed: 143 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2453,6 +2453,13 @@ protected
24532453
list<HpcOmSimCode.Task> nodeList;
24542454
array<HpcOmTaskGraph.Communications> commCosts;
24552455
array<list<Integer>> inComps;
2456+
2457+
array<Integer> priorityArr;
2458+
list<list<Integer>> levelNodes;
2459+
array<list<Integer>> procAss;
2460+
list<Integer> priorityTasks,otherTasks;
2461+
list<Integer> order;
2462+
list<HpcOmSimCode.Task> removeLocks;
24562463
algorithm
24572464
oSchedule := matchcontinue(iTaskGraph,iTaskGraphMeta,iNumberOfThreads,iSccSimEqMapping,iSimVarMapping)
24582465
case(_,HpcOmTaskGraph.TASKGRAPHMETA(commCosts=commCosts,inComps=inComps),_,_,_)
@@ -2465,23 +2472,43 @@ algorithm
24652472
extInfo = HpcOmSchedulerExt.scheduleMetis(xadj, adjncy, vwgt, adjwgt, iNumberOfThreads);
24662473
extInfoArr = listArray(extInfo);
24672474
else
2468-
extInfoArr = arrayCreate(arrayLength(iTaskGraph), 1);
2475+
extInfoArr = arrayCreate(arrayLength(iTaskGraph), -1);
24692476
end if;
24702477

24712478
//print("External scheduling info: " + stringDelimitList(List.map(extInfo, intString), ",") + "\n");
24722479
true = intEq(arrayLength(iTaskGraph),arrayLength(extInfoArr));
2473-
24742480
taskGraphT = BackendDAEUtil.transposeMatrix(iTaskGraph,arrayLength(iTaskGraph));
24752481
rootNodes = HpcOmTaskGraph.getRootNodes(iTaskGraph);
2482+
2483+
//sort the tasks in the partitions, always the tasks that are predecessors of other partitions first.
2484+
priorityArr = arrayCreate(arrayLength(iTaskGraph),0);
2485+
createMetisSchedule1(List.intRange(arrayLength(iTaskGraph)),extInfoArr,iTaskGraph,taskGraphT,priorityArr);
2486+
levelNodes = HpcOmTaskGraph.getLevelNodes(iTaskGraph);
24762487
allCalcTasks = convertTaskGraphToTasks(taskGraphT,iTaskGraphMeta,convertNodeToTask);
2477-
nodeList_refCount = List.map1(rootNodes, getTaskByIndex, allCalcTasks);
2478-
nodeList = List.map(nodeList_refCount, Util.tuple21);
2479-
nodeList = List.sort(nodeList, compareTasksByWeighting);
2488+
(priorityTasks,otherTasks) = createMetisSchedule2(levelNodes,priorityArr,{},{});
2489+
order = listAppend(priorityTasks,otherTasks);
2490+
2491+
//create schedule
2492+
procAss = arrayCreate(iNumberOfThreads,{});
2493+
List.map2_0(List.intRange(arrayLength(iTaskGraph)),getProcAss,extInfoArr,procAss);
24802494
threadTasks = arrayCreate(iNumberOfThreads,{});
2495+
removeLocks = {};
24812496
tmpSchedule = HpcOmSimCode.THREADSCHEDULE(threadTasks,{},{},allCalcTasks);
2482-
tmpSchedule = createExtSchedule1(nodeList,extInfoArr, iTaskGraph, taskGraphT, commCosts, inComps, iSccSimEqMapping, iSimVarMapping, getLocksByPredecessorList, tmpSchedule);
2483-
tmpSchedule = addSuccessorLocksToSchedule(iTaskGraph,addReleaseLocksToSchedule,commCosts,inComps,iSimVarMapping,tmpSchedule);
2484-
//printSchedule(tmpSchedule);
2497+
2498+
(tmpSchedule,removeLocks) = createScheduleFromAssignments(extInfoArr,procAss,SOME(order),iTaskGraph,taskGraphT,iTaskGraphMeta,iSccSimEqMapping,removeLocks,order,commCosts,inComps,iSimVarMapping,tmpSchedule);
2499+
// remove superfluous locks
2500+
if Flags.isSet(Flags.HPCOM_DUMP) then
2501+
print("number of removed superfluous locks: "+intString(intDiv(listLength(removeLocks),2))+"\n");
2502+
end if;
2503+
tmpSchedule = traverseAndUpdateThreadsInSchedule(tmpSchedule,removeLocksFromThread,removeLocks);
2504+
tmpSchedule = updateLockIdcsInThreadschedule(tmpSchedule,removeLocksFromLockList,removeLocks);
2505+
2506+
//nodeList_refCount = List.map1(rootNodes, getTaskByIndex, allCalcTasks);
2507+
//nodeList = List.map(nodeList_refCount, Util.tuple21);
2508+
//nodeList = List.sort(nodeList, compareTasksByWeighting);
2509+
//tmpSchedule = HpcOmSimCode.THREADSCHEDULE(threadTasks,{},{},allCalcTasks);
2510+
//tmpSchedule = createExtSchedule1(nodeList,extInfoArr, iTaskGraph, taskGraphT, commCosts, inComps, iSccSimEqMapping, iSimVarMapping, getLocksByPredecessorList, tmpSchedule);
2511+
//tmpSchedule = addSuccessorLocksToSchedule(iTaskGraph,addReleaseLocksToSchedule,commCosts,inComps,iSimVarMapping,tmpSchedule);
24852512
then tmpSchedule;
24862513
else
24872514
equation
@@ -2490,7 +2517,107 @@ algorithm
24902517
end matchcontinue;
24912518
end createMetisSchedule;
24922519

2493-
public function createHMetisSchedule "function createExtSchedule
2520+
protected function getProcAss
2521+
input Integer idx;
2522+
input array<Integer> taskAss;
2523+
input array<list<Integer>> procAss;
2524+
protected
2525+
Integer thread;
2526+
algorithm
2527+
thread := arrayGet(taskAss,idx);
2528+
Array.updateElementListAppend(thread,{idx},procAss);
2529+
end getProcAss;
2530+
2531+
protected function createMetisSchedule2"sorts the tasks in 2 causal lists. one prioritylist and another one that is appended to this one.
2532+
author: Waurich TUD 03-2015"
2533+
input list<list<Integer>> levelNodes;
2534+
input array<Integer> priorityArr;
2535+
input list<Integer> prioLstIn;
2536+
input list<Integer> otherLstIn;
2537+
output list<Integer> prioLstOut;
2538+
output list<Integer> otherLstOut;
2539+
algorithm
2540+
(prioLstOut,otherLstOut) := matchcontinue(levelNodes,priorityArr,prioLstIn,otherLstIn)
2541+
local
2542+
list<Integer> level, prioLst, otherLst;
2543+
list<list<Integer>> rest;
2544+
case({},_,_,_)
2545+
algorithm
2546+
then (prioLstIn,otherLstIn);
2547+
case(level::rest,_,_,_)
2548+
algorithm
2549+
(prioLst,otherLst) := List.split1OnTrue(level,isPrioNode,priorityArr);
2550+
//prioTaskLst := List.map(List.map1(prioLst,Array.getIndexFirst,allCalcTasks),Util.tuple21);
2551+
//otherTaskLst := List.map(List.map1(otherLst,Array.getIndexFirst,allCalcTasks),Util.tuple21);
2552+
prioLst := listAppend(prioLstIn,prioLst);
2553+
otherLst := listAppend(otherLstIn,otherLst);
2554+
(prioLst,otherLst) := createMetisSchedule2(rest,priorityArr,prioLst,otherLst);
2555+
then (prioLst,otherLst);
2556+
end matchcontinue;
2557+
end createMetisSchedule2;
2558+
2559+
protected function isPrioNode"
2560+
author: Waurich TUD 03-2015"
2561+
input Integer idx;
2562+
input array<Integer> prioArr;
2563+
output Boolean isPrio;
2564+
algorithm
2565+
isPrio := intEq(1,arrayGet(prioArr,idx));
2566+
end isPrioNode;
2567+
2568+
protected function createMetisSchedule1"builds a priority array to mark tasks that have to be solved as early as possible
2569+
author: Waurich TUD 03-2015"
2570+
input list<Integer> taskIdcs;
2571+
input array<Integer> threadIds; // the assigned thread for each task
2572+
input array<list<Integer>> taskGraph;
2573+
input array<list<Integer>> taskGraphT;
2574+
input array<Integer> priorityArr;
2575+
algorithm
2576+
_ := matchcontinue(taskIdcs,threadIds,taskGraph,taskGraphT,priorityArr)
2577+
local
2578+
Integer threadId, taskIdx;
2579+
list<Integer> preds, predThreads, rest;
2580+
case({},_,_,_,_)
2581+
then ();
2582+
case(taskIdx::rest,_,_,_,_)
2583+
algorithm // this task is already prioritized, add the predecessors as well
2584+
true := intEq(1,arrayGet(priorityArr,taskIdx));
2585+
preds := arrayGet(taskGraphT,taskIdx);
2586+
preds := List.filter1OnTrue(preds,arrayIntIsNotOne,priorityArr);// are not prioritized
2587+
List.map2_0(preds,Array.updateIndexFirst,1,priorityArr);
2588+
//print("priority: "+stringDelimitList(List.map(preds,intString),", ")+"\n");
2589+
rest := listAppend(preds,rest);
2590+
createMetisSchedule1(rest,threadIds,taskGraph,taskGraphT,priorityArr);
2591+
then ();
2592+
case(taskIdx::rest,_,_,_,_)
2593+
algorithm// check if this task is a successor of a differently threaded task
2594+
//true := intLe(0,arrayGet(priorityArr,taskIdx));
2595+
threadId := arrayGet(threadIds,taskIdx);
2596+
preds := arrayGet(taskGraphT,taskIdx);
2597+
predThreads := List.map1(preds,Array.getIndexFirst,threadIds);
2598+
(predThreads,preds) := List.filter1OnTrueSync(predThreads,intNe,threadId,preds);
2599+
if List.isNotEmpty(predThreads) then
2600+
//print("priority: "+stringDelimitList(List.map(preds,intString),", ")+"\n");
2601+
List.map2_0(preds,Array.updateIndexFirst,1,priorityArr);
2602+
rest := listAppend(preds,rest);
2603+
else
2604+
arrayUpdate(priorityArr,taskIdx,0);
2605+
end if;
2606+
createMetisSchedule1(rest,threadIds,taskGraph,taskGraphT,priorityArr);
2607+
then ();
2608+
end matchcontinue;
2609+
end createMetisSchedule1;
2610+
2611+
protected function arrayIntIsNotOne"
2612+
author: Waurich TUD 03-2015"
2613+
input Integer idx;
2614+
input array<Integer> arr;
2615+
output Boolean isOne;
2616+
algorithm
2617+
isOne := intNe(1,arrayGet(arr,idx));
2618+
end arrayIntIsNotOne;
2619+
2620+
public function createHMetisSchedule "function createHMetisSchedule
24942621
author: marcusw
24952622
Creates a scheduling by passing the arguments to hmetis."
24962623
input HpcOmTaskGraph.TaskGraph iTaskGraph;
@@ -5529,6 +5656,12 @@ algorithm
55295656
print("the parallelCosts: "+realString(parTime)+"\n");
55305657
print("the cpCosts: "+realString(cpCostsWoC)+"\n");
55315658
end if;
5659+
if realLe(speedUpMax,2.0) then
5660+
print("There is no parallel potential for this model!\n");
5661+
end if;
5662+
if realLe(serTime,20000.0) then
5663+
print("This model is not big enough to perform an effective parallel simulation!\n");
5664+
end if;
55325665
printPredictedExeTimeInfo(serTime,parTime,speedUp,speedUpMax,numProcIn);
55335666
then
55345667
criticalPathInfo;
@@ -5755,7 +5888,7 @@ algorithm
57555888
if speedUp > speedUpMax then
57565889
print("Something is weird. The predicted SpeedUp is "+ System.snprintff("%.2f", 25, speedUp)+" and the theoretical maximum speedUp is "+ System.snprintff("%.2f", 25, speedUpMax)+"\n");
57575890
elseif speedUp <= speedUpMax then
5758-
print("The predicted SpeedUp with "+intString(numProc)+" processors is: "+ System.snprintff("%.2f", 25, speedUp)+" With a theoretical maxmimum speedUp of: "+ System.snprintff("%.2f", 25, speedUpMax)+"\n");
5891+
print("The predicted SpeedUp with "+intString(numProc)+" processors is: "+ System.snprintff("%.2f", 25, speedUp)+" With a theoretical maximmum speedUp of: "+ System.snprintff("%.2f", 25, speedUpMax)+"\n");
57595892
end if;
57605893
end if;
57615894
then

Compiler/Util/List.mo

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5069,7 +5069,7 @@ public function filterOnFalse<T>
50695069
"Takes a list of values and a filter function over the values and returns a
50705070
sub list of values for which the matching function returns false.
50715071
Example:
5072-
filter1OnFalse({1, 2, 3, 1, 5}, isEven) => {1, 3, 1, 5}"
5072+
filterOnFalse({1, 2, 3, 1, 5}, isEven) => {1, 3, 1, 5}"
50735073
input list<T> inList;
50745074
input FilterFunc inFilterFunc;
50755075
output list<T> outList;

0 commit comments

Comments
 (0)