Skip to content
This repository was archived by the owner on May 18, 2019. It is now read-only.

Commit 53af8ff

Browse files
sjoelundOpenModelica-Hudson
authored andcommitted
Introduce aliasing of SimCode equations
Very many equations are the same in the continuous, initial, lambda0, and parameter equation systems. This makes some of these equations become aliases to other ones. The aliasing is performed as the last step before code generation since this is the most conservative approach (it might be bad for performance since the same traversals have been performed on the different systems). Strongly connected components, if-equations, and algorithms are not considered yet. Roughly 1/3 of the equations seem to be removed by this aliasing which hopefully increases performance. Belonging to [master]: - #2361 - OpenModelica/OpenModelica-testsuite#922
1 parent 4d89e7f commit 53af8ff

File tree

10 files changed

+273
-21
lines changed

10 files changed

+273
-21
lines changed

Compiler/BackEnd/HpcOmTaskGraph.mo

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6898,7 +6898,11 @@ algorithm
68986898
case(SimCode.SES_NONLINEAR(SimCode.NONLINEARSYSTEM(index=index), SOME(SimCode.NONLINEARSYSTEM(index=index2)))) then (index,index2);
68996899
case(SimCode.SES_MIXED(index=index)) then (index,0);
69006900
case(SimCode.SES_WHEN(index=index)) then (index,0);
6901-
else fail();
6901+
case(SimCode.SES_ALIAS(aliasOf=index)) then (index,0);
6902+
else
6903+
algorithm
6904+
Error.addInternalError(getInstanceName()+" failed", sourceInfo());
6905+
then fail();
69026906
end match;
69036907
end getIndexBySimCodeEq;
69046908

Compiler/SimCode/SerializeModelInfo.mo

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1020,6 +1020,16 @@ algorithm
10201020
File.write(file, "}");
10211021
then true;
10221022

1023+
case SimCode.SES_ALIAS() equation
1024+
File.write(file, "\n{\"eqIndex\":");
1025+
File.writeInt(file, eq.index);
1026+
File.write(file, ",\"tag\":\"alias\",\"equation\":[");
1027+
File.writeInt(file, eq.aliasOf);
1028+
File.write(file, "],\"section\":\"");
1029+
File.write(file, section);
1030+
File.write(file, "\"}");
1031+
then true;
1032+
10231033
else equation
10241034
Error.addInternalError("serializeEquation failed: " + anyString(eq), sourceInfo());
10251035
then fail();

Compiler/SimCode/SimCode.mo

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,11 @@ uniontype SimEqSystem
389389
BackendDAE.EquationAttributes eqAttr;
390390
end SES_FOR_LOOP;
391391

392+
record SES_ALIAS
393+
Integer index;
394+
Integer aliasOf;
395+
end SES_ALIAS;
396+
392397
end SimEqSystem;
393398

394399
public

Compiler/SimCode/SimCodeUtil.mo

Lines changed: 126 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ import Global;
9494
import Graph;
9595
import HashSet;
9696
import HashSetExp;
97+
import HashTableSimCodeEqCache;
9798
import HpcOmSimCode;
9899
import Inline;
99100
import List;
@@ -141,6 +142,42 @@ algorithm
141142
// ((i, ht, literals)) := BackendDAEUtil.traverseBackendDAEExpsNoCopyWithUpdate(dae, findLiteralsHelper, (i, ht, literals));
142143
end simulationFindLiterals;
143144

145+
public function hashEqSystemMod
146+
input SimCode.SimEqSystem eq;
147+
input Integer mod;
148+
output Integer hash;
149+
algorithm
150+
hash := match eq
151+
local
152+
DAE.Statement stmt;
153+
case SimCode.SES_RESIDUAL() then Expression.hashExpMod(eq.exp, mod);
154+
case SimCode.SES_SIMPLE_ASSIGN() then intMod(ComponentReference.hashComponentRefMod(eq.cref,mod)+7*Expression.hashExpMod(eq.exp, mod), mod);
155+
case SimCode.SES_SIMPLE_ASSIGN_CONSTRAINTS() then intMod(ComponentReference.hashComponentRefMod(eq.cref,mod)+7*Expression.hashExpMod(eq.exp, mod), mod);
156+
case SimCode.SES_ARRAY_CALL_ASSIGN() then intMod(Expression.hashExpMod(eq.lhs, mod)+7*Expression.hashExpMod(eq.exp, mod), mod);
157+
case SimCode.SES_ALGORITHM(statements={stmt as DAE.STMT_ASSERT()}) then intMod(Expression.hashExpMod(stmt.cond, mod)+7*Expression.hashExpMod(stmt.msg, mod)+49*Expression.hashExpMod(stmt.level, mod), mod);
158+
// Whatever; we're not caching these values anyway
159+
else intMod(valueConstructor(eq), mod);
160+
end match;
161+
end hashEqSystemMod;
162+
163+
public function compareEqSystemsEquality "Is true if the equations are the same except the index. If false they might still be the same."
164+
input SimCode.SimEqSystem eq1;
165+
input SimCode.SimEqSystem eq2;
166+
output Boolean b;
167+
algorithm
168+
b := match (eq1,eq2)
169+
local
170+
DAE.Statement stmt1,stmt2;
171+
case (SimCode.SES_SIMPLE_ASSIGN(),SimCode.SES_SIMPLE_ASSIGN())
172+
then if 0==ComponentReference.crefCompareGeneric(eq1.cref, eq2.cref) then Expression.expEqual(eq1.exp, eq2.exp) else false;
173+
case (SimCode.SES_ARRAY_CALL_ASSIGN(),SimCode.SES_ARRAY_CALL_ASSIGN())
174+
then if Expression.expEqual(eq1.lhs, eq2.lhs) then Expression.expEqual(eq1.exp, eq2.exp) else false;
175+
case (SimCode.SES_ALGORITHM(statements={stmt1 as DAE.STMT_ASSERT()}),SimCode.SES_ALGORITHM(statements={stmt2 as DAE.STMT_ASSERT()}))
176+
then if Expression.expEqual(stmt1.cond, stmt2.cond) then (if Expression.expEqual(stmt1.msg, stmt2.msg) then Expression.expEqual(stmt1.level, stmt2.level) else false) else false;
177+
else false;
178+
end match;
179+
end compareEqSystemsEquality;
180+
144181
// =============================================================================
145182
// section to create SimCode from BackendDAE
146183
//
@@ -182,7 +219,7 @@ protected
182219
HashTableCrIListArray.HashTable varToArrayIndexMapping "maps each array-variable to a array of positions";
183220
HashTableCrILst.HashTable varToIndexMapping "maps each variable to an array position";
184221
Integer maxDelayedExpIndex, uniqueEqIndex, numberofEqns, numStateSets, numberOfJacobians, sccOffset;
185-
Integer numberofLinearSys, numberofNonLinearSys, numberofMixedSys, numberofFixedParameters;
222+
Integer numberofLinearSys, numberofNonLinearSys, numberofMixedSys, numberofFixedParameters, reasonableSize;
186223
Option<SimCode.FmiModelStructure> modelStructure = NONE();
187224
SimCode.BackendMapping backendMapping;
188225
SimCode.ExtObjInfo extObjInfo;
@@ -237,6 +274,7 @@ protected
237274
Integer SymEuler_help = 0;
238275
SimCodeVar.SimVar dtSimVar;
239276
BackendDAE.Var dtVar;
277+
HashTableSimCodeEqCache.HashTable eqCache;
240278

241279
constant Boolean debug = false;
242280
algorithm
@@ -490,7 +528,6 @@ algorithm
490528
if Flags.isSet(Flags.EXEC_HASH) then
491529
print("*** SimCode -> generate cref2simVar hashtable done!: " + realString(clock()) + "\n");
492530
end if;
493-
494531
// add known inline vars to simVarHT
495532
if (Flags.getConfigEnum(Flags.SYM_SOLVER) > 0) then
496533
SOME(inlineData) := inInlineData;
@@ -526,6 +563,20 @@ algorithm
526563

527564
(crefToClockIndexHT, _) := List.fold(listReverse(inBackendDAE.eqs), collectClockedVars, (HashTable.emptyHashTable(), 1));
528565

566+
reasonableSize := Util.nextPrime(10+2*listLength(allEquations));
567+
eqCache := HashTableSimCodeEqCache.emptyHashTableSized(reasonableSize);
568+
569+
(allEquations, eqCache) := aliasSimEqs(allEquations, eqCache);
570+
(odeEquations, eqCache) := aliasSimEqSystems(odeEquations, eqCache);
571+
(algebraicEquations, eqCache) := aliasSimEqSystems(algebraicEquations, eqCache);
572+
(initialEquations, eqCache) := aliasSimEqs(initialEquations, eqCache);
573+
(initialEquations_lambda0, eqCache) := aliasSimEqs(initialEquations_lambda0, eqCache);
574+
(removedEquations, eqCache) := aliasSimEqs(removedEquations, eqCache);
575+
(removedInitialEquations, eqCache) := aliasSimEqs(removedInitialEquations, eqCache);
576+
(algorithmAndEquationAsserts, eqCache) := aliasSimEqs(algorithmAndEquationAsserts, eqCache);
577+
(jacobianEquations, eqCache) := aliasSimEqs(jacobianEquations, eqCache);
578+
(parameterEquations, eqCache) := aliasSimEqs(parameterEquations, eqCache);
579+
529580
simCode := SimCode.SIMCODE(modelInfo,
530581
{}, // Set by the traversal below...
531582
recordDecls,
@@ -1503,7 +1554,6 @@ algorithm
15031554
BackendDump.dumpEquationList(eqnlst,"Equations:");
15041555
BackendDump.dumpVarList(varlst,"Variables:");
15051556
end if;
1506-
15071557
// skip is when equations
15081558
skip := List.mapBoolAnd(eqnlst, BackendEquation.isWhenEquation);
15091559
// skip is discrete
@@ -1694,7 +1744,7 @@ protected function appendSccIdxRange
16941744
input Integer iCurrentIdxStop;
16951745
input Integer iSccIdx;
16961746
input list<tuple<Integer,Integer>> iSccIdc;
1697-
output list<tuple<Integer,Integer>> oSccIdc;
1747+
output list<tuple<Integer,Integer>> oSccIdc = iSccIdc;
16981748
algorithm
16991749
for i in iCurrentIdxStop:-1:iCurrentIdxStart loop
17001750
oSccIdc := ((i,iSccIdx))::iSccIdc;
@@ -2021,16 +2071,24 @@ protected
20212071
BackendDAE.Variables vars;
20222072
BackendDAE.EquationArray eqns;
20232073
BackendDAE.Equation eqn;
2074+
BackendDAE.Var v;
20242075
algorithm
20252076
BackendDAE.EQSYSTEM(orderedVars=vars, orderedEqs=eqns) := syst;
20262077
eqn := BackendEquation.get(eqns, eqNum);
2078+
_ := match eqn
2079+
case BackendDAE.WHEN_EQUATION() then ();
2080+
else
2081+
algorithm
2082+
v := BackendVariable.getVarAt(vars, varNum);
2083+
then ();
2084+
end match;
2085+
20272086
(equation_, ouniqueEqIndex, otempvars) := match eqn
20282087
local
20292088
DAE.ComponentRef cr;
20302089
BackendDAE.VarKind kind;
20312090
Option<DAE.VariableAttributes> values;
2032-
BackendDAE.Var v;
2033-
Integer uniqueEqIndex;
2091+
Integer uniqueEqIndex1, uniqueEqIndex;
20342092
list<DAE.Statement> algStatements;
20352093
list<DAE.ComponentRef> conditions, solveCr;
20362094
list<SimCode.SimEqSystem> resEqs;
@@ -2057,10 +2115,10 @@ algorithm
20572115

20582116
// solved equation
20592117
case BackendDAE.SOLVED_EQUATION(exp=e2, source=source, attr=eqAttr)
2060-
equation
2061-
(v as BackendDAE.VAR(varName = cr)) = BackendVariable.getVarAt(vars, varNum);
2062-
varexp = Expression.crefExp(cr);
2063-
varexp = if BackendVariable.isStateVar(v) then Expression.expDer(varexp) else varexp;
2118+
algorithm
2119+
cr := v.varName;
2120+
varexp := Expression.crefExp(cr);
2121+
varexp := if BackendVariable.isStateVar(v) then Expression.expDer(varexp) else varexp;
20642122
then
20652123
({SimCode.SES_SIMPLE_ASSIGN(iuniqueEqIndex, cr, e2, source, eqAttr)}, iuniqueEqIndex+1, itempvars);
20662124

@@ -2083,7 +2141,7 @@ algorithm
20832141
// single equation
20842142
case BackendDAE.EQUATION(exp=e1, scalar=e2, source=source, attr=eqAttr)
20852143
algorithm
2086-
(v as BackendDAE.VAR(varName = cr)) := BackendVariable.getVarAt(vars, varNum);
2144+
cr := v.varName;
20872145
varexp := Expression.crefExp(cr);
20882146
varexp := if BackendVariable.isStateVar(v) then Expression.expDer(varexp) else varexp;
20892147
BackendDAE.SHARED(functionTree = funcs) := shared;
@@ -2098,11 +2156,11 @@ algorithm
20982156
solveCr := listReverse(solveCr);
20992157
cr := if BackendVariable.isStateVar(v) then ComponentReference.crefPrefixDer(cr) else cr;
21002158
source := ElementSource.addSymbolicTransformationSolve(true, source, cr, e1, e2, exp_, asserts);
2101-
(eqSystlst, uniqueEqIndex) := List.mapFold(solveEqns, makeSolved_SES_SIMPLE_ASSIGN, iuniqueEqIndex);
2159+
(eqSystlst, uniqueEqIndex1) := List.mapFold(solveEqns, makeSolved_SES_SIMPLE_ASSIGN, iuniqueEqIndex);
21022160
if listEmpty(cons) then
2103-
(resEqs, uniqueEqIndex) := addAssertEqn(asserts, {SimCode.SES_SIMPLE_ASSIGN(uniqueEqIndex, cr, exp_, source, eqAttr)}, uniqueEqIndex+1);
2161+
(resEqs, uniqueEqIndex) := addAssertEqn(asserts, {SimCode.SES_SIMPLE_ASSIGN(uniqueEqIndex1, cr, exp_, source, eqAttr)}, uniqueEqIndex1+1);
21042162
else
2105-
(resEqs, uniqueEqIndex) := addAssertEqn(asserts, {SimCode.SES_SIMPLE_ASSIGN_CONSTRAINTS(uniqueEqIndex, cr, exp_, source, cons, eqAttr)}, uniqueEqIndex+1);
2163+
(resEqs, uniqueEqIndex) := addAssertEqn(asserts, {SimCode.SES_SIMPLE_ASSIGN_CONSTRAINTS(uniqueEqIndex1, cr, exp_, source, cons, eqAttr)}, uniqueEqIndex1+1);
21062164
end if;
21072165
eqSystlst := listAppend(eqSystlst,resEqs);
21082166
tempvars := createTempVarsforCrefs(List.map(solveCr, Expression.crefExp),itempvars);
@@ -2141,7 +2199,6 @@ algorithm
21412199
case BackendDAE.ALGORITHM(alg=alg, source=source, expand=crefExpand, attr=eqAttr)
21422200
algorithm
21432201
varOutput::{} := CheckModel.checkAndGetAlgorithmOutputs(alg, source, crefExpand);
2144-
v := BackendVariable.getVarAt(vars, varNum);
21452202
// The output variable of the algorithm must be the variable solved
21462203
// for, otherwise we need to solve an inverse problem of an algorithm
21472204
// section.
@@ -7290,7 +7347,7 @@ algorithm
72907347
end dumpSimEqSystemLst;
72917348

72927349

7293-
protected function simEqSystemString
7350+
public function simEqSystemString
72947351
"outputs a string representation of the given SimEqSystem.
72957352
author:Waurich TUD 2016-04"
72967353
input SimCode.SimEqSystem eqSysIn;
@@ -7422,6 +7479,11 @@ algorithm
74227479
s = s+"end for;";
74237480
then s;
74247481

7482+
case SimCode.SES_ALIAS()
7483+
equation
7484+
s = String(eqSysIn.index) +": alias of "+ String(eqSysIn.aliasOf);
7485+
then s;
7486+
74257487
else
74267488
then
74277489
"SOMETHING DIFFERENT\n";
@@ -8889,6 +8951,7 @@ algorithm
88898951
case SimCode.SES_MIXED(index=index) then index;
88908952
case SimCode.SES_WHEN(index=index) then index;
88918953
case SimCode.SES_FOR_LOOP(index=index) then index;
8954+
case SimCode.SES_ALIAS(index=index) then index;
88928955
else
88938956
equation
88948957
Error.addMessage(Error.INTERNAL_ERROR,{"SimCodeUtil.simEqSystemIndex failed"});
@@ -10379,6 +10442,14 @@ algorithm
1037910442
case (SimCode.SES_FOR_LOOP(), _, a)
1038010443
/* TODO: Me */
1038110444
then (eq, a);
10445+
10446+
case (SimCode.SES_ALIAS(), _, a)
10447+
then (eq, a);
10448+
10449+
else
10450+
algorithm
10451+
Error.addInternalError(getInstanceName() + " got unknown equation", sourceInfo());
10452+
then fail();
1038210453
end match;
1038310454
end traverseExpsEqSystem;
1038410455

@@ -13061,5 +13132,44 @@ algorithm
1306113132
end match;
1306213133
end findResources;
1306313134

13135+
function aliasSimEqSystems
13136+
input output list<list<SimCode.SimEqSystem>> eqs;
13137+
input output HashTableSimCodeEqCache.HashTable cache;
13138+
algorithm
13139+
(eqs, cache) := List.mapFold(eqs, aliasSimEqs, cache);
13140+
end aliasSimEqSystems;
13141+
13142+
function aliasSimEqs
13143+
input output list<SimCode.SimEqSystem> eqs;
13144+
input output HashTableSimCodeEqCache.HashTable cache;
13145+
algorithm
13146+
(eqs, cache) := List.mapFold(eqs, aliasSimEq, cache);
13147+
end aliasSimEqs;
13148+
13149+
function aliasSimEq
13150+
input output SimCode.SimEqSystem eq;
13151+
input output HashTableSimCodeEqCache.HashTable cache;
13152+
protected
13153+
Integer ix, aliasOf;
13154+
algorithm
13155+
ix := simEqSystemIndex(eq);
13156+
if BaseHashTable.hasKey(eq,cache) then
13157+
aliasOf := BaseHashTable.get(eq,cache);
13158+
if aliasOf <> ix then
13159+
eq := SimCode.SES_ALIAS(ix, BaseHashTable.get(eq,cache));
13160+
end if;
13161+
return;
13162+
end if;
13163+
if match eq
13164+
case SimCode.SES_SIMPLE_ASSIGN() then true;
13165+
case SimCode.SES_ARRAY_CALL_ASSIGN() then true;
13166+
case SimCode.SES_ALGORITHM(statements={DAE.STMT_NORETCALL()}) then true;
13167+
// TODO: Check if LS / NLS are equal and alias the whole systems?
13168+
else false;
13169+
end match then
13170+
cache := BaseHashTable.add((eq,ix), cache);
13171+
end if;
13172+
end aliasSimEq;
13173+
1306413174
annotation(__OpenModelica_Interface="backend");
1306513175
end SimCodeUtil;

Compiler/Template/CodegenC.tpl

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3010,7 +3010,7 @@ template functionEquationsMultiFiles(list<SimEqSystem> inEqs, Integer numEqs, In
30103010
<%simulationFileHeader(fileNamePrefix)%>
30113011
#if defined(__cplusplus)
30123012
extern "C" {
3013-
#endif
3013+
#endif<%\n%>
30143014
>>)) +
30153015
(eqs |> eq => equation_impl_options(-1, eq, contextSimulationDiscrete, modelNamePrefix, static, noOpt) ; separator="\n") +
30163016
<<
@@ -4839,7 +4839,7 @@ template equation_arrayFormat(SimEqSystem eq, String name, Context context, Inte
48394839
case e as SES_MIXED(__)
48404840
then equationMixed(e, context, &eqfuncs, modelNamePrefix)
48414841
else
4842-
"NOT IMPLEMENTED EQUATION equation_"
4842+
error(sourceInfo(), "NOT IMPLEMENTED EQUATION equation_")
48434843

48444844
let &eqArray += '<%symbolName(modelNamePrefix,"eqFunction")%>_<%ix%>, <%\n%>'
48454845
let &varD += addRootsTempArray()
@@ -4889,7 +4889,8 @@ template equation_impl2(Integer clockIndex, SimEqSystem eq, Context context, Str
48894889
::=
48904890
let OMC_NO_OPT = if noOpt then 'OMC_DISABLE_OPT<%\n%>' else (match eq case SES_LINEAR(__) then 'OMC_DISABLE_OPT<%\n%>')
48914891
match eq
4892-
case e as SES_ALGORITHM(statements={})
4892+
case SES_ALIAS(__) then 'extern void <%symbolName(modelNamePrefix,"eqFunction")%>_<%aliasOf%>(DATA *data, threadData_t *threadData);<%\n%>'
4893+
case SES_ALGORITHM(statements={})
48934894
then ""
48944895
else
48954896
(
@@ -4936,7 +4937,7 @@ template equation_impl2(Integer clockIndex, SimEqSystem eq, Context context, Str
49364937
case e as SES_FOR_LOOP(__)
49374938
then equationForLoop(e, context, &varD, &tempeqns)
49384939
else
4939-
"NOT IMPLEMENTED EQUATION equation_"
4940+
error(sourceInfo(), "NOT IMPLEMENTED EQUATION equation_")
49404941
let x2 = match eq
49414942
case e as SES_LINEAR(lSystem=ls as LINEARSYSTEM(__), alternativeTearing = SOME(at as LINEARSYSTEM(__))) then
49424943
equationLinearAlternativeTearing(e, context, &varD)

Compiler/Template/CodegenUtilSimulation.tpl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,9 @@ template equationIndex(SimEqSystem eq)
8484
case SES_WHEN(__)
8585
case SES_FOR_LOOP(__)
8686
then index
87+
case SES_ALIAS(__)
88+
then aliasOf
89+
else error(sourceInfo(), "equationIndex failed")
8790
end equationIndex;
8891

8992
template equationIndexAlternativeTearing(SimEqSystem eq)

Compiler/Template/CodegenXML.tpl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -722,6 +722,8 @@ template equation_Xml(SimEqSystem eq, Context context, Text &varDecls /*BUFP*/,
722722
then equationNonlinearXml(e, context, &varD /*BUFD*/)
723723
case e as SES_WHEN(__)
724724
then " "
725+
case e as SES_ALIAS(__)
726+
then " "
725727
else
726728
"NOT IMPLEMENTED EQUATION"
727729
let &eqs +=

Compiler/Template/SimCodeTV.mo

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,10 @@ package SimCode
512512
DAE.ElementSource source;
513513
BackendDAE.EquationAttributes eqAttr;
514514
end SES_FOR_LOOP;
515+
516+
record SES_ALIAS
517+
Integer aliasOf;
518+
end SES_ALIAS;
515519
end SimEqSystem;
516520

517521
uniontype LinearSystem

0 commit comments

Comments
 (0)