start refactoring MIndex

This commit is contained in:
Christian Zimmermann 2022-11-02 18:51:18 +01:00
parent 6b2bbc3020
commit 172110c5de
4 changed files with 199 additions and 93 deletions

View file

@ -8,41 +8,74 @@
namespace CNORXZ namespace CNORXZ
{ {
/***********************
* MIndex (private) *
***********************/
template <class... Indices>
template <SizeT P, SizeT... Is>
constexpr decltype(auto) MIndex<Indices...>::indexSequencePlus(std::index_sequence<Is...> is) const
{
return std::index_sequence<P+Is...> {};
}
template <class... Indices>
template <SizeT B, SizeT E>
constexpr decltype(auto) MIndex<Indices...>::mkIndexSequence() const
{
return indexSequencePlus<B>(std::make_index_sequence<E-B>{});
}
template <class... Indices>
template <class G, class F, SizeT... Is>
constexpr decltype(auto) MIndex<Indices...>::accumulatei(const G& g, const F& f, std::index_sequence<Is...> is) const
{
return f( g(std::get<Is>(mIPack))... );
}
template <class... Indices>
template <SizeT B, SizeT E, class G, class F>
constexpr decltype(auto) MIndex<Indices...>::accumulate(const G& g, const F& f) const
{
return accumulatei(g, f, mkIndexSequence<B,E>())
}
template <class... Indices>
template <SizeT... Is>
constexpr decltype(auto) mkIPack(SizeT pos, std::index_sequence<Is...> is) const
{
static_assert(sizeof...(Is) == sizeof...(Indices),
"sequence size does not match number of indices");
return std::make_tuple( std::make_shared<Indices>( mRange->sub(Is) )... );
}
template <class... Indices>
template <SizeT... Is>
constexpr decltype(auto) mkBlockSizes(std::index_sequence<Is...> is) const
{
static_assert(sizeof...(Is) == sizeof...(Indices)-1,
"set lowest block size manually");
return Arr<SizeT,sizeof...(Indices)>
{ accumulate<Is,sizeof...(Indices)>( [](const auto& i) { return i->max(); },
[](const auto&... as) { return (as * ...); } ),
1 };
}
/************** /**************
* MIndex * * MIndex *
**************/ **************/
template <class... Indices> template <class... Indices>
template <class MRange> template <class MRange>
MIndex<Indices...>::MIndex(const Sptr<MRange>& range) : MIndex<Indices...>::MIndex(const Sptr<MRange>& range, SizeT pos) :
IndexInterface<MIndex<Indices...>,Tuple<typename Indices::MetaType...> >(0) IndexInterface<MIndex<Indices...>,Tuple<typename Indices::MetaType...>>(pos),
{ mIPack(mkIPack(IB::mPos, std::make_index_sequence<sizeof...(Indices)>{})),
std::get<sizeof...(Indices)>(mBlockSizes) = 1; mBlockSizes(mkBlockSizes(IB::mPos), std::make_index_sequence<sizeof...(Indices)>{}),
sfor_mn<sizeof...(Indices),0> mRange(range)
( [&](auto i) { {}
auto r = range->template getPtr<i>();
std::get<i>(mIPack) = r->beginPtr();
*std::get<i>(mIPack) = 0;
std::get<i>(mBlockSizes) = sfor_p<i,sizeof...(Indices)>
( [&](auto j) { return std::get<j>(mIPack)->max(); } ,
[&](auto a, auto b) { return a * b; });
return 0;
});
IB::mPos = sfor_m<sizeof...(Indices),0>
( [&](auto i) { return std::get<i>(mIPack); },
[&](auto a, auto b) {return a->pos() + b*a->max();}, 0 );
}
template <class... Indices> template <class... Indices>
MIndex<Indices...>& MIndex<Indices...>::operator()(Sptr<Indices>&... indices) MIndex<Indices...>& MIndex<Indices...>::operator()(const Sptr<MIndex>& mi)
{
return (*this)(std::make_tuple(indices...));
}
template <class... Indices>
MIndex<Indices...>& MIndex<Indices...>::operator()(const Tuple<Sptr<Indices>...>& indices)
{ {
sfor_pn<0,sizeof...(Indices)> sfor_pn<0,sizeof...(Indices)>
( [&](auto i) { std::get<i>(mIPack) = std::get<i>(indices); return 0; } ); ( [&](auto i) { std::get<i>(mIPack) = std::get<i>(indices); return 0; } );
@ -158,20 +191,6 @@ namespace CNORXZ
{ {
return RangeHelper::mkFor<0>(step, mIPack, mBlockSizes, exs); return RangeHelper::mkFor<0>(step, mIPack, mBlockSizes, exs);
} }
template <class... Indices>
template <class Exprs>
auto MIndex<Indices...>::iforh(SizeT step, Exprs exs) const
{
return RangeHelper::mkForh<0>(step, mIPack, mBlockSizes, exs);
}
template <class... Indices>
template <class Exprs>
auto MIndex<Indices...>::pifor(SizeT step, Exprs exs) const
{
return RangeHelper::mkPFor<0>(step, mIPack, mBlockSizes, exs);
}
*/ */
/********************* /*********************
@ -179,63 +198,115 @@ namespace CNORXZ
*********************/ *********************/
template <class... Ranges> template <class... Ranges>
MRangeFactory<Ranges...>::MRangeFactory(const Sptr<Ranges>&... rs) MRangeFactory<Ranges...>::MRangeFactory(const Tuple<Sptr<Ranges>...>& rs) :
{ mRs(rs)
mProd = Sptr< MRange<Ranges...> >( new MRange<Ranges...>( rs... ) ); {}
}
template <class... Ranges>
MRangeFactory<Ranges...>::MRangeFactory(const typename MRange<Ranges...>::Space& st)
{
mProd = Sptr< MRange<Ranges...> >( new MRange<Ranges...>( st ) );
}
template <class... Ranges> template <class... Ranges>
Sptr<RangeBase> MRangeFactory<Ranges...>::create() MRangeFactory<Ranges...>::MRangeFactory(const Tuple<Sptr<Ranges>...>& rs,
const RangePtr& ref) :
mRs(rs),
mRef(ref)
{}
template <class... Ranges>
void MRangeFactory<Ranges...>::make()
{ {
mProd = checkIfCreated( std::dynamic_pointer_cast<oType>( mProd )->mSpace ); auto info = typeid(MRange<Ranges...>);
setSelf(); if(mRef != nullptr) {
return mProd; mProd = this->fromCreated[info.hash_code()][mRef->id()];
}
if(mProd == nullptr) {
RangePtr key = mProd = std::shared_ptr<MRange<Ranges...>>
( new MRange<Ranges...>( mSpace ) );
if(mRef != nullptr) { key = mRef }
this->addToCreated(info, { key->id() }, mProd);
}
} }
/****************** /**************
* MRange * * MRange *
******************/ **************/
template <class... Ranges> template <class... Ranges>
MRange<Ranges...>::MRange(const Sptr<Ranges>&... rs) : mSpace(std::make_tuple(rs...)) {} MRange<Ranges...>::MRange(const Tuple<Sptr<Ranges>...>& rs) :
mRs(rs),
mA( mkA( std::make_index_sequence<sizeof...(Ranges)>{} ) )
{}
template <class... Ranges> template <class... Ranges>
MRange<Ranges...>::MRange(const Space& space) : mSpace( space ) {} RangePtr MRange<Ranges...>::sub(SizeT num) const
template <class... Ranges>
SizeT MRange<Ranges...>::getMeta(const MetaType& metaPos) const
{ {
return RangeHelper::getMeta<sizeof...(Ranges)-1>(mSpace,metaPos); CXZ_ASSERT(num < this->dim(), "index out of range");
return mA[num];
}
template <class... Ranges>
SizeT MRange<Ranges...>::size() const
{
return this->sizei(std::make_index_sequence<sizeof...(Ranges)> {});
} }
template <class... Ranges> template <class... Ranges>
SizeT MRange<Ranges...>::dim() const SizeT MRange<Ranges...>::dim() const
{ {
return sdim; return sizeof...(Ranges);
} }
template <class... Ranges> template <class... Ranges>
SizeT MRange<Ranges...>::size() const String MRange<Ranges...>::stringMeta(SizeT pos) const
{ {
return sfor_p<0,sizeof...(Ranges)>
( [&](auto i) { return std::get<i>(mSpace)->size(); },
[&](auto a, auto b) { return a * b; } );
} }
template <class... Ranges> template <class... Ranges>
String MRange<Ranges...>::stringMeta(SizeT pos) const IndexType MRange<Ranges...>::begin() const
{ {
auto i = begin();
i = pos; }
return "[" + RangeHelper::getStringMeta<0>(i) + "]";
template <class... Ranges>
IndexType MRange<Ranges...>::end() const
{
} }
template <class... Ranges>
decltype(auto) MRange<Ranges...>::space() const
{
return mRs;
}
template <class... Ranges>
const MetaType MRange<Ranges...>::get(SizeT pos) const
{
}
template <class... Ranges>
SizeT MRange<Ranges...>::getMeta(const MetaType& metaPos) const
{
assert(0);
//return RangeHelper::getMeta<sizeof...(Ranges)-1>(mSpace,metaPos);
}
/************************
* MRange (private) *
************************/
template <class... Ranges>
template <SizeT... Is>
decltype(auto) MRange<Ranges...>::mkA(std::index_sequence<Is...> is) const
{
return Arr<RangePtr,sizeof...(Ranges)> { std::get<Is>(mRs)... };
}
template <class... Ranges>
SizeT MRange<Ranges...>::sizei(std::index_sequence<Is...> is) const
{
return ( std::get<Is>(mRs)->size() * ... );
}
} }
#endif #endif

View file

@ -33,8 +33,7 @@ namespace CNORXZ
MIndex(const RangePtr& range, SizeT pos = 0); MIndex(const RangePtr& range, SizeT pos = 0);
// replace sub-index instances; only use if you know what you are doing! // replace sub-index instances; only use if you know what you are doing!
MIndex& operator()(Sptr<Indices>&... indices); MIndex& operator()(const Sptr<MIndex>& mi);
MIndex& operator()(const MIndex& indices);
const IndexPack& pack() const { return mIPack; } const IndexPack& pack() const { return mIPack; }
const auto& getBlockSizes() const { return mBlockSizes; } const auto& getBlockSizes() const { return mBlockSizes; }
@ -66,16 +65,36 @@ namespace CNORXZ
MetaType meta() const; MetaType meta() const;
MIndex& at(const MetaType& metaPos); MIndex& at(const MetaType& metaPos);
template <class PosT, class Xpr> template <class Xpr, class F>
auto ifor(const PosT& step, const Xpr& xpr) const; decltype(auto) ifor(const Xpr& xpr, F&& f) const;
private: private:
MIndex() = default; MIndex() = default;
IndexPack mIPack; IndexPack mIPack;
Arr<SizeT,sizeof...(Indices)+1> mBlockSizes; Arr<SizeT,sizeof...(Indices)> mBlockSizes;
Sptr<RangeType> mRange; Sptr<RangeType> mRange;
// shift to utils:
template <SizeT P, SizeT... Is>
constexpr decltype(auto) indexSequencePlus(std::index_sequence<Is...> is) const;
// shift to utils:
template <SizeT B, SizeT E>
constexpr decltype(auto) mkIndexSequence() const;
template <class G, class F, SizeT... Is>
constexpr decltype(auto) accumulatei(const G& g, const F& f, std::index_sequence<Is...> is) const;
template <SizeT B, SizeT E, class G, class F>
constexpr decltype(auto) accumulate(const G& g, const F& f) const;
template <SizeT... Is>
constexpr decltype(auto) mkIPack(SizeT pos, std::index_sequence<Is...> is) const;
template <SizeT... Is>
constexpr decltype(auto) mkBlockSizes(std::index_sequence<Is...> is) const;
}; };
@ -84,44 +103,54 @@ namespace CNORXZ
class MRangeFactory : public RangeFactoryBase class MRangeFactory : public RangeFactoryBase
{ {
public: public:
MRangeFactory() = delete;
MRangeFactory(const Sptr<Ranges>&... rs);
MRangeFactory(const Tuple<Sptr<Ranges>...>& rs); MRangeFactory(const Tuple<Sptr<Ranges>...>& rs);
MRangeFactory(const Tuple<Sptr<Ranges>...>& rs, const RangePtr& ref);
private: private:
MRangeFactory() = default;
virtual void make() override final; virtual void make() override final;
Tuple<Sptr<Ranges>...> mRs; Tuple<Sptr<Ranges>...> mRs;
RangePtr mRef;
}; };
template <class... Ranges> template <class... Ranges>
class MRange : public RangeInterface<MIndex<typename Ranges::IndexType...> > class MRange : public RangeInterface<MIndex<typename Ranges::IndexType...>,
Tuple<typename Ranges::IndexType::MetaType...>>
{ {
public: public:
typedef RangeBase RB; typedef RangeBase RB;
typedef MIndex<typename Ranges::IndexType...> IndexType; typedef MIndex<typename Ranges::IndexType...> IndexType;
typedef Tuple<typename Ranges::IndexType::MetaType...> MetaType; typedef Tuple<typename Ranges::IndexType::MetaType...> MetaType;
const Space& space() const;
SizeT getMeta(const MetaType& metaPos) const;
virtual Sptr<RangeBase> sub(SizeT num) const override;
virtual SizeT dim() const final;
virtual SizeT size() const final;
virtual String stringMeta(SizeT pos) const final;
friend MRangeFactory<Ranges...>; friend MRangeFactory<Ranges...>;
virtual RangePtr sub(SizeT num) const override final;
virtual SizeT size() const override final;
virtual SizeT dim() const override final;
virtual String stringMeta(SizeT pos) const override final;
virtual IndexType begin() const override final;
virtual IndexType end() const override final;
decltype(auto) space() const;
const MetaType get(SizeT pos) const;
SizeT getMeta(const MetaType& metaPos) const;
protected: protected:
MRange() = delete; MRange() = delete;
MRange(const MRange& in) = delete; MRange(const MRange& in) = delete;
MRange& operator=(const MRange& in) = delete; MRange& operator=(const MRange& in) = delete;
MRange(const Tuple<Sptr<Ranges>...>& rs);
Tuple<Sptr<Ranges>...> mRs; Tuple<Sptr<Ranges>...> mRs;
Arr<RangePtr,sizeof...(Ranges)> mA;
private:
template <SizeT... Is>
decltype(auto) mkA(std::index_sequence<Is...> is) const;
template <SizeT... Is>
SizeT sizei(std::index_sequence<Is...> is) const;
}; };
} }

View file

@ -44,7 +44,8 @@ namespace CNORXZ
public: public:
virtual ~RangeBase() = default; virtual ~RangeBase() = default;
virtual RangePtr sub() const;
virtual SizeT size() const = 0; virtual SizeT size() const = 0;
virtual SizeT dim() const = 0; virtual SizeT dim() const = 0;
virtual const TypeInfo& type() const = 0; virtual const TypeInfo& type() const = 0;

View file

@ -39,6 +39,11 @@ namespace CNORXZ
* RangeBase * * RangeBase *
******************/ ******************/
RangePtr RangeBase::sub() const
{
return nullptr;
}
bool RangeBase::operator==(const RangeBase& in) const bool RangeBase::operator==(const RangeBase& in) const
{ {
return this == &in; return this == &in;