1dim operation test + corresponding fixes
This commit is contained in:
parent
42a8acbc6e
commit
4f1ebb9986
17 changed files with 306 additions and 1271 deletions
|
@ -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
|
|
@ -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
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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); }
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
@ -155,17 +184,27 @@ namespace CNORXZ
|
|||
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>>
|
||||
{
|
||||
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>
|
||||
|
|
|
@ -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{});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
3
src/include/operation/operation.cc.h
Normal file
3
src/include/operation/operation.cc.h
Normal file
|
@ -0,0 +1,3 @@
|
|||
|
||||
#include "op_types.cc.h"
|
||||
#include "op_utility.cc.h"
|
5
src/include/operation/operation.h
Normal file
5
src/include/operation/operation.h
Normal file
|
@ -0,0 +1,5 @@
|
|||
|
||||
#include "op_types.h"
|
||||
#include "op_utility.h"
|
||||
|
||||
#include "operation.cc.h"
|
|
@ -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
|
|
@ -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
|
|
@ -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)
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
namespace
|
||||
{
|
||||
using namespace CNORXZ;
|
||||
using Test::Numbers;
|
||||
|
||||
class DA_1D_Test : public ::testing::Test
|
||||
{
|
||||
|
@ -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);
|
||||
|
|
105
src/tests/operation_unit_test.cc
Normal file
105
src/tests/operation_unit_test.cc
Normal 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]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue