... remaining fixes: hybrid dynamic multi-threaded operations work
This commit is contained in:
parent
4e7e57fcb9
commit
566da70618
8 changed files with 171 additions and 14 deletions
|
@ -41,10 +41,89 @@ namespace MultiArrayTools
|
||||||
return std::make_shared<DynamicOperation<T,Operation>>(*this);
|
return std::make_shared<DynamicOperation<T,Operation>>(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T, class Operation, class... Ranges>
|
||||||
|
DynamicOuterOp<T,Operation,Ranges...>::DynamicOuterOp(const DynamicOuterOp& in) :
|
||||||
|
mThreadId(omp_get_thread_num()), mOp(in.mOp),
|
||||||
|
mIndices(in.mIndices),
|
||||||
|
mMa((mThreadId != in.mThreadId) ? std::make_shared<MultiArray<T,Ranges...>>(*in.mMa) : in.mMa),
|
||||||
|
mProto((mThreadId != in.mThreadId) ? OperationRoot<T,Ranges...>(*mMa,mIndices) : in.mProto),
|
||||||
|
mL((mThreadId != in.mThreadId) ?
|
||||||
|
mkILoop(std::make_tuple(*mProto.mOp,mOp), mIndices,
|
||||||
|
std::make_tuple(mMa),
|
||||||
|
std::make_tuple(mProto.mOp->assign( mOp, mkMIndex(mIndices) )),
|
||||||
|
std::array<size_t,1>({1}), std::array<size_t,1>({0})) :
|
||||||
|
in.mL)
|
||||||
|
|
||||||
|
{*mMa = 0;}
|
||||||
|
|
||||||
|
template <typename T, class Operation, class... Ranges>
|
||||||
|
DynamicOuterOp<T,Operation,Ranges...>::DynamicOuterOp(DynamicOuterOp&& in) :
|
||||||
|
mThreadId(omp_get_thread_num()), mOp(in.mOp),
|
||||||
|
mIndices(in.mIndices),
|
||||||
|
mMa((mThreadId != in.mThreadId) ? std::make_shared<MultiArray<T,Ranges...>>(*in.mMa) : in.mMa),
|
||||||
|
mProto((mThreadId != in.mThreadId) ? OperationRoot<T,Ranges...>(*mMa,mIndices) : in.mProto),
|
||||||
|
mL((mThreadId != in.mThreadId) ?
|
||||||
|
mkILoop(std::make_tuple(*mProto.mOp,mOp), mIndices,
|
||||||
|
std::make_tuple(mMa),
|
||||||
|
std::make_tuple(mProto.mOp->assign( mOp, mkMIndex(mIndices) )),
|
||||||
|
std::array<size_t,1>({1}), std::array<size_t,1>({0})) :
|
||||||
|
in.mL)
|
||||||
|
|
||||||
|
{*mMa = 0;}
|
||||||
|
|
||||||
|
template <typename T, class Operation, class... Ranges>
|
||||||
|
DynamicOuterOp<T,Operation,Ranges...>&
|
||||||
|
DynamicOuterOp<T,Operation,Ranges...>::operator=(const DynamicOuterOp& in)
|
||||||
|
{
|
||||||
|
mThreadId = omp_get_thread_num();
|
||||||
|
mOp = in.mOp;
|
||||||
|
mIndices = in.mIndices;
|
||||||
|
if(mThreadId != in.mThreadId){
|
||||||
|
mMa = std::make_shared<MultiArray<T,Ranges...>>(in.mMa);
|
||||||
|
mProto = OperationRoot<T,Ranges...>(*mMa,mIndices);
|
||||||
|
mL = mkILoop(std::make_tuple(*mProto.mOp,mOp), mIndices,
|
||||||
|
std::make_tuple(mMa),
|
||||||
|
std::make_tuple(mProto.mOp->assign( mOp, mkMIndex(mIndices) )),
|
||||||
|
std::array<size_t,1>({1}), std::array<size_t,1>({0}));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mMa = in.mMa;
|
||||||
|
mProto = in.mProto;
|
||||||
|
mL = in.mL;
|
||||||
|
}
|
||||||
|
*mMa = 0;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class Operation, class... Ranges>
|
||||||
|
DynamicOuterOp<T,Operation,Ranges...>&
|
||||||
|
DynamicOuterOp<T,Operation,Ranges...>::operator=(DynamicOuterOp&& in)
|
||||||
|
{
|
||||||
|
mThreadId = omp_get_thread_num();
|
||||||
|
mOp = in.mOp;
|
||||||
|
mIndices = in.mIndices;
|
||||||
|
if(mThreadId != in.mThreadId){
|
||||||
|
mMa = std::make_shared<MultiArray<T,Ranges...>>(in.mMa);
|
||||||
|
mProto = OperationRoot<T,Ranges...>(*mMa,mIndices);
|
||||||
|
mL = mkILoop(std::make_tuple(*mProto.mOp,mOp), mIndices,
|
||||||
|
std::make_tuple(mMa),
|
||||||
|
std::make_tuple(mProto.mOp->assign( mOp, mkMIndex(mIndices) )),
|
||||||
|
std::array<size_t,1>({1}), std::array<size_t,1>({0}));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mMa = in.mMa;
|
||||||
|
mProto = in.mProto;
|
||||||
|
mL = in.mL;
|
||||||
|
}
|
||||||
|
*mMa = 0;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T, class Operation, class... Ranges>
|
template <typename T, class Operation, class... Ranges>
|
||||||
DynamicOuterOp<T,Operation,Ranges...>::DynamicOuterOp(const Operation& op,
|
DynamicOuterOp<T,Operation,Ranges...>::DynamicOuterOp(const Operation& op,
|
||||||
const std::shared_ptr<typename Ranges::IndexType>&... inds)
|
const std::shared_ptr<typename Ranges::IndexType>&... inds)
|
||||||
: mOp(op),
|
: mThreadId(omp_get_thread_num()), mOp(op),
|
||||||
|
mIndices(inds...),
|
||||||
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...),
|
||||||
|
|
|
@ -70,8 +70,10 @@ namespace MultiArrayTools
|
||||||
class DynamicOuterOp : public DynamicOperationBase<OpH<OperationRoot<T,Ranges...>>>
|
class DynamicOuterOp : public DynamicOperationBase<OpH<OperationRoot<T,Ranges...>>>
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
size_t mThreadId;
|
||||||
Operation mOp;
|
Operation mOp;
|
||||||
//OperationRoot<T,Ranges...> mProto;
|
//OperationRoot<T,Ranges...> mProto;
|
||||||
|
std::tuple<std::shared_ptr<typename Ranges::IndexType>...> mIndices;
|
||||||
std::shared_ptr<MultiArray<T,Ranges...>> mMa;
|
std::shared_ptr<MultiArray<T,Ranges...>> mMa;
|
||||||
OpH<OperationRoot<T,Ranges...>> mProto;
|
OpH<OperationRoot<T,Ranges...>> mProto;
|
||||||
|
|
||||||
|
@ -90,11 +92,11 @@ namespace MultiArrayTools
|
||||||
typedef decltype(mL.rootSteps()) ET;
|
typedef decltype(mL.rootSteps()) ET;
|
||||||
//typedef decltype(std::declval<Operation>().rootSteps()) ET;
|
//typedef decltype(std::declval<Operation>().rootSteps()) ET;
|
||||||
|
|
||||||
DynamicOuterOp() = default;
|
DynamicOuterOp() : mThreadId(omp_get_thread_num()) {}
|
||||||
DynamicOuterOp(const DynamicOuterOp& in) = default;
|
DynamicOuterOp(const DynamicOuterOp& in);
|
||||||
DynamicOuterOp(DynamicOuterOp&& in) = default;
|
DynamicOuterOp(DynamicOuterOp&& in);
|
||||||
DynamicOuterOp& operator=(const DynamicOuterOp& in) = default;
|
DynamicOuterOp& operator=(const DynamicOuterOp& in);
|
||||||
DynamicOuterOp& operator=(DynamicOuterOp&& in) = default;
|
DynamicOuterOp& operator=(DynamicOuterOp&& in);
|
||||||
|
|
||||||
DynamicOuterOp(const Operation& op, const std::shared_ptr<typename Ranges::IndexType>&... inds);
|
DynamicOuterOp(const Operation& op, const std::shared_ptr<typename Ranges::IndexType>&... inds);
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,41 @@ namespace MultiArrayTools
|
||||||
return std::dynamic_pointer_cast<MultiRange<RangeTypes...> >( mrf.create() );
|
return std::dynamic_pointer_cast<MultiRange<RangeTypes...> >( mrf.create() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
template <size_t N>
|
||||||
|
struct IndexToRangeTuple
|
||||||
|
{
|
||||||
|
template <class... IndexTypes>
|
||||||
|
static inline void set(std::tuple<std::shared_ptr<typename IndexTypes::RangeType>...>& out,
|
||||||
|
const std::tuple<std::shared_ptr<IndexTypes>...>& indices)
|
||||||
|
{
|
||||||
|
std::get<N>(out) = std::get<N>(indices)->range();
|
||||||
|
IndexToRangeTuple<N-1>::set(out,indices);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct IndexToRangeTuple<0>
|
||||||
|
{
|
||||||
|
template <class... IndexTypes>
|
||||||
|
static inline void set(std::tuple<std::shared_ptr<typename IndexTypes::RangeType>...>& out,
|
||||||
|
const std::tuple<std::shared_ptr<IndexTypes>...>& indices)
|
||||||
|
{
|
||||||
|
std::get<0>(out) = std::get<0>(indices)->range();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class... IndexTypes>
|
||||||
|
auto indexToRangeTuple(const std::tuple<std::shared_ptr<IndexTypes>...>& indices)
|
||||||
|
-> std::tuple<std::shared_ptr<typename IndexTypes::RangeType>...>
|
||||||
|
{
|
||||||
|
std::tuple<std::shared_ptr<typename IndexTypes::RangeType>...> out;
|
||||||
|
IndexToRangeTuple<sizeof...(IndexTypes)-1>::set(out, indices);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
template <class... IndexTypes>
|
template <class... IndexTypes>
|
||||||
auto mkMIndex(std::shared_ptr<IndexTypes>... indices)
|
auto mkMIndex(std::shared_ptr<IndexTypes>... indices)
|
||||||
-> decltype( getIndex( mkMulti( indices->range()... ) ) )
|
-> decltype( getIndex( mkMulti( indices->range()... ) ) )
|
||||||
|
@ -45,6 +80,16 @@ namespace MultiArrayTools
|
||||||
return mi;
|
return mi;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class... IndexTypes>
|
||||||
|
auto mkMIndex(const std::tuple<std::shared_ptr<IndexTypes>...>& indices)
|
||||||
|
-> decltype( getIndex( mkMulti( indexToRangeTuple(indices) ) ) )
|
||||||
|
{
|
||||||
|
auto mi = getIndex( mkMulti( indexToRangeTuple(indices) ) );
|
||||||
|
(*mi)( indices );
|
||||||
|
return mi;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template <class Index>
|
template <class Index>
|
||||||
auto mkIndexW(const std::shared_ptr<Index>& ind)
|
auto mkIndexW(const std::shared_ptr<Index>& ind)
|
||||||
-> std::shared_ptr<IndexW>
|
-> std::shared_ptr<IndexW>
|
||||||
|
@ -102,7 +147,7 @@ namespace MultiArrayTools
|
||||||
|
|
||||||
template <class... RangeTypes>
|
template <class... RangeTypes>
|
||||||
auto mkMulti(std::tuple<std::shared_ptr<RangeTypes>...> rangesTuple)
|
auto mkMulti(std::tuple<std::shared_ptr<RangeTypes>...> rangesTuple)
|
||||||
-> MultiRange<RangeTypes...>
|
-> std::shared_ptr<MultiRange<RangeTypes...>>
|
||||||
{
|
{
|
||||||
MultiRangeFactory<RangeTypes...> mrf( rangesTuple );
|
MultiRangeFactory<RangeTypes...> mrf( rangesTuple );
|
||||||
return std::dynamic_pointer_cast<MultiRange<RangeTypes...> >( mrf.create() );
|
return std::dynamic_pointer_cast<MultiRange<RangeTypes...> >( mrf.create() );
|
||||||
|
|
|
@ -57,17 +57,26 @@ namespace MultiArrayTools
|
||||||
auto mkMapI(const std::tuple<Op,MA>& f, std::shared_ptr<IndexTypes>... indices)
|
auto mkMapI(const std::tuple<Op,MA>& f, std::shared_ptr<IndexTypes>... indices)
|
||||||
-> decltype( mkGenMapI<SpaceType::ANY>(f, indices... ) );
|
-> decltype( mkGenMapI<SpaceType::ANY>(f, indices... ) );
|
||||||
|
|
||||||
|
template <class... IndexTypes>
|
||||||
|
auto indexToRangeTuple(const std::tuple<std::shared_ptr<IndexTypes>...>& indices)
|
||||||
|
-> std::tuple<std::shared_ptr<typename IndexTypes::RangeType>...>;
|
||||||
|
|
||||||
|
template <class... RangeTypes>
|
||||||
|
auto mkMulti(std::tuple<std::shared_ptr<RangeTypes>...> rangesTuple)
|
||||||
|
-> std::shared_ptr<MultiRange<RangeTypes...>>;
|
||||||
|
|
||||||
template <class... IndexTypes>
|
template <class... IndexTypes>
|
||||||
auto mkMIndex(std::shared_ptr<IndexTypes>... indices)
|
auto mkMIndex(std::shared_ptr<IndexTypes>... indices)
|
||||||
-> decltype( getIndex( mkMulti( indices.range()... ) ) );
|
-> decltype( getIndex( mkMulti( indices.range()... ) ) );
|
||||||
|
|
||||||
|
template <class... IndexTypes>
|
||||||
|
auto mkMIndex(const std::tuple<std::shared_ptr<IndexTypes>...>& indices)
|
||||||
|
-> decltype( getIndex( mkMulti( indexToRangeTuple(indices) ) ) );
|
||||||
|
|
||||||
template <class Index>
|
template <class Index>
|
||||||
auto mkIndexW(const std::shared_ptr<Index>& ind)
|
auto mkIndexW(const std::shared_ptr<Index>& ind)
|
||||||
-> std::shared_ptr<IndexW>;
|
-> std::shared_ptr<IndexW>;
|
||||||
|
|
||||||
template <class... RangeTypes>
|
|
||||||
auto mkMulti(std::tuple<std::shared_ptr<RangeTypes>...> rangesTuple)
|
|
||||||
-> MultiRange<RangeTypes...>;
|
|
||||||
|
|
||||||
template <class RangeFactory>
|
template <class RangeFactory>
|
||||||
auto createExplicit(RangeFactory& rf)
|
auto createExplicit(RangeFactory& rf)
|
||||||
|
|
|
@ -481,6 +481,18 @@ namespace MultiArrayTools
|
||||||
mDataPtr = mOrigDataPtr + mIndex.pos();
|
mDataPtr = mOrigDataPtr + mIndex.pos();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T, class... Ranges>
|
||||||
|
OperationRoot<T,Ranges...>::
|
||||||
|
OperationRoot(MutableMultiArrayBase<T,Ranges...>& ma,
|
||||||
|
const std::tuple<std::shared_ptr<typename Ranges::IndexType>...>& indices) :
|
||||||
|
mDataPtr(ma.data()),
|
||||||
|
mOrigDataPtr(ma.data()),
|
||||||
|
mIndex( ma.begin() )
|
||||||
|
{
|
||||||
|
mIndex(indices);
|
||||||
|
mDataPtr = mOrigDataPtr + mIndex.pos();
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T, class... Ranges>
|
template <typename T, class... Ranges>
|
||||||
OperationRoot<T,Ranges...>::
|
OperationRoot<T,Ranges...>::
|
||||||
OperationRoot(T* data, const IndexType& ind) :
|
OperationRoot(T* data, const IndexType& ind) :
|
||||||
|
|
|
@ -368,6 +368,9 @@ namespace MultiArrayTools
|
||||||
OperationRoot(MutableMultiArrayBase<T,Ranges...>& ma,
|
OperationRoot(MutableMultiArrayBase<T,Ranges...>& ma,
|
||||||
const std::shared_ptr<typename Ranges::IndexType>&... indices);
|
const std::shared_ptr<typename Ranges::IndexType>&... indices);
|
||||||
|
|
||||||
|
OperationRoot(MutableMultiArrayBase<T,Ranges...>& ma,
|
||||||
|
const std::tuple<std::shared_ptr<typename Ranges::IndexType>...>& indices);
|
||||||
|
|
||||||
OperationRoot(T* data, const IndexType& ind);
|
OperationRoot(T* data, const IndexType& ind);
|
||||||
|
|
||||||
template <class OpClass>
|
template <class OpClass>
|
||||||
|
|
|
@ -85,6 +85,7 @@ namespace MultiArrayTools
|
||||||
// NO foreign/external controll)
|
// NO foreign/external controll)
|
||||||
// Do NOT share index instances between two or more MultiIndex instances
|
// Do NOT share index instances between two or more MultiIndex instances
|
||||||
MultiIndex& operator()(std::shared_ptr<Indices>&... indices);
|
MultiIndex& operator()(std::shared_ptr<Indices>&... indices);
|
||||||
|
MultiIndex& operator()(const std::tuple<std::shared_ptr<Indices>...>& indices);
|
||||||
|
|
||||||
// ==== >>>>> STATIC POLYMORPHISM <<<<< ====
|
// ==== >>>>> STATIC POLYMORPHISM <<<<< ====
|
||||||
|
|
||||||
|
@ -324,6 +325,14 @@ namespace MultiArrayTools
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class... Indices>
|
||||||
|
MultiIndex<Indices...>& MultiIndex<Indices...>::operator()(const std::tuple<std::shared_ptr<Indices>...>& indices)
|
||||||
|
{
|
||||||
|
RPackNum<sizeof...(Indices)-1>::swapIndices(mIPack, indices);
|
||||||
|
RPackNum<sizeof...(Indices)-1>::setIndexPack(mIPack, IB::mPos);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
template <class... Indices>
|
template <class... Indices>
|
||||||
IndexType MultiIndex<Indices...>::type() const
|
IndexType MultiIndex<Indices...>::type() const
|
||||||
{
|
{
|
||||||
|
|
|
@ -137,14 +137,12 @@ 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_1, ci4_2);
|
auto op1x = mkDynOutOp((ma1(i1,di1) * ma2(i1,di2)), ci4_1, ci4_2);
|
||||||
//auto opr = resx4(i1,di4);
|
|
||||||
auto op1x = (ma1(i1,di1) * ma2(i1,di2));
|
|
||||||
auto opr = resx4(i1,di4);
|
auto opr = resx4(i1,di4);
|
||||||
|
|
||||||
auto loop = mkPILoop
|
auto loop = mkPILoop
|
||||||
( [&op1x,&opr,&xx,this](){
|
( [&op1x,&opr,&xx,this](){
|
||||||
auto op1 = mkDynOutOp(op1x, ci4_1, ci4_2);
|
auto op1 = op1x;
|
||||||
return mkGetExpr(op1,mkILoop(std::make_tuple(opr,op1,*op1.data()->mOp), std::make_tuple(ci4_1, ci4_2),
|
return mkGetExpr(op1,mkILoop(std::make_tuple(opr,op1,*op1.data()->mOp), std::make_tuple(ci4_1, ci4_2),
|
||||||
std::make_tuple(xx),
|
std::make_tuple(xx),
|
||||||
std::make_tuple(opr.assign( *op1.data()->mOp, mkMIndex(ci4_1, ci4_2) )),
|
std::make_tuple(opr.assign( *op1.data()->mOp, mkMIndex(ci4_1, ci4_2) )),
|
||||||
|
|
Loading…
Reference in a new issue