Skip to content

Commit

Permalink
Implement product operator and DIV_SCALAR_ARRAY in Cpp runtime (#7641)
Browse files Browse the repository at this point in the history
* Implement product operator in Cpp runtime

* Update OMCompiler/SimulationRuntime/cpp/Core/Math/ArrayOperations.cpp

Co-authored-by: phannebohm <phannebohm@fh-bielefeld.de>

* Update test

* Implement DIV_SCALAR_ARRAY in Cpp runtime

See e.g. PowerSystems.Examples.AC3ph.Precalculation.EqCircFromTransDat

Co-authored-by: phannebohm <phannebohm@fh-bielefeld.de>
  • Loading branch information
rfranke and phannebohm committed Jul 3, 2021
1 parent a6b4e42 commit de5d495
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 13 deletions.
26 changes: 15 additions & 11 deletions OMCompiler/Compiler/Template/CodegenCppCommon.tpl
Expand Up @@ -1946,28 +1946,29 @@ template daeExpCall(Exp call, Context context, Text &preExp /*BUFP*/, Text &varD
'semiLinear(<%var1%>,<%var2%>,<%var3%>)'

case CALL(path=IDENT(name="max"), attr=CALL_ATTR(ty = ty), expLst={array}) then
//let &tmpVar = buffer "" /*BUFD*/
let expVar = daeExp(array, context, &preExp /*BUFC*/, &varDecls /*BUFD*/,simCode , &extraFuncs , &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation)
let arr_tp_str = expTypeShort(ty)
let tvar = tempDecl(arr_tp_str, &varDecls /*BUFD*/)
let &preExp += '<%tvar%> = min_max<<%arr_tp_str%>>(<%expVar%>).second;<%\n%>'
'<%tvar%>'
case CALL(path=IDENT(name="sum"), attr=CALL_ATTR(ty = ty), expLst={array}) then
//let &tmpVar = buffer "" /*BUFD*/
let expVar = daeExp(array, context, &preExp /*BUFC*/, &varDecls /*BUFD*/,simCode , &extraFuncs , &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation)
let arr_tp_str = expTypeShort(ty)
let tvar = tempDecl(arr_tp_str, &varDecls /*BUFD*/)
let &preExp += '<%tvar%> = sum_array<<%arr_tp_str%>>(<%expVar%>);<%\n%>'
'<%tvar%>'

case CALL(path=IDENT(name="min"), attr=CALL_ATTR(ty = ty), expLst={array}) then
//let &tmpVar = buffer "" /*BUFD*/
let expVar = daeExp(array, context, &preExp /*BUFC*/, &varDecls /*BUFD*/,simCode , &extraFuncs , &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation)
let arr_tp_str = expTypeShort(ty)
let tvar = tempDecl(arr_tp_str, &varDecls /*BUFD*/)
let &preExp += '<%tvar%> = min_max<<%arr_tp_str%>>(<%expVar%>).first;<%\n%>'
'<%tvar%>'

case CALL(path=IDENT(name="sum"), attr=CALL_ATTR(ty = ty), expLst={array}) then
let expVar = daeExp(array, context, &preExp /*BUFC*/, &varDecls /*BUFD*/,simCode , &extraFuncs , &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation)
let arr_tp_str = expTypeShort(ty)
'sum_array<<%arr_tp_str%>>(<%expVar%>)'

case CALL(path=IDENT(name="product"), attr=CALL_ATTR(ty = ty), expLst={array}) then
let expVar = daeExp(array, context, &preExp, &varDecls, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation)
let arr_tp_str = expTypeShort(ty)
'product_array<<%arr_tp_str%>>(<%expVar%>)'

case call as CALL(path=IDENT(name="vector"), expLst={exp}, attr=CALL_ATTR(ty=ty)) then
let expVar = daeExp(exp, context, &preExp /*BUFC*/, &varDecls /*BUFD*/,simCode , &extraFuncs , &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation)
let tvar = match ty
Expand Down Expand Up @@ -2335,7 +2336,11 @@ template daeExpBinary(Operator it, Exp exp1, Exp exp2, Context context, Text &pr
let tvar = tempDecl(expTypeArrayDims(ty.ty, dims), &varDecls /*BUFD*/)
let &preExp += 'divide_array<<%type%>>(<%e1%>, <%e2%>, <%tvar%>);<%\n%>'
'<%tvar%>'
case DIV_SCALAR_ARRAY(__) then "daeExpBinary:ERR DIV_SCALAR_ARR not supported"
case DIV_SCALAR_ARRAY(ty=T_ARRAY(dims=dims)) then
let type = expTypeShort(ty.ty)
let tvar = tempDecl(expTypeArrayDims(ty.ty, dims), &varDecls /*BUFD*/)
let &preExp += 'divide_array<<%type%>>(<%e1%>, <%e2%>, <%tvar%>);<%\n%>'
'<%tvar%>'
case UMINUS(__) then "daeExpBinary:ERR UMINUS not supported"
case UMINUS_ARR(__) then "daeExpBinary:ERR UMINUS_ARR not supported"
case ADD_ARR(ty=T_ARRAY(dims=dims)) then
Expand Down Expand Up @@ -2373,7 +2378,6 @@ template daeExpBinary(Operator it, Exp exp1, Exp exp2, Context context, Text &pr
case MUL_SCALAR_PRODUCT(__) then
let type = expTypeShort(ty)
'dot_array<<%type%>>(<%e1%>, <%e2%>)'
case DIV_SCALAR_ARRAY(__) then "daeExpBinary:ERR DIV_SCALAR_ARRAY not supported"
case POW_ARRAY_SCALAR(ty=T_ARRAY(dims=dims)) then
let tvar = tempDecl(expTypeArrayDims(ty.ty, dims), &varDecls /*BUFD*/)
let &preExp += 'pow_array_scalar(<%e1%>, <%e2%>, <%tvar%>);<%\n%>'
Expand Down
31 changes: 31 additions & 0 deletions OMCompiler/SimulationRuntime/cpp/Core/Math/ArrayOperations.cpp
Expand Up @@ -369,6 +369,19 @@ void divide_array(const BaseArray<T>& inputArray, const T &b, BaseArray<T>& outp
std::transform(data, data + nelems, aim, std::bind2nd(std::divides<T>(), b));
}

template <typename T>
void divide_array(const T &b, const BaseArray<T>& inputArray, BaseArray<T>& outputArray)
{
size_t nelems = inputArray.getNumElems();
if (outputArray.getNumElems() != nelems)
{
outputArray.setDims(inputArray.getDims());
}
const T* data = inputArray.getData();
T* aim = outputArray.getData();
std::transform(data, data + nelems, aim, std::bind1st(std::divides<T>(), b));
}

template <typename T>
void divide_array_elem_wise(const BaseArray<T> &leftArray, const BaseArray<T> &rightArray, BaseArray<T> &resultArray)
{
Expand Down Expand Up @@ -492,6 +505,14 @@ T sum_array (const BaseArray<T>& x)
return val;
}

template <typename T>
T product_array(const BaseArray<T>& x)
{
const T* data = x.getData();
T val = std::accumulate(data, data + x.getNumElems(), T(1), std::multiplies<T>());
return val;
}

/**
scalar product of two arrays (a,b type as template parameter)
*/
Expand Down Expand Up @@ -669,6 +690,11 @@ divide_array(const BaseArray<int>& inputArray, const int &b, BaseArray<int>& out
template void BOOST_EXTENSION_EXPORT_DECL
divide_array(const BaseArray<bool>& inputArray, const bool &b, BaseArray<bool>& outputArray);

template void BOOST_EXTENSION_EXPORT_DECL
divide_array(const double &b, const BaseArray<double>& inputArray, BaseArray<double>& outputArray);
template void BOOST_EXTENSION_EXPORT_DECL
divide_array(const int &b, const BaseArray<int>& inputArray, BaseArray<int>& outputArray);

template void BOOST_EXTENSION_EXPORT_DECL
divide_array_elem_wise(const BaseArray<double> &leftArray, const BaseArray<double> &rightArray, BaseArray<double> &resultArray);
template void BOOST_EXTENSION_EXPORT_DECL
Expand Down Expand Up @@ -730,6 +756,11 @@ sum_array(const BaseArray<int>& x);
template bool BOOST_EXTENSION_EXPORT_DECL
sum_array(const BaseArray<bool>& x);

template double BOOST_EXTENSION_EXPORT_DECL
product_array(const BaseArray<double>& x);
template int BOOST_EXTENSION_EXPORT_DECL
product_array(const BaseArray<int>& x);

template void BOOST_EXTENSION_EXPORT_DECL
cross_array(const BaseArray<double>& a, const BaseArray<double>& b, BaseArray<double>& res);
template void BOOST_EXTENSION_EXPORT_DECL
Expand Down
Expand Up @@ -69,6 +69,9 @@ void multiply_array_elem_wise(const BaseArray<T> &leftArray, const BaseArray<T>
template <typename T>
void divide_array(const BaseArray<T>& inputArray, const T &b, BaseArray<T>& outputArray);

template <typename T>
void divide_array(const T &b, const BaseArray<T>& inputArray, BaseArray<T>& outputArray);

template <typename T>
void divide_array_elem_wise(const BaseArray<T> &leftArray, const BaseArray<T> &rightArray, BaseArray<T> &resultArray);

Expand Down Expand Up @@ -99,6 +102,9 @@ void usub_array(const BaseArray<T>& a , BaseArray<T>& b);
template < typename T >
T sum_array(const BaseArray<T>& x);

template < typename T >
T product_array(const BaseArray<T>& x);

/**
finds min/max elements of an array */
template <typename T>
Expand Down
16 changes: 14 additions & 2 deletions testsuite/openmodelica/cppruntime/arrayOperationsTest.mos
Expand Up @@ -2,7 +2,6 @@
// keywords: array operations
// status: correct
// teardown_command: rm -f *ArrayOperations.Test*
// cflags: -d=-newInst

setCommandLineOptions("+simCodeTarget=Cpp");

Expand All @@ -13,6 +12,7 @@ package ArrayOperations
Real y = f1({u + 1, u + 2, u + 3});
Real[2] z = f2(u);
Real[2,2] D = f3(z);
Real p = f4(z);
annotation(experiment(StopTime = 0));
end Test;
// see Modelica.Mechanics.MultiBody.Examples.Rotational3DEffects.MovingActuatedDrive
Expand All @@ -36,9 +36,19 @@ package ArrayOperations
function f3
input Real[:] v;
output Real[size(v, 1), size(v, 1)] D;
protected
Real[size(v,1)] w;
algorithm
D := diagonal(v);
w := v[1] ./ v; // DIV_SCALAR_ARRAY
D := diagonal(w);
end f3;
// built-in product
function f4
input Real[:] v;
output Real p;
algorithm
p := product(v);
end f4;
end ArrayOperations;
");
getErrorString();
Expand All @@ -53,6 +63,7 @@ val(D[1,1], 0);
val(D[1,2], 0);
val(D[2,1], 0);
val(D[2,2], 0);
val(p, 0);

// Result:
// true
Expand All @@ -70,5 +81,6 @@ val(D[2,2], 0);
// 1.0
// 0.0
// 0.0
// 0.5
// 2.0
// endResult

0 comments on commit de5d495

Please sign in to comment.