Skip to content

Commit

Permalink
fix for cat array function in cpp template
Browse files Browse the repository at this point in the history
git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@22100 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
niklwors committed Sep 2, 2014
1 parent df6c408 commit 08750ba
Show file tree
Hide file tree
Showing 5 changed files with 131 additions and 91 deletions.
21 changes: 6 additions & 15 deletions Compiler/Template/CodegenCpp.tpl
Expand Up @@ -6,11 +6,6 @@ import CodegenUtil.*;








template translateModel(SimCode simCode, Boolean useFlatArrayNotation) ::=
match simCode
case SIMCODE(modelInfo = MODELINFO(__)) then
Expand Down Expand Up @@ -9262,20 +9257,20 @@ template daeExpCall(Exp call, Context context, Text &preExp /*BUFP*/,
let tmp_type_str = match typeof(a0)
case ty as T_ARRAY(dims=dims) then
let &dimstr += listLength(dims)
'multi_array<<%expTypeShort(ty)%>,<%listLength(dims)%>>'
'DynArrayDim<%listLength(dims)%><<%expTypeShort(ty)%>>'
else
let &dimstr += 'error array dims'
'array error'
let ty_str = '<%expTypeArray(attr.ty)%>'
let tvar = tempDecl(tmp_type_str, &varDecls /*BUFD*/)
let a0str = daeExp(a0, context, &preExp /*BUFC*/, &varDecls /*BUFD*/,simCode, useFlatArrayNotation)
let arrays_exp = (arrays |> array =>
'<%tvar%>_list.push_back(<%daeExp(array, context, &preExp /*BUFC*/, &varDecls /*BUFD*/,simCode, useFlatArrayNotation)%>);' ;separator="\n")
'<%tvar%>_list.push_back(&<%daeExp(array, context, &preExp /*BUFC*/, &varDecls /*BUFD*/,simCode, useFlatArrayNotation)%>);' ;separator="\n")
let &preExp +=
'std::vector<<%tmp_type_str%> > <%tvar%>_list;
<%tvar%>_list.push_back(<%a0str%>);
'vector<BaseArray<<%ty_str%>>* > <%tvar%>_list;
<%tvar%>_list.push_back(&<%a0str%>);
<%arrays_exp%>
cat_array<<%ty_str%>,<%dimstr%> >(<%dim_exp%>,<%tvar%>, <%tvar%>_list );
cat_array<<%ty_str%> >(<%dim_exp%>,<%tvar%>, <%tvar%>_list );
'
'<%tvar%>'

Expand Down Expand Up @@ -12239,11 +12234,7 @@ template copyArrayData(DAE.Type ty, String exp, DAE.ComponentRef cr,
::=
let type = expTypeArray(ty)
let cref = contextArrayCref(cr, context)
match context
case FUNCTION_CONTEXT(__) then
'assign_array(<%cref%>,<%exp%>);'
else
'assign_array(<%cref%>,<%exp%>);'
'<%cref%>.assign(<%exp%>);'
end copyArrayData;

template algStmtWhen(DAE.Statement when, Context context, Text &varDecls /*BUFP*/,SimCode simCode, Boolean useFlatArrayNotation)
Expand Down
71 changes: 71 additions & 0 deletions SimulationRuntime/cpp/Core/Math/ArrayOperations.cpp
Expand Up @@ -15,4 +15,75 @@ size_t getNextIndex(vector<size_t> idx,size_t k)
else
return idx[k];
}
/**
Concatenates n real arrays along the k:th dimension.
*/
template < typename T >
void cat_array (int k,BaseArray<T>& a, vector<BaseArray<T>* >& x )
{
unsigned int new_k_dim_size = 0;
unsigned int n = x.size();
/* check dim sizes of all inputs */
if(n<1)
throw std::invalid_argument("No input arrays");

if(x[0]->getDims().size() < k)
throw std::invalid_argument("Wrong dimension for input array");

new_k_dim_size = x[0]->getDims()[k-1];
for(int i = 1; i < n; i++)
{
if(x[0]->getDims().size() != x[i]->getDims().size())
throw std::invalid_argument("Wrong dimension for input array");
for(int j = 0; j < (k - 1); j++)
{
if (x[0]->getDims()[j] != x[i]->getDims()[j])
throw std::invalid_argument("Wrong size for input array");
}
new_k_dim_size += x[i]->getDims()[k-1];
for(int j = k; j < x[0]->getDims().size(); j++)
{
if (x[0]->getDims()[j] != x[i]->getDims()[j])
throw std::invalid_argument("Wrong size for input array");
}
}
/* calculate size of sub and super structure in 1-dim data representation */
unsigned int n_sub = 1;
unsigned int n_super = 1;
for (int i = 0; i < (k - 1); i++)
{
n_super *= x[0]->getDims()[i];
}
for (int i = k; i < x[0]->getDims().size(); i++)
{
n_sub *= x[0]->getDims()[i];
}
/* allocate output array */
vector<size_t> ex = x[0]->getDims();
ex[k-1] = new_k_dim_size;
if(ex.size()<k)
throw std::invalid_argument("Error resizing concatenate array");
a.setDims( ex );

/* concatenation along k-th dimension */
T* a_data = a.getData();
int j = 0;
for(int i = 0; i < n_super; i++)
{
for(int c = 0; c < n; c++)
{
int n_sub_k = n_sub * x[c]->getDims()[k-1];
T* x_data = x[c]->getData();
for(int r = 0; r < n_sub_k; r++)
{
a_data[j] = x_data[r + (i * n_sub_k)];
j++;
}
}
}


}
template void cat_array<double> (int k,BaseArray<double>& a, vector<BaseArray<double>* >& x );
template void cat_array<int> (int k,BaseArray<int>& a, vector<BaseArray<int>* >& x );
template void cat_array<bool> (int k,BaseArray<bool>& a, vector<BaseArray<bool>* >& x );
58 changes: 51 additions & 7 deletions SimulationRuntime/cpp/Include/Core/Math/Array.h
@@ -1,11 +1,16 @@
#pragma once


//forward declaration
template <class T> class DynArrayDim1;
template <class T> class DynArrayDim2;
template <class T> class DynArrayDim3;

template<class T>class BaseArray
{
public:
BaseArray(){};
BaseArray(bool is_static)
:_static(is_static)
{};

virtual T& operator()(unsigned int i)
{
Expand Down Expand Up @@ -53,25 +58,34 @@ template<class T>class BaseArray
{
throw std::invalid_argument("Wrong virtual Array setDims call");
}


bool isStatic()
{
return _static;
}
protected:
bool _static;
};

template<typename T, std::size_t size>class StatArrayDim1 : public BaseArray<T>
{

public:
StatArrayDim1(const T* data)
:BaseArray<T>(true)
{
//std::copy(data,data+size,_real_array.begin());
memcpy( _real_array.begin(), data, size * sizeof( T ) );
}

StatArrayDim1(const StatArrayDim1<T,size>& otherarray)
:BaseArray<T>(true)
{
_real_array = otherarray._real_array;
}

StatArrayDim1()
:BaseArray<T>(true)
{
}

Expand All @@ -86,15 +100,28 @@ template<typename T, std::size_t size>class StatArrayDim1 : public BaseArray<T>
{
if (this != &rhs)
{

try
{
StatArrayDim1<T,size>& a = dynamic_cast<StatArrayDim1<T,size>& >(rhs);
_real_array = a._real_array;
if(rhs.isStatic())
{
StatArrayDim1<T,size>& a = dynamic_cast<StatArrayDim1<T,size>& >(rhs);
_real_array = a._real_array;
}
else
{
DynArrayDim1<T>& a = dynamic_cast<DynArrayDim1<T>& >(rhs);
const T* data = rhs.getData();
memcpy( _real_array.begin(), data, size * sizeof( T ) );

}
}
catch(std::bad_exception & be)
{
throw std::runtime_error("Wrong array type assign");

}

}
return *this;
}
Expand Down Expand Up @@ -186,16 +213,19 @@ template<typename T ,std::size_t size1,std::size_t size2,bool fotran = false>cla

public:
StatArrayDim2(const T* data) //const T (&data) const T (&data)[size1*size2]
:BaseArray<T>(true)
{
//std::copy(data,data+size1*size2,_real_array.begin());
memcpy( _real_array.begin(), data, size1*size2 * sizeof( T ) );
}

StatArrayDim2()
:BaseArray<T>(true)
{
}

StatArrayDim2(const StatArrayDim2<T,size1,size2>& otherarray)
:BaseArray<T>(true)
{
_real_array = otherarray._real_array;
}
Expand Down Expand Up @@ -326,16 +356,19 @@ template<typename T ,std::size_t size1, std::size_t size2, std::size_t size3> cl
//friend class ArrayDim3<T, size1, size2, size3>;
public:
StatArrayDim3(const T data[])
:BaseArray<T>(true)
{
//std::copy(data,data+size1*size2*size3,_real_array.begin());
memcpy( _real_array.begin(), data, size1*size2*size3 * sizeof( T ) );
}

StatArrayDim3()
:BaseArray<T>(true)
{
}

~StatArrayDim3(){}
~StatArrayDim3()
{}

/*void assign(StatArrayDim3<T,size1,size2,size3> otherArray)
{
Expand Down Expand Up @@ -670,11 +703,13 @@ template<typename T>class DynArrayDim1 : public BaseArray<T>


DynArrayDim1()
:BaseArray<T>(false)
{
_multi_array.reindex(1);
}

DynArrayDim1(const DynArrayDim1<T>& dynarray)
:BaseArray<T>(false)
{
//assign(dynarray);
setDims(dynarray.getDims()[0]);
Expand All @@ -683,6 +718,7 @@ template<typename T>class DynArrayDim1 : public BaseArray<T>
}

DynArrayDim1(unsigned int size1)
:BaseArray<T>(false)
{
std::vector<size_t> v;
v.push_back(size1);
Expand All @@ -691,6 +727,7 @@ template<typename T>class DynArrayDim1 : public BaseArray<T>
}

DynArrayDim1(const BaseArray<T>& otherArray)
:BaseArray<T>(false)
{
std::vector<size_t> v = otherArray.getDims();
if(v.size()!=1)
Expand Down Expand Up @@ -806,11 +843,13 @@ template<typename T >class DynArrayDim2 : public BaseArray<T>

public:
DynArrayDim2()
:BaseArray<T>(false)
{
_multi_array.reindex(1);
}

DynArrayDim2(const DynArrayDim2<T>& dynarray)
:BaseArray<T>(false)
{
//assign(dynarray);
setDims(dynarray.getDims()[0],dynarray.getDims()[1]);
Expand All @@ -819,7 +858,8 @@ template<typename T >class DynArrayDim2 : public BaseArray<T>
}

DynArrayDim2(const BaseArray<T>& otherArray)
{
:BaseArray<T>(false)
{
std::vector<size_t> v = otherArray.getDims();
if(v.size()!=2)
throw std::runtime_error("Wrong number of dimensions in DynArrayDim2");
Expand All @@ -829,6 +869,7 @@ template<typename T >class DynArrayDim2 : public BaseArray<T>
_multi_array.assign(data_otherarray,data_otherarray+v[0]*v[1]);
}
DynArrayDim2(unsigned int size1, unsigned int size2)
:BaseArray<T>(false)
{
std::vector<size_t> v;
v.push_back(size1);
Expand Down Expand Up @@ -938,11 +979,13 @@ template<typename T> class DynArrayDim3 : public BaseArray<T>
//friend class ArrayDim3<T, size1, size2, size3>;
public:
DynArrayDim3()
:BaseArray<T>(false)
{
_multi_array.reindex(1);
}

DynArrayDim3(unsigned int size1, unsigned int size2, unsigned int size3)
:BaseArray<T>(false)
{
std::vector<size_t> v;
v.push_back(size1);
Expand All @@ -952,6 +995,7 @@ template<typename T> class DynArrayDim3 : public BaseArray<T>
_multi_array.reindex(1);
}
DynArrayDim3(const BaseArray<T>& otherArray)
:BaseArray<T>(false)
{
std::vector<size_t> v = otherArray.getDims();
if(v.size()!=3)
Expand Down

0 comments on commit 08750ba

Please sign in to comment.