Skip to content

Commit

Permalink
Use tail recursion to avoid stack overflow (OpenModelica#12538)
Browse files Browse the repository at this point in the history
  • Loading branch information
anotheruserofgithub committed Jun 10, 2024
1 parent 9429d1f commit 5ffd12a
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 96 deletions.
87 changes: 40 additions & 47 deletions OMCompiler/Compiler/BackEnd/IndexReduction.mo
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ protected function pantelidesIndexReduction1
output list<tuple<list<Integer>,list<Integer>,list<Integer>>> oNotDiffableMSS;
algorithm
(osyst,oshared,outAssignments1,outAssignments2,outArg,oNotDiffableMSS) :=
matchcontinue (unassignedStates, unassignedEqns, alleqns, iEqns)
match (unassignedStates, unassignedEqns, alleqns, iEqns)
local
list<Integer> states,eqns,eqns_1,ueqns;
list<list<Integer>> statelst,ueqnsrest,eqnsrest,eqnsrest_1;
Expand Down Expand Up @@ -236,7 +236,7 @@ algorithm
Error.addMessage(Error.INTERNAL_ERROR, {"- IndexReduction.pantelidesIndexReduction1 failed! Use -d=bltdump to get more information."});
then
fail();
end matchcontinue;
end match;
end pantelidesIndexReduction1;

protected function pantelidesIndexReductionMSS
Expand Down Expand Up @@ -1829,7 +1829,7 @@ protected function selectStatesWork
output Integer oSetIndex=iSetIndex;
algorithm
(osyst,oshared,oHt,oSetIndex) :=
matchcontinue (inSystem, iOrgEqnsLst)
match (inSystem, iOrgEqnsLst)
local
BackendDAE.EqSystem syst;
BackendDAE.Shared shared;
Expand All @@ -1847,8 +1847,7 @@ algorithm
HashTableCrIntToExp.HashTable ht;
HashTable2.HashTable repl;
case (_,_)
equation
true = Array.arrayListsEmpty(iOrgEqnsLst);
guard Array.arrayListsEmpty(iOrgEqnsLst)
then (inSystem,inShared,iHt,iSetIndex);
case (BackendDAE.EQSYSTEM(orderedVars=vars,matching=BackendDAE.MATCHING(ass1=ass1,ass2=ass2)),_)
equation
Expand Down Expand Up @@ -1914,7 +1913,7 @@ algorithm
(syst,shared,ht,setIndex) = selectStatesWork(level+1,lov,syst,inShared,so,orgEqnsLst,mapEqnIncRow,mapIncRowEqn,ht,setIndex);
then
(syst,shared,ht,setIndex);
end matchcontinue;
end match;
end selectStatesWork;

protected function removeFirstOrderDerivatives
Expand Down Expand Up @@ -2025,7 +2024,7 @@ protected function selectStatesWork1
output StateSets oStateSets;
algorithm
(outDummyVars,oStateSets) :=
matchcontinue inSystem
match inSystem
local
list<BackendDAE.Var> dummyVars,stateVars,vlst;
array<list<Integer>> mapEqnIncRow;
Expand Down Expand Up @@ -2186,6 +2185,7 @@ algorithm
then
(listAppend(dummyVars, vlst), stateSets);
// to much equations this is an error
// number of differentiated equations exceeds number of free states, add StateSelect.always states and try again
case _
guard intGt(neqns,nfreeStates)
algorithm
Expand All @@ -2201,19 +2201,15 @@ algorithm
// no chance, to much equations
msg := "It is not possible to select continuous time states because Number of Equations " + intString(neqns) + " greater than number of States " + intString(nfreeStates) + " to select from.";
Error.addMessage(Error.INTERNAL_ERROR, {msg});
then
fail();
// number of differentiated equations exceeds number of free states, add StateSelect.always states and try again
case _
guard intGt(neqns,nfreeStates)
equation
// try again and add also stateSelect.always vars.
nv = listLength(iHov);
true = intGe(nv,neqns);
(dummyVars,stateSets) = selectStatesWork1(nv,iHov,neqns,eqnslst,level,inSystem,inShared,so,iMapEqnIncRow,iMapIncRowEqn,iHov,inDummyVars,iStateSets);
nv := listLength(iHov);
if not intGe(nv,neqns) then
fail();
end if;
(dummyVars,stateSets) := selectStatesWork1(nv,iHov,neqns,eqnslst,level,inSystem,inShared,so,iMapEqnIncRow,iMapIncRowEqn,iHov,inDummyVars,iStateSets);
then
(dummyVars,stateSets);
end matchcontinue;
end match;
end selectStatesWork1;

protected function forceStateSelectNever
Expand Down Expand Up @@ -2577,25 +2573,24 @@ protected function partitionSystem1
input Integer iNSystems;
output Integer oNSystems;
algorithm
oNSystems := matchcontinue(index)
oNSystems := match(index)
local
list<Integer> rows;
Integer nsystems;
case 0 then iNSystems-1;
case _
guard not intGt(rowmarkarr[index],0)
equation
// if unmarked then increse nsystems
false = intGt(rowmarkarr[index],0);
arrayUpdate(rowmarkarr,index,iNSystems);
rows = List.select(m[index], Util.intPositive);
nsystems = partitionSystemstraverseRows(rows,{},m,mT,rowmarkarr,collmarkarr,iNSystems);
then
partitionSystem1(index-1,m,mT,rowmarkarr,collmarkarr,nsystems);
else equation
// if marked skip it
true = intGt(rowmarkarr[index],0);
then partitionSystem1(index-1,m,mT,rowmarkarr,collmarkarr,iNSystems);
end matchcontinue;
end match;
end partitionSystem1;

protected function partitionSystemstraverseRows
Expand All @@ -2608,7 +2603,7 @@ protected function partitionSystemstraverseRows
input Integer iNSystems;
output Integer oNSystems;
algorithm
oNSystems := matchcontinue(iRows,iQueue)
oNSystems := match(iRows,iQueue)
local
list<Integer> rest,colls,rows;
Integer r;
Expand All @@ -2617,9 +2612,9 @@ algorithm
then
partitionSystemstraverseRows(iQueue,{},m,mT,rowmarkarr,collmarkarr,iNSystems);
case (r::rest,_)
guard not intGt(collmarkarr[r],0)
equation
// if unmarked then add
false = intGt(collmarkarr[r],0);
arrayUpdate(collmarkarr,r,iNSystems);
colls = List.select(mT[r], Util.intPositive);
colls = List.select1r(colls,Matching.isUnAssigned, rowmarkarr);
Expand All @@ -2631,10 +2626,9 @@ algorithm
case (r::rest,_)
equation
// if marked skipp it
true = intGt(collmarkarr[r],0);
then
partitionSystemstraverseRows(rest,iQueue,m,mT,rowmarkarr,collmarkarr,iNSystems);
end matchcontinue;
end match;
end partitionSystemstraverseRows;

protected function partitionSystemSplitt
Expand Down Expand Up @@ -2788,7 +2782,7 @@ protected function getSetSystem
output BackendDAE.EquationArray oEqnsArr;
algorithm
(oEqnsLst,oVarsLst,oAss1,oAss2,oEqnsArr) :=
matchcontinue iEqns
match iEqns
local
Integer e,e1;
list<Integer> rest,eqns,vindx,ass,ass1,ass2;
Expand Down Expand Up @@ -2818,7 +2812,7 @@ algorithm
(oEqnsLst,oVarsLst,ass1,ass2,eqnarr) = getSetSystem(rest,inMapEqnIncRow,inMapIncRowEqn,vec1,iVars,iEqnsArr,flag,n,iEqnsLst,iVarsLst,iAss1,iAss2);
then
(oEqnsLst,oVarsLst,ass1,ass2,eqnarr);
end matchcontinue;
end match;
end getSetSystem;

protected function getSetStates
Expand Down Expand Up @@ -2890,15 +2884,15 @@ protected function getEqnsforDynamicStateSelection1
input list<Integer> inSubset;
output list<Integer> outSubset;
algorithm
outSubset:= matchcontinue (U,m,mT,mark,colummarks,ass1,ass2,mapEqnIncRow,mapIncRowEqn,inSubset)
outSubset:= match (U,m,mT,mark,colummarks,ass1,ass2,mapEqnIncRow,mapIncRowEqn,inSubset)
local
list<Integer> rest,eqns,set;
Integer e,e1;
case ({},_,_,_,_,_,_,_,_,_) then inSubset;
case (e::rest,_,_,_,_,_,_,_,_,_)
guard intEq(colummarks[e],0)
equation
// row is not visited
true = intEq(colummarks[e],0);
// if it is a multi dim equation take all scalare equations
e1 = mapIncRowEqn[e];
eqns = mapEqnIncRow[e1];
Expand All @@ -2910,7 +2904,7 @@ algorithm
case (_::rest,_,_,_,_,_,_,_,_,_)
then
getEqnsforDynamicStateSelection1(rest,m,mT,mark,colummarks,ass1,ass2,mapEqnIncRow,mapIncRowEqn,inSubset);
end matchcontinue;
end match;
end getEqnsforDynamicStateSelection1;

protected function getEqnsforDynamicStateSelectionPhase
Expand Down Expand Up @@ -2969,31 +2963,30 @@ protected function getEqnsforDynamicStateSelectionRows
output Boolean oFound;
algorithm
(outSubset,oFound):=
matchcontinue (rows,m,mT,mark,colummarks,ass1,ass2,mapEqnIncRow,mapIncRowEqn,inSubset,iFound)
match (rows,m,mT,mark,colummarks,ass1,ass2,mapEqnIncRow,mapIncRowEqn,inSubset,iFound)
local
list<Integer> rest,set,eqns;
Integer rc,r,e;
Boolean b;
case ({},_,_,_,_,_,_,_,_,_,_) then (inSubset,iFound);
case (r::rest,_,_,_,_,_,_,_,_,_,_)
guard not intGt(ass2[r],0)
equation
// row is free
// print("check Row " + intString(r) + "\n");
rc = ass2[r];
// print("check Row " + intString(r) + "\n");
// print("check Colum " + intString(rc) + "\n");
false = intGt(rc,0);
// print("Found free eqn " + intString(rc) + "\n");
(set,b) = getEqnsforDynamicStateSelectionRows(rest,m,mT,mark,colummarks,ass1,ass2,mapEqnIncRow,mapIncRowEqn,inSubset,true);
then
(set,b);
case (r::rest,_,_,_,_,_,_,_,_,_,_)
guard intGt(ass2[r],0) and intEq(colummarks[ass2[r]],0)
equation
// row is matched
// print("check Row " + intString(r) + "\n");
rc = ass2[r];
// print("check Row " + intString(r) + "\n");
// print("check Colum " + intString(rc) + "\n");
true = intGt(rc,0);
true = intEq(colummarks[rc],0);
// if it is a multi dim equation take all scalare equations
e = mapIncRowEqn[rc];
eqns = mapEqnIncRow[e];
Expand All @@ -3006,18 +2999,18 @@ algorithm
then
(set,b);
case (r::rest,_,_,_,_,_,_,_,_,_,_)
guard intGt(ass2[r],0)
equation
// row is matched
// print("check Row " + intString(r) + "\n");
rc = ass2[r];
// print("check Row " + intString(r) + "\n");
// print("check Colum " + intString(rc) + "\n");
true = intGt(rc,0);
b = intGt(colummarks[rc],0);
// print("Found " + boolString(b) + " equation " + intString(rc) + "\n");
(set,b) = getEqnsforDynamicStateSelectionRows(rest,m,mT,mark,colummarks,ass1,ass2,mapEqnIncRow,mapIncRowEqn,inSubset,b or iFound);
then
(set,b);
end matchcontinue;
end match;
end getEqnsforDynamicStateSelectionRows;

protected function removeFirstOrgEqns
Expand Down Expand Up @@ -3671,7 +3664,7 @@ protected function makeHigherStatesRepl1
output HashTableCrIntToExp.HashTable oHt;
output Integer oN;
algorithm
(oVarLst,oHt,oN) := matchcontinue (diffCount,diffedCount,iOrigName,iName,inVar,vars,iVarLst,iHt,iN)
(oVarLst,oHt,oN) := match (diffCount,diffedCount,iOrigName,iName,inVar,vars,iVarLst,iHt,iN)
local
HashTableCrIntToExp.HashTable ht;
DAE.ComponentRef name;
Expand All @@ -3695,8 +3688,8 @@ algorithm
Boolean encrypted;
// state no derivative known
case (_,_,_,_,BackendDAE.VAR(varName=name,varDirection=dir,varParallelism=prl,varType=tp,arryDim=dim,source=source,tearingSelectOption=ts,hideResult=hideResult,comment=comment,connectorType=ct,innerOuter=io,encrypted=encrypted),_,_,_,_)
guard intGt(diffCount,-1)
equation
true = intGt(diffCount,-1);
name = ComponentReference.crefPrefixDer(iName);
// generate replacement
e = Expression.crefExp(name);
Expand All @@ -3713,7 +3706,7 @@ algorithm
then (vlst,ht,n);
// finished
case (_,_,_,_,_,_,_,_,_) then (iVarLst,iHt,iN);
end matchcontinue;
end match;
end makeHigherStatesRepl1;

protected function addAllDummyStates
Expand Down Expand Up @@ -3841,7 +3834,7 @@ protected function makeAllDummyVarandDummyDerivativeRepl1
output list<BackendDAE.Var> oVarLst;
output HashTableCrIntToExp.HashTable oHt;
algorithm
(oVarLst,oHt) := matchcontinue (diffCount,diffedCount,iOrigName,iName,inVar,vars,so,iVarLst,iHt)
(oVarLst,oHt) := match (diffCount,diffedCount,iOrigName,iName,inVar,vars,so,iVarLst,iHt)
local
HashTableCrIntToExp.HashTable ht;
DAE.ComponentRef name;
Expand Down Expand Up @@ -3896,7 +3889,7 @@ algorithm
Error.addMessage(Error.INTERNAL_ERROR, {"IndexReduction.makeAllDummyVarandDummyDerivativeRepl1 failed!"});
then
fail();
end matchcontinue;
end match;
end makeAllDummyVarandDummyDerivativeRepl1;

protected function addDummyStates
Expand Down Expand Up @@ -4001,12 +3994,12 @@ protected function crefPrefixDerN
output DAE.ComponentRef oName;
output DAE.ComponentRef oDerName;
algorithm
(oName,oDerName) := matchcontinue(n,iName)
(oName,oDerName) := match(n,iName)
local
DAE.ComponentRef name,dername;
case(0,_)
guard not intGt(n,0)
equation
false = intGt(n,0);
dername = ComponentReference.crefPrefixDer(iName);
then
(iName,dername);
Expand All @@ -4016,7 +4009,7 @@ algorithm
(name,dername) = crefPrefixDerN(n-1,dername);
then
(name,dername);
end matchcontinue;
end match;
end crefPrefixDerN;

protected function replaceFirstOrderDerivativesExp "author: Frenkel TUD 2013-01"
Expand Down
Loading

0 comments on commit 5ffd12a

Please sign in to comment.