Skip to content

Commit

Permalink
Reuse of constant parts of Jacobians
Browse files Browse the repository at this point in the history
Purpose
  - A Jacobian can have constant parts, meaning equations that are
    independent of the seed vector. These equations only need to be
    evaluated once per Jacobian evaluation.

How to use
  - Use new debug flag `symJacConstantSplit` to generate Jacobians with separated
    constant part. This will also use PostOptModule removeSimpleEquations
    in function optimizeJacobianMatrix.

Changes
  - Added SparsePatternCref type in BackendDAE.mo.
  - Split equation system for jacobian in first with all directional derivative
    equations and additional systems for constant equations, which are
    independente of seed variables and therefore constant.
  - Added constantEqns in SimCode.JAC_COLUMN to strore constant part of Jacobian.
  - Adapted C code generation to generate constant equations.
  - Evaluate constant equations bevor evaluating directional derivativs for Jacobian.
  - Added debug flags symJacConstantSplit.
  - Updated testsuite due to changed logs.
  - Added testcase for reuse constant parts of Jacobian.
  • Loading branch information
AnHeuermann authored and adrpo committed Nov 7, 2019
1 parent 065a64f commit 5aea5c3
Show file tree
Hide file tree
Showing 28 changed files with 1,614 additions and 1,346 deletions.
6 changes: 3 additions & 3 deletions OMCompiler/Compiler/BackEnd/HpcOmScheduler.mo
Expand Up @@ -3569,15 +3569,15 @@ protected function TDS_replaceSimEqSysIdxInJacobianColumnWithUpdate "author: Wau
algorithm
(jacOut,tplOut) := matchcontinue(jacIn,tplIn)
local
list<SimCode.SimEqSystem> simEqs;
list<SimCode.SimEqSystem> simEqs, constEqns;
list<SimCodeVar.SimVar> simVars;
Integer rowLen;
array<Integer> ass;
Integer newIdx;
case (SimCode.JAC_COLUMN(simEqs,simVars,rowLen),(newIdx,ass))
case (SimCode.JAC_COLUMN(simEqs,simVars,rowLen,constEqns),(newIdx,ass))
equation
(simEqs,(newIdx,ass)) = List.mapFold(simEqs,TDS_replaceSimEqSysIndexWithUpdate,(newIdx,ass));
then (SimCode.JAC_COLUMN(simEqs,simVars,rowLen),(newIdx,ass));
then (SimCode.JAC_COLUMN(simEqs,simVars,rowLen,constEqns),(newIdx,ass));
else (jacIn,tplIn);
end matchcontinue;
end TDS_replaceSimEqSysIdxInJacobianColumnWithUpdate;
Expand Down
48 changes: 33 additions & 15 deletions OMCompiler/Compiler/BackEnd/SymbolicJacobian.mo
Expand Up @@ -2071,6 +2071,8 @@ algorithm
BackendDAE.EqSystem syst;
BackendDAE.Shared shared;
Boolean b;
String addRemoveConstantEqnsModule;
list<String> strPostOptModules;

case (BackendDAE.DAE(syst::{}, shared), {}, _)
equation
Expand All @@ -2094,21 +2096,34 @@ algorithm
b = Flags.disableDebug(Flags.EXEC_STAT);
end if;

strPostOptModules = {"wrapFunctionCalls",
"inlineArrayEqn",
"constantLinearSystem",
"solveSimpleEquations",
"tearingSystem",
"calculateStrongComponentJacobians",
"removeConstants",
"simplifyTimeIndepFuncCalls"};

// Add removeSimpleEquation to remove constant(= independent of seed) equations.
if Flags.isSet(Flags.SPLIT_CONSTANT_PARTS_SYMJAC) then
/* ToDo: removeSimpleEquation can't handle all sorts of equations inside the
* jacobian BackendDAE. E.g. for equations lile
* $cse14 := $DER$$PModelica$PMedia$PWater$PIF97_Utilities$PwaterBaseProp_ph(p[10], h[10], 0, 0, 1.0, 0.0);
* from SteamPipe from ScalableTestSuite.
* Add a new module which finds constant (= independent of seed) equations
* and moves them to a different system.
*/
strPostOptModules = List.insert(strPostOptModules, 4, "removeSimpleEquations");
end if;

backendDAE2 = BackendDAEUtil.getSolvedSystemforJacobians(backendDAE,
{"removeEqualRHS",
"removeSimpleEquations",
"evalFunc"},
NONE(),
NONE(),
{
"wrapFunctionCalls",
"inlineArrayEqn",
"constantLinearSystem",
"solveSimpleEquations",
"tearingSystem",
"calculateStrongComponentJacobians",
"removeConstants",
"simplifyTimeIndepFuncCalls"});
NONE(),
NONE(),
strPostOptModules);
if Flags.isSet(Flags.JAC_DUMP) then
BackendDump.bltdump("Symbolic Jacobian",backendDAE2);
else
Expand Down Expand Up @@ -2227,10 +2242,10 @@ algorithm
BackendVariable.varsSize(globalKnownVars) +
BackendVariable.varsSize(inSeedVars);
jacKnownVars = BackendVariable.emptyVarsSized(size);
jacKnownVars = BackendVariable.addVariables(orderedVars, jacKnownVars);
jacKnownVars = BackendVariable.addVariables(globalKnownVars, jacKnownVars);
jacKnownVars = BackendVariable.addVariables(inSeedVars, jacKnownVars);
(jacKnownVars,_) = BackendVariable.traverseBackendDAEVarsWithUpdate(jacKnownVars, BackendVariable.setVarDirectionTpl, (DAE.INPUT()));
jacKnownVars = BackendVariable.addVariables(orderedVars, jacKnownVars);
jacKnownVars = BackendVariable.addVariables(globalKnownVars, jacKnownVars);
jacOrderedEqs = BackendEquation.listEquation(derivedEquations);


Expand Down Expand Up @@ -2422,10 +2437,13 @@ public function calcJacobianDependencies
input BackendDAE.SymbolicJacobian jacobian;
output list<DAE.ComponentRef> dependencies;
protected
BackendDAE.EqSystem syst;
BackendDAE.EqSystems systems;
BackendDAE.Shared shared;
BackendDAE.EqSystem syst;
algorithm
(BackendDAE.DAE({syst}, shared), _, _, _, _, _) := jacobian;
(BackendDAE.DAE(systems, shared), _, _, _, _, _) := jacobian;
syst := List.first(systems); // Only the first system contains directional derivative,
// the others contain optional constant equations
dependencies := BackendEquation.getCrefsFromEquations(syst.orderedEqs, syst.orderedVars, shared.globalKnownVars);
end calcJacobianDependencies;

Expand Down
14 changes: 7 additions & 7 deletions OMCompiler/Compiler/SimCode/SerializeModelInfo.mo
Expand Up @@ -444,7 +444,7 @@ algorithm
local
Integer i,j;
DAE.Statement stmt;
list<SimCode.SimEqSystem> eqs,jeqs;
list<SimCode.SimEqSystem> eqs,jeqs,constantEqns;
SimCode.LinearSystem lSystem, atL;
SimCode.NonlinearSystem nlSystem, atNL;
BackendDAE.WhenOperator whenOp;
Expand Down Expand Up @@ -558,7 +558,7 @@ algorithm
end if;

jeqs = match lSystem.jacobianMatrix
case SOME(SimCode.JAC_MATRIX(columns={SimCode.JAC_COLUMN(columnEqns=jeqs)})) then SimCodeUtil.sortEqSystems(jeqs);
case SOME(SimCode.JAC_MATRIX(columns={SimCode.JAC_COLUMN(columnEqns=jeqs,constantEqns=constantEqns)})) then SimCodeUtil.sortEqSystems(listAppend(jeqs,constantEqns));
else {};
end match;
if not listEmpty(jeqs) then
Expand Down Expand Up @@ -616,7 +616,7 @@ algorithm
end if;

jeqs = match lSystem.jacobianMatrix
case SOME(SimCode.JAC_MATRIX(columns={SimCode.JAC_COLUMN(columnEqns=jeqs)})) then SimCodeUtil.sortEqSystems(jeqs);
case SOME(SimCode.JAC_MATRIX(columns={SimCode.JAC_COLUMN(columnEqns=jeqs,constantEqns=constantEqns)})) then SimCodeUtil.sortEqSystems(listAppend(jeqs,constantEqns));
else {};
end match;
if not listEmpty(jeqs) then
Expand Down Expand Up @@ -671,7 +671,7 @@ algorithm
end if;

jeqs = match atL.jacobianMatrix
case SOME(SimCode.JAC_MATRIX(columns={SimCode.JAC_COLUMN(columnEqns=jeqs)})) then SimCodeUtil.sortEqSystems(jeqs);
case SOME(SimCode.JAC_MATRIX(columns={SimCode.JAC_COLUMN(columnEqns=jeqs,constantEqns=constantEqns)})) then SimCodeUtil.sortEqSystems(listAppend(jeqs,constantEqns));
else {};
end match;
if not listEmpty(jeqs) then
Expand Down Expand Up @@ -772,7 +772,7 @@ algorithm
min(serializeEquation(file,e,section,withOperations,parent=nlSystem.index,assign_type=if nlSystem.tornSystem then 1 else 0) for e in List.rest(eqs));

jeqs = match nlSystem.jacobianMatrix
case SOME(SimCode.JAC_MATRIX(columns={SimCode.JAC_COLUMN(columnEqns=jeqs)})) then SimCodeUtil.sortEqSystems(jeqs);
case SOME(SimCode.JAC_MATRIX(columns={SimCode.JAC_COLUMN(columnEqns=jeqs,constantEqns=constantEqns)})) then SimCodeUtil.sortEqSystems(listAppend(jeqs,constantEqns));
else {};
end match;
if not listEmpty(jeqs) then
Expand Down Expand Up @@ -813,7 +813,7 @@ algorithm
min(serializeEquation(file,e,section,withOperations,parent=nlSystem.index,assign_type=if nlSystem.tornSystem then 1 else 0) for e in List.rest(eqs));

jeqs = match nlSystem.jacobianMatrix
case SOME(SimCode.JAC_MATRIX(columns={SimCode.JAC_COLUMN(columnEqns=jeqs)})) then SimCodeUtil.sortEqSystems(jeqs);
case SOME(SimCode.JAC_MATRIX(columns={SimCode.JAC_COLUMN(columnEqns=jeqs,constantEqns=constantEqns)})) then SimCodeUtil.sortEqSystems(listAppend(jeqs,constantEqns));
else {};
end match;
if not listEmpty(jeqs) then
Expand Down Expand Up @@ -851,7 +851,7 @@ algorithm
min(serializeEquation(file,e,section,withOperations,parent=atNL.index,assign_type=if atNL.tornSystem then 1 else 0) for e in List.rest(eqs));

jeqs = match atNL.jacobianMatrix
case SOME(SimCode.JAC_MATRIX(columns={SimCode.JAC_COLUMN(columnEqns=jeqs)})) then SimCodeUtil.sortEqSystems(jeqs);
case SOME(SimCode.JAC_MATRIX(columns={SimCode.JAC_COLUMN(columnEqns=jeqs,constantEqns=constantEqns)})) then SimCodeUtil.sortEqSystems(listAppend(jeqs,constantEqns));
else {};
end match;
if not listEmpty(jeqs) then
Expand Down
1 change: 1 addition & 0 deletions OMCompiler/Compiler/SimCode/SimCode.mo
Expand Up @@ -74,6 +74,7 @@ uniontype JacobianColumn
list<SimEqSystem> columnEqns; // column equations equals in size to column vars
list<SimCodeVar.SimVar> columnVars; // all column vars, none results vars index -1, the other corresponding to rows index
Integer numberOfResultVars; // corresponds to the number of rows
list<SimEqSystem> constantEqns; // List of constant equations independent of seed variables
end JAC_COLUMN;
end JacobianColumn;

Expand Down

0 comments on commit 5aea5c3

Please sign in to comment.