diff --git a/src/opt/mpi/include/rrange.cc.h b/src/opt/mpi/include/rrange.cc.h index 8efabf5..41cf1f4 100644 --- a/src/opt/mpi/include/rrange.cc.h +++ b/src/opt/mpi/include/rrange.cc.h @@ -227,7 +227,29 @@ namespace CNORXZ template RIndex& RIndex::at(const MetaType& metaPos) { - CXZ_ERROR("not implemented"); + //VCHECK(toString(metaPos)); + //VCHECK(toString(mI->meta())); + mI->at(metaPos); + //VCHECK(toString(mI->meta())); + const size_t lex = mI->lex(); + //VCHECK(lex); + Vector lexs(mK->lmax().val()); + MPI_Allgather(&lex, 1, MPI_UNSIGNED_LONG, lexs.data(), 1, MPI_UNSIGNED_LONG, + MPI_COMM_WORLD); + VCHECK(toString(lexs)); + SizeT root = 0; + VCHECK(mI->lmax().val()); + for(; root != lexs.size() and lexs[root] == mI->lmax().val(); ++root) {} + if(root == lexs.size()){ // metaPos not in rrange + *this = lmax().val(); + assert(0); + } + else { + *mK = root; + *mI = lexs[root]; + VCHECK(lexs[root]); + (*this)(); + } return *this; } @@ -277,6 +299,42 @@ namespace CNORXZ return _this->local()->xpr( _this->local() ); } + template + RIndex& RIndex::operator()() + { + if constexpr(has_static_sub::value){ + constexpr SizeT NI = index_dim::value; + IB::mPos = iter<0,NI> + ([&](auto i) { + return mK->pack()[i]->lex() * mK->lexFormat()[i].val() * + mI->lexFormat()[i].val() * mI->pack()[i]->lmax().val() + + mI->pack()[i]->lex() * mI->lexFormat()[i].val() * + mK->lexFormat()[i].val(); + }, [](const auto&... e) { return (e + ...); }); + } + else if constexpr( has_static_sub::value){ + constexpr SizeT NI = index_dim::value; + IB::mPos = iter<0,NI> + ([&](auto i) { + return mK->pack()[i]->lex() * mK->lexFormat()[i].val() * + mI->lexFormat()[i].val() * mI->pack()[i]->lmax().val() + + mI->pack()[i]->lex() * mI->lexFormat()[i].val() * + mK->lexFormat()[i].val(); + }, [](const auto&... e) { return (e + ...); }); + } + else { + const SizeT NI = mI->dim(); + IB::mPos = 0; + for(SizeT i = 0; i != NI; ++i){ + IB::mPos += mK->pack()[i]->lex() * mK->lexFormat()[i].val() * + mI->lexFormat()[i].val() * mI->pack()[i]->lmax().val() + + mI->pack()[i]->lex() * mI->lexFormat()[i].val() * + mK->lexFormat()[i].val(); + } + } + return *this; + } + template SizeT RIndex::rank() const { @@ -365,7 +423,7 @@ namespace CNORXZ template SizeT RRange::dim() const { - return mGeom->dim() + mLocal->dim(); + return 2; } template @@ -439,8 +497,23 @@ namespace CNORXZ { return Vector { mLocal->id(), mGeom->id() }; } - + + /*============================+ + | non-member functions | + +============================*/ + } // namespace mpi + + template + Sptr> RangeCast>::func(const RangePtr& r) + { + CXZ_ASSERT(r->dim() == 2, "expected RRange"); + Sptr loc = rangeCast(r->sub(1)); + Sptr geom = rangeCast(r->sub(0)); + return std::dynamic_pointer_cast> + ( mpi::RRangeFactory( loc, geom ).create() ); + } + } // namespace CNORXZ #endif diff --git a/src/opt/mpi/include/rrange.h b/src/opt/mpi/include/rrange.h index 2f636cf..3aa0767 100644 --- a/src/opt/mpi/include/rrange.h +++ b/src/opt/mpi/include/rrange.h @@ -136,6 +136,9 @@ namespace CNORXZ /** @copydoc IndexInterface::xpr() */ decltype(auto) xpr(const Sptr>& _this) const; + /** Update index position according to the sub-indices. */ + RIndex& operator()(); + /** Get the current rank. */ SizeT rank() const; @@ -254,8 +257,15 @@ namespace CNORXZ @param geom Rank geometry. */ RangePtr rrange(const RangePtr& global, const RangePtr& geom); - + } // namespace mpi + + template + struct RangeCast> + { + static Sptr> func(const RangePtr& r); + }; + } // namespace CNORXZ #endif diff --git a/src/opt/mpi/tests/rrange_unit_test.cc b/src/opt/mpi/tests/rrange_unit_test.cc index 6f2b6ce..b7f4e2e 100644 --- a/src/opt/mpi/tests/rrange_unit_test.cc +++ b/src/opt/mpi/tests/rrange_unit_test.cc @@ -119,6 +119,43 @@ namespace EXPECT_EQ(s1 ,s2); } } + + TEST_F(RRange_Test, Global2) + { + typedef UIndex UI; + typedef MIndex LocI; + typedef MIndex RankI; + RIndex rgi(mRRange); + LocI gi(mGRange); + for(SizeT c = 0; gi.lex() != gi.lmax().val(); ++gi, ++rgi, ++c) { + const String s1 = gi.stringMeta(); + const String s2 = rgi.stringMeta(); + EXPECT_EQ(rgi.lex(), c); + EXPECT_EQ(s1 ,s2); + } + rgi = 0; + gi = 0; + auto xi = gi; + gi = 10; + xi.at( gi.meta() ); + EXPECT_EQ( xi.lex(), gi.lex() ); + //VCHECK(toString(rgi.local()->meta())); + VCHECK(rgi.local()->at( gi.meta() ).lex()); + /* + auto j = rgi; + for(auto i = rgi; i.lex() != i.lmax().val(); ++i){ + j.at( i.meta() ); + if(getRankNumber() == 0){ + EXPECT_EQ(i.lex(), j.lex()); + EXPECT_EQ(i.rank(), j.rank()); + EXPECT_EQ(i.local()->lex(), j.local()->lex()); + } + if(i.lex() == 50) { + break; + } + } + */ + } }