19#define DOCTEST_CONFIG_IMPLEMENT
29int main(
int argc,
char **argv)
31 MPI_Init(&argc, &argv);
33 ctx.applyCommandLine(argc, argv);
52static std::vector<DNDS::index> pullFirstNFromOthers(
57 std::vector<DNDS::index> idx;
64 idx.push_back(base + i);
93 SUBCASE(
"verify all values after Compress")
106 SUBCASE(
"operator[] returns AdjacencyRow with correct data")
113 CHECK(row[j] == i * 100 + j);
117 SUBCASE(
"rowPtr returns valid pointer")
122 REQUIRE(ptr !=
nullptr);
123 CHECK(ptr[0] == i * 100);
137 auto father = std::make_shared<ArrayAdjacency<NonUniformSize>>(mpi);
141 father->createGlobalMapping();
147 father->operator()(i, j) = (
gOff + i) * 100 + j;
149 auto son = std::make_shared<ArrayAdjacency<NonUniformSize>>(mpi);
152 trans.createFatherGlobalMapping();
154 auto pullIdx = pullFirstNFromOthers(mpi, *
trans.pLGlobalMapping, nGhostPer);
155 trans.createGhostMapping(std::vector<DNDS::index>(pullIdx));
156 trans.createMPITypes();
167 bool found =
trans.pLGlobalMapping->search(ghostGlobal, srcRank, srcLoc);
171 CHECK(
son->RowSize(g) == expectedRowSize);
174 CHECK(
son->operator()(g, j) == ghostGlobal * 100 + j);
201 SUBCASE(
"operator[] returns Eigen::Map with correct values")
206 CHECK(
v.size() == vecSize);
212 SUBCASE(
"Size and RowSize")
229 auto father = std::make_shared<ArrayEigenVector<DynamicSize>>(mpi);
231 father->createGlobalMapping();
237 auto v =
father->operator[](i);
242 auto son = std::make_shared<ArrayEigenVector<DynamicSize>>(mpi);
245 trans.createFatherGlobalMapping();
247 auto pullIdx = pullFirstNFromOthers(mpi, *
trans.pLGlobalMapping, nGhostPer);
248 trans.createGhostMapping(std::vector<DNDS::index>(pullIdx));
249 trans.createMPITypes();
257 auto v =
son->operator[](g);
259 CHECK(
v(j) == doctest::Approx(
static_cast<DNDS::real>(ghostGlobal * 10 + j)));
283 for (
int r = 0;
r < 3;
r++)
284 for (
int c = 0; c < 4; c++)
285 m(
r, c) =
static_cast<DNDS::real>(i * 100 +
r * 10 + c);
288 SUBCASE(
"verify via operator[] Eigen::Map")
293 CHECK(m.rows() == 3);
294 CHECK(m.cols() == 4);
295 for (
int r = 0;
r < 3;
r++)
296 for (
int c = 0; c < 4; c++)
297 CHECK(m(
r, c) == doctest::Approx(
static_cast<DNDS::real>(i * 100 +
r * 10 + c)));
301 SUBCASE(
"MatRowSize and MatColSize")
329 for (
int r = 0;
r < dynRows;
r++)
330 for (
int c = 0; c <
dynCols; c++)
331 m(
r, c) =
static_cast<DNDS::real>(i * 1000 +
r * 10 + c);
337 CHECK(m.rows() == dynRows);
339 for (
int r = 0;
r < dynRows;
r++)
340 for (
int c = 0; c <
dynCols; c++)
341 CHECK(m(
r, c) == doctest::Approx(
static_cast<DNDS::real>(i * 1000 +
r * 10 + c)));
358 pair.
InitPair(
"matGhost::pair", mpi);
360 pair.
father->createGlobalMapping();
365 auto m = pair.
father->operator[](i);
366 for (
int r = 0;
r < matR;
r++)
367 for (
int c = 0; c < matC; c++)
372 pair.
trans.createFatherGlobalMapping();
374 auto pullIdx = pullFirstNFromOthers(mpi, *pair.
trans.pLGlobalMapping, nGhostPer);
375 pair.
trans.createGhostMapping(std::vector<DNDS::index>(pullIdx));
376 pair.
trans.createMPITypes();
377 pair.
trans.pullOnce();
384 auto m = pair.
son->operator[](g);
385 for (
int r = 0;
r < matR;
r++)
386 for (
int c = 0; c < matC; c++)
387 CHECK(m(
r, c) == doctest::Approx(
388 static_cast<DNDS::real>(ghostGlobal * 1000 +
r * 10 + c)));
406 int nMats =
static_cast<int>(i % 3 + 1);
407 std::vector<Eigen::MatrixXd> matrices;
408 matrices.reserve(nMats);
409 for (
int k = 0; k < nMats; k++)
413 Eigen::MatrixXd m(rows, cols);
414 for (
int r = 0;
r < rows;
r++)
415 for (
int c = 0; c < cols; c++)
416 m(
r, c) =
static_cast<DNDS::real>(i * 10000 + k * 100 +
r * 10 + c);
417 matrices.push_back(m);
424 SUBCASE(
"verify BatchSize")
428 auto expectedBatchSize =
static_cast<DNDS::index>(i % 3 + 1);
433 SUBCASE(
"read back via operator()(i, j)")
437 int nMats =
static_cast<int>(i % 3 + 1);
438 for (
int k = 0; k < nMats; k++)
440 auto m = batch(i, k);
443 CHECK(m.rows() == rows);
444 CHECK(m.cols() == cols);
445 for (
int r = 0;
r < rows;
r++)
446 for (
int c = 0; c < cols; c++)
447 CHECK(m(
r, c) == doctest::Approx(
448 static_cast<DNDS::real>(i * 10000 + k * 100 +
r * 10 + c)));
461 constexpr int matRows = 3;
462 constexpr int matCols = 4;
465 ubatch.
Resize(
N, matRows, matCols);
482 auto m = ubatch(i, j);
483 for (
int r = 0;
r < matRows;
r++)
484 for (
int c = 0; c < matCols; c++)
485 m(
r, c) =
static_cast<DNDS::real>(i * 10000 + j * 100 +
r * 10 + c);
491 SUBCASE(
"verify BatchSize after Compress")
500 SUBCASE(
"verify matrix values after Compress")
507 auto m = ubatch(i, j);
508 CHECK(m.rows() == matRows);
509 CHECK(m.cols() == matCols);
510 for (
int r = 0;
r < matRows;
r++)
511 for (
int c = 0; c < matCols; c++)
512 CHECK(m(
r, c) == doctest::Approx(
513 static_cast<DNDS::real>(i * 10000 + j * 100 +
r * 10 + c)));
542 auto m = ubatch(i, j);
543 m.setConstant(
static_cast<DNDS::real>(i * 100 + j));
555 auto m = ubatch(i, j);
556 for (
int r = 0;
r < 2;
r++)
557 for (
int c = 0; c < 3; c++)
577 adj.rowPtr(i)[j] = i * 100 + j;
590 adj.rowPtr(0)[0] = -999;
618 for (
int r = 0;
r < m.rows();
r++)
619 for (
int c = 0; c < m.cols(); c++)
620 m(
r, c) =
static_cast<DNDS::real>(i * 1000 +
r * 10 + c);
634 for (
int r = 0;
r < nr;
r++)
635 for (
int c = 0; c < nc; c++)
636 CHECK(m(
r, c) == doctest::Approx(
static_cast<DNDS::real>(i * 1000 +
r * 10 + c)));
665 for (
int j = 0; j < 5; j++)
681 pair.
InitPair(
"batchGhost::pair", mpi);
687 std::vector<Eigen::MatrixXd> matrices;
688 for (
int k = 0; k < 2; k++)
690 Eigen::MatrixXd m(2, 2);
692 matrices.push_back(m);
694 pair.
father->InitializeWriteRow(i, matrices);
697 pair.
father->createGlobalMapping();
704 for (
int k = 0; k < 2; k++)
706 auto m = pair.
father->operator()(i, k);
712 pair.
trans.createFatherGlobalMapping();
714 auto pullIdx = pullFirstNFromOthers(mpi, *pair.
trans.pLGlobalMapping, nGhostPer);
715 pair.
trans.createGhostMapping(std::vector<DNDS::index>(pullIdx));
716 pair.
trans.createMPITypes();
717 pair.
trans.pullOnce();
726 for (
int k = 0; k < 2; k++)
728 auto m = pair.
son->operator()(g, k);
729 CHECK(m.rows() == 2);
730 CHECK(m.cols() == 2);
732 for (
int r = 0;
r < 2;
r++)
733 for (
int c = 0; c < 2; c++)
764 CHECK(row.size() == 3);
766 CHECK(row[j] == i * 10 + j);
775template <DNDS::rowsize RS>
810 adj(i, j) = i * 100 + j;
812 SUBCASE(
"data round-trip")
825 SUBCASE(
"ghost pull")
830 adj.createGlobalMapping();
836 adj(i, j) = (
gOff + i) * 100 + j;
838 auto father = std::make_shared<ArrayAdjacency<RS>>(
adj);
839 auto son = std::make_shared<ArrayAdjacency<RS>>(mpi);
843 trans.createFatherGlobalMapping();
844 auto pullIdx = pullFirstNFromOthers(mpi, *
trans.pLGlobalMapping, 3);
845 trans.createGhostMapping(std::vector<DNDS::index>(pullIdx));
846 trans.createMPITypes();
854 CHECK(
son->operator()(g, j) == ghostGlobal * 100 + j);
864template <DNDS::rowsize VS>
900 SUBCASE(
"data round-trip")
905 CHECK(
v.size() == actualSize);
911 SUBCASE(
"ghost pull")
925 auto father = std::make_shared<ArrayEigenVector<VS>>(vec);
926 auto son = std::make_shared<ArrayEigenVector<VS>>(mpi);
930 trans.createFatherGlobalMapping();
931 auto pullIdx = pullFirstNFromOthers(mpi, *
trans.pLGlobalMapping, 4);
932 trans.createGhostMapping(std::vector<DNDS::index>(pullIdx));
933 trans.createMPITypes();
940 auto v =
son->operator[](g);
942 CHECK(
v(j) == doctest::Approx(
static_cast<DNDS::real>(ghostGlobal * 100 + j)));
952template <DNDS::rowsize NI, DNDS::rowsize NJ>
976 mat.
Resize(
N, actualNI, actualNJ);
986 for (
int r = 0;
r < actualNI;
r++)
987 for (
int c = 0; c < actualNJ; c++)
988 m(
r, c) =
static_cast<DNDS::real>(i * 1000 +
r * 10 + c);
991 SUBCASE(
"data round-trip")
996 CHECK(m.rows() == actualNI);
997 CHECK(m.cols() == actualNJ);
998 for (
int r = 0;
r < actualNI;
r++)
999 for (
int c = 0; c < actualNJ; c++)
1000 CHECK(m(
r, c) == doctest::Approx(
static_cast<DNDS::real>(i * 1000 +
r * 10 + c)));
1004 SUBCASE(
"ghost pull")
1010 pair.
InitPair(
"matParam::pair", mpi);
1011 pair.
father->Resize(
N, actualNI, actualNJ);
1012 pair.
son->Resize(0, actualNI, actualNJ);
1014 pair.
father->createGlobalMapping();
1018 auto m = pair.
father->operator[](i);
1019 for (
int r = 0;
r < actualNI;
r++)
1020 for (
int c = 0; c < actualNJ; c++)
1025 pair.
trans.createFatherGlobalMapping();
1027 auto pullIdx = pullFirstNFromOthers(mpi, *pair.
trans.pLGlobalMapping, 3);
1028 pair.
trans.createGhostMapping(std::vector<DNDS::index>(pullIdx));
1029 pair.
trans.createMPITypes();
1030 pair.
trans.pullOnce();
1036 auto m = pair.
son->operator[](g);
1037 for (
int r = 0;
r < actualNI;
r++)
1038 for (
int c = 0; c < actualNJ; c++)
1039 CHECK(m(
r, c) == doctest::Approx(
1040 static_cast<DNDS::real>(ghostGlobal * 1000 +
r * 10 + c)));
Father-son array pairs with device views and ghost communication.
Mesh-connectivity array: ParArray<index> whose operator[] yields an AdjacencyRow typed view.
index * rowPtr(index i)
Raw index* pointer to row i (bypasses the typed wrapper).
void clone(const t_self &R)
Shallow copy (same semantics as assignment).
CSR array storing a variable-sized batch of Eigen matrices per row.
void InitializeWriteRow(index i, const std::vector< t_matrices_elem > &matrices)
ParArray<real> whose operator[] returns an Eigen::Map<Matrix<real, Ni, Nj>>.
rowsize MatColSize(index iMat=0) const
void ResizeMat(index iMat, rowsize nSizeRow, rowsize nSizeCol)
void Resize(index nSize, rowsize nSizeRowDynamic, rowsize nSizeColDynamic)
rowsize MatRowSize(index iMat=0) const
CSR array whose rows store a batch of identically-sized Eigen matrices.
rowsize BatchSize(index i) const
void Resize(index n_size, int r, int c)
void ResizeBatch(index i, rowsize b_size)
ParArray<real, N> whose operator[] returns an Eigen::Map<Vector>.
void Resize(index nSize, rowsize nRow_size_dynamic)
Resize the array, setting a uniform or maximum row width.
rowsize RowSize() const
Uniform row width for fixed layouts (no row index needed).
void Compress()
Layout-polymorphic compress: no-op for non-CSR, calls CSRCompress for CSR.
index Size() const
Number of rows currently stored. O(1).
Table mapping rank-local row indices to the global index space.
t_pLGlobalMapping pLGlobalMapping
Shared pointer to the global-offsets table. Populated by createGlobalMapping; may be pointed at an ex...
void createGlobalMapping()
Collective: build the global offsets table.
the host side operators are provided as implemented
int32_t rowsize
Row-width / per-row element-count type (signed 32-bit).
DNDS_CONSTANT const rowsize DynamicSize
Template parameter flag: "row width is set at runtime but uniform".
DNDS_CONSTANT const rowsize NonUniformSize
Template parameter flag: "each row has an independent width".
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).
int MPI_int
MPI counterpart type for MPI_int (= C int). Used for counts and ranks in MPI calls.
static constexpr DNDS::rowsize rs
DNDS_DEVICE_CALLABLE index Size() const
Combined father + son row count.
Convenience bundle of a father, son, and attached ArrayTransformer.
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.
Lightweight bundle of an MPI communicator and the calling rank's coordinates.
static constexpr DNDS::rowsize nj
static constexpr DNDS::rowsize ni
static constexpr DNDS::rowsize vs
Eigen::Matrix< real, 5, 1 > v
TEST_CASE_TEMPLATE("ArrayAdjacency parametric", Tag, AdjTag< 2 >, AdjTag< 5 >, AdjTag< 8 >, AdjTag< NonUniformSize >)
TYPE_TO_STRING(AdjTag< 2 >)
TEST_CASE("3D: VFV P2 HQM error < P1 on sinCos3D")