17#include <unordered_map>
60 if (!RankOffsets.empty())
61 return RankOffsets[RankOffsets.size() - 1];
74 RankLengths.resize(mpi.size);
75 RankOffsets.resize(mpi.size + 1);
76 RankLengths[mpi.rank] = myLength;
86 for (
size_t i = 0; i < RankLengths.size(); i++)
88 RankOffsets[i + 1] = RankOffsets[i] + RankLengths[i];
103 DNDS_assert((rank >= 0 && rank <= RankLengths.size()) &&
104 (val >= 0 && val <= RankOffsets[rank + 1] - RankOffsets[rank]));
105 return RankOffsets[rank] + val;
121 if (RankOffsets.empty())
123 auto place = std::lower_bound(RankOffsets.begin(), RankOffsets.end(), globalQuery, std::less_equal<index>());
124 rank =
static_cast<MPI_int>(place - 1 - RankOffsets.begin());
125 if (rank < RankLengths.size() && rank >= 0)
127 val = globalQuery - RankOffsets[rank];
133 [[nodiscard]] std::tuple<bool, MPI_int, index>
search(
index globalQuery)
const
137 bool ret = this->
search(globalQuery, rank, val);
138 return std::make_tuple(ret, rank, val);
168 using t_MapIndexVec = std::vector<mapIndex>;
169 static_assert(std::numeric_limits<mapIndex>::max() >= std::numeric_limits<MPI_int>::max());
213 template <
class TpullSet>
215 TpullSet &&pullingIndexGlobal,
218 : mainOffset(nmainOffset),
222 std::sort(pullingIndexGlobal.begin(), pullingIndexGlobal.end());
223 auto last = std::unique(pullingIndexGlobal.begin(), pullingIndexGlobal.end());
224 pullingIndexGlobal.erase(last, pullingIndexGlobal.end());
225 pullingIndexGlobal.shrink_to_fit();
230 for (
auto i : pullingIndexGlobal)
234 bool search_result = LGlobalMapping.
search(i, rank, loc);
245 for (
auto i : pullingIndexGlobal)
249 bool search_result = LGlobalMapping.
search(i, rank, loc);
258 pushIndexSizes.resize(mpi.size);
296 template <
class TpushSet,
class TpushStart>
298 TpushSet &&pushingIndexesLocal,
299 TpushStart &&pushingStarts,
302 : mainOffset(nmainOffset),
305 DNDS_assert(pushingStarts.size() == mpi.size + 1 && pushingIndexesLocal.size() == pushingStarts[mpi.size]);
308 for (
int i = 0; i < mpi.size; i++)
321 for (
size_t i = 0; i <
ghostSizes.size(); i++)
364 if (globalQuery >= mainOffset && globalQuery < mainSize + mainOffset)
366 val = globalQuery - mainOffset;
382 auto place = std::lower_bound(start, end, globalQuery);
383 if (place != end && *place == globalQuery)
399 auto place = std::lower_bound(start, end, globalQuery);
400 if (place != end && *place == globalQuery)
405 auto s_place = std::lower_bound(s_start, s_end, val, std::less_equal<rowsize>());
406 DNDS_assert(s_place != s_end && s_place > s_start);
407 rank =
static_cast<MPI_int>(s_place - s_start - 1);
432 [[nodiscard]] std::tuple<bool, MPI_int, index>
search(
index globalQuery)
const
436 bool ret = this->
search(globalQuery, rank, val);
437 return std::make_tuple(ret, rank, val);
467 return std::make_tuple(ret, rank, val);
497 return std::make_tuple(ret, rank, val);
515 return val + mainOffset;
525 (rank >= 0 && rank <
ghostStart.size() - 1) &&
Core type aliases, constants, and metaprogramming utilities for the DNDS framework.
#define DNDS_assert_info(expr, info)
Debug-only assertion with an extra std::string info message.
#define DNDS_assert(expr)
Debug-only assertion (compiled out when DNDS_NDEBUG is defined). Prints the expression + file/line + ...
MPI wrappers: MPIInfo, collective operations, type mapping, CommStrategy.
Table mapping rank-local row indices to the global index space.
std::tuple< bool, MPI_int, index > search(index globalQuery) const
index globalSize() const
Total number of rows across all ranks.
t_IndexVec & ROffsets()
Prefix-sum offsets vector (size == nRanks + 1, last element == globalSize).
void setMPIAlignBcast(const MPIInfo &mpi, index myLength)
Broadcast each rank's length, then compute the global prefix sums.
index operator()(MPI_int rank, index val) const
Convert a (rank, local) pair to a global index.
bool search(index globalQuery, MPI_int &rank, index &val) const
Convert a global index to (rank, local). Returns false if out of range.
t_IndexVec & RLengths()
Per-rank lengths vector (size == nRanks).
Mapping between a rank's main data and its ghost copies.
bool search_indexAppend(index globalQuery, MPI_int &rank, index &val) const
Like search, but the returned val is in the concatenated father+son address space.
bool searchInGhost(index globalQuery, MPI_int rank, index &val) const
Search a single peer rank's ghost slab for a global index.
OffsetAscendIndexMapping(index nmainOffset, index nmainSize, TpullSet &&pullingIndexGlobal, const GlobalOffsetsMapping &LGlobalMapping, const MPIInfo &mpi)
Construct the mapping from a pull specification.
t_IndexVec ghostIndex
Global indices of all ghost rows on this rank, ascending. (a.k.a. pullingIndexGlobal)
t_IndexVec pushingIndexGlobal
Global indices this rank sends to others, grouped by receiver.
OffsetAscendIndexMapping(index nmainOffset, index nmainSize, TpushSet &&pushingIndexesLocal, TpushStart &&pushingStarts, const GlobalOffsetsMapping &LGlobalMapping, const MPIInfo &mpi)
Construct the mapping from a push specification.
bool searchInMain(index globalQuery, index &val) const
Check whether a global index lies within the main block.
index operator()(MPI_int rank, index val) const
Reverse (local -> global) mapping.
bool search_indexRank(index globalQuery, MPI_int &rank, index &val) const
Like search, but val is expressed relative to the owner rank's ghost slab (ghostStart[rank]-relative)...
std::tuple< bool, MPI_int, index > search_indexRank(index globalQuery) const
Tuple-return overload of search_indexRank.
index & ghostAt(MPI_int rank, index ighost)
Direct mutable access to the ighost-th ghost global index for peer rank.
tMPI_intVec pushIndexSizes
Per-peer number of rows this rank will send out on a push.
t_MapIndexVec ghostStart
Per-peer prefix-sum offsets into ghostIndex (size == nRanks + 1). (a.k.a. pullIndexStarts)
tMPI_intVec ghostSizes
Number of ghost rows pulled from each peer rank. (a.k.a. pullIndexSizes)
std::tuple< bool, MPI_int, index > search(index globalQuery) const
Tuple-return overload of the main search. (success, rank, local).
std::tuple< bool, MPI_int, index > search_indexAppend(index globalQuery) const
Tuple-return overload of search_indexAppend.
t_IndexVec pullingRequestLocal
Optional cached local-index form of ghostIndex (unused in current code).
void sort()
Sort ghostIndex into ascending order. Required invariant maintained after pull construction.
t_MapIndexVec pushIndexStarts
Per-peer prefix-sum offsets into pushingIndexGlobal.
bool search(index globalQuery, MPI_int &rank, index &val) const
Search main + ghost in one call. rank == -1 signals "hit in main".
bool searchInAllGhost(index globalQuery, MPI_int &rank, index &val) const
Search the concatenated ghost array for a global index (O(log nGhost)).
MPI_int Bcast(void *buf, MPI_int num, MPI_Datatype type, MPI_int source_rank, MPI_Comm comm)
dumb wrapper
MPI_int Alltoall(void *send, MPI_int sendNum, MPI_Datatype typeSend, void *recv, MPI_int recvNum, MPI_Datatype typeRecv, MPI_Comm comm)
Wrapper over MPI_Alltoall (fixed per-peer count).
MPI_int Alltoallv(void *send, MPI_int *sendSizes, MPI_int *sendStarts, MPI_Datatype sendType, void *recv, MPI_int *recvSizes, MPI_int *recvStarts, MPI_Datatype recvType, MPI_Comm comm)
Wrapper over MPI_Alltoallv (variable per-peer counts + displacements).
the host side operators are provided as implemented
const MPI_Datatype DNDS_MPI_INDEX
MPI datatype matching index (= MPI_INT64_T).
void AccumulateRowSize(const TtRowsizeVec &rowsizes, TtIndexVec &rowstarts)
Build a prefix-sum table from a row-size vector.
std::vector< index > t_IndexVec
Vector of index values (global offsets, local ids, etc.).
int64_t index
Global row / DOF index type (signed 64-bit; handles multi-billion-cell meshes).
tMPI_sizeVec tMPI_intVec
Alias for tMPI_sizeVec; used where the name "int vec" reads better.
int MPI_int
MPI counterpart type for MPI_int (= C int). Used for counts and ranks in MPI calls.
Lightweight bundle of an MPI communicator and the calling rank's coordinates.