Skip to content

Commit 4eaefd5

Browse files
committed
Fix BackendDAEOptimize.listAllIterationVariables
- Change listAllIterationVariables to use for-loops instead of recursion to avoid stack overflows.
1 parent 7150e7f commit 4eaefd5

File tree

1 file changed

+67
-87
lines changed

1 file changed

+67
-87
lines changed

OMCompiler/Compiler/BackEnd/BackendDAEOptimize.mo

Lines changed: 67 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -5624,23 +5624,20 @@ public function listAllIterationVariables0 "author: lochel"
56245624
input list<BackendDAE.EqSystem> inEqs;
56255625
output list<String> outWarnings;
56265626
output list<DAE.ComponentRef> outComponentRef;
5627+
protected
5628+
list<String> warnings;
5629+
list<DAE.ComponentRef> crefs;
5630+
list<list<String>> warnings_accum = {};
5631+
list<list<DAE.ComponentRef>> crefs_accum = {};
56275632
algorithm
5628-
(outWarnings, outComponentRef) := match(inEqs)
5629-
local
5630-
BackendDAE.EqSystem eq;
5631-
list<BackendDAE.EqSystem> eqs;
5632-
list<String> warning;
5633-
list<String> warningList;
5634-
list<DAE.ComponentRef> creflist1,creflist2;
5635-
5636-
case ({})
5637-
then ({},{});
5638-
5639-
case (eq::eqs) equation
5640-
(warning, creflist1) = listAllIterationVariables1(eq);
5641-
(warningList, creflist2) = listAllIterationVariables0(eqs);
5642-
then (listAppend(warning, warningList), listAppend(creflist1, creflist2));
5643-
end match;
5633+
for eq in inEqs loop
5634+
(warnings, crefs) := listAllIterationVariables1(eq);
5635+
warnings_accum := warnings :: warnings_accum;
5636+
crefs_accum := crefs :: crefs_accum;
5637+
end for;
5638+
5639+
outWarnings := List.flattenReverse(warnings_accum);
5640+
outComponentRef := List.flattenReverse(crefs_accum);
56445641
end listAllIterationVariables0;
56455642

56465643
protected function listAllIterationVariables1 "author: lochel"
@@ -5656,80 +5653,63 @@ algorithm
56565653
(outWarning, outComponentRef) := listAllIterationVariables2(comps, vars);
56575654
end listAllIterationVariables1;
56585655

5659-
protected function listAllIterationVariables2 "author: lochel"
5660-
input BackendDAE.StrongComponents inComps;
5661-
input BackendDAE.Variables inVars;
5662-
output list<String> outWarning;
5663-
output list<DAE.ComponentRef> outComponentRef;
5656+
protected function listAllIterationVariables2
5657+
input BackendDAE.StrongComponents comps;
5658+
input BackendDAE.Variables vars;
5659+
output list<String> warnings = {};
5660+
output list<DAE.ComponentRef> componentRefs = {};
5661+
protected
5662+
list<Integer> var_idxs, var_idxs2;
5663+
5664+
constant String NONLINEAR_SYSTEM = "Iteration variables of nonlinear equation system:\n";
5665+
constant String ANALYTIC_JACOBIAN = "Iteration variables of equation system with analytic Jacobian:\n";
5666+
constant String NO_ANALYTIC_JACOBIAN = "Iteration variables of equation system without analytic Jacobian:\n";
5667+
constant String TORN_LINEAR = "Iteration variables of torn linear equation system:\n";
5668+
constant String TORN_NONLINEAR = "Iteration variables of torn nonlinear equation system:\n";
56645669
algorithm
5665-
(outWarning, outComponentRef) := matchcontinue(inComps, inVars)
5666-
local
5667-
BackendDAE.StrongComponents rest;
5668-
list<BackendDAE.Var> varlst;
5669-
list<Integer> vlst,vlst2;
5670-
Boolean linear;
5671-
String str;
5672-
String warning;
5673-
list<String> warningList;
5674-
list<DAE.ComponentRef> crefList;
5675-
5676-
case ({}, _)
5677-
then ({}, {});
5678-
5679-
case (BackendDAE.EQUATIONSYSTEM(vars=vlst, jacType=BackendDAE.JAC_NONLINEAR())::rest, _) equation
5680-
varlst = List.map1r(vlst, BackendVariable.getVarAt, inVars);
5681-
false = listEmpty(varlst);
5682-
crefList = List.map(varlst, BackendVariable.varCref); // create cref list of the iterationVars
5683-
5684-
warning = "Iteration variables of nonlinear equation system:\n" + warnAboutVars(varlst);
5685-
warningList = listAllIterationVariables2(rest, inVars);
5686-
then (warning::warningList, crefList);
5687-
5688-
case (BackendDAE.EQUATIONSYSTEM(vars=vlst, jacType=BackendDAE.JAC_GENERIC())::rest, _) equation
5689-
varlst = List.map1r(vlst, BackendVariable.getVarAt, inVars);
5690-
false = listEmpty(varlst);
5691-
crefList = List.map(varlst, BackendVariable.varCref); // create cref list of the iterationVars
5692-
5693-
warning = "Iteration variables of equation system with analytic Jacobian:\n" + warnAboutVars(varlst);
5694-
warningList = listAllIterationVariables2(rest, inVars);
5695-
then (warning::warningList, crefList);
5696-
5697-
case (BackendDAE.EQUATIONSYSTEM(vars=vlst, jacType=BackendDAE.JAC_NO_ANALYTIC())::rest, _) equation
5698-
varlst = List.map1r(vlst, BackendVariable.getVarAt, inVars);
5699-
false = listEmpty(varlst);
5700-
crefList = List.map(varlst, BackendVariable.varCref); // create cref list of the iterationVars
5701-
5702-
warning = "Iteration variables of equation system without analytic Jacobian:\n" + warnAboutVars(varlst);
5703-
warningList = listAllIterationVariables2(rest, inVars);
5704-
then (warning::warningList, crefList);
5705-
5706-
case (BackendDAE.TORNSYSTEM(strictTearingSet=BackendDAE.TEARINGSET(tearingvars=vlst), casualTearingSet=NONE(), linear=linear)::rest, _) equation
5707-
varlst = List.map1r(vlst, BackendVariable.getVarAt, inVars);
5708-
false = listEmpty(varlst);
5709-
crefList = List.map(varlst, BackendVariable.varCref); // create cref list of the iterationVars
5710-
5711-
str = if linear then "linear" else "nonlinear";
5712-
warning = "Iteration variables of torn " + str + " equation system:\n" + warnAboutVars(varlst);
5713-
warningList = listAllIterationVariables2(rest, inVars);
5714-
then (warning::warningList, crefList);
5715-
5716-
case (BackendDAE.TORNSYSTEM(strictTearingSet=BackendDAE.TEARINGSET(tearingvars=vlst), casualTearingSet=SOME(BackendDAE.TEARINGSET(tearingvars=vlst2)), linear=linear)::rest, _) equation
5717-
vlst = List.unique(listAppend(vlst,vlst2));
5718-
varlst = List.map1r(vlst, BackendVariable.getVarAt, inVars);
5719-
false = listEmpty(varlst);
5720-
crefList = List.map(varlst, BackendVariable.varCref); // create cref list of the iterationVars
5721-
5722-
str = if linear then "linear" else "nonlinear";
5723-
warning = "Iteration variables of torn " + str + " equation system:\n" + warnAboutVars(varlst);
5724-
warningList = listAllIterationVariables2(rest, inVars);
5725-
then (warning::warningList, crefList);
5726-
5727-
case (_::rest, _) equation
5728-
(warningList, crefList) = listAllIterationVariables2(rest, inVars);
5729-
then (warningList, crefList);
5730-
end matchcontinue;
5670+
for comp in listReverse(comps) loop
5671+
(warnings, componentRefs) := match comp
5672+
case BackendDAE.EQUATIONSYSTEM(jacType = BackendDAE.JAC_NONLINEAR())
5673+
then listAllIterationVariables3(comp.vars, vars, NONLINEAR_SYSTEM, warnings, componentRefs);
5674+
5675+
case BackendDAE.EQUATIONSYSTEM(jacType = BackendDAE.JAC_GENERIC())
5676+
then listAllIterationVariables3(comp.vars, vars, ANALYTIC_JACOBIAN, warnings, componentRefs);
5677+
5678+
case BackendDAE.EQUATIONSYSTEM(jacType = BackendDAE.JAC_NO_ANALYTIC())
5679+
then listAllIterationVariables3(comp.vars, vars, NO_ANALYTIC_JACOBIAN, warnings, componentRefs);
5680+
5681+
case BackendDAE.TORNSYSTEM(strictTearingSet = BackendDAE.TEARINGSET(tearingvars = var_idxs),
5682+
casualTearingSet = NONE())
5683+
then listAllIterationVariables3(var_idxs, vars,
5684+
if comp.linear then TORN_LINEAR else TORN_NONLINEAR, warnings, componentRefs);
5685+
5686+
case BackendDAE.TORNSYSTEM(strictTearingSet = BackendDAE.TEARINGSET(tearingvars = var_idxs),
5687+
casualTearingSet = SOME(BackendDAE.TEARINGSET(tearingvars = var_idxs2)))
5688+
then
5689+
listAllIterationVariables3(List.union(var_idxs, var_idxs2), vars,
5690+
if comp.linear then TORN_LINEAR else TORN_NONLINEAR, warnings, componentRefs);
5691+
5692+
else (warnings, componentRefs);
5693+
end match;
5694+
end for;
57315695
end listAllIterationVariables2;
57325696

5697+
protected function listAllIterationVariables3
5698+
input list<Integer> varIndices;
5699+
input BackendDAE.Variables allVars;
5700+
input String message;
5701+
input output list<String> warnings;
5702+
input output list<DAE.ComponentRef> crefs;
5703+
protected
5704+
list<BackendDAE.Var> vars;
5705+
algorithm
5706+
if not listEmpty(varIndices) then
5707+
vars := list(BackendVariable.getVarAt(allVars, v) for v in varIndices);
5708+
crefs := list(BackendVariable.varCref(v) for v in vars);
5709+
warnings := (message + warnAboutVars(vars)) :: warnings;
5710+
end if;
5711+
end listAllIterationVariables3;
5712+
57335713
protected function warnAboutVars
57345714
input list<BackendDAE.Var> vars;
57355715
output String str;

0 commit comments

Comments
 (0)