mpi: rindex: synchronize/localize utilities

This commit is contained in:
Christian Zimmermann 2024-10-18 23:59:41 -07:00
parent 19a4cd2467
commit 03afacb1e5
3 changed files with 71 additions and 4 deletions

View file

@ -339,10 +339,10 @@ namespace CNORXZ
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
{ {
const SizeT r = getRankNumber(); //const SizeT r = getRankNumber();
const SizeT off = r % mRankFormat; //const SizeT off = r % mRankFormat;
//assert(off == mRankOffset); //const SizeT n = ( (r-off) / mRankFormat ) % mK->pmax().val();
const SizeT n = ( (r-off) / mRankFormat ) % mK->pmax().val(); const SizeT n = mK->lex();
return accxpr( n, mK->id(), mI->ifor(xpr, std::forward<F>(f)), NoF {}); return accxpr( n, mK->id(), mI->ifor(xpr, std::forward<F>(f)), NoF {});
} }
@ -458,6 +458,60 @@ namespace CNORXZ
return mStepRatio; return mStepRatio;
} }
template <class IndexI, class IndexK>
bool RIndex<IndexI,IndexK>::isSynchronous() const
{
const size_t lx = lex();
Vector<size_t> lexs(mNRanks);
MPI_Allgather(&lx, 1, MPI_UNSIGNED_LONG, lexs.data(), 1, MPI_UNSIGNED_LONG,
MPI_COMM_WORLD);
const size_t glex = lexs[0];
bool o = true;
for(const auto& l: lexs){
if(l != glex){
o = false;
break;
}
}
return o;
}
template <class IndexI, class IndexK>
bool RIndex<IndexI,IndexK>::isLocalized() const
{
const size_t lx = mK->lex();
const unsigned short is = (lx == myrank());
Vector<unsigned short> iss(mNRanks);
MPI_Allgather(&is, 1, MPI_UNSIGNED_SHORT, iss.data(), 1, MPI_UNSIGNED_SHORT,
MPI_COMM_WORLD);
bool o = true;
for(const auto& l: iss){
if(not l){
o = false;
break;
}
}
return o;
}
template <class IndexI, class IndexK>
RIndex<IndexI,IndexK>& RIndex<IndexI,IndexK>::localize()
{
(*mK) = myrank();
(*this)();
return *this;
}
template <class IndexI, class IndexK>
SizeT RIndex<IndexI,IndexK>::myrank() const
{
const SizeT r = getRankNumber();
const SizeT off = r % mRankFormat;
assert((r-off)/mRankFormat == r/mRankFormat);
const SizeT n = ( (r-off) / mRankFormat ) % mK->pmax().val();
return n;
}
template <class IndexI, class IndexK, class I1> template <class IndexI, class IndexK, class I1>
decltype(auto) operator*(const Sptr<RIndex<IndexI,IndexK>>& a, const Sptr<I1>& b) decltype(auto) operator*(const Sptr<RIndex<IndexI,IndexK>>& a, const Sptr<I1>& b)
{ {

View file

@ -172,6 +172,18 @@ namespace CNORXZ
/** Get step ratio. */ /** Get step ratio. */
SizeT stepRatio() const; SizeT stepRatio() const;
/** Check if index points to the same global position on each rank. */
bool isSynchronous() const;
/** Check if index points to own rank on each rank. */
bool isLocalized() const;
/** Set internl rank index to own rank. Results in non-synchronous state. */
RIndex& localize();
/** Get this rank considering rank format. */
SizeT myrank() const;
private: private:
SizeT mLex = 0; SizeT mLex = 0;
Sptr<RangeType> mRange; /**< RRange. */ Sptr<RangeType> mRange; /**< RRange. */

View file

@ -140,6 +140,7 @@ namespace
for(const auto& r: *imap1){ for(const auto& r: *imap1){
req[r] = true; req[r] = true;
} }
x->localize();
res.load(x, AB, req); // DUMMY, not used... res.load(x, AB, req); // DUMMY, not used...
mM1.load(xp, AB, req); mM1.load(xp, AB, req);
res(x*A*B) = mapXpr(xp,x,imap1, mM1(xp*A*B) - mM1(x*A*B) ); res(x*A*B) = mapXpr(xp,x,imap1, mM1(xp*A*B) - mM1(x*A*B) );