1dim operation test + corresponding fixes

This commit is contained in:
Christian Zimmermann 2022-11-27 00:27:34 +01:00
parent 42a8acbc6e
commit 4f1ebb9986
17 changed files with 306 additions and 1271 deletions

View file

@ -1,198 +0,0 @@
#include "dynamic_operation.h"
#include "helper_tools.h"
namespace CNORXZ
{
template <typename T, class Operation>
T DynamicOperation<T,Operation>::get(const DExtT& pos) const
{
return mOp.get(pos.expl<ET>());
}
template <typename T, class Operation>
DynamicOperationBase<T>& DynamicOperation<T,Operation>::set(const DExtT& pos)
{
mOp.set(pos.expl<ET>());
return *this;
}
template <typename T, class Operation>
DExtT DynamicOperation<T,Operation>::rootSteps(std::intptr_t iPtrNum) const
{
return DExtT(mkDExt(mkExtT(mOp.rootSteps(iPtrNum))),None(0));
}
template <typename T, class Operation>
DynamicExpression DynamicOperation<T,Operation>::loop(const DynamicExpression& exp) const
{
return mOp.loop(exp);
}
template <typename T, class Operation>
const T* DynamicOperation<T,Operation>::data() const
{
return mOp.data();
}
template <typename T, class Operation>
std::shared_ptr<DynamicOperationBase<T>> DynamicOperation<T,Operation>::deepCopy() const
{
return std::make_shared<DynamicOperation<T,Operation>>(*this);
}
template <typename T, class Operation, class... Ranges>
DynamicOuterOp<T,Operation,Ranges...>::DynamicOuterOp(const DynamicOuterOp& in) :
mThreadId(omp_get_thread_num()), mOp(in.mOp),
mIndices(in.mIndices),
mMa((mThreadId != in.mThreadId) ? std::make_shared<Array<T,Ranges...>>(*in.mMa) : in.mMa),
mProto((mThreadId != in.mThreadId) ? OperationRoot<T,Ranges...>(*mMa,mIndices) : in.mProto),
mL((mThreadId != in.mThreadId) ?
mkILoop(std::make_tuple(*mProto.mOp,mOp), mIndices,
std::make_tuple(mMa),
std::make_tuple(mProto.mOp->assign( mOp, mkMIndex(mIndices) )),
std::array<size_t,1>({1}), std::array<size_t,1>({0})) :
in.mL)
{*mMa = 0;}
template <typename T, class Operation, class... Ranges>
DynamicOuterOp<T,Operation,Ranges...>::DynamicOuterOp(DynamicOuterOp&& in) :
mThreadId(omp_get_thread_num()), mOp(in.mOp),
mIndices(in.mIndices),
mMa((mThreadId != in.mThreadId) ? std::make_shared<Array<T,Ranges...>>(*in.mMa) : in.mMa),
mProto((mThreadId != in.mThreadId) ? OperationRoot<T,Ranges...>(*mMa,mIndices) : in.mProto),
mL((mThreadId != in.mThreadId) ?
mkILoop(std::make_tuple(*mProto.mOp,mOp), mIndices,
std::make_tuple(mMa),
std::make_tuple(mProto.mOp->assign( mOp, mkMIndex(mIndices) )),
std::array<size_t,1>({1}), std::array<size_t,1>({0})) :
in.mL)
{*mMa = 0;}
template <typename T, class Operation, class... Ranges>
DynamicOuterOp<T,Operation,Ranges...>&
DynamicOuterOp<T,Operation,Ranges...>::operator=(const DynamicOuterOp& in)
{
mThreadId = omp_get_thread_num();
mOp = in.mOp;
mIndices = in.mIndices;
if(mThreadId != in.mThreadId){
mMa = std::make_shared<Array<T,Ranges...>>(in.mMa);
mProto = OperationRoot<T,Ranges...>(*mMa,mIndices);
mL = mkILoop(std::make_tuple(*mProto.mOp,mOp), mIndices,
std::make_tuple(mMa),
std::make_tuple(mProto.mOp->assign( mOp, mkMIndex(mIndices) )),
std::array<size_t,1>({1}), std::array<size_t,1>({0}));
}
else {
mMa = in.mMa;
mProto = in.mProto;
mL = in.mL;
}
*mMa = 0;
return *this;
}
template <typename T, class Operation, class... Ranges>
DynamicOuterOp<T,Operation,Ranges...>&
DynamicOuterOp<T,Operation,Ranges...>::operator=(DynamicOuterOp&& in)
{
mThreadId = omp_get_thread_num();
mOp = in.mOp;
mIndices = in.mIndices;
if(mThreadId != in.mThreadId){
mMa = std::make_shared<Array<T,Ranges...>>(in.mMa);
mProto = OperationRoot<T,Ranges...>(*mMa,mIndices);
mL = mkILoop(std::make_tuple(*mProto.mOp,mOp), mIndices,
std::make_tuple(mMa),
std::make_tuple(mProto.mOp->assign( mOp, mkMIndex(mIndices) )),
std::array<size_t,1>({1}), std::array<size_t,1>({0}));
}
else {
mMa = in.mMa;
mProto = in.mProto;
mL = in.mL;
}
*mMa = 0;
return *this;
}
template <typename T, class Operation, class... Ranges>
DynamicOuterOp<T,Operation,Ranges...>::DynamicOuterOp(const Operation& op,
const std::shared_ptr<typename Ranges::IndexType>&... inds)
: mThreadId(omp_get_thread_num()), mOp(op),
mIndices(inds...),
mMa(std::make_shared<Array<T,Ranges...>>(mkArray<T>(inds->range()...))),
mProto(OperationRoot<T,Ranges...>(*mMa,inds...)),
mL(std::make_tuple(*mProto.mOp,mOp), std::make_tuple(inds...),
std::make_tuple(mMa), std::make_tuple(mProto.mOp->assign( mOp, mkMIndex(inds...) )),
std::array<size_t,1>({1}), std::array<size_t,1>({0}))
{}
/*
DynamicOuterOp(const std::shared_ptr<DynamicOperationBase<OpH<OperationRoot<typename Operatrion::value_type,Ranges...>>>>& dyn,
const Operation& op, const std::shared_ptr<Indices>&... inds )
: mThreadId(omp_get_thread_num()),
//mDyn(dyn),
mOp(op), mIndices(inds...),
mMa(std::make_shared<Array<T,Ranges...>>(mkArray<T>(inds->range()...))),
mProto(OperationRoot<T,Ranges...>(*mMa,inds...)),
mL(std::make_tuple(*mProto.mOp,mOp), std::make_tuple(inds...),
std::make_tuple(mMa), std::make_tuple(mProto.mOp->assign( mOp, mkMIndex(inds...) )),
std::array<size_t,1>({1}), std::array<size_t,1>({0}))
{}
*/
template <typename T, class Operation, class... Ranges>
OpH<OperationRoot<T,Ranges...>> DynamicOuterOp<T,Operation,Ranges...>::get(const DExtT& pos) const
{
//if(mPrev) mPrev.get(pos.expl<ET>());
mL(0,pos.expl<ET>());
return mProto; // empty
}
template <typename T, class Operation, class... Ranges>
DynamicOperationBase<OpH<OperationRoot<T,Ranges...>>>&
DynamicOuterOp<T,Operation,Ranges...>::set(const DExtT& pos)
{
mOp.set(pos.expl<ET>());
return *this;
}
template <typename T, class Operation, class... Ranges>
DExtT DynamicOuterOp<T,Operation,Ranges...>::rootSteps(std::intptr_t iPtrNum) const
{
return DExtT(mkDExt(mkExtT(mL.rootSteps(iPtrNum))),None(0));
}
template <typename T, class Operation, class... Ranges>
DynamicExpression DynamicOuterOp<T,Operation,Ranges...>::loop(const DynamicExpression& exp) const
{
return mOp.loop(exp); // ???!!
}
template <typename T, class Operation, class... Ranges>
const OpH<OperationRoot<T,Ranges...>>* DynamicOuterOp<T,Operation,Ranges...>::data() const
{
return &mProto;
}
/*
template <class Op1, class Op2>
template <class ET>
inline T TwoOp<Op1,Op2>::get(const ET& pos) const
{
return mOp2.get(pos);
}
*/
template <typename T, class Operation, class... Ranges>
std::shared_ptr<DynamicOperationBase<OpH<OperationRoot<T,Ranges...>>>>
DynamicOuterOp<T,Operation,Ranges...>::deepCopy() const
{
return std::make_shared<DynamicOuterOp<T,Operation,Ranges...>>(*this);
}
} // namespace CNORXZ

View file

@ -1,209 +0,0 @@
#ifndef __cxz_dynamic_operation_h__
#define __cxz_dynamic_operation_h__
#include "base_def.h"
#include "cxz_operation.h"
namespace CNORXZ
{
template <typename T>
class DynamicOperationBase : public OperationTemplate<T,DynamicOperationBase<T>>
{
public:
typedef T value_type;
typedef OperationBase<T,DynamicOperationBase<T>> OT;
static constexpr size_t SIZE = 1;
static constexpr bool CONT = true;
static constexpr bool VABLE = false;
DynamicOperationBase() = default;
DynamicOperationBase(const DynamicOperationBase& in) = default;
DynamicOperationBase(DynamicOperationBase&& in) = default;
DynamicOperationBase& operator=(const DynamicOperationBase& in) = default;
DynamicOperationBase& operator=(DynamicOperationBase&& in) = default;
virtual T get(const DExtT& pos) const = 0;
virtual DynamicOperationBase& set(const DExtT& pos) = 0;
virtual DExtT rootSteps(std::intptr_t iPtrNum = 0) const = 0;
virtual DynamicExpression loop(const DynamicExpression& exp) const = 0;
virtual const T* data() const = 0;
virtual std::shared_ptr<DynamicOperationBase<T>> deepCopy() const = 0;
};
template <typename T, class Operation>
class DynamicOperation : public DynamicOperationBase<T>
{
private:
Operation mOp;
public:
typedef decltype(mOp.rootSteps()) ET;
//typedef decltype(std::declval<Operation>().rootSteps()) ET;
DynamicOperation() = default;
DynamicOperation(const DynamicOperation& in) = default;
DynamicOperation(DynamicOperation&& in) = default;
DynamicOperation& operator=(const DynamicOperation& in) = default;
DynamicOperation& operator=(DynamicOperation&& in) = default;
DynamicOperation(const Operation& op) : mOp(op) {}
virtual T get(const DExtT& pos) const override final;
virtual DynamicOperationBase<T>& set(const DExtT& pos) override final;
virtual DExtT rootSteps(std::intptr_t iPtrNum = 0) const override final;
virtual DynamicExpression loop(const DynamicExpression& exp) const override final;
virtual const T* data() const override final;
virtual std::shared_ptr<DynamicOperationBase<T>> deepCopy() const override final;
};
template <class Op>
struct OpH
{
std::shared_ptr<Op> mOp;
OpH(const Op& op) : mOp(std::make_shared<Op>(op)) {}
// overload all operations here ...
};
template <typename T, class Operation, class... Ranges>
class DynamicOuterOp : public DynamicOperationBase<OpH<OperationRoot<T,Ranges...>>>
{
private:
size_t mThreadId;
//std::shared_ptr<DynamicOperationBase<OpH<OperationRoot<T,Ranges...>>>> mDyn;
Operation mOp;
//OperationRoot<T,Ranges...> mProto;
std::tuple<std::shared_ptr<typename Ranges::IndexType>...> mIndices;
std::shared_ptr<Array<T,Ranges...>> mMa;
OpH<OperationRoot<T,Ranges...>> mProto;
typedef ILoop<std::tuple<OperationRoot<T,Ranges...>,Operation>,
std::tuple<std::shared_ptr<typename Ranges::IndexType>...>,
std::tuple<std::shared_ptr<Array<T,Ranges...>>>,
std::tuple<decltype(mProto.mOp->assign( mOp, mkMIndex(std::shared_ptr<typename Ranges::IndexType>()...) ))>> LoopT;
mutable LoopT mL;
public:
typedef decltype(mL.rootSteps()) ET;
//typedef decltype(std::declval<Operation>().rootSteps()) ET;
DynamicOuterOp() : mThreadId(omp_get_thread_num()) {}
DynamicOuterOp(const DynamicOuterOp& in);
DynamicOuterOp(DynamicOuterOp&& in);
DynamicOuterOp& operator=(const DynamicOuterOp& in);
DynamicOuterOp& operator=(DynamicOuterOp&& in);
DynamicOuterOp(const Operation& op, const std::shared_ptr<typename Ranges::IndexType>&... inds);
/*
DynamicOuterOp(const std::shared_ptr<DynamicOperationBase<OpH<OperationRoot<typename Operatrion::value_type,Ranges...>>>>& dyn,
const Operation& op, const std::shared_ptr<Indices>&... inds );
*/
virtual OpH<OperationRoot<T,Ranges...>> get(const DExtT& pos) const override final;
virtual DynamicOperationBase<OpH<OperationRoot<T,Ranges...>>>& set(const DExtT& pos) override final;
virtual DExtT rootSteps(std::intptr_t iPtrNum = 0) const override final;
virtual DynamicExpression loop(const DynamicExpression& exp) const override final;
virtual const OpH<OperationRoot<T,Ranges...>>* data() const override final;
virtual std::shared_ptr<DynamicOperationBase<OpH<OperationRoot<T,Ranges...>>>> deepCopy() const override final;
};
template <typename T>
class DynamicO : public OperationTemplate<T,DynamicO<T>>
{
private:
// NOT THREAD SAFE!!!
std::shared_ptr<DynamicOperationBase<T>> mOp;
public:
typedef T value_type;
typedef OperationBase<T,DynamicO<T>> OT;
static constexpr size_t SIZE = 1;
static constexpr bool CONT = true;
static constexpr bool VABLE = false;
DynamicO() = default;
DynamicO(const DynamicO& in) : mOp(in.mOp ? in.mOp->deepCopy() : nullptr) {}
DynamicO(DynamicO&& in) : mOp(in.mOp ? in.mOp->deepCopy() : nullptr) {}
DynamicO& operator=(const DynamicO& in)
{ mOp = in.mOp ? in.mOp->deepCopy() : nullptr; return *this; }
DynamicO& operator=(DynamicO&& in)
{ mOp = in.mOp ? in.mOp->deepCopy() : nullptr; return *this; }
bool init() const { return mOp != nullptr; }
template <class Op>
DynamicO(const Op& op) : mOp(std::make_shared<DynamicOperation<T,Op>>(op)) {}
DynamicO(const std::shared_ptr<DynamicOperationBase<T>>& op) :
mOp(op) {}
template <class X>
inline T get(const DExtTX<X>& pos) const { return mOp->get(pos.reduce()); }
template <typename V,class X>
inline auto vget(const DExtTX<X>& pos) const
{ return mOp->template vget<V>(pos.reduce()); }
template <class X>
inline DynamicO& set(const DExtTX<X>& pos) { mOp->set(pos.reduce()); return *this; }
inline DExtT rootSteps(std::intptr_t iPtrNum = 0) const { return mOp->rootSteps(iPtrNum); }
inline DynamicExpression loop(const DynamicExpression& exp) const { return mOp->loop(exp); }
inline const T* data() const { return mOp->data(); }
};
/*
template <class Op1>
class TwoOp : public OperationTemplate<typename Op2::value_type,TwoOp<Op1>>
{
private:
Op1 mOp1;
typename Op1::value_type mOp2; // mOp1.data()->mOp
public:
typedef typename Op2::value_type value_type;
typedef value_type T;
TwoOp(const Op1& op1);
template <class ET>
inline T get(const ET& pos) const;
};
*/
template <class Operation, class... Indices>
auto mkDynOutOp(const Operation& op, const std::shared_ptr<Indices>&... inds)
{
return DynamicO<OpH<OperationRoot<typename Operation::value_type,
typename Indices::RangeType...>>>
(DynamicOuterOp<typename Operation::value_type,Operation,
typename Indices::RangeType...>(op, inds...));
}
/*
template <class Operation, class... Indices>
auto mkDynOutOp(const std::shared_ptr<DynamicOperationBase<OpH<OperationRoot<typename Operatrion::value_type,Ranges...>>>>& dyn,
const Operation& op, const std::shared_ptr<Indices>&... inds)
{
return DynamicO<OpH<OperationRoot<typename Operation::value_type,
typename Indices::RangeType...>>>
(DynamicOuterOp<typename Operation::value_type,Operation,
typename Indices::RangeType...>(dyn, op, inds...));
}
*/
// Build plan
/*
template <class Operation>
class OperationBuilder
{
};
*/
} // namespace CNORXZ
#endif

View file

@ -12,7 +12,7 @@ namespace CNORXZ
{
constexpr SizeT N = epos_size<EPosT>::value;
static_assert(N == sizeof...(Is), "got inconsistent index sequence");
return Consecutive<T,N> { args... };
return Consecutive<T,N> { d[pos.template get<Is>().val()]... };
}
template <typename T, class EPosT>
@ -82,7 +82,7 @@ namespace CNORXZ
template <class F, typename... Args, SizeT... Is>
static constexpr decltype(auto) consecFuncI(const F& f, const Args&... args,
std::index_sequence<Is...> is);
std::index_sequence<Is...> is)
{
typedef decltype(consecApply<0>(f, args...)) OType;
constexpr SizeT N = sizeof...(Is);
@ -121,10 +121,10 @@ namespace CNORXZ
}
template <typename T, typename U, SizeT N>
constexpr Consecutive<T,N>&
constexpr decltype(auto)
PlusCC<T,U,N>::aeval(Consecutive<T,N>& o, const Consecutive<U,N>& a)
{
return consecFuncA( [](auto& x, const auto& y) { return x += y; }, a, b );
return consecFuncA( [](auto& x, const auto& y) { return x += y; }, o, a );
}
template <typename T, typename X, SizeT N>
@ -134,15 +134,15 @@ namespace CNORXZ
}
template <typename T, typename X, SizeT N>
constexpr decltype(auto) PlusCX<T,X,N>::eval(const X& a, const Consecutive<U,N>& b)
constexpr decltype(auto) PlusCX<T,X,N>::eval(const X& a, const Consecutive<T,N>& b)
{
return consecFunc( [](const auto& x, const auto& y) { return x + y; }, a, b );
}
template <typename T, typename X, SizeT N>
constexpr Consecutive<T,N>& PlusCX<T,X,N>::aeval(Consecutive<T,N>& o, const X& a)
constexpr decltype(auto) PlusCX<T,X,N>::aeval(Consecutive<T,N>& o, const X& a)
{
return consecFuncA( [](auto& x, const auto& y) { return x += y; }, a, b );
return consecFuncA( [](auto& x, const auto& y) { return x += y; }, o, a );
}
/*******************************
@ -168,15 +168,15 @@ namespace CNORXZ
}
template <typename T, typename U, SizeT N>
constexpr Consecutive<T,N>& MinusCC<T,U,N>::aeval(Consecutive<T,N>& o, const Consecutive<U,N>& a)
constexpr decltype(auto) MinusCC<T,U,N>::aeval(Consecutive<T,N>& o, const Consecutive<U,N>& a)
{
return consecFuncA( [](auto& x, const auto& y) { return x -= y; }, a, b );
return consecFuncA( [](auto& x, const auto& y) { return x -= y; }, o, a );
}
template <typename T, typename X, SizeT N>
constexpr Consecutive<T,N>& MinusCX<T,X,N>::aeval(Consecutive<T,N>& o, const X& a)
constexpr decltype(auto) MinusCX<T,X,N>::aeval(Consecutive<T,N>& o, const X& a)
{
return consecFuncA( [](auto& x, const auto& y) { return x -= y; }, a, b );
return consecFuncA( [](auto& x, const auto& y) { return x -= y; }, o, a );
}
/***********************************
@ -190,7 +190,7 @@ namespace CNORXZ
}
template <typename T, typename X, SizeT N>
constexpr decltype(auto) MultipliesCX<T,U,N>::eval(const Consecutive<T,N>& a, const U& b)
constexpr decltype(auto) MultipliesCX<T,X,N>::eval(const Consecutive<T,N>& a, const X& b)
{
return consecFunc( [](const auto& x, const auto& y) { return x * y; }, a, b );
}
@ -202,15 +202,15 @@ namespace CNORXZ
}
template <typename T, typename U, SizeT N>
constexpr Consecutive<T,N>& MultipliesCC<T,U,N>::aeval(Consecutive<T,N>& o, const Consecutive<U,N>& a)
constexpr decltype(auto) MultipliesCC<T,U,N>::aeval(Consecutive<T,N>& o, const Consecutive<U,N>& a)
{
return consecFuncA( [](const auto& x, const auto& y) { return x *= y; }, a, b );
return consecFuncA( [](const auto& x, const auto& y) { return x *= y; }, o, a );
}
template <typename T, typename X, SizeT N>
constexpr Consecutive<T,N>& MultipliesCX<T,X,N>::eval(Consecutive<T,N>& o, const X& a)
constexpr decltype(auto) MultipliesCX<T,X,N>::aeval(Consecutive<T,N>& o, const X& a)
{
return consecFuncA( [](const auto& x, const auto& y) { return x *= y; }, a, b );
return consecFuncA( [](const auto& x, const auto& y) { return x *= y; }, o, a );
}
/*********************************
@ -236,15 +236,15 @@ namespace CNORXZ
}
template <typename T, typename U, SizeT N>
constexpr Consecutive<T,N>& DividesCC<T,U,N>::aeval(Consecutive<T,N>& o, const Consecutive<U,N>& a)
constexpr decltype(auto) DividesCC<T,U,N>::aeval(Consecutive<T,N>& o, const Consecutive<U,N>& a)
{
return consecFuncA( [](const auto& x, const auto& y) { return x /= y; }, a, b );
return consecFuncA( [](const auto& x, const auto& y) { return x /= y; }, o, a );
}
template <typename T, typename X, SizeT N>
constexpr Consecutive<T,N>& DividesCX<T,X,N>::eval(Consecutive<T,N>& o, const X& a)
constexpr decltype(auto) DividesCX<T,X,N>::aeval(Consecutive<T,N>& o, const X& a)
{
return consecFuncA( [](const auto& x, const auto& y) { return x /= y; }, a, b );
return consecFuncA( [](const auto& x, const auto& y) { return x /= y; }, o, a );
}
}

View file

@ -117,11 +117,11 @@ namespace CNORXZ
template <typename T, typename U, SizeT N>
constexpr Consecutive<T,N>& operator+=(Consecutive<T,N>& o, const Consecutive<U,N>& a)
{ return PlusCC<T,U,N>::aeval(a,b); }
{ return PlusCC<T,U,N>::aeval(o,a); }
template <typename T, typename U, SizeT N>
constexpr Consecutive<T,N>& operator+=(Consecutive<T,N>& o, const U& a)
{ return PlusCX<T,U,N>::aeval(a,b); }
{ return PlusCX<T,U,N>::aeval(o,a); }
/*******************************
* basic operations: minus *
@ -164,11 +164,11 @@ namespace CNORXZ
template <typename T, typename U, SizeT N>
constexpr Consecutive<T,N>& operator-=(Consecutive<T,N>& o, const Consecutive<U,N>& a)
{ return MinusCC<T,U,N>::eval(a,b); }
{ return MinusCC<T,U,N>::eval(o,a); }
template <typename T, typename U, SizeT N>
constexpr Consecutive<T,N>& operator-=(Consecutive<T,N>& o, const U& a)
{ return MinusCX<T,U,N>::eval(a,b); }
{ return MinusCX<T,U,N>::eval(o,a); }
/***********************************
* basic operations: muliplies *
@ -199,23 +199,23 @@ namespace CNORXZ
template <typename T, typename U, SizeT N>
constexpr decltype(auto) operator*(const Consecutive<T,N>& a, const Consecutive<U,N>& b)
{ return MulitpliesCC<T,U,N>::eval(a,b); }
{ return MultipliesCC<T,U,N>::eval(a,b); }
template <typename T, typename U, SizeT N>
constexpr decltype(auto) operator*(const Consecutive<T,N>& a, const U& b)
{ return MulitpliesCX<T,U,N>::eval(a,b); }
{ return MultipliesCX<T,U,N>::eval(a,b); }
template <typename T, typename U, SizeT N>
constexpr decltype(auto) operator*(const T& a, const Consecutive<U,N>& b)
{ return MulitpliesXC<U,T,N>::eval(a,b); }
{ return MultipliesCX<U,T,N>::eval(a,b); }
template <typename T, typename U, SizeT N>
constexpr Consecutive<T,N>& operator*=(Consecutive<T,N>& o, const Consecutive<U,N>& a)
{ return MulitpliesCC<T,U,N>::eval(a,b); }
{ return MultipliesCC<T,U,N>::eval(o,a); }
template <typename T, typename U, SizeT N>
constexpr Consecutive<T,N>& operator*=(Consecutive<T,N>& o, const U& a)
{ return MulitpliesCX<T,U,N>::eval(a,b); }
{ return MultipliesCX<T,U,N>::eval(o,a); }
/*********************************
* basic operations: divides *
@ -258,11 +258,11 @@ namespace CNORXZ
template <typename T, typename U, SizeT N>
constexpr Consecutive<T,N>& operator/=(Consecutive<T,N>& o, const Consecutive<U,N>& a)
{ return DividesCC<T,U,N>::eval(a,b); }
{ return DividesCC<T,U,N>::eval(o,a); }
template <typename T, typename U, SizeT N>
constexpr Consecutive<T,N>& operator/=(Consecutive<T,N>& o, const U& a)
{ return DividesCX<T,U,N>::eval(a,b); }
{ return DividesCX<T,U,N>::eval(o,a); }
}

View file

@ -1,72 +0,0 @@
#include "op_expressions.h"
namespace CNORXZ
{
namespace
{
using namespace CNORXZInternal;
}
/************************
* AssignmentExpr *
************************/
template <OpIndexAff OIA, class ExtType>
inline size_t opIndexResolve(size_t start, ExtType last)
{
if constexpr(OIA == OpIndexAff::EXTERN){
return last.val();
}
if constexpr(OIA == OpIndexAff::TARGET){
return start;
}
return 0;
}
template <typename T, class Func, class AT, class Target, class OpClass, OpIndexAff OIA>
AssignmentExpr<T,Func,AT,Target,OpClass,OIA>::AssignmentExpr(const AccessTemplate<AT>& dataAcc, const Target& tar, const OpClass& sec) :
mTar(tar), mSec(sec), mDataAcc(static_cast<const AT&>(dataAcc)) {}
template <typename T, class Func, class AT, class Target, class OpClass, OpIndexAff OIA>
inline void AssignmentExpr<T,Func,AT,Target,OpClass,OIA>::operator()(size_t start)
{
ExtType last = rootSteps();
last.zero();
// TODO: ask MA container for data (ptr)!!!
mDataAcc.template exec<Func>(opIndexResolve<OIA>(start,last),mSec,last.next());
}
template <typename T, class Func, class AT, class Target, class OpClass, OpIndexAff OIA>
inline void AssignmentExpr<T,Func,AT,Target,OpClass,OIA>::operator()(size_t start, ExtType last)
{
mDataAcc.template exec<Func>(opIndexResolve<OIA>(start,last),mSec,last.next());
}
template <typename T, class Func, class AT, class Target, class OpClass, OpIndexAff OIA>
typename AssignmentExpr<T,Func,AT,Target,OpClass,OIA>::ExtType
AssignmentExpr<T,Func,AT,Target,OpClass,OIA>::rootSteps(std::intptr_t iPtrNum) const
{
return mTar.rootSteps(iPtrNum).extend( mSec.rootSteps(iPtrNum) );
}
template <typename T, class Func, class AT, class Target, class OpClass, OpIndexAff OIA>
inline void AssignmentExpr<T,Func,AT,Target,OpClass,OIA>::operator()(size_t mlast, DExt last)
{
(*this)(mlast, std::dynamic_pointer_cast<ExtT<ExtType>>(last)->ext());
}
template <typename T, class Func, class AT, class Target, class OpClass, OpIndexAff OIA>
inline DExt AssignmentExpr<T,Func,AT,Target,OpClass,OIA>::dRootSteps(std::intptr_t iPtrNum) const
{
return std::make_shared<ExtT<ExtType>>(rootSteps(iPtrNum));
}
template <typename T, class Func, class AT, class Target, class OpClass, OpIndexAff OIA>
inline DExt AssignmentExpr<T,Func,AT,Target,OpClass,OIA>::dExtension() const
{
return nullptr; //???!!!
}
} // namespace CNORXZ

View file

@ -1,59 +0,0 @@
#ifndef __cxz_op_expressions__
#define __cxz_op_expressions__
#include "access.h"
namespace CNORXZ
{
namespace
{
using namespace CNORXZInternal;
}
enum class OpIndexAff {
EXTERN = 0,
TARGET = 1
};
template <typename T, class Func, class AT, class Target, class OpClass, OpIndexAff OIA=OpIndexAff::EXTERN>
class AssignmentExpr : public ExpressionBase
{
private:
AssignmentExpr() = default;
Target mTar;
OpClass mSec;
AT mDataAcc;
public:
static constexpr size_t LAYER = 0;
static constexpr size_t NHLAYER = 0;
static constexpr size_t SIZE = Target::SIZE + OpClass::SIZE;
typedef decltype(mTar.rootSteps(0).extend( mSec.rootSteps(0) )) ExtType;
AssignmentExpr(const AccessTemplate<AT>& dataAcc, const Target& tar, const OpClass& sec);
AssignmentExpr(const AssignmentExpr& in) = default;
AssignmentExpr(AssignmentExpr&& in) = default;
AssignmentExpr& operator=(const AssignmentExpr& in) = default;
AssignmentExpr& operator=(AssignmentExpr&& in) = default;
virtual std::shared_ptr<ExpressionBase> deepCopy() const override final
{
return std::make_shared<AssignmentExpr<T,Func,AT,Target,OpClass,OIA>>(*this);
}
inline void operator()(size_t start = 0);
inline void operator()(size_t start, ExtType last);
auto rootSteps(std::intptr_t iPtrNum = 0) const -> ExtType;
inline void operator()(size_t mlast, DExt last) override final;
inline DExt dRootSteps(std::intptr_t iPtrNum = 0) const override final;
inline DExt dExtension() const override final;
};
} // namespace CNORXZ
#endif

View file

@ -3,9 +3,8 @@
#define __cxz_op_types_cc_h__
#include "op_types.h"
#include "xpr/pos_type.h"
#include "xpr/op_xpr.h"
#include "op_utility.h"
//#include "xpr/xpr.h"
//#include "op_utility.h"
#include "extensions/extensions.h"
namespace CNORXZ
@ -17,14 +16,14 @@ namespace CNORXZ
template <class OpT>
template <class F, class IndexT>
decltype(auto) COpInterface<OpT>::c(F&& f, const Sptr<IndexT>& ind) const
constexpr decltype(auto) COpInterface<OpT>::c(F&& f, const Sptr<IndexT>& ind) const
{
return mkContraction(std::forward<F>(f), THIS(), ind);
}
template <class OpT>
template <class IndexT>
decltype(auto) COpInterface<OpT>::c(const Sptr<IndexT>& ind) const
constexpr decltype(auto) COpInterface<OpT>::c(const Sptr<IndexT>& ind) const
{
return mkContraction([](auto& a, const auto& b) { a += b; },
THIS(), ind);
@ -32,8 +31,7 @@ namespace CNORXZ
template <class OpT>
template <class F, class... Args>
constexpr auto a(F&& f, Args&&... args) const;
decltype(auto) COpInterface<OpT>::o(F&& f, Args&&... args) const
constexpr decltype(auto) COpInterface<OpT>::o(F&& f, Args&&... args) const
{
return Operation<F,OpT,Args...>(std::forward<F>(f), THIS(), args...);
}
@ -45,16 +43,16 @@ namespace CNORXZ
template <class OpT>
template <class IndexT, class F, class... Args>
constexpr decltype(auto) OpInterface<OpT>::ax(const Sptr<IndexT>& ind, F&& f, Args&&... args)
constexpr decltype(auto) OpInterface<OpT>::ax(const Sptr<IndexT>& ind, F&& f, const Args&... args)
{
return ind->ifor( Operation<F,OpT,Args...>(f, THIS(), args...) );
return ind->ifor( Operation<F,OpT,Args...>(f, THIS(), args...), NoF {} );
}
template <class OpT>
template <class IndexT, class F, class... Args>
inline SizeT OpInterface<OpT>::a(const Sptr<IndexT>& ind, F&& f, Arg&&... args)
inline void OpInterface<OpT>::a(const Sptr<IndexT>& ind, F&& f, const Args&... args)
{
return ax(ind, f, args...)();
ax(ind, f, args...)();
}
@ -74,6 +72,14 @@ namespace CNORXZ
mIndex(ind)
{}
template <typename T, class IndexT>
constexpr COpRoot<T,IndexT>& COpRoot<T,IndexT>::init(const T* data, const Sptr<IndexT>& ind)
{
mData = data;
mIndex = ind;
return *this;
}
template <typename T, class IndexT>
template <class PosT>
constexpr decltype(auto) COpRoot<T,IndexT>::operator()(const PosT& pos) const
@ -111,34 +117,81 @@ namespace CNORXZ
****************/
template <typename T, class IndexT>
constexpr OpCont<T,IndexT>::OpCont(const Sptr<Index>& ind) :
constexpr OpCont<T,IndexT>::OpCont(const Sptr<IndexT>& ind) :
mIndex(ind),
mC(mIndex.max())
mC(std::make_shared<Vector<T>>(mIndex->pmax().val()))
{}
template <typename T, class IndexT>
constexpr OpCont<T,IndexT>& OpCont<T,IndexT>::init(const Sptr<IndexT>& ind)
{
mIndex = ind;
if(not mC){
mC = std::make_shared<Vector<T>>(mIndex->pmax().val());
}
else if(mC->size() != mIndex->pmax().val()){
mC->resize(mIndex->pmax().val());
}
return *this;
}
template <typename T, class IndexT>
constexpr OpCont<T,IndexT>& OpCont<T,IndexT>::init(const Sptr<IndexT>& ind,
const Vector<T>& c)
{
init(ind);
CXZ_ASSERT(c.size() == mC->size(),
"size-mismatch: expected " << mC->size() << ", got " << c.size());
std::transform(c.begin(), c.end(), mC->begin(), [](const auto& x) { return x; } );
return *this;
}
template <typename T, class IndexT>
template <class Op>
constexpr OpCont<T,IndexT>& OpCont<T,IndexT>::operator=(const Op& o)
{
OI::a(mIndex, [](auto& a1, const auto& a2) { a1 = a2; }, o);
return *this;
}
template <typename T, class IndexT>
template <class Op>
constexpr OpCont<T,IndexT>& OpCont<T,IndexT>::operator+=(const Op& o)
{
OI::a(mIndex, [](auto& a1, const auto& a2) { a1 += a2; }, o);
return *this;
}
template <typename T, class IndexT>
constexpr OpCont<T,IndexT>& OpCont<T,IndexT>::operator=(const OpCont<T,IndexT>& o)
{
OI::a(mIndex, [](auto& a1, const auto& a2) { a1 = a2; }, o);
return *this;
}
template <typename T, class IndexT>
template <class PosT>
constexpr decltype(auto) OpCont<T,IndexT>::operator()(const PosT& pos) const
{
if constexpr(is_epos_type<PosT>::value){
if constexpr(pos_type_is_consecutive<PosT>::value){
return vreg(mC.data(),pos);
return vreg(mC->data(),pos);
}
else {
// non-consecutive data cannot be directly accessed
// so there is no non-const (write) access!
return vreg(const_cast<const T*>(mData),pos);
return vreg(const_cast<const T*>(mC->data()),pos);
}
}
else {
return mC[pos.val()];
return (*mC)[pos.val()];
}
}
template <typename T, class IndexT>
constexpr decltype(auto) OpCont<T,IndexT>::operator()() const
{
return mC[0];
return (*mC)[0];
}
template <typename T, class IndexT>
@ -151,13 +204,13 @@ namespace CNORXZ
template <typename T, class IndexT>
T* OpCont<T,IndexT>::data()
{
return mC.data();
return mC->data();
}
template <typename T, class IndexT>
const T* OpCont<T,IndexT>::data() const
{
return mC.data();
return mC->data();
}
/****************
@ -165,7 +218,7 @@ namespace CNORXZ
****************/
template <typename T, class IndexT>
constexpr OpRoot<T,IndexT>::OpRoot(MDArrayBase<T>& a, const Sptr<IndexT>& ind);
constexpr OpRoot<T,IndexT>::OpRoot(MDArrayBase<T>& a, const Sptr<IndexT>& ind) :
mData(a.data()),
mIndex(ind)
{}
@ -176,11 +229,19 @@ namespace CNORXZ
mIndex(ind)
{}
template <typename T, class IndexT>
constexpr OpRoot<T,IndexT>& OpRoot<T,IndexT>::init(T* data, const Sptr<IndexT>& ind)
{
mData = data;
mIndex = ind;
return *this;
}
template <typename T, class IndexT>
template <class Op>
constexpr OpRoot<T,IndexT>& OpRoot<T,IndexT>::operator=(const Op& o)
{
a(mInd, [](auto& a, const auto& b) { a = b; }, o)
a(mIndex, [](auto& a, const auto& b) { a = b; }, o);
return *this;
}
@ -188,14 +249,14 @@ namespace CNORXZ
template <class Op>
constexpr OpRoot<T,IndexT>& OpRoot<T,IndexT>::operator+=(const Op& o)
{
a(mInd, [](auto& a, const auto& b) { a += b; }, o)
a(mIndex, [](auto& a, const auto& b) { a += b; }, o);
return *this;
}
template <typename T, class IndexT>
constexpr OpRoot<T,IndexT>& OpRoot<T,IndexT>::operator=(const OpRoot<T,IndexT>& o)
{
a(mInd, [](auto& a, const auto& b) { a = b; }, o)
a(mIndex, [](auto& a, const auto& b) { a = b; }, o);
return *this;
}
@ -242,45 +303,53 @@ namespace CNORXZ
*******************/
template <class F, class... Ops>
Operation<F,Ops...>::Operation(F&& f, Ops&&... ops) :
constexpr Operation<F,Ops...>::Operation(F&& f, const Ops&... ops) :
mOps(ops...),
mF(ff)
mF(std::forward<F>(f))
{}
template <class F, class... Ops>
template <class PosT>
inline decltype(auto) Operation<F,Ops...>::operator()(const PosT& pos) const
constexpr decltype(auto) Operation<F,Ops...>::operator()(const PosT& pos) const
{
return pos_unpack_args(mF, pos, mOps);
}
template <class F, class... Ops>
template <class PosT>
inline decltype(auto) Operation<F,Ops...>::operator()() const
constexpr decltype(auto) Operation<F,Ops...>::operator()() const
{
return exec(std::make_index_sequence<sizeof...(Ops)>{});
}
template <class F, class... Ops>
template <SizeT I>
constexpr decltype(auto) Operation<F,Ops...>::rootSteps(const IndexId<I>& id) const
{
// !!!
return mOps.rootSteps(id);
return rootStepsi(id, std::make_index_sequence<sizeof...(Ops)>{});
}
template <class F, class... Ops>
template <SizeT... Is>
constexpr decltype(auto) Operation<F,Ops...>::exec(std::index_sequence<Is...> is) const
{
return mF( std::get<Is>(mOps)() ... );
}
template <class F, class... Ops>
template <SizeT I, SizeT... Is>
constexpr decltype(auto) Operation<F,Ops...>::rootStepsi(const IndexId<I>& id,
std::index_sequence<Is...> is) const
{
return ( std::get<Is>(mOps).rootSteps(id) << ... );
}
/*********************
* Contraction *
*********************/
template <class CXpr>
Contraction<CXpr>::Contraction(CXpr&& cxpr) :
constexpr Contraction<CXpr>::Contraction(CXpr&& cxpr) :
mCXpr(cxpr)
{}
@ -299,7 +368,7 @@ namespace CNORXZ
template <class CXpr>
template <SizeT I>
constexpr decltype(auto) Contraction<CXpr>::rootSteps(const IndexId<I>& id) const;
constexpr decltype(auto) Contraction<CXpr>::rootSteps(const IndexId<I>& id) const
{
return mCXpr.stepSize(id);
}

View file

@ -4,6 +4,8 @@
#define __cxz_op_types_h__
#include "base/base.h"
#include "xpr/xpr_base.h"
#include "array/darray_base.h"
namespace CNORXZ
{
@ -13,6 +15,7 @@ namespace CNORXZ
class COpInterface : public XprInterface<OpT>
{
public:
constexpr COpInterface() = default;
OpT& THIS() { return static_cast<OpT&>(*this); }
const OpT& THIS() const { return static_cast<const OpT&>(*this); }
@ -34,32 +37,41 @@ namespace CNORXZ
public:
typedef COpInterface<OpT> OI;
constexpr OpInterface() = default;
OpT& THIS() { return static_cast<OpT&>(*this); }
const OpT& THIS() const { return static_cast<const OpT&>(*this); }
template <class IndexT, class F, class... Args>
constexpr decltype(auto) ax(const Sptr<IndexT>& ind, F&& f, Args&&... args);
constexpr decltype(auto) ax(const Sptr<IndexT>& ind, F&& f, const Args&... args);
template <class IndexT, class F, class... Args>
inline SizeT a(const Sptr<IndexT>& ind, F&& f, Args&&... args);
inline void a(const Sptr<IndexT>& ind, F&& f, const Args&... args);
};
template <class T>
struct is_operation
{ static constexpr bool value = std::is_base_of<COpInterface,T>::value };
{ static constexpr bool value = std::is_base_of<COpInterface<T>,T>::value; };
template <class T>
struct is_mutable_operation
{ static constexpr bool value = std::is_base_of<OpInterface,T>::value };
{ static constexpr bool value = std::is_base_of<OpInterface<T>,T>::value; };
template <class T>
struct op_size
{ static constexpr SizeT value = is_operation<T>::value ? 1 : 0; };
template <typename T, class IndexT>
class COpRoot : public COpInterface<COpRoot<T,IndexT>>
{
public:
typedef OpInterface<T,COpRoot<T,IndexT>> OI;
typedef OpInterface<COpRoot<T,IndexT>> OI;
constexpr COpRoot() = default;
constexpr COpRoot(const DArrayBase<T>& a, const Sptr<IndexT>& ind);
constexpr COpRoot(const T* data, const Sptr<IndexT>& ind);
constexpr COpRoot& init(const T* data, const Sptr<IndexT>& ind);
template <class PosT>
constexpr decltype(auto) operator()(const PosT& pos) const;
@ -73,7 +85,7 @@ namespace CNORXZ
private:
const T* mData = nullptr;
Sptr<IndexType> mIndex;
Sptr<IndexT> mIndex;
};
template <typename T, class IndexT>
@ -82,7 +94,19 @@ namespace CNORXZ
public:
typedef OpInterface<OpCont<T,IndexT>> OI;
constexpr OpCont(const Sptr<Index>& ind);
constexpr OpCont() = default;
constexpr OpCont(const Sptr<IndexT>& ind);
constexpr OpCont& init(const Sptr<IndexT>& ind);
constexpr OpCont& init(const Sptr<IndexT>& ind, const Vector<T>& c);
template <class Op>
constexpr OpCont& operator=(const Op& in);
template <class Op>
constexpr OpCont& operator+=(const Op& in);
constexpr OpCont& operator=(const OpCont& in);
template <class PosT>
constexpr decltype(auto) operator()(const PosT& pos) const;
@ -97,7 +121,7 @@ namespace CNORXZ
private:
Sptr<IndexT> mIndex;
Vector<T> mC;
Sptr<Vector<T>> mC;
};
@ -107,8 +131,11 @@ namespace CNORXZ
public:
typedef OpInterface<OpRoot<T,IndexT>> OI;
constexpr OpRoot() = default;
constexpr OpRoot(MDArrayBase<T>& a, const Sptr<IndexT>& ind);
constexpr OpRoot(T* data, const Sptr<IndexT>& ind);
constexpr OpRoot& init(T* data, const Sptr<IndexT>& ind);
template <class Op>
constexpr OpRoot& operator=(const Op& in);
@ -139,9 +166,11 @@ namespace CNORXZ
class Operation : public OpInterface<Operation<F,Ops...>>
{
public:
typedef OpInterface<T,Operation<T,F,Ops...>> OI;
typedef OpInterface<Operation<F,Ops...>> OI;
constexpr Operation(F&& f, Ops&&... ops);
constexpr Operation() = default;
constexpr Operation(F&& f, const Ops&... ops);
template <class PosT>
constexpr decltype(auto) operator()(const PosT& pos) const;
@ -154,11 +183,19 @@ namespace CNORXZ
private:
template <SizeT... Is>
constexpr decltype(auto) exec(std::index_sequence<Is...> is) const;
template <SizeT I, SizeT... Is>
constexpr decltype(auto) rootStepsi(const IndexId<I>& id,
std::index_sequence<Is...> is) const;
Tuple<Ops...> mOps;
F mF;
};
template <class F, class... Ops>
struct op_size<Operation<F,Ops...>>
{ static constexpr SizeT value = sizeof...(Ops); };
template <class CXpr>
class Contraction : public OpInterface<Contraction<CXpr>>
@ -166,6 +203,8 @@ namespace CNORXZ
public:
typedef OpInterface<Contraction<CXpr>> OI;
constexpr Contraction() = default;
constexpr Contraction(CXpr&& cxpr);
template <class PosT>
@ -178,7 +217,6 @@ namespace CNORXZ
private:
CXpr mCXpr;
Sptr<IndexType> mInd;
};
template <class F, class Op, class IndexT>

View file

@ -4,7 +4,7 @@
#include "op_utility.h"
#include "xpr/pos_type.h"
#include "operation/op_type.h"
//#include "operation/op_types.h"
namespace CNORXZ
{
@ -36,7 +36,7 @@ namespace CNORXZ
inline void pos_unpack_args_i(const F& f, const PosT& pos, const OpTuple& args,
OpSizes opsizes, std::index_sequence<Is...> is)
{
f(std::get<Is>(args).get(pos_get<sum_index_sequence<Is>(opsizes)>(pos))...);
f(std::get<Is>(args)(pos_get<sum_index_sequence<Is>(opsizes)>(pos))...);
}
template <class F, class PosT, class... Ops>
@ -44,9 +44,9 @@ namespace CNORXZ
{
static_assert(is_pos_type<PosT>::value, "got non-pos-type");
static_assert((is_operation<Ops>::value and ...), "got non-operation type");
typedef std::make_index_sequence<sizeof...Ops> Idxs;
typedef std::make_index_sequence<sizeof...(Ops)> Idxs;
typedef std::index_sequence<op_size<Ops>::value...> OpSizes;
pos_unpack_args_i(f, pos, args, OpSizes{}, Idx{});
pos_unpack_args_i(f, pos, args, OpSizes{}, Idxs{});
}
}

View file

@ -19,7 +19,6 @@ namespace CNORXZ
template <class F, class PosT, class... Ops>
inline void pos_unpack_args(const F& f, const PosT& pos, const Tuple<Ops...>& args);
}
#endif

View file

@ -0,0 +1,3 @@
#include "op_types.cc.h"
#include "op_utility.cc.h"

View file

@ -0,0 +1,5 @@
#include "op_types.h"
#include "op_utility.h"
#include "operation.cc.h"

View file

@ -1,94 +0,0 @@
#ifndef __cxz_operation_def_h__
#define __cxz_operation_def_h__
#include "cxz_operation.h"
namespace CNORXZ
{
template <typename T, class OperationClass>
auto operator+(const T& a, const OperationBase<T,OperationClass>& b)
-> Operation<T,plus<T>,OperationValue<T>,OperationClass>
{
OperationValue<T> v(a);
return Operation<T,plus<T>,OperationValue<T>,OperationClass>(v, b.THIS());
}
template <typename T, class OperationClass>
auto operator-(const T& a, const OperationBase<T,OperationClass>& b)
-> Operation<T,minus<T>,OperationValue<T>,OperationClass>
{
OperationValue<T> v(a);
return Operation<T,minus<T>,OperationValue<T>,OperationClass>(v, b.THIS());
}
template <typename T, class OperationClass>
auto operator*(const T& a, const OperationBase<T,OperationClass>& b)
-> Operation<T,multiplies<T>,OperationValue<T>,OperationClass>
{
OperationValue<T> v(a);
return Operation<T,multiplies<T>,OperationValue<T>,OperationClass>(v, b.THIS());
}
template <typename T, class OperationClass>
auto operator/(const T& a, const OperationBase<T,OperationClass>& b)
-> Operation<T,divides<T>,OperationValue<T>,OperationClass>
{
OperationValue<T> v(a);
return Operation<T,divides<T>,OperationValue<T>,OperationClass>(v, b.THIS());
}
template <typename T, class OperationClass>
auto operator+(const OperationBase<T,OperationClass>& a, const T& b)
-> Operation<T,plus<T>,OperationClass,OperationValue<T> >
{
OperationValue<T> v(b);
return Operation<T,plus<T>,OperationClass,OperationValue<T> >(a.THIS(), v);
}
template <typename T, class OperationClass>
auto operator-(const OperationBase<T,OperationClass>& a, const T& b)
-> Operation<T,minus<T>,OperationClass,OperationValue<T> >
{
OperationValue<T> v(b);
return Operation<T,minus<T>,OperationClass,OperationValue<T> >(a.THIS(), v);
}
template <typename T, class OperationClass>
auto operator*(const OperationBase<T,OperationClass>& a, const T& b)
-> Operation<T,multiplies<T>,OperationClass,OperationValue<T> >
{
OperationValue<T> v(b);
return Operation<T,multiplies<T>,OperationClass,OperationValue<T> >(a.THIS(), v);
}
template <typename T, class OperationClass>
auto operator/(const OperationBase<T,OperationClass>& a, const T& b)
-> Operation<T,divides<T>,OperationClass,OperationValue<T> >
{
OperationValue<T> v(b);
return Operation<T,divides<T>,OperationClass,OperationValue<T> >(a.THIS(), v);
}
#define regFunc1(fff) template <typename T, class OperationClass> \
auto fff(const OperationBase<T,OperationClass>& a) \
-> Operation<T,x_##fff<T>,OperationClass> { \
return Operation<T,x_##fff<T>,OperationClass>(a.THIS()); }
#include "extensions/math.h"
#undef regFunc1
template <size_t N, typename T, class OperationClass>
auto ipow(const OperationBase<T,OperationClass>& a)
-> Operation<T,x_ipow<N-1>,OperationClass>
{
return Operation<T,x_ipow<N-1>,OperationClass>(a.THIS());
}
}
#endif

View file

@ -1,523 +0,0 @@
#ifndef __cxz_type_operations_h__
#define __cxz_type_operations_h__
#include <cstdlib>
#include <vector>
#include <algorithm>
#include "base_def.h"
#include "mbase_def.h"
#include "statics/static_for.h"
#include <cmath>
namespace CNORXZ
{
namespace
{
using namespace CNORXZInternal;
}
// Array
template <typename T, class... Ranges>
class operate
{
public:
static constexpr bool FISSTATIC = false;
operate(const std::shared_ptr<typename Ranges::IndexType>&... inds) : ituple(inds...) {}
inline auto apply(const Array<T,Ranges...>& ma)
-> OperationRoot<T,Ranges...>
{
return unpack<0,sizeof...(Ranges),0>
( [&](auto i) constexpr { return i+1; },
[&](auto i){ return std::get<i>(ituple); },
[&](auto... args) { return ma(args...); });
}
private:
// this is, why non-static
std::tuple<std::shared_ptr<typename Ranges::IndexType>...> ituple;
};
template <class OperationClass, typename T, class... Ranges>
class OperationTemplate<Array<T,Ranges...>,OperationClass> : public OperationBase<Array<T,Ranges...>,OperationClass>
{
typedef OperationBase<Array<T,Ranges...>,OperationClass> OB;
auto operator()(const std::shared_ptr<typename Ranges::IndexType>&... indices)
-> Operation<OperationRoot<T,Ranges...>,operate<T,Ranges...>,OperationClass>
{
std::shared_ptr<operate<T,Ranges...> > ff(indices...);
return Operation<OperationRoot<T,Ranges...>,operate<T,Ranges...>,OperationClass>(ff, OB::THIS());
}
private:
OperationTemplate() = default;
friend OperationClass;
};
// vector
template <typename T>
class getter
{
private:
size_t mPos;
public:
static constexpr bool FISSTATIC = false;
getter(size_t i) : mPos(i) {}
inline T operator()(const vector<T>& in)
{
return in[mPos];
}
};
template <typename T>
vector<T>& operator+=(vector<T>& a, const vector<T>& b)
{
std::transform(a.begin(), a.end(), b.begin(), a.begin(), std::plus<T>());
return a;
}
template <typename T>
vector<T>& operator-=(vector<T>& a, const vector<T>& b)
{
std::transform(a.begin(), a.end(), b.begin(), a.begin(), std::minus<T>());
return a;
}
template <typename T>
vector<T>& operator*=(vector<T>& a, const vector<T>& b)
{
std::transform(a.begin(), a.end(), b.begin(), a.begin(), std::multiplies<T>());
return a;
}
template <typename T>
vector<T>& operator/=(vector<T>& a, const vector<T>& b)
{
std::transform(a.begin(), a.end(), b.begin(), a.begin(), std::divides<T>());
return a;
}
template <typename T>
vector<T> operator+(vector<T>& a, const vector<T>& b)
{
vector<T> out(a.size());
std::transform(a.begin(), a.end(), b.begin(), out.begin(), std::plus<T>());
return out;
}
template <typename T>
vector<T> operator-(vector<T>& a, const vector<T>& b)
{
vector<T> out(a.size());
std::transform(a.begin(), a.end(), b.begin(), out.begin(), std::minus<T>());
return out;
}
template <typename T>
vector<T> operator*(vector<T>& a, const vector<T>& b)
{
vector<T> out(a.size());
std::transform(a.begin(), a.end(), b.begin(), out.begin(), std::multiplies<T>());
return out;
}
template <typename T>
vector<T> operator/(vector<T>& a, const vector<T>& b)
{
vector<T> out(a.size());
std::transform(a.begin(), a.end(), b.begin(), out.begin(), std::divides<T>());
return out;
}
template <class OperationClass, typename T>
class OperationTemplate<vector<T>,OperationClass> : public OperationBase<vector<T>,OperationClass>
{
public:
typedef OperationBase<vector<T>,OperationClass> OB;
auto operator[](size_t i)
-> Operation<T,getter<T>,OperationClass>
{
std::shared_ptr<getter<T> > ff = std::make_shared<getter<T> >(i);
return Operation<T,getter<T>,OperationClass>(ff,OB::THIS());
}
private:
OperationTemplate() = default;
friend OperationClass;
};
struct v256
{
alignas(32) double _x[4];
};
template <int N>
inline void xadd(double* o, const double* a, const double* b)
{
#pragma omp simd aligned(o, a, b: 32)
for(int i = 0; i < N; i++) {
o[i] = a[i] + b[i];
}
}
template <int N>
inline void x1add(double* o, const double* a, const double& b)
{
#pragma omp simd aligned(o, a: 32)
for(int i = 0; i < N; i++) {
o[i] = a[i] + b;
}
}
template <int N>
inline void x2add(double* o, const double& a, const double* b)
{
#pragma omp simd aligned(o, b: 32)
for(int i = 0; i < N; i++) {
o[i] = a + b[i];
}
}
template <int N>
inline void xsadd(double* o, const double* a)
{
#pragma omp simd aligned(o, a: 32)
for(int i = 0; i < N; i++) {
o[i] += a[i];
}
}
template <int N>
inline void xradd(double& o, const double* a)
{
#pragma omp simd reduction(+: o) aligned(a: 32)
for(int i = 0; i < N; i++) {
o += a[i];
}
}
template <int N>
inline void xsub(double* o, const double* a, const double* b)
{
#pragma omp simd aligned(o, a, b: 32)
for(int i = 0; i < N; i++) {
o[i] = a[i] - b[i];
}
}
template <int N>
inline void xssub(double* o, const double* a)
{
#pragma omp simd aligned(o, a: 32)
for(int i = 0; i < N; i++) {
o[i] -= a[i];
}
}
template <int N>
inline void xrsub(double& o, const double* a)
{
#pragma omp simd reduction(-: o) aligned(a: 32)
for(int i = 0; i < N; i++) {
o -= a[i];
}
}
template <int N>
inline void x1sub(double* o, const double* a, const double& b)
{
#pragma omp simd aligned(o, a: 32)
for(int i = 0; i < N; i++) {
o[i] = a[i] - b;
}
}
template <int N>
inline void x2sub(double* o, const double& a, const double* b)
{
#pragma omp simd aligned(o, b: 32)
for(int i = 0; i < N; i++) {
o[i] = a - b[i];
}
}
template <int N>
inline void xmul(double* o, const double* a, const double* b)
{
#pragma omp simd aligned(o, a, b: 32)
for(int i = 0; i < N; i++) {
o[i] = a[i] * b[i];
}
}
template <int N>
inline void xsmul(double* o, const double* a)
{
#pragma omp simd aligned(o, a: 32)
for(int i = 0; i < N; i++) {
o[i] *= a[i];
}
}
template <int N>
inline void xrmul(double& o, const double* a)
{
#pragma omp simd reduction(*: o) aligned(a: 32)
for(int i = 0; i < N; i++) {
o *= a[i];
}
}
template <int N>
inline void x1mul(double* o, const double* a, const double& b)
{
#pragma omp simd aligned(o, a: 32)
for(int i = 0; i < N; i++) {
o[i] = a[i] * b;
}
}
template <int N>
inline void x2mul(double* o, const double& a, const double* b)
{
#pragma omp simd aligned(o, b: 32)
for(int i = 0; i < N; i++) {
o[i] = a * b[i];
}
}
template <int N>
inline void xdiv(double* o, const double* a, const double* b)
{
#pragma omp simd aligned(o, a, b: 32)
for(int i = 0; i < N; i++) {
o[i] = a[i] / b[i];
}
}
template <int N>
inline void xsdiv(double* o, const double* a)
{
#pragma omp simd aligned(o, a: 32)
for(int i = 0; i < N; i++) {
o[i] /= a[i];
}
}
/*
template <int N>
inline void xrdiv(double& o, const double* a)
{
#pragma omp simd reduction(/: o) aligned(a: 32)
for(int i = 0; i < N; i++) {
o /= a[i];
}
}
*/
template <int N>
inline void x1div(double* o, const double* a, const double& b)
{
#pragma omp simd aligned(o, a: 32)
for(int i = 0; i < N; i++) {
o[i] = a[i] / b;
}
}
template <int N>
inline void x2div(double* o, const double& a, const double* b)
{
#pragma omp simd aligned(o, b: 32)
for(int i = 0; i < N; i++) {
o[i] = a / b[i];
}
}
inline v256 operator+(const v256& a, const v256& b)
{
v256 o;
xadd<4>( o._x, a._x, b._x );
return o;
}
inline v256 operator+(const v256& a, const double& b)
{
v256 o;
x1add<4>( o._x, a._x, b );
return o;
}
inline v256 operator+(const double& a, const v256& b)
{
v256 o;
x2add<4>( o._x, a, b._x );
return o;
}
inline double& operator+=(double& o, const v256& a)
{
xradd<4>( o, a._x );
return o;
}
inline v256& operator+=(v256& o, const v256& a)
{
xsadd<4>( o._x, a._x );
return o;
}
inline v256 operator-(const v256& a, const v256& b)
{
v256 o;
xsub<4>( o._x, a._x, b._x );
return o;
}
inline v256 operator-(const v256& a, const double& b)
{
v256 o;
x1sub<4>( o._x, a._x, b );
return o;
}
inline v256 operator-(const double& a, const v256& b)
{
v256 o;
x2sub<4>( o._x, a, b._x );
return o;
}
inline double& operator-=(double& o, const v256& a)
{
xrsub<4>( o, a._x );
return o;
}
inline v256& operator-=(v256& o, const v256& a)
{
xssub<4>( o._x, a._x );
return o;
}
inline v256 operator*(const v256& a, const v256& b)
{
v256 o;
xmul<4>( o._x, a._x, b._x );
return o;
}
inline v256& operator*=(v256& o, const v256& a)
{
xsmul<4>( o._x, a._x );
return o;
}
inline v256 operator*(const v256& a, const double& b)
{
v256 o;
x1mul<4>( o._x, a._x, b );
return o;
}
inline v256 operator*(const double& a, const v256& b)
{
v256 o;
x2mul<4>( o._x, a, b._x );
return o;
}
inline double& operator*=(double& o, const v256& a)
{
xrmul<4>( o, a._x );
return o;
}
inline v256 operator/(const v256& a, const v256& b)
{
v256 o;
xdiv<4>( o._x, a._x, b._x );
return o;
}
inline v256 operator/(const v256& a, const double& b)
{
v256 o;
x1div<4>( o._x, a._x, b );
return o;
}
inline v256 operator/(const double& a, const v256& b)
{
v256 o;
x2div<4>( o._x, a, b._x );
return o;
}
/*
inline double& operator/=(double& o, const v256& a)
{
xrdiv<4>( o, a._x );
return o;
}
*/
inline v256& operator/=(v256& o, const v256& a)
{
xsdiv<4>( o._x, a._x );
return o;
}
inline double xpow(const double& b, const double& e)
{
return pow(b,e);
}
inline v256 pow(const v256& b, const v256& e)
{
v256 out;
for(int i = 0; i < 4; i++){
out._x[i] = xpow(b._x[i],e._x[i]);
}
return out;
}
inline double xexp(const double& a)
{
return exp(a);
}
inline v256 exp(const v256& a)
{
v256 out;
for(int i = 0; i < 4; i++){
out._x[i] = xexp(a._x[i]);
}
return out;
}
inline double xsqrt(const double& a)
{
return sqrt(a);
}
inline v256 sqrt(const v256& a)
{
v256 out;
for(int i = 0; i < 4; i++){
out._x[i] = xsqrt(a._x[i]);
}
return out;
}
} // namespace CNORXZ
#endif

View file

@ -7,11 +7,6 @@ set(test_SOURCES
add_library(test_lib STATIC ${test_SOURCES})
#add_executable(iutest ranges/index_unit_test.cc)
#add_dependencies(iutest cnorxz)
#target_link_libraries(iutest ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} cnorxz)
#add_test(NAME iutest COMMAND iutest)
add_executable(xprutest xpr_unit_test.cc)
add_dependencies(xprutest cnorxz)
target_link_libraries(xprutest ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} cnorxz test_lib)
@ -22,40 +17,15 @@ add_dependencies(rutest cnorxz)
target_link_libraries(rutest ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} cnorxz test_lib)
add_test(NAME rutest COMMAND rutest)
#add_executable(autest ranges/anonymous_unit_test.cc)
#add_dependencies(autest cnorxz)
#target_link_libraries(autest ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} cnorxz)
#add_test(NAME autest COMMAND autest)
#add_executable(mautest array_unit_test.cc)
#add_dependencies(mautest cnorxz)
#target_link_libraries(mautest ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} cnorxz)
#add_test(NAME mautest COMMAND mautest)
add_executable(dautest darray_unit_test.cc)
add_dependencies(dautest cnorxz)
target_link_libraries(dautest ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} cnorxz test_lib)
add_test(NAME dautest COMMAND dautest)
#add_executable(oputest op_unit_test.cc)
#add_dependencies(oputest cnorxz)
#target_link_libraries(oputest ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} cnorxz)
#add_test(NAME oputest COMMAND oputest)
#add_executable(op2utest op2_unit_test.cc)
#add_dependencies(op2utest cnorxz)
#target_link_libraries(op2utest ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} cnorxz)
#add_test(NAME op2utest COMMAND op2utest)
#add_executable(op3utest op3_unit_test.cc)
#add_dependencies(op3utest cnorxz)
#target_link_libraries(op3utest ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} cnorxz)
#add_test(NAME op3utest COMMAND op3utest)
#add_executable(op4utest op4_unit_test.cc)
#add_dependencies(op4utest cnorxz hlcnorxz)
#target_link_libraries(op4utest ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} cnorxz hlcnorxz)
#add_test(NAME op4utest COMMAND op4utest)
add_executable(oputest operation_unit_test.cc)
add_dependencies(oputest cnorxz)
target_link_libraries(oputest ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} cnorxz test_lib)
add_test(NAME oputest COMMAND oputest)
#add_executable(opptest op_perf_test.cc)
#add_dependencies(opptest cnorxz)

View file

@ -11,7 +11,8 @@
namespace
{
using namespace CNORXZ;
using Test::Numbers;
class DA_1D_Test : public ::testing::Test
{
protected:
@ -46,7 +47,7 @@ namespace
TEST_F(DA_1D_Test, Basics)
{
const DArray<Double> a(mCR1, ::CNORXZ::Test::Numbers::get(0,mSize));
const DArray<Double> a(mCR1, Numbers::get(0,mSize));
auto crx = std::dynamic_pointer_cast<CRange>(mCR1);
EXPECT_EQ(a.size(), mSize);
EXPECT_FALSE(a.isView());
@ -65,7 +66,7 @@ namespace
{
const SizeT ssize = mStrMeta.size();
const SizeT size = mSize * ssize;
const DArray<Double> a(mCR1*mUR1, ::CNORXZ::Test::Numbers::get(0,size));
const DArray<Double> a(mCR1*mUR1, Numbers::get(0,size));
EXPECT_EQ(a.range()->dim(), 2u);
EXPECT_EQ(a.size(), size);
EXPECT_EQ(a.pmax(), size);

View file

@ -0,0 +1,105 @@
#include <cstdlib>
#include <iostream>
#include "gtest/gtest.h"
#include "ranges/ranges.h"
#include "operation/operation.h"
#include "test_numbers.h"
namespace
{
using namespace CNORXZ;
using Test::Numbers;
class OpCont_CR_Test : public ::testing::Test
{
protected:
OpCont_CR_Test()
{
mSize = 7;
const SizeT off = 10;
mData1 = Numbers::get(off, mSize);
mData2 = Numbers::get(off + mSize*2, mSize);
auto cr = CRangeFactory(mSize).create();
mCI1 = std::make_shared<CIndex>(cr);
mCI2 = std::make_shared<CIndex>(cr);
mOp1.init(mCI1);
mOp2.init(mData1.data(), mCI1);
mOp3.init(mCI2);
mOp4.init(mData2.data(), mCI2);
}
SizeT mSize;
Vector<Double> mData1;
Vector<Double> mData2;
Sptr<CIndex> mCI1;
Sptr<CIndex> mCI2;
OpCont<double,CIndex> mOp1;
COpRoot<double,CIndex> mOp2;
OpCont<double,CIndex> mOp3;
COpRoot<double,CIndex> mOp4;
};
TEST_F(OpCont_CR_Test, Basics)
{
EXPECT_EQ(mOp2.data(), mData1.data());
EXPECT_EQ(mOp4.data(), mData2.data());
auto rs11 = mOp1.rootSteps(mCI1->id());
auto rs21 = mOp2.rootSteps(mCI1->id());
auto rs31 = mOp3.rootSteps(mCI1->id());
auto rs41 = mOp4.rootSteps(mCI1->id());
auto rs12 = mOp1.rootSteps(mCI2->id());
auto rs22 = mOp2.rootSteps(mCI2->id());
auto rs32 = mOp3.rootSteps(mCI2->id());
auto rs42 = mOp4.rootSteps(mCI2->id());
EXPECT_EQ(rs11.val(), 1);
EXPECT_EQ(rs21.val(), 1);
EXPECT_EQ(rs31.val(), 0);
EXPECT_EQ(rs41.val(), 0);
EXPECT_EQ(rs12.val(), 0);
EXPECT_EQ(rs22.val(), 0);
EXPECT_EQ(rs32.val(), 1);
EXPECT_EQ(rs42.val(), 1);
}
TEST_F(OpCont_CR_Test, Assignment)
{
mOp1 = mOp2;
mOp3 = mOp4;
for(SizeT i = 0; i != mSize; ++i){
EXPECT_EQ(mOp1.data()[i], mOp2.data()[i]);
EXPECT_EQ(mOp3.data()[i], mOp4.data()[i]);
}
mOp1 = mOp4;
mOp3 = mOp2;
for(SizeT i = 0; i != mSize; ++i){
EXPECT_EQ(mOp1.data()[i], mOp4.data()[0]);
EXPECT_EQ(mOp3.data()[i], mOp2.data()[0]);
}
}
TEST_F(OpCont_CR_Test, PlusAssign)
{
Vector<Double> z(mSize, 0);
mOp1.init(mCI1, z);
mOp3.init(mCI2, z);
mOp1 += mOp2;
mOp3 += mOp4;
for(SizeT i = 0; i != mSize; ++i){
EXPECT_EQ(mOp1.data()[i], mOp2.data()[i]);
EXPECT_EQ(mOp3.data()[i], mOp4.data()[i]);
}
mOp1.init(mCI1, z);
mOp3.init(mCI2, z);
mOp1 = mOp4;
mOp3 = mOp2;
for(SizeT i = 0; i != mSize; ++i){
EXPECT_EQ(mOp1.data()[i], mOp4.data()[0]);
EXPECT_EQ(mOp3.data()[i], mOp2.data()[0]);
}
}
}