Skip to content

Commit

Permalink
[Backend] symbolic jacobian remove defines in generates code
Browse files Browse the repository at this point in the history
 - prepare for thread-safe linear systems in symbolic jacobian
 - mark which linear systems are part of the jacobian
 - expand most jacobian related functions in the cRuntime

Belonging to [master]:
  - OpenModelica/OMCompiler#2745
  - OpenModelica/OpenModelica-testsuite#1084
  • Loading branch information
Willi Braun authored and OpenModelica-Hudson committed Dec 5, 2018
1 parent de12219 commit e7d386d
Show file tree
Hide file tree
Showing 42 changed files with 962 additions and 648 deletions.
10 changes: 10 additions & 0 deletions Compiler/BackEnd/BackendDAEUtil.mo
Expand Up @@ -142,6 +142,16 @@ algorithm
end match;
end isSimulationDAE;

public function isJacobianDAE
input BackendDAE.Shared inShared;
output Boolean res;
algorithm
res := match(inShared)
case (BackendDAE.SHARED(backendDAEType=BackendDAE.JACOBIAN())) then true;
else false;
end match;
end isJacobianDAE;

/*************************************************
* checkBackendDAE and stuff
************************************************/
Expand Down
37 changes: 3 additions & 34 deletions Compiler/BackEnd/Differentiate.mo
Expand Up @@ -1200,7 +1200,7 @@ algorithm
//Take care! state means => der(state)
false = BackendVariable.isStateVar(var);

cr = createDifferentiatedCrefName(cr, inDiffwrtCref, matrixName);
cr = ComponentReference.createDifferentiatedCrefName(cr, inDiffwrtCref, matrixName);
res = DAE.CREF(cr, tp);
then
(res, inFunctionTree);
Expand All @@ -1212,7 +1212,7 @@ algorithm
//Take care! state means => der(state)
false = BackendVariable.isStateVar(var);

cr = createDifferentiatedCrefName(cr, inDiffwrtCref, matrixName);
cr = ComponentReference.createDifferentiatedCrefName(cr, inDiffwrtCref, matrixName);
res = DAE.CREF(cr, tp);
then
(res, inFunctionTree);
Expand Down Expand Up @@ -1257,37 +1257,6 @@ algorithm
outCref := ComponentReference.crefSetLastType(outCref, ComponentReference.crefLastType(inCref));
end createDiffedCrefName;

public function createDifferentiatedCrefName
input DAE.ComponentRef inCref;
input DAE.ComponentRef inX;
input String inMatrixName;
output DAE.ComponentRef outCref;
protected
list<DAE.Subscript> subs;
constant Boolean debug = false;
algorithm
if debug then print("inCref: " + ComponentReference.printComponentRefStr(inCref) +"\n"); end if;

// move subs and and type to lastCref, to move type replace by last type
// and move last cref type to the last cref.
subs := ComponentReference.crefLastSubs(inCref);
outCref := ComponentReference.crefStripLastSubs(inCref);
outCref := ComponentReference.replaceSubsWithString(outCref);
if debug then print("after full type " + Types.printTypeStr(ComponentReference.crefTypeConsiderSubs(inCref)) + "\n"); end if;
outCref := ComponentReference.crefSetLastType(outCref, DAE.T_UNKNOWN_DEFAULT);
if debug then print("after strip: " + ComponentReference.printComponentRefListStr(ComponentReference.expandCref(outCref, true)) + "\n"); end if;

// join crefs
outCref := ComponentReference.joinCrefs(outCref, ComponentReference.makeCrefIdent(BackendDAE.partialDerivativeNamePrefix + inMatrixName, DAE.T_UNKNOWN_DEFAULT, {}));
outCref := ComponentReference.joinCrefs(outCref, inX);
if debug then print("after join: " + ComponentReference.printComponentRefListStr(ComponentReference.expandCref(outCref, true)) + "\n"); end if;

// fix subs and type of the last cref
outCref := ComponentReference.crefSetLastSubs(outCref, subs);
outCref := ComponentReference.crefSetLastType(outCref, ComponentReference.crefLastType(inCref));
if debug then print("outCref: " + ComponentReference.printComponentRefStr(outCref) +"\n"); end if;
end createDifferentiatedCrefName;

public function createSeedCrefName
input DAE.ComponentRef inCref;
input String inMatrixName;
Expand Down Expand Up @@ -1382,7 +1351,7 @@ algorithm
cr = Expression.expCref(e);
tp = Expression.typeof(e);
cr = ComponentReference.crefPrefixDer(cr);
cr = createDifferentiatedCrefName(cr, inDiffwrtCref, matrixName);
cr = ComponentReference.createDifferentiatedCrefName(cr, inDiffwrtCref, matrixName);
res = Expression.makeCrefExp(cr, tp);

b = ComponentReference.crefEqual(DAE.CREF_IDENT("$",DAE.T_REAL_DEFAULT,{}), inDiffwrtCref);
Expand Down
5 changes: 3 additions & 2 deletions Compiler/BackEnd/HpcOmScheduler.mo
Expand Up @@ -3550,10 +3550,11 @@ algorithm
list<list<Integer>> colCols;
array<Integer> ass;
Integer newIdx;
case(SOME(SimCode.JAC_MATRIX(jacCols,vars,name,sparsity,sparsityT,colCols,maxCol,jacIdx,partIdx)),(newIdx,ass))
Option<HashTableCrefSimVar.HashTable> crefToSimVarHTJacobian;
case(SOME(SimCode.JAC_MATRIX(jacCols,vars,name,sparsity,sparsityT,colCols,maxCol,jacIdx,partIdx,crefToSimVarHTJacobian)),(newIdx,ass))
equation
(jacCols,(newIdx,ass)) = List.mapFold(jacCols,TDS_replaceSimEqSysIdxInJacobianColumnWithUpdate,(newIdx,ass));
then (SOME(SimCode.JAC_MATRIX(jacCols,vars,name,sparsity,sparsityT,colCols,maxCol,jacIdx,partIdx)),(newIdx,ass));
then (SOME(SimCode.JAC_MATRIX(jacCols,vars,name,sparsity,sparsityT,colCols,maxCol,jacIdx,partIdx,crefToSimVarHTJacobian)),(newIdx,ass));
else (jacIn,tplIn);
end matchcontinue;
end TDS_replaceSimEqSysIdxInJacobianMatrixWithUpdate;
Expand Down
63 changes: 59 additions & 4 deletions Compiler/BackEnd/SymbolicJacobian.mo
Expand Up @@ -1972,6 +1972,7 @@ algorithm
outFunctionTree := shared.functionTree;
if not onlySparsePattern then
(symbolicJacobian, outFunctionTree) := createJacobian(inBackendDAE,inDiffVars, inStateVars, inInputVars, inParameterVars, inDifferentiatedVars, inVars, inName);
true := checkForNonLinearStrongComponents(symbolicJacobian);
outJacobian := SOME(symbolicJacobian);
else
outJacobian := NONE();
Expand Down Expand Up @@ -2294,14 +2295,14 @@ algorithm
try
(_, _) := BackendVariable.getVarSingle(currVar, inAllVars);
currVar := ComponentReference.crefPrefixDer(currVar);
derivedCref := Differentiate.createDifferentiatedCrefName(currVar, cref, inMatrixName);
derivedCref := ComponentReference.createDifferentiatedCrefName(currVar, cref, inMatrixName);
r1 := BackendVariable.copyVarNewName(derivedCref, v);
r1 := BackendVariable.setVarKind(r1, BackendDAE.STATE_DER());
r1.unreplaceable := true;
index := index + 1;
else
currVar := ComponentReference.crefPrefixDer(currVar);
derivedCref := Differentiate.createDifferentiatedCrefName(currVar, cref, inMatrixName);
derivedCref := ComponentReference.createDifferentiatedCrefName(currVar, cref, inMatrixName);
r1 := BackendVariable.copyVarNewName(derivedCref, v);
r1 := BackendVariable.setVarKind(r1, BackendDAE.STATE_DER());
end try;
Expand All @@ -2311,13 +2312,13 @@ algorithm
case((v as BackendDAE.VAR(varName=currVar))::restVar, cref, _, index, _, _) algorithm
try
(_, _) := BackendVariable.getVarSingle(currVar, inAllVars);
derivedCref := Differentiate.createDifferentiatedCrefName(currVar, cref, inMatrixName);
derivedCref := ComponentReference.createDifferentiatedCrefName(currVar, cref, inMatrixName);
r1 := BackendVariable.copyVarNewName(derivedCref, v);
r1 := BackendVariable.setVarKind(r1, BackendDAE.VARIABLE());
r1.unreplaceable := true;
index := index + 1;
else
derivedCref := Differentiate.createDifferentiatedCrefName(currVar, cref, inMatrixName);
derivedCref := ComponentReference.createDifferentiatedCrefName(currVar, cref, inMatrixName);
r1 := BackendVariable.copyVarNewName(derivedCref, v);
r1 := BackendVariable.setVarKind(r1, BackendDAE.VARIABLE());
end try;
Expand Down Expand Up @@ -3700,5 +3701,59 @@ algorithm
end matchcontinue;
end rhsConstant2;

// =============================================================================
// Function detects non-linear strong component in symbolic jacobians
// - non-linear components should never appear in symbolic jacobian and
// indicate an singular or wrong system
// - this modules stops compiling and outputs an error, otherwise we
// would get error at runtime compiling
// =============================================================================

function checkForNonLinearStrongComponents
"Checks for non-linear algebraic strong compontents and break if some found."
input BackendDAE.SymbolicJacobian symbolicJacobian;
output Boolean result;
protected
BackendDAE.BackendDAE jacBDAE;
String name;
algorithm
(jacBDAE, name, _, _, _) := symbolicJacobian;
try
_ := BackendDAEUtil.mapEqSystem(jacBDAE, checkForNonLinearStrongComponents_work);
result := true;
else
Error.addMessage(Error.INVALID_NONLINEAR_JACOBIAN_COMPONENT, {name});
result := false;
end try;
end checkForNonLinearStrongComponents;

function checkForNonLinearStrongComponents_work
input output BackendDAE.EqSystem syst;
input output BackendDAE.Shared shared;
protected
BackendDAE.StrongComponents comps;
algorithm
try
BackendDAE.EQSYSTEM(matching=BackendDAE.MATCHING(comps=comps)) := syst;
for comp in comps loop
() := match (comp)
local
BackendDAE.JacobianType jacTp;
case BackendDAE.EQUATIONSYSTEM(jacType=BackendDAE.JAC_NONLINEAR())
then fail();
case BackendDAE.EQUATIONSYSTEM(jacType=BackendDAE.JAC_NO_ANALYTIC())
then fail();
case BackendDAE.EQUATIONSYSTEM(jacType=BackendDAE.JAC_GENERIC())
then fail();
case BackendDAE.TORNSYSTEM(linear=false)
then fail();
else ();
end match;
end for;
else
fail();
end try;
end checkForNonLinearStrongComponents_work;

annotation(__OpenModelica_Interface="backend");
end SymbolicJacobian;
31 changes: 31 additions & 0 deletions Compiler/FrontEnd/ComponentReference.mo
Expand Up @@ -3955,5 +3955,36 @@ algorithm
end while;
end getConsumedMemory;

public function createDifferentiatedCrefName
input DAE.ComponentRef inCref;
input DAE.ComponentRef inX;
input String inMatrixName;
output DAE.ComponentRef outCref;
protected
list<DAE.Subscript> subs;
constant Boolean debug = false;
algorithm
if debug then print("inCref: " + ComponentReference.printComponentRefStr(inCref) +"\n"); end if;

// move subs and and type to lastCref, to move type replace by last type
// and move last cref type to the last cref.
subs := ComponentReference.crefLastSubs(inCref);
outCref := ComponentReference.crefStripLastSubs(inCref);
outCref := ComponentReference.replaceSubsWithString(outCref);
if debug then print("after full type " + Types.printTypeStr(ComponentReference.crefTypeConsiderSubs(inCref)) + "\n"); end if;
outCref := ComponentReference.crefSetLastType(outCref, DAE.T_UNKNOWN_DEFAULT);
if debug then print("after strip: " + ComponentReference.printComponentRefListStr(ComponentReference.expandCref(outCref, true)) + "\n"); end if;

// join crefs
outCref := ComponentReference.joinCrefs(outCref, ComponentReference.makeCrefIdent(DAE.partialDerivativeNamePrefix + inMatrixName, DAE.T_UNKNOWN_DEFAULT, {}));
outCref := ComponentReference.joinCrefs(outCref, inX);
if debug then print("after join: " + ComponentReference.printComponentRefListStr(ComponentReference.expandCref(outCref, true)) + "\n"); end if;

// fix subs and type of the last cref
outCref := ComponentReference.crefSetLastSubs(outCref, subs);
outCref := ComponentReference.crefSetLastType(outCref, ComponentReference.crefLastType(inCref));
if debug then print("outCref: " + ComponentReference.printComponentRefStr(outCref) +"\n"); end if;
end createDifferentiatedCrefName;

annotation(__OpenModelica_Interface="frontend");
end ComponentReference;
1 change: 1 addition & 0 deletions Compiler/FrontEnd/DAE.mo
Expand Up @@ -61,6 +61,7 @@ public type StartValue = Option<Exp>;
public constant String UNIQUEIO = "$unique$outer$";

public constant String derivativeNamePrefix = "$DER";
public constant String partialDerivativeNamePrefix = "$pDER";
public constant String preNamePrefix = "$PRE";
public constant String previousNamePrefix = "$CLKPRE";
public constant String startNamePrefix = "$START";
Expand Down
7 changes: 5 additions & 2 deletions Compiler/SimCode/ReduceDAE.mo
Expand Up @@ -342,6 +342,7 @@ protected function addLabelToEquations
list<SimCode.SimEqSystem> residual;
Option<SimCode.JacobianMatrix> jacobianMatrix;
BackendDAE.EquationAttributes eqAttr;
Boolean partOfJac;

// nothing
case ({},vars,idx,_,_) then ({},vars,idx,{});
Expand Down Expand Up @@ -395,8 +396,9 @@ protected function addLabelToEquations
labels3=listAppend(labels,labels2);
then
(SimCode.SES_ALGORITHM(i,statements2, eqAttr) :: es_1,vars_2,idx3,labels3);

// linear systems
case (((eq as SimCode.SES_LINEAR (SimCode.LINEARSYSTEM(i,partOfLinear,tornSystem,varsLin,b,A,residual,jacobianMatrix,sourcelist,idxLS,nUnknownsLS),NONE(), eqAttr)) :: es),vars,idx,_,_)
case (((eq as SimCode.SES_LINEAR (SimCode.LINEARSYSTEM(i,partOfLinear,tornSystem,varsLin,b,A,residual,jacobianMatrix,sourcelist,idxLS,nUnknownsLS,partOfJac),NONE(), eqAttr)) :: es),vars,idx,_,_)
equation

if(Flags.isSet(Flags.REDUCE_DAE)) then
Expand All @@ -409,7 +411,8 @@ protected function addLabelToEquations
labels3=listAppend(labels,labels2);

then
(SimCode.SES_LINEAR(SimCode.LINEARSYSTEM(i,partOfLinear,tornSystem,varsLin,b,A2,residual,jacobianMatrix,sourcelist,idxLS,nUnknownsLS),NONE(), eqAttr) :: es_1,vars_2,idx3,labels3);
(SimCode.SES_LINEAR(SimCode.LINEARSYSTEM(i,partOfLinear,tornSystem,varsLin,b,A2,residual,jacobianMatrix,sourcelist,idxLS,nUnknownsLS, partOfJac),NONE(), eqAttr) :: es_1,vars_2,idx3,labels3);

// non-linear systems
case (((eq as SimCode.SES_NONLINEAR(SimCode.NONLINEARSYSTEM(index=i,eqs=nl,crefs=crefs,indexNonLinearSystem=idxNLS,nUnknowns=nUnknownsNLS,jacobianMatrix=jacobianMatrix),NONE(), eqAttr)) :: es),vars,idx,_,_)
equation
Expand Down
4 changes: 3 additions & 1 deletion Compiler/SimCode/SimCode.mo
Expand Up @@ -88,10 +88,11 @@ uniontype JacobianMatrix
Integer maxColorCols;
Integer jacobianIndex;
Integer partitionIndex;
Option<HashTableCrefSimVar.HashTable> crefsHT; // all jacobian variables
end JAC_MATRIX;
end JacobianMatrix;

constant JacobianMatrix emptyJacobian = JAC_MATRIX({}, {}, "", {}, {}, {}, 0, -1, 0);
constant JacobianMatrix emptyJacobian = JAC_MATRIX({}, {}, "", {}, {}, {}, 0, -1, 0, NONE());

constant PartitionData emptyPartitionData = PARTITIONDATA(-1,{},{},{});

Expand Down Expand Up @@ -411,6 +412,7 @@ uniontype LinearSystem
list<DAE.ElementSource> sources;
Integer indexLinearSystem;
Integer nUnknowns "Number of variables that are solved in this system. Needed because 'crefs' only contains the iteration variables.";
Boolean partOfJac "if TRUE then this system is part of a jacobian matrix";
end LINEARSYSTEM;
end LinearSystem;

Expand Down
5 changes: 4 additions & 1 deletion Compiler/SimCode/SimCodeFunction.mo
Expand Up @@ -37,6 +37,7 @@ public
import Absyn;
import DAE;
import HashTableStringToPath;
import HashTableCrefSimVar;
import Tpl;

uniontype FunctionCode
Expand Down Expand Up @@ -206,6 +207,7 @@ uniontype Context
end ALGLOOP_CONTEXT;

record JACOBIAN_CONTEXT
Option<HashTableCrefSimVar.HashTable> jacHT;
end JACOBIAN_CONTEXT;

record OTHER_CONTEXT
Expand All @@ -225,12 +227,13 @@ uniontype Context

record DAE_MODE_CONTEXT
end DAE_MODE_CONTEXT;

end Context;

public constant Context contextSimulationNonDiscrete = SIMULATION_CONTEXT(false);
public constant Context contextSimulationDiscrete = SIMULATION_CONTEXT(true);
public constant Context contextFunction = FUNCTION_CONTEXT();
public constant Context contextJacobian = JACOBIAN_CONTEXT();
public constant Context contextJacobian = JACOBIAN_CONTEXT(NONE());
public constant Context contextAlgloopJacobian = ALGLOOP_CONTEXT(false,true);
public constant Context contextAlgloopInitialisation = ALGLOOP_CONTEXT(true,false);
public constant Context contextAlgloop = ALGLOOP_CONTEXT(false,false);
Expand Down

0 comments on commit e7d386d

Please sign in to comment.