Skip to content

Commit

Permalink
[BE] Index reduction update
Browse files Browse the repository at this point in the history
   - consider non states as stateSelect never
  • Loading branch information
kabdelhak authored and adrpo committed Dec 19, 2019
1 parent 2a7939a commit 387c3b2
Show file tree
Hide file tree
Showing 16 changed files with 339 additions and 342 deletions.
2 changes: 1 addition & 1 deletion OMCompiler/Compiler/BackEnd/BackendDAE.mo
Expand Up @@ -258,7 +258,7 @@ uniontype VarKind "variable kind"
record STATE
Integer index "how often this states was differentiated";
Option< .DAE.ComponentRef> derName "the name of the derivative";
Boolean natural "false if it was forced by StateSelect.always or StateSelect.prefer";
Boolean natural "false if it was forced by StateSelect.always or StateSelect.prefer or generated by index reduction";
end STATE;
record STATE_DER end STATE_DER;
record DUMMY_DER end DUMMY_DER;
Expand Down
6 changes: 3 additions & 3 deletions OMCompiler/Compiler/BackEnd/BackendDAECreate.mo
Expand Up @@ -1107,17 +1107,17 @@ algorithm
then BackendDAE.STATE(1, NONE(), false);

else
equation
algorithm
/* Consider toplevel inputs as known unless they are protected. Ticket #5591 */
false = DAEUtil.topLevelInput(inComponentRef, inVarDirection, inConnectorType, protection);
false := DAEUtil.topLevelInput(inComponentRef, inVarDirection, inConnectorType, protection);
then
match (inVarKind, inType)
case (DAE.VARIABLE(), DAE.T_BOOL()) then BackendDAE.DISCRETE();
case (DAE.VARIABLE(), DAE.T_INTEGER()) then BackendDAE.DISCRETE();
case (DAE.VARIABLE(), DAE.T_ENUMERATION()) then BackendDAE.DISCRETE();
case (DAE.VARIABLE(), _) then BackendDAE.VARIABLE();
case (DAE.DISCRETE(), _) then BackendDAE.DISCRETE();
end match;
end match;
end match;
end lowerVarkind;

Expand Down
30 changes: 29 additions & 1 deletion OMCompiler/Compiler/BackEnd/BackendVariable.mo
Expand Up @@ -459,7 +459,35 @@ algorithm
end match;
end varStateSelect;

public function varStateSelectNever "author: kabdelhak
public function varStateSelectAlways
"author: Frenkel TUD 2012-06
return true if var is StateSelect.always else false"
input BackendDAE.Var v;
output Boolean b;
algorithm
b := match(v)
case BackendDAE.VAR(varKind=BackendDAE.STATE(),values = SOME(DAE.VAR_ATTR_REAL(stateSelectOption = SOME(DAE.ALWAYS())))) then true;
else false;
end match;
end varStateSelectAlways;

public function notVarStateSelectAlways
"author: Frenkel TUD 2012-06
true if var is not StateSelect.always"
input BackendDAE.Var v;
input Integer level;
output Boolean b;
algorithm
b := match v
local Integer diffcount;
case BackendDAE.VAR(varKind=BackendDAE.STATE(index=diffcount))
then not(varStateSelectAlways(v) and (diffcount == level or diffcount == 1));
else true;
end match;
end notVarStateSelectAlways;

public function varStateSelectNever
"author: kabdelhak
Returns true, if the state select attribute is DAE.NEVER()"
input BackendDAE.Var inVar;
output Boolean isNever;
Expand Down
117 changes: 59 additions & 58 deletions OMCompiler/Compiler/BackEnd/IndexReduction.mo
Expand Up @@ -1366,22 +1366,22 @@ algorithm
case BackendDAE.VAR(varKind=BackendDAE.STATE(index=1))
equation
// do not count states with stateSelect.always
b = varStateSelectAlways(inVar);
b = BackendVariable.varStateSelectAlways(inVar);
statecount = if not b then inCount+1 else inCount;
then statecount;

case BackendDAE.VAR(varKind=BackendDAE.STATE(derName=SOME(_)))
equation
// do not count states with stateSelect.always, but ignore only higest state
b = varStateSelectAlways(inVar);
b = BackendVariable.varStateSelectAlways(inVar);
statecount = if b then inCount+1 else inCount;
then statecount;

case BackendDAE.VAR(varKind=BackendDAE.STATE(index=diffcount,derName=NONE()))
equation
statecount = diffcount + inCount;
// do not count states with stateSelect.always, but ignore only higest state
b = varStateSelectAlways(inVar);
b = BackendVariable.varStateSelectAlways(inVar);
statecount = if b then statecount-1 else statecount;
then statecount;

Expand All @@ -1404,22 +1404,22 @@ algorithm
case BackendDAE.VAR(varKind=BackendDAE.STATE(index=1))
equation
// do only count states with stateSelect.never
b = varStateSelectNever(inVar);
b = BackendVariable.varStateSelectNever(inVar);
statecount = if b then inCount+1 else inCount;
then statecount;

case BackendDAE.VAR(varKind=BackendDAE.STATE(derName=SOME(_)))
equation
// do only count states with stateSelect.never, but ignore only higest state
b = varStateSelectNever(inVar);
b = BackendVariable.varStateSelectNever(inVar);
statecount = if not b then inCount+1 else inCount;
then statecount;

case BackendDAE.VAR(varKind=BackendDAE.STATE(index=diffcount,derName=NONE()))
equation
statecount = diffcount + inCount;
// do only count states with stateSelect.never, but ignore only higest state
b = varStateSelectNever(inVar);
b = BackendVariable.varStateSelectNever(inVar);
statecount = if not b then statecount-1 else statecount;
then statecount;

Expand Down Expand Up @@ -1868,7 +1868,7 @@ algorithm
(eqnslst,_) = BackendEquation.traverseExpsOfEquationList(eqnslst, Expression.traverseSubexpressionsHelper, (replaceDummyDerivativesExp, ht));
(eqnslst1,_) = BackendEquation.traverseExpsOfEquationList(eqnslst1, Expression.traverseSubexpressionsHelper, (replaceDummyDerivativesExp, ht));
// remove stateSelect=StateSelect.always vars
varlst = list(var for var guard notVarStateSelectAlways(var, level) in hov);
varlst = list(var for var guard BackendVariable.notVarStateSelectAlways(var, level) in hov);
neqns = BackendEquation.equationLstSizeKeepAlgorithmAsOne(eqnslst); //vwaurich: algorithms are handled as single equations, like a function call
nfreeStates = listLength(varlst);
// do state selection of that level
Expand Down Expand Up @@ -2251,7 +2251,8 @@ algorithm

for state in states loop
var := BackendVariable.getVarAt(vars,Util.tuple22(state));
if varStateSelectNever(var) and not BaseHashTable.hasKey(BackendVariable.varCref(var), ht) then
if BackendVariable.varStateSelectNever(var) and not BaseHashTable.hasKey(BackendVariable.varCref(var), ht) then

neverVars := var::neverVars;
neverIdx := Util.tuple22(state)::neverIdx;
end if;
Expand All @@ -2261,10 +2262,6 @@ algorithm
if not listEmpty(neverVars) then
if Flags.isSet(Flags.BLT_DUMP) then
BackendDump.dumpVarList(neverVars, "StateSelect.never variables that will tried to be forced as dummys");
else
msg := System.gettext(BackendDump.varListStringShort(neverVars,"") +
"They were forced to be statically selected as dummys, this could lead to errors during simulation, please use -d=bltdump for more information.\n");
Error.addMessage(Error.STATE_STATESELECT_NEVER_FORCED, {msg});
end if;

// If there are unmatched equations try to match full system with casual rules for stateSelect.never vars
Expand All @@ -2273,15 +2270,20 @@ algorithm
m := incidenceMatrixfromEnhanced(me,vars,so);
mT := AdjacencyMatrix.transposeAdjacencyMatrix(m,nv);

(vec2,vec1,_) := Matching.ContinueMatching(mT,ne,nv,vec2,vec1);
BackendDAEEXT.setAssignment(ne,nv,vec2,vec1);
Matching.matchingExternalsetIncidenceMatrix(ne,nv,mT);
/* Call with clearMatching = 0 to reuse old information */
BackendDAEEXT.matching(ne,nv,3,-1,1.0,1);
BackendDAEEXT.getAssignment(vec1,vec2);
//(vec2,vec1,_) := Matching.ContinueMatching(mT,ne,nv,vec2,vec1);
(dummyStates,states) := checkAssignment(1,nv,vec1,vars);

// look for leftover unmatched stateSelect.never vars
neverVars := {};
neverIdx := {};
for state in states loop
var := BackendVariable.getVarAt(vars,Util.tuple22(state));
if varStateSelectNever(var) and not BaseHashTable.hasKey(BackendVariable.varCref(var), ht) then
if BackendVariable.varStateSelectNever(var) and not BaseHashTable.hasKey(BackendVariable.varCref(var), ht) then
neverVars := var::neverVars;
neverIdx := Util.tuple22(state)::neverIdx;
end if;
Expand All @@ -2301,14 +2303,15 @@ algorithm

if not AdjacencyMatrix.isEmpty(m) then
mT := AdjacencyMatrix.transposeAdjacencyMatrix(m,nv2);
Matching.matchingExternalsetIncidenceMatrix(ne,nv2,mT);
BackendDAEEXT.matching(ne,nv2,3,-1,1.0,1);
vec_res1 := arrayCreate(nv2,-1);
vec_res2 := arrayCreate(ne,-1);
BackendDAEEXT.setAssignment(ne,nv2,vec_res2,vec_res1);
Matching.matchingExternalsetIncidenceMatrix(ne,nv2,mT);
BackendDAEEXT.matching(ne,nv2,3,-1,1.0,1);
BackendDAEEXT.getAssignment(vec_res1,vec_res2);

// swap out new matchings
tplLst := List.zip(neverIdx,List.intRange(listLength(neverIdx)));
tplLst := List.zip(neverIdx,List.intRange(listLength(neverIdx)));
for tpl in tplLst loop
(never_i, eq_i) := tpl;
// assigning matched never var to matched eq
Expand All @@ -2321,6 +2324,25 @@ algorithm
end if;
end for;
end if;

// look for leftover unmatched natural stateSelect.never vars and report them
neverVars := {};
neverIdx := {};
for state in states loop
var := BackendVariable.getVarAt(vars,Util.tuple22(state));
if BackendVariable.varStateSelectNever(var)
and BackendVariable.isNaturalState(var)
and not BaseHashTable.hasKey(BackendVariable.varCref(var), ht) then
neverVars := var::neverVars;
neverIdx := Util.tuple22(state)::neverIdx;
end if;
end for;

if not listEmpty(neverVars) then
msg := System.gettext(BackendDump.varListStringShort(neverVars,"") +
"They could not be forced to be statically selected as dummys, this could lead to errors during simulation, please use -d=bltdump for more information.\n");
Error.addMessage(Error.STATE_STATESELECT_NEVER_FORCED, {msg});
end if;
end if;

if Flags.isSet(Flags.BLT_DUMP) then
Expand Down Expand Up @@ -3224,7 +3246,7 @@ protected function varStateSelectPrioAttribute
algorithm
ss := BackendVariable.varStateSelect(v);
prio := match ss
case DAE.NEVER() then -20.0;
case DAE.NEVER() then if BackendVariable.isArtificialState(v) then -25.0 else -20.0;
case DAE.AVOID() then -1.5;
case DAE.DEFAULT() then 0.0;
case DAE.PREFER() then 1.5;
Expand Down Expand Up @@ -3326,45 +3348,6 @@ algorithm
outExp := DAE.CALL(Absyn.IDENT("der"), {inExp}, DAE.CALL_ATTR(tp, false, true, false, false, DAE.NO_INLINE(),DAE.NO_TAIL()));
end makeder;

protected function notVarStateSelectAlways
"author: Frenkel TUD 2012-06
true if var is not StateSelect.always"
input BackendDAE.Var v;
input Integer level;
output Boolean b;
algorithm
b := match v
local Integer diffcount;
case BackendDAE.VAR(varKind=BackendDAE.STATE(index=diffcount))
then not(varStateSelectAlways(v) and (diffcount == level or diffcount == 1));
else true;
end match;
end notVarStateSelectAlways;

protected function varStateSelectAlways
"author: Frenkel TUD 2012-06
return true if var is StateSelect.always else false"
input BackendDAE.Var v;
output Boolean b;
algorithm
b := match(v)
case BackendDAE.VAR(varKind=BackendDAE.STATE(),values = SOME(DAE.VAR_ATTR_REAL(stateSelectOption = SOME(DAE.ALWAYS())))) then true;
else false;
end match;
end varStateSelectAlways;

protected function varStateSelectNever
"author: kabdelhak FHB 2019-07
return true if var is StateSelect.never else false"
input BackendDAE.Var v;
output Boolean b;
algorithm
b := match(v)
case BackendDAE.VAR(varKind=BackendDAE.STATE(),values = SOME(DAE.VAR_ATTR_REAL(stateSelectOption = SOME(DAE.NEVER())))) then true;
else false;
end match;
end varStateSelectNever;

protected function incidenceMatrixfromEnhancedStrict
"author: Frenkel TUD 2012-11
converts an AdjacencyMatrixEnhanced into a IncidenceMatrix"
Expand Down Expand Up @@ -3826,6 +3809,16 @@ algorithm
cr = ComponentReference.crefPrefixDer(name);
source = ElementSource.addSymbolicTransformation(source,DAE.NEW_DUMMY_DER(cr,{}));
then (BackendDAE.VAR(name,BackendDAE.DUMMY_STATE(),dir,prl,tp,bind,tplExp,dim,source,attr,ts,hideResult,comment,ct,io,false),(vars,so,varlst,ht));
// regular variable with StateSelect.Prefer
case (var as BackendDAE.VAR(name,BackendDAE.VARIABLE(),dir,prl,tp,bind,tplExp,dim,source,attr,ts,hideResult,comment,ct,io),(vars,so,varlst,ht))
guard(BackendVariable.varStateSelectNever(var))
equation
// add replacement for each derivative
(varlst,ht) = makeAllDummyVarandDummyDerivativeRepl1(1,1,name,name,var,vars,so,varlst,ht);
// dummy_der name vor Source information
cr = ComponentReference.crefPrefixDer(name);
source = ElementSource.addSymbolicTransformation(source,DAE.NEW_DUMMY_DER(cr,{}));
then (BackendDAE.VAR(name,BackendDAE.DUMMY_STATE(),dir,prl,tp,bind,tplExp,dim,source,attr,ts,hideResult,comment,ct,io,false),(vars,so,varlst,ht));
else (inVar,inTpl);
end matchcontinue;
end makeAllDummyVarandDummyDerivativeRepl;
Expand Down Expand Up @@ -4229,9 +4222,17 @@ algorithm
(vars,changedVars) = algebraicState(vlst,ilst,inVars,iChangedVars);
then
(vars,changedVars);
case((v as BackendDAE.VAR(values=SOME(DAE.VAR_ATTR_REAL(stateSelectOption = NONE()))))::vlst,index::ilst,_,_)
equation
v = BackendVariable.setVarKind(v, BackendDAE.STATE(1,NONE(),false));
v.values = DAEUtil.setStateSelect(v.values, DAE.NEVER());
vars = BackendVariable.addVar(v, inVars);
(vars,changedVars) = algebraicState(vlst,ilst,vars,index::iChangedVars);
then
(vars,changedVars);
case(v::vlst,index::ilst,_,_)
equation
v = BackendVariable.setVarKind(v, BackendDAE.STATE(1,NONE(),true));
v = BackendVariable.setVarKind(v, BackendDAE.STATE(1,NONE(),false));
vars = BackendVariable.addVar(v, inVars);
(vars,changedVars) = algebraicState(vlst,ilst,vars,index::iChangedVars);
then
Expand Down
2 changes: 1 addition & 1 deletion OMCompiler/Compiler/SimCode/SimCodeUtil.mo
Expand Up @@ -9251,7 +9251,7 @@ algorithm
source = source)), _, vars)
equation
_ = match BackendVariable.varStateSelect(dlowVar)
case DAE.NEVER()
case DAE.NEVER() guard(BackendVariable.isNaturalState(dlowVar))
algorithm
Error.addSourceMessage(Error.STATE_STATESELECT_NEVER, {ComponentReference.printComponentRefStr(cr)}, source.info);
then ();
Expand Down

0 comments on commit 387c3b2

Please sign in to comment.