#ifndef __cxz_xfor_h__ #define __cxz_xfor_h__ #include #include "base/base.h" #include "for_type.h" #include "for_utils.h" #include "exttype.h" namespace CNORXZ { // 'HIDDEN FOR' CLASS for nested for loops in contractions a.s.o. // (NO COUNTING OF MASTER POSITION !!!!!) /* template struct PosForward { static inline size_t valuex(size_t last, size_t step, size_t pos) { return last + pos * step; } static inline size_t value(size_t last, size_t max, size_t pos) { return last * max + pos; } }; template <> struct PosForward { static inline size_t valuex(size_t last, size_t step, size_t pos) { return last; } static inline size_t value(size_t last, size_t max, size_t pos) { return last; } }; template class SubExpr : public ExpressionBase { private: SubExpr() = default; const IndexClass* mIndPtr; PtrId mSIPtr; size_t mSPos; size_t mMax; Expr mExpr; typedef decltype(mkExt(0).extend(mExpr.rootSteps())) ExtType; ExtType mExt; const Vector* mSubSet; mutable ExtType mRootSteps; public: typedef ExpressionBase EB; static constexpr size_t LAYER = Expr::LAYER + 1; static constexpr size_t SIZE = Expr::SIZE + 1; //static constexpr size_t NHLAYER = Expr::NHLAYER + 1; DEFAULT_MEMBERS_X(SubExpr); SubExpr(const Sptr& indPtr, std::intptr_t siptr, const vector* subset, Expr expr); SubExpr(const IndexClass* indPtr, std::intptr_t siptr, const vector* subset, Expr expr); inline void operator()(size_t mlast, DExt last) override final; inline void operator()(size_t mlast, ExtType last) ; inline void operator()(size_t mlast = 0) override final; DExt dRootSteps(std::intptr_t iPtrNum = 0) const override final; DExt dExtension() const override final; auto rootSteps(std::intptr_t iPtrNum = 0) const -> ExtType; auto extension() const -> ExtType; }; template struct NHLayer { template static constexpr size_t get() { return Expr::NHLAYER + 1; } }; template struct NHLayer { template static constexpr size_t get() { return 0; } }; template <> struct NHLayer { template static constexpr size_t get() { return Expr::LAYER; } }; template class For : public ExpressionBase { private: For() = default; typedef typename IndexClass::RangeType RangeType; const IndexClass* mIndPtr; size_t mSPos; size_t mMax; size_t mStep; Expr mExpr; typedef decltype(mExpr.rootSteps()) ExtType; ExtType mExt; mutable ExtType mRootSteps; public: typedef ExpressionBase EB; static constexpr size_t LAYER = Expr::LAYER + 1; static constexpr size_t SIZE = Expr::SIZE; //static constexpr size_t MAX = RangeType::SIZE / DIV; //static constexpr size_t NHLAYER = (FT == ForType::HIDDEN) ? 0 : Expr::NHLAYER + 1; DEFAULT_MEMBERS(For); For(const Sptr& indPtr, size_t step, Expr expr); For(const IndexClass* indPtr, size_t step, Expr expr); inline void operator()(size_t mlast, DExt last) override final; inline void operator()(size_t mlast, ExtType last) ; inline void operator()(size_t mlast = 0) override final; PFor parallel() const; DExt dRootSteps(std::intptr_t iPtrNum = 0) const override final; DExt dExtension() const override final; auto rootSteps(std::intptr_t iPtrNum = 0) const -> ExtType; auto extension() const -> ExtType; }; class DynamicExpression : public ExpressionBase { private: size_t mThreadId = 0; Sptr mNext; DynamicExpression() : mThreadId(omp_get_thread_num()) {} public: static constexpr size_t LAYER = 0; static constexpr size_t SIZE = 0; static constexpr size_t NHLAYER = 0; DynamicExpression(const DynamicExpression& in) : mThreadId(omp_get_thread_num()), mNext( (static_cast(in.mThreadId) == omp_get_thread_num()) ? in.mNext : in.mNext->deepCopy()) {} DynamicExpression(DynamicExpression&& in) : mThreadId(omp_get_thread_num()), mNext( (static_cast(in.mThreadId) == omp_get_thread_num()) ? in.mNext : in.mNext->deepCopy()) {} DynamicExpression& operator=(const DynamicExpression& in) { mThreadId = omp_get_thread_num(); mNext = (static_cast(in.mThreadId) == omp_get_thread_num()) ? in.mNext : in.mNext->deepCopy(); return *this; } DynamicExpression& operator=(DynamicExpression&& in) { mThreadId = omp_get_thread_num(); mNext = (static_cast(in.mThreadId) == omp_get_thread_num()) ? in.mNext : in.mNext->deepCopy(); return *this; } DynamicExpression(const Sptr& next) : mNext(next) {} template DynamicExpression(const ExpressionBase& next) : mNext(std::make_shared(next)) {} template DynamicExpression(Expr ex) : mNext( std::make_shared(ex) ) {} virtual Sptr deepCopy() const override final { return std::make_shared(*this); } 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 = 0) override final; inline DExt dRootSteps(std::intptr_t iPtrNum = 0) const override final; inline DExt dExtension() const override final; inline DExtT rootSteps(std::intptr_t iPtrNum = 0) const { return DExtT(dRootSteps(iPtrNum)); } inline DExtT extension() const { return DExtT(dExtension()); } }; */ } /* ========================= * * --- TEMPLATE CODE --- * * ========================= */ namespace CNORXZ { /***************** * F o r * *****************/ /* template For::For(const Sptr& indPtr, size_t step, Expr expr) : mIndPtr(indPtr.get()), mSPos(mIndPtr->pos()), mMax(mIndPtr->max()), mStep(step), mExpr(expr), mExt(mExpr.rootSteps( reinterpret_cast( mIndPtr ))) { assert(mMax % DIV == 0); assert(mIndPtr != nullptr); } template For::For(const IndexClass* indPtr, size_t step, Expr expr) : mIndPtr(indPtr), mSPos(mIndPtr->pos()), mMax(mIndPtr->max()), mStep(step), mExpr(expr), mExt(mExpr.rootSteps( reinterpret_cast( mIndPtr ))) { //VCHECK(mMax); //VCHECK(DIV); //assert(mMax % DIV == 0); assert(mIndPtr != nullptr); } template inline void For::operator()(size_t mlast, DExt last) { operator()(mlast, std::dynamic_pointer_cast>(last)->ext()); //operator()(mlast, *reinterpret_cast(last.first)); } template inline void For::operator()(size_t mlast, ExtType last) { typedef typename IndexClass::RangeType RangeType; for(size_t pos = 0u; pos != ForBound::template bound(mMax); ++pos){ const size_t mnpos = PosForward::valuex(mlast, mStep, pos); const ExtType npos = last + mExt*pos; mExpr(mnpos, npos); } } template inline void For::operator()(size_t mlast) { typedef typename IndexClass::RangeType RangeType; ExtType last = rootSteps(); last.zero(); for(size_t pos = 0u; pos != ForBound::template bound(mMax); ++pos){ const size_t mnpos = PosForward::valuex(mlast, mStep, pos); const ExtType npos = last + mExt*pos; mExpr(mnpos, npos); } } template auto For::rootSteps(std::intptr_t iPtrNum) const -> ExtType { return mExpr.rootSteps(iPtrNum); } template auto For::extension() const -> ExtType { return mExt; } template DExt For::dRootSteps(std::intptr_t iPtrNum) const { return std::make_shared>(rootSteps(iPtrNum)); //mRootSteps = rootSteps(iPtrNum); //return std::make_pair(reinterpret_cast(&mRootSteps), // sizeof(ExtType)/sizeof(size_t)); } template DExt For::dExtension() const { return std::make_shared>(mExt); //return std::make_pair(reinterpret_cast(&mExt), // sizeof(ExtType)/sizeof(size_t)); } template PFor For::parallel() const { static_assert(FT == ForType::DEFAULT, "hidden for not parallelizable"); return PFor(mIndPtr, mStep, mExpr); } */ /****************** * P F o r * ******************/ /* template PFor::PFor(const Sptr& indPtr, size_t step, Expr expr) : mIndPtr(indPtr.get()), mSPos(mIndPtr->pos()), mMax(mIndPtr->max()), mStep(step), mExpr(expr), mExt(mExpr.rootSteps( reinterpret_cast( mIndPtr ))) { //assert(mMax % DIV == 0); assert(mIndPtr != nullptr); } template PFor::PFor(const IndexClass* indPtr, size_t step, Expr expr) : mIndPtr(indPtr), mSPos(mIndPtr->pos()), mMax(mIndPtr->max()), mStep(step), mExpr(expr), mExt(mExpr.rootSteps( reinterpret_cast( mIndPtr ))) { assert(mMax % DIV == 0); assert(mIndPtr != nullptr); } template inline void PFor::operator()(size_t mlast, DExt last) { operator()(mlast, std::dynamic_pointer_cast>(last)->ext()); //operator()(mlast, *reinterpret_cast(last.first)); } template inline void PFor::operator()(size_t mlast, ExtType last) { CHECK; typedef typename IndexClass::RangeType RangeType; int pos = 0; size_t mnpos = 0; ExtType npos; #pragma omp parallel shared(mExpr) private(pos,mnpos,npos) { auto expr = mExpr; #pragma omp for nowait for(pos = 0; pos < static_cast(ForBound::template bound(mMax)); pos++){ mnpos = PosForward::valuex(mlast, mStep, pos); npos = last + mExt*static_cast(pos); expr(mnpos, npos); } } } template inline void PFor::operator()(size_t mlast) { CHECK; ExtType last = rootSteps(); last.zero(); int pos = 0; size_t mnpos = 0; ExtType npos = rootSteps(); npos.zero(); #pragma omp parallel shared(mExpr) private(pos,mnpos,npos) { auto expr = mExpr; #pragma omp for nowait for(pos = 0; pos < static_cast(ForBound::template bound(mMax)); pos++){ mnpos = PosForward::valuex(mlast, mStep, pos); npos = last + mExt*static_cast(pos); expr(mnpos, npos); } } } template auto PFor::rootSteps(std::intptr_t iPtrNum) const -> ExtType { return mExpr.rootSteps(iPtrNum); } template auto PFor::extension() const -> ExtType { return mExt; } template DExt PFor::dRootSteps(std::intptr_t iPtrNum) const { return std::make_shared>(rootSteps(iPtrNum)); //mRootSteps = rootSteps(iPtrNum); //return std::make_pair(reinterpret_cast(&mRootSteps), // sizeof(ExtType)/sizeof(size_t)); } template DExt PFor::dExtension() const { return std::make_shared>(mExt); //return std::make_pair(reinterpret_cast(&mExt), // sizeof(ExtType)/sizeof(size_t)); } */ /**************** * SubExpr * ****************/ /* template SubExpr::SubExpr(const Sptr& indPtr, std::intptr_t siptr, const vector* subset, Expr expr) : mIndPtr(indPtr.get()), mSIPtr(siptr), mSPos(mIndPtr->pos()), mMax(mIndPtr->max()), mExpr(expr), mExt( mkExt(0).extend( mExpr.rootSteps( reinterpret_cast( mIndPtr )) ) ), mSubSet(subset) { assert(mIndPtr != nullptr); } template SubExpr::SubExpr(const IndexClass* indPtr, std::intptr_t siptr, const vector* subset, Expr expr) : mIndPtr(indPtr), mSIPtr(siptr), mSPos(mIndPtr->pos()), mMax(mIndPtr->max()), mExpr(expr), mExt( mkExt(0).extend( mExpr.rootSteps( reinterpret_cast( mIndPtr )) ) ), mSubSet(subset) { assert(mIndPtr != nullptr); } template inline void SubExpr::operator()(size_t mlast, DExt last) { operator()(mlast, std::dynamic_pointer_cast>(last)->ext()); //operator()(mlast, *reinterpret_cast(last.first)); } template inline void SubExpr::operator()(size_t mlast, ExtType last) { const size_t pos = (*mSubSet)[last.val()]; const size_t mnpos = mlast; const ExtType npos = last + mExt*pos; mExpr(mnpos, getX<1>( npos )); } template inline void SubExpr::operator()(size_t mlast) { ExtType last = rootSteps(); last.zero(); const size_t pos = (*mSubSet)[last.val()]; const size_t mnpos = mlast; const ExtType npos = last + mExt*pos; mExpr(mnpos, getX<1>( npos )); } template auto SubExpr::rootSteps(std::intptr_t iPtrNum) const -> ExtType { return mkExt(iPtrNum == mSIPtr ? 1 : 0).extend(mExpr.rootSteps(iPtrNum)); } template auto SubExpr::extension() const -> ExtType { return mExt; } template DExt SubExpr::dRootSteps(std::intptr_t iPtrNum) const { return std::make_shared>(rootSteps(iPtrNum)); //mRootSteps = rootSteps(iPtrNum); //return std::make_pair(reinterpret_cast(&mRootSteps), //sizeof(ExtType)/sizeof(size_t)); } template DExt SubExpr::dExtension() const { return std::make_shared>(mExt); //return std::make_pair(reinterpret_cast(&mExt), // sizeof(ExtType)/sizeof(size_t)); } */ /*************************** * DynamicExpression * ***************************/ /* inline void DynamicExpression::operator()(size_t mlast, DExt last) { (*mNext)(mlast,last); } inline void DynamicExpression::operator()(size_t mlast) { (*mNext)(mlast); } inline DExt DynamicExpression::dRootSteps(std::intptr_t iPtrNum) const { return mNext->dRootSteps(iPtrNum); } inline DExt DynamicExpression::dExtension() const { return mNext->dExtension(); } */ } // namespace CNORXZInternal #endif