5#include <unordered_set>
14 template <
class TArray>
15 static void EvenSplitReadFather(
19 const std::string &name)
21 father = std::make_shared<TArray>(mpi);
22 son = std::make_shared<TArray>(mpi);
23 auto offset = Serializer::ArrayGlobalOffset_EvenSplit;
24 father->ReadSerializer(serializerP, name, offset);
28 template <
class TArray>
29 static void EvenSplitReadFather(
33 const std::string &name,
34 MPI_Datatype commType,
int commMult)
36 father = std::make_shared<TArray>(commType, commMult, mpi);
37 son = std::make_shared<TArray>(commType, commMult, mpi);
38 auto offset = Serializer::ArrayGlobalOffset_EvenSplit;
39 father->ReadSerializer(serializerP, name, offset);
45 const std::string &name,
49 "ReadSerializeAndDistribute requires a collective (H5) serializer");
52 log() <<
"UnstructuredMesh === ReadSerializeAndDistribute: begin" << std::endl;
77 log() <<
"UnstructuredMesh === ReadSerializeAndDistribute: even-split read" << std::endl;
133 log() <<
"UnstructuredMesh === ReadSerializeAndDistribute: even-split read done, "
144 log() <<
"UnstructuredMesh === ReadSerializeAndDistribute: building distributed cell2cell" << std::endl;
158 log() <<
"UnstructuredMesh === ReadSerializeAndDistribute: building facial cell2cell" << std::endl;
232 std::set_intersection(
vertI.begin(),
vertI.end(),
248 log() <<
"UnstructuredMesh === ReadSerializeAndDistribute: ParMetis repartition" << std::endl;
273 for (
int i = 0; i <
mpi.
size; i++)
275 "ParMetis requires > 0 cells on each proc");
279 std::vector<real_t>
tpWeights(
static_cast<size_t>(nPart) *
nCon, 1.0 / nPart);
293 fmt::format(
"ParMETIS_V3_PartKway returned {}",
ret));
300 std::fill(cellPartition.begin(), cellPartition.end(), 0);
306 for (
auto p : cellPartition)
313 index nCellGlobal = 0;
316 log() <<
"UnstructuredMesh === ReadSerializeAndDistribute: partition done, "
317 << fmt::format(
"nCellGlobal [{}], ave [{}], min [{}], max [{}], ratio [{:.4f}]",
329 log() <<
"UnstructuredMesh === ReadSerializeAndDistribute: redistributing" << std::endl;
344 nodePartition[val] = std::min(nodePartition[val], cellPartition.at(
iCell));
349 for (
auto &p : nodePartition)
392 fmt::format(
"bnd {} has no owner cell after RecoverCell2CellAndBnd2Cell",
iBnd));
500 log() <<
"UnstructuredMesh === ReadSerializeAndDistribute done, "
501 << fmt::format(
"nCellGlobal [{}], nNodeGlobal [{}], nBndGlobal [{}]",
506 {
log() << fmt::format(
" Rank {}: nCell {}, nNode {}, nBnd {}",
#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 + ...
#define DNDS_check_throw_info(expr, info)
Same as DNDS_check_throw but attaches a user-supplied info message to the thrown std::runtime_error.
Internal helpers for mesh partition redistribution.
void Partition2LocalIdx(const std::vector< TPartitionIdx > &partition, std::vector< DNDS::index > &localPush, std::vector< DNDS::index > &localPushStart, const DNDS::MPIInfo &mpi)
void Partition2Serial2Global(const std::vector< TPartitionIdx > &partition, std::vector< DNDS::index > &serial2Global, const DNDS::MPIInfo &mpi, DNDS::MPI_int nPart)
void TransferDataSerial2Global(TArr &arraySerial, TArr &arrayDist, const std::vector< DNDS::index > &pushIndex, const std::vector< DNDS::index > &pushIndexStart, const DNDS::MPIInfo &mpi)
void ConvertAdjSerial2Global(TAdj &arraySerialAdj, const std::vector< DNDS::index > &partitionJSerial2Global, const DNDS::MPIInfo &mpi)
MPI_int Allreduce(const void *sendbuf, void *recvbuf, MPI_int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
Wrapper over MPI_Allreduce.
ssp< SerializerBase > SerializerBaseSSP
const MPI_Datatype DNDS_MPI_INDEX
MPI datatype matching index (= MPI_INT64_T).
DNDS_CONSTANT const index UnInitIndex
Sentinel "not initialised" index value (= INT64_MIN).
void MPISerialDo(const MPIInfo &mpi, F f)
Execute f on each rank serially, in rank order.
int32_t rowsize
Row-width / per-row element-count type (signed 32-bit).
int64_t index
Global row / DOF index type (signed 64-bit; handles multi-billion-cell meshes).
double real
Canonical floating-point scalar used throughout DNDSR (double precision).
std::ostream & log()
Return the current DNDSR log stream (either std::cout or the installed file).
int MPI_int
MPI counterpart type for MPI_int (= C int). Used for counts and ranks in MPI calls.
void TransAttach()
Bind the transformer to the current father / son pointers.
ssp< TArray > father
Owned-side array (must be resized before ghost setup).
void InitPair(const std::string &name, Args &&...args)
Allocate both father and son arrays, forwarding all args to TArray constructor.
ssp< TArray > son
Ghost-side array (sized automatically by createMPITypes / BorrowAndPull).
TTrans trans
Ghost-communication engine bound to father and son.
static MPI_Datatype CommType()
static MPI_Datatype CommType()
DNDS_HOST void ReadSerializer(Serializer::SerializerBaseSSP serializerP, const std::string &name)
UnstructuredMeshDeviceView< B > t_deviceView
tPbiPair cell2nodePbi
periodic only, after reader
void RecoverNode2CellAndNode2Bnd()
only requires father part of cell2node, bnd2node and coords generates node2cell and node2bnd (father ...
tAdjPair node2cell
inverse relations
MeshAdjState adjPrimaryState
void RecoverCell2CellAndBnd2Cell()
needs to use RecoverNode2CellAndNode2Bnd before doing this. Requires node2cell.father and builds a ve...
tElemInfoArrayPair cellElemInfo
void ReadSerializeAndDistribute(Serializer::SerializerBaseSSP serializerP, const std::string &name, const PartitionOptions &partitionOptions)
Reads mesh from an H5 serializer using even-split distribution, then repartitions via ParMetis for lo...
tElemInfoArrayPair bndElemInfo
int size
Number of ranks in comm (-1 until initialised).
int rank
This rank's 0-based index within comm (-1 until initialised).
MPI_Comm comm
The underlying MPI communicator handle.
Tag type for naming objects created via make_ssp.