26#define DOCTEST_CONFIG_IMPLEMENT
38namespace fs = std::filesystem;
40int main(
int argc,
char **argv)
42 MPI_Init(&argc, &argv);
44 ctx.applyCommandLine(argc, argv);
51static std::string TmpJSON(
const std::string &tag)
54 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
55 return fmt::format(
"__test_ser_{}_{}_r{}.json", tag, ::getpid(), rank);
58static std::string TmpH5(
const std::string &tag)
64 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
67 MPI_Bcast(&pid, 1, MPI_INT, 0, MPI_COMM_WORLD);
68 return fmt::format(
"__test_ser_{}_{}.h5", tag, pid);
77 explicit FileGuard(std::string p,
bool shared =
false)
86 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
89 MPI_Barrier(MPI_COMM_WORLD);
103 std::string fname = TmpJSON(
"scalar");
128 std::string fname = TmpH5(
"h5_redist");
132 std::vector<DNDS::index> origIndex(
nLocal);
135 for (
int r = 0;
r < mpi.rank;
r++)
136 globalOffset += 100 +
r * 13;
138 origIndex[i] = globalOffset + (
nLocal - 1 - i);
151 auto ser = std::make_shared<S::SerializerH5>(mpi);
152 ser->OpenFile(fname,
false);
153 pair.WriteSerialize(ser,
"data", origIndex,
false,
false);
156 MPI_Barrier(MPI_COMM_WORLD);
161 pair.
InitPair(
"redist::readPair", mpi);
164 auto ser = std::make_shared<S::SerializerH5>(mpi);
165 ser->OpenFile(fname,
true);
166 pair.ReadSerializeRedistributed(ser,
"data", origIndex);
174TEST_CASE(
"ArrayPair redistribute — shuffled partition same np")
177 std::string fname = TmpH5(
"h5_redist_shuffle");
184 MPI::Allreduce(&tmp, &nGlobal, 1,
DNDS_MPI_INDEX, MPI_SUM, mpi.comm);
187 std::vector<DNDS::index> writeOrigIndex(
nLocal);
190 for (
int r = 0;
r < mpi.rank;
r++)
191 globalOffset += 50 +
r * 7;
193 writeOrigIndex[i] = globalOffset + i;
200 pair.
InitPair(
"redistShuf::pair", mpi);
206 auto ser = std::make_shared<S::SerializerH5>(mpi);
207 ser->OpenFile(fname,
false);
208 pair.WriteSerialize(ser,
"data", writeOrigIndex,
false,
false);
211 MPI_Barrier(MPI_COMM_WORLD);
213 std::vector<DNDS::index> readOrigIndex(
nLocal);
216 for (
int r = 0;
r < mpi.rank;
r++)
217 globalEndOffset -= (50 +
r * 7);
219 readOrigIndex[i] = globalEndOffset -
nLocal + i;
224 pair.
InitPair(
"redistShuf::readPair", mpi);
227 auto ser = std::make_shared<S::SerializerH5>(mpi);
228 ser->OpenFile(fname,
true);
229 pair.ReadSerializeRedistributed(ser,
"data", readOrigIndex);
244 return static_cast<T
>(origIdx * 100 + col * 3 + 7);
247static int g_redist_ctr = 0;
248static std::string NextTag() {
return "rd_" + std::to_string(g_redist_ctr++); }
250static void BuildSeqOrig(std::vector<DNDS::index> &
v,
DNDS::index n,
int rank,
255 for (
int r = 0;
r < rank;
r++)
261static void BuildRevOrig(std::vector<DNDS::index> &
v,
DNDS::index n,
267 for (
int r = 0;
r < rank;
r++)
283template <
class T,
class Layout, DNDS::rowsize RS>
291#define REDIST_TAG_STR(T, L, RS) TYPE_TO_STRING(RedistTag<T, L, RS>)
329#define REDIST_ALL_TAGS \
330 RedistTag<DNDS::real, LayoutStaticFixed, 1>, RedistTag<DNDS::real, LayoutStaticFixed, 3>, RedistTag<DNDS::real, LayoutStaticFixed, 7>, \
331 RedistTag<DNDS::real, LayoutDynamic, 1>, RedistTag<DNDS::real, LayoutDynamic, 3>, RedistTag<DNDS::real, LayoutDynamic, 7>, \
332 RedistTag<DNDS::real, LayoutCSR, 0>, \
333 RedistTag<DNDS::index, LayoutStaticFixed, 1>, RedistTag<DNDS::index, LayoutStaticFixed, 3>, RedistTag<DNDS::index, LayoutStaticFixed, 7>, \
334 RedistTag<DNDS::index, LayoutDynamic, 1>, RedistTag<DNDS::index, LayoutDynamic, 3>, RedistTag<DNDS::index, LayoutDynamic, 7>, \
335 RedistTag<DNDS::index, LayoutCSR, 0>, \
336 RedistTag<uint16_t, LayoutStaticFixed, 1>, RedistTag<uint16_t, LayoutStaticFixed, 3>, RedistTag<uint16_t, LayoutStaticFixed, 7>, \
337 RedistTag<uint16_t, LayoutDynamic, 1>, RedistTag<uint16_t, LayoutDynamic, 3>, RedistTag<uint16_t, LayoutDynamic, 7>, \
338 RedistTag<uint16_t, LayoutCSR, 0>, \
339 RedistTag<int32_t, LayoutStaticFixed, 1>, RedistTag<int32_t, LayoutStaticFixed, 3>, RedistTag<int32_t, LayoutStaticFixed, 7>, \
340 RedistTag<int32_t, LayoutDynamic, 1>, RedistTag<int32_t, LayoutDynamic, 3>, RedistTag<int32_t, LayoutDynamic, 7>, \
341 RedistTag<int32_t, LayoutCSR, 0>, \
342 RedistTag<uint8_t, LayoutStaticFixed, 1>, RedistTag<uint8_t, LayoutStaticFixed, 3>, RedistTag<uint8_t, LayoutStaticFixed, 7>, \
343 RedistTag<uint8_t, LayoutDynamic, 1>, RedistTag<uint8_t, LayoutDynamic, 3>, RedistTag<uint8_t, LayoutDynamic, 7>, \
344 RedistTag<uint8_t, LayoutCSR, 0>
348 using T =
typename Tag::type;
349 using L =
typename Tag::layout;
357 std::string fname = TmpH5(NextTag());
361 {
return baseSize +
r * 9; };
366 MPI::Allreduce(&tmp, &nGlobal, 1,
DNDS_MPI_INDEX, MPI_SUM, mpi.comm);
372 std::vector<DNDS::index> writeOrig;
373 BuildSeqOrig(writeOrig,
nLocal, mpi.rank, nLocalFor);
376 if constexpr (std::is_same_v<L, LayoutStaticFixed>)
386 pair.father->operator()(i, j) = MakeTestValue<T>(writeOrig[i], j);
387 auto ser = std::make_shared<S::SerializerH5>(mpi);
388 ser->OpenFile(fname,
false);
389 pair.WriteSerialize(ser,
"data", writeOrig,
false,
false);
392 else if constexpr (std::is_same_v<L, LayoutDynamic>)
399 pair.son->Resize(0, RS);
402 pair.father->operator()(i, j) = MakeTestValue<T>(writeOrig[i], j);
403 auto ser = std::make_shared<S::SerializerH5>(mpi);
404 ser->OpenFile(fname,
false);
405 pair.WriteSerialize(ser,
"data", writeOrig,
false,
false);
417 pair.father->ResizeRow(i, csrRowSize(writeOrig[i]));
418 pair.father->Compress();
421 pair.father->operator()(i, j) = MakeTestValue<T>(writeOrig[i], j);
422 auto ser = std::make_shared<S::SerializerH5>(mpi);
423 ser->OpenFile(fname,
false);
424 pair.WriteSerialize(ser,
"data", writeOrig,
false,
false);
427 MPI_Barrier(MPI_COMM_WORLD);
430 std::vector<DNDS::index> readOrig;
431 BuildRevOrig(readOrig,
nLocal, nGlobal, mpi.rank, nLocalFor);
433 if constexpr (std::is_same_v<L, LayoutStaticFixed>)
441 auto ser = std::make_shared<S::SerializerH5>(mpi);
442 ser->OpenFile(fname,
true);
443 pair.ReadSerializeRedistributed(ser,
"data", readOrig);
447 CHECK(pair.father->operator()(i, j) == MakeTestValue<T>(readOrig[i], j));
449 else if constexpr (std::is_same_v<L, LayoutDynamic>)
456 pair.son->Resize(0, RS);
457 auto ser = std::make_shared<S::SerializerH5>(mpi);
458 ser->OpenFile(fname,
true);
459 pair.ReadSerializeRedistributed(ser,
"data", readOrig);
463 CHECK(pair.father->operator()(i, j) == MakeTestValue<T>(readOrig[i], j));
473 auto ser = std::make_shared<S::SerializerH5>(mpi);
474 ser->OpenFile(fname,
true);
475 pair.ReadSerializeRedistributed(ser,
"data", readOrig);
479 CHECK(pair.father->RowSize(i) == csrRowSize(readOrig[i]));
481 CHECK(pair.father->operator()(i, j) == MakeTestValue<T>(readOrig[i], j));
494template <
class T,
class L, DNDS::rowsize RS>
497 MPIInfo worldMpi(MPI_COMM_WORLD);
498 if (worldMpi.
size < 3)
505 std::string fname = TmpH5(NextTag());
511 int color = (worldMpi.
rank < npWrite) ? 0 : MPI_UNDEFINED;
512 MPI_Comm writeComm = MPI_COMM_NULL;
513 MPI_Comm_split(MPI_COMM_WORLD, color, worldMpi.
rank, &writeComm);
516 for (
int r = 0;
r < npWrite;
r++)
517 nGlobalWrite += baseSize +
r * 7;
519 if (writeComm != MPI_COMM_NULL)
523 {
return baseSize +
r * 7; };
526 std::vector<DNDS::index> writeOrig;
527 BuildSeqOrig(writeOrig,
nLocal, writeMpi.
rank, nLocalFor);
529 if constexpr (std::is_same_v<L, LayoutStaticFixed>)
534 pair.
InitPair(
"rdNp::wPair", writeMpi);
539 pair.father->operator()(i, j) = MakeTestValue<T>(writeOrig[i], j);
540 auto ser = std::make_shared<S::SerializerH5>(writeMpi);
541 ser->OpenFile(fname,
false);
542 pair.WriteSerialize(ser,
"data", writeOrig,
false,
false);
545 else if constexpr (std::is_same_v<L, LayoutDynamic>)
550 pair.
InitPair(
"rdNp::wPair", writeMpi);
552 pair.son->Resize(0, RS);
555 pair.father->operator()(i, j) = MakeTestValue<T>(writeOrig[i], j);
556 auto ser = std::make_shared<S::SerializerH5>(writeMpi);
557 ser->OpenFile(fname,
false);
558 pair.WriteSerialize(ser,
"data", writeOrig,
false,
false);
566 pair.
InitPair(
"rdNp::wPair", writeMpi);
570 pair.father->ResizeRow(i, csrRowSize(writeOrig[i]));
571 pair.father->Compress();
574 pair.father->operator()(i, j) = MakeTestValue<T>(writeOrig[i], j);
575 auto ser = std::make_shared<S::SerializerH5>(writeMpi);
576 ser->OpenFile(fname,
false);
577 pair.WriteSerialize(ser,
"data", writeOrig,
false,
false);
580 MPI_Comm_free(&writeComm);
583 MPI_Barrier(MPI_COMM_WORLD);
590 std::vector<DNDS::index> readOrig(
nLocal);
592 readOrig[i] = startRow + i;
594 if constexpr (std::is_same_v<L, LayoutStaticFixed>)
599 pair.
InitPair(
"rdNp::rPair", worldMpi);
602 auto ser = std::make_shared<S::SerializerH5>(worldMpi);
603 ser->OpenFile(fname,
true);
604 pair.ReadSerializeRedistributed(ser,
"data", readOrig);
608 CHECK(pair.father->operator()(i, j) == MakeTestValue<T>(readOrig[i], j));
610 else if constexpr (std::is_same_v<L, LayoutDynamic>)
615 pair.
InitPair(
"rdNp::rPair", worldMpi);
617 pair.son->Resize(0, RS);
618 auto ser = std::make_shared<S::SerializerH5>(worldMpi);
619 ser->OpenFile(fname,
true);
620 pair.ReadSerializeRedistributed(ser,
"data", readOrig);
624 CHECK(pair.father->operator()(i, j) == MakeTestValue<T>(readOrig[i], j));
631 pair.
InitPair(
"rdNp::rPair", worldMpi);
634 auto ser = std::make_shared<S::SerializerH5>(worldMpi);
635 ser->OpenFile(fname,
true);
636 pair.ReadSerializeRedistributed(ser,
"data", readOrig);
640 CHECK(pair.father->RowSize(i) == csrRowSize(readOrig[i]));
642 CHECK(pair.father->operator()(i, j) == MakeTestValue<T>(readOrig[i], j));
650 using T =
typename Tag::type;
651 using L =
typename Tag::layout;
658 for (
int npWrite : {1, 2, 3})
664 TestDifferentNp<T, L, RS>(npWrite, baseSize);
674 std::string fname = TmpJSON(
"vec");
677 const std::vector<real> wReals = {1.1, 2.2, 3.3, 4.4, 5.5};
678 const std::vector<DNDS::index> wIndices = {10, 20, 30};
679 const std::vector<rowsize> wRows = {1, 2, 3, 4};
701 std::vector<real> rReals;
702 std::vector<DNDS::index> rIndices;
703 std::vector<rowsize> rRows;
707 off = S::ArrayGlobalOffset_Unknown;
709 off = S::ArrayGlobalOffset_Unknown;
712 REQUIRE(rReals.size() == wReals.size());
713 for (
size_t i = 0; i < wReals.size(); ++i)
714 CHECK(rReals[i] == doctest::Approx(wReals[i]));
716 REQUIRE(rIndices.size() == wIndices.size());
717 for (
size_t i = 0; i < wIndices.size(); ++i)
718 CHECK(rIndices[i] == wIndices[i]);
720 REQUIRE(rRows.size() == wRows.size());
721 for (
size_t i = 0; i < wRows.size(); ++i)
722 CHECK(rRows[i] == wRows[i]);
734 std::vector<uint8_t> pattern(512);
735 for (
size_t i = 0; i < pattern.size(); ++i)
736 pattern[i] =
static_cast<uint8_t
>(i & 0xFF);
738 SUBCASE(
"without codec")
740 std::string fname = TmpJSON(
"u8_raw");
751 S::ArrayGlobalOffset_Unknown);
764 REQUIRE(sz ==
static_cast<DNDS::index>(pattern.size()));
766 std::vector<uint8_t> readBack(sz);
767 off = S::ArrayGlobalOffset_Unknown;
769 CHECK(readBack == pattern);
775 SUBCASE(
"with codec (base64 + zlib)")
777 std::string fname = TmpJSON(
"u8_codec");
789 S::ArrayGlobalOffset_Unknown);
801 REQUIRE(sz ==
static_cast<DNDS::index>(pattern.size()));
803 std::vector<uint8_t> readBack(sz);
804 off = S::ArrayGlobalOffset_Unknown;
806 CHECK(readBack == pattern);
818 std::string fname = TmpJSON(
"paths");
837 CHECK(entries.count(
"c") == 1);
838 CHECK(entries.count(
"d") == 1);
864 std::string fname = TmpJSON(
"shared");
868 auto sharedVec = std::make_shared<host_device_vector<DNDS::index>>();
869 sharedVec->resize(5);
870 for (
size_t i = 0; i < 5; ++i)
871 (*sharedVec)[i] =
static_cast<DNDS::index>(100 + i);
897 off = S::ArrayGlobalOffset_Unknown;
904 CHECK(readFirst.get() == readSecond.get());
907 REQUIRE(readFirst->size() == 5);
908 for (
size_t i = 0; i < 5; ++i)
921 std::string fname = TmpH5(
"h5scalar");
939 MPI_Barrier(MPI_COMM_WORLD);
958 CHECK(rIdx == 987654321LL);
959 CHECK(rReal == doctest::Approx(2.718281828));
960 CHECK(rStr ==
"world");
972 std::string fname = TmpH5(
"h5vec");
980 std::vector<real> wReals(
N);
981 std::vector<DNDS::index> wIndices(
N);
984 wReals[i] =
static_cast<real>(myOffset + i) * 0.1;
985 wIndices[i] = myOffset + i;
1003 MPI_Barrier(MPI_COMM_WORLD);
1011 std::vector<real> rReals;
1012 std::vector<DNDS::index> rIndices;
1019 REQUIRE(rReals.size() ==
static_cast<size_t>(
N));
1021 CHECK(rReals[i] == doctest::Approx(wReals[i]));
1023 REQUIRE(rIndices.size() ==
static_cast<size_t>(
N));
1025 CHECK(rIndices[i] == wIndices[i]);
1037 std::string fname = TmpH5(
"h5dist");
1047 MPI_Scan(&localN64, &myOffset, 1, MPI_INT64_T, MPI_SUM, MPI_COMM_WORLD);
1048 myOffset -= localN64;
1050 MPI_Allreduce(&localN64, &
globalSize, 1, MPI_INT64_T, MPI_SUM, MPI_COMM_WORLD);
1055 std::vector<DNDS::index> wData(localN);
1057 wData[i] = (myOffset + i) * 7 + 3;
1071 MPI_Barrier(MPI_COMM_WORLD);
1079 std::vector<DNDS::index> rData;
1084 REQUIRE(rData.size() ==
static_cast<size_t>(localN));
1086 CHECK(rData[i] == (myOffset + i) * 7 + 3);
1097 std::vector<DNDS::index> rData;
1102 REQUIRE(rData.size() ==
static_cast<size_t>(localN));
1104 CHECK(rData[i] == (myOffset + i) * 7 + 3);
1116 std::string fname = TmpH5(
"h5u8");
1126 std::vector<uint8_t> wBytes(localN);
1128 wBytes[i] =
static_cast<uint8_t
>((myOffset + i) & 0xFF);
1142 MPI_Barrier(MPI_COMM_WORLD);
1154 REQUIRE(sz == localN);
1157 std::vector<uint8_t> rBytes(sz);
1160 REQUIRE(rBytes.size() ==
static_cast<size_t>(localN));
1161 CHECK(rBytes == wBytes);
1173 std::string fname = TmpH5(
"h5paths");
1200 MPI_Barrier(MPI_COMM_WORLD);
1208 CHECK(entries.count(
"y") == 1);
1209 CHECK(entries.count(
"z") == 1);
1225 std::string fname = TmpH5(
"h5str");
1238 MPI_Barrier(MPI_COMM_WORLD);
1245 std::string solver, version;
1249 CHECK(solver ==
"euler3D");
1250 CHECK(version ==
"1.2.3");
Father-son array pairs with device views and ghost communication.
#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.
MPI-parallel HDF5 serializer implementing the SerializerBase interface.
Per-rank JSON serializer implementing the SerializerBase interface.
MPI-aware Array: adds a communicator, rank, and global index mapping.
Describes one rank's window into a globally-distributed dataset.
MPI-parallel HDF5 serializer; all ranks collectively read/write a single .h5 file.
void WriteIndex(const std::string &name, index v) override
Write a scalar index under name.
void ReadRealVector(const std::string &name, std::vector< real > &v, ArrayGlobalOffset &offset) override
std::string GetCurrentPath() override
String form of the current path.
void ReadIndexVector(const std::string &name, std::vector< index > &v, ArrayGlobalOffset &offset) override
void ReadIndex(const std::string &name, index &v) override
Read a scalar index into v.
void WriteInt(const std::string &name, int v) override
Write a scalar int under name at the current path.
void WriteUint8Array(const std::string &name, const uint8_t *data, index size, ArrayGlobalOffset offset) override
Write a raw byte buffer under name. offset.isDist() = true means the caller provides the exact per-ra...
std::set< std::string > ListCurrentPath() override
Names of direct children of the current path.
void ReadInt(const std::string &name, int &v) override
Read a scalar int into v.
void OpenFile(const std::string &fName, bool read) override
Open a backing file (H5 file or JSON file depending on subclass).
void WriteRealVector(const std::string &name, const std::vector< real > &v, ArrayGlobalOffset offset) override
Write a real vector (collective for H5).
void GoToPath(const std::string &p) override
Navigate to an existing path. Supports / -separated segments.
void WriteReal(const std::string &name, real v) override
Write a scalar real under name.
void ReadReal(const std::string &name, real &v) override
Read a scalar real into v.
void CloseFile() override
Close the backing file, flushing buffers.
void WriteString(const std::string &name, const std::string &v) override
Write a UTF-8 string under name.
void CreatePath(const std::string &p) override
Create a sub-path (H5 group / JSON object) at the current location.
void ReadString(const std::string &name, std::string &v) override
Read a UTF-8 string into v.
void WriteIndexVector(const std::string &name, const std::vector< index > &v, ArrayGlobalOffset offset) override
Write an index vector (collective for H5). offset carries the distribution mode (ArrayGlobalOffset_Pa...
void ReadUint8Array(const std::string &name, uint8_t *data, index &size, ArrayGlobalOffset &offset) override
Two-pass byte array read.
Per-rank JSON file serializer; each MPI rank writes its own .json file.
void ReadIndexVector(const std::string &name, std::vector< index > &v, ArrayGlobalOffset &offset) override
void ReadSharedIndexVector(const std::string &name, ssp< host_device_vector< index > > &v, ArrayGlobalOffset &offset) override
void ReadRealVector(const std::string &name, std::vector< real > &v, ArrayGlobalOffset &offset) override
std::set< std::string > ListCurrentPath() override
Names of direct children of the current path.
std::string GetCurrentPath() override
String form of the current path.
void CloseFile() override
Close the backing file, flushing buffers.
void WriteString(const std::string &name, const std::string &v) override
Write a UTF-8 string under name.
void OpenFile(const std::string &fName, bool read) override
Open a backing file (H5 file or JSON file depending on subclass).
void WriteSharedIndexVector(const std::string &name, const ssp< host_device_vector< index > > &v, ArrayGlobalOffset offset) override
Write a shared index vector; deduplicated across multiple writes that share the same shared_ptr.
void ReadInt(const std::string &name, int &v) override
Read a scalar int into v.
void ReadUint8Array(const std::string &name, uint8_t *data, index &size, ArrayGlobalOffset &offset) override
Two-pass byte array read.
void CreatePath(const std::string &p) override
Create a sub-path (H5 group / JSON object) at the current location.
void WriteRowsizeVector(const std::string &name, const std::vector< rowsize > &v, ArrayGlobalOffset offset) override
Write a rowsize vector (collective for H5).
void SetDeflateLevel(int v)
void WriteInt(const std::string &name, int v) override
Write a scalar int under name at the current path.
void WriteIndexVector(const std::string &name, const std::vector< index > &v, ArrayGlobalOffset offset) override
Write an index vector (collective for H5). offset carries the distribution mode (ArrayGlobalOffset_Pa...
void WriteUint8Array(const std::string &name, const uint8_t *data, index size, ArrayGlobalOffset offset) override
Write a raw byte buffer under name. offset.isDist() = true means the caller provides the exact per-ra...
void WriteRealVector(const std::string &name, const std::vector< real > &v, ArrayGlobalOffset offset) override
Write a real vector (collective for H5).
void WriteReal(const std::string &name, real v) override
Write a scalar real under name.
void ReadRowsizeVector(const std::string &name, std::vector< rowsize > &v, ArrayGlobalOffset &offset) override
void WriteIndex(const std::string &name, index v) override
Write a scalar index under name.
void SetUseCodecOnUint8(bool v)
void GoToPath(const std::string &p) override
Navigate to an existing path. Supports / -separated segments.
the host side operators are provided as implemented
const MPI_Datatype DNDS_MPI_INDEX
MPI datatype matching index (= MPI_INT64_T).
int32_t rowsize
Row-width / per-row element-count type (signed 32-bit).
std::pair< index, index > EvenSplitRange(int rank, int nRanks, index nGlobal)
Split a global range [0, nGlobal) evenly among nRanks workers.
int64_t index
Global row / DOF index type (signed 64-bit; handles multi-billion-cell meshes).
std::shared_ptr< T > ssp
Shortened alias for std::shared_ptr used pervasively in DNDSR.
double real
Canonical floating-point scalar used throughout DNDSR (double precision).
Convenience bundle of a father, son, and attached ArrayTransformer.
void InitPair(const std::string &name, Args &&...args)
Allocate both father and son arrays, forwarding all args to TArray constructor.
Lightweight bundle of an MPI communicator and the calling rank's coordinates.
int size
Number of ranks in comm (-1 until initialised).
int rank
This rank's 0-based index within comm (-1 until initialised).
FileGuard(std::string p, bool shared=false)
static constexpr DNDS::rowsize rs
Eigen::Matrix< real, 5, 1 > v
TEST_CASE("3D: VFV P2 HQM error < P1 on sinCos3D")
Eigen::Vector3d n(1.0, 0.0, 0.0)
#define REDIST_TAG_STR(T, L, RS)
TEST_CASE_TEMPLATE("redistribute", Tag, REDIST_ALL_TAGS)
void TestDifferentNp(int npWrite, DNDS::index baseSize)
T MakeTestValue(DNDS::index origIdx, DNDS::rowsize col)