Skip to content

Commit

Permalink
Improve treatment of unknown dimensions in Cpp runtime (#7677)
Browse files Browse the repository at this point in the history
See ModelicaTest.Math.TestMatrices3 (MSL 4.0.0)
ERROR  : init  : SimManager: Could not initialize system
ERROR  : init  : SimManager: std::bad_alloc
  • Loading branch information
rfranke committed Jul 8, 2021
1 parent bc38ed3 commit bc38d8e
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 60 deletions.
47 changes: 19 additions & 28 deletions OMCompiler/Compiler/Template/CodegenCpp.tpl
Expand Up @@ -5088,14 +5088,16 @@ match var
*/
case var as VARIABLE(__) then
let marker = '<%contextCref(var.name,contextFunction,simCode , &extraFuncs , &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation)%>'
let &varInits += '/* varOutputTuple varInits(<%marker%>) */ <%\n%>'
let &varAssign += '// varOutput varAssign(<%marker%>) <%\n%>'
let &varInits += '// varOutputTuple varInits(<%marker%>)<%\n%>'
let &varAssign += '// varOutput varAssign(<%marker%>)<%\n%>'
let testinstDimsInit = (instDims |> dim => testDaeDimension(dim);separator="")
let instDimsInit = (instDims |> dim => daeDimension(dim, contextFunction, &varInits, &varDecls, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation)
;separator=",")
let assginBegin = 'get<<%ix%>>'
if instDims then
let &varInits += '<%assginBegin%>(/*_<%fname%>*/output.data).setDims(<%instDimsInit%>);//todo setDims not for stat arrays
<%\n%>'
// don't setDims for static or unknown dimensions, treated as "" and "---", respectively
let &varInits += if boolAnd(intGt(stringLength(testinstDimsInit), 0), intEq(-1, stringFind(testinstDimsInit, "---"))) then
'<%assginBegin%>(/*_<%fname%>*/output.data).setDims(<%instDimsInit%>);<%\n%>'
let &varAssign += '<%assginBegin%>(/*_<%fname%>*/output.data)=<%contextCref(var.name,contextFunction,simCode , &extraFuncs , &extraFuncsDecl, extraFuncsNamespace,stateDerVectorName,useFlatArrayNotation)%>;<%\n%>'
""
else
Expand Down Expand Up @@ -5225,13 +5227,16 @@ template recordMemberInit(Var v, Text varName, Text &preExp /*BUFP*/, Text &varD
end recordMemberInit;

template setDims(Text testinstDimsInit, String varName , Text &varInits, String instDimsInit)
"call varName.setDims for dynamic and known dimensions"
::=
match testinstDimsInit
case "" then let &varInits += ''
case "" then
""
else let &varInits += '<%varName%>.setDims(<%instDimsInit%>);<%\n%>'
else
let &varInits += if intEq(-1, stringFind(testinstDimsInit, "---")) then
'<%varName%>.setDims(<%instDimsInit%>);<%\n%>'
""
end match
end match
end setDims;


Expand Down Expand Up @@ -5397,8 +5402,8 @@ case var as VARIABLE(__) then
let &varInits = buffer ""
let testinstDimsInit = (instDims |> dim => testDaeDimension(dim);separator="")
let instDimsInit = (instDims |> dim => daeDimension(dim, contextFunction, &varInits, &varDecls, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation);separator=",")
// check for unknown dimension that is treated as -1
if boolAnd(stringEq(testinstDimsInit, ""), intEq(-1, stringFind(instDimsInit, "-"))) then
// check for static and known dimension
if boolAnd(stringEq(testinstDimsInit, ""), intEq(-1, stringFind(testinstDimsInit, "---"))) then
if instDims then 'StatArrayDim<%listLength(instDims)%><<%expTypeShort(var.ty)%>, <%instDimsInit%>>& ' else expTypeFlag(var.ty, 5)
else
if instDims then 'DynArrayDim<%listLength(instDims)%><<%expTypeShort(var.ty)%>>/*<%instDimsInit%>*/&' else expTypeFlag(var.ty, 5)
Expand All @@ -5412,8 +5417,8 @@ case var as VARIABLE(__) then
let &varInits = buffer "" // should be empty
let testinstDimsInit = (instDims |> dim => testDaeDimension(dim);separator="")
let instDimsInit = (instDims |> dim => daeDimension(dim, contextFunction, &varInits, &varDecls, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, "stateDerVectorName_not_given", false /*is false the default?*/);separator=",")
// check for unknown dimension that is treated as -1
if boolAnd(stringEq(testinstDimsInit, ""), intEq(-1, stringFind(instDimsInit, "-"))) then
// check for static and known dimension
if boolAnd(stringEq(testinstDimsInit, ""), intEq(-1, stringFind(testinstDimsInit, "---"))) then
if instDims then 'StatArrayDim<%listLength(instDims)%><<%expTypeShort(var.ty)%>, <%instDimsInit%>> ' else expTypeArrayIf(var.ty)
else
if instDims then 'DynArrayDim<%listLength(instDims)%><<%expTypeShort(var.ty)%>>/*<%instDimsInit%>*/ ' else expTypeArrayIf(var.ty)
Expand Down Expand Up @@ -9340,21 +9345,6 @@ bool <%lastIdentOfPath(modelInfo.name)%>::isODE()
>>
end isODE;

template testdimension(Dimension d)
::=
match d
case DAE.DIM_BOOLEAN(__) then ''
case DAE.DIM_INTEGER(__) then ''
case DAE.DIM_ENUM(__) then ''
case DAE.DIM_EXP(exp=e) then
match e
case DAE.CREF(componentRef = cr) then ''
else '-1'
end match
case DAE.DIM_UNKNOWN(__) then '-1'
else '-1'
end testdimension;

template functionInitial(list<SimEqSystem> startValueEquations, Text &varDecls, SimCode simCode, Text& extraFuncs, Text& extraFuncsDecl, Text extraFuncsNamespace, Text stateDerVectorName /*=__zDot*/, Boolean useFlatArrayNotation)
::=
let eqPart = (startValueEquations |> eq as SES_SIMPLE_ASSIGN(__) =>
Expand Down Expand Up @@ -11332,8 +11322,9 @@ template testDaeDimensionExp(Exp exp)
"Generates code for an expression."
::=
match exp
case e as ICONST(__) then ''
else '-1'
case ICONST(integer=-1) then '---' // unknown
case ICONST(__) then '' // known static
else '-1' // known dynamic
end testDaeDimensionExp;

template daeDimension(DAE.Dimension dim, Context context, Text &preExp, Text &varDecls, SimCode simCode, Text& extraFuncs, Text& extraFuncsDecl, Text extraFuncsNamespace, Text stateDerVectorName, Boolean useFlatArrayNotation)
Expand Down
47 changes: 19 additions & 28 deletions OMCompiler/Compiler/Template/CodegenCppOld.tpl
Expand Up @@ -5317,14 +5317,16 @@ match var
*/
case var as VARIABLE(__) then
let marker = '<%contextCref(var.name,contextFunction,simCode , &extraFuncs , &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation)%>'
let &varInits += '/* varOutputTuple varInits(<%marker%>) */ <%\n%>'
let &varAssign += '// varOutput varAssign(<%marker%>) <%\n%>'
let &varInits += '// varOutputTuple varInits(<%marker%>)<%\n%>'
let &varAssign += '// varOutput varAssign(<%marker%>)<%\n%>'
let testinstDimsInit = (instDims |> dim => testDaeDimension(dim);separator="")
let instDimsInit = (instDims |> dim => daeDimension(dim, contextFunction, &varInits, &varDecls, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation)
;separator=",")
let assginBegin = 'get<<%ix%>>'
if instDims then
let &varInits += '<%assginBegin%>(/*_<%fname%>*/output.data).setDims(<%instDimsInit%>);//todo setDims not for stat arrays
<%\n%>'
// don't setDims for static or unknown dimensions, treated as "" and "---", respectively
let &varInits += if boolAnd(intGt(stringLength(testinstDimsInit), 0), intEq(-1, stringFind(testinstDimsInit, "---"))) then
'<%assginBegin%>(/*_<%fname%>*/output.data).setDims(<%instDimsInit%>);<%\n%>'
let &varAssign += '<%assginBegin%>(/*_<%fname%>*/output.data)=<%contextCref(var.name,contextFunction,simCode , &extraFuncs , &extraFuncsDecl, extraFuncsNamespace,stateDerVectorName,useFlatArrayNotation)%>;<%\n%>'
""
else
Expand Down Expand Up @@ -5454,13 +5456,16 @@ template recordMemberInit(Var v, Text varName, Text &preExp /*BUFP*/, Text &varD
end recordMemberInit;

template setDims(Text testinstDimsInit, String varName , Text &varInits, String instDimsInit)
"call varName.setDims for dynamic and known dimensions"
::=
match testinstDimsInit
case "" then let &varInits += ''
case "" then
""
else let &varInits += '<%varName%>.setDims(<%instDimsInit%>);<%\n%>'
else
let &varInits += if intEq(-1, stringFind(testinstDimsInit, "---")) then
'<%varName%>.setDims(<%instDimsInit%>);<%\n%>'
""
end match
end match
end setDims;


Expand Down Expand Up @@ -5626,8 +5631,8 @@ case var as VARIABLE(__) then
let &varInits = buffer ""
let testinstDimsInit = (instDims |> dim => testDaeDimension(dim);separator="")
let instDimsInit = (instDims |> dim => daeDimension(dim, contextFunction, &varInits, &varDecls, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation);separator=",")
// check for unknown dimension that is treated as -1
if boolAnd(stringEq(testinstDimsInit, ""), intEq(-1, stringFind(instDimsInit, "-"))) then
// check for static and known dimension
if boolAnd(stringEq(testinstDimsInit, ""), intEq(-1, stringFind(testinstDimsInit, "---"))) then
if instDims then 'StatArrayDim<%listLength(instDims)%><<%expTypeShort(var.ty)%>, <%instDimsInit%>>& ' else expTypeFlag(var.ty, 5)
else
if instDims then 'DynArrayDim<%listLength(instDims)%><<%expTypeShort(var.ty)%>>/*<%instDimsInit%>*/&' else expTypeFlag(var.ty, 5)
Expand All @@ -5641,8 +5646,8 @@ case var as VARIABLE(__) then
let &varInits = buffer "" // should be empty
let testinstDimsInit = (instDims |> dim => testDaeDimension(dim);separator="")
let instDimsInit = (instDims |> dim => daeDimension(dim, contextFunction, &varInits, &varDecls, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, "stateDerVectorName_not_given", false /*is false the default?*/);separator=",")
// check for unknown dimension that is treated as -1
if boolAnd(stringEq(testinstDimsInit, ""), intEq(-1, stringFind(instDimsInit, "-"))) then
// check for static and known dimension
if boolAnd(stringEq(testinstDimsInit, ""), intEq(-1, stringFind(testinstDimsInit, "---"))) then
if instDims then 'StatArrayDim<%listLength(instDims)%><<%expTypeShort(var.ty)%>, <%instDimsInit%>> ' else expTypeArrayIf(var.ty)
else
if instDims then 'DynArrayDim<%listLength(instDims)%><<%expTypeShort(var.ty)%>>/*<%instDimsInit%>*/ ' else expTypeArrayIf(var.ty)
Expand Down Expand Up @@ -9558,21 +9563,6 @@ bool <%lastIdentOfPath(modelInfo.name)%>::isODE()
>>
end isODE;

template testdimension(Dimension d)
::=
match d
case DAE.DIM_BOOLEAN(__) then ''
case DAE.DIM_INTEGER(__) then ''
case DAE.DIM_ENUM(__) then ''
case DAE.DIM_EXP(exp=e) then
match e
case DAE.CREF(componentRef = cr) then ''
else '-1'
end match
case DAE.DIM_UNKNOWN(__) then '-1'
else '-1'
end testdimension;

template functionInitial(list<SimEqSystem> startValueEquations, Text &varDecls, SimCode simCode, Text& extraFuncs, Text& extraFuncsDecl, Text extraFuncsNamespace, Text stateDerVectorName /*=__zDot*/, Boolean useFlatArrayNotation)
::=
let eqPart = (startValueEquations |> eq as SES_SIMPLE_ASSIGN(__) =>
Expand Down Expand Up @@ -11549,8 +11539,9 @@ template testDaeDimensionExp(Exp exp)
"Generates code for an expression."
::=
match exp
case e as ICONST(__) then ''
else '-1'
case ICONST(integer=-1) then '---' // unknown
case ICONST(__) then '' // known static
else '-1' // known dynamic
end testDaeDimensionExp;

template daeDimension(DAE.Dimension dim, Context context, Text &preExp, Text &varDecls, SimCode simCode, Text& extraFuncs, Text& extraFuncsDecl, Text extraFuncsNamespace, Text stateDerVectorName, Boolean useFlatArrayNotation)
Expand Down
10 changes: 6 additions & 4 deletions OMCompiler/SimulationRuntime/cpp/Core/Math/ArrayOperations.cpp
Expand Up @@ -519,9 +519,8 @@ scalar product of two arrays (a,b type as template parameter)
template <typename T>
T dot_array(const BaseArray<T>& a, const BaseArray<T>& b)
{
if(a.getNumDims() != 1 || b.getNumDims() != 1)
throw ModelicaSimulationError(MODEL_ARRAY_FUNCTION,"error in dot array function. Wrong dimension");

if (a.getNumDims() != 1 || b.getNumDims() != 1)
throw ModelicaSimulationError(MODEL_ARRAY_FUNCTION, "error in dot array function. Wrong dimension");
const T* data1 = a.getData();
const T* data2 = b.getData();
T r = std::inner_product(data1, data1 + a.getNumElems(), data2, 0.0);
Expand All @@ -540,10 +539,13 @@ void cross_array(const BaseArray<T>& a, const BaseArray<T>& b, BaseArray<T>& res
};

/**
finds min/max elements of an array */
finds min/max elements of an array
*/
template <typename T>
std::pair<T,T> min_max(const BaseArray<T>& x)
{
if (x.getNumElems() < 1)
throw ModelicaSimulationError(MODEL_ARRAY_FUNCTION, "min/max requires at least one element");
const T* data = x.getData();
std::pair<const T*, const T*>
ret = minmax_element(data, data + x.getNumElems());
Expand Down

0 comments on commit bc38d8e

Please sign in to comment.