Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixing assignment between Array<TinyVector> and TinyVector expression #109

Open
wants to merge 5 commits into
base: main
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
8 changes: 8 additions & 0 deletions blitz/array-impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
#include <boost/serialization/base_object.hpp>
#endif

#include <type_traits>

BZ_NAMESPACE(blitz)

Expand Down Expand Up @@ -2268,6 +2269,13 @@ class Array : public MemoryBlockReference<P_numtype>
isStorageContiguous when operator, is used. \todo We should do
bounds checking, right now we will buffer overrun if the number
of initializers in the list is larger than numElements. */
template <typename T_expr, typename = typename std::enable_if<std::is_convertible<
typename T_expr::T_type, T_numtype>::value>::type>
ListInitializationSwitch<T_array> operator=(const T_expr &expr)
{
return ListInitializationSwitch<T_array>(*this, T_numtype(expr));
}

ListInitializationSwitch<T_array> operator=(T_numtype x)
{
return ListInitializationSwitch<T_array>(*this, x);
Expand Down
176 changes: 171 additions & 5 deletions blitz/array/expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,168 @@ BZ_NAMESPACE(blitz)
#define BZ_MAX(a,b) (a)>(b) ? (a) : (b)
#define BZ_MIN(a,b) (a)<(b) ? (a) : (b)

//NOTE: These template structures make to choose type of result binary operation between left and right side
//TODO: It's necessary to consider the cases of expressions with ArrayIndexMapping and/or IndexPlaceholder

template <typename T_expr1, typename T_expr2> struct TypeSwitch { typedef void Type; };

template <typename T_expr1, typename T_expr2, int N_rows1, int N_rows2, int N_columns1, int N_columns2>
struct TypeSwitch<TinyMatrix<T_expr1, N_rows1, N_columns1>, TinyMatrix<T_expr2, N_rows2, N_columns2> > {
typedef void Type;
};

template <typename T_expr1, typename T_expr2, int N_rows, int N_columns, int N_length>
struct TypeSwitch<TinyMatrix<T_expr1, N_rows, N_columns>, TinyVector<T_expr2, N_length> > {
typedef void Type;
};

template <typename T_expr1, typename T_expr2, int N_rows, int N_columns, int N_length>
struct TypeSwitch<TinyVector<T_expr2, N_length>, TinyMatrix<T_expr1, N_rows, N_columns> > {
typedef void Type;
};

template <typename T_expr1, typename T_expr2, int N_length1, int N_length2>
struct TypeSwitch<TinyVector<T_expr1, N_length1>, TinyVector<T_expr2, N_length2> > {
typedef void Type;
};

//TinyMatrix:

template <typename T_expr1, typename T_expr2, int N_rows, int N_columns, int N_rank>
struct TypeSwitch<TinyMatrix<T_expr1, N_rows, N_columns>, Array<TinyMatrix<T_expr2, N_rows, N_columns>, N_rank> > {
typedef Array<TinyMatrix<T_expr2, N_rows, N_columns>, N_rank> Type;
};

template <typename T_expr1, typename T_expr2, int N_rows, int N_columns, int N_rank>
struct TypeSwitch<Array<TinyMatrix<T_expr1, N_rows, N_columns>, N_rank>, TinyMatrix<T_expr2, N_rows, N_columns> > {
typedef Array<TinyMatrix<T_expr1, N_rows, N_columns>, N_rank> Type;
};

template <typename T_expr1, typename T_expr2, int N_rows, int N_columns>
struct TypeSwitch<TinyMatrix<T_expr1, N_rows, N_columns>, TinyMatrix<T_expr2, N_rows, N_columns> > {
typedef TinyMatrix<T_expr1, N_rows, N_columns> Type;
};

template <typename T_expr1, typename T_expr2, int N_rows, int N_columns>
struct TypeSwitch<T_expr1, TinyMatrix<T_expr2, N_rows, N_columns> > {
typedef TinyMatrix<T_expr2, N_rows, N_columns> Type;
};

template <typename T_expr1, typename T_expr2, int N_rows, int N_columns>
struct TypeSwitch<TinyMatrix<T_expr1, N_rows, N_columns>, T_expr2> {
typedef TinyMatrix<T_expr1, N_rows, N_columns> Type;
};

//TinyVector:

template <typename T_expr1, typename T_expr2, int N_length, int N_rank>
struct TypeSwitch<TinyVector<T_expr1, N_length>, Array<TinyVector<T_expr2, N_length>, N_rank> > {
typedef Array<TinyVector<T_expr2, N_length>, N_rank> Type;
};

template <typename T_expr1, typename T_expr2, int N_length, int N_rank>
struct TypeSwitch<Array<TinyVector<T_expr1, N_length>, N_rank>, TinyVector<T_expr2, N_length> > {
typedef Array<TinyVector<T_expr1, N_length>, N_rank> Type;
};

template <typename T_expr1, typename T_expr2, int N_length>
struct TypeSwitch<TinyVector<T_expr1, N_length>, TinyVector<T_expr2, N_length> > {
typedef TinyVector<T_expr1, N_length> Type;
};

template <typename T_expr1, typename T_expr2, int N_length>
struct TypeSwitch<T_expr1, TinyVector<T_expr2, N_length> > {
typedef TinyVector<T_expr2, N_length> Type;
};

template <typename T_expr1, typename T_expr2, int N_length>
struct TypeSwitch<TinyVector<T_expr1, N_length>, T_expr2> {
typedef TinyVector<T_expr1, N_length> Type;
};

//Array:

template <typename T_expr1, typename T_expr2, int N_rank>
struct TypeSwitch<Array<T_expr1, N_rank>, Array<T_expr2, N_rank> > {
typedef Array<T_expr2, N_rank> Type;
};

template <typename T_expr1, typename T_expr2, int N_rank>
struct TypeSwitch<Array<T_expr1, N_rank>, T_expr2> {
typedef Array<T_expr1, N_rank> Type;
};

template <typename T_expr1, typename T_expr2, int N_rank>
struct TypeSwitch<T_expr1, Array<T_expr2, N_rank> > {
typedef Array<T_expr2, N_rank> Type;
};

//NOTE: These template structures define final type of an array expression

template <typename T_expr> struct TypeInfo { typedef T_expr Type; };

template <typename T_expr, int N_rows, int N_columns>
struct TypeInfo<FastTM2CopyIterator<T_expr, N_rows, N_columns> > {
typedef typename FastTM2CopyIterator<T_expr, N_rows, N_columns>::T_matrix Type;
};

template <typename T_expr, int N_rows, int N_columns>
struct TypeInfo<FastTM2Iterator<T_expr, N_rows, N_columns> > {
typedef typename FastTM2Iterator<T_expr, N_rows, N_columns>::T_matrix Type;
};

template <typename T_expr, int N_length>
struct TypeInfo<FastTV2CopyIterator<T_expr, N_length> > {
typedef typename FastTV2CopyIterator<T_expr, N_length>::T_vector Type;
};

template <typename T_expr, int N_length>
struct TypeInfo<FastTV2Iterator<T_expr, N_length> > {
typedef typename FastTV2Iterator<T_expr, N_length>::T_vector Type;
};

template <typename T_expr, int N_rank>
struct TypeInfo<FastArrayCopyIterator<T_expr, N_rank> > {
typedef typename FastArrayCopyIterator<T_expr, N_rank>::T_array Type;
};

template <typename T_expr, int N_rank>
struct TypeInfo<FastArrayIterator<T_expr, N_rank> > {
typedef typename FastArrayIterator<T_expr, N_rank>::T_array Type;
};

template <typename T_expr1, typename T_expr2, typename OP>
struct TypeInfo<_bz_ArrayExprBinaryOp<T_expr1, T_expr2, OP> > {
typedef typename TypeSwitch<
typename TypeInfo<T_expr1>::Type,
typename TypeInfo<T_expr2>::Type
>::Type Type;
};

template <typename T_expr, typename OP>
struct TypeInfo<_bz_ArrayExprUnaryOp<T_expr, OP> > {
typedef
typename TypeInfo<T_expr>::Type
Type;
};

template <typename T_expr>
struct TypeInfo<_bz_ArrayExprConstant<T_expr> > {
typedef
typename TypeInfo<T_expr>::Type
Type;
};

template <typename T_expr>
struct TypeInfo<_bz_ArrayExpr<T_expr> > {
typedef
typename TypeInfo<T_expr>::Type
Type;
};

//...


template<typename T1, typename T2>
class _bz_ExprPair {
public:
Expand Down Expand Up @@ -108,6 +270,7 @@ class _bz_ArrayExpr
{

public:
typedef typename TypeInfo<_bz_ArrayExpr<P_expr> >::Type T_type;
typedef P_expr T_expr;
typedef _bz_typename T_expr::T_numtype T_numtype;
// select return type
Expand Down Expand Up @@ -500,6 +663,7 @@ class _bz_ArrayExpr
template<typename P_expr, typename P_op>
class _bz_ArrayExprUnaryOp {
public:
typedef typename TypeInfo<_bz_ArrayExprUnaryOp<P_expr, P_op> >::Type T_type;
typedef P_expr T_expr;
typedef P_op T_op;
typedef _bz_typename T_expr::T_numtype T_numtype1;
Expand Down Expand Up @@ -775,6 +939,7 @@ class _bz_ArrayExprUnaryOp {
template<typename P_expr1, typename P_expr2, typename P_op>
class _bz_ArrayExprBinaryOp {
public:
typedef typename TypeInfo<_bz_ArrayExprBinaryOp<P_expr1, P_expr2, P_op> >::Type T_type;
typedef P_expr1 T_expr1;
typedef P_expr2 T_expr2;
typedef P_op T_op;
Expand Down Expand Up @@ -1976,14 +2141,15 @@ class _bz_ArrayExprQuaternaryOp {
template<typename P_numtype>
class _bz_ArrayExprConstant {
public:
typedef typename TypeInfo<_bz_ArrayExprConstant<P_numtype> >::Type T_type;
typedef P_numtype T_numtype;
typedef typename opType<T_numtype>::T_optype T_optype;
typedef typename asET<T_numtype>::T_wrapped T_typeprop;
typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
typedef typename opType<T_numtype>::T_optype T_optype;
typedef typename asET<T_numtype>::T_wrapped T_typeprop;
typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;

typedef T_numtype T_ctorArg1;
typedef int T_ctorArg2; // dummy
typedef _bz_ArrayExprConstant<P_numtype> T_range_result;
typedef _bz_ArrayExprConstant<P_numtype> T_range_result;
static const int
numArrayOperands = 0,
numTVOperands = 0,
Expand All @@ -1996,7 +2162,7 @@ class _bz_ArrayExprConstant {
/** For the purpose of vectorizing across the container (as opposed
to for operating on multicomponent types), a constant is always
a constant. */
template<int N> struct tvresult {
template<int N> struct tvresult {
typedef _bz_ArrayExprConstant<T_numtype> Type;
};

Expand Down
6 changes: 5 additions & 1 deletion blitz/array/ops.cc
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,11 @@ Array<P_numtype, N_rank>& Array<P_numtype,N_rank>::initialize(T_numtype x)
// we can't use asExpr here, because if we are initializing an array
// whose components are also ETBase, it would parse as an array
// expression, not as an initialization with a scalar.
(*this) = _bz_ArrayExpr<_bz_ArrayExprConstant<T_numtype> >(x);

//(*this) = _bz_ArrayExpr<_bz_ArrayExprConstant<T_numtype> >(x);
iterator iter, last = end();
for (iter = begin(); iter != last; ++ iter) *iter = x;

return *this;
}

Expand Down
29 changes: 23 additions & 6 deletions blitz/tinymat2.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,13 @@ class TinyMatrix : public ETBase<TinyMatrix<P_numtype, N_rows, N_columns> >
typedef P_numtype T_numtype;
// typedef _bz_tinyMatrixRef<T_numtype, N_rows, N_columns, N_columns, 1>
// T_reference;
typedef TinyVector<int, 2> T_index;
typedef TinyMatrix<T_numtype, N_rows, N_columns> T_matrix;
typedef FastTM2Iterator<T_numtype,N_rows, N_columns> T_iterator;
typedef T_numtype* iterator;
typedef const T_numtype* const_iterator;
typedef FastTM2CopyIterator<P_numtype, N_rows, N_columns> T_range_result;
typedef TinyVector<int, 2> T_index;
typedef TinyMatrix<T_numtype, N_rows, N_columns> T_matrix;
typedef T_matrix T_type;
typedef FastTM2Iterator<T_numtype,N_rows, N_columns> T_iterator;
typedef T_numtype* iterator;
typedef const T_numtype* const_iterator;
typedef FastTM2CopyIterator<P_numtype, N_rows, N_columns> T_range_result;

static const int
//numArrayOperands = 1,
Expand All @@ -94,6 +95,22 @@ class TinyMatrix : public ETBase<TinyMatrix<P_numtype, N_rows, N_columns> >
template <typename T_numtype2>
inline TinyMatrix(const TinyMatrix<T_numtype2, N_rows, N_columns>& x);

/** This constructor creates a TinyMatrix from another ETBase
object. It needs to be explicit to avoid all kinds of
ambiguities. */
template <typename T_expr>
inline explicit TinyMatrix(const ETBase<T_expr>& expr) {
*this = expr; }

/** This constructor creates a TinyMatrix specifically from an
expression. This one we do NOT want to be explicit because that
breaks simple construction assignments like "TinyMatrix<double,
1, 2> v = a+b;", forcing the user to explicitly write it like a
construction. */
template <typename T_expr>
inline TinyMatrix(const _bz_ArrayExpr<T_expr>& expr) {
*this = expr; }

inline TinyMatrix(T_numtype initValue);

static TinyVector<int, 2> base()
Expand Down
13 changes: 7 additions & 6 deletions blitz/tinyvec2.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,13 @@ class TinyVector : public ETBase<TinyVector<P_numtype, N_length> >
// Public Types
//////////////////////////////////////////////

typedef P_numtype T_numtype;
typedef TinyVector<T_numtype,N_length> T_vector;
typedef FastTV2Iterator<T_numtype,N_length> T_iterator;
typedef T_numtype* iterator;
typedef const T_numtype* const_iterator;
typedef FastTV2CopyIterator<P_numtype, N_length> T_range_result;
typedef P_numtype T_numtype;
typedef TinyVector<T_numtype,N_length> T_vector;
typedef T_vector T_type;
typedef FastTV2Iterator<T_numtype,N_length> T_iterator;
typedef T_numtype* iterator;
typedef const T_numtype* const_iterator;
typedef FastTV2CopyIterator<P_numtype, N_length> T_range_result;

static const int
//numArrayOperands = 1,
Expand Down
3 changes: 2 additions & 1 deletion testsuite/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ derrick-bass-1 derrick-bass-3 exprctor expression-slicing extract free \
gary-huber-1 indexexpr-base initialize int-math-func interlace iter \
Josef-Wagenhuber levicivita loop1 matthias-troyer-1 matthias-troyer-2 \
mattias-lindstroem-1 member_function minmax minsumpow module \
multicomponent multicomponent-2 newet Olaf-Ronneberger-1 \
multicomponent multicomponent-1 multicomponent-2 newet Olaf-Ronneberger-1 \
patrik-jonsson-1 peter-bienstman-1 peter-bienstman-2 peter-bienstman-3 \
peter-bienstman-4 peter-bienstman-5 peter-nordlund-1 peter-nordlund-2 \
peter-nordlund-3 preexisting promote pthread qcd reduce reindex \
Expand Down Expand Up @@ -73,6 +73,7 @@ minmax_SOURCES = minmax.cpp
minsumpow_SOURCES = minsumpow.cpp
module_SOURCES = module1.cpp module2.cpp
multicomponent_SOURCES = multicomponent.cpp
multicomponent_1_SOURCES = multicomponent-1.cpp
multicomponent_2_SOURCES = multicomponent-2.cpp
newet_SOURCES = newet.cpp
Olaf_Ronneberger_1_SOURCES = Olaf-Ronneberger-1.cpp
Expand Down
Loading