Skip to content

Commit

Permalink
Separation of back end transformations...
Browse files Browse the repository at this point in the history
... for simulation and initialization

* Move initialization before post-optimization phase
* Revert some CodegenC.tpl changes
* Remove workaround for "symEuler"
* Moved 'encapsulateWhenConditions' to pre-optimization phase
* Cleanup known variables after 'remove simple equations'
* Activate more modules for initialization
  - activate modules "simplifyComplexFunction" and "simplifyLoops"
  - Fixed module "simplifyLoops" for initialization
* Moved each post-opt module to a new line
* Moved module "simplifyLoops" from simulation to initialization
* Don't add known vars to simulation system in post-optimization
* Updated debug dumps
* Fixed "Known Variables" again
* Initialize relations properly
* New opt module "removeInitializationStuff"
  - This module does simplifications by removing initialization
    information like homotopy(..) and initial() from simulation DAE.
* Fixed Stubs files
  • Loading branch information
lochel committed Sep 11, 2015
1 parent 523217e commit 56d186b
Show file tree
Hide file tree
Showing 17 changed files with 310 additions and 117 deletions.
2 changes: 0 additions & 2 deletions Compiler/BackEnd/BackendDAE.mo
Expand Up @@ -33,8 +33,6 @@ encapsulated package BackendDAE
" file: BackendDAE.mo
package: BackendDAE
description: BackendDAE contains the data-types used by the back end.

RCS: $Id$
"

public import Absyn;
Expand Down
14 changes: 2 additions & 12 deletions Compiler/BackEnd/BackendDAEOptimize.mo
Expand Up @@ -4340,7 +4340,8 @@ algorithm
functionTree := shared.functionTree;

simDAE := match shared
case BackendDAE.SHARED(backendDAEType = BackendDAE.SIMULATION()) then true;
case BackendDAE.SHARED(backendDAEType=BackendDAE.SIMULATION()) then true;
case BackendDAE.SHARED(backendDAEType=BackendDAE.INITIALSYSTEM()) then true;
else false;
end match;

Expand Down Expand Up @@ -4818,17 +4819,6 @@ public function symEuler
algorithm
outDAE := if Flags.getConfigBool(Flags.SYM_EULER) then symEulerWork(inDAE, true) else inDAE;
end symEuler;
public function symEulerInit
"
fix the difference quotient for initial equations[0/0]
ToDo: remove me
"
input BackendDAE.BackendDAE inDAE;
output BackendDAE.BackendDAE outDAE;
algorithm
outDAE := if Flags.getConfigBool(Flags.SYM_EULER) then symEulerWork(BackendDAEUtil.copyBackendDAE(inDAE), false) else inDAE;

end symEulerInit;

protected function symEulerWork
input BackendDAE.BackendDAE inDAE;
Expand Down
68 changes: 34 additions & 34 deletions Compiler/BackEnd/BackendDAEUtil.mo
Expand Up @@ -34,8 +34,6 @@ encapsulated package BackendDAEUtil
package: BackendDAEUtil
description: BackendDAEUtil comprised functions for BackendDAE data types.

RCS: $Id$

This module is a lowered form of a DAE including equations
and simple equations in
two separate lists. The variables are split into known variables
Expand All @@ -62,8 +60,8 @@ protected import BackendDump;
protected import BackendEquation;
protected import BackendDAEEXT;
protected import BackendInline;
protected import BackendVariable;
protected import BackendVarTransform;
protected import BackendVariable;
protected import BinaryTree;
protected import Causalize;
protected import Ceval;
Expand Down Expand Up @@ -93,10 +91,12 @@ protected import HpcOmEqSystems;
protected import HpcOmTaskGraph;
protected import HpcOmSimCodeMain;
protected import IndexReduction;
protected import Initialization;
protected import Inline;
protected import InlineArrayEquations;
protected import List;
protected import Matching;
protected import MetaModelica.Dangerous.listReverseInPlace;
protected import OnRelaxation;
protected import RemoveSimpleEquations;
protected import ResolveLoops;
Expand All @@ -112,7 +112,6 @@ protected import Types;
protected import UnitCheck;
protected import Values;
protected import XMLDump;
protected import MetaModelica.Dangerous.listReverseInPlace;

protected
type Var = BackendDAE.Var;
Expand Down Expand Up @@ -6494,6 +6493,11 @@ public function getSolvedSystem "Run the equation system pipeline."
input Option<String> strdaeHandler = NONE();
input Option<list<String>> strPostOptModules = NONE();
output BackendDAE.BackendDAE outSODE;
output BackendDAE.BackendDAE outInitDAE;
output Boolean outUseHomotopy "true if homotopy(...) is used during initialization";
output list<BackendDAE.Equation> outRemovedInitialEquationLst;
output list<BackendDAE.Var> outPrimaryParameters "already sorted";
output list<BackendDAE.Var> outAllPrimaryParameters "already sorted";
protected
BackendDAE.BackendDAE optdae, sode, sode1, optsode;
list<tuple<BackendDAEFunc.preOptimizationDAEModule, String, Boolean>> preOptModules;
Expand Down Expand Up @@ -6533,6 +6537,9 @@ algorithm
sode := BackendDAEOptimize.evaluateOutputsOnly(sode);
end if;

// generate system for initialization
(outInitDAE, outUseHomotopy, outRemovedInitialEquationLst, outPrimaryParameters, outAllPrimaryParameters) := Initialization.solveInitialSystem(sode);

// post-optimization phase
optsode := postOptimizeDAE(sode, postOptModules, matchingAlgorithm, daeHandler);

Expand Down Expand Up @@ -7192,7 +7199,8 @@ algorithm
(CommonSubExpression.commonSubExpressionReplacement, "comSubExp", false),
(CommonSubExpression.CSE_EachCall, "CSE_EachCall", false),
(BackendDump.dumpDAE, "dumpDAE", false),
(XMLDump.dumpDAEXML, "dumpDAEXML", false)
(XMLDump.dumpDAEXML, "dumpDAEXML", false),
(FindZeroCrossings.encapsulateWhenConditions, "encapsulateWhenConditions", true)
};
strPreOptModules := getPreOptModulesString();
strPreOptModules := Util.getOptionOrDefault(ostrPreOptModules,strPreOptModules);
Expand All @@ -7210,10 +7218,10 @@ public function getPostOptModules
input Option<list<String>> ostrpostOptModules;
output list<tuple<BackendDAEFunc.postOptimizationDAEModule,String,Boolean>> postOptModules;
protected
list<tuple<BackendDAEFunc.postOptimizationDAEModule,String,Boolean>> allpostOptModules;
list<tuple<BackendDAEFunc.postOptimizationDAEModule,String,Boolean/*stopOnFailure*/>> allpostOptModules;
list<String> strpostOptModules;
algorithm
allpostOptModules := {(FindZeroCrossings.encapsulateWhenConditions, "encapsulateWhenConditions", true),
allpostOptModules := {(Initialization.removeInitializationStuff, "removeInitializationStuff", true),
(BackendInline.lateInlineFunction, "lateInlineFunction", false),
(RemoveSimpleEquations.removeSimpleEquations, "removeSimpleEquations", false),
(BackendDAEOptimize.removeEqualFunctionCalls, "removeEqualFunctionCalls", false),
Expand All @@ -7228,7 +7236,6 @@ algorithm
(BackendDAEOptimize.removeUnusedParameter, "removeUnusedParameter", false),
(BackendDAEOptimize.removeUnusedVariables, "removeUnusedVariables", false),
(BackendDAEOptimize.symEuler, "symEuler", false),
(BackendDAEOptimize.symEulerInit, "symEulerInit", false),
(SymbolicJacobian.constantLinearSystem, "constantLinearSystem", false),
(OnRelaxation.relaxSystem, "relaxSystem", false),
(BackendDAEOptimize.countOperations, "countOperations", false),
Expand Down Expand Up @@ -7654,34 +7661,33 @@ protected function getConditionList1 "author: lochel"
output list<DAE.ComponentRef> outConditionVarList;
output Boolean outInitialCall;
algorithm
(outConditionVarList, outInitialCall) := matchcontinue (inConditionList, inConditionVarList, inInitialCall)
(outConditionVarList, outInitialCall) := match inConditionList
local
list<DAE.Exp> conditionList;
list<DAE.ComponentRef> conditionVarList;
Boolean initialCall;
DAE.ComponentRef componentRef;
DAE.Exp exp;
String msg;

case ({}, _, _)
then (inConditionVarList, inInitialCall);
case {}
then (inConditionVarList, inInitialCall);

case (DAE.CALL(path = Absyn.IDENT(name = "initial"))::conditionList, _, _)
equation
(conditionVarList, initialCall) = getConditionList1(conditionList, inConditionVarList, true);
then (conditionVarList, initialCall);
case DAE.BCONST(false)::conditionList equation
(conditionVarList, initialCall) = getConditionList1(conditionList, inConditionVarList, inInitialCall);
then (conditionVarList, initialCall);

case (DAE.CREF(componentRef=componentRef)::conditionList, _, _)
equation
(conditionVarList, initialCall) = getConditionList1(conditionList, componentRef::inConditionVarList, inInitialCall);
then (conditionVarList, initialCall);
case DAE.CALL(path=Absyn.IDENT(name="initial"))::conditionList equation
(conditionVarList, initialCall) = getConditionList1(conditionList, inConditionVarList, true);
then (conditionVarList, initialCall);

case (exp::_, _ ,_)
equation
msg = "./Compiler/BackEnd/BackendDAEUtil.mo: function getConditionList1 failed for " + ExpressionDump.printExpStr(exp) + "\n";
Error.addMessage(Error.INTERNAL_ERROR, {msg});
then fail();
end matchcontinue;
case DAE.CREF(componentRef=componentRef)::conditionList equation
(conditionVarList, initialCall) = getConditionList1(conditionList, componentRef::inConditionVarList, inInitialCall);
then (conditionVarList, initialCall);

case exp::_ equation
Error.addInternalError("function getConditionList1 failed for " + ExpressionDump.printExpStr(exp), sourceInfo());
then fail();
end match;
end getConditionList1;

public function isArrayComp"outputs true if the strongComponent is an arrayEquation"
Expand Down Expand Up @@ -8093,15 +8099,9 @@ end setSharedEventInfo;
public function setSharedKnVars
input BackendDAE.Shared inShared;
input BackendDAE.Variables knownVars;
output BackendDAE.Shared outShared;
output BackendDAE.Shared outShared = inShared;
algorithm
outShared := match inShared
local
BackendDAE.Shared shared;
case shared as BackendDAE.SHARED()
algorithm shared.knownVars := knownVars;
then shared;
end match;
outShared.knownVars := knownVars;
end setSharedKnVars;

public function setSharedAliasVars
Expand Down
1 change: 1 addition & 0 deletions Compiler/BackEnd/BackendEquation.mo
Expand Up @@ -2479,6 +2479,7 @@ algorithm
b := listEmpty(inputsKnVars);
end if;

b := false "hack";
if b then
if noPara then
oExp := ExpressionSimplify.simplify(iExp);
Expand Down
16 changes: 16 additions & 0 deletions Compiler/BackEnd/BackendVariable.mo
Expand Up @@ -2449,6 +2449,22 @@ algorithm
end try;
end existsVar;

public function existsAnyVar
"author: PA
Return true if a variable exists in the vector"
input list<DAE.ComponentRef> inComponentRefs;
input BackendDAE.Variables inVariables;
input Boolean skipDiscrete = false;
output Boolean outExists = false;
algorithm
for cref in inComponentRefs loop
if existsVar(cref, inVariables, skipDiscrete) and not isState(cref, inVariables) then
outExists := true;
break;
end if;
end for;
end existsAnyVar;

public function makeVar
input DAE.ComponentRef cr;
output BackendDAE.Var v = BackendDAE.VAR(cr, BackendDAE.VARIABLE(), DAE.BIDIR(), DAE.NON_PARALLEL(), DAE.T_REAL_DEFAULT, NONE(), NONE(), {}, DAE.emptyElementSource, NONE(), NONE(), NONE(), DAE.NON_CONNECTOR(), DAE.NOT_INNER_OUTER(), false);
Expand Down
82 changes: 73 additions & 9 deletions Compiler/BackEnd/Initialization.mo
Expand Up @@ -34,8 +34,7 @@ encapsulated package Initialization
package: Initialization
description: Initialization.mo contains everything needed to set up the
BackendDAE for the initial system.

RCS: $Id$"
"

public import Absyn;
public import BackendDAE;
Expand Down Expand Up @@ -99,15 +98,20 @@ protected
tuple<BackendDAEFunc.matchingAlgorithmFunc, String> matchingAlgorithm;
algorithm
try
// TODO: remove this once the initialization is moved before post-optimization
dae := BackendDAEOptimize.symEulerInit(inDAE);
//if Flags.isSet(Flags.DUMP_INITIAL_SYSTEM) then
// BackendDump.dumpBackendDAE(inDAE, "inDAE for initialization");
//end if;

// inline all when equations, if active with body else with lhs=pre(lhs)
dae := inlineWhenForInitialization(dae);
// fcall2(Flags.DUMP_INITIAL_SYSTEM, BackendDump.dumpBackendDAE, dae, "inlineWhenForInitialization");
dae := inlineWhenForInitialization(inDAE);
//if Flags.isSet(Flags.DUMP_INITIAL_SYSTEM) then
// BackendDump.dumpBackendDAE(dae, "inlineWhenForInitialization");
//end if;

(initVars, outPrimaryParameters, outAllPrimaryParameters) := selectInitializationVariablesDAE(dae);
// fcall2(Flags.DUMP_INITIAL_SYSTEM, BackendDump.dumpVariables, initVars, "selected initialization variables");
//if Flags.isSet(Flags.DUMP_INITIAL_SYSTEM) then
// BackendDump.dumpVariables(initVars, "selected initialization variables");
//end if;
hs := collectPreVariables(dae);

// collect vars and eqns for initial system
Expand All @@ -120,7 +124,9 @@ algorithm
((vars, fixvars, eqns, _)) := BackendVariable.traverseBackendDAEVars(dae.shared.knownVars, collectInitialVars, (vars, fixvars, eqns, hs));
((eqns, reeqns)) := BackendEquation.traverseEquationArray(dae.shared.initialEqs, collectInitialEqns, (eqns, reeqns));

// fcall2(Flags.DUMP_INITIAL_SYSTEM, BackendDump.dumpEquationArray, eqns, "initial equations");
//if Flags.isSet(Flags.DUMP_INITIAL_SYSTEM) then
// BackendDump.dumpEquationArray(eqns, "initial equations");
//end if;

((vars, fixvars, eqns, reeqns, _)) := List.fold(dae.eqs, collectInitialVarsEqnsSystem, ((vars, fixvars, eqns, reeqns, hs)));

Expand Down Expand Up @@ -172,7 +178,19 @@ algorithm
initdae := BackendDAEUtil.mapEqSystem(initdae, solveInitialSystemEqSystem);

// transform and optimize DAE
pastOptModules := BackendDAEUtil.getPostOptModules(SOME({"constantLinearSystem", "tearingSystem", "calculateStrongComponentJacobians", "solveSimpleEquations"}));
pastOptModules := BackendDAEUtil.getPostOptModules(SOME({
"constantLinearSystem",
"simplifyComplexFunction",
//"reduceDynamicOptimization", // before tearing
"tearingSystem",
"simplifyLoops",
"recursiveTearing",
"calculateStrongComponentJacobians",
"solveSimpleEquations"
//"inputDerivativesUsed",
//"extendDynamicOptimization"
}));

matchingAlgorithm := BackendDAEUtil.getMatchingAlgorithm(NONE());
daeHandler := BackendDAEUtil.getIndexReductionMethod(NONE());

Expand Down Expand Up @@ -2310,5 +2328,51 @@ algorithm
end match;
end collectInitialBindings;


// =============================================================================
// section for post-optimization module "removeInitializationStuff"
//
// =============================================================================

public function removeInitializationStuff
input BackendDAE.BackendDAE inDAE;
output BackendDAE.BackendDAE outDAE = inDAE;
algorithm
for eqs in outDAE.eqs loop
_ := BackendDAEUtil.traverseBackendDAEExpsEqnsWithUpdate(eqs.orderedEqs, removeInitializationStuff1, false);
end for;
end removeInitializationStuff;

protected function removeInitializationStuff1
input DAE.Exp inExp;
input Boolean inUseHomotopy;
output DAE.Exp outExp;
output Boolean outUseHomotopy;
algorithm
(outExp, outUseHomotopy) := Expression.traverseExpBottomUp(inExp, removeInitializationStuff2, inUseHomotopy);
end removeInitializationStuff1;

protected function removeInitializationStuff2
input DAE.Exp inExp;
input Boolean inUseHomotopy;
output DAE.Exp outExp;
output Boolean outUseHomotopy;
algorithm
(outExp, outUseHomotopy) := match (inExp, inUseHomotopy)
local
DAE.Exp e1, e2, e3, actual, simplified;

// replace initial() with false
case (DAE.CALL(path=Absyn.IDENT(name="initial")), _)
then (DAE.BCONST(false), inUseHomotopy);

// replace homotopy(actual, simplified) with actual
case (DAE.CALL(path=Absyn.IDENT(name="homotopy"), expLst=actual::simplified::_), _)
then (actual, true);

else (inExp, inUseHomotopy);
end match;
end removeInitializationStuff2;

annotation(__OpenModelica_Interface="backend");
end Initialization;
10 changes: 8 additions & 2 deletions Compiler/BackEnd/OpenTURNS.mo
Expand Up @@ -88,6 +88,11 @@ public function generateOpenTURNSInterface "generates the dll and the python scr
list<String> libs;
BackendDAE.BackendDAE dae,strippedDae;
SimCode.SimulationSettings simSettings;
BackendDAE.BackendDAE initDAE;
Boolean useHomotopy "true if homotopy(...) is used during initialization";
list<BackendDAE.Equation> removedInitialEquationLst;
list<BackendDAE.Var> primaryParameters "already sorted";
list<BackendDAE.Var> allPrimaryParameters "already sorted";
algorithm
cname_str := Absyn.pathString(inPath);
cname_last_str := Absyn.pathLastIdent(inPath);
Expand All @@ -108,12 +113,13 @@ algorithm
// Strip correlation vector from dae to be able to compile (bug in OpenModelica with vectors of records )
strippedDae := stripCorrelationFromDae(inDaelow);

strippedDae := BackendDAEUtil.getSolvedSystem(strippedDae,"");
(strippedDae, initDAE, useHomotopy, removedInitialEquationLst, primaryParameters, allPrimaryParameters) := BackendDAEUtil.getSolvedSystem(strippedDae,"");

//print("strippedDae :");
//BackendDump.dump(strippedDae);
_ := System.realtimeTock(ClockIndexes.RT_CLOCK_BACKEND); // Is this necessary?
(libs, fileDir, _, _) := SimCodeMain.generateModelCode(strippedDae, inProgram, inPath, cname_str, SOME(simSettings), Absyn.FUNCTIONARGS({}, {}));

(libs, fileDir, _, _) := SimCodeMain.generateModelCode(strippedDae, initDAE, useHomotopy, removedInitialEquationLst, primaryParameters, allPrimaryParameters,inProgram, inPath, cname_str, SOME(simSettings), Absyn.FUNCTIONARGS({}, {}));

//print("..compiling, fileNamePrefix = "+fileNamePrefix+"\n");
CevalScript.compileModel(fileNamePrefix , libs);
Expand Down

0 comments on commit 56d186b

Please sign in to comment.