1*a90d8e38SSatish Balay static char help[] = "Tests DMDAVecGetKokkosOffsetView() and DMDAVecGetKokkosOffsetViewDOF() \n\n"; 2*a90d8e38SSatish Balay 3*a90d8e38SSatish Balay #include <petscdmda_kokkos.hpp> 4*a90d8e38SSatish Balay #include <petscdm.h> 5*a90d8e38SSatish Balay #include <petscdmda.h> 6*a90d8e38SSatish Balay 7*a90d8e38SSatish Balay using Kokkos::Iterate; 8*a90d8e38SSatish Balay using Kokkos::MDRangePolicy; 9*a90d8e38SSatish Balay using Kokkos::Rank; 10*a90d8e38SSatish Balay using PetscScalarKokkosOffsetView2D = Kokkos::Experimental::OffsetView<PetscScalar **, Kokkos::LayoutRight, Kokkos::DefaultExecutionSpace::memory_space>; 11*a90d8e38SSatish Balay using ConstPetscScalarKokkosOffsetView2D = Kokkos::Experimental::OffsetView<const PetscScalar **, Kokkos::LayoutRight, Kokkos::DefaultExecutionSpace::memory_space>; 12*a90d8e38SSatish Balay 13*a90d8e38SSatish Balay using PetscScalarKokkosOffsetView3D = Kokkos::Experimental::OffsetView<PetscScalar ***, Kokkos::LayoutRight, Kokkos::DefaultExecutionSpace::memory_space>; 14*a90d8e38SSatish Balay using ConstPetscScalarKokkosOffsetView3D = Kokkos::Experimental::OffsetView<const PetscScalar ***, Kokkos::LayoutRight, Kokkos::DefaultExecutionSpace::memory_space>; 15*a90d8e38SSatish Balay 16*a90d8e38SSatish Balay /* can not define the type inside main, otherwise have this compilation error: 17*a90d8e38SSatish Balay error: A type local to a function ("Node") cannot be used in the type of a 18*a90d8e38SSatish Balay variable captured by an extended __device__ or __host__ __device__ lambda 19*a90d8e38SSatish Balay */ 20*a90d8e38SSatish Balay typedef struct { 21*a90d8e38SSatish Balay PetscScalar u, v, w; 22*a90d8e38SSatish Balay } Node; 23*a90d8e38SSatish Balay 24*a90d8e38SSatish Balay using NodeKokkosOffsetView2D = Kokkos::Experimental::OffsetView<Node **, Kokkos::LayoutRight, Kokkos::DefaultExecutionSpace::memory_space>; 25*a90d8e38SSatish Balay using ConstNodeKokkosOffsetView2D = Kokkos::Experimental::OffsetView<const Node **, Kokkos::LayoutRight, Kokkos::DefaultExecutionSpace::memory_space>; 26*a90d8e38SSatish Balay 27*a90d8e38SSatish Balay int main(int argc, char **argv) 28*a90d8e38SSatish Balay { 29*a90d8e38SSatish Balay DM da; 30*a90d8e38SSatish Balay PetscInt M = 5, N = 7, xm, ym, xs, ys; 31*a90d8e38SSatish Balay PetscInt dof = 1, sw = 1; 32*a90d8e38SSatish Balay DMBoundaryType bx = DM_BOUNDARY_PERIODIC, by = DM_BOUNDARY_PERIODIC; 33*a90d8e38SSatish Balay DMDAStencilType st = DMDA_STENCIL_STAR; 34*a90d8e38SSatish Balay PetscReal nrm; 35*a90d8e38SSatish Balay Vec g, l, gg, ll; /* global/local vectors of the da */ 36*a90d8e38SSatish Balay 37*a90d8e38SSatish Balay PetscFunctionBeginUser; 38*a90d8e38SSatish Balay PetscCall(PetscInitialize(&argc, &argv, nullptr, help)); 39*a90d8e38SSatish Balay 40*a90d8e38SSatish Balay /* =========================================================================== 41*a90d8e38SSatish Balay Show how to manage a multi-component DMDA with DMDAVecGetKokkosOffsetViewDOF 42*a90d8e38SSatish Balay ============================================================================*/ 43*a90d8e38SSatish Balay PetscScalar ***garray; /* arrays of g, ll */ 44*a90d8e38SSatish Balay const PetscScalar ***larray; 45*a90d8e38SSatish Balay PetscScalarKokkosOffsetView3D gview; /* views of gg, ll */ 46*a90d8e38SSatish Balay ConstPetscScalarKokkosOffsetView3D lview; 47*a90d8e38SSatish Balay 48*a90d8e38SSatish Balay dof = 2; 49*a90d8e38SSatish Balay PetscCall(DMDACreate2d(PETSC_COMM_WORLD, bx, by, st, M, N, PETSC_DECIDE, PETSC_DECIDE, dof, sw, NULL, NULL, &da)); 50*a90d8e38SSatish Balay PetscCall(DMSetFromOptions(da)); 51*a90d8e38SSatish Balay PetscCall(DMSetUp(da)); 52*a90d8e38SSatish Balay PetscCall(DMDAGetCorners(da, &xs, &ys, 0, &xm, &ym, 0)); 53*a90d8e38SSatish Balay PetscCall(DMCreateGlobalVector(da, &g)); 54*a90d8e38SSatish Balay PetscCall(DMCreateLocalVector(da, &l)); 55*a90d8e38SSatish Balay PetscCall(DMCreateGlobalVector(da, &gg)); 56*a90d8e38SSatish Balay PetscCall(DMCreateLocalVector(da, &ll)); 57*a90d8e38SSatish Balay 58*a90d8e38SSatish Balay /* Init g using array */ 59*a90d8e38SSatish Balay PetscCall(DMDAVecGetArrayDOFWrite(da, g, &garray)); 60*a90d8e38SSatish Balay for (PetscInt j = ys; j < ys + ym; j++) { /* run on host */ 61*a90d8e38SSatish Balay for (PetscInt i = xs; i < xs + xm; i++) { 62*a90d8e38SSatish Balay for (PetscInt c = 0; c < dof; c++) garray[j][i][c] = 100 * j + 10 * (i + 1) + c; 63*a90d8e38SSatish Balay } 64*a90d8e38SSatish Balay } 65*a90d8e38SSatish Balay PetscCall(DMDAVecRestoreArrayDOFWrite(da, g, &garray)); 66*a90d8e38SSatish Balay 67*a90d8e38SSatish Balay /* Init gg using view */ 68*a90d8e38SSatish Balay PetscCall(DMDAVecGetKokkosOffsetViewDOFWrite(da, gg, &gview)); 69*a90d8e38SSatish Balay Kokkos::parallel_for( 70*a90d8e38SSatish Balay "init 1", MDRangePolicy<Rank<3, Iterate::Right, Iterate::Right>>({ys, xs, 0}, {ys + ym, xs + xm, dof}), 71*a90d8e38SSatish Balay KOKKOS_LAMBDA(PetscInt j, PetscInt i, PetscInt c) /* might run on device */ 72*a90d8e38SSatish Balay { gview(j, i, c) = 100 * j + 10 * (i + 1) + c; }); 73*a90d8e38SSatish Balay PetscCall(DMDAVecRestoreKokkosOffsetViewDOFWrite(da, gg, &gview)); 74*a90d8e38SSatish Balay 75*a90d8e38SSatish Balay /* Scatter g, gg to l, ll */ 76*a90d8e38SSatish Balay PetscCall(DMGlobalToLocal(da, g, INSERT_VALUES, l)); 77*a90d8e38SSatish Balay PetscCall(DMGlobalToLocal(da, gg, INSERT_VALUES, ll)); 78*a90d8e38SSatish Balay 79*a90d8e38SSatish Balay /* Do stencil on g with values from l that contains ghosts */ 80*a90d8e38SSatish Balay PetscCall(DMDAVecGetArrayDOFWrite(da, g, &garray)); 81*a90d8e38SSatish Balay PetscCall(DMDAVecGetArrayDOFRead(da, l, &larray)); 82*a90d8e38SSatish Balay for (PetscInt j = ys; j < ys + ym; j++) { 83*a90d8e38SSatish Balay for (PetscInt i = xs; i < xs + xm; i++) { 84*a90d8e38SSatish Balay for (PetscInt c = 0; c < dof; c++) garray[j][i][c] = (larray[j][i - 1][c] + larray[j][i + 1][c] + larray[j - 1][i][c] + larray[j + 1][i][c]) / 4.0; 85*a90d8e38SSatish Balay } 86*a90d8e38SSatish Balay } 87*a90d8e38SSatish Balay PetscCall(DMDAVecRestoreArrayDOFWrite(da, g, &garray)); 88*a90d8e38SSatish Balay PetscCall(DMDAVecRestoreArrayDOFRead(da, l, &larray)); 89*a90d8e38SSatish Balay 90*a90d8e38SSatish Balay /* Do stencil on gg with values from ll that contains ghosts */ 91*a90d8e38SSatish Balay PetscCall(DMDAVecGetKokkosOffsetViewDOFWrite(da, gg, &gview)); 92*a90d8e38SSatish Balay PetscCall(DMDAVecGetKokkosOffsetViewDOF(da, ll, &lview)); 93*a90d8e38SSatish Balay Kokkos::parallel_for( 94*a90d8e38SSatish Balay "stencil 1", MDRangePolicy<Rank<3, Iterate::Right, Iterate::Right>>({ys, xs, 0}, {ys + ym, xs + xm, dof}), 95*a90d8e38SSatish Balay KOKKOS_LAMBDA(PetscInt j, PetscInt i, PetscInt c) { gview(j, i, c) = (lview(j, i - 1, c) + lview(j, i + 1, c) + lview(j - 1, i, c) + lview(j + 1, i, c)) / 4.0; }); 96*a90d8e38SSatish Balay PetscCall(DMDAVecRestoreKokkosOffsetViewDOFWrite(da, gg, &gview)); 97*a90d8e38SSatish Balay PetscCall(DMDAVecRestoreKokkosOffsetViewDOF(da, ll, &lview)); 98*a90d8e38SSatish Balay 99*a90d8e38SSatish Balay /* gg should be equal to g */ 100*a90d8e38SSatish Balay PetscCall(VecAXPY(g, -1.0, gg)); 101*a90d8e38SSatish Balay PetscCall(VecNorm(g, NORM_2, &nrm)); 102*a90d8e38SSatish Balay PetscCheck(nrm < PETSC_SMALL, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "gg is not equal to g"); 103*a90d8e38SSatish Balay 104*a90d8e38SSatish Balay PetscCall(DMDestroy(&da)); 105*a90d8e38SSatish Balay PetscCall(VecDestroy(&l)); 106*a90d8e38SSatish Balay PetscCall(VecDestroy(&g)); 107*a90d8e38SSatish Balay PetscCall(VecDestroy(&ll)); 108*a90d8e38SSatish Balay PetscCall(VecDestroy(&gg)); 109*a90d8e38SSatish Balay 110*a90d8e38SSatish Balay /* ============================================================================= 111*a90d8e38SSatish Balay Show how to manage a multi-component DMDA using DMDAVecGetKokkosOffsetView and 112*a90d8e38SSatish Balay a customized struct type 113*a90d8e38SSatish Balay ==============================================================================*/ 114*a90d8e38SSatish Balay Node **garray2; /* Node arrays of g, l */ 115*a90d8e38SSatish Balay const Node **larray2; 116*a90d8e38SSatish Balay PetscScalarKokkosOffsetView2D gview2; /* PetscScalar views of gg, ll */ 117*a90d8e38SSatish Balay ConstPetscScalarKokkosOffsetView2D lview2; 118*a90d8e38SSatish Balay NodeKokkosOffsetView2D gnview; /* Node views of gg, ll */ 119*a90d8e38SSatish Balay ConstNodeKokkosOffsetView2D lnview; 120*a90d8e38SSatish Balay 121*a90d8e38SSatish Balay dof = sizeof(Node) / sizeof(PetscScalar); 122*a90d8e38SSatish Balay PetscCall(DMDACreate2d(PETSC_COMM_WORLD, bx, by, st, M, N, PETSC_DECIDE, PETSC_DECIDE, sizeof(Node) / sizeof(PetscScalar), sw, NULL, NULL, &da)); 123*a90d8e38SSatish Balay PetscCall(DMSetFromOptions(da)); 124*a90d8e38SSatish Balay PetscCall(DMSetUp(da)); 125*a90d8e38SSatish Balay PetscCall(DMDAGetCorners(da, &xs, &ys, 0, &xm, &ym, 0)); 126*a90d8e38SSatish Balay PetscCall(DMCreateGlobalVector(da, &g)); 127*a90d8e38SSatish Balay PetscCall(DMCreateLocalVector(da, &l)); 128*a90d8e38SSatish Balay PetscCall(DMCreateGlobalVector(da, &gg)); 129*a90d8e38SSatish Balay PetscCall(DMCreateLocalVector(da, &ll)); 130*a90d8e38SSatish Balay 131*a90d8e38SSatish Balay /* Init g using array */ 132*a90d8e38SSatish Balay PetscCall(DMDAVecGetArrayWrite(da, g, &garray2)); 133*a90d8e38SSatish Balay for (PetscInt j = ys; j < ys + ym; j++) { 134*a90d8e38SSatish Balay for (PetscInt i = xs; i < xs + xm; i++) { 135*a90d8e38SSatish Balay garray2[j][i].u = 100 * j + 10 * (i + 1) + 111; 136*a90d8e38SSatish Balay garray2[j][i].v = 100 * j + 10 * (i + 1) + 222; 137*a90d8e38SSatish Balay garray2[j][i].w = 100 * j + 10 * (i + 1) + 333; 138*a90d8e38SSatish Balay } 139*a90d8e38SSatish Balay } 140*a90d8e38SSatish Balay PetscCall(DMDAVecRestoreArrayWrite(da, g, &garray2)); 141*a90d8e38SSatish Balay 142*a90d8e38SSatish Balay /* Init gg using view */ 143*a90d8e38SSatish Balay PetscCall(DMDAVecGetKokkosOffsetViewWrite(da, gg, &gview2)); 144*a90d8e38SSatish Balay gnview = NodeKokkosOffsetView2D(reinterpret_cast<Node *>(gview2.data()), {gview2.begin(0) / dof, gview2.begin(1) / dof}, {gview2.end(0) / dof, gview2.end(1) / dof}); 145*a90d8e38SSatish Balay Kokkos::parallel_for( 146*a90d8e38SSatish Balay "init 2", MDRangePolicy<Rank<2, Iterate::Right, Iterate::Right>>({ys, xs}, {ys + ym, xs + xm}), KOKKOS_LAMBDA(PetscInt j, PetscInt i) { 147*a90d8e38SSatish Balay gnview(j, i).u = 100 * j + 10 * (i + 1) + 111; 148*a90d8e38SSatish Balay gnview(j, i).v = 100 * j + 10 * (i + 1) + 222; 149*a90d8e38SSatish Balay gnview(j, i).w = 100 * j + 10 * (i + 1) + 333; 150*a90d8e38SSatish Balay }); 151*a90d8e38SSatish Balay PetscCall(DMDAVecRestoreKokkosOffsetViewWrite(da, gg, &gview2)); 152*a90d8e38SSatish Balay 153*a90d8e38SSatish Balay /* Scatter g, gg to l, ll */ 154*a90d8e38SSatish Balay PetscCall(DMGlobalToLocal(da, g, INSERT_VALUES, l)); 155*a90d8e38SSatish Balay PetscCall(DMGlobalToLocal(da, gg, INSERT_VALUES, ll)); 156*a90d8e38SSatish Balay 157*a90d8e38SSatish Balay /* Do stencil on g with values from l that contains ghosts */ 158*a90d8e38SSatish Balay PetscCall(DMDAVecGetArrayWrite(da, g, &garray2)); 159*a90d8e38SSatish Balay PetscCall(DMDAVecGetArray(da, l, &larray2)); 160*a90d8e38SSatish Balay for (PetscInt j = ys; j < ys + ym; j++) { 161*a90d8e38SSatish Balay for (PetscInt i = xs; i < xs + xm; i++) { 162*a90d8e38SSatish Balay garray2[j][i].u = (larray2[j][i - 1].u + larray2[j][i + 1].u + larray2[j - 1][i].u + larray2[j + 1][i].u) / 4.0; 163*a90d8e38SSatish Balay garray2[j][i].v = (larray2[j][i - 1].v + larray2[j][i + 1].v + larray2[j - 1][i].v + larray2[j + 1][i].v) / 4.0; 164*a90d8e38SSatish Balay garray2[j][i].w = (larray2[j][i - 1].w + larray2[j][i + 1].w + larray2[j - 1][i].w + larray2[j + 1][i].w) / 4.0; 165*a90d8e38SSatish Balay } 166*a90d8e38SSatish Balay } 167*a90d8e38SSatish Balay PetscCall(DMDAVecRestoreArrayWrite(da, g, &garray2)); 168*a90d8e38SSatish Balay PetscCall(DMDAVecRestoreArray(da, l, &larray2)); 169*a90d8e38SSatish Balay 170*a90d8e38SSatish Balay /* Do stencil on gg with values from ll that contains ghosts */ 171*a90d8e38SSatish Balay PetscCall(DMDAVecGetKokkosOffsetViewWrite(da, gg, &gview2)); /* write-only */ 172*a90d8e38SSatish Balay PetscCall(DMDAVecGetKokkosOffsetView(da, ll, &lview2)); /* read-only */ 173*a90d8e38SSatish Balay gnview = NodeKokkosOffsetView2D(reinterpret_cast<Node *>(gview2.data()), {gview2.begin(0) / dof, gview2.begin(1) / dof}, {gview2.end(0) / dof, gview2.end(1) / dof}); 174*a90d8e38SSatish Balay lnview = ConstNodeKokkosOffsetView2D(reinterpret_cast<const Node *>(lview2.data()), {lview2.begin(0) / dof, lview2.begin(1) / dof}, {lview2.end(0) / dof, lview2.end(1) / dof}); 175*a90d8e38SSatish Balay Kokkos::parallel_for( 176*a90d8e38SSatish Balay "stencil 2", MDRangePolicy<Rank<2, Iterate::Right, Iterate::Right>>({ys, xs}, {ys + ym, xs + xm}), KOKKOS_LAMBDA(PetscInt j, PetscInt i) { 177*a90d8e38SSatish Balay gnview(j, i).u = (lnview(j, i - 1).u + lnview(j, i + 1).u + lnview(j - 1, i).u + lnview(j + 1, i).u) / 4.0; 178*a90d8e38SSatish Balay gnview(j, i).v = (lnview(j, i - 1).v + lnview(j, i + 1).v + lnview(j - 1, i).v + lnview(j + 1, i).v) / 4.0; 179*a90d8e38SSatish Balay gnview(j, i).w = (lnview(j, i - 1).w + lnview(j, i + 1).w + lnview(j - 1, i).w + lnview(j + 1, i).w) / 4.0; 180*a90d8e38SSatish Balay }); 181*a90d8e38SSatish Balay PetscCall(DMDAVecRestoreKokkosOffsetViewWrite(da, gg, &gview2)); 182*a90d8e38SSatish Balay PetscCall(DMDAVecRestoreKokkosOffsetView(da, ll, &lview2)); 183*a90d8e38SSatish Balay 184*a90d8e38SSatish Balay /* gg should be equal to g */ 185*a90d8e38SSatish Balay PetscCall(VecAXPY(g, -1.0, gg)); 186*a90d8e38SSatish Balay PetscCall(VecNorm(g, NORM_2, &nrm)); 187*a90d8e38SSatish Balay PetscCheck(nrm < PETSC_SMALL, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "gg is not equal to g"); 188*a90d8e38SSatish Balay 189*a90d8e38SSatish Balay PetscCall(DMDestroy(&da)); 190*a90d8e38SSatish Balay PetscCall(VecDestroy(&l)); 191*a90d8e38SSatish Balay PetscCall(VecDestroy(&g)); 192*a90d8e38SSatish Balay PetscCall(VecDestroy(&ll)); 193*a90d8e38SSatish Balay PetscCall(VecDestroy(&gg)); 194*a90d8e38SSatish Balay PetscCall(PetscFinalize()); 195*a90d8e38SSatish Balay return 0; 196*a90d8e38SSatish Balay } 197*a90d8e38SSatish Balay 198*a90d8e38SSatish Balay /*TEST 199*a90d8e38SSatish Balay build: 200*a90d8e38SSatish Balay requires: kokkos_kernels 201*a90d8e38SSatish Balay 202*a90d8e38SSatish Balay test: 203*a90d8e38SSatish Balay suffix: 1 204*a90d8e38SSatish Balay nsize: 4 205*a90d8e38SSatish Balay requires: kokkos_kernels 206*a90d8e38SSatish Balay args: -dm_vec_type kokkos 207*a90d8e38SSatish Balay output_file: output/empty.out 208*a90d8e38SSatish Balay 209*a90d8e38SSatish Balay TEST*/ 210