Skip to content

Commit

Permalink
fix for some array functions in cpp template and cpp runtime
Browse files Browse the repository at this point in the history
git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@20300 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
niklwors committed Apr 29, 2014
1 parent 1524561 commit f0a2ed8
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 47 deletions.
37 changes: 22 additions & 15 deletions Compiler/Template/CodegenCpp.tpl
Expand Up @@ -7232,22 +7232,22 @@ template daeExpCall(Exp call, Context context, Text &preExp /*BUFP*/,
case CALL(path=IDENT(name="max"), expLst={array}) then
let &tmpVar = buffer "" /*BUFD*/
let expVar = daeExp(array, context, &preExp /*BUFC*/, &tmpVar /*BUFD*/,simCode)
let arr_tp_str = '<%expTypeFromExpArray(array)%>'
let arr_tp_str = expTypeFromExpShort(array)
let tvar = tempDecl(expTypeFromExpModelica(array), &varDecls /*BUFD*/)
let &preExp += '<%tvar%> = min_max<<%arr_tp_str%>,1>(<%expVar%>).second;<%\n%>'
'<%tvar%>'
case CALL(path=IDENT(name="sum"), expLst={array}) then
let &tmpVar = buffer "" /*BUFD*/
let expVar = daeExp(array, context, &preExp /*BUFC*/, &tmpVar /*BUFD*/,simCode)
let arr_tp_str = '<%expTypeFromExpArray(array)%>'
let arr_tp_str = expTypeFromExpShort(array)
let tvar = tempDecl(expTypeFromExpModelica(array), &varDecls /*BUFD*/)
let &preExp += '<%tvar%> = sum_array<<%arr_tp_str%>,1>(<%expVar%>);<%\n%>'
'<%tvar%>'

case CALL(path=IDENT(name="min"), expLst={array}) then
let &tmpVar = buffer "" /*BUFD*/
let expVar = daeExp(array, context, &preExp /*BUFC*/, &tmpVar /*BUFD*/,simCode)
let arr_tp_str = '<%expTypeFromExpArray(array)%>'
let arr_tp_str = expTypeFromExpShort(array)
let tvar = tempDecl(expTypeFromExpModelica(array), &varDecls /*BUFD*/)
let &preExp += '<%tvar%> = min_max<<%arr_tp_str%>,1>(<%expVar%>).first;<%\n%>'
'<%tvar%>'
Expand All @@ -7256,7 +7256,7 @@ template daeExpCall(Exp call, Context context, Text &preExp /*BUFP*/,
let valExp = daeExp(val, context, &preExp /*BUFC*/, &varDecls /*BUFD*/,simCode)
let dimsExp = (dims |> dim =>
daeExp(dim, context, &preExp /*BUFC*/, &varDecls /*BUFD*/,simCode) ;separator="][")
let ty_str = '<%expTypeArray(attr.ty)%>'
let ty_str = '<%expTypeShort(attr.ty)%>'
let tmp_type_str = 'multi_array<<%ty_str%>,<%listLength(dims)%>>'

let tvar = tempDecl(tmp_type_str, &varDecls /*BUFD*/)
Expand Down Expand Up @@ -7718,6 +7718,7 @@ case T_COMPLEX(complexClassType = record_state, varLst = var_lst) then
'<%ret_var%>'
end daeExpRecordCrefRhs;


template daeExpCrefRhs2(Exp ecr, Context context, Text &preExp /*BUFP*/,
Text &varDecls /*BUFP*/,SimCode simCode)
"Generates code for a component reference."
Expand Down Expand Up @@ -7765,28 +7766,34 @@ template daeExpCrefRhsIndexSpec(list<Subscript> subs, Context context,
Text &preExp /*BUFP*/, Text &varDecls /*BUFP*/,SimCode simCode)
"Helper to daeExpCrefRhs."
::=
let tmp = tempDecl("vector< vector<size_t> >", &varDecls /*BUFD*/)

let nridx_str = listLength(subs)
//let tmp = tempDecl("index_type", &varDecls /*BUFD*/)
let tmp_shape = tempDecl("vector<size_t>", &varDecls /*BUFD*/)
let tmp_indeces = tempDecl("idx_type", &varDecls /*BUFD*/)
let idx_str = (subs |> sub hasindex i1 =>
match sub
case INDEX(__) then
/* let tmp_index = tempDecl("vector<size_t>", &varDecls)
let &preExp += '<%tmp_index%>.push_back(0);//<%\n%>
<%tmp%>.push_back(<%tmp_index%>);<%\n%> '*/
let expPart = daeExp(exp, context, &preExp /*BUFC*/, &varDecls /*BUFD*/,simCode)
let tmp_idx = tempDecl("vector<size_t>", &varDecls /*BUFD*/)
let &preExp += '<%tmp_shape%>.push_back(0);<%\n%>
<%tmp_idx%>.push_back(<%expPart%>);<%\n%>
<%tmp_indeces%>.push_back(<%tmp_idx%>);<%\n%>'
''
case WHOLEDIM(__) then
let tmp_index = tempDecl("vector<size_t>", &varDecls /*BUFD*/)
let &preExp += '<%tmp_index%>.push_back(1);<%\n%>
<%tmp%>.push_back(<%tmp_index%>);<%\n%>'
let tmp_idx = tempDecl("vector<size_t>", &varDecls /*BUFD*/)
let &preExp += '<%tmp_shape%>.push_back(1);<%\n%>
<%tmp_indeces%>.push_back(<%tmp_idx%>);<%\n%>'
''
case SLICE(__) then
let tmp_index = tempDecl("vector<size_t>", &varDecls /*BUFD*/)
let tmp_idx = tempDecl("vector<size_t>", &varDecls /*BUFD*/)
let expPart = daeExp(exp, context, &preExp /*BUFC*/, &varDecls /*BUFD*/,simCode)
let &preExp += '<%tmp_index%>.assign(<%expPart%>.data(),<%expPart%>.data()+<%expPart%>.num_elements());<%\n%>
<%tmp%>.push_back(<%tmp_index%>);<%\n%>'
let &preExp += '<%tmp_idx%>.assign(<%expPart%>.data(),<%expPart%>.data()+<%expPart%>.num_elements());<%\n%>
<%tmp_shape%>.push_back(<%expPart%>.shape()[0]);<%\n%>
<%tmp_indeces%>.push_back(<%tmp_idx%>);<%\n%>'
''
;separator="\n ")
tmp
<< make_pair(<%tmp_shape%>,<%tmp_indeces%>) >>
end daeExpCrefRhsIndexSpec;


Expand Down
7 changes: 7 additions & 0 deletions SimulationRuntime/cpp/Core/Math/ArrayOperations.cpp
Expand Up @@ -8,3 +8,10 @@ using namespace std;
//{
// fprintf(stdout, "Range check failed for Array please check indices \n" );
//}
size_t getNextIndex(vector<size_t> idx,size_t k)
{
if((idx.size()-1)<k)
return idx.back();
else
return idx[k];
}
9 changes: 8 additions & 1 deletion SimulationRuntime/cpp/Core/Math/stdafx.h
Expand Up @@ -11,4 +11,11 @@
//typedef ublas::vector<double, adaptor_t> shared_vector_t;
//typedef ublas::matrix<double, adaptor_t> shared_matrix_t;
#include <vector>
using std::vector;
#include "boost/tuple/tuple.hpp"
#include <boost/array.hpp>
using std::vector;
using boost::tuple;
using boost::tie;
using boost::get;
using boost::make_tuple;
using boost::array;
116 changes: 85 additions & 31 deletions SimulationRuntime/cpp/Include/Core/Math/ArrayOperations.h
Expand Up @@ -35,8 +35,12 @@ using namespace boost::numeric;
using boost::multi_array;
using boost::const_multi_array_ref;
using boost::multi_array_ref;
/*index type for multi array, first shape, second indeces*/
typedef std::vector<std::vector<size_t> > idx_type;
typedef std::pair<vector<size_t>,idx_type > spec_type;


size_t getNextIndex(vector<size_t> idx,size_t k);

/**
Operation class which performs the array operation *,/
Expand Down Expand Up @@ -82,8 +86,7 @@ Helper function for subtract_array,add_array, copies array a used as return valu
template<
typename T,size_t NumDims, class F
>
boost::multi_array< T, NumDims > op_cp_array
( boost::multi_array_ref< T, NumDims > a, boost::multi_array_ref< T, NumDims > b, F f )
boost::multi_array< T, NumDims > op_cp_array( boost::multi_array_ref< T, NumDims > a, boost::multi_array_ref< T, NumDims > b, F f )
{
boost::multi_array< T, NumDims > retVal( a );
return array_operation( retVal, a, b, Operation2< T, F >( f ) );
Expand All @@ -103,7 +106,7 @@ boost::multi_array< T, NumDims > multiply_array( boost::multi_array_ref< T, NumD
Divides an array with a scalar value (a type as template parameter)
*/
template < typename T, size_t NumDims >
boost::multi_array< T, NumDims > divide_array( boost::multi_array_ref< T, NumDims > &a, const T &b )
boost::multi_array< T, NumDims > divide_array( boost::multi_array_ref< T, NumDims > a, const T &b )
{
return op_cp_array<T>( a, std::bind2nd( std::divides< T >(), b ) );
};
Expand Down Expand Up @@ -169,7 +172,7 @@ Applies array operation F (*,/) on array
*/

template< typename T, size_t dims, class F >
boost::multi_array_ref< T, dims > array_operation( boost::multi_array< T, dims > a, boost::multi_array_ref< T, dims > b, F& op )
boost::multi_array< T, dims > array_operation( boost::multi_array_ref< T, dims > a, boost::multi_array_ref< T, dims > b, F& op )
{
typename boost::multi_array_ref< T, dims >::iterator j = b.begin();
for ( typename boost::multi_array< T, dims >::iterator i = a.begin();
Expand All @@ -185,7 +188,8 @@ Applies array operation F (*,/) on one dimensional array
template<
typename T, class F
>
boost::multi_array< T, 1 > array_operation( boost::multi_array< T, 1 > a, boost::multi_array_ref< T, 1 > b, F& op )

boost::multi_array< T, 1 > array_operation( boost::multi_array_ref< T, 1 > a, boost::multi_array_ref< T, 1 > b, F& op )
{
typename boost::multi_array_ref< T, 1 >::iterator j = b.begin();
for ( typename boost::multi_array< T, 1 >::iterator i = a.begin();
Expand Down Expand Up @@ -245,7 +249,7 @@ Applies array operation F (+,-) on array

template<
typename T, class F >
boost::multi_array< T, 1 > &array_operation( boost::multi_array< T, 1 > &a, boost::multi_array_ref< T, 1 > b, boost::multi_array_ref< T, 1 > c, F op )
boost::multi_array< T, 1 > array_operation( boost::multi_array< T, 1 > &a, boost::multi_array_ref< T, 1 > b, boost::multi_array_ref< T, 1 > c, F op )
{
typename boost::multi_array_ref< T, 1 >::iterator j = b.begin();
typename boost::multi_array_ref< T, 1 >::iterator k = c.begin();
Expand Down Expand Up @@ -275,7 +279,7 @@ Applies array operation F (+,-) on array

template<
typename T, size_t dims, class F >
boost::multi_array< T, dims > &array_operation( boost::multi_array< T, dims > &a, boost::multi_array_ref< T, dims > b, boost::multi_array_ref< T, dims > c, F op )
boost::multi_array< T, dims > array_operation( boost::multi_array_ref< T, dims > a, boost::multi_array_ref< T, dims > b, boost::multi_array_ref< T, dims > c, F op )
{
typename boost::multi_array_ref< T, dims >::iterator j = b.begin();
typename boost::multi_array_ref< T, dims >::iterator k = c.begin();
Expand Down Expand Up @@ -427,38 +431,70 @@ void transpose_array (boost::multi_array< T, 2 >& a, boost::multi_array< T, 2 >
a.assign( data, data + a.num_elements() );

}

template < typename T , size_t NumDims, size_t NumDims2 >
void create_array_from_shape(const vector<vector<size_t> >& sp,boost::multi_array< T, NumDims >& s,boost::multi_array< T, NumDims2 >& d)
/*
creates an array (d) for passed multi array shape (sp) and initialized it with elements from passed source array (s)
s source array
d destination array
sp (shape,indices) of source array
*/
template < typename T , size_t NumDims, size_t NumDims2>
void create_array_from_shape(const spec_type& sp,boost::multi_array< T, NumDims >& s,boost::multi_array< T, NumDims2 >& d)
{
vector<size_t> shape;
vector<vector<size_t> >::const_iterator iter;
vector<size_t>::const_iterator index_iter;
for(iter = sp.begin();iter!=sp.end();++iter)
//alocate target array
vector<size_t> shape;
vector<size_t>::const_iterator iter;
for(iter = (sp.first).begin();iter!=(sp.first).end();++iter)
{
if((iter->size())!=0)
shape.push_back(iter->size());
if(*iter!=0)
shape.push_back(*iter);

}
d.resize(shape);
d.reindex(1);
T* data = new T[d.num_elements()];
int i = 0;
T* source_data = s.data();
for(iter = sp.begin();iter!=sp.end();++iter)
//Check if the dimension of passed indices match the dimension of target array
if(sp.second.size()!=s.num_dimensions())
throw std::invalid_argument("Erro in create array from shape, number of dimensions does not match");

T* data = new T[d.num_elements()];

idx_type::const_iterator spec_iter;
//calc number of indeces
size_t n =1;
for(spec_iter = sp.second.begin();spec_iter!=sp.second.end();++spec_iter)
{
for(index_iter = iter->begin();index_iter!=iter->end();++index_iter)
{
unsigned int index = *index_iter -1;
data[i] = source_data[index];
i++;
}

}

d.assign( data, data + d.num_elements() );
n*=spec_iter->size();
}
size_t k =0;
size_t index=0;
vector<size_t>::const_iterator indeces_iter;

//initialize target array with elements of source array using passed indices
vector<size_t> idx;
for(int i=0;i<n;i++)
{
spec_iter = sp.second.begin();
for(int dim=0;dim<s.num_dimensions();dim++)
{
size_t idx1 = getNextIndex(*spec_iter,i);
idx.push_back(idx1);
spec_iter++;
}
if(index>(d.num_elements()-1))
{
throw std::invalid_argument("Erro in create array from shape, number of dimensions does not match");
}
data[index] = s(idx);
idx.clear();
index++;
}
//assign elemets to target array
d.assign( data, data + d.num_elements() );
delete [] data;
}
}





template < typename T , size_t NumDims, size_t NumDims2 >
Expand All @@ -471,7 +507,7 @@ void promote_array(unsigned int n,boost::multi_array< T, NumDims >& s,boost::mul
ex.push_back(1);
d.resize(ex);
T* data = s.data();
d.assign( data, data + d.num_elements() );
d.assign( data, data + s.num_elements() );
}

/**
Expand Down Expand Up @@ -515,3 +551,21 @@ toVector(const size_t size, T * data)
v(size,ublas::shallow_array_adaptor<T>(size,data));
return v;
}


template <typename Array>
inline void print_array(std::ostream& os, const Array& A)
{
typename Array::const_iterator i;
os << "[";
for (i = A.begin(); i != A.end(); ++i) {
print_array(os, *i);
if (boost::next(i) != A.end())
os << ',';
}
os << "]";
}
inline void print_array(std::ostream& os, const double& x)
{
os << x;
}
1 change: 1 addition & 0 deletions SimulationRuntime/cpp/Include/Core/Modelica.h
Expand Up @@ -72,6 +72,7 @@ using boost::tie;
using boost::get;
using boost::make_tuple;
using boost::multi_array;
using boost::array;
using std::max;
using std::min;
using std::string;
Expand Down

0 comments on commit f0a2ed8

Please sign in to comment.