This commit is contained in:
Christian Zimmermann 2024-04-02 00:48:15 +02:00
parent ec30ad5839
commit 2fddb42e6c
7 changed files with 272 additions and 11 deletions

View file

@ -631,6 +631,12 @@ namespace CNORXZ
return MIndex<Indices...>(pack); return MIndex<Indices...>(pack);
} }
template <class... Indices>
constexpr decltype(auto) mindexPtr(const Sptr<Indices>&... is)
{
return std::make_shared<MIndex<Indices...>>(is...);
}
template <class... Indices> template <class... Indices>
constexpr decltype(auto) mindexPtr(const SPack<Indices...>& pack) constexpr decltype(auto) mindexPtr(const SPack<Indices...>& pack)
{ {

View file

@ -163,7 +163,7 @@ namespace CNORXZ
// 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!
/** Replace sub-index instances and update index position correspondingly. /** Replace sub-index instances and update index position correspondingly.
@param new index instances. @param mi New index instances.
*/ */
GMIndex& operator()(const Sptr<MIndex<Indices...>>& mi); GMIndex& operator()(const Sptr<MIndex<Indices...>>& mi);
@ -286,6 +286,12 @@ namespace CNORXZ
template <class... Indices> template <class... Indices>
constexpr decltype(auto) mindex(const SPack<Indices...>& pack); constexpr decltype(auto) mindex(const SPack<Indices...>& pack);
/** Create pointer to MIndex from index pack.
@param is Input index pointers.
*/
template <class... Indices>
constexpr decltype(auto) mindexPtr(const Sptr<Indices>&... is);
/** Create pointer to MIndex from index pack. /** Create pointer to MIndex from index pack.
@param pack Pack of input indices. @param pack Pack of input indices.
*/ */

View file

@ -187,7 +187,8 @@ namespace CNORXZ
| FPos | | FPos |
+==========*/ +==========*/
inline FPos::FPos(SizeT ext, const SizeT* map) : mExt(ext), mMap(map) {} inline FPos::FPos(SizeT ext, const SizeT* map, SizeT max, SizeT max2) :
mExt(ext), mMap(map), mMax(max), mMax2(max2) {}
constexpr SizeT FPos::size() const constexpr SizeT FPos::size() const
{ {
@ -214,6 +215,7 @@ namespace CNORXZ
template <class PosT1> template <class PosT1>
constexpr UPos FPos::operator()(const PosT1& a) const constexpr UPos FPos::operator()(const PosT1& a) const
{ {
assert(0);
return UPos(mExt * mMap[a.val()]); return UPos(mExt * mMap[a.val()]);
} }
@ -234,6 +236,11 @@ namespace CNORXZ
return val(); return val();
} }
constexpr SizeT FPos::max() const
{
return mMax;
}
/*===========+ /*===========+
| SFPos | | SFPos |
+===========*/ +===========*/
@ -320,6 +327,12 @@ namespace CNORXZ
return val(); return val();
} }
template <SizeT N, SizeT... Ms>
constexpr SizeT SFPos<N,Ms...>::max() const
{
return sizeof...(Ms); // CHECK!!!
}
/*==========+ /*==========+
| MPos | | MPos |
+==========*/ +==========*/

View file

@ -93,11 +93,13 @@ namespace CNORXZ
private: private:
SizeT mExt = 0; SizeT mExt = 0;
const SizeT* mMap = nullptr; const SizeT* mMap = nullptr;
SizeT mMax = 0;
SizeT mMax2 = 0; // !!!!
public: public:
DEFAULT_MEMBERS(FPos); DEFAULT_MEMBERS(FPos);
inline FPos(SizeT ext, const SizeT* map); inline FPos(SizeT ext, const SizeT* map, SizeT max = 0, SizeT max2 = 0);
constexpr SizeT size() const; constexpr SizeT size() const;
constexpr const SizeT& val() const; constexpr const SizeT& val() const;
@ -118,6 +120,10 @@ namespace CNORXZ
constexpr decltype(auto) operator<<(const PosT& a) const; constexpr decltype(auto) operator<<(const PosT& a) const;
explicit constexpr operator SizeT() const; explicit constexpr operator SizeT() const;
constexpr SizeT max() const;
constexpr SizeT max2() const { return mMax2; }
constexpr const SizeT* map() const { return mMap; }
}; };
template <SizeT N, SizeT... Ms> template <SizeT N, SizeT... Ms>
@ -151,6 +157,8 @@ namespace CNORXZ
explicit constexpr operator FPos() const; explicit constexpr operator FPos() const;
explicit constexpr operator SizeT() const; explicit constexpr operator SizeT() const;
constexpr SizeT max() const;
}; };
template <class BPosT, class NPosT> template <class BPosT, class NPosT>

View file

@ -53,6 +53,15 @@ namespace CNORXZ
*this = lexpos; *this = lexpos;
} }
template <class IndexI, class IndexK>
RIndex<IndexI,IndexK>::RIndex(const Sptr<IndexI>& i, const Sptr<IndexK>& k) :
mRange(rangeCast<RangeType>( RRangeFactory(i->range(), k->range()).create() )),
mI(i),
mK(k)
{
(*this)();
}
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)
{ {
@ -196,7 +205,7 @@ namespace CNORXZ
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() + mI->stepSize(id); return getRankStepSize(id) * mI->pmax() + mI->stepSize(id);
} }
template <class IndexI, class IndexK> template <class IndexI, class IndexK>
@ -283,8 +292,7 @@ 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
{ {
CXZ_ERROR("not implemented"); return mI->ifor(xpr, std::forward<F>(f));
return xpr;
} }
template <class IndexI, class IndexK> template <class IndexI, class IndexK>
@ -299,6 +307,13 @@ namespace CNORXZ
return _this->local()->xpr( _this->local() ); return _this->local()->xpr( _this->local() );
} }
template <class IndexI, class IndexK>
RIndex<IndexI,IndexK>& RIndex<IndexI,IndexK>::operator()(const Sptr<IndexI>& i)
{
mI = i;
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()()
{ {

View file

@ -56,6 +56,12 @@ namespace CNORXZ
*/ */
RIndex(const RangePtr& global, SizeT lexpos = 0); RIndex(const RangePtr& global, SizeT lexpos = 0);
/** Construct from local index and rank index.
@param i Local index.
@param k Rank index.
*/
RIndex(const Sptr<IndexI>& i, const Sptr<IndexK>& k);
/** @copydoc IndexInterface::operator=(SizeT) */ /** @copydoc IndexInterface::operator=(SizeT) */
RIndex& operator=(SizeT pos); RIndex& operator=(SizeT pos);
@ -136,6 +142,11 @@ namespace CNORXZ
/** @copydoc IndexInterface::xpr() */ /** @copydoc IndexInterface::xpr() */
decltype(auto) xpr(const Sptr<RIndex<IndexI,IndexK>>& _this) const; decltype(auto) xpr(const Sptr<RIndex<IndexI,IndexK>>& _this) const;
/** Replace local index instance and update index position correspondingly.
@param i New index instances.
*/
RIndex& operator()(const Sptr<IndexI>& i);
/** Update index position according to the sub-indices. */ /** Update index position according to the sub-indices. */
RIndex& operator()(); RIndex& operator()();
@ -150,8 +161,50 @@ namespace CNORXZ
Sptr<RangeType> mRange; /**< RRange. */ Sptr<RangeType> mRange; /**< RRange. */
Sptr<IndexI> mI; /**< 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. */
mutable std::map<PtrId,Vector<SizeT>> mRankMap;
template <SizeT I>
decltype(auto) getRankStepSize(const IndexId<I>& id) const
{
auto ss = mI->stepSize(id);
FPos x;
VCHECK(typeid(ss).name());
VCHECK(typeid(x).name());
assert(0);
if constexpr(std::is_same<decltype(ss),FPos>::value){
assert(0);
if(mRankMap.count(id.id()) != 0){
return FPos(ss.val(), mRankMap[id.id()].data());
}
else {
Vector<SizeT> mp(ss.max());
for(SizeT i = 0; i != mp.size(); ++i){
//max2 = num ranks in this dir (preliminary solution)!!!
mp[i] = ( ss.map()[i] / ss.max() ) % ss.max2();
}
mRankMap[id.id()] = mp;
return FPos(ss.val(), mp.data());
}
}
else {
return SPos<0> {};
}
}
}; };
template <class IndexI, class IndexK>
constexpr decltype(auto) rindex(const Sptr<IndexI>& i, const Sptr<IndexK>& k)
{
return RIndex<IndexI,IndexK>(i,k);
}
template <class IndexI, class IndexK>
constexpr decltype(auto) rindexPtr(const Sptr<IndexI>& i, const Sptr<IndexK>& k)
{
return std::make_shared<RIndex<IndexI,IndexK>>(i,k);
}
// Traits!!! // Traits!!!
template <class I> template <class I>
struct is_rank_index struct is_rank_index

View file

@ -52,14 +52,163 @@ namespace
RangePtr mGeom; RangePtr mGeom;
RangePtr mRRange; RangePtr mRRange;
}; };
template <class Index, class IndexR>
class IndexMap : public Index
{
public:
typedef typename Index::IB IB;
typedef typename Index::RangeType RangeType;
DEFAULT_MEMBERS(IndexMap);
IndexMap(const Sptr<Index>& i, const Vector<SizeT>& map, const Sptr<IndexR>& r) :
Index(*i), mI(i), mR(r), mMap(map) {}
constexpr decltype(auto) id() const
{
return mI->id();
}
template <SizeT I>
decltype(auto) stepSize(const IndexId<I>& id) const
{
// TODO: new Pos Type!!!
//assert(0);
return FPos( mI->stepSize(id).val(), mMap.data(), mI->lmax().val(), mR->lmax().val() );
}
private:
Sptr<Index> mI;
Sptr<IndexR> mR;
Vector<SizeT> mMap;
};
template <class Index, class IndexR>
constexpr decltype(auto) shift(const Sptr<Index>& i, const Sptr<IndexR>& r)
{
// only one-dim indices!!!
auto j = *i;
Vector<SizeT> mp(j.lmax().val());
const SizeT L = i->lmax().val()*r->lmax().val();
for(j = 0; j.lex() != j.lmax().val(); ++j){
mp[j.lex()] = ( j.lex() + 1 + L) % L;
}
return std::make_shared<IndexMap<Index,IndexR>>(i, mp, r);
}
template <class Index>
class PosOp : public COpInterface<PosOp<Index>>
{
public:
typedef COpInterface<PosOp<Index>> OI;
constexpr PosOp() = default;
constexpr PosOp(const Sptr<Index>& i, SizeT block) :
mMyrank(getRankNumber()), mI(i), mBlock(block) {}
template <class PosT>
constexpr decltype(auto) operator()(const PosT& pos) const
{
return static_cast<SizeT>(pos)+mMyrank*mBlock;
}
constexpr decltype(auto) operator()() const
{
return static_cast<SizeT>(mMyrank*mBlock);
}
template <SizeT I>
constexpr decltype(auto) rootSteps(const IndexId<I>& id) const
{
return mI->stepSize(id);
}
private:
SizeT mMyrank;
Sptr<Index> mI;
SizeT mBlock;
};
template <class Index>
constexpr decltype(auto) posop(const Sptr<Index>& i, SizeT block)
{
return PosOp<Index>(i, block);
}
} }
void run2(const Env& env)
int main(int argc, char** argv)
{ {
MPI_Init(&argc, &argv); const SizeT myrank = getRankNumber();
const SizeT Nranks = getNumRanks();
typedef UIndex<Int> UI;
typedef MIndex<UI,UI,UI,UI> LocI;
typedef MIndex<CIndex,CIndex,CIndex,CIndex> RankI;
auto rgi = std::make_shared<RIndex<LocI,RankI>>(env.mRRange);
auto rgj = std::make_shared<RIndex<LocI,RankI>>(env.mRRange);
auto rgk = std::make_shared<RIndex<LocI,RankI>>(env.mRRange);
LocI gi(env.mGRange);
LocI gj(env.mGRange);
auto ri = std::make_shared<RankI>(env.mGeom);
constexpr auto C0 = CSizeT<0> {};
constexpr auto C1 = CSizeT<1> {};
constexpr auto C2 = CSizeT<2> {};
constexpr auto C3 = CSizeT<3> {};
Env env; const SizeT LSize = env.mRRange->sub(1)->size();
const SizeT blocks = env.mSRange->size();
Vector<Double> data(LSize*blocks);
Vector<Double> buf;
Vector<Double*> map(env.mRRange->size(),nullptr);
for(SizeT i = 0; i != data.size(); ++i){
data[i] = static_cast<Double>(LSize*myrank*blocks+i);
}
Vector<Vector<SizeT>> cnt(Nranks);
for(auto& c: cnt){
c.resize(Nranks);
}
Vector<Vector<Double>> sendbuf(Nranks);
for(auto& sb: sendbuf){
sb.reserve(data.size());
}
auto srgi = rindexPtr( mindexPtr(
shift(rgi->local()->pack()[C0], ri->pack()[C0]),
rgi->local()->pack()[C1],
shift(rgi->local()->pack()[C2], ri->pack()[C2]),
shift(rgi->local()->pack()[C3], ri->pack()[C3])
), ri );
VCHECK(srgi->lmax().val());
*rgj = 0;
while(rgj->rank() != 1){
++*rgj;
}
*rgj->local() = 0;
rgi->ifor( operation
( [&](SizeT p) {
gj = rgj->lex();
*gj.pack()[C0] = (gj.pack()[C0]->lex() + 1) % gj.pack()[C0]->lmax().val();
*gj.pack()[C2] = (gj.pack()[C2]->lex() + 1) % gj.pack()[C2]->lmax().val();
*gj.pack()[C3] = (gj.pack()[C3]->lex() + 1) % gj.pack()[C3]->lmax().val();
gj();
*rgk = gj.lex();
if(myrank == 1){
std::cout << p << " " << rgk->pos() << " " << rgj->pos() << std::endl;
}
++*rgj->local();
(*rgj)();
} , posop(srgi, rgi->local()->pmax().val()) ) ,
NoF {} )();
MPI_Barrier(MPI_COMM_WORLD);
}
void run1(const Env& env)
{
const SizeT myrank = getRankNumber(); const SizeT myrank = getRankNumber();
const SizeT Nranks = getNumRanks(); const SizeT Nranks = getNumRanks();
@ -92,6 +241,7 @@ int main(int argc, char** argv)
for(auto& sb: sendbuf){ for(auto& sb: sendbuf){
sb.reserve(data.size()); sb.reserve(data.size());
} }
// First loop: setup send buffer // First loop: setup send buffer
for(rgi = 0, gi = 0; rgi.lex() != rgi.lmax().val(); ++rgi, ++gi){ for(rgi = 0, gi = 0; rgi.lex() != rgi.lmax().val(); ++rgi, ++gi){
gj = gi.lex(); gj = gi.lex();
@ -183,6 +333,16 @@ int main(int argc, char** argv)
assert(vn == rgj.pos()); assert(vn == rgj.pos());
} }
} }
MPI_Barrier(MPI_COMM_WORLD);
}
int main(int argc, char** argv)
{
MPI_Init(&argc, &argv);
Env env;
run1(env);
run2(env);
MPI_Finalize(); MPI_Finalize();
return 0; return 0;