WIP: RRange

This commit is contained in:
Christian Zimmermann 2024-03-12 00:44:23 +01:00
parent 6bfba5cdd9
commit 6edd39de37
2 changed files with 157 additions and 48 deletions

View file

@ -19,6 +19,10 @@ namespace CNORXZ
namespace mpi namespace mpi
{ {
/*==============+
| RIndex |
+==============*/
template <class IndexI, class IndexK> template <class IndexI, class IndexK>
RIndex<IndexI,IndexK>::RIndex(const RIndex& in) : RIndex<IndexI,IndexK>::RIndex(const RIndex& in) :
mRange(in.mRange), mRange(in.mRange),
@ -50,193 +54,274 @@ namespace CNORXZ
template <class IndexI, class IndexK> template <class IndexI, class IndexK>
RIndex<IndexI,IndexK>::RIndex(const Sptr<Index>& local) : RIndex<IndexI,IndexK>::RIndex(const Sptr<Index>& local) :
{ {
CXZ_ERROR("not implemented");
//!!! //!!!
} }
template <class IndexI, class IndexK> template <class IndexI, class IndexK>
RIndex<IndexI,IndexK>& RIndex<IndexI,IndexK>::operator=(SizeT pos) RIndex<IndexI,IndexK>& RIndex<IndexI,IndexK>::operator=(SizeT pos)
{ {
IB::mPos = pos; // = lex
if(lexpos >= lmax().val()){
IB::mPos = pmax().val();
return *this;
}
// pos is the lexicographic position of the global range. // pos is the lexicographic position of the global range.
// Hence, have to consider the rank geometry. // Hence, have to consider the rank geometry.
if constexpr(has_static_sub<IndexI>::value or has_static_sub<IndexK>::value){ const auto& i = mI->pack();
const auto& k = mK->pack();
const auto& ilf = mI->lexFormat();
const auto& klf = mK->lexFormat();
SizeT r = 0;
SizeT l = 0;
if constexpr(has_static_sub<IndexI>::value){
constexpr SizeT NI = index_dim<IndexI>::value;
iter<0,NI>( [&](auto mu) {
const SizeT jmu = (IB::mPos / ilf[mu].val()*klf[mu].val()) %
i[mu]->lmax().val()*k[mu]->lmax().val();
r += ( jmu / i[mu]->lmax().val() ) * klf[mu].val();
l += ( jmu % i[mu]->lmax().val() ) * ilf[mu].val();
}, NoF{} );
}
else if constexpr( has_static_sub<IndexK>::value){
constexpr SizeT NI = index_dim<IndexK>::value;
iter<0,NI>( [&](auto mu) {
const SizeT jmu = (IB::mPos / ilf[mu].val()*klf[mu].val()) %
i[mu]->lmax().val()*k[mu]->lmax().val();
r += ( jmu / i[mu]->lmax().val() ) * klf[mu].val();
l += ( jmu % i[mu]->lmax().val() ) * ilf[mu].val();
}, NoF{} );
} }
else { else {
const SizeT NI = mI->dim();
for(SizeT mu = 0; mu != NI; ++mu){
const SizeT jmu = (IB::mPos / ilf[mu].val()*klf[mu].val()) %
i[mu]->lmax().val()*k[mu]->lmax().val();
r += ( jmu / i[mu]->lmax().val() ) * klf[mu].val();
l += ( jmu % i[mu]->lmax().val() ) * ilf[mu].val();
} }
}
*mI = l;
*mK = r;
return *this; return *this;
} }
template <class IndexI, class IndexK> template <class IndexI, class IndexK>
RIndex<IndexI,IndexK>& RIndex<IndexI,IndexK>::operator++() RIndex<IndexI,IndexK>& RIndex<IndexI,IndexK>::operator++()
{ {
*this = lex() + 1; // room for optimization
return *this; return *this;
} }
template <class IndexI, class IndexK> template <class IndexI, class IndexK>
RIndex<IndexI,IndexK>& RIndex<IndexI,IndexK>::operator--() RIndex<IndexI,IndexK>& RIndex<IndexI,IndexK>::operator--()
{ {
*this = lex() - 1; // room for optimization
return *this; return *this;
} }
template <class IndexI, class IndexK> template <class IndexI, class IndexK>
RIndex<IndexI,IndexK> RIndex<IndexI,IndexK>::operator+(Int n) const RIndex<IndexI,IndexK> RIndex<IndexI,IndexK>::operator+(Int n) const
{ {
RIndex<IndexI,IndexK> o(*this);
return o += n;
} }
template <class IndexI, class IndexK> template <class IndexI, class IndexK>
RIndex<IndexI,IndexK> RIndex<IndexI,IndexK>::operator-(Int n) const RIndex<IndexI,IndexK> RIndex<IndexI,IndexK>::operator-(Int n) const
{ {
RIndex<IndexI,IndexK> o(*this);
return o -= n;
} }
template <class IndexI, class IndexK> template <class IndexI, class IndexK>
SizeT RIndex<IndexI,IndexK>::operator-(const RIndex& i) const SizeT RIndex<IndexI,IndexK>::operator-(const RIndex& i) const
{ {
return lex() - i.lex();
} }
template <class IndexI, class IndexK> template <class IndexI, class IndexK>
RIndex<IndexI,IndexK>& RIndex<IndexI,IndexK>::operator+=(Int n) RIndex<IndexI,IndexK>& RIndex<IndexI,IndexK>::operator+=(Int n)
{ {
*this = lex() + n;
return *this; return *this;
} }
template <class IndexI, class IndexK> template <class IndexI, class IndexK>
RIndex<IndexI,IndexK>& RIndex<IndexI,IndexK>::operator-=(Int n) RIndex<IndexI,IndexK>& RIndex<IndexI,IndexK>::operator-=(Int n)
{ {
*this = lex() - n;
return *this; return *this;
} }
template <class IndexI, class IndexK> template <class IndexI, class IndexK>
SizeT RIndex<IndexI,IndexK>::lex() const SizeT RIndex<IndexI,IndexK>::lex() const
{ {
return IB::mPos;
} }
template <class IndexI, class IndexK> template <class IndexI, class IndexK>
constexpr RIndex<IndexI,IndexK>::decltype(auto) pmax() const constexpr RIndex<IndexI,IndexK>::decltype(auto) pmax() const
{ {
return mK->lmax().val() * mI->lmax().val();
} }
template <class IndexI, class IndexK> template <class IndexI, class IndexK>
constexpr RIndex<IndexI,IndexK>::decltype(auto) lmax() const constexpr RIndex<IndexI,IndexK>::decltype(auto) lmax() const
{ {
return mK->lmax().val() * mI->lmax().val();
} }
template <class IndexI, class IndexK> template <class IndexI, class IndexK>
IndexId<0> RIndex<IndexI,IndexK>::id() const IndexId<0> RIndex<IndexI,IndexK>::id() const
{ {
return IndexId<0>(this->ptrId());
} }
template <class IndexI, class IndexK> template <class IndexI, class IndexK>
MetaType RIndex<IndexI,IndexK>::operator*() const MetaType RIndex<IndexI,IndexK>::operator*() const
{ {
return meta();
} }
template <class IndexI, class IndexK> template <class IndexI, class IndexK>
constexpr SizeT RIndex<IndexI,IndexK>::dim() const constexpr SizeT RIndex<IndexI,IndexK>::dim() const
{ {
return mI->dim();
} }
template <class IndexI, class IndexK> template <class IndexI, class IndexK>
Sptr<RangeType> RIndex<IndexI,IndexK>::range() const Sptr<RangeType> RIndex<IndexI,IndexK>::range() const
{ {
return mRange;
} }
template <class IndexI, class IndexK> template <class IndexI, class IndexK>
template <SizeT I> template <SizeT I>
decltype(auto) RIndex<IndexI,IndexK>::stepSize(const IndexId<I>& id) const decltype(auto) RIndex<IndexI,IndexK>::stepSize(const IndexId<I>& id) const
{ {
return mK->stepSize(id) * mI->lmax().val() + mI->stepSize(id);
} }
template <class IndexI, class IndexK> template <class IndexI, class IndexK>
String RIndex<IndexI,IndexK>::stringMeta() const String RIndex<IndexI,IndexK>::stringMeta() const
{ {
const SizeT r = mK->lex();
String o;
broadcast(r, mI->stringMeta(), &o);
return o;
} }
template <class IndexI, class IndexK> template <class IndexI, class IndexK>
MetaType RIndex<IndexI,IndexK>::meta() const MetaType RIndex<IndexI,IndexK>::meta() const
{ {
const SizeT r = mK->lex();
MetaType o;
broadcast(r, mI->meta(), &o);
return o;
} }
template <class IndexI, class IndexK> template <class IndexI, class IndexK>
RIndex<IndexI,IndexK>& RIndex<IndexI,IndexK>::at(const MetaType& metaPos) RIndex<IndexI,IndexK>& RIndex<IndexI,IndexK>::at(const MetaType& metaPos)
{ {
CXZ_ERROR("not implemented");
return *this;
} }
template <class IndexI, class IndexK> template <class IndexI, class IndexK>
RangePtr RIndex<IndexI,IndexK>::prange(const RIndex<IndexI,IndexK>& last) const RangePtr RIndex<IndexI,IndexK>::prange(const RIndex<IndexI,IndexK>& last) const
{ {
CXZ_ERROR("not implemented");
return nullptr;
} }
template <class IndexI, class IndexK> template <class IndexI, class IndexK>
auto RIndex<IndexI,IndexK>::deepFormat() const auto RIndex<IndexI,IndexK>::deepFormat() const
{ {
return concat( mul(mK->deepFormat(), mI->lmax().val() ), mI->deepFormat() );
} }
template <class IndexI, class IndexK> template <class IndexI, class IndexK>
auto RIndex<IndexI,IndexK>::deepMax() const auto RIndex<IndexI,IndexK>::deepMax() const
{ {
return concat( mK->deepMax(), mI->deepMax() );
} }
template <class IndexI, class IndexK> template <class IndexI, class IndexK>
RIndex<IndexI,IndexK>& RIndex<IndexI,IndexK>::reformat(const Vector<SizeT>& f, const Vector<SizeT>& s) RIndex<IndexI,IndexK>& RIndex<IndexI,IndexK>::reformat(const Vector<SizeT>& f, const Vector<SizeT>& s)
{ {
CXZ_ERROR("not implemented");
return *this;
} }
template <class IndexI, class IndexK> template <class IndexI, class IndexK>
template <class Xpr, class F> template <class Xpr, class F>
constexpr decltype(auto) RIndex<IndexI,IndexK>::ifor(const Xpr& xpr, F&& f) const constexpr decltype(auto) RIndex<IndexI,IndexK>::ifor(const Xpr& xpr, F&& f) const
{ {
CXZ_ERROR("not implemented");
return 0;
} }
template <class IndexI, class IndexK> template <class IndexI, class IndexK>
bool RIndex<IndexI,IndexK>::formatIsTrivial() const bool RIndex<IndexI,IndexK>::formatIsTrivial() const
{ {
return mI->formatIsTrivial();
} }
template <class IndexI, class IndexK> template <class IndexI, class IndexK>
decltype(auto) RIndex<IndexI,IndexK>::xpr(const Sptr<RIndex<IndexI,IndexK>>& _this) const decltype(auto) RIndex<IndexI,IndexK>::xpr(const Sptr<RIndex<IndexI,IndexK>>& _this) const
{ {
CXZ_ERROR("not implemented");
return 0;
} }
template <class IndexI, class IndexK> template <class IndexI, class IndexK>
int RIndex<IndexI,IndexK>::rank() const SizeT RIndex<IndexI,IndexK>::rank() const
{ {
return mK->lex();
} }
template <class IndexI, class IndexK> template <class IndexI, class IndexK>
Sptr<Index> RIndex<IndexI,IndexK>::local() const Sptr<Index> RIndex<IndexI,IndexK>::local() const
{ {
return mI;
} }
/*=====================+
| RRangeFactory |
+=====================*/
template <class RangeI, class RangeK>
RRangeFactory<RangeI,RangeK>::RRangeFactory(const Sptr<RangeI>& ri,
const Sptr<RangeK>& rk):
mRI(ri),
mRK(rk)
{
if constexpr(has_static_sub<typename RangeI::IndexType>::value and
has_static_sub<typename RangeK::IndexType>::value) {
static_assert(typename RangeI::NR == typename RangeK::NR,
"ranges have to be of same dimension");
}
else {
CXZ_ASSERT(ri->dim() == rk->dim(), "ranges have to be of same dimension, got "
<< ri->dim() << " and " << rk->dim());
}
}
template <class RangeI, class RangeK>
void RRangeFactory<RangeI,RangeK>::make()
{
Vector<Uuid> key = { mRI->key(), mRK->key() };
const auto& info = typeid(RRange<RangeI,RangeK>);
mProd = this->fromCreated(info, key);
if(mProd == nullptr) {
mProd = std::shared_ptr<RRange<RangeI,RangeK>>
( new RRange<RangeI,RangeK>(mRI, mRK) );
this->addToCreated(info, key, mProd);
}
}
} // namespace mpi } // namespace mpi
} // namespace CNORXZ } // namespace CNORXZ

View file

@ -26,12 +26,12 @@ namespace CNORXZ
@tparam IndexK Index type used to indicate the rank. @tparam IndexK Index type used to indicate the rank.
*/ */
template <class IndexI, class IndexK> template <class IndexI, class IndexK>
class RIndex : public IndexInterface<RIndex<IndexI,IndexK>,typename Index::MetaType> class RIndex : public IndexInterface<RIndex<IndexI,IndexK>,typename IndexI::MetaType>
{ {
public: public:
typedef IndexInterface<RIndex<IndexI,IndexK>,typename Index::MetaType> IB; typedef IndexInterface<RIndex<IndexI,IndexK>,typename IndexI::MetaType> IB;
typedef typename Index::MetaType MetaType; typedef typename IndexI::MetaType MetaType;
typedef RRange<typename Index::RangeType> RangeType; typedef RRange<typename IndexI::RangeType,typename IndexK::RangeType> RangeType;
INDEX_RANDOM_ACCESS_ITERATOR_DEFS(MetaType); INDEX_RANDOM_ACCESS_ITERATOR_DEFS(MetaType);
@ -141,7 +141,7 @@ namespace CNORXZ
decltype(auto) xpr(const Sptr<RIndex<IndexI,IndexK>>& _this) const; decltype(auto) xpr(const Sptr<RIndex<IndexI,IndexK>>& _this) const;
/** Get the current rank. */ /** Get the current rank. */
int rank() const; SizeT rank() const;
/** Get the local index on THIS rank. */ /** Get the local index on THIS rank. */
Sptr<IndexI,IndexK> local() const; Sptr<IndexI,IndexK> local() const;
@ -149,24 +149,48 @@ namespace CNORXZ
private: private:
Sptr<RangeType> mRange; /**< RRange. */ Sptr<RangeType> mRange; /**< RRange. */
Sptr<IndexI> mJ; /**< Index on the local range of the THIS rank. */ Sptr<IndexI> mI; /**< Index on the local range of the THIS rank. */
Sptr<IndexK> mK; /**< Multi-index indicating the current rank. */ Sptr<IndexK> mK; /**< Multi-index indicating the current rank. */
//!!! //!!!
}; };
// Factory!!! // Traits!!!
/** ****
Specific factory for RRange.
@tparam RangeI Local range type.
@tparam RangeK Geometry range type.
*/
template <class RangeI, class RangeK>
class RRangeFactory : public RangeFactoryBase
{
public:
/** Construct and setup factory.
@param ri Local range.
@param rk Geometry range.
*/
RRangeFactory(const Sptr<RangeI>& ri, const Sptr<RangeK>& rk);
private:
RRangeFactory() = default;
virtual void make() override final;
Sptr<RangeI> mRI;
Sptr<RangeK> mRK;
};
/** **** /** ****
Range-Wrapper for ranges that are distributed on MPI ranks. Range-Wrapper for ranges that are distributed on MPI ranks.
@tparam Range Local range type. @tparam RangeI Local range type.
@tparam RangeK Geometry range type.
*/ */
template <class Range> template <class RangeI, class RangeK>
class RRange : public RangeInterface<RRange<Range>> class RRange : public RangeInterface<RRange<RangeI,RangeK>>
{ {
public: public:
typedef RangeBase RB; typedef RangeBase RB;
typedef RIndex<typename Range::IndexType> IndexType; typedef RIndex<typename RangeI::IndexType,typename RangeK::IndexType> IndexType;
typedef typename Range::MetaType MetaType; typedef typename RangeI::MetaType MetaType;
friend RRangeFactory<Range>; friend RRangeFactory<Range>;
@ -180,10 +204,10 @@ namespace CNORXZ
virtual RangePtr extend(const RangePtr& r) const override final; virtual RangePtr extend(const RangePtr& r) const override final;
/** Get local range. */ /** Get local range. */
Sptr<Range> local() const; Sptr<RangeI> local() const;
/** Get range of the rank geometry. */ /** Get range of the rank geometry. */
Sptr<YRange> geom() const; Sptr<RangeK> geom() const;
/** Get meta data for given lexicographic position. /** Get meta data for given lexicographic position.
@param pos Lexicographic position. @param pos Lexicographic position.
@ -214,8 +238,8 @@ namespace CNORXZ
*/ */
RRange(const Sptr<Range>& loc, const Sptr<YRange>& geom); RRange(const Sptr<Range>& loc, const Sptr<YRange>& geom);
Sptr<Range> mLocal; /**< Local range of THIS rank. */ Sptr<RangeI> mLocal; /**< Local range of THIS rank. */
Sptr<YRange> mGeom; /**< Rank geometry range. */ Sptr<RangeK> mGeom; /**< Rank geometry range. */
}; };