This commit is contained in:
Christian Zimmermann 2021-01-23 19:40:15 +01:00
parent 15664781f7
commit 3bacc6c1c4
5 changed files with 173 additions and 97 deletions

View file

@ -82,6 +82,9 @@ namespace MultiArrayTools
virtual std::shared_ptr<ExpressionBase> deepCopy() const override final; virtual std::shared_ptr<ExpressionBase> deepCopy() const override final;
template <size_t VS>
inline auto vec() const { return *this; }
inline void operator()(size_t mlast, DExt last) override final; inline void operator()(size_t mlast, DExt last) override final;
inline void operator()(size_t mlast, ExtType last); inline void operator()(size_t mlast, ExtType last);
inline void operator()(size_t mlast = 0) override final; inline void operator()(size_t mlast = 0) override final;

View file

@ -523,12 +523,12 @@ namespace MultiArrayTools
template <class IOp, class OpClass> template <class IOp, class OpClass>
auto OperationRoot<T,Ranges...>::asx(const OpClass& in) const auto OperationRoot<T,Ranges...>::asx(const OpClass& in) const
-> decltype(mIndex.ifor(1,in.loop(AssignmentExpr<T,IOp,OperationRoot<T,Ranges...>,OpClass,OpIndexAff::TARGET> -> decltype(mIndex.ifor(1,in.loop(AssignmentExpr<T,IOp,OperationRoot<T,Ranges...>,OpClass,OpIndexAff::TARGET>
(mOrigDataPtr,*this,in)))) (mOrigDataPtr,*this,in))).template vec<IOp::VSIZE>())
{ {
static_assert( OpClass::SIZE == decltype(in.rootSteps())::SIZE, "Ext Size mismatch" ); static_assert( OpClass::SIZE == decltype(in.rootSteps())::SIZE, "Ext Size mismatch" );
return mIndex.ifor(1,in.loop(AssignmentExpr<T,IOp,OperationRoot<T,Ranges...>,OpClass,OpIndexAff::TARGET> return mIndex.ifor(1,in.loop(AssignmentExpr<T,IOp,OperationRoot<T,Ranges...>,OpClass,OpIndexAff::TARGET>
(mOrigDataPtr,*this,in))); (mOrigDataPtr,*this,in))).template vec<IOp::VSIZE>();
} }
template <typename T, class... Ranges> template <typename T, class... Ranges>
@ -546,11 +546,11 @@ namespace MultiArrayTools
template <class IOp, class OpClass, class Index> template <class IOp, class OpClass, class Index>
auto OperationRoot<T,Ranges...>::asx(const OpClass& in, const std::shared_ptr<Index>& i) const auto OperationRoot<T,Ranges...>::asx(const OpClass& in, const std::shared_ptr<Index>& i) const
-> decltype(i->ifor(1,in.loop(AssignmentExpr<T,IOp,OperationRoot<T,Ranges...>,OpClass> -> decltype(i->ifor(1,in.loop(AssignmentExpr<T,IOp,OperationRoot<T,Ranges...>,OpClass>
(mOrigDataPtr,*this,in)))) (mOrigDataPtr,*this,in))).template vec<IOp::VSIZE>())
{ {
static_assert( OpClass::SIZE == decltype(in.rootSteps())::SIZE, "Ext Size mismatch" ); static_assert( OpClass::SIZE == decltype(in.rootSteps())::SIZE, "Ext Size mismatch" );
return i->ifor(1,in.loop(AssignmentExpr<T,IOp,OperationRoot<T,Ranges...>,OpClass> return i->ifor(1,in.loop(AssignmentExpr<T,IOp,OperationRoot<T,Ranges...>,OpClass>
(mOrigDataPtr,*this,in))); (mOrigDataPtr,*this,in))).template vec<IOp::VSIZE>();
} }
template <typename T, class... Ranges> template <typename T, class... Ranges>
@ -600,7 +600,8 @@ namespace MultiArrayTools
static inline void exec(TarOp& th, const OpClass& in) static inline void exec(TarOp& th, const OpClass& in)
{ {
typedef typename TarOp::value_type T; typedef typename TarOp::value_type T;
th.template asx<IAccess<F<T>>>(in)(); IAccess<T,F<T>> tmp;
th.template asx<decltype(tmp)>(in)();
} }
}; };
@ -612,14 +613,13 @@ namespace MultiArrayTools
{ {
CHECK; CHECK;
typedef typename TarOp::value_type T; typedef typename TarOp::value_type T;
auto x = th.template asx<IVAccess<typename VType<T>::type,F<T>>>(in); auto x = th.template asx<IVAccess<T,F<T>>>(in);
const size_t inum = x.vec(VType<T>::MULT); if(x.divResid() == 0){
if(x.rootSteps(inum) == 1){
CHECK; CHECK;
x(); x();
} }
else { else {
th.template asx<IAccess<F<T>>>(in)(); th.template asx<IAccess<T,F<T>>>(in)();
} }
} }
}; };

View file

@ -235,24 +235,32 @@ namespace MultiArrayTools
template <class F> template <class F>
using VFunc = decltype(mkVFunc(std::declval<F>())); using VFunc = decltype(mkVFunc(std::declval<F>()));
template <class F> template <typename T, class F>
struct IAccess struct IAccess
{ {
template <typename T, typename Op, class ExtType> typedef T value_type;
typedef T in_type;
static constexpr size_t VSIZE = sizeof(value_type) / sizeof(in_type);
template <typename Op, class ExtType>
static inline void f(T*& t, size_t pos, const Op& op, ExtType e) static inline void f(T*& t, size_t pos, const Op& op, ExtType e)
{ {
F::selfApply(t[pos],op.get(e)); F::selfApply(t[pos],op.get(e));
} }
}; };
template <typename V, class F> template <typename T, class F>
struct IVAccess struct IVAccess
{ {
template <typename T, typename Op, class ExtType> typedef typename VType<T>::type value_type;
typedef T in_type;
static constexpr size_t VSIZE = sizeof(value_type) / sizeof(in_type);
template <typename Op, class ExtType>
static inline void f(T*& t, size_t pos, const Op& op, ExtType e) static inline void f(T*& t, size_t pos, const Op& op, ExtType e)
{ {
VCHECK(pos); VCHECK(pos);
VFunc<F>::selfApply(reinterpret_cast<V*>(t)[pos],op.template vget<V>(e)); VFunc<F>::selfApply(reinterpret_cast<value_type*>(t)[pos],op.template vget<value_type>(e));
} }
}; };
@ -260,16 +268,16 @@ namespace MultiArrayTools
using xxxplus = plus<T>; using xxxplus = plus<T>;
template <typename T> template <typename T>
using IAssign = IAccess<identity<T>>; using IAssign = IAccess<T,identity<T>>;
template <typename T> template <typename T>
using IPlus = IAccess<plus<T>>; using IPlus = IAccess<T,plus<T>>;
template <typename V, typename T> template <typename T>
using IVAssign = IVAccess<V,identity<T>>; using IVAssign = IVAccess<T,identity<T>>;
template <typename V, typename T> template <typename T>
using IVPlus = IVAccess<V,plus<T>>; using IVPlus = IVAccess<T,plus<T>>;
/* /*
struct IAssign struct IAssign
{ {
@ -599,7 +607,7 @@ namespace MultiArrayTools
template <class IOp, class OpClass> template <class IOp, class OpClass>
auto asx(const OpClass& in) const auto asx(const OpClass& in) const
-> decltype(mIndex.ifor(1,in.loop(AssignmentExpr<T,IOp,OperationRoot<T,Ranges...>,OpClass,OpIndexAff::TARGET> -> decltype(mIndex.ifor(1,in.loop(AssignmentExpr<T,IOp,OperationRoot<T,Ranges...>,OpClass,OpIndexAff::TARGET>
(mOrigDataPtr,*this,in)))); (mOrigDataPtr,*this,in))).template vec<IOp::VSIZE>());
template <class IOp, class OpClass> template <class IOp, class OpClass>
auto asxExpr(const OpClass& in) const auto asxExpr(const OpClass& in) const
@ -608,7 +616,7 @@ namespace MultiArrayTools
template <class IOp, class OpClass, class Index> template <class IOp, class OpClass, class Index>
auto asx(const OpClass& in, const std::shared_ptr<Index>& i) const auto asx(const OpClass& in, const std::shared_ptr<Index>& i) const
-> decltype(i->ifor(1,in.loop(AssignmentExpr<T,IOp,OperationRoot<T,Ranges...>,OpClass> -> decltype(i->ifor(1,in.loop(AssignmentExpr<T,IOp,OperationRoot<T,Ranges...>,OpClass>
(mOrigDataPtr,*this,in)))); (mOrigDataPtr,*this,in))).template vec<IOp::VSIZE>());
template <class OpClass> template <class OpClass>
auto assign(const OpClass& in) const auto assign(const OpClass& in) const

View file

@ -10,9 +10,12 @@ namespace MultiArrayHelper
HIDDEN = 1 HIDDEN = 1
}; };
template <class IndexClass, class Expr, ForType FT = ForType::DEFAULT> template <class IndexClass, class Expr, ForType FT = ForType::DEFAULT, size_t DIV = 1>
class For; class For;
template <class IndexClass, class Expr, size_t DIV = 1>
class PFor;
} // end namespace MultiArrayHelper } // end namespace MultiArrayHelper

View file

@ -187,7 +187,7 @@ namespace MultiArrayHelper
ExpressionBase& operator=(const ExpressionBase& in) = default; ExpressionBase& operator=(const ExpressionBase& in) = default;
ExpressionBase& operator=(ExpressionBase&& in) = default; ExpressionBase& operator=(ExpressionBase&& in) = default;
virtual std::intptr_t vec(size_t vs) { return 0; } virtual size_t divResid() const { return 0; }
virtual std::shared_ptr<ExpressionBase> deepCopy() const = 0; virtual std::shared_ptr<ExpressionBase> deepCopy() const = 0;
@ -231,20 +231,20 @@ namespace MultiArrayHelper
template <size_t ISSTATIC> template <size_t ISSTATIC>
struct ForBound struct ForBound
{ {
template <size_t BOUND> template <size_t BOUND, size_t DIV = 1>
static inline size_t bound(size_t bound) static inline size_t bound(size_t bound)
{ {
return bound; return bound / DIV;
} }
}; };
template <> template <>
struct ForBound<1> struct ForBound<1>
{ {
template <size_t BOUND> template <size_t BOUND, size_t DIV = 1>
static constexpr size_t bound(size_t bound) static constexpr size_t bound(size_t bound)
{ {
return BOUND; return BOUND / DIV;
} }
}; };
@ -287,6 +287,9 @@ namespace MultiArrayHelper
return std::make_shared<SingleExpression<IndexClass,Expr>>(*this); return std::make_shared<SingleExpression<IndexClass,Expr>>(*this);
} }
template <size_t VS>
inline auto vec() const { return *this; }
inline void operator()(size_t mlast, DExt last) override final; inline void operator()(size_t mlast, DExt last) override final;
inline void operator()(size_t mlast, ExtType last); inline void operator()(size_t mlast, ExtType last);
inline void operator()(size_t mlast = 0) override final; inline void operator()(size_t mlast = 0) override final;
@ -340,6 +343,9 @@ namespace MultiArrayHelper
return std::make_shared<SubExpr<IndexClass,Expr>>(*this); return std::make_shared<SubExpr<IndexClass,Expr>>(*this);
} }
template <size_t VS>
inline auto vec() const { return *this; }
inline void operator()(size_t mlast, DExt last) override final; inline void operator()(size_t mlast, DExt last) override final;
inline void operator()(size_t mlast, ExtType last) ; inline void operator()(size_t mlast, ExtType last) ;
inline void operator()(size_t mlast = 0) override final; inline void operator()(size_t mlast = 0) override final;
@ -351,15 +357,65 @@ namespace MultiArrayHelper
auto extension() const -> ExtType; auto extension() const -> ExtType;
}; };
template <class IndexClass, class Expr> template <size_t LAYER, bool ISV>
class PFor; struct MkVFor
{
template <size_t DIV, class IndexClass, class Expr>
using ptype = PFor<IndexClass,Expr,1>;
template <class IndexClass, class Expr, ForType FT> template <size_t DIV, class IndexClass, class Expr, ForType FT>
using type = For<IndexClass,Expr,FT,1>;
};
template <>
struct MkVFor<1,true>
{
template <size_t DIV, class IndexClass, class Expr>
using ptype = PFor<IndexClass,Expr,DIV>;
template <size_t DIV, class IndexClass, class Expr, ForType FT>
using type = For<IndexClass,Expr,FT,DIV>;
};
template <size_t LAYER>
struct MkVExpr
{
template <size_t VS, class Expr>
static auto mk(const Expr& e)
{
return e.template vec<VS>();
}
template <class Expr>
static inline size_t divResid(const Expr& e)
{
return e.divResid();
}
};
template <>
struct MkVExpr<1>
{
template <size_t VS, class Expr>
static auto mk(const Expr& e)
{
return e; // terminate
}
template <class Expr>
static inline size_t divResid(const Expr& e)
{
return 0;
}
};
template <class IndexClass, class Expr, ForType FT, size_t DIV>
class For : public ExpressionBase class For : public ExpressionBase
{ {
private: private:
For() = default; For() = default;
typedef typename IndexClass::RangeType RangeType;
const IndexClass* mIndPtr; const IndexClass* mIndPtr;
size_t mSPos; size_t mSPos;
size_t mMax; size_t mMax;
@ -376,6 +432,7 @@ namespace MultiArrayHelper
static constexpr size_t LAYER = Expr::LAYER + 1; static constexpr size_t LAYER = Expr::LAYER + 1;
static constexpr size_t SIZE = Expr::SIZE; static constexpr size_t SIZE = Expr::SIZE;
static constexpr size_t MAX = RangeType::SIZE / DIV;
For(const For& in) = default; For(const For& in) = default;
For& operator=(const For& in) = default; For& operator=(const For& in) = default;
@ -390,25 +447,24 @@ namespace MultiArrayHelper
virtual std::shared_ptr<ExpressionBase> deepCopy() const override final virtual std::shared_ptr<ExpressionBase> deepCopy() const override final
{ {
return std::make_shared<For<IndexClass,Expr,FT>>(*this); return std::make_shared<For<IndexClass,Expr,FT,DIV>>(*this);
} }
virtual std::intptr_t vec(size_t vs) override final virtual size_t divResid() const override final { return mMax % DIV + MkVExpr<LAYER>::divResid(mExpr); }
template <size_t VS>
auto vec() const
{ {
if(mStep == 1 and mMax % vs == 0){ typedef typename MkVFor<LAYER,RangeType::SIZE % DIV == 0 or RangeType::SIZE == static_cast<size_t>(-1)>::
VCHECK(vs); template type<VS,IndexClass,decltype(MkVExpr<LAYER>::template mk<VS>(mExpr)),FT> oType;
mMax /= vs; return oType(mIndPtr,mStep,MkVExpr<LAYER>::template mk<VS>(mExpr));
VCHECK(mMax);
return reinterpret_cast<std::intptr_t>(mIndPtr);
}
return mExpr.vec(vs);
} }
inline void operator()(size_t mlast, DExt last) override final; inline void operator()(size_t mlast, DExt last) override final;
inline void operator()(size_t mlast, ExtType last) ; inline void operator()(size_t mlast, ExtType last) ;
inline void operator()(size_t mlast = 0) override final; inline void operator()(size_t mlast = 0) override final;
PFor<IndexClass,Expr> parallel() const; PFor<IndexClass,Expr,DIV> parallel() const;
DExt dRootSteps(std::intptr_t iPtrNum = 0) const override final; DExt dRootSteps(std::intptr_t iPtrNum = 0) const override final;
DExt dExtension() const override final; DExt dExtension() const override final;
@ -418,12 +474,14 @@ namespace MultiArrayHelper
}; };
template <class IndexClass, class Expr>
template <class IndexClass, class Expr, size_t DIV>
class PFor : public ExpressionBase class PFor : public ExpressionBase
{ {
private: private:
PFor() = default; PFor() = default;
typedef typename IndexClass::RangeType RangeType;
const IndexClass* mIndPtr; const IndexClass* mIndPtr;
size_t mSPos; size_t mSPos;
size_t mMax; size_t mMax;
@ -440,6 +498,7 @@ namespace MultiArrayHelper
static constexpr size_t LAYER = Expr::LAYER + 1; static constexpr size_t LAYER = Expr::LAYER + 1;
static constexpr size_t SIZE = Expr::SIZE; static constexpr size_t SIZE = Expr::SIZE;
static constexpr size_t MAX = RangeType::SIZE / DIV;
PFor(const PFor& in) = default; PFor(const PFor& in) = default;
PFor& operator=(const PFor& in) = default; PFor& operator=(const PFor& in) = default;
@ -452,17 +511,14 @@ namespace MultiArrayHelper
PFor(const IndexClass* indPtr, PFor(const IndexClass* indPtr,
size_t step, Expr expr); size_t step, Expr expr);
virtual size_t divResid() const override final { return mMax % DIV + MkVExpr<LAYER>::divResid(mExpr); }
template <size_t VS> template <size_t VS>
auto vec() const auto vec() const
{ {
// statically distinguish!!! typedef typename MkVFor<LAYER,RangeType::SIZE % DIV == 0 or RangeType::SIZE == static_cast<size_t>(-1)>::
if(mStep == 1 and mMax % vs == 0){ template ptype<VS,IndexClass,decltype(MkVExpr<LAYER>::template mk<VS>(mExpr))> oType;
VCHECK(vs); return oType(mIndPtr,mStep,MkVExpr<LAYER>::template mk<VS>(mExpr));
mMax /= vs;
VCHECK(mMax);
return reinterpret_cast<std::intptr_t>(mIndPtr);
}
return mExpr.vec(vs);
} }
virtual std::shared_ptr<ExpressionBase> deepCopy() const override final virtual std::shared_ptr<ExpressionBase> deepCopy() const override final
@ -542,6 +598,9 @@ namespace MultiArrayHelper
return std::make_shared<DynamicExpression>(*this); return std::make_shared<DynamicExpression>(*this);
} }
template <size_t VS>
inline auto vec() const { return *this; }
inline void operator()(size_t mlast, DExt last) override final; inline void operator()(size_t mlast, DExt last) override final;
inline void operator()(size_t mlast, DExtT last) { (*this)(mlast,last.get()); } inline void operator()(size_t mlast, DExtT last) { (*this)(mlast,last.get()); }
inline void operator()(size_t mlast = 0) override final; inline void operator()(size_t mlast = 0) override final;
@ -617,50 +676,52 @@ namespace MultiArrayHelper
* F o r * * F o r *
*****************/ *****************/
template <class IndexClass, class Expr, ForType FT> template <class IndexClass, class Expr, ForType FT, size_t DIV>
For<IndexClass,Expr,FT>::For(const std::shared_ptr<IndexClass>& indPtr, For<IndexClass,Expr,FT,DIV>::For(const std::shared_ptr<IndexClass>& indPtr,
size_t step, Expr expr) : size_t step, Expr expr) :
mIndPtr(indPtr.get()), mSPos(mIndPtr->pos()), mMax(mIndPtr->max()), mStep(step), mIndPtr(indPtr.get()), mSPos(mIndPtr->pos()), mMax(mIndPtr->max()), mStep(step),
mExpr(expr), mExt(mExpr.rootSteps( reinterpret_cast<std::intptr_t>( mIndPtr ))) mExpr(expr), mExt(mExpr.rootSteps( reinterpret_cast<std::intptr_t>( mIndPtr )))
{ {
assert(mMax % DIV == 0);
assert(mIndPtr != nullptr); assert(mIndPtr != nullptr);
} }
template <class IndexClass, class Expr, ForType FT> template <class IndexClass, class Expr, ForType FT, size_t DIV>
For<IndexClass,Expr,FT>::For(const IndexClass* indPtr, For<IndexClass,Expr,FT,DIV>::For(const IndexClass* indPtr,
size_t step, Expr expr) : size_t step, Expr expr) :
mIndPtr(indPtr), mSPos(mIndPtr->pos()), mMax(mIndPtr->max()), mStep(step), mIndPtr(indPtr), mSPos(mIndPtr->pos()), mMax(mIndPtr->max()), mStep(step),
mExpr(expr), mExt(mExpr.rootSteps( reinterpret_cast<std::intptr_t>( mIndPtr ))) mExpr(expr), mExt(mExpr.rootSteps( reinterpret_cast<std::intptr_t>( mIndPtr )))
{ {
assert(mMax % DIV == 0);
assert(mIndPtr != nullptr); assert(mIndPtr != nullptr);
} }
template <class IndexClass, class Expr, ForType FT> template <class IndexClass, class Expr, ForType FT, size_t DIV>
inline void For<IndexClass,Expr,FT>::operator()(size_t mlast, DExt last) inline void For<IndexClass,Expr,FT,DIV>::operator()(size_t mlast, DExt last)
{ {
operator()(mlast, std::dynamic_pointer_cast<ExtT<ExtType>>(last)->ext()); operator()(mlast, std::dynamic_pointer_cast<ExtT<ExtType>>(last)->ext());
//operator()(mlast, *reinterpret_cast<ExtType const*>(last.first)); //operator()(mlast, *reinterpret_cast<ExtType const*>(last.first));
} }
template <class IndexClass, class Expr, ForType FT> template <class IndexClass, class Expr, ForType FT, size_t DIV>
inline void For<IndexClass,Expr,FT>::operator()(size_t mlast, inline void For<IndexClass,Expr,FT,DIV>::operator()(size_t mlast,
ExtType last) ExtType last)
{ {
typedef typename IndexClass::RangeType RangeType; typedef typename IndexClass::RangeType RangeType;
for(size_t pos = 0u; pos != ForBound<RangeType::ISSTATIC>::template bound<RangeType::SIZE>(mMax); ++pos){ for(size_t pos = 0u; pos != ForBound<RangeType::ISSTATIC>::template bound<RangeType::SIZE,DIV>(mMax); ++pos){
const size_t mnpos = PosForward<FT>::valuex(mlast, mStep, pos); const size_t mnpos = PosForward<FT>::valuex(mlast, mStep, pos);
const ExtType npos = last + mExt*pos; const ExtType npos = last + mExt*pos;
mExpr(mnpos, npos); mExpr(mnpos, npos);
} }
} }
template <class IndexClass, class Expr, ForType FT> template <class IndexClass, class Expr, ForType FT, size_t DIV>
inline void For<IndexClass,Expr,FT>::operator()(size_t mlast) inline void For<IndexClass,Expr,FT,DIV>::operator()(size_t mlast)
{ {
typedef typename IndexClass::RangeType RangeType; typedef typename IndexClass::RangeType RangeType;
ExtType last = rootSteps(); ExtType last = rootSteps();
last.zero(); last.zero();
for(size_t pos = 0u; pos != ForBound<RangeType::ISSTATIC>::template bound<RangeType::SIZE>(mMax); ++pos){ for(size_t pos = 0u; pos != ForBound<RangeType::ISSTATIC>::template bound<RangeType::SIZE,DIV>(mMax); ++pos){
const size_t mnpos = PosForward<FT>::valuex(mlast, mStep, pos); const size_t mnpos = PosForward<FT>::valuex(mlast, mStep, pos);
const ExtType npos = last + mExt*pos; const ExtType npos = last + mExt*pos;
mExpr(mnpos, npos); mExpr(mnpos, npos);
@ -668,22 +729,22 @@ namespace MultiArrayHelper
} }
template <class IndexClass, class Expr, ForType FT> template <class IndexClass, class Expr, ForType FT, size_t DIV>
auto For<IndexClass,Expr,FT>::rootSteps(std::intptr_t iPtrNum) const auto For<IndexClass,Expr,FT,DIV>::rootSteps(std::intptr_t iPtrNum) const
-> ExtType -> ExtType
{ {
return mExpr.rootSteps(iPtrNum); return mExpr.rootSteps(iPtrNum);
} }
template <class IndexClass, class Expr, ForType FT> template <class IndexClass, class Expr, ForType FT, size_t DIV>
auto For<IndexClass,Expr,FT>::extension() const auto For<IndexClass,Expr,FT,DIV>::extension() const
-> ExtType -> ExtType
{ {
return mExt; return mExt;
} }
template <class IndexClass, class Expr, ForType FT> template <class IndexClass, class Expr, ForType FT, size_t DIV>
DExt For<IndexClass,Expr,FT>::dRootSteps(std::intptr_t iPtrNum) const DExt For<IndexClass,Expr,FT,DIV>::dRootSteps(std::intptr_t iPtrNum) const
{ {
return std::make_shared<ExtT<ExtType>>(rootSteps(iPtrNum)); return std::make_shared<ExtT<ExtType>>(rootSteps(iPtrNum));
//mRootSteps = rootSteps(iPtrNum); //mRootSteps = rootSteps(iPtrNum);
@ -691,52 +752,54 @@ namespace MultiArrayHelper
// sizeof(ExtType)/sizeof(size_t)); // sizeof(ExtType)/sizeof(size_t));
} }
template <class IndexClass, class Expr, ForType FT> template <class IndexClass, class Expr, ForType FT, size_t DIV>
DExt For<IndexClass,Expr,FT>::dExtension() const DExt For<IndexClass,Expr,FT,DIV>::dExtension() const
{ {
return std::make_shared<ExtT<ExtType>>(mExt); return std::make_shared<ExtT<ExtType>>(mExt);
//return std::make_pair<size_t const*,size_t>(reinterpret_cast<size_t const*>(&mExt), //return std::make_pair<size_t const*,size_t>(reinterpret_cast<size_t const*>(&mExt),
// sizeof(ExtType)/sizeof(size_t)); // sizeof(ExtType)/sizeof(size_t));
} }
template <class IndexClass, class Expr, ForType FT> template <class IndexClass, class Expr, ForType FT, size_t DIV>
PFor<IndexClass,Expr> For<IndexClass,Expr,FT>::parallel() const PFor<IndexClass,Expr,DIV> For<IndexClass,Expr,FT,DIV>::parallel() const
{ {
static_assert(FT == ForType::DEFAULT, "hidden for not parallelizable"); static_assert(FT == ForType::DEFAULT, "hidden for not parallelizable");
return PFor<IndexClass,Expr>(mIndPtr, mStep, mExpr); return PFor<IndexClass,Expr,DIV>(mIndPtr, mStep, mExpr);
} }
/****************** /******************
* P F o r * * P F o r *
******************/ ******************/
template <class IndexClass, class Expr> template <class IndexClass, class Expr, size_t DIV>
PFor<IndexClass,Expr>::PFor(const std::shared_ptr<IndexClass>& indPtr, PFor<IndexClass,Expr,DIV>::PFor(const std::shared_ptr<IndexClass>& indPtr,
size_t step, Expr expr) : size_t step, Expr expr) :
mIndPtr(indPtr.get()), mSPos(mIndPtr->pos()), mMax(mIndPtr->max()), mStep(step), mIndPtr(indPtr.get()), mSPos(mIndPtr->pos()), mMax(mIndPtr->max()), mStep(step),
mExpr(expr), mExt(mExpr.rootSteps( reinterpret_cast<std::intptr_t>( mIndPtr ))) mExpr(expr), mExt(mExpr.rootSteps( reinterpret_cast<std::intptr_t>( mIndPtr )))
{ {
assert(mMax % DIV == 0);
assert(mIndPtr != nullptr); assert(mIndPtr != nullptr);
} }
template <class IndexClass, class Expr> template <class IndexClass, class Expr, size_t DIV>
PFor<IndexClass,Expr>::PFor(const IndexClass* indPtr, PFor<IndexClass,Expr,DIV>::PFor(const IndexClass* indPtr,
size_t step, Expr expr) : size_t step, Expr expr) :
mIndPtr(indPtr), mSPos(mIndPtr->pos()), mMax(mIndPtr->max()), mStep(step), mIndPtr(indPtr), mSPos(mIndPtr->pos()), mMax(mIndPtr->max()), mStep(step),
mExpr(expr), mExt(mExpr.rootSteps( reinterpret_cast<std::intptr_t>( mIndPtr ))) mExpr(expr), mExt(mExpr.rootSteps( reinterpret_cast<std::intptr_t>( mIndPtr )))
{ {
assert(mMax % DIV == 0);
assert(mIndPtr != nullptr); assert(mIndPtr != nullptr);
} }
template <class IndexClass, class Expr> template <class IndexClass, class Expr, size_t DIV>
inline void PFor<IndexClass,Expr>::operator()(size_t mlast, DExt last) inline void PFor<IndexClass,Expr,DIV>::operator()(size_t mlast, DExt last)
{ {
operator()(mlast, std::dynamic_pointer_cast<ExtT<ExtType>>(last)->ext()); operator()(mlast, std::dynamic_pointer_cast<ExtT<ExtType>>(last)->ext());
//operator()(mlast, *reinterpret_cast<ExtType const*>(last.first)); //operator()(mlast, *reinterpret_cast<ExtType const*>(last.first));
} }
template <class IndexClass, class Expr> template <class IndexClass, class Expr, size_t DIV>
inline void PFor<IndexClass,Expr>::operator()(size_t mlast, inline void PFor<IndexClass,Expr,DIV>::operator()(size_t mlast,
ExtType last) ExtType last)
{ {
CHECK; CHECK;
@ -748,7 +811,7 @@ namespace MultiArrayHelper
{ {
auto expr = mExpr; auto expr = mExpr;
#pragma omp for nowait #pragma omp for nowait
for(pos = 0; pos < static_cast<int>(ForBound<RangeType::ISSTATIC>::template bound<RangeType::SIZE>(mMax)); pos++){ for(pos = 0; pos < static_cast<int>(ForBound<RangeType::ISSTATIC>::template bound<RangeType::SIZE,DIV>(mMax)); pos++){
mnpos = PosForward<ForType::DEFAULT>::valuex(mlast, mStep, pos); mnpos = PosForward<ForType::DEFAULT>::valuex(mlast, mStep, pos);
npos = last + mExt*static_cast<size_t>(pos); npos = last + mExt*static_cast<size_t>(pos);
expr(mnpos, npos); expr(mnpos, npos);
@ -756,11 +819,10 @@ namespace MultiArrayHelper
} }
} }
template <class IndexClass, class Expr> template <class IndexClass, class Expr, size_t DIV>
inline void PFor<IndexClass,Expr>::operator()(size_t mlast) inline void PFor<IndexClass,Expr,DIV>::operator()(size_t mlast)
{ {
CHECK; CHECK;
typedef typename IndexClass::RangeType RangeType;
ExtType last = rootSteps(); ExtType last = rootSteps();
last.zero(); last.zero();
int pos = 0; int pos = 0;
@ -771,7 +833,7 @@ namespace MultiArrayHelper
{ {
auto expr = mExpr; auto expr = mExpr;
#pragma omp for nowait #pragma omp for nowait
for(pos = 0; pos < static_cast<int>(ForBound<RangeType::ISSTATIC>::template bound<RangeType::SIZE>(mMax)); pos++){ for(pos = 0; pos < static_cast<int>(ForBound<RangeType::ISSTATIC>::template bound<RangeType::SIZE,DIV>(mMax)); pos++){
mnpos = PosForward<ForType::DEFAULT>::valuex(mlast, mStep, pos); mnpos = PosForward<ForType::DEFAULT>::valuex(mlast, mStep, pos);
npos = last + mExt*static_cast<size_t>(pos); npos = last + mExt*static_cast<size_t>(pos);
expr(mnpos, npos); expr(mnpos, npos);
@ -780,22 +842,22 @@ namespace MultiArrayHelper
} }
template <class IndexClass, class Expr> template <class IndexClass, class Expr, size_t DIV>
auto PFor<IndexClass,Expr>::rootSteps(std::intptr_t iPtrNum) const auto PFor<IndexClass,Expr,DIV>::rootSteps(std::intptr_t iPtrNum) const
-> ExtType -> ExtType
{ {
return mExpr.rootSteps(iPtrNum); return mExpr.rootSteps(iPtrNum);
} }
template <class IndexClass, class Expr> template <class IndexClass, class Expr, size_t DIV>
auto PFor<IndexClass,Expr>::extension() const auto PFor<IndexClass,Expr,DIV>::extension() const
-> ExtType -> ExtType
{ {
return mExt; return mExt;
} }
template <class IndexClass, class Expr> template <class IndexClass, class Expr, size_t DIV>
DExt PFor<IndexClass,Expr>::dRootSteps(std::intptr_t iPtrNum) const DExt PFor<IndexClass,Expr,DIV>::dRootSteps(std::intptr_t iPtrNum) const
{ {
return std::make_shared<ExtT<ExtType>>(rootSteps(iPtrNum)); return std::make_shared<ExtT<ExtType>>(rootSteps(iPtrNum));
//mRootSteps = rootSteps(iPtrNum); //mRootSteps = rootSteps(iPtrNum);
@ -803,8 +865,8 @@ namespace MultiArrayHelper
// sizeof(ExtType)/sizeof(size_t)); // sizeof(ExtType)/sizeof(size_t));
} }
template <class IndexClass, class Expr> template <class IndexClass, class Expr, size_t DIV>
DExt PFor<IndexClass,Expr>::dExtension() const DExt PFor<IndexClass,Expr,DIV>::dExtension() const
{ {
return std::make_shared<ExtT<ExtType>>(mExt); return std::make_shared<ExtT<ExtType>>(mExt);
//return std::make_pair<size_t const*,size_t>(reinterpret_cast<size_t const*>(&mExt), //return std::make_pair<size_t const*,size_t>(reinterpret_cast<size_t const*>(&mExt),