This commit is contained in:
Christian Zimmermann 2020-08-30 23:20:09 +02:00
parent a80e9271c8
commit 3a8b837a1c
4 changed files with 144 additions and 17 deletions

View file

@ -4,33 +4,147 @@
#include "base_def.h" #include "base_def.h"
#include "dynamic_operation.h" #include "dynamic_operation.h"
#include "multi_array_operation.h"
namespace MultiArrayTools namespace MultiArrayTools
{ {
template <class DOp> template <class DOp, class... Indices>
class HLOBuilderBase class HLOBuilderBase
{ {
protected:
//typedef typename DOp::value_type IOp;
DOp mDOp;
typedef decltype(mDOp.data()->mOp) IOpP;
IOpP mIOpP;
typedef std::shared_ptr<HLOBuilderBase<DOp>> HLOBP;
HLOBP mPrev;
public: public:
virtual DOp mkDOp() const = 0;
virtual DynamicExpression mkGetExpr() const = 0; HLOBuilderBase(const HLOBP& prev) : mPrev(prev) {}
virtual void create(const std::shared_ptr<Indices>&... inds) = 0;
virtual std::shared_ptr<HLOBuilderBase<DOp,Indices...>>
operator*(const std::shared_ptr<HLOBuilderBase<DOp,Indices...>>& 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 <class Expr>
DynamicExpression mkGetExpr(const Expr& expr) const
{
if(not mPrev){
return DynamicExpression( mkGetExpr(mDOp, expr) );
}
else {
return DynamicExpression( mkGetExpr(mDOp, mPrev->mkGetExpr(expr) ) );
}
}
}; };
template <class DOp, class Op>
class HLOBuilder : public HLOBuilderBase<DOp> template <class DOp, class CF, class... Indices>
class HLOBuilder : public HLOBuilderBase<DOp,Indices...>
{ {
private: private:
typedef HLOBuilderBase<DOp,Indices...> 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<Indices>&... 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<B>
operator*(const std::shared_ptr<HLOBuilderBase<DOp,Indices...>>& in) const override final
{
HLOBP xprev = B::mPrev;
xprev->appendPrev(in->prev());
xprev->append(in);
xprev->appendPrev(std::make_shared<HLOBuilder<DOp,CF,Indices...>>(*this));
return std::make_shared<HLOBuilder<DOp,decltype(*B::mIOpP*in->mkDOp().data()->mOp),Indices...>>
(xprev, [&in,this]() { this->create(); return *B::mIOpP*in->mkDOp().data()->mOp; });
}
};
template <class DOp, class Op, class... Indices>
class HLOBuilderRoot : public HLOBuilderBase<DOp,Indices...>
{
private:
typedef HLOBuilderBase<DOp,Indices...> B;
typedef typename B::HLOBP HLOBP;
Op mOp; Op mOp;
public: public:
// ...
HLOBuilder(const Op& op) : mOp(op) {}
auto operator*(const HLOBuilderBase<DOp>& in) HLOBuilderRoot(const Op& op) : B(nullptr), mOp(op) {}
virtual void create(const std::shared_ptr<Indices>&... inds) override final
{ {
} //B::mPrev->create(inds...);
//mOp = mCF();
//B::mDOp = mkDynOutOp(op, inds...);
//B::mIOpP = B::mDOp.data()->mOp;
} }
virtual std::shared_ptr<B>
operator*(const std::shared_ptr<HLOBuilderBase<DOp,Indices...>>& in) const override final
{
HLOBP xprev = in->prev();
xprev->append(in);
//xprev->appendPrev(in.prev());
//xprev->appendPrev(std::make_shared<HLOBuilder<DOp,CF>>(*this));
return std::make_shared<HLOBuilder<DOp,decltype(mOp*in->mkDOp().data()->mOp),Indices...>>
(xprev, [&in,this]() { this->create(); return mOp*in->mkDOp().data()->mOp; });
}
};
template <class DOp, class CF,class... Indices>
std::shared_ptr<HLOBuilderBase<DOp,Indices...>>
mkHLOBuilder( const CF& cf, const std::shared_ptr<Indices>&... inds)
{
return std::make_shared<HLOBuilder<DOp,CF,Indices...>>(cf);
}
template <class DOp, class Op ,class... Indices>
std::shared_ptr<HLOBuilderBase<DOp,Indices...>>
mkHLOBuilderRoot( const Op& op, const std::shared_ptr<Indices>&... inds )
{
return std::make_shared<HLOBuilderRoot<DOp,Op,Indices...>>(op);
}
} }
#endif #endif

View file

@ -13,6 +13,7 @@
#include "map_range.h" #include "map_range.h"
#include "dynamic_operation.h" #include "dynamic_operation.h"
//#include "expressions.h" //#include "expressions.h"
#include "high_level_operation.h"
#include "multi_array_header.cc.h" #include "multi_array_header.cc.h"

View file

@ -458,6 +458,7 @@ namespace MultiArrayHelper
public: public:
typedef DExtT ExtType;
static constexpr size_t LAYER = 0; static constexpr size_t LAYER = 0;
static constexpr size_t SIZE = 0; static constexpr size_t SIZE = 0;

View file

@ -306,18 +306,29 @@ namespace
auto op1 = ma2(i1,di2); auto op1 = ma2(i1,di2);
auto op3 = ma1(i1,di1); auto op3 = ma1(i1,di1);
auto opr = resx4(i1,di4); auto opr = resx4(i1,di4);
typedef decltype(mkDynOutOp(exp(op1), ic_1, ic_2)) DOp;
auto loop = mkPILoop auto loop = mkPILoop
( [&op1,&op3,&opr,&xx,&ic_1,&ic_2,this](){ ( [&op1,&op3,&opr,&xx,&ic_1,&ic_2,this](){
auto dop1 = mkDynOutOp(exp(op1), ic_1, ic_2); //auto dop1 = mkDynOutOp(exp(op1), ic_1, ic_2);
auto op2 = *dop1.data()->mOp; //auto op2 = *dop1.data()->mOp;
auto dop2 = mkDynOutOp(op3 * op2, ic_1, ic_2); //auto dop2 = mkDynOutOp(op3 * op2, ic_1, ic_2);
auto dop2 = (*mkHLOBuilderRoot<DOp>( op3, ic_1, ic_2 )) * mkHLOBuilder<DOp>([&op1,this]() { return exp(op1); }, ic_1, ic_2);
dop2->create(ic_1,ic_2);
const OperationRoot<double,CI::RangeType,CI::RangeType>& 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<size_t,1>({1}), std::array<size_t,1>({0})));
/*
return mkGetExpr return mkGetExpr
(dop1,mkGetExpr (dop1,mkGetExpr
(dop2,mkILoop(std::make_tuple(*dop2.data()->mOp), std::make_tuple(ic_1, ic_2), (dop2,mkILoop(std::make_tuple(*dop2.data()->mOp), std::make_tuple(ic_1, ic_2),
std::make_tuple(xx), std::make_tuple(xx),
std::make_tuple(opr.assign( *dop2.data()->mOp, mkMIndex(ic_1, ic_2) )), std::make_tuple(opr.assign( *dop2.data()->mOp, mkMIndex(ic_1, ic_2) )),
std::array<size_t,1>({1}), std::array<size_t,1>({0})))); } ); std::array<size_t,1>({1}), std::array<size_t,1>({0}))));
*/
} );
mi->pifor(1,loop)(); mi->pifor(1,loop)();
auto i2_1 = imap.at("i2_1"); auto i2_1 = imap.at("i2_1");