Skip to content

Commit

Permalink
Vectorize equations with iter at appropriate position
Browse files Browse the repository at this point in the history
Basically replace crefSetLastSubs with crefApplySubs.

Belonging to [master]:
  - OpenModelica/OMCompiler#2786
  - OpenModelica/OpenModelica-testsuite#1075
  • Loading branch information
rfranke authored and OpenModelica-Hudson committed Nov 14, 2018
1 parent c308368 commit 789a1ec
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 24 deletions.
2 changes: 1 addition & 1 deletion Compiler/BackEnd/SynchronousFeatures.mo
Expand Up @@ -249,7 +249,7 @@ algorithm
// add forIter subscript and use element type if var is array
derVar := match var.varType
case DAE.T_ARRAY(ty = ty)
then ComponentReference.crefSetLastSubs(derVar, {DAE.INDEX(DAE.CREF(DAE.CREF_IDENT("i", DAE.T_INTEGER_DEFAULT, {}), DAE.T_INTEGER_DEFAULT))});
then ComponentReference.crefApplySubs(derVar, {DAE.INDEX(DAE.CREF(DAE.CREF_IDENT("i", DAE.T_INTEGER_DEFAULT, {}), DAE.T_INTEGER_DEFAULT))});
else derVar;
end match;
exp := DAE.CALL(Absyn.IDENT(name = "der"), {DAE.CREF(derVar, ty)}, DAE.callAttrBuiltinImpureReal);
Expand Down
75 changes: 63 additions & 12 deletions Compiler/FrontEnd/ComponentReference.mo
Expand Up @@ -2430,6 +2430,43 @@ algorithm
end match;
end crefSetLastSubs;

public function crefApplySubs
"Apply subs to the first componenentref ident that is of array type.
TODO: must not apply subs whose list length exceeds array dimensions.
author: rfranke"
input DAE.ComponentRef inComponentRef;
input list<DAE.Subscript> inSubs;
output DAE.ComponentRef outComponentRef;
algorithm
outComponentRef := match inComponentRef
local
DAE.Ident id;
DAE.Type tp;
list<DAE.Subscript> subs;
DAE.ComponentRef cr;

case DAE.CREF_IDENT(ident = id, identType = tp as DAE.T_ARRAY(), subscriptLst = subs)
then
makeCrefIdent(id, tp, listAppend(subs, inSubs));

case DAE.CREF_QUAL(ident = id, identType = tp as DAE.T_ARRAY(), subscriptLst = subs, componentRef = cr)
then
makeCrefQual(id, tp, listAppend(subs, inSubs), cr);

case DAE.CREF_QUAL(ident = id, identType = tp, subscriptLst = subs, componentRef = cr)
equation
cr = crefApplySubs(cr, inSubs);
then
makeCrefQual(id, tp, subs, cr);

else
equation
Error.addInternalError("function ComponentReference.crefApplySubs to non array\n", sourceInfo());
then
fail();
end match;
end crefApplySubs;

public function crefSetType "
sets the type of a cref."
input DAE.ComponentRef inRef;
Expand Down Expand Up @@ -2771,25 +2808,39 @@ algorithm
end crefStripLastSubs;

public function crefStripIterSub
"Strips the last sub if it is equal to the given iter ident.
"Recursively looks up subscripts and strips the given iter sub.
This gives an array variable that is defined in a for loop (no NF_SCALARIZE).
author: rfranke"
input DAE.ComponentRef inComponentRef;
input DAE.Ident iter;
output DAE.ComponentRef outComponentRef;
protected
DAE.Ident index;
DAE.Ident ident, index;
DAE.Type ty;
list<DAE.Subscript> subs;
DAE.ComponentRef cref;
algorithm
outComponentRef := match crefLastSubs(inComponentRef)
case {DAE.INDEX(exp = DAE.CREF(componentRef = DAE.CREF_IDENT(ident = index)))}
algorithm
if index == iter then
outComponentRef := crefStripLastSubs(inComponentRef);
else
outComponentRef := inComponentRef;
end if;
then outComponentRef;
else inComponentRef;
outComponentRef := match inComponentRef
case DAE.CREF_IDENT(ident = ident, identType = ty,
subscriptLst = subs as {DAE.INDEX(exp = DAE.CREF(componentRef = DAE.CREF_IDENT(ident = index)))})
then
makeCrefIdent(ident, ty, if index == iter then {} else subs);
case DAE.CREF_QUAL(ident = ident, identType = ty, componentRef = cref,
subscriptLst = subs as {DAE.INDEX(exp = DAE.CREF(componentRef = DAE.CREF_IDENT(ident = index)))})
algorithm
if index == iter then
subs := {};
else
cref := crefStripIterSub(cref, iter);
end if;
then
makeCrefQual(ident, ty, subs, cref);
case DAE.CREF_QUAL(ident = ident, identType = ty, componentRef = cref,
subscriptLst = subs)
then
makeCrefQual(ident, ty, subs, crefStripIterSub(cref, iter));
else
inComponentRef;
end match;
end crefStripIterSub;

Expand Down
2 changes: 1 addition & 1 deletion Compiler/NFFrontEnd/NFFlatten.mo
Expand Up @@ -707,7 +707,7 @@ algorithm
algorithm
restString := ComponentRef.toString(restCref);
if prefixLength <= stringLength(restString) and prefixString == substring(restString, 1, prefixLength) then
exp.cref := ComponentRef.setSubscripts(subscript :: ComponentRef.getSubscripts(exp.cref), exp.cref);
exp.cref := ComponentRef.applySubscripts({subscript}, exp.cref);
end if;
then
exp;
Expand Down
4 changes: 3 additions & 1 deletion Compiler/SimCode/SimCodeFunctionUtil.mo
Expand Up @@ -131,8 +131,10 @@ public function crefIsScalar
algorithm
if inFunctionContext(context) then
isScalar := listEmpty(ComponentReference.crefLastSubs(cref));
else
elseif Flags.isSet(Flags.NF_SCALARIZE) then
isScalar := ComponentReference.crefHasScalarSubscripts(cref);
else
isScalar := not ComponentReference.crefHaveSubs(cref);
end if;
end crefIsScalar;

Expand Down
23 changes: 17 additions & 6 deletions Compiler/SimCode/SimCodeUtil.mo
Expand Up @@ -2123,9 +2123,14 @@ algorithm
then fail();
end match;
DAE.CREF(componentRef = DAE.CREF_IDENT(ident = iter)) := varexp;
cr := ComponentReference.crefSetLastSubs(v.varName, {DAE.INDEX(DAE.CREF(DAE.CREF_IDENT(iter, DAE.T_INTEGER_DEFAULT, {}), DAE.T_INTEGER_DEFAULT))});
cr := ComponentReference.crefApplySubs(v.varName, {DAE.INDEX(DAE.CREF(DAE.CREF_IDENT(iter, DAE.T_INTEGER_DEFAULT, {}), DAE.T_INTEGER_DEFAULT))});
BackendDAE.SHARED(functionTree = funcs) := shared;
(exp_, asserts, solveEqns, solveCr) := ExpressionSolve.solve2(e1, e2, Expression.crefExp(cr), SOME(funcs), SOME(iuniqueEqIndex), true, BackendDAEUtil.isSimulationDAE(shared));
try
(exp_, asserts, solveEqns, solveCr) := ExpressionSolve.solve2(e1, e2, Expression.crefExp(cr), SOME(funcs), SOME(iuniqueEqIndex), true, BackendDAEUtil.isSimulationDAE(shared));
else
Error.addInternalError("solving FOR_EQUATION body: " + BackendDump.equationString(eqn.body) + "\nfor variable: " + ComponentReference.printComponentRefStr(cr) + ".", sourceInfo());
fail();
end try;
then
({SimCode.SES_FOR_LOOP(iuniqueEqIndex, varexp, start, cond, cr, exp_, source, eqAttr)}, iuniqueEqIndex + 1, itempvars);

Expand Down Expand Up @@ -5582,7 +5587,7 @@ algorithm
else equation
BackendDAE.VAR(varName = cr)::_ = inVars;
str = BackendDump.dumpEqnsStr(inEquations);
str = "solving array equation: " + str + "\nfor variable: " + ComponentReference.crefStr(cr) + ".";
str = "solving array equation: " + str + "\nfor variable: " + ComponentReference.printComponentRefStr(cr) + ".";
Error.addInternalError(str, sourceInfo());
then fail();
end matchcontinue;
Expand Down Expand Up @@ -12676,9 +12681,15 @@ algorithm
sv := BaseHashTable.get(cref, crefToSimVarHT);
else
// lookup array variable and add offset for array element
sv := BaseHashTable.get(ComponentReference.crefStripLastSubs(cref), crefToSimVarHT);
subs := ComponentReference.crefLastSubs(cref);
sv.name := ComponentReference.crefSetLastSubs(sv.name, subs);
if Flags.isSet(Flags.NF_SCALARIZE) then
sv := BaseHashTable.get(ComponentReference.crefStripLastSubs(cref), crefToSimVarHT);
subs := ComponentReference.crefLastSubs(cref);
sv.name := ComponentReference.crefSetLastSubs(sv.name, subs);
else
sv := BaseHashTable.get(ComponentReference.crefStripSubs(cref), crefToSimVarHT);
subs := ComponentReference.crefSubs(cref);
sv.name := ComponentReference.crefApplySubs(sv.name, subs);
end if;
sv.variable_index := match sv.variable_index
case SOME(index)
then SOME(index + getScalarElementIndex(subs, List.map(sv.numArrayElement, stringInt)) - 1);
Expand Down
10 changes: 7 additions & 3 deletions Compiler/Template/CodegenCppCommon.tpl
Expand Up @@ -319,8 +319,12 @@ template crefToCStr(ComponentRef cr, Boolean useFlatArrayNotation)
"Helper function to cref."
::=
match cr
case CREF_IDENT(__) then '<%ident%>_<%subscriptsToCStr(subscriptLst, useFlatArrayNotation)%>'
case CREF_QUAL(__) then '<%ident%><%subscriptsToCStrForArray(subscriptLst)%>_P_<%crefToCStr(componentRef,useFlatArrayNotation)%>'
case CREF_IDENT(__) then
let subs = if Flags.isSet(Flags.NF_SCALARIZE) then subscriptsToCStr(subscriptLst, useFlatArrayNotation)
'<%ident%>_<%subs%>'
case CREF_QUAL(__) then
let subs = if Flags.isSet(Flags.NF_SCALARIZE) then subscriptsToCStrForArray(subscriptLst)
'<%ident%><%subs%>_P_<%crefToCStr(componentRef, useFlatArrayNotation)%>'
case WILD(__) then ''
else "CREF_NOT_IDENT_OR_QUAL"
end crefToCStr;
Expand Down Expand Up @@ -1706,7 +1710,7 @@ template daeExpCall(Exp call, Context context, Text &preExp /*BUFP*/, Text &varD
'_discrete_events->pre(<%var1%>)'

case CALL(path=IDENT(name="previous"), expLst={arg as CREF(__)}) then
'<%contextSystem(context)%><%cref(crefPrefixPrevious(arg.componentRef), useFlatArrayNotation)%>'
'<%daeExp(crefExp(crefPrefixPrevious(arg.componentRef)), context, &preExp, &varDecls, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation)%>'

case CALL(path=IDENT(name="firstTick")) then
'(<%contextSystem(context)%>_clockStart[clockIndex - 1] || <%contextSystem(context)%>_clockSubactive[clockIndex - 1])'
Expand Down

0 comments on commit 789a1ec

Please sign in to comment.