Skip to content

Commit 95e3a3b

Browse files
sjoelundOpenModelica-Hudson
authored andcommitted
Avoid some memory allocations in tearing
1 parent b4c41d7 commit 95e3a3b

File tree

1 file changed

+43
-68
lines changed

1 file changed

+43
-68
lines changed

Compiler/BackEnd/Tearing.mo

Lines changed: 43 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ protected import BackendDump;
4949
protected import BackendEquation;
5050
protected import BackendVariable;
5151
protected import Config;
52+
protected import DoubleEndedList;
5253
protected import DumpGraphML;
5354
protected import Error;
5455
protected import ExecStat.execStat;
@@ -1693,6 +1694,7 @@ algorithm
16931694

16941695
// Get advanced adjacency matrix (determine how the variables occur in the equations)
16951696
(me,meT,mapEqnIncRow,mapIncRowEqn) := BackendDAEUtil.getAdjacencyMatrixEnhancedScalar(subsyst,ishared,false);
1697+
if debug then execStat("Tearing.CellierTearing -> 1.5"); end if;
16961698

16971699
// Determine unsolvable vars to consider solvability
16981700
unsolvables := getUnsolvableVars(1,size,meT,{});
@@ -1749,7 +1751,7 @@ algorithm
17491751

17501752
if debug then execStat("Tearing.CellierTearing -> 3.2"); end if;
17511753
// Unassigned equations are residual equations
1752-
((_,residual)) := Array.fold(ass2,getUnassigned,(1,{}));
1754+
residual := getUnassigned(ass2);
17531755
if debug then execStat("Tearing.CellierTearing -> 3.3"); end if;
17541756
residual_coll := List.map1r(residual,arrayGet,mapIncRowEqn);
17551757
if debug then execStat("Tearing.CellierTearing -> 3.4"); end if;
@@ -1840,7 +1842,7 @@ algorithm
18401842
if intLt(listLength(OutTVars), tornsize) then
18411843

18421844
// Unassigned equations are residual equations
1843-
((_,residual)) := Array.fold(ass2,getUnassigned,(1,{}));
1845+
residual := getUnassigned(ass2);
18441846
residual_coll := List.map1r(residual,arrayGet,mapIncRowEqn);
18451847
residual_coll := List.unique(residual_coll);
18461848
if Flags.isSet(Flags.TEARING_DUMP) or Flags.isSet(Flags.TEARING_DUMPVERBOSE) then
@@ -2243,9 +2245,7 @@ algorithm
22432245
end if;
22442246

22452247
// 5. select the rows(eqs) from mIn which could be causalized by knowing one more Var
2246-
((_,assEq)) := Array.fold(ass2In,getUnassigned,(1,{}));
2247-
(assEq_multi,assEq_single) := traverseEqnsforAssignable(assEq,mIn,mapEqnIncRow,mapIncRowEqn,1);
2248-
selectedrows := listAppend(assEq_multi,assEq_single);
2248+
selectedrows := traverseEqnsforAssignable(ass2In,mIn,mapEqnIncRow,mapIncRowEqn,1);
22492249
if Flags.isSet(Flags.TEARING_DUMPVERBOSE) then
22502250
print(stringDelimitList(List.map(selectedrows,intString),",")+"\n(Equations which could be causalized by knowing one more Var)\n\n");
22512251
end if;
@@ -2290,9 +2290,7 @@ algorithm
22902290
end if;
22912291

22922292
// 2. select the rows(eqs) from mIn which could be causalized by knowing one more Var
2293-
((_,assEq)) := Array.fold(ass2In,getUnassigned,(1,{}));
2294-
(assEq_multi,assEq_single) := traverseEqnsforAssignable(assEq,mIn,mapEqnIncRow,mapIncRowEqn,1);
2295-
selectedrows := listAppend(assEq_multi,assEq_single);
2293+
selectedrows := traverseEqnsforAssignable(ass2In,mIn,mapEqnIncRow,mapIncRowEqn,1);
22962294
if Flags.isSet(Flags.TEARING_DUMPVERBOSE) then
22972295
print(stringDelimitList(List.map(selectedrows,intString),",")+"\n(Equations which could be causalized by knowing one more Var)\n\n");
22982296
end if;
@@ -2349,9 +2347,7 @@ algorithm
23492347
end if;
23502348

23512349
// 5. select the rows(eqs) from mIn which could be causalized by knowing one more Var
2352-
((_,assEq)) := Array.fold(ass2In,getUnassigned,(1,{}));
2353-
(assEq_multi,assEq_single) := traverseEqnsforAssignable(assEq,mIn,mapEqnIncRow,mapIncRowEqn,1);
2354-
selectedrows := listAppend(assEq_multi,assEq_single);
2350+
selectedrows := traverseEqnsforAssignable(ass2In,mIn,mapEqnIncRow,mapIncRowEqn,1);
23552351
if Flags.isSet(Flags.TEARING_DUMPVERBOSE) then
23562352
print(stringDelimitList(List.map(selectedrows,intString),",")+"\n(Equations which could be causalized by knowing one more Var)\n\n");
23572353
end if;
@@ -2402,9 +2398,7 @@ algorithm
24022398
end if;
24032399

24042400
// 2. select the rows(eqs) from mIn which could be causalized by knowing one more Var
2405-
((_,assEq)) := Array.fold(ass2In,getUnassigned,(1,{}));
2406-
(assEq_multi,assEq_single) := traverseEqnsforAssignable(assEq,mIn,mapEqnIncRow,mapIncRowEqn,1);
2407-
selectedrows := listAppend(assEq_multi,assEq_single);
2401+
selectedrows := traverseEqnsforAssignable(ass2In,mIn,mapEqnIncRow,mapIncRowEqn,1);
24082402
if Flags.isSet(Flags.TEARING_DUMPVERBOSE) then
24092403
print(stringDelimitList(List.map(selectedrows,intString),",")+"\n(Equations which could be causalized by knowing one more Var)\n\n");
24102404
end if;
@@ -2473,9 +2467,7 @@ algorithm
24732467
end if;
24742468

24752469
// 6. select the rows(eqs) from mIn which could be causalized by knowing one more Var
2476-
((_,assEq)) := Array.fold(ass2In,getUnassigned,(1,{}));
2477-
(assEq_multi,assEq_single) := traverseEqnsforAssignable(assEq,mIn,mapEqnIncRow,mapIncRowEqn,1);
2478-
selectedrows := listAppend(assEq_multi,assEq_single);
2470+
selectedrows := traverseEqnsforAssignable(ass2In,mIn,mapEqnIncRow,mapIncRowEqn,1);
24792471
if Flags.isSet(Flags.TEARING_DUMPVERBOSE) then
24802472
print(stringDelimitList(List.map(selectedrows,intString),",")+"\n(Equations which could be causalized by knowing one more Var)\n\n");
24812473
end if;
@@ -2526,9 +2518,7 @@ algorithm
25262518
end if;
25272519

25282520
// 3. select the rows(eqs) from mIn which could be causalized by knowing one more Var
2529-
((_,assEq)) := Array.fold(ass2In,getUnassigned,(1,{}));
2530-
(assEq_multi,assEq_single) := traverseEqnsforAssignable(assEq,mIn,mapEqnIncRow,mapIncRowEqn,1);
2531-
selectedrows := listAppend(assEq_multi,assEq_single);
2521+
selectedrows := traverseEqnsforAssignable(ass2In,mIn,mapEqnIncRow,mapIncRowEqn,1);
25322522
if Flags.isSet(Flags.TEARING_DUMPVERBOSE) then
25332523
print(stringDelimitList(List.map(selectedrows,intString),",")+"\n(Equations which could be causalized by knowing one more Var)\n\n");
25342524
end if;
@@ -2585,9 +2575,7 @@ algorithm
25852575
end if;
25862576

25872577
// 5. select the rows(eqs) from mIn which could be causalized by knowing one more Var
2588-
((_,assEq)) := Array.fold(ass2In,getUnassigned,(1,{}));
2589-
(assEq_multi,assEq_single) := traverseEqnsforAssignable(assEq,mIn,mapEqnIncRow,mapIncRowEqn,1);
2590-
selectedrows := listAppend(assEq_multi,assEq_single);
2578+
selectedrows := traverseEqnsforAssignable(ass2In,mIn,mapEqnIncRow,mapIncRowEqn,1);
25912579
if Flags.isSet(Flags.TEARING_DUMPVERBOSE) then
25922580
print(stringDelimitList(List.map(selectedrows,intString),",")+"\n(Equations which could be causalized by knowing one more Var)\n\n");
25932581
end if;
@@ -2644,9 +2632,7 @@ algorithm
26442632
end if;
26452633

26462634
// 3. select the rows(eqs) from mIn which could be causalized by knowing one more Var
2647-
((_,assEq)) := Array.fold(ass2In,getUnassigned,(1,{}));
2648-
(assEq_multi,assEq_single) := traverseEqnsforAssignable(assEq,mIn,mapEqnIncRow,mapIncRowEqn,1);
2649-
selectedrows := listAppend(assEq_multi,assEq_single);
2635+
selectedrows := traverseEqnsforAssignable(ass2In,mIn,mapEqnIncRow,mapIncRowEqn,1);
26502636
if Flags.isSet(Flags.TEARING_DUMPVERBOSE) then
26512637
print(stringDelimitList(List.map(selectedrows,intString),",")+"\n(Equations which could be causalized by knowing one more Var)\n\n");
26522638
end if;
@@ -2708,9 +2694,7 @@ algorithm
27082694
end if;
27092695

27102696
// 3. select the rows(eqs) from mIn which could be causalized by knowing one more Var
2711-
((_,assEq)) := Array.fold(ass2In,getUnassigned,(1,{}));
2712-
(assEq_multi,assEq_single) := traverseEqnsforAssignable(assEq,mIn,mapEqnIncRow,mapIncRowEqn,1);
2713-
selectedrows := listAppend(assEq_multi,assEq_single);
2697+
selectedrows := traverseEqnsforAssignable(ass2In,mIn,mapEqnIncRow,mapIncRowEqn,1);
27142698
if Flags.isSet(Flags.TEARING_DUMPVERBOSE) then
27152699
print(stringDelimitList(List.map(selectedrows,intString),",")+"\n(Equations which could be causalized by knowing one more Var)\n\n");
27162700
end if;
@@ -2797,15 +2781,10 @@ algorithm
27972781
// Cellier heuristic [MC3]
27982782

27992783
// 1. Find all unassigned equations
2800-
((_,assEq)) := Array.fold(ass2In,getUnassigned,(1,{}));
2801-
if Flags.isSet(Flags.TEARING_DUMPVERBOSE) then
2802-
print("1st: "+ stringDelimitList(List.map(assEq,intString),",")+"\n(All unassigned equations)\n\n");
2803-
end if;
28042784
if debug then execStat("Tearing.ModifiedCellierHeuristic_3 - 1"); end if;
28052785

28062786
// 2. Determine the equations with size(equation)+1 variables and save them in causEq
2807-
(assEq_multi,assEq_single) := traverseEqnsforAssignable(assEq,mIn,mapEqnIncRow,mapIncRowEqn,1);
2808-
causEq := listAppend(assEq_multi,assEq_single);
2787+
causEq := traverseEqnsforAssignable(ass2In,mIn,mapEqnIncRow,mapIncRowEqn,1);
28092788
if Flags.isSet(Flags.TEARING_DUMPVERBOSE) then
28102789
print("2nd: "+ stringDelimitList(List.map(causEq,intString),",")+"\n(Equations from (1st) which could be causalized by knowing one more variable)\n\n");
28112790
end if;
@@ -2829,7 +2808,8 @@ algorithm
28292808

28302809
// 4.1 Check if potentialTVars is empty, if yes, choose all unassigned non-discrete variables without attribute tearingSelect=never as potentialTVars
28312810
if listEmpty(potentialTVars) then
2832-
((_,potentialTVars)) := Array.fold(ass1In,getUnassigned,(1,{}));
2811+
potentialTVars := getUnassigned(ass1In);
2812+
28332813
(_,potentialTVars,_) := List.intersection1OnTrue(potentialTVars,discreteVars,intEq);
28342814
(_,potentialTVars,_) := List.intersection1OnTrue(potentialTVars,tSel_never,intEq);
28352815
if listEmpty(potentialTVars) then
@@ -3190,15 +3170,17 @@ protected
31903170
list<Integer> subOrder,unassigned,eqQueue=eqQueueIn;
31913171
list<Integer> order=orderIn;
31923172
Boolean assignable = true;
3173+
constant Boolean debug = false;
31933174
algorithm
31943175
while assignable loop
31953176
if Flags.isSet(Flags.TEARING_DUMPVERBOSE) then
31963177
print("\nTarjanAssignment:\n");
31973178
end if;
31983179
(eqQueue,order,assignable) := TarjanAssignment(eqQueue,mIn,mtIn,meIn,metIn,ass1In,ass2In,order,mapEqnIncRow,mapIncRowEqn);
31993180
end while;
3181+
if debug then execStat("Tearing.TarjanMatching iters done"); end if;
32003182

3201-
((_,unassigned)) := Array.fold(ass1In,getUnassigned,(1,{}));
3183+
unassigned := getUnassigned(ass1In);
32023184
if listEmpty(unassigned) then
32033185
if Flags.isSet(Flags.TEARING_DUMPVERBOSE) then
32043186
print("\ncausal\n");
@@ -3212,6 +3194,7 @@ algorithm
32123194
orderOut := order;
32133195
causal := false;
32143196
end if;
3197+
if debug then execStat("Tearing.TarjanMatching done"); end if;
32153198
end TarjanMatching;
32163199

32173200

@@ -3232,12 +3215,8 @@ author: ptaeuber FHB 2013-2015"
32323215
protected
32333216
list<Integer> assEq,assEq_multi,assEq_single,assEq_coll,eqns,vars;
32343217
algorithm
3235-
// select equations not assigned yet
3236-
((_,assEq)) := Array.fold(ass2In,getUnassigned,(1,{}));
3237-
32383218
// find equations with one variable
3239-
(assEq_multi,assEq_single) := traverseEqnsforAssignable(assEq,mIn,mapEqnIncRow,mapIncRowEqn,0);
3240-
assEq := listAppend(assEq_multi,assEq_single);
3219+
assEq := traverseEqnsforAssignable(ass2In,mIn,mapEqnIncRow,mapIncRowEqn,0);
32413220

32423221
// transform equationlist to equationlist with collective equations
32433222
assEq_coll := List.map1r(assEq,arrayGet,mapIncRowEqn);
@@ -3297,50 +3276,35 @@ algorithm
32973276
end matchcontinue;
32983277
end TarjanGetAssignable;
32993278

3300-
3301-
protected function getUnassigned " finds the unassigned vars or eqs.combine with List.fold"
3302-
input Integer assEntry;
3303-
input tuple<Integer,list<Integer>> InValue;
3304-
output tuple<Integer,list<Integer>> OutValue;
3305-
algorithm
3306-
OutValue := match(assEntry,InValue)
3307-
local
3308-
Integer indx;
3309-
list<Integer> lst;
3310-
case(_,(indx,lst))
3311-
then
3312-
if intEq(assEntry,-1) then
3313-
((indx+1,indx::lst))
3314-
else
3315-
((indx+1,lst));
3316-
end match;
3317-
end getUnassigned;
3318-
3319-
33203279
protected function traverseEqnsforAssignable
33213280
" selects next equations that can be causalized
33223281
author: ptaeuber FHB 2013-10"
3323-
input list<Integer> inAssEq;
3282+
input array<Integer> inAss;
33243283
input BackendDAE.IncidenceMatrix m;
33253284
input array<list<Integer>> mapEqnIncRow;
33263285
input array<Integer> mapIncRowEqn;
33273286
input Integer prescient;
3328-
output list<Integer> outAssEq_multi = {};
3329-
output list<Integer> outAssEq_single = {};
3287+
output list<Integer> selectedrows;
33303288
protected
33313289
Integer eqnColl,eqnSize;
3290+
DoubleEndedList<Integer> delst;
33323291
algorithm
3333-
for e in inAssEq loop
3292+
delst := DoubleEndedList.empty(0);
3293+
for e in 1:arrayLength(inAss) loop
3294+
if arrayGet(inAss,e)<>-1 then
3295+
continue;
3296+
end if;
33343297
eqnColl := mapIncRowEqn[e];
33353298
eqnSize := listLength(mapEqnIncRow[eqnColl]);
33363299
if listLength(m[e]) == eqnSize + prescient then
33373300
if eqnSize == 1 then
3338-
outAssEq_single := e::outAssEq_single;
3301+
DoubleEndedList.push_back(delst, e);
33393302
else
3340-
outAssEq_multi := e::outAssEq_multi;
3303+
DoubleEndedList.push_front(delst, e);
33413304
end if;
33423305
end if;
33433306
end for;
3307+
selectedrows := DoubleEndedList.toListAndClear(delst);
33443308
end traverseEqnsforAssignable;
33453309

33463310

@@ -4028,5 +3992,16 @@ algorithm
40283992

40293993
end recursiveTearingReplace;
40303994

3995+
protected function getUnassigned
3996+
input array<Integer> ass;
3997+
output list<Integer> unassigned={};
3998+
algorithm
3999+
for i in 1:arrayLength(ass) loop
4000+
if Dangerous.arrayGetNoBoundsChecking(ass, i)==-1 then
4001+
unassigned := i::unassigned;
4002+
end if;
4003+
end for;
4004+
end getUnassigned;
4005+
40314006
annotation(__OpenModelica_Interface="backend");
40324007
end Tearing;

0 commit comments

Comments
 (0)