Skip to content
This repository has been archived by the owner on May 18, 2019. It is now read-only.

Handle array_get better for multi-dim arrays #2187

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions Compiler/SimCode/SimCodeFunctionUtil.mo
Original file line number Diff line number Diff line change
Expand Up @@ -2617,6 +2617,40 @@ algorithm
outdef := stringDelimitList(List.threadMap(List.fill("i_", nrdims), idxstrlst, stringAppend), ",");
end generateSubPalceholders;

public function getConstantSubscriptMemoryLocation "Returns SOME(ix) if the subscript or type is not constant.
For a subscript like [1,4] with dimensions [5,4] it returns 1*4 + 4 to match the C runtime"
input list<DAE.Exp> indexes;
input DAE.Type ty;
output Option<Integer> outIndex=NONE();
protected
list<DAE.Dimension> dims;
list<Integer> dimsInt, ixInt;
Integer ndim, sz, ix, i, j;
algorithm
if not Types.dimensionsKnown(ty) then
return;
end if;
dims := Types.getDimensions(ty);
ndim := Types.numberOfDimensions(ty);
if ndim <= 1 or ndim <> listLength(Types.getDimensions(ty)) or ndim <> listLength(indexes) then
return;
end if;
try
dimsInt := listReverse(Expression.dimensionSize(d) for d in dims);
ixInt := listReverse(Expression.expArrayIndex(index) for index in indexes);
ix := 0;
sz := 1;
while not listEmpty(ixInt) loop
i::ixInt := ixInt;
j::dimsInt := dimsInt;
ix := ix + (i-1)*sz;
sz := sz * j;
end while;
outIndex := SOME(ix);
else
end try;
end getConstantSubscriptMemoryLocation;



annotation(__OpenModelica_Interface="backendInterface");
Expand Down
33 changes: 29 additions & 4 deletions Compiler/Template/CodegenCFunctions.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -6314,15 +6314,40 @@ template daeExpAsub(Exp inExp, Context context, Text &preExp,
arrayScalarRhs(ecr.ty, subs, arrName, context, &preExp, &varDecls, &auxFunction)

case ASUB(exp=e, sub=indexes) then
let exp = daeExp(e, context, &preExp, &varDecls, &auxFunction)
let typeShort = expTypeFromExpShort(e)
match Expression.typeof(inExp)
case T_ARRAY(__) then
error(sourceInfo(),'ASUB non-scalar <%ExpressionDumpTpl.dumpExp(inExp,"\"")%>. The inner exp has type: <%unparseType(Expression.typeof(e))%>. After ASUB it is still an array: <%unparseType(Expression.typeof(inExp))%>.')
else
let expIndexes = (indexes |> index => '<%daeExpASubIndex(index, context, &preExp, &varDecls, &auxFunction)%>' ;separator=", ")
'<%typeShort%>_get<%match listLength(indexes) case 1 then "" case i then '_<%i%>D'%>(<%exp%>, <%expIndexes%>)'

match getConstantSubscriptMemoryLocation(indexes, Expression.typeof(e))
case SOME(ix) then
let exp = daeExp(e, context, &preExp, &varDecls, &auxFunction)
'<%typeShort%>_get(<%exp%>, <%ix%>)'
else (match indexes
case {index} then
let exp = daeExp(e, context, &preExp, &varDecls, &auxFunction)
let ix = daeExpASubIndex(index, context, &preExp, &varDecls, &auxFunction)
'<%typeShort%>_get(<%exp%>, <%ix%>)'
else
let ix = tempDecl("int", &varDecls)
let sz = tempDecl("int", &varDecls)
let exp = daeExpAsLValue(e, context, &preExp, &varDecls, &auxFunction)
let expIndexes = (indexes |> index => '<%daeExpASubIndex(index, context, &preExp, &varDecls, &auxFunction)%>' ;separator=", ")
let tmp =
<<
<%ix%> = 0;
<%sz%> = 1;
<%
listReverse(indexes) |> index hasindex i1 fromindex 1 =>
<<
<%ix%> += <%daeExpASubIndex(index, context, &preExp, &varDecls, &auxFunction)%>;
<%sz%> *= <%exp%>.dim_size[<%intSub(listLength(indexes),i1)%>];
>> ; separator="\n"
%>
>>
let &preExp += tmp
'<%typeShort%>_get(<%exp%>, /*<%listLength(indexes)%>-dim*/ <%ix%>)'
)
else
error(sourceInfo(),'OTHER_ASUB <%ExpressionDumpTpl.dumpExp(inExp,"\"")%>')
end daeExpAsub;
Expand Down
6 changes: 5 additions & 1 deletion Compiler/Template/SimCodeTV.mo
Original file line number Diff line number Diff line change
Expand Up @@ -1186,7 +1186,11 @@ package SimCodeFunctionUtil
output String outdef;
end generateSubPalceholders;


function getConstantSubscriptMemoryLocation
input list<DAE.Exp> indexes;
input DAE.Type ty;
output Option<Integer> outIndex;
end getConstantSubscriptMemoryLocation;

end SimCodeFunctionUtil;

Expand Down
4 changes: 0 additions & 4 deletions SimulationRuntime/c/util/base_array.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,6 @@
#include <stdarg.h>
#include "omc_msvc.h"

static OMC_INLINE size_t getIndex_2D(_index_t *dim, int i, int j) {return i*dim[1]+j;}
static OMC_INLINE size_t getIndex_3D(_index_t *dim, int i, int j, int k) {return i*dim[1]*dim[2]+j*dim[2]+k;}
static OMC_INLINE size_t getIndex_4D(_index_t *dim, int i, int j, int k, int l) {return i*dim[1]*dim[2]*dim[3]+j*dim[2]*dim[3]+k*dim[3]+l;}

/* Settings the fields of a base_array */
void base_array_create(base_array_t *dest, void *data, int ndims, va_list ap);

Expand Down
15 changes: 0 additions & 15 deletions SimulationRuntime/c/util/boolean_array.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,21 +42,6 @@ static OMC_INLINE modelica_boolean boolean_get(const boolean_array_t a, size_t i
return ((modelica_boolean *) a.data)[i];
}

static OMC_INLINE modelica_boolean boolean_get_2D(const boolean_array_t a, size_t i, size_t j)
{
return boolean_get(a, getIndex_2D(a.dim_size,i,j));
}

static OMC_INLINE modelica_boolean boolean_get_3D(const boolean_array_t a, size_t i, size_t j, size_t k)
{
return boolean_get(a, getIndex_3D(a.dim_size,i,j,k));
}

static OMC_INLINE modelica_boolean boolean_get_4D(const boolean_array_t a, size_t i, size_t j, size_t k, size_t l)
{
return boolean_get(a, getIndex_4D(a.dim_size,i,j,k,l));
}

/* Setting the fields of a boolean_array */
extern void boolean_array_create(boolean_array_t *dest, modelica_boolean *data, int ndims, ...);

Expand Down
15 changes: 0 additions & 15 deletions SimulationRuntime/c/util/integer_array.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,21 +43,6 @@ static OMC_INLINE modelica_integer integer_get(const integer_array_t a, size_t i
return ((modelica_integer *) a.data)[i];
}

static OMC_INLINE modelica_integer integer_get_2D(const integer_array_t a, size_t i, size_t j)
{
return integer_get(a, getIndex_2D(a.dim_size,i,j));
}

static OMC_INLINE modelica_integer integer_get_3D(const integer_array_t a, size_t i, size_t j, size_t k)
{
return integer_get(a, getIndex_3D(a.dim_size,i,j,k));
}

static OMC_INLINE modelica_integer integer_get_4D(const integer_array_t a, size_t i, size_t j, size_t k, size_t l)
{
return integer_get(a, getIndex_4D(a.dim_size,i,j,k,l));
}

/* Settings the fields of a integer_array */
extern void integer_array_create(integer_array_t *dest, modelica_integer *data,
int ndims, ...);
Expand Down
15 changes: 0 additions & 15 deletions SimulationRuntime/c/util/real_array.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,21 +44,6 @@ static OMC_INLINE modelica_real real_get(const real_array_t a, size_t i)
return ((modelica_real *) a.data)[i];
}

static OMC_INLINE modelica_real real_get_2D(const real_array_t a, size_t i, size_t j)
{
return real_get(a, getIndex_2D(a.dim_size,i,j));
}

static OMC_INLINE modelica_real real_get_3D(const real_array_t a, size_t i, size_t j, size_t k)
{
return real_get(a, getIndex_3D(a.dim_size,i,j,k));
}

static OMC_INLINE modelica_real real_get_4D(const real_array_t a, size_t i, size_t j, size_t k, size_t l)
{
return real_get(a, getIndex_4D(a.dim_size,i,j,k,l));
}

/* Setting the fields of a real_array */
extern void real_array_create(real_array_t *dest, modelica_real *data, int ndims, ...);

Expand Down