Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
adrpo committed Sep 2, 2015
2 parents 865e87c + 9a17982 commit 77249d4
Show file tree
Hide file tree
Showing 6 changed files with 155 additions and 27 deletions.
102 changes: 87 additions & 15 deletions Compiler/BackEnd/EvaluateFunctions.mo
Expand Up @@ -1646,7 +1646,6 @@ algorithm
DAE.Type typ;
list<BackendDAE.Equation> addEqs;
list<DAE.ComponentRef> scalars, varScalars,constScalars, outputs, initOutputs;
list<list<DAE.Exp>> lhsExpLst;
list<DAE.Statement> stmts1, stmts2, stmtsIf, rest, addStmts, stmtsNew, allStmts, initStmts, tplStmts;
list<list<DAE.Statement>> stmtsLst;
list<DAE.Exp> expLst,tplExpsLHS,tplExpsRHS,lhsExps,lhsExpsInit,rhsExps;
Expand Down Expand Up @@ -1680,9 +1679,9 @@ algorithm
repl = BackendVarTransform.removeReplacements(repl,outputs,NONE());

// check if its constant, a record or a tuple
isCon = Expression.isConst(exp2);
isCon = Expression.isConst(exp2) and not Expression.isCall(exp2);
eqDim = listLength(scalars) == listLength(expLst); // so it can be partly constant
isRec = ComponentReference.isRecord(cref) or Expression.isCall(exp2);
isRec = ComponentReference.isRecord(cref) or Expression.isRecordCall(exp2,funcTree);
isTpl = Expression.isTuple(exp1) and Expression.isTuple(exp2);
//print("is it const? "+boolString(isCon)+" ,is it rec: "+boolString(isRec)+" ,is it tpl: "+boolString(isTpl)+"\n");

Expand Down Expand Up @@ -1745,7 +1744,7 @@ algorithm
repl = BackendVarTransform.removeReplacements(repl,outputs,NONE());

// check if its constant, a record or a tuple
isCon = Expression.isConst(exp2);
isCon = Expression.isConst(exp2) and not Expression.isCall(exp2);
eqDim = listLength(scalars) == listLength(expLst); // so it can be partly constant
isRec = ComponentReference.isRecord(cref);
isArr = ComponentReference.isArrayElement(cref);
Expand Down Expand Up @@ -1780,7 +1779,7 @@ algorithm
tplStmts = List.map2(List.intRange(listLength(tplExpsLHS)),makeAssignmentMap,tplExpsLHS,tplExpsRHS);
stmts1 = if isTpl then tplStmts else {alg};
if Flags.isSet(Flags.EVAL_FUNC_DUMP) then
print("evaluated assignment to:\n"+stringDelimitList(List.map(stmts1,DAEDump.ppStatementStr),"\n")+"\n");
print("evaluated array assignment to:\n"+stringDelimitList(List.map(stmts1,DAEDump.ppStatementStr),"\n")+"\n");
end if;

//stmts1 = listAppend({alg},lstIn);
Expand Down Expand Up @@ -1913,21 +1912,14 @@ algorithm
if Flags.isSet(Flags.EVAL_FUNC_DUMP) then
print("For-statement:\n"+DAEDump.ppStatementStr(alg));
end if;
// at least remove the replacements for the lhs so we dont declare something as constant which isnt
lhsExps = List.fold(stmts1,getStatementLHS,{});
lhsExps = List.unique(lhsExps);
lhsExpLst = List.map(lhsExps,Expression.getComplexContents); //consider arrays etc.
lhsExps = listAppend(List.flatten(lhsExpLst),lhsExps);
lhsExps = List.filterOnTrue(lhsExps,Expression.isCref); //remove e.g. ASUBs and consider only the scalar subs
outputs = List.map(lhsExps,Expression.expCref);
repl = if true then BackendVarTransform.removeReplacements(replIn,outputs,NONE()) else replIn;

// lets see if we can evaluate it
(stmts1,funcTree,repl,idx) = evaluateForStatement(listHead(algsIn), funcTree,replIn,idx);

if Flags.isSet(Flags.EVAL_FUNC_DUMP) then
print("evaluated For-statement to:\n"+DAEDump.ppStatementStr(alg));
print("evaluated for-statements to:\n"+stringDelimitList(List.map(stmts1,DAEDump.ppStatementStr),"\n")+"\n");
end if;
stmts2 = alg::lstIn;
stmts2 = listAppend(listReverse(stmts1),lstIn);
(rest,(funcTree,repl,idx)) = evaluateFunctions_updateStatement(rest,(funcTree,repl,idx),stmts2);
then (rest,(funcTree,repl,idx));

Expand Down Expand Up @@ -2017,6 +2009,86 @@ algorithm
end matchcontinue;
end evaluateFunctions_updateStatement;

protected function evaluateForStatement"evaluates a for statement. neste for loops wont work"
input DAE.Statement stmtIn;
input DAE.FunctionTree funcTreeIn;
input BackendVarTransform.VariableReplacements replIn;
input Integer idxIn;
output list<DAE.Statement> stmtsOut;
output DAE.FunctionTree funcTreeOut;
output BackendVarTransform.VariableReplacements replOut;
output Integer idxOut;
protected
Boolean hasNoRepl;
Integer i, start, stop ,step;
DAE.Ident iter;
DAE.Exp range;
BackendVarTransform.VariableReplacements repl;
list<DAE.ComponentRef> outputs;
list<DAE.Exp> lhsExps;
list<list<DAE.Exp>> lhsExpLst;
list<DAE.Statement> stmts,stmtsIn;
algorithm
DAE.STMT_FOR(iter=iter, range=range, statementLst=stmtsIn) := stmtIn;
try
(range,_) := BackendVarTransform.replaceExp(range,replIn,NONE());
(start,stop,step) := getRangeBounds(range);
true := intEq(step,1);
repl := replIn;
for i in List.intRange2(start,stop) loop
repl := BackendVarTransform.addReplacement(repl, ComponentReference.makeCrefIdent(iter,DAE.T_INTEGER_DEFAULT,{}),DAE.ICONST(i),NONE());
(stmts,((_,repl,_))) := evaluateFunctions_updateStatement(stmtsIn,(funcTreeIn,repl,i),{});

// check if any variable has been evaluated. If not, skip the loop (this is necessary for testsuite/modelica/linear_systems/problem1.mos)
lhsExps := List.fold1(stmts,getStatementLHSScalar,funcTreeIn,{});
lhsExps := List.unique(lhsExps);
outputs := List.map(lhsExps,Expression.expCref);
hasNoRepl := List.fold(List.map1(outputs,BackendVarTransform.hasNoReplacementCrefFirst,repl),boolAnd,true);
if hasNoRepl then
if Flags.isSet(Flags.EVAL_FUNC_DUMP) then print("For-loop evaluation is skipped, since the first loop evaluated nothing.\n"); end if;
fail();
end if;
end for;
replOut := BackendVarTransform.removeReplacement(repl,ComponentReference.makeCrefIdent(iter,DAE.T_INTEGER_DEFAULT,{}),NONE());
funcTreeOut := funcTreeIn;
idxOut := idxIn;
stmtsOut := stmts;
else
// at least remove the replacements for the lhs so we dont declare something as constant which isnt
lhsExps := List.fold(stmtsIn,getStatementLHS,{});
lhsExps := List.unique(lhsExps);
lhsExpLst := List.map(lhsExps,Expression.getComplexContents); //consider arrays etc.
lhsExps := listAppend(List.flatten(lhsExpLst),lhsExps);
lhsExps := List.filterOnTrue(lhsExps,Expression.isCref); //remove e.g. ASUBs and consider only the scalar subs
outputs := List.map(lhsExps,Expression.expCref);
replOut := if true then BackendVarTransform.removeReplacements(replIn,outputs,NONE()) else replIn;
stmtsOut := {stmtIn};
funcTreeOut := funcTreeIn;
idxOut := idxIn;
end try;
end evaluateForStatement;

protected function getRangeBounds
input DAE.Exp range;
output Integer start;
output Integer stop;
output Integer step;
algorithm
(start, stop, step) := matchcontinue(range)
local
Integer i1,i2,i3;
case(DAE.RANGE(start= DAE.ICONST(i1),step=NONE(),stop=DAE.ICONST(i2)))
then (i1,i2,1);
case(DAE.RANGE(start= DAE.ICONST(i1),step=SOME(DAE.ICONST(i3)),stop=DAE.ICONST(i2)))
then (i1,i2,i3);
else
equation
//print("getRangeBounds failed!"+ExpressionDump.printExpStr(range)+"\n");
then fail();
end matchcontinue;
end getRangeBounds;


protected function evaluateIfStatement "check if the cases are constant and if so evaluate them.
author: Waurich TUD 2014-04"
input DAE.Statement stmtIn;
Expand Down
3 changes: 3 additions & 0 deletions Compiler/BackEnd/EvaluateParameter.mo
Expand Up @@ -994,6 +994,7 @@ algorithm
// apply replacements
(e,true) = BackendVarTransform.replaceExp(e, iReplEvaluate, NONE());
(e,_) = ExpressionSimplify.simplify(e);
e = EvaluateFunctions.evaluateConstantFunctionCallExp(e,FCore.getFunctionTree(iCache));
v = BackendVariable.setBindExp(var, SOME(e));
(repl,repleval) = addConstExpReplacement(e,cr,iRepl,iReplEvaluate);
(attr,(repleval,_)) = BackendDAEUtil.traverseBackendDAEVarAttr(attr,traverseExpVisitorWrapper,(repleval,false));
Expand All @@ -1015,6 +1016,7 @@ algorithm
// apply replacements
(e,true) = BackendVarTransform.replaceExp(e, iReplEvaluate, NONE());
(e,_) = ExpressionSimplify.simplify(e);
e = EvaluateFunctions.evaluateConstantFunctionCallExp(e,FCore.getFunctionTree(iCache));
v = BackendVariable.setVarStartValue(var,e);
(repl,repleval) = addConstExpReplacement(e,cr,iRepl,iReplEvaluate);
(attr,(repleval,_)) = BackendDAEUtil.traverseBackendDAEVarAttr(attr,traverseExpVisitorWrapper,(repleval,false));
Expand All @@ -1035,6 +1037,7 @@ algorithm
// apply replacements
(e,true) = BackendVarTransform.replaceExp(e, iReplEvaluate, NONE());
(e,_) = ExpressionSimplify.simplify(e);
e = EvaluateFunctions.evaluateConstantFunctionCallExp(e,FCore.getFunctionTree(iCache));
v = BackendVariable.setBindExp(var, SOME(e));
(attr,(repleval,_)) = BackendDAEUtil.traverseBackendDAEVarAttr(attr,traverseExpVisitorWrapper,(iReplEvaluate,false));
v = BackendVariable.setVarAttributes(v,attr);
Expand Down
46 changes: 40 additions & 6 deletions Compiler/BackEnd/HpcOmEqSystems.mo
Expand Up @@ -90,7 +90,7 @@ Remark: this is still under development

idea:
we have the algebraic equations (other equations): g(xa,xt) : 0 = Ag*xt + Bg*xa + cg;
and the residual equations h(xa,xt,r) : r = Ah*xt + Bh*xt + ch;
and the residual equations h(xa,xt,r) : r = Ah*xt + Bh*xa + ch;
and we want something like this:
new algebraic equations gs(xa,xt) : xa = B_*xt + dg;
new residual equations hs(xt,r) : r = A_*xt +dh;
Expand Down Expand Up @@ -244,7 +244,7 @@ algorithm
comp = listGet(compsIn,compIdx);
BackendDAE.EQUATIONSYSTEM(vars = varIdcs, eqns = eqIdcs) = comp;
true = intLe(listLength(varIdcs),3);
false = compHasDummyState(comp,systIn);
//false = compHasDummyState(comp,systIn);

//print("EQUATION SYSTEM OF SIZE "+intString(listLength(varIdcs))+"\n");
//print("Jac:\n" + BackendDump.jacobianString(jac) + "\n");
Expand Down Expand Up @@ -296,7 +296,7 @@ algorithm
ass2All = Array.copy(ass2,ass2All);
List.map2_0(compsNew,updateAssignmentsByComp,ass1All,ass2All);
syst.matching = BackendDAE.MATCHING(ass1All, ass2All, compsTmp);
//BackendDump.dumpFullMatching(matching);
//BackendDump.dumpFullMatching(syst.matching);

//build new DAE-EqSystem
syst = BackendDAEUtil.setEqSystMatrices(syst);
Expand Down Expand Up @@ -1053,6 +1053,9 @@ algorithm
BackendDAEEXT.getAssignment(ass2, ass1);
matching = BackendDAE.MATCHING(ass1, ass2, {});
sysTmp = BackendDAEUtil.createEqSystem(vars, eqArr);
(sysTmp,_,_) = BackendDAEUtil.getIncidenceMatrix(sysTmp,BackendDAE.ABSOLUTE(),NONE());
sysTmp = BackendDAEUtil.setEqSystMatching(sysTmp, matching);

// perform BLT to order the StrongComponents
mapIncRowEqn = listArray(List.intRange(nEqs));
mapEqnIncRow = Array.map(mapIncRowEqn,List.create);
Expand Down Expand Up @@ -1546,15 +1549,46 @@ algorithm
(allTerms,coeffsIn) := foldIn;
(coeffs,allTerms) := List.extract1OnTrue(allTerms,Expression.expHasCref,cref);
coeff := List.fold(coeffs,Expression.expAdd,DAE.RCONST(0));
if Expression.containFunctioncall(coeff) then
//print("This system of equations cannot be decomposed because its actually not linear (the coeffs are function calls of x).\n");
fail();
if containsFunctioncallOfCref(coeff,cref) then
print("This system of equations cannot be decomposed because its actually not linear (the coeffs are function calls of x).\n");
fail();
end if;
(coeff,_) := Expression.replaceExp(coeff,Expression.crefExp(cref),DAE.RCONST(1.0));
(coeff,_) := ExpressionSimplify.simplify(coeff);
foldOut := (allTerms,coeff::coeffsIn);
end getEqSystem3;

protected function containsFunctioncallOfCref"outputs true if the expIn contains a function call which has cref as input"
input DAE.Exp expIn;
input DAE.ComponentRef cref;
output Boolean hasCrefInCall;
protected
list<DAE.Exp> expLst;
algorithm
if Expression.containFunctioncall(expIn) then
(_,expLst) := Expression.traverseExpBottomUp(expIn,getCallExpLst,{});
hasCrefInCall := List.fold(List.map1(expLst,Expression.expHasCref,cref),boolOr,false);
else
hasCrefInCall := false;
end if;
end containsFunctioncallOfCref;

public function getCallExpLst "returns the list of expressions from a call.
author:Waurich TUD 2015-08"
input DAE.Exp eIn;
input list<DAE.Exp> eLstIn;
output DAE.Exp eOut;
output list<DAE.Exp> eLstOut;
algorithm
(eOut,eLstOut) := matchcontinue(eIn,eLstIn)
local
list<DAE.Exp> expLst;
case(DAE.CALL(expLst=expLst),_)
then (eIn,listAppend(expLst,eLstIn));
else
then (eIn,eLstIn);
end matchcontinue;
end getCallExpLst;

protected function getSummands"gets all sum-terms in the equation"
input BackendDAE.Equation eq;
Expand Down
19 changes: 19 additions & 0 deletions Compiler/FrontEnd/Expression.mo
Expand Up @@ -8346,6 +8346,25 @@ algorithm
end match;
end isCall;

public function isRecordCall
"Returns true if the given expression is a record call,i.e. a function call without elements
otherwise false."
input DAE.Exp inExp;
input DAE.FunctionTree funcsIn;
output Boolean outIsCall;
algorithm
outIsCall := match(inExp,funcsIn)
local
Absyn.Path path;
DAE.Function func;
case (DAE.CALL(path=path),_)
equation
SOME(func) = DAEUtil.avlTreeGet(funcsIn,path);
then listEmpty(DAEUtil.getFunctionElements(func));
else false;
end match;
end isRecordCall;

public function isNotCref
"Returns true if the given expression is a not component reference,
otherwise false."
Expand Down
6 changes: 3 additions & 3 deletions Compiler/Template/CodegenCpp.tpl
Expand Up @@ -12395,9 +12395,9 @@ template initialAnalyticJacobians(Integer indexJacobian, list<JacobianColumn> ja
let type = getConfigString(MATRIX_FORMAT)
let matrixinit = match type
case ("dense") then
'ublas::zero_matrix<double> (<%index_%>,<%indexColumn%>)'
'ublas::zero_matrix<double> (<%indexColumn%>,<%index_%>)'
case ("sparse") then
'<%index_%>,<%indexColumn%>,<%sp_size_index%>'
'<%indexColumn%>,<%index_%>,<%sp_size_index%>'
else "A matrix type is not supported"
end match
<<
Expand Down Expand Up @@ -12561,7 +12561,7 @@ case _ then
;separator="\n")
let jacvals = ( sparsepattern |> (index,indexes) hasindex index0 =>
let jaccol = ( indexes |> i_index hasindex index1 =>
(match indexColumn case "1" then '_<%matrixName%>jacobian(<%index%>,0) = _<%matrixName%>jac_y(0);/*test1<%index0%>,<%index1%>*/'
(match indexColumn case "1" then '_<%matrixName%>jacobian(0,<%index%>) = _<%matrixName%>jac_y(0);/*test1<%index0%>,<%index1%>*/'
else '_<%matrixName%>jacobian(<%i_index%>,<%index%>) = _<%matrixName%>jac_y(<%i_index%>);/*test2<%index0%>,<%index1%>*/'
)
;separator="\n" )
Expand Down
Expand Up @@ -188,7 +188,7 @@ void SystemDefaultImplementation::initialize()
_conditions0= new bool[_dimZeroFunc];

memset(_conditions,false,(_dimZeroFunc)*sizeof(bool));

_event_system = dynamic_cast<IEvent*>(this);
}
if(_dimTimeEvent > 0)
{
Expand All @@ -205,7 +205,7 @@ void SystemDefaultImplementation::initialize()
_start_time = 0.0;
_terminal = false;
_terminate = false;
_event_system = dynamic_cast<IEvent*>(this);


};

Expand Down Expand Up @@ -282,7 +282,7 @@ boost::shared_ptr<ISimData> SystemDefaultImplementation::getSimData()

bool SystemDefaultImplementation::isConsistent()
{
if(_event_system)
if(_dimZeroFunc > 0)
{
getConditions(_conditions0);
IContinuous::UPDATETYPE pre_call_type=_callType;
Expand Down

0 comments on commit 77249d4

Please sign in to comment.