Skip to content

Commit

Permalink
Support multi-dimensional arrays in the external "C" interface again (#…
Browse files Browse the repository at this point in the history
…3286)

This change introduces incompatible changes to fix a bug that only showed up for bool arrays so far.


git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@25629 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
rfranke committed Apr 20, 2015
1 parent d329ff2 commit f0c15ae
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 51 deletions.
63 changes: 25 additions & 38 deletions Compiler/Template/CodegenCpp.tpl
Expand Up @@ -4467,9 +4467,9 @@ template extArg(SimExtArg extArg, Text &preExp, Text &varDecls, Text &inputAssig
//let name = if oi then 'out.targTest5<%oi%>' else contextCref2(c,contextFunction)
let name = contextCref2(c,contextFunction)
let shortTypeStr = expTypeShort(t)
let boolCast = extCBoolCast(extArg, &preExp, &varDecls, &inputAssign /*BUFD*/, &outputAssign /*BUFD*/, &outputAllocate)
let arrayArg = extCArrayArg(extArg, &preExp, &varDecls, &inputAssign /*BUFD*/, &outputAssign /*BUFD*/, &outputAllocate)
<<
<%boolCast%>
<%arrayArg%>
>>

case SIMEXTARG(cref=c, isInput=ii, outputIndex=0, type_=t) then
Expand All @@ -4491,44 +4491,31 @@ template extArg(SimExtArg extArg, Text &preExp, Text &varDecls, Text &inputAssig
end extArg;


template extCBoolCast(SimExtArg extArg, Text &preExp, Text &varDecls /*BUFP*/, Text &inputAssign /*BUFD*/, Text &outputAssign /*BUFD*/, Text &outputAllocate)
"Function to allocate memory for output and to cast the output to the right data type"
template extCArrayArg(SimExtArg extArg, Text &preExp, Text &varDecls /*BUFP*/, Text &inputAssign /*BUFD*/, Text &outputAssign /*BUFD*/, Text &outputAllocate)
"Function to convert arrays to external C"
::=
match extArg
case SIMEXTARG(cref=c, isInput =iI, outputIndex=oi, isArray=true, type_=t)then
match extArg
case SIMEXTARG(cref=c, isInput =iI, outputIndex=oi, isArray=true, type_=t)then
let name = contextCref2(c,contextFunction)
match type_
case T_ARRAY(__)then
let dimStr = listLength(dims)
let dimsStr = checkDimension(dims)

match ty
case T_BOOL(__) then
let tmp = match dimsStr

case "" then tempDecl('DynArrayDim<%listLength(dims)%><int>', &varDecls /*BUFD*/)
else tempDecl('StatArrayDim<%dimStr%><int,<%dimsStr%> > ', &varDecls /*BUFD*/)
end match
if(iI)
then
let _ = inputAssignTest(c, contextFunction, tmp, &inputAssign)
<<
<%tmp%>.getData()
>>
else
let _ = outputAssignTest(c, contextFunction, tmp, &outputAssign)
let &outputAllocate += '<%tmp%>.setDims(<%name%>.getDims());'
<<
<%tmp%>.getData()
>>
case T_STRING(__) then
'(<%extType2(t,iI,true)%>)<%name%>.getCStrData()/*testfuncdata*/ '
else
'(<%extType2(t,iI,true)%>)<%name%>.getData()/*testfuncdata2*/ '
end match
end extCBoolCast;


match type_
case T_ARRAY(__)then
let dimStr = listLength(dims)
let dimsStr = checkDimension(dims)
let elType = expTypeShort(ty)
let extType = extType2(ty, true, false)
let extCStr = if stringEq(elType, "string") then '.getCStrData()'
if boolOr(intGt(listLength(dims), 1), stringEq(elType, "bool")) then
let tmp = match dimsStr
case "" then
tempDecl('DynArrayDim<%listLength(dims)%><<%extType%>>', &varDecls /*BUFD*/)
else
tempDecl('StatArrayDim<%dimStr%><<%extType%>, <%dimsStr%>>', &varDecls /*BUFD*/)
let &inputAssign += 'convertArrayLayout(<%name%>, <%tmp%>);'
let &outputAssign += if intGt(oi, 0) then 'convertArrayLayout(<%tmp%>, <%name%>);'
'<%tmp%>.getData()<%extCStr%>'
else
'<%name%>.getData()<%extCStr%>'
end extCArrayArg;


template inputAssignTest(DAE.ComponentRef cref, Context context, Text tmp, Text &inputAssign /*BUFD*/)
Expand Down
30 changes: 19 additions & 11 deletions SimulationRuntime/cpp/Core/Math/ArrayOperations.cpp
Expand Up @@ -378,9 +378,9 @@ void convertIntToBool(BaseArray<int>& a, BaseArray<bool>& b)
* helper for assignRowMajorData
* recursive function for muli-dimensional assignment of raw data
*/
template <typename S, typename T>
static size_t assignRowMajorDim(size_t dim, const S* data,
BaseArray<T> &array, vector<size_t> idx) {
template <typename T>
static size_t assignRowMajorDim(size_t dim, const T* data,
BaseArray<T> &array, vector<size_t> &idx) {
size_t processed = 0;
size_t size = array.getDim(dim);
for (size_t i = 1; i <= size; i++) {
Expand All @@ -393,9 +393,10 @@ static size_t assignRowMajorDim(size_t dim, const S* data,
return processed;
}

template <typename S, typename T>
void assignRowMajorData(const S *data, BaseArray<T> &array) {
assignRowMajorDim(1, data, array, vector<size_t>(array.getNumDims()));
template <typename T>
void assignRowMajorData(const T *data, BaseArray<T> &array) {
vector<size_t> idx(array.getNumDims());
assignRowMajorDim(1, data, array, idx);
}

/**
Expand All @@ -404,11 +405,12 @@ void assignRowMajorData(const S *data, BaseArray<T> &array) {
*/
template <typename S, typename T>
static void convertArrayDim(size_t dim,
const BaseArray<S> &s, vector<size_t> &sidx,
BaseArray<S> &d, vector<size_t> &didx) {
BaseArray<S> &s, vector<size_t> &sidx,
BaseArray<T> &d, vector<size_t> &didx) {
size_t ndims = s.getNumDims();
size_t size = s.getDim(dim);
for (size_t i = 1; i <= size; i++) {
didx[dim - i] = sidx[dim - 1] = i;
didx[ndims - dim] = sidx[dim - 1] = i;
if (dim < sidx.size())
convertArrayDim(dim + 1, s, sidx, d, didx);
else
Expand All @@ -421,7 +423,7 @@ static void convertArrayDim(size_t dim,
* including optional type conversion if supported in assignment from S to T
*/
template <typename S, typename T>
void convertArrayLayout(const BaseArray<S> &s, BaseArray<T> &d) {
void convertArrayLayout(BaseArray<S> &s, BaseArray<T> &d) {
size_t ndims = s.getNumDims();
if (ndims != d.getNumDims())
throw ModelicaSimulationError(MODEL_ARRAY_FUNCTION,
Expand All @@ -431,7 +433,7 @@ void convertArrayLayout(const BaseArray<S> &s, BaseArray<T> &d) {
for (size_t dim = 1; dim <= ndims; dim++)
ddims[ndims - dim] = sdims[dim - 1];
d.resize(ddims);
convertDim(1, s, vector<size_t>(ndims), d, vector<size_t>(ndims));
convertArrayDim(1, s, sdims, d, ddims);
}

/*
Expand Down Expand Up @@ -500,6 +502,12 @@ template std::pair <bool,bool> BOOST_EXTENSION_EXPORT_DECL min_max (BaseArray<bo
void BOOST_EXTENSION_EXPORT_DECL convertBoolToInt( BaseArray<bool> & a ,BaseArray<int> & b );
void BOOST_EXTENSION_EXPORT_DECL convertIntToBool( BaseArray<int> & a ,BaseArray<bool> & b );

template void BOOST_EXTENSION_EXPORT_DECL convertArrayLayout(BaseArray<double> &s, BaseArray<double> &d);
template void BOOST_EXTENSION_EXPORT_DECL convertArrayLayout(BaseArray<int> &s, BaseArray<int> &d);
template void BOOST_EXTENSION_EXPORT_DECL convertArrayLayout(BaseArray<bool> &s, BaseArray<int> &d);
template void BOOST_EXTENSION_EXPORT_DECL convertArrayLayout(BaseArray<int> &s, BaseArray<bool> &d);
template void BOOST_EXTENSION_EXPORT_DECL convertArrayLayout(BaseArray<string> &s, BaseArray<string> &d);

template void BOOST_EXTENSION_EXPORT_DECL assignRowMajorData(const double *data, BaseArray<double> &d);
template void BOOST_EXTENSION_EXPORT_DECL assignRowMajorData(const int *data, BaseArray<int> &d);
template void BOOST_EXTENSION_EXPORT_DECL assignRowMajorData(const bool *data, BaseArray<bool> &d);
Expand Down
10 changes: 8 additions & 2 deletions SimulationRuntime/cpp/Include/Core/Math/ArrayOperations.h
Expand Up @@ -94,8 +94,14 @@ void BOOST_EXTENSION_EXPORT_DECL convertBoolToInt( BaseArray<bool> & a ,BaseArra
void BOOST_EXTENSION_EXPORT_DECL convertIntToBool( BaseArray<int> & a ,BaseArray<bool> & b );

/**
* assign data with row major order to BaseArray with arbitrary storage layout,
* Permutes dims between row and column major storage layout,
* including optional type conversion if supported in assignment from S to T
*/
template <typename S, typename T>
void assignRowMajorData(const S *data, BaseArray<T> &array);
void convertArrayLayout(BaseArray<S> &s, BaseArray<T> &d);

/**
* Assign data with row major order to BaseArray with arbitrary storage layout
*/
template <typename T>
void assignRowMajorData(const T *data, BaseArray<T> &array);

0 comments on commit f0c15ae

Please sign in to comment.