diff --git a/src/include/high_level_operation.h b/src/include/high_level_operation.h index 5dfb116..0bad1b8 100644 --- a/src/include/high_level_operation.h +++ b/src/include/high_level_operation.h @@ -4,33 +4,147 @@ #include "base_def.h" #include "dynamic_operation.h" +#include "multi_array_operation.h" namespace MultiArrayTools { - template + template class HLOBuilderBase { - + protected: + //typedef typename DOp::value_type IOp; + DOp mDOp; + typedef decltype(mDOp.data()->mOp) IOpP; + IOpP mIOpP; + typedef std::shared_ptr> HLOBP; + HLOBP mPrev; public: - virtual DOp mkDOp() const = 0; - virtual DynamicExpression mkGetExpr() const = 0; + + HLOBuilderBase(const HLOBP& prev) : mPrev(prev) {} + + virtual void create(const std::shared_ptr&... inds) = 0; + + virtual std::shared_ptr> + operator*(const std::shared_ptr>& in) const = 0; + + const IOpP& get() const + { + return mIOpP; + } + + const DOp& dget() const + { + return mDOp; + } + + const HLOBP& prev() const + { + return mPrev; + } + + void appendPrev(const HLOBP& prev) + { + if(mPrev){ + mPrev->append(prev); + } + else { + mPrev = prev; + } + } + + template + DynamicExpression mkGetExpr(const Expr& expr) const + { + if(not mPrev){ + return DynamicExpression( mkGetExpr(mDOp, expr) ); + } + else { + return DynamicExpression( mkGetExpr(mDOp, mPrev->mkGetExpr(expr) ) ); + } + } }; - template - class HLOBuilder : public HLOBuilderBase + + template + class HLOBuilder : public HLOBuilderBase { private: + typedef HLOBuilderBase B; + typedef typename B::HLOBP HLOBP; + CF mCF; + public: + + HLOBuilder(const HLOBP& prev, + const CF& cf) : B(prev), mCF(cf) {} + + HLOBuilder(const CF& cf) : B(nullptr), mCF(cf) {} + + virtual void create(const std::shared_ptr&... inds) override final + { + B::mPrev->create(inds...); + auto op = mCF(); + B::mDOp = mkDynOutOp(op, inds...); + B::mIOpP = B::mDOp.data()->mOp; + } + + virtual std::shared_ptr + operator*(const std::shared_ptr>& in) const override final + { + HLOBP xprev = B::mPrev; + xprev->appendPrev(in->prev()); + xprev->append(in); + xprev->appendPrev(std::make_shared>(*this)); + return std::make_sharedmkDOp().data()->mOp),Indices...>> + (xprev, [&in,this]() { this->create(); return *B::mIOpP*in->mkDOp().data()->mOp; }); + } + }; + + + template + class HLOBuilderRoot : public HLOBuilderBase + { + private: + typedef HLOBuilderBase B; + typedef typename B::HLOBP HLOBP; Op mOp; public: - // ... - HLOBuilder(const Op& op) : mOp(op) {} - - auto operator*(const HLOBuilderBase& in) + + HLOBuilderRoot(const Op& op) : B(nullptr), mOp(op) {} + + virtual void create(const std::shared_ptr&... inds) override final { + //B::mPrev->create(inds...); + //mOp = mCF(); + //B::mDOp = mkDynOutOp(op, inds...); + //B::mIOpP = B::mDOp.data()->mOp; } + + virtual std::shared_ptr + operator*(const std::shared_ptr>& in) const override final + { + HLOBP xprev = in->prev(); + xprev->append(in); + //xprev->appendPrev(in.prev()); + //xprev->appendPrev(std::make_shared>(*this)); + return std::make_sharedmkDOp().data()->mOp),Indices...>> + (xprev, [&in,this]() { this->create(); return mOp*in->mkDOp().data()->mOp; }); + } + }; + + template + std::shared_ptr> + mkHLOBuilder( const CF& cf, const std::shared_ptr&... inds) + { + return std::make_shared>(cf); + } + + template + std::shared_ptr> + mkHLOBuilderRoot( const Op& op, const std::shared_ptr&... inds ) + { + return std::make_shared>(op); } - } #endif diff --git a/src/include/multi_array_header.h b/src/include/multi_array_header.h index 95ffbc5..6b62fbb 100644 --- a/src/include/multi_array_header.h +++ b/src/include/multi_array_header.h @@ -13,6 +13,7 @@ #include "map_range.h" #include "dynamic_operation.h" //#include "expressions.h" +#include "high_level_operation.h" #include "multi_array_header.cc.h" diff --git a/src/include/xfor/xfor.h b/src/include/xfor/xfor.h index 1bffc0f..31e94e5 100644 --- a/src/include/xfor/xfor.h +++ b/src/include/xfor/xfor.h @@ -457,7 +457,8 @@ namespace MultiArrayHelper std::shared_ptr mNext; public: - + + typedef DExtT ExtType; static constexpr size_t LAYER = 0; static constexpr size_t SIZE = 0; diff --git a/src/tests/op4_unit_test.cc b/src/tests/op4_unit_test.cc index 253fedf..418388b 100644 --- a/src/tests/op4_unit_test.cc +++ b/src/tests/op4_unit_test.cc @@ -306,18 +306,29 @@ namespace auto op1 = ma2(i1,di2); auto op3 = ma1(i1,di1); auto opr = resx4(i1,di4); + typedef decltype(mkDynOutOp(exp(op1), ic_1, ic_2)) DOp; auto loop = mkPILoop ( [&op1,&op3,&opr,&xx,&ic_1,&ic_2,this](){ - auto dop1 = mkDynOutOp(exp(op1), ic_1, ic_2); - auto op2 = *dop1.data()->mOp; - auto dop2 = mkDynOutOp(op3 * op2, ic_1, ic_2); + //auto dop1 = mkDynOutOp(exp(op1), ic_1, ic_2); + //auto op2 = *dop1.data()->mOp; + //auto dop2 = mkDynOutOp(op3 * op2, ic_1, ic_2); + auto dop2 = (*mkHLOBuilderRoot( op3, ic_1, ic_2 )) * mkHLOBuilder([&op1,this]() { return exp(op1); }, ic_1, ic_2); + dop2->create(ic_1,ic_2); + const OperationRoot& yy = *dop2->get(); + return dop2->mkGetExpr + (mkILoop(std::make_tuple(dop2->dget()), std::make_tuple(ic_1, ic_2), + std::make_tuple(xx), + std::make_tuple(opr.assign( yy , mkMIndex(ic_1, ic_2) )), + std::array({1}), std::array({0}))); + /* return mkGetExpr (dop1,mkGetExpr (dop2,mkILoop(std::make_tuple(*dop2.data()->mOp), std::make_tuple(ic_1, ic_2), std::make_tuple(xx), std::make_tuple(opr.assign( *dop2.data()->mOp, mkMIndex(ic_1, ic_2) )), - std::array({1}), std::array({0})))); } ); - + std::array({1}), std::array({0})))); + */ + } ); mi->pifor(1,loop)(); auto i2_1 = imap.at("i2_1");