From 529ae3353e63e2694d5f195f5dd59a70fd5182e0 Mon Sep 17 00:00:00 2001 From: Christian Zimmermann Date: Tue, 9 Jan 2018 17:24:10 +0100 Subject: [PATCH] some implementations reg FOR-utilities (step-array creation still missing) --- src/multi_array_operation.h | 115 ++++++++++++++++++++++++++++------- src/pack_num.h | 27 +++++++- src/ranges/container_range.h | 16 ++--- src/ranges/multi_range.h | 14 ++--- src/ranges/rpack_num.h | 19 +++--- src/ranges/single_range.h | 12 ++-- src/xfor/xfor.h | 50 +++++++++++++-- 7 files changed, 194 insertions(+), 59 deletions(-) diff --git a/src/multi_array_operation.h b/src/multi_array_operation.h index a89804a..bc4af02 100644 --- a/src/multi_array_operation.h +++ b/src/multi_array_operation.h @@ -50,7 +50,7 @@ namespace MultiArrayTools OperationClass& THIS() { return static_cast(*this); } const OperationClass& THIS() const { return static_cast(*this); } - + template auto operator+(const Second& in) const -> Operation,OperationClass,Second>; @@ -84,7 +84,9 @@ namespace MultiArrayTools class AssignmentExpr { public: - AssignmentExpr(OperationMaster* mPtr, OpClass* secPtr); + static size_t layer() { return 0; } + + AssignmentExpr(OperationMaster* mPtr, const OpClass* secPtr); AssignmentExpr(AssignmentExpr&& in) = default; AssignmentExpr& operator=(AssignmentExpr&& in) = default; @@ -95,7 +97,7 @@ namespace MultiArrayTools AssignmentExpr() = default; OperationMaster* mMPtr; - OpClass* mSecPtr; + const OpClass* mSecPtr; }; typedef T value_type; @@ -103,6 +105,8 @@ namespace MultiArrayTools typedef ContainerRange CRange; typedef typename MultiRange::IndexType IndexType; typedef MBlock bType; + + static size_t rootNum() { return 1; } OperationMaster(MutableMultiArrayBase& ma, const OpClass& second, std::shared_ptr& index); @@ -117,7 +121,7 @@ namespace MultiArrayTools std::vector block(const IndexInfo* blockIndex, bool init = false) const; const OperationMaster& block() const; - protected: + private: std::shared_ptr mkIndex(std::shared_ptr& index); void performAssignment(std::intptr_t blockIndexNum); @@ -141,6 +145,8 @@ namespace MultiArrayTools typedef ContainerRange CRange; typedef typename CRange::IndexType IndexType; typedef Block bType; + + static size_t rootNum() { return 1; } ConstOperationRoot(const MultiArrayBase& ma, const std::shared_ptr&... indices); @@ -149,8 +155,10 @@ namespace MultiArrayTools std::vector block(const IndexInfo* blockIndex, bool init = false) const; const ConstOperationRoot& block() const; + + std::tuple rootSteps(const IndexInfo* ii = nullptr) const; // nullptr for simple usage with decltype - protected: + private: std::shared_ptr mkIndex(const MultiArrayBase& ma, @@ -174,6 +182,8 @@ namespace MultiArrayTools typedef typename CRange::IndexType IndexType; typedef MBlock bType; + static size_t rootNum() { return 1; } + OperationRoot(MutableMultiArrayBase& ma, const std::shared_ptr&... indices); @@ -186,8 +196,10 @@ namespace MultiArrayTools OperationRoot& set(const IndexInfo* blockIndex); std::vector block(const IndexInfo* blockIndex, bool init = false) const; const OperationRoot& block() const; + + std::tuple rootSteps(const IndexInfo* ii = nullptr) const; // nullptr for simple usage with decltype - protected: + private: std::shared_ptr mkIndex(const MultiArrayBase& ma, @@ -199,6 +211,18 @@ namespace MultiArrayTools mutable bType mBlock; const IndexInfo* mBlockII; // predefine to save time }; + + template + size_t sumRootNum() + { + return typename Op::rootNum(); + } + + template + size_t sumRootNum() + { + return typename Op1::rootNum() + sumRootNum(); + } template class Operation : public OperationTemplate > @@ -210,17 +234,24 @@ namespace MultiArrayTools typedef OperationTemplate > OT; typedef OpFunction F; typedef BlockResult bType; - + + static size_t rootNum() { return sumRootNum(); } + + private: + std::tuple mOps; + mutable bType mRes; + + public: Operation(const Ops&... ops); const BlockResult& get() const; std::vector block(const IndexInfo* blockIndex, bool init = false) const; const Operation& block() const; + + auto rootSteps(const IndexInfo* ii = nullptr) const // nullptr for simple usage with decltype + -> decltype(PackNum::mkStepTuple(ii, mOps)); - protected: - std::tuple mOps; - mutable bType mRes; }; template @@ -231,19 +262,26 @@ namespace MultiArrayTools typedef T value_type; typedef OperationTemplate > OT; typedef BlockResult bType; - + + static size_t rootNum() { return typename Op::rootNum(); } + + private: + + const Op& mOp; + std::shared_ptr mInd; + mutable bType mRes; + + public: Contraction(const Op& op, std::shared_ptr ind); const BlockResult& get() const; std::vector block(const IndexInfo* blockIndex, bool init = false) const; const Contraction& block() const; - - protected: - const Op& mOp; - std::shared_ptr mInd; - mutable bType mRes; + auto rootSteps(const IndexInfo* ii = nullptr) const // nullptr for simple usage with decltype + -> decltype(mOp.rootSteps(ii)); + }; } @@ -399,13 +437,21 @@ namespace MultiArrayTools template void OperationMaster::performAssignment(std::intptr_t blockIndexNum) { - //static auto loop = mkLoop(mIndex, *this, mSecond); - //loop(); - +#ifdef XX_USE_NEW_LOOP_ROUTINE_XX + // === N E W === + AssignmentExpr ae(this, &mSecond); + typedef decltype(mSecond.rootSteps()) RootStepType; + std::array + ee(PackNum::mkExt(mIndex, mSecond)); + static auto loop = mIndex->ifor(ee, ae); + loop(); +#else + // === O L D === for(*mIndex = 0; mIndex->pos() != mIndex->max(); mIndex->pp(blockIndexNum) ){ block(); get() = mSecond.get(); } +#endif } template @@ -437,7 +483,7 @@ namespace MultiArrayTools mBlock.set( mIndex->pos() ); return *this; } - + /**************************** * ConstOperationRoot * ****************************/ @@ -484,6 +530,12 @@ namespace MultiArrayTools mBlock.set( (*mIndex)().pos() ); return *this; } + + template + std::tuple ConstOperationRoot::rootSteps(const IndexInfo* ii) const + { + return std::tuple(0ul); // !!!!!! + } /*********************** * OperationRoot * @@ -559,6 +611,12 @@ namespace MultiArrayTools mBlock.set( (*mIndex)().pos() ); return *this; } + + template + std::tuple OperationRoot::rootSteps(const IndexInfo* ii) const + { + return std::tuple(0ul); // !!!!!! + } /******************* * Operation * @@ -595,6 +653,14 @@ namespace MultiArrayTools return *this; } + template + auto Operation::rootSteps(const IndexInfo* ii) const + -> decltype(PackNum::mkStepTuple(ii, mOps)) + { + return PackNum::mkStepTuple(ii, mOps); + } + + /********************* * Contraction * *********************/ @@ -629,7 +695,14 @@ namespace MultiArrayTools { return *this; } - + + template + auto Contraction::rootSteps(const IndexInfo* ii) const + -> decltype(mOp.rootSteps(ii)) + { + return mOp.rootSteps(ii); + } + } #endif diff --git a/src/pack_num.h b/src/pack_num.h index 0c4b8e0..a7dc0db 100644 --- a/src/pack_num.h +++ b/src/pack_num.h @@ -44,11 +44,24 @@ namespace MultiArrayHelper } template - static void printTuple(std::ostream& out, const std::tuple& tp){ + static void printTuple(std::ostream& out, const std::tuple& tp) + { out << std::get(tp) << ", "; PackNum::printTuple(out, tp); } + template + static auto mkStepTuple(const IndexInfo* ii, std::tuple otp) + -> decltype(std::tuple_cat( PackNum::mkStepTuple(ii, otp), std::get(otp).rootSteps(ii) )) + { + return std::tuple_cat( PackNum::mkStepTuple(ii, otp), std::get(otp).rootSteps(ii) ); + } + /* + template + static auto mkExt(const std::shared_ptr& idxPtr, const OpClass& second) + { + // !!!!! + }*/ }; template<> @@ -83,10 +96,18 @@ namespace MultiArrayHelper } template - static void printTuple(std::ostream& out, const std::tuple& tp){ + static void printTuple(std::ostream& out, const std::tuple& tp) + { out << std::get(tp); } - + + template + static auto mkStepTuple(const IndexInfo* ii, std::tuple otp) + -> decltype(std::get<0>(otp).rootSteps(ii)) + { + return std::get<0>(otp).rootSteps(ii); + } + }; diff --git a/src/ranges/container_range.h b/src/ranges/container_range.h index a2662c0..e1d38cb 100644 --- a/src/ranges/container_range.h +++ b/src/ranges/container_range.h @@ -87,10 +87,10 @@ namespace MultiArrayTools std::string id(); void print(size_t offset); - - template - auto ifor(Exprs&&... exs) const - -> decltype(RPackNum::mkFor(mIPack, exs...)); + + template + auto ifor(const Ext& ext, Exprs&& exs) const + -> decltype(RPackNum::mkFor(mIPack, ext, exs)); }; @@ -371,11 +371,11 @@ namespace MultiArrayTools } template - template - auto ContainerIndex::ifor(Exprs&&... exs) const - -> decltype(RPackNum::mkFor(mIPack, exs...)) + template + auto ContainerIndex::ifor(const Ext& ext, Exprs&& exs) const + -> decltype(RPackNum::mkFor(mIPack, ext, exs)) { - return RPackNum::mkFor(mIPack, exs...); + return RPackNum::mkFor(mIPack, ext, exs); } diff --git a/src/ranges/multi_range.h b/src/ranges/multi_range.h index 28735ce..0b02516 100644 --- a/src/ranges/multi_range.h +++ b/src/ranges/multi_range.h @@ -104,9 +104,9 @@ namespace MultiArrayTools std::string id(); void print(size_t offset); - template - auto ifor(Exprs&&... exs) const - -> decltype(RPackNum::mkFor(mIPack, exs...)); + template + auto ifor(const Ext& ext, Exprs&& exs) const + -> decltype(RPackNum::mkFor(mIPack, ext, exs)); }; /************************* @@ -415,11 +415,11 @@ namespace MultiArrayTools } template - template - auto MultiIndex::ifor(Exprs&&... exs) const - -> decltype(RPackNum::mkFor(mIPack, exs...)) + template + auto MultiIndex::ifor(const Ext& ext, Exprs&& exs) const + -> decltype(RPackNum::mkFor(mIPack, ext, exs)) { - return RPackNum::mkFor(mIPack, exs...); + return RPackNum::mkFor(mIPack, ext, exs); } /************************* diff --git a/src/ranges/rpack_num.h b/src/ranges/rpack_num.h index 0bcdf17..d3af73f 100644 --- a/src/ranges/rpack_num.h +++ b/src/ranges/rpack_num.h @@ -219,14 +219,13 @@ namespace MultiArrayHelper RPackNum::buildInfoVec(out, ip, bs); } - template - static auto mkFor(const IndexPack& ipack, Exprs&&... exs) + template + static auto mkFor(const IndexPack& ipack, const Ext& ext, Exprs&& exs) -> decltype(std::get::value-N>(ipack) - ->ifor(RPackNum::template mkFor - (ipack, exs...) ) ) + ->ifor(ext, RPackNum::mkFor(ipack, ext, exs) ) ) { return std::get::value-N>(ipack) - ->ifor( RPackNum::template mkFor(ipack, exs...) ); + ->ifor( ext, RPackNum::mkFor(ipack, ext, exs) ); } }; @@ -392,12 +391,12 @@ namespace MultiArrayHelper out.emplace_back(*std::get(ip), std::get(bs)); } - template - static auto mkFor(const IndexPack& ipack, Exprs&&... exs) - -> decltype(std::get::value-1>(ipack) - ->ifor(exs...) ) + template + static auto mkFor(const IndexPack& ipack, const Ext& ext, Exprs&& exs) + -> decltype(std::get::value-1>(ipack, ext) + ->ifor(ext, exs) ) { - return std::get::value-1>(ipack)->ifor(exs...); + return std::get::value-1>(ipack)->ifor(ext, exs); } }; diff --git a/src/ranges/single_range.h b/src/ranges/single_range.h index 40f6fea..b453c4c 100644 --- a/src/ranges/single_range.h +++ b/src/ranges/single_range.h @@ -64,8 +64,8 @@ namespace MultiArrayTools std::string id(); void print(size_t offset); - template - auto ifor(std::tuple...>&& ee, Expr&& ex) const + template + auto ifor(const std::array...>,DIM>& ee, Expr&& ex) const -> For,Expr,Ops...>; }; @@ -248,12 +248,12 @@ namespace MultiArrayTools } template - template - auto SingleIndex::ifor(std::tuple...>&& ee, Expr&& ex) const + template + auto SingleIndex::ifor(const std::array...>,DIM>& ee, Expr&& ex) const -> For,Expr,Ops...> { - return For,Expr> - ( std::make_shared >(*this), ex, ee ); + static const size_t layer = typename Expr::layer(); + return For,Expr,Ops...>( this, ex, std::get( ee ) ); } diff --git a/src/xfor/xfor.h b/src/xfor/xfor.h index 1dd9099..26ffda3 100644 --- a/src/xfor/xfor.h +++ b/src/xfor/xfor.h @@ -15,6 +15,8 @@ namespace MultiArrayHelper { public: + static size_t layer() { return typename Expr::layer() + 1; } + For(For&& in) = default; For& operator=(For&& in) = default; @@ -24,18 +26,32 @@ namespace MultiArrayHelper For(const std::shared_ptr& indPtr, Expr&& expr, std::tuple...>&& ext); + + template + For(IndexClass* indPtr, + std::tuple...>&& ext, const Args&... args); + + For(IndexClass* indPtr, + Expr&& expr, std::tuple...>&& ext); + inline void operator()(size_t mlast, const std::tuple...>& last) const; + inline void operator()(size_t mlast = 0) const; private: For() = default; - mutable std::shared_ptr mIndPtr; + IndexClass* mIndPtr; const Expr mExpr; const std::tuple...> mExt; }; - + template + size_t exceptMax(size_t max) { return max; } + + template <> + size_t exceptMax<1>(size_t max) { return 1; } + } // namespace MultiArrayHelper @@ -51,11 +67,23 @@ namespace MultiArrayHelper For::For(const std::shared_ptr& indPtr, std::tuple...>&& ext, const Args&... args) : - mIndPtr(indPtr), mExpr(args...), mExt(ext) {} + mIndPtr(indPtr.get()), mExpr(args...), mExt(ext) {} template For::For(const std::shared_ptr& indPtr, Expr&& expr, std::tuple...>&& ext) : + mIndPtr(indPtr.get()), mExpr(expr), mExt(ext) {} + + template + template + For::For(IndexClass* indPtr, + std::tuple...>&& ext, + const Args&... args) : + mIndPtr(indPtr), mExpr(args...), mExt(ext) {} + + template + For::For(IndexClass* indPtr, + Expr&& expr, std::tuple...>&& ext) : mIndPtr(indPtr), mExpr(expr), mExt(ext) {} template @@ -64,7 +92,21 @@ namespace MultiArrayHelper { static const size_t opNum = sizeof...(Ops); auto& ind = *mIndPtr; - const size_t max = ind.max(); + const size_t max = exceptMax::layer()>( ind.max() ); // blocking + for(ind = 0; ind.pos() != max; ++ind){ + const size_t mnpos = mlast * max + ind.pos(); + const std::tuple...> npos = std::move( XFPackNum::mkPos(ind, mExt, last) ); + mExpr(mnpos, npos); + } + } + + template + inline void For::operator()(size_t mlast) const + { + static const size_t opNum = sizeof...(Ops); + std::tuple...> last(to_size_t(0)...); + auto& ind = *mIndPtr; + const size_t max = exceptMax::layer()>( ind.max() ); // blocking for(ind = 0; ind.pos() != max; ++ind){ const size_t mnpos = mlast * max + ind.pos(); const std::tuple...> npos = std::move( XFPackNum::mkPos(ind, mExt, last) );