diff --git a/src/include/dynamic_operation.cc.h b/src/include/dynamic_operation.cc.h index 5f8b109..29144af 100644 --- a/src/include/dynamic_operation.cc.h +++ b/src/include/dynamic_operation.cc.h @@ -50,9 +50,7 @@ namespace MultiArrayTools 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({1}), std::array({0})) - { - *mMa = 0; - } + {} template OpH> DynamicOuterOp::get(const DExtT& pos) const diff --git a/src/include/dynamic_operation.h b/src/include/dynamic_operation.h index 399f5c8..f5373ef 100644 --- a/src/include/dynamic_operation.h +++ b/src/include/dynamic_operation.h @@ -74,12 +74,16 @@ namespace MultiArrayTools //OperationRoot mProto; std::shared_ptr> mMa; OpH> mProto; + + typedef ILoop,Operation>, std::tuple...>, std::tuple>>, std::tupleassign( mOp, mkMIndex(std::shared_ptr()...) ))>> LoopT; + + mutable LoopT mL; public: diff --git a/src/include/multi_array_operation.h b/src/include/multi_array_operation.h index 00cdc26..046a9cd 100644 --- a/src/include/multi_array_operation.h +++ b/src/include/multi_array_operation.h @@ -131,7 +131,14 @@ namespace MultiArrayTools AssignmentExpr2(T* dataPtr, const Target& tar, const OpClass& sec); AssignmentExpr2(const AssignmentExpr2& in) = default; AssignmentExpr2(AssignmentExpr2&& in) = default; - + AssignmentExpr2& operator=(const AssignmentExpr2& in) = default; + AssignmentExpr2& operator=(AssignmentExpr2&& in) = default; + + virtual std::shared_ptr deepCopy() const override final + { + return std::make_shared>(*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; @@ -160,7 +167,14 @@ namespace MultiArrayTools GetExpr(const OpClass& sec, const NextExpr& nexpr); GetExpr(const GetExpr& in) = default; GetExpr(GetExpr&& in) = default; + GetExpr& operator=(const GetExpr& in) = default; + GetExpr& operator=(GetExpr&& in) = default; + virtual std::shared_ptr deepCopy() const override final + { + return std::make_shared>(*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; @@ -201,7 +215,14 @@ namespace MultiArrayTools AddExpr(T* dataPtr, const Target& tar, const OpClass& sec); AddExpr(const AddExpr& in) = default; AddExpr(AddExpr&& in) = default; + AddExpr& operator=(const AddExpr& in) = default; + AddExpr& operator=(AddExpr&& in) = default; + virtual std::shared_ptr deepCopy() const override final + { + return std::make_shared>(*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; diff --git a/src/include/xfor/iloop.h b/src/include/xfor/iloop.h index a6320d7..0bad5a0 100644 --- a/src/include/xfor/iloop.h +++ b/src/include/xfor/iloop.h @@ -126,7 +126,12 @@ namespace MultiArrayHelper const std::array& umpos, const std::array& setzero) : mOpTp(opTp), mIndTp(indTp), mVarTp(varTp), mLTp(lTp), mUmpos(umpos), mSetzero(setzero) {} - inline size_t operator()(size_t mpos, ExtType pos) + virtual std::shared_ptr deepCopy() const override final + { + return std::make_shared>(*this); + } + + inline size_t operator()(size_t mpos, ExtType pos) { NN::zero(mVarTp, mSetzero); //VCHECK(mpos); @@ -229,7 +234,7 @@ namespace MultiArrayHelper // if instance copied to different thread, the "copy" will be newly created from this function // -> ensures that there is NO SHARED WORKSPACE template - class PILoop + class PILoop : public ExpressionBase { private: size_t mThreadId = 0; @@ -268,10 +273,25 @@ namespace MultiArrayHelper } PILoop(const CF& cf) : mThreadId(omp_get_thread_num()), mCF(cf), mL(mCF()) {} + /* + virtual void ensureThread() override final + { + VCHECK(omp_get_thread_num()); + //if(static_cast(mThreadId) != omp_get_thread_num()){ + mThreadId = omp_get_thread_num(); + mL = mCF(); + //} + } + */ + virtual std::shared_ptr deepCopy() const override final + { + return std::make_shared>(*this); + } inline size_t operator()(size_t mpos, ExtType pos) { - return mL(mpos, pos); + mL(mpos, pos); + return 0; } auto rootSteps(std::intptr_t i = 0) const @@ -284,6 +304,28 @@ namespace MultiArrayHelper { return mL.var(); } + + virtual void operator()(size_t mlast, DExt last) override final + { + operator()(mlast, std::dynamic_pointer_cast>(last)->ext()); + } + + virtual void operator()(size_t mlast = 0) override final + { + ExtType last = rootSteps(); + last.zero(); + operator()(mlast, last); + } + + virtual DExt dRootSteps(std::intptr_t iPtrNum = 0) const override final + { + return std::make_shared>(rootSteps(iPtrNum)); + } + + virtual DExt dExtension() const override final + { + return nullptr; //!! + } }; } diff --git a/src/include/xfor/xfor.h b/src/include/xfor/xfor.h index 9da6586..1bffc0f 100644 --- a/src/include/xfor/xfor.h +++ b/src/include/xfor/xfor.h @@ -112,8 +112,8 @@ namespace MultiArrayHelper DExtTX() { mDExt = std::make_shared>(); } DExtTX(const DExtTX& in) : mDExt(in.mDExt->deepCopy()), mNext(in.mNext) {} DExtTX(DExtTX&& in) : mDExt(in.mDExt->deepCopy()), mNext(in.mNext) {} - DExtTX& operator=(const DExtTX& in) { mNext = in.mNext; mDExt = in.mDExt->deepCopy(); } - DExtTX& operator=(DExtTX&& in) { mNext = in.mNext; mDExt = in.mDExt->deepCopy(); } + DExtTX& operator=(const DExtTX& in) { mNext = in.mNext; mDExt = in.mDExt->deepCopy(); return *this; } + DExtTX& operator=(DExtTX&& in) { mNext = in.mNext; mDExt = in.mDExt->deepCopy(); return *this; } explicit DExtTX(const DExt& in) : mDExt(in) {} /* template @@ -173,6 +173,8 @@ namespace MultiArrayHelper ExpressionBase& operator=(const ExpressionBase& in) = default; ExpressionBase& operator=(ExpressionBase&& in) = default; + virtual std::shared_ptr deepCopy() const = 0; + virtual void operator()(size_t mlast, DExt last) = 0; virtual void operator()(size_t mlast = 0) = 0; @@ -264,7 +266,11 @@ namespace MultiArrayHelper SingleExpression(const IndexClass* indPtr, Expr expr); - + virtual std::shared_ptr 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, ExtType last); inline void operator()(size_t mlast = 0) override final; @@ -313,7 +319,11 @@ namespace MultiArrayHelper SubExpr(const IndexClass* indPtr, std::intptr_t siptr, const vector* subset, Expr expr); - + virtual std::shared_ptr 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, ExtType last) ; inline void operator()(size_t mlast = 0) override final; @@ -362,6 +372,11 @@ namespace MultiArrayHelper For(const IndexClass* indPtr, size_t step, Expr expr); + virtual std::shared_ptr 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, ExtType last) ; inline void operator()(size_t mlast = 0) override final; @@ -410,6 +425,11 @@ namespace MultiArrayHelper PFor(const IndexClass* indPtr, size_t step, Expr expr); + virtual std::shared_ptr 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, ExtType last) ; inline void operator()(size_t mlast = 0) override final; @@ -431,8 +451,9 @@ namespace MultiArrayHelper class DynamicExpression : public ExpressionBase { private: - DynamicExpression() = default; + DynamicExpression() : mThreadId(omp_get_thread_num()) {} + size_t mThreadId; std::shared_ptr mNext; public: @@ -440,10 +461,29 @@ namespace MultiArrayHelper static constexpr size_t LAYER = 0; static constexpr size_t SIZE = 0; - DynamicExpression(const DynamicExpression& in) = default; - DynamicExpression(DynamicExpression&& in) = default; - DynamicExpression& operator=(const DynamicExpression& in) = default; - DynamicExpression& operator=(DynamicExpression&& in) = default; + 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 std::shared_ptr& next) : mNext(next) @@ -457,6 +497,11 @@ namespace MultiArrayHelper template DynamicExpression(Expr ex) : mNext( std::make_shared(ex) ) {} + virtual std::shared_ptr 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; @@ -495,6 +540,11 @@ namespace MultiArrayHelper ExpressionHolder(DynamicExpression expr); + virtual std::shared_ptr 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, ExtType last) ; inline void operator()(size_t mlast = 0) override final; diff --git a/src/tests/op4_unit_test.cc b/src/tests/op4_unit_test.cc index f41ecef..4327cc9 100644 --- a/src/tests/op4_unit_test.cc +++ b/src/tests/op4_unit_test.cc @@ -137,15 +137,21 @@ namespace resx2(i1,di4) = mkDynOp(ma1(i1,di1) * ma2(i1,di2)); resx3(i1,di4) = mkDynOp(mkDynOp(ma1(i1,di1)) * mkDynOp(ma2(i1,di2))); - auto op1 = mkDynOutOp((ma1(i1,di1) * ma2(i1,di2)), ci4_1, ci4_2); + //auto op1 = mkDynOutOp((ma1(i1,di1) * ma2(i1,di2)), ci4_1, ci4_2); + //auto opr = resx4(i1,di4); + auto op1x = (ma1(i1,di1) * ma2(i1,di2)); auto opr = resx4(i1,di4); - - auto loop = mkILoop(std::make_tuple(opr,op1,*op1.data()->mOp), std::make_tuple(ci4_1, ci4_2), - std::make_tuple(xx), - std::make_tuple(opr.assign( *op1.data()->mOp, mkMIndex(ci4_1, ci4_2) )), - std::array({1}), std::array({0})); - - mi->ifor(1, mkGetExpr(op1,loop))(); + + auto loop = mkPILoop + ( [&op1x,&opr,&xx,this](){ + auto op1 = mkDynOutOp(op1x, ci4_1, ci4_2); + return mkGetExpr(op1,mkILoop(std::make_tuple(opr,op1,*op1.data()->mOp), std::make_tuple(ci4_1, ci4_2), + std::make_tuple(xx), + std::make_tuple(opr.assign( *op1.data()->mOp, mkMIndex(ci4_1, ci4_2) )), + std::array({1}), std::array({0}))); } ); + + //loop.dummy(); + mi->pifor(1,loop)(); auto i2_1 = imap.at("i2_1"); auto i2_2 = imap.at("i2_2");