dynamic operations: partial static call works consistently
This commit is contained in:
parent
cb6a6ccdb3
commit
67b343d217
6 changed files with 119 additions and 41 deletions
|
@ -47,29 +47,25 @@ namespace MultiArrayTools
|
|||
: mOp(op),
|
||||
mMa(std::make_shared<MultiArray<T,Ranges...>>(mkArray<T>(inds->range()...))),
|
||||
mProto(OperationRoot<T,Ranges...>(*mMa,inds...)),
|
||||
mL(std::make_tuple(mProto.mOp,mOp), std::make_tuple(inds...),
|
||||
std::make_tuple(mMa), std::make_tuple(mProto.mOp.assign( mOp )),
|
||||
std::array<size_t,1>({0}), std::array<size_t,1>({0}))
|
||||
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<size_t,1>({1}), std::array<size_t,1>({0}))
|
||||
{
|
||||
VCHECK(reinterpret_cast<std::intptr_t>(mProto.mOp.data()));
|
||||
VCHECK(reinterpret_cast<std::intptr_t>(mMa->data()));
|
||||
*mMa = 0;
|
||||
}
|
||||
|
||||
template <typename T, class Operation, class... Ranges>
|
||||
OpH<OperationRoot<T,Ranges...>> DynamicOuterOp<T,Operation,Ranges...>::get(const DExtT& pos) const
|
||||
{
|
||||
CHECK;
|
||||
//mOp.get(pos.expl<ET>());
|
||||
//mL(0,pos.expl<ET>());
|
||||
mL(0,pos.expl<ET>());
|
||||
// execute assignment... care about threads!!!
|
||||
return mProto.mOp; // empty
|
||||
return mProto; // empty
|
||||
}
|
||||
|
||||
template <typename T, class Operation, class... Ranges>
|
||||
DynamicOperationBase<OpH<OperationRoot<T,Ranges...>>>&
|
||||
DynamicOuterOp<T,Operation,Ranges...>::set(const DExtT& pos)
|
||||
{
|
||||
CHECK;
|
||||
mOp.set(pos.expl<ET>());
|
||||
return *this;
|
||||
}
|
||||
|
@ -77,21 +73,18 @@ namespace MultiArrayTools
|
|||
template <typename T, class Operation, class... Ranges>
|
||||
DExtT DynamicOuterOp<T,Operation,Ranges...>::rootSteps(std::intptr_t iPtrNum) const
|
||||
{
|
||||
CHECK;
|
||||
return DExtT(mkDExt(mkExtT(mL.rootSteps(iPtrNum))),None(0));
|
||||
}
|
||||
|
||||
template <typename T, class Operation, class... Ranges>
|
||||
DynamicExpression DynamicOuterOp<T,Operation,Ranges...>::loop(const DynamicExpression& exp) const
|
||||
{
|
||||
CHECK;
|
||||
return mOp.loop(exp); // ???!!
|
||||
}
|
||||
|
||||
template <typename T, class Operation, class... Ranges>
|
||||
const OpH<OperationRoot<T,Ranges...>>* DynamicOuterOp<T,Operation,Ranges...>::data() const
|
||||
{
|
||||
CHECK;
|
||||
return &mProto;
|
||||
}
|
||||
|
||||
|
@ -99,7 +92,6 @@ namespace MultiArrayTools
|
|||
std::shared_ptr<DynamicOperationBase<OpH<OperationRoot<T,Ranges...>>>>
|
||||
DynamicOuterOp<T,Operation,Ranges...>::deepCopy() const
|
||||
{
|
||||
CHECK;
|
||||
return std::make_shared<DynamicOuterOp<T,Operation,Ranges...>>(*this);
|
||||
}
|
||||
|
||||
|
|
|
@ -61,8 +61,9 @@ namespace MultiArrayTools
|
|||
template <class Op>
|
||||
struct OpH
|
||||
{
|
||||
Op mOp;
|
||||
OpH(const Op& op) : mOp(op) {}
|
||||
std::shared_ptr<Op> mOp;
|
||||
OpH(const Op& op) : mOp(std::make_shared<Op>(op)) {}
|
||||
|
||||
};
|
||||
|
||||
template <typename T, class Operation, class... Ranges>
|
||||
|
@ -77,7 +78,7 @@ namespace MultiArrayTools
|
|||
typedef ILoop<std::tuple<OperationRoot<T,Ranges...>,Operation>,
|
||||
std::tuple<std::shared_ptr<typename Ranges::IndexType>...>,
|
||||
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;
|
||||
|
||||
|
|
|
@ -211,6 +211,52 @@ namespace MultiArrayTools
|
|||
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>
|
||||
AddExpr<T,Target,OpClass,OIA>::AddExpr(T* dataPtr, const Target& tar, const OpClass& sec) :
|
||||
mTar(tar), mSec(sec), mDataPtr(dataPtr) {}
|
||||
|
|
|
@ -142,6 +142,41 @@ namespace MultiArrayTools
|
|||
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 Target, class OpClass, OpIndexAff OIA=OpIndexAff::EXTERN>
|
||||
class AddExpr : public ExpressionBase
|
||||
|
|
|
@ -102,6 +102,9 @@ namespace MultiArrayHelper
|
|||
private:
|
||||
mutable DExt mDExt = nullptr;
|
||||
X mNext;
|
||||
|
||||
template <class Y>
|
||||
friend class DExtTX;
|
||||
public:
|
||||
static constexpr size_t NUM = X::SIZE;
|
||||
static constexpr size_t SIZE = NUM + 1;
|
||||
|
@ -119,8 +122,12 @@ namespace MultiArrayHelper
|
|||
template <class Y>
|
||||
DExtTX(const Y& y) : mDExt(std::make_shared<ExtT<Y>>(y)) {}
|
||||
*/
|
||||
explicit DExtTX(const DExt& y, const X& x) : mDExt(y->deepCopy()),
|
||||
mNext(x) {}
|
||||
|
||||
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) {}
|
||||
|
||||
virtual size_t size() const { return mDExt->size(); }
|
||||
inline const DExt& get() const { return mDExt; }
|
||||
|
|
|
@ -53,10 +53,11 @@ namespace
|
|||
std::map<std::string,std::shared_ptr<IndexW>> imap;
|
||||
|
||||
std::shared_ptr<DR> dr1;
|
||||
std::shared_ptr<DR> dr1a;
|
||||
//std::shared_ptr<DR> dr1a;
|
||||
std::shared_ptr<DR> dr2;
|
||||
std::shared_ptr<DR> dr3;
|
||||
std::shared_ptr<DR> dr4;
|
||||
std::shared_ptr<DR> dr4a;
|
||||
std::shared_ptr<DR> dr5;
|
||||
std::shared_ptr<DR> dr6;
|
||||
std::shared_ptr<CR> cr1;
|
||||
|
@ -73,13 +74,14 @@ namespace
|
|||
auto cr5 = createRangeE<CR>(13);
|
||||
|
||||
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);
|
||||
dr3 = createRangeE<DR>(cr2,cr5);
|
||||
dr5 = createRangeE<DR>(cr5);
|
||||
dr6 = createRangeE<DR>(cr3,cr4);
|
||||
|
||||
dr4 = createRangeE<DR>(cr2,cr3,cr4,cr4);
|
||||
dr4a = createRangeE<DR>(cr2,cr3,cr4);
|
||||
|
||||
ma1 = mkArray<double>(cr1,dr1);
|
||||
ma2 = mkArray<double>(cr1,dr2);
|
||||
|
@ -99,8 +101,8 @@ namespace
|
|||
imap["i3_1"] = mkIndexW(getIndex(cr3));
|
||||
imap["i3_2"] = mkIndexW(getIndex(cr3));
|
||||
ci4 = getIndex(cr4);
|
||||
imap["i4_1"] = mkIndexW(ci4);
|
||||
imap["i4_2"] = mkIndexW(getIndex(cr4));
|
||||
imap["i4_1"] = mkIndexW(getIndex(cr4));
|
||||
imap["i4_2"] = mkIndexW(ci4);
|
||||
imap["i5_1"] = mkIndexW(getIndex(cr5));
|
||||
imap["i5_2"] = mkIndexW(getIndex(cr5));
|
||||
}
|
||||
|
@ -110,16 +112,18 @@ namespace
|
|||
{
|
||||
auto i1 = getIndex(cr1);
|
||||
auto di1 = getIndex(dr1);
|
||||
auto di1a = getIndex(dr1a);
|
||||
//auto di1a = getIndex(dr1a);
|
||||
auto di2 = getIndex(dr2);
|
||||
auto di4 = getIndex(dr4);
|
||||
|
||||
auto mi = mkMIndex(i1,di1a);
|
||||
auto di4a = getIndex(dr4a);
|
||||
|
||||
(*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"]});
|
||||
(*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 resx2 = res1;
|
||||
|
@ -130,24 +134,15 @@ namespace
|
|||
resx1(i1,di4) = mkDynOp(ma1(i1,di1)) * mkDynOp(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)));
|
||||
|
||||
auto op1 = mkDynOutOp(ma1(i1,di1) * ma2(i1,di2), ci4);
|
||||
auto op1x = ma1(i1,di1) * ma2(i1,di2);
|
||||
|
||||
auto op1 = mkDynOutOp((ma1(i1,di1) * ma2(i1,di2)), ci4);
|
||||
auto opr = resx4(i1,di4);
|
||||
|
||||
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(), std::make_tuple(),
|
||||
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::array<size_t,1>({1}), std::array<size_t,1>({0}));
|
||||
|
||||
/*
|
||||
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)();
|
||||
mi->ifor(1, mkGetExpr(op1,loop))();
|
||||
|
||||
auto i2_1 = imap.at("i2_1");
|
||||
auto i2_2 = imap.at("i2_2");
|
||||
|
@ -168,11 +163,13 @@ namespace
|
|||
auto resx1v = xround(resx1.vdata()[jr]);
|
||||
auto resx2v = xround(resx2.vdata()[jr]);
|
||||
auto resx3v = xround(resx3.vdata()[jr]);
|
||||
auto resx4v = xround(resx4.vdata()[jr]);
|
||||
auto x12 = xround(ma1.vdata()[j1]*ma2.vdata()[j2]);
|
||||
EXPECT_EQ( resv, x12 );
|
||||
EXPECT_EQ( resx1v, x12 );
|
||||
EXPECT_EQ( resx2v, x12 );
|
||||
EXPECT_EQ( resx3v, x12 );
|
||||
EXPECT_EQ( resx4v, x12 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue