Skip to content

Commit

Permalink
- added module to evaluate a function partially / check if the output…
Browse files Browse the repository at this point in the history
… or parts of the output are constant

- added function BackendVarTransform.getReplacementCRefFirst and Debug.bcallret1_2
- added debug flag "evalConstFuncs"

git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@19474 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
Volker Waurich committed Mar 6, 2014
1 parent 374b6bb commit c84bd02
Show file tree
Hide file tree
Showing 6 changed files with 284 additions and 6 deletions.
220 changes: 220 additions & 0 deletions Compiler/BackEnd/BackendDAEOptimize.mo
Expand Up @@ -64,6 +64,7 @@ protected import ClassInf;
protected import Config;
protected import ComponentReference;
protected import DAEUtil;
protected import DAEDump;
protected import Debug;
protected import Differentiate;
protected import Expression;
Expand Down Expand Up @@ -9613,4 +9614,223 @@ algorithm
outDAE := BackendDAE.DAE(systs, BackendDAE.SHARED(knvars, exobj, aliasVars, inieqns, remeqns, constrs, clsAttrs, cache, env, funcTree, eventInfo, eoc, btp, symjacs, ei));
end applyRewriteRulesBackendShared;

// =============================================================================
// evaluate functions partially
//
// =============================================================================


public function evalFunctions
input BackendDAE.BackendDAE inDAE;
output BackendDAE.BackendDAE outDAE;
algorithm
outDAE := matchcontinue(inDAE)
local
BackendDAE.EqSystems eqSysts;
BackendDAE.Shared shared;
case(_)
equation
true = Flags.isSet(Flags.EVALUATE_CONST_FUNCTIONS);
BackendDAE.DAE(eqs = eqSysts,shared = shared) = inDAE;
(eqSysts,(shared,_)) = List.mapFold(eqSysts,evalFunctions_main,(shared,1));
outDAE = BackendDAE.DAE(eqSysts,shared);
print("evaluate the functions\n");
then
outDAE;
else
then
inDAE;
end matchcontinue;
end evalFunctions;

protected function evalFunctions_main
input BackendDAE.EqSystem eqSysIn;
input tuple<BackendDAE.Shared,Integer> tplIn;
output BackendDAE.EqSystem eqSysOut;
output tuple<BackendDAE.Shared,Integer> tplOut;
protected
Integer sysIdx;
Option<BackendDAE.IncidenceMatrix> m;
Option<BackendDAE.IncidenceMatrixT> mT;
BackendDAE.Shared sharedIn;
BackendDAE.EquationArray eqs;
BackendDAE.Matching matching;
BackendDAE.Variables vars;
list<BackendDAE.Var> varLst;
list<BackendDAE.Equation> eqLst;
BackendDAE.StateSets stateSets;
algorithm
(sharedIn,sysIdx) := tplIn;
BackendDAE.EQSYSTEM(orderedVars=vars,orderedEqs=eqs,m=m,mT=mT,matching=matching,stateSets=stateSets) := eqSysIn;
eqLst := BackendEquation.equationList(eqs);
varLst := BackendVariable.varList(vars);
//BackendDump.dumpEquationArray(eqs, "before");

//traverse the eqSystem for function calls
eqLst := List.map1(eqLst,evalFunctions_findFuncs,sharedIn);
eqs := BackendEquation.listEquation(eqLst);
//BackendDump.dumpEquationArray(eqs, "after");

eqSysOut := BackendDAE.EQSYSTEM(vars,eqs,m,mT,matching,stateSets);
tplOut := tplIn;
end evalFunctions_main;

protected function evalFunctions_findFuncs
input BackendDAE.Equation eqIn;
input BackendDAE.Shared sharedIn;
output BackendDAE.Equation eqOut;
algorithm
eqOut := matchcontinue(eqIn,sharedIn)
local
Boolean b1,b2,diff;
BackendDAE.Equation eq;
DAE.Exp exp1,exp2;
DAE.ElementSource source;
DAE.FunctionTree funcs;
case(BackendDAE.EQUATION(exp=exp1, scalar=exp2,source=source,differentiated=diff),_)
equation
b1 = Expression.containFunctioncall(exp1);
b2 = Expression.containFunctioncall(exp2);
true = b1 or b2;
funcs = BackendDAEUtil.getFunctions(sharedIn);
exp1 = Debug.bcallret2(b1,evaluateConstantFunction,exp1,funcs,exp1);
exp2 = Debug.bcallret2(b2,evaluateConstantFunction,exp2,funcs,exp2);
eq = BackendDAE.EQUATION(exp1,exp2,source,diff);
then
eq;
else
equation
then
eqIn;
end matchcontinue;
end evalFunctions_findFuncs;

protected function evaluateConstantFunction
input DAE.Exp expIn;
input DAE.FunctionTree funcs;
output DAE.Exp expOut;
algorithm
expOut := matchcontinue(expIn,funcs)
local
Boolean funcIsConst;
list<Integer> constIdcs;
Absyn.Path path;
BackendVarTransform.VariableReplacements repl;
HashTable2.HashTable ht;
DAE.Exp exp;
DAE.Function func;
list<DAE.ComponentRef> inputCrefs, outputCrefs;
list<DAE.Element> elements, algs, cvars, allInputs, constInputs, allOutputs;
list<DAE.Exp> crefs, consts;
list<DAE.Statement> stmts;
case(DAE.CALL(path=path, expLst=crefs,attr=_),_)
equation
//print("BEFORE:\n");
//ExpressionDump.dumpExp(expIn);

// get the elements of the function
SOME(func) = DAEUtil.avlTreeGet(funcs,path);
elements = DAEUtil.getFunctionElements(func);
allInputs = List.filter(elements,DAEUtil.isInputVar);
allOutputs = List.filter(elements,DAEUtil.isOutputVar);
algs = List.filter(elements,DAEUtil.isAlgorithm);

// get constant function inputs
consts = List.filterOnTrue(crefs,Expression.isConst);
constIdcs = List.map1(consts,List.position,crefs);
constIdcs = List.map1(constIdcs,intAdd,1);
constInputs = List.map1(constIdcs,List.getIndexFirst,allInputs);
inputCrefs = List.map(constInputs,DAEUtil.varCref);
outputCrefs = List.map(allOutputs,DAEUtil.varCref);
/*
print("\nall const crefs\n");
print(ExpressionDump.printExpListStr(consts));
print("\nall constant inputs\n");
print(ComponentReference.printComponentRefListStr(inputCrefs));
print("\nall algs "+&intString(listLength(algs))+&"\n");
print(DAEDump.dumpElementsStr(algs));
*/

//build replacement rules
repl = BackendVarTransform.emptyReplacements();
repl = BackendVarTransform.addReplacements(repl,inputCrefs,consts,NONE());
//BackendVarTransform.dumpReplacements(repl);

// go through all algorithms and replace the variables with constants if possible, update the ht with new constant variables
(algs,repl) = List.mapFold(algs,evaluateFunctions_updateAlgorithms,repl);
//print("\nall algs after "+&intString(listLength(algs))+&"\n");
//print(DAEDump.dumpElementsStr(algs));
//BackendVarTransform.dumpReplacements(repl);

//check if the outputs became constant and build new algs
consts = List.map1(outputCrefs,BackendVarTransform.getReplacementCRefFirst,repl);

exp = List.first(consts);
//print("AFTER:\n");
//ExpressionDump.dumpExp(exp);
then
exp;
else
equation
//print("the function is not constant\n");
then
expIn;
end matchcontinue;
end evaluateConstantFunction;

protected function evaluateFunctions_updateAlgorithms"gets the statements from an algorithm in order to traverse them.
author:Waurich TUD 2014-03"
input DAE.Element algIn;
input BackendVarTransform.VariableReplacements replIn;
output DAE.Element algOut;
output BackendVarTransform.VariableReplacements replOut;
protected
DAE.Algorithm alg;
DAE.ElementSource source;
list<DAE.Statement> stmts;
algorithm
DAE.ALGORITHM(alg,source) := algIn;
stmts := DAEUtil.getStatement(algIn);
(stmts,replOut) := List.mapFold(stmts,evaluateFunctions_updateStatements,replIn);
alg := DAE.ALGORITHM_STMTS(stmts);
algOut := DAE.ALGORITHM(alg,source);
end evaluateFunctions_updateAlgorithms;

protected function evaluateFunctions_updateStatements"
author:Waurich TUD 2014-03"
input DAE.Statement algIn;
input BackendVarTransform.VariableReplacements replIn;
output DAE.Statement algOut;
output BackendVarTransform.VariableReplacements replOut;
algorithm
(algOut,replOut) := matchcontinue(algIn,replIn)
local
Boolean changed, isConst;
BackendVarTransform.VariableReplacements repl;
DAE.ComponentRef cref;
DAE.ElementSource source;
DAE.Exp exp1, exp2;
DAE.Statement alg;
DAE.Type typ;
case(alg as DAE.STMT_ASSIGN(type_=typ, exp1=exp1, exp=exp2, source=source),_)
equation
cref = Expression.expCref(exp1);
(exp2,changed) = BackendVarTransform.replaceExp(exp2,replIn,NONE());
(exp2,changed) = Debug.bcallret1_2(changed,ExpressionSimplify.simplify,exp2,exp2,changed);
(exp2,_) = ExpressionSimplify.simplify(exp2);
isConst = Expression.isConst(exp2);
repl = Debug.bcallret4(isConst,BackendVarTransform.addReplacement,replIn,cref,exp2,NONE(),replIn);
//print("isConst "+&boolString(isConst)+&"\n");
alg = Util.if_(isConst,DAE.STMT_ASSIGN(typ,exp1,exp2,source),alg);
//print("the alg: "+&DAEDump.ppStatementStr(alg)+&"\n");
then
(alg,repl);
else
equation
print("evaluateFunctions_updateStatements failed!\n");
then
fail();
end matchcontinue;
end evaluateFunctions_updateStatements;

end BackendDAEOptimize;
3 changes: 2 additions & 1 deletion Compiler/BackEnd/BackendDAEUtil.mo
Expand Up @@ -8764,7 +8764,8 @@ algorithm
(BackendDAEOptimize.simplifyIfEquations, "simplifyIfEquations", false),
(BackendDAEOptimize.replaceEdgeChange, "replaceEdgeChange", false),
(BackendDAEOptimize.residualForm, "residualForm", false),
(BackendDAEOptimize.resolveLoops, "resolveLoops",false)
(BackendDAEOptimize.resolveLoops, "resolveLoops",false),
(BackendDAEOptimize.evalFunctions, "evalFunc",false)
};
strPreOptModules := getPreOptModulesString();
strPreOptModules := Util.getOptionOrDefault(ostrPreOptModules,strPreOptModules);
Expand Down
22 changes: 22 additions & 0 deletions Compiler/BackEnd/BackendVarTransform.mo
Expand Up @@ -712,6 +712,28 @@ algorithm
end match;
end getReplacement;

public function getReplacementCRefFirst "
Retrives a replacement variable given a set of replacement rules and a
source variable.
"
input DAE.ComponentRef inComponentRef;
input VariableReplacements inVariableReplacements;
output DAE.Exp outComponentRef;
algorithm
outComponentRef:=
match (inComponentRef,inVariableReplacements)
local
DAE.ComponentRef src;
DAE.Exp dst;
HashTable2.HashTable ht;
case (src,REPLACEMENTS(hashTable=ht))
equation
dst = BaseHashTable.get(src,ht);
then
dst;
end match;
end getReplacementCRefFirst;

public function getAllReplacements "
Author BZ 2009-04
Extract all crefs -> exp to two separate lists.
Expand Down
4 changes: 2 additions & 2 deletions Compiler/FrontEnd/DAEUtil.mo
Expand Up @@ -2703,7 +2703,7 @@ algorithm
bodyStmts := List.mapFlat(List.filter(elements, isAlgorithm), getStatement);
end getFunctionAlgorithmStmts;

protected function getStatement
public function getStatement
input DAE.Element inElement;
output list<DAE.Statement> outStatements;
algorithm
Expand Down Expand Up @@ -5391,7 +5391,7 @@ algorithm
end matchcontinue;
end getOptionStr;

protected function printAvlTreeStr "
public function printAvlTreeStr "
Prints the avl tree to a string"
input DAE.AvlTree inAvlTree;
output String outString;
Expand Down
30 changes: 30 additions & 0 deletions Compiler/Util/Debug.mo
Expand Up @@ -380,6 +380,36 @@ algorithm
end match;
end bcallret1;

public function bcallret1_2
"Boolean controlled calling of given function (2nd arg).
The passed function gets 1 arguments.
The last two parameters are returned if the given flag is not set."
input Boolean flag;
input FuncA_BC func;
input Type_a arg1;
input Type_b default1;
input Type_c default2;
output Type_b res1;
output Type_c res2;
partial function FuncA_BC
input Type_a inTypeA;
output Type_b outTypeD;
output Type_c outTypeE;
end FuncA_BC;
replaceable type Type_a subtypeof Any;
replaceable type Type_b subtypeof Any;
replaceable type Type_c subtypeof Any;
// Apparently cannot inline stuff with function pointers... annotation(__OpenModelica_EarlyInline = true);
algorithm
(res1,res2) := match (flag,func,arg1,default1,default2)
case (true,_,_,_,_)
equation
(res1,res2) = func(arg1);
then (res1,res2);
else (default1,default2);
end match;
end bcallret1_2;

public function bcallret2
"Boolean controlled calling of given function (2nd arg).
The passed function gets 2 arguments.
Expand Down
11 changes: 8 additions & 3 deletions Compiler/Util/Flags.mo
Expand Up @@ -379,6 +379,8 @@ constant DebugFlag DISABLE_RECORD_CONSTRUCTOR_OUTPUT = DEBUG_FLAG(106, "disableR
Util.gettext("Disables output of record constructors in the flat code."));
constant DebugFlag DUMP_TRANSFORMED_MODELICA_MODEL = DEBUG_FLAG(107, "dumpTransformedModelica", false,
Util.gettext("dumps the back-end DAE to a Modelica-like model after all symbolic transformations are applied"));
constant DebugFlag EVALUATE_CONST_FUNCTIONS = DEBUG_FLAG(108, "evalConstFuncs", false,
Util.gettext("evaluates functions complete and partially and checks for constant output"));

// This is a list of all debug flags, to keep track of which flags are used. A
// flag can not be used unless it's in this list, and the list is checked at
Expand Down Expand Up @@ -491,7 +493,8 @@ constant list<DebugFlag> allDebugFlags = {
RESOLVE_LOOPS,
DISABLE_WINDOWS_PATH_CHECK_WARNING,
DISABLE_RECORD_CONSTRUCTOR_OUTPUT,
DUMP_TRANSFORMED_MODELICA_MODEL
DUMP_TRANSFORMED_MODELICA_MODEL,
EVALUATE_CONST_FUNCTIONS
};

// CONFIGURATION FLAGS
Expand Down Expand Up @@ -556,7 +559,8 @@ constant ConfigFlag PRE_OPT_MODULES = CONFIG_FLAG(12, "preOptModules",
"inlineArrayEqn",
"removeSimpleEquations",
// "addInitialStmtsToAlgorithms",
"resolveLoops"
"resolveLoops",
"evalFunc"
}),
SOME(STRING_DESC_OPTION({
("removeSimpleEquations", removeSimpleEquationDesc),
Expand All @@ -579,7 +583,8 @@ constant ConfigFlag PRE_OPT_MODULES = CONFIG_FLAG(12, "preOptModules",
("replaceEdgeChange", Util.gettext("Replace edge(b) = b and not pre(b) and change(b) = v <> pre(v).")),
("residualForm", Util.gettext("Transforms simple equations x=y to zero-sum equations 0=y-x.")),
("addInitialStmtsToAlgorithms", Util.gettext("Expands all algorithms with initial statements for outputs.")),
("resolveLoops", Util.gettext("resolves linear equations in loops"))
("resolveLoops", Util.gettext("resolves linear equations in loops")),
("evalFunc", Util.gettext("evaluates functions partially"))
})),
Util.gettext("Sets the pre optimization modules to use in the back end. See +help=optmodules for more info."));

Expand Down

0 comments on commit c84bd02

Please sign in to comment.