dynamic operations: partial static call works consistently

This commit is contained in:
Christian Zimmermann 2020-08-28 17:55:54 +02:00
parent cb6a6ccdb3
commit 67b343d217
6 changed files with 119 additions and 41 deletions

View file

@ -47,29 +47,25 @@ namespace MultiArrayTools
: mOp(op), : mOp(op),
mMa(std::make_shared<MultiArray<T,Ranges...>>(mkArray<T>(inds->range()...))), mMa(std::make_shared<MultiArray<T,Ranges...>>(mkArray<T>(inds->range()...))),
mProto(OperationRoot<T,Ranges...>(*mMa,inds...)), mProto(OperationRoot<T,Ranges...>(*mMa,inds...)),
mL(std::make_tuple(mProto.mOp,mOp), std::make_tuple(inds...), mL(std::make_tuple(*mProto.mOp,mOp), std::make_tuple(inds...),
std::make_tuple(mMa), std::make_tuple(mProto.mOp.assign( mOp )), std::make_tuple(mMa), std::make_tuple(mProto.mOp->assign( mOp, mkMIndex(inds...) )),
std::array<size_t,1>({0}), std::array<size_t,1>({0})) std::array<size_t,1>({1}), std::array<size_t,1>({0}))
{ {
VCHECK(reinterpret_cast<std::intptr_t>(mProto.mOp.data())); *mMa = 0;
VCHECK(reinterpret_cast<std::intptr_t>(mMa->data()));
} }
template <typename T, class Operation, class... Ranges> template <typename T, class Operation, class... Ranges>
OpH<OperationRoot<T,Ranges...>> DynamicOuterOp<T,Operation,Ranges...>::get(const DExtT& pos) const OpH<OperationRoot<T,Ranges...>> DynamicOuterOp<T,Operation,Ranges...>::get(const DExtT& pos) const
{ {
CHECK; mL(0,pos.expl<ET>());
//mOp.get(pos.expl<ET>());
//mL(0,pos.expl<ET>());
// execute assignment... care about threads!!! // execute assignment... care about threads!!!
return mProto.mOp; // empty return mProto; // empty
} }
template <typename T, class Operation, class... Ranges> template <typename T, class Operation, class... Ranges>
DynamicOperationBase<OpH<OperationRoot<T,Ranges...>>>& DynamicOperationBase<OpH<OperationRoot<T,Ranges...>>>&
DynamicOuterOp<T,Operation,Ranges...>::set(const DExtT& pos) DynamicOuterOp<T,Operation,Ranges...>::set(const DExtT& pos)
{ {
CHECK;
mOp.set(pos.expl<ET>()); mOp.set(pos.expl<ET>());
return *this; return *this;
} }
@ -77,21 +73,18 @@ namespace MultiArrayTools
template <typename T, class Operation, class... Ranges> template <typename T, class Operation, class... Ranges>
DExtT DynamicOuterOp<T,Operation,Ranges...>::rootSteps(std::intptr_t iPtrNum) const DExtT DynamicOuterOp<T,Operation,Ranges...>::rootSteps(std::intptr_t iPtrNum) const
{ {
CHECK;
return DExtT(mkDExt(mkExtT(mL.rootSteps(iPtrNum))),None(0)); return DExtT(mkDExt(mkExtT(mL.rootSteps(iPtrNum))),None(0));
} }
template <typename T, class Operation, class... Ranges> template <typename T, class Operation, class... Ranges>
DynamicExpression DynamicOuterOp<T,Operation,Ranges...>::loop(const DynamicExpression& exp) const DynamicExpression DynamicOuterOp<T,Operation,Ranges...>::loop(const DynamicExpression& exp) const
{ {
CHECK;
return mOp.loop(exp); // ???!! return mOp.loop(exp); // ???!!
} }
template <typename T, class Operation, class... Ranges> template <typename T, class Operation, class... Ranges>
const OpH<OperationRoot<T,Ranges...>>* DynamicOuterOp<T,Operation,Ranges...>::data() const const OpH<OperationRoot<T,Ranges...>>* DynamicOuterOp<T,Operation,Ranges...>::data() const
{ {
CHECK;
return &mProto; return &mProto;
} }
@ -99,7 +92,6 @@ namespace MultiArrayTools
std::shared_ptr<DynamicOperationBase<OpH<OperationRoot<T,Ranges...>>>> std::shared_ptr<DynamicOperationBase<OpH<OperationRoot<T,Ranges...>>>>
DynamicOuterOp<T,Operation,Ranges...>::deepCopy() const DynamicOuterOp<T,Operation,Ranges...>::deepCopy() const
{ {
CHECK;
return std::make_shared<DynamicOuterOp<T,Operation,Ranges...>>(*this); return std::make_shared<DynamicOuterOp<T,Operation,Ranges...>>(*this);
} }

View file

@ -61,8 +61,9 @@ namespace MultiArrayTools
template <class Op> template <class Op>
struct OpH struct OpH
{ {
Op mOp; std::shared_ptr<Op> mOp;
OpH(const Op& op) : mOp(op) {} OpH(const Op& op) : mOp(std::make_shared<Op>(op)) {}
}; };
template <typename T, class Operation, class... Ranges> template <typename T, class Operation, class... Ranges>
@ -77,7 +78,7 @@ namespace MultiArrayTools
typedef ILoop<std::tuple<OperationRoot<T,Ranges...>,Operation>, typedef ILoop<std::tuple<OperationRoot<T,Ranges...>,Operation>,
std::tuple<std::shared_ptr<typename Ranges::IndexType>...>, std::tuple<std::shared_ptr<typename Ranges::IndexType>...>,
std::tuple<std::shared_ptr<MultiArray<T,Ranges...>>>, std::tuple<std::shared_ptr<MultiArray<T,Ranges...>>>,
std::tuple<decltype(mProto.mOp.assign( mOp ))>> LoopT; std::tuple<decltype(mProto.mOp->assign( mOp, mkMIndex(std::shared_ptr<typename Ranges::IndexType>()...) ))>> LoopT;
mutable LoopT mL; mutable LoopT mL;

View file

@ -211,6 +211,52 @@ namespace MultiArrayTools
return nullptr; //???!!! return nullptr; //???!!!
} }
template <class OpClass, class NextExpr>
GetExpr<OpClass,NextExpr>::GetExpr(const OpClass& sec, const NextExpr& nexpr) :
mSec(sec), mNExpr(nexpr) {}
template <class OpClass, class NextExpr>
inline void GetExpr<OpClass,NextExpr>::operator()(size_t start)
{
ExtType last = rootSteps();
last.zero();
mSec.get(last);
mNExpr(start,last.next());
}
template <class OpClass, class NextExpr>
inline void GetExpr<OpClass,NextExpr>::operator()(size_t start, ExtType last)
{
mSec.get(last);
mNExpr(start,last.next());
}
template <class OpClass, class NextExpr>
typename GetExpr<OpClass,NextExpr>::ExtType
GetExpr<OpClass,NextExpr>::rootSteps(std::intptr_t iPtrNum) const
{
return mSec.rootSteps(iPtrNum).extend( mNExpr.rootSteps(iPtrNum) );
}
template <class OpClass, class NextExpr>
inline void GetExpr<OpClass,NextExpr>::operator()(size_t mlast, DExt last)
{
(*this)(mlast, std::dynamic_pointer_cast<ExtT<ExtType>>(last)->ext());
}
template <class OpClass, class NextExpr>
inline DExt GetExpr<OpClass,NextExpr>::dRootSteps(std::intptr_t iPtrNum) const
{
return std::make_shared<ExtT<ExtType>>(rootSteps(iPtrNum));
}
template <class OpClass, class NextExpr>
inline DExt GetExpr<OpClass,NextExpr>::dExtension() const
{
CHECK;
return nullptr; //???!!!
}
template <typename T, class Target, class OpClass, OpIndexAff OIA> template <typename T, class Target, class OpClass, OpIndexAff OIA>
AddExpr<T,Target,OpClass,OIA>::AddExpr(T* dataPtr, const Target& tar, const OpClass& sec) : AddExpr<T,Target,OpClass,OIA>::AddExpr(T* dataPtr, const Target& tar, const OpClass& sec) :
mTar(tar), mSec(sec), mDataPtr(dataPtr) {} mTar(tar), mSec(sec), mDataPtr(dataPtr) {}

View file

@ -142,6 +142,41 @@ namespace MultiArrayTools
inline DExt dExtension() const override final; inline DExt dExtension() const override final;
}; };
template <class OpClass, class NextExpr>
class GetExpr : public ExpressionBase
{
private:
GetExpr() = default;
OpClass mSec;
NextExpr mNExpr;
public:
static constexpr size_t LAYER = 0;
static constexpr size_t SIZE = OpClass::SIZE + NextExpr::SIZE;
typedef decltype(mSec.rootSteps(0).extend( mNExpr.rootSteps(0) ) ) ExtType;
GetExpr(const OpClass& sec, const NextExpr& nexpr);
GetExpr(const GetExpr& in) = default;
GetExpr(GetExpr&& in) = default;
inline void operator()(size_t start = 0);
inline void operator()(size_t start, ExtType last);
auto rootSteps(std::intptr_t iPtrNum = 0) const -> ExtType;
inline void operator()(size_t mlast, DExt last) override final;
inline DExt dRootSteps(std::intptr_t iPtrNum = 0) const override final;
inline DExt dExtension() const override final;
};
template <class OpClass, class NextExpr>
auto mkGetExpr(const OpClass& op, const NextExpr& nexpr)
{
return GetExpr<OpClass,NextExpr>(op, nexpr);
}
//template <typename T, class OpClass> //template <typename T, class OpClass>
template <typename T, class Target, class OpClass, OpIndexAff OIA=OpIndexAff::EXTERN> template <typename T, class Target, class OpClass, OpIndexAff OIA=OpIndexAff::EXTERN>
class AddExpr : public ExpressionBase class AddExpr : public ExpressionBase

View file

@ -102,6 +102,9 @@ namespace MultiArrayHelper
private: private:
mutable DExt mDExt = nullptr; mutable DExt mDExt = nullptr;
X mNext; X mNext;
template <class Y>
friend class DExtTX;
public: public:
static constexpr size_t NUM = X::SIZE; static constexpr size_t NUM = X::SIZE;
static constexpr size_t SIZE = NUM + 1; static constexpr size_t SIZE = NUM + 1;
@ -119,7 +122,11 @@ namespace MultiArrayHelper
template <class Y> template <class Y>
DExtTX(const Y& y) : mDExt(std::make_shared<ExtT<Y>>(y)) {} DExtTX(const Y& y) : mDExt(std::make_shared<ExtT<Y>>(y)) {}
*/ */
explicit DExtTX(const DExt& y, const X& x) : mDExt(y->deepCopy()),
template <class Y>
DExtTX(const DExtTX<Y>& in) : mDExt(in.mDExt), mNext(in.mNext) {}
DExtTX(const DExt& y, const X& x) : mDExt(y->deepCopy()),
mNext(x) {} mNext(x) {}
virtual size_t size() const { return mDExt->size(); } virtual size_t size() const { return mDExt->size(); }

View file

@ -53,10 +53,11 @@ namespace
std::map<std::string,std::shared_ptr<IndexW>> imap; std::map<std::string,std::shared_ptr<IndexW>> imap;
std::shared_ptr<DR> dr1; std::shared_ptr<DR> dr1;
std::shared_ptr<DR> dr1a; //std::shared_ptr<DR> dr1a;
std::shared_ptr<DR> dr2; std::shared_ptr<DR> dr2;
std::shared_ptr<DR> dr3; std::shared_ptr<DR> dr3;
std::shared_ptr<DR> dr4; std::shared_ptr<DR> dr4;
std::shared_ptr<DR> dr4a;
std::shared_ptr<DR> dr5; std::shared_ptr<DR> dr5;
std::shared_ptr<DR> dr6; std::shared_ptr<DR> dr6;
std::shared_ptr<CR> cr1; std::shared_ptr<CR> cr1;
@ -73,13 +74,14 @@ namespace
auto cr5 = createRangeE<CR>(13); auto cr5 = createRangeE<CR>(13);
dr1 = createRangeE<DR>(cr2,cr2,cr3,cr4); dr1 = createRangeE<DR>(cr2,cr2,cr3,cr4);
dr1a = createRangeE<DR>(cr2,cr2,cr3); //dr1a = createRangeE<DR>(cr2,cr2,cr3);
dr2 = createRangeE<DR>(cr3,cr3,cr4); dr2 = createRangeE<DR>(cr3,cr3,cr4);
dr3 = createRangeE<DR>(cr2,cr5); dr3 = createRangeE<DR>(cr2,cr5);
dr5 = createRangeE<DR>(cr5); dr5 = createRangeE<DR>(cr5);
dr6 = createRangeE<DR>(cr3,cr4); dr6 = createRangeE<DR>(cr3,cr4);
dr4 = createRangeE<DR>(cr2,cr3,cr4,cr4); dr4 = createRangeE<DR>(cr2,cr3,cr4,cr4);
dr4a = createRangeE<DR>(cr2,cr3,cr4);
ma1 = mkArray<double>(cr1,dr1); ma1 = mkArray<double>(cr1,dr1);
ma2 = mkArray<double>(cr1,dr2); ma2 = mkArray<double>(cr1,dr2);
@ -99,8 +101,8 @@ namespace
imap["i3_1"] = mkIndexW(getIndex(cr3)); imap["i3_1"] = mkIndexW(getIndex(cr3));
imap["i3_2"] = mkIndexW(getIndex(cr3)); imap["i3_2"] = mkIndexW(getIndex(cr3));
ci4 = getIndex(cr4); ci4 = getIndex(cr4);
imap["i4_1"] = mkIndexW(ci4); imap["i4_1"] = mkIndexW(getIndex(cr4));
imap["i4_2"] = mkIndexW(getIndex(cr4)); imap["i4_2"] = mkIndexW(ci4);
imap["i5_1"] = mkIndexW(getIndex(cr5)); imap["i5_1"] = mkIndexW(getIndex(cr5));
imap["i5_2"] = mkIndexW(getIndex(cr5)); imap["i5_2"] = mkIndexW(getIndex(cr5));
} }
@ -110,16 +112,18 @@ namespace
{ {
auto i1 = getIndex(cr1); auto i1 = getIndex(cr1);
auto di1 = getIndex(dr1); auto di1 = getIndex(dr1);
auto di1a = getIndex(dr1a); //auto di1a = getIndex(dr1a);
auto di2 = getIndex(dr2); auto di2 = getIndex(dr2);
auto di4 = getIndex(dr4); auto di4 = getIndex(dr4);
auto di4a = getIndex(dr4a);
auto mi = mkMIndex(i1,di1a);
(*di1)({imap["i2_1"],imap["i2_2"],imap["i3_1"],imap["i4_1"]}); (*di1)({imap["i2_1"],imap["i2_2"],imap["i3_1"],imap["i4_1"]});
(*di1a)({imap["i2_1"],imap["i2_2"],imap["i3_1"]}); //(*di1a)({imap["i2_1"],imap["i2_2"],imap["i3_1"]});
(*di2)({imap["i3_1"],imap["i3_1"],imap["i4_2"]}); (*di2)({imap["i3_1"],imap["i3_1"],imap["i4_2"]});
(*di4)({imap["i2_1"],imap["i3_1"],imap["i4_1"],imap["i4_2"]}); (*di4)({imap["i2_1"],imap["i3_1"],imap["i4_1"],imap["i4_2"]});
(*di4a)({imap["i2_1"],imap["i3_1"],imap["i4_1"]});
auto mi = mkMIndex(i1,di4a);
auto resx1 = res1; auto resx1 = res1;
auto resx2 = res1; auto resx2 = res1;
@ -131,23 +135,14 @@ namespace
resx2(i1,di4) = mkDynOp(ma1(i1,di1) * ma2(i1,di2)); resx2(i1,di4) = mkDynOp(ma1(i1,di1) * ma2(i1,di2));
resx3(i1,di4) = mkDynOp(mkDynOp(ma1(i1,di1)) * mkDynOp(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); auto op1 = mkDynOutOp((ma1(i1,di1) * ma2(i1,di2)), ci4);
auto op1x = ma1(i1,di1) * ma2(i1,di2);
auto opr = resx4(i1,di4); auto opr = resx4(i1,di4);
auto loop = mkILoop(std::make_tuple(opr,op1,op1.data()->mOp), std::make_tuple(ci4), auto loop = mkILoop(std::make_tuple(opr,op1,*op1.data()->mOp), std::make_tuple(ci4),
std::make_tuple(xx), std::make_tuple(opr.assign( op1.data()->mOp, ci4 )), std::make_tuple(xx), std::make_tuple(opr.assign( *op1.data()->mOp, ci4 )),
//std::make_tuple(), std::make_tuple(),
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->ifor(1, mkGetExpr(op1,loop))();
auto loop = mkILoop(std::make_tuple(opr,op1x), std::make_tuple(ci4),
std::make_tuple(xx), std::make_tuple(opr.assign( op1x, ci4 )),
//std::make_tuple(), std::make_tuple(),
std::array<size_t,1>({1}), std::array<size_t,1>({0}));
*/
//mi->ifor(1, loop)();
mi->ifor(1, loop)();
auto i2_1 = imap.at("i2_1"); auto i2_1 = imap.at("i2_1");
auto i2_2 = imap.at("i2_2"); auto i2_2 = imap.at("i2_2");
@ -168,11 +163,13 @@ namespace
auto resx1v = xround(resx1.vdata()[jr]); auto resx1v = xround(resx1.vdata()[jr]);
auto resx2v = xround(resx2.vdata()[jr]); auto resx2v = xround(resx2.vdata()[jr]);
auto resx3v = xround(resx3.vdata()[jr]); auto resx3v = xround(resx3.vdata()[jr]);
auto resx4v = xround(resx4.vdata()[jr]);
auto x12 = xround(ma1.vdata()[j1]*ma2.vdata()[j2]); auto x12 = xround(ma1.vdata()[j1]*ma2.vdata()[j2]);
EXPECT_EQ( resv, x12 ); EXPECT_EQ( resv, x12 );
EXPECT_EQ( resx1v, x12 ); EXPECT_EQ( resx1v, x12 );
EXPECT_EQ( resx2v, x12 ); EXPECT_EQ( resx2v, x12 );
EXPECT_EQ( resx3v, x12 ); EXPECT_EQ( resx3v, x12 );
EXPECT_EQ( resx4v, x12 );
} }
} }
} }