1c4762a1bSJed Brown 29371c9d4SSatish Balay static char help[] = "Tests VecView() functionality with DMDA objects when using:" 3c4762a1bSJed Brown "(i) a PetscViewer binary with MPI-IO support; and (ii) when the binary header is skipped.\n\n"; 4c4762a1bSJed Brown 5c4762a1bSJed Brown #include <petscdm.h> 6c4762a1bSJed Brown #include <petscdmda.h> 7c4762a1bSJed Brown 8c4762a1bSJed Brown #define DMDA_I 5 9c4762a1bSJed Brown #define DMDA_J 4 10c4762a1bSJed Brown #define DMDA_K 6 11c4762a1bSJed Brown 12c4762a1bSJed Brown const PetscReal dmda_i_val[] = {1.10, 2.3006, 2.32444, 3.44006, 66.9009}; 13c4762a1bSJed Brown const PetscReal dmda_j_val[] = {0.0, 0.25, 0.5, 0.75}; 14c4762a1bSJed Brown const PetscReal dmda_k_val[] = {0.0, 1.1, 2.2, 3.3, 4.4, 5.5}; 15c4762a1bSJed Brown 16d71ae5a4SJacob Faibussowitsch PetscErrorCode MyVecDump(const char fname[], PetscBool skippheader, PetscBool usempiio, Vec x) 17d71ae5a4SJacob Faibussowitsch { 18c4762a1bSJed Brown MPI_Comm comm; 19c4762a1bSJed Brown PetscViewer viewer; 20c4762a1bSJed Brown PetscBool ismpiio, isskip; 21c4762a1bSJed Brown 22c4762a1bSJed Brown PetscFunctionBeginUser; 239566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)x, &comm)); 24c4762a1bSJed Brown 259566063dSJacob Faibussowitsch PetscCall(PetscViewerCreate(comm, &viewer)); 269566063dSJacob Faibussowitsch PetscCall(PetscViewerSetType(viewer, PETSCVIEWERBINARY)); 279566063dSJacob Faibussowitsch if (skippheader) PetscCall(PetscViewerBinarySetSkipHeader(viewer, PETSC_TRUE)); 289566063dSJacob Faibussowitsch PetscCall(PetscViewerFileSetMode(viewer, FILE_MODE_WRITE)); 299566063dSJacob Faibussowitsch if (usempiio) PetscCall(PetscViewerBinarySetUseMPIIO(viewer, PETSC_TRUE)); 309566063dSJacob Faibussowitsch PetscCall(PetscViewerFileSetName(viewer, fname)); 31c4762a1bSJed Brown 329566063dSJacob Faibussowitsch PetscCall(VecView(x, viewer)); 33c4762a1bSJed Brown 349566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryGetUseMPIIO(viewer, &ismpiio)); 359566063dSJacob Faibussowitsch if (ismpiio) PetscCall(PetscPrintf(comm, "*** PetscViewer[write] using MPI-IO ***\n")); 369566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryGetSkipHeader(viewer, &isskip)); 379566063dSJacob Faibussowitsch if (isskip) PetscCall(PetscPrintf(comm, "*** PetscViewer[write] skipping header ***\n")); 38c4762a1bSJed Brown 399566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&viewer)); 40*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 41c4762a1bSJed Brown } 42c4762a1bSJed Brown 43d71ae5a4SJacob Faibussowitsch PetscErrorCode MyVecLoad(const char fname[], PetscBool skippheader, PetscBool usempiio, Vec x) 44d71ae5a4SJacob Faibussowitsch { 45c4762a1bSJed Brown MPI_Comm comm; 46c4762a1bSJed Brown PetscViewer viewer; 47c4762a1bSJed Brown PetscBool ismpiio, isskip; 48c4762a1bSJed Brown 49c4762a1bSJed Brown PetscFunctionBeginUser; 509566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)x, &comm)); 51c4762a1bSJed Brown 529566063dSJacob Faibussowitsch PetscCall(PetscViewerCreate(comm, &viewer)); 539566063dSJacob Faibussowitsch PetscCall(PetscViewerSetType(viewer, PETSCVIEWERBINARY)); 549566063dSJacob Faibussowitsch if (skippheader) PetscCall(PetscViewerBinarySetSkipHeader(viewer, PETSC_TRUE)); 559566063dSJacob Faibussowitsch PetscCall(PetscViewerFileSetMode(viewer, FILE_MODE_READ)); 569566063dSJacob Faibussowitsch if (usempiio) PetscCall(PetscViewerBinarySetUseMPIIO(viewer, PETSC_TRUE)); 579566063dSJacob Faibussowitsch PetscCall(PetscViewerFileSetName(viewer, fname)); 58c4762a1bSJed Brown 599566063dSJacob Faibussowitsch PetscCall(VecLoad(x, viewer)); 60c4762a1bSJed Brown 619566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryGetSkipHeader(viewer, &isskip)); 629566063dSJacob Faibussowitsch if (isskip) PetscCall(PetscPrintf(comm, "*** PetscViewer[load] skipping header ***\n")); 639566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryGetUseMPIIO(viewer, &ismpiio)); 649566063dSJacob Faibussowitsch if (ismpiio) PetscCall(PetscPrintf(comm, "*** PetscViewer[load] using MPI-IO ***\n")); 65c4762a1bSJed Brown 669566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&viewer)); 67*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 68c4762a1bSJed Brown } 69c4762a1bSJed Brown 70d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAVecGenerateEntries(DM dm, Vec a) 71d71ae5a4SJacob Faibussowitsch { 72c4762a1bSJed Brown PetscScalar ****LA_v; 73c4762a1bSJed Brown PetscInt i, j, k, l, si, sj, sk, ni, nj, nk, M, N, dof; 74c4762a1bSJed Brown 75c4762a1bSJed Brown PetscFunctionBeginUser; 769566063dSJacob Faibussowitsch PetscCall(DMDAGetInfo(dm, NULL, &M, &N, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL)); 779566063dSJacob Faibussowitsch PetscCall(DMDAGetCorners(dm, &si, &sj, &sk, &ni, &nj, &nk)); 789566063dSJacob Faibussowitsch PetscCall(DMDAVecGetArrayDOF(dm, a, &LA_v)); 79c4762a1bSJed Brown for (k = sk; k < sk + nk; k++) { 80c4762a1bSJed Brown for (j = sj; j < sj + nj; j++) { 81c4762a1bSJed Brown for (i = si; i < si + ni; i++) { 82c4762a1bSJed Brown PetscScalar test_value_s; 83c4762a1bSJed Brown 84c4762a1bSJed Brown test_value_s = dmda_i_val[i] * ((PetscScalar)i) + dmda_j_val[j] * ((PetscScalar)(i + j * M)) + dmda_k_val[k] * ((PetscScalar)(i + j * M + k * M * N)); 85ad540459SPierre Jolivet for (l = 0; l < dof; l++) LA_v[k][j][i][l] = (PetscScalar)dof * test_value_s + (PetscScalar)l; 86c4762a1bSJed Brown } 87c4762a1bSJed Brown } 88c4762a1bSJed Brown } 899566063dSJacob Faibussowitsch PetscCall(DMDAVecRestoreArrayDOF(dm, a, &LA_v)); 90*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 91c4762a1bSJed Brown } 92c4762a1bSJed Brown 93d71ae5a4SJacob Faibussowitsch PetscErrorCode HeaderlessBinaryReadCheck(DM dm, const char name[]) 94d71ae5a4SJacob Faibussowitsch { 95c4762a1bSJed Brown int fdes; 96c4762a1bSJed Brown PetscScalar buffer[DMDA_I * DMDA_J * DMDA_K * 10]; 97c4762a1bSJed Brown PetscInt len, d, i, j, k, M, N, dof; 98c4762a1bSJed Brown PetscMPIInt rank; 99c4762a1bSJed Brown PetscBool dataverified = PETSC_TRUE; 100c4762a1bSJed Brown 101c4762a1bSJed Brown PetscFunctionBeginUser; 1029566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank)); 1039566063dSJacob Faibussowitsch PetscCall(DMDAGetInfo(dm, NULL, &M, &N, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL)); 104c4762a1bSJed Brown len = DMDA_I * DMDA_J * DMDA_K * dof; 105dd400576SPatrick Sanan if (rank == 0) { 1069566063dSJacob Faibussowitsch PetscCall(PetscBinaryOpen(name, FILE_MODE_READ, &fdes)); 1079566063dSJacob Faibussowitsch PetscCall(PetscBinaryRead(fdes, buffer, len, NULL, PETSC_SCALAR)); 1089566063dSJacob Faibussowitsch PetscCall(PetscBinaryClose(fdes)); 109c4762a1bSJed Brown 110c4762a1bSJed Brown for (k = 0; k < DMDA_K; k++) { 111c4762a1bSJed Brown for (j = 0; j < DMDA_J; j++) { 112c4762a1bSJed Brown for (i = 0; i < DMDA_I; i++) { 113c4762a1bSJed Brown for (d = 0; d < dof; d++) { 114c4762a1bSJed Brown PetscScalar v, test_value_s, test_value; 115c4762a1bSJed Brown PetscInt index; 116c4762a1bSJed Brown 117c4762a1bSJed Brown test_value_s = dmda_i_val[i] * ((PetscScalar)i) + dmda_j_val[j] * ((PetscScalar)(i + j * M)) + dmda_k_val[k] * ((PetscScalar)(i + j * M + k * M * N)); 118c4762a1bSJed Brown test_value = (PetscScalar)dof * test_value_s + (PetscScalar)d; 119c4762a1bSJed Brown 120c4762a1bSJed Brown index = dof * (i + j * M + k * M * N) + d; 121c4762a1bSJed Brown v = PetscAbsScalar(test_value - buffer[index]); 122c4762a1bSJed Brown #if defined(PETSC_USE_COMPLEX) 123c4762a1bSJed Brown if ((PetscRealPart(v) > 1.0e-10) || (PetscImaginaryPart(v) > 1.0e-10)) { 12463a3b9bcSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_SELF, "ERROR: Difference > 1.0e-10 occurred (delta = (%+1.12e,%+1.12e) [loc %" PetscInt_FMT ",%" PetscInt_FMT ",%" PetscInt_FMT "(%" PetscInt_FMT ")])\n", (double)PetscRealPart(test_value), (double)PetscImaginaryPart(test_value), i, j, k, d)); 125c4762a1bSJed Brown dataverified = PETSC_FALSE; 126c4762a1bSJed Brown } 127c4762a1bSJed Brown #else 128c4762a1bSJed Brown if (PetscRealPart(v) > 1.0e-10) { 12963a3b9bcSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_SELF, "ERROR: Difference > 1.0e-10 occurred (delta = %+1.12e [loc %" PetscInt_FMT ",%" PetscInt_FMT ",%" PetscInt_FMT "(%" PetscInt_FMT ")])\n", (double)PetscRealPart(test_value), i, j, k, d)); 130c4762a1bSJed Brown dataverified = PETSC_FALSE; 131c4762a1bSJed Brown } 132c4762a1bSJed Brown #endif 133c4762a1bSJed Brown } 134c4762a1bSJed Brown } 135c4762a1bSJed Brown } 136c4762a1bSJed Brown } 13748a46eb9SPierre Jolivet if (dataverified) PetscCall(PetscPrintf(PETSC_COMM_SELF, "Headerless read of data verified for: %s\n", name)); 138c4762a1bSJed Brown } 139*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 140c4762a1bSJed Brown } 141c4762a1bSJed Brown 142d71ae5a4SJacob Faibussowitsch PetscErrorCode VecCompare(Vec a, Vec b) 143d71ae5a4SJacob Faibussowitsch { 144c4762a1bSJed Brown PetscInt locmin[2], locmax[2]; 145c4762a1bSJed Brown PetscReal min[2], max[2]; 146c4762a1bSJed Brown Vec ref; 147c4762a1bSJed Brown 148c4762a1bSJed Brown PetscFunctionBeginUser; 1499566063dSJacob Faibussowitsch PetscCall(VecMin(a, &locmin[0], &min[0])); 1509566063dSJacob Faibussowitsch PetscCall(VecMax(a, &locmax[0], &max[0])); 151c4762a1bSJed Brown 1529566063dSJacob Faibussowitsch PetscCall(VecMin(b, &locmin[1], &min[1])); 1539566063dSJacob Faibussowitsch PetscCall(VecMax(b, &locmax[1], &max[1])); 154c4762a1bSJed Brown 1559566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "VecCompare\n")); 15663a3b9bcSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, " min(a) = %+1.2e [loc %" PetscInt_FMT "]\n", (double)min[0], locmin[0])); 15763a3b9bcSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, " max(a) = %+1.2e [loc %" PetscInt_FMT "]\n", (double)max[0], locmax[0])); 158c4762a1bSJed Brown 15963a3b9bcSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, " min(b) = %+1.2e [loc %" PetscInt_FMT "]\n", (double)min[1], locmin[1])); 16063a3b9bcSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, " max(b) = %+1.2e [loc %" PetscInt_FMT "]\n", (double)max[1], locmax[1])); 161c4762a1bSJed Brown 1629566063dSJacob Faibussowitsch PetscCall(VecDuplicate(a, &ref)); 1639566063dSJacob Faibussowitsch PetscCall(VecCopy(a, ref)); 1649566063dSJacob Faibussowitsch PetscCall(VecAXPY(ref, -1.0, b)); 1659566063dSJacob Faibussowitsch PetscCall(VecMin(ref, &locmin[0], &min[0])); 166c4762a1bSJed Brown if (PetscAbsReal(min[0]) > 1.0e-10) { 1679566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, " ERROR: min(a-b) > 1.0e-10\n")); 1689566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, " min(a-b) = %+1.10e\n", (double)PetscAbsReal(min[0]))); 169c4762a1bSJed Brown } else { 1709566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, " min(a-b) < 1.0e-10\n")); 171c4762a1bSJed Brown } 1729566063dSJacob Faibussowitsch PetscCall(VecDestroy(&ref)); 173*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 174c4762a1bSJed Brown } 175c4762a1bSJed Brown 176d71ae5a4SJacob Faibussowitsch PetscErrorCode TestDMDAVec(PetscBool usempiio) 177d71ae5a4SJacob Faibussowitsch { 178c4762a1bSJed Brown DM dm; 179c4762a1bSJed Brown Vec x_ref, x_test; 180c4762a1bSJed Brown PetscBool skipheader = PETSC_TRUE; 181c4762a1bSJed Brown 182c4762a1bSJed Brown PetscFunctionBeginUser; 1839566063dSJacob Faibussowitsch if (!usempiio) PetscCall(PetscPrintf(PETSC_COMM_WORLD, "%s\n", PETSC_FUNCTION_NAME)); 1849566063dSJacob Faibussowitsch else PetscCall(PetscPrintf(PETSC_COMM_WORLD, "%s [using mpi-io]\n", PETSC_FUNCTION_NAME)); 1859371c9d4SSatish Balay PetscCall(DMDACreate3d(PETSC_COMM_WORLD, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, DMDA_STENCIL_BOX, DMDA_I, DMDA_J, DMDA_K, PETSC_DECIDE, PETSC_DECIDE, PETSC_DECIDE, 3, 2, NULL, NULL, NULL, &dm)); 1869566063dSJacob Faibussowitsch PetscCall(DMSetFromOptions(dm)); 1879566063dSJacob Faibussowitsch PetscCall(DMSetUp(dm)); 188c4762a1bSJed Brown 1899566063dSJacob Faibussowitsch PetscCall(DMCreateGlobalVector(dm, &x_ref)); 1909566063dSJacob Faibussowitsch PetscCall(DMDAVecGenerateEntries(dm, x_ref)); 191c4762a1bSJed Brown 192c4762a1bSJed Brown if (!usempiio) { 1939566063dSJacob Faibussowitsch PetscCall(MyVecDump("dmda.pbvec", skipheader, PETSC_FALSE, x_ref)); 194c4762a1bSJed Brown } else { 1959566063dSJacob Faibussowitsch PetscCall(MyVecDump("dmda-mpiio.pbvec", skipheader, PETSC_TRUE, x_ref)); 196c4762a1bSJed Brown } 197c4762a1bSJed Brown 1989566063dSJacob Faibussowitsch PetscCall(DMCreateGlobalVector(dm, &x_test)); 199c4762a1bSJed Brown 200c4762a1bSJed Brown if (!usempiio) { 2019566063dSJacob Faibussowitsch PetscCall(MyVecLoad("dmda.pbvec", skipheader, usempiio, x_test)); 202c4762a1bSJed Brown } else { 2039566063dSJacob Faibussowitsch PetscCall(MyVecLoad("dmda-mpiio.pbvec", skipheader, usempiio, x_test)); 204c4762a1bSJed Brown } 205c4762a1bSJed Brown 2069566063dSJacob Faibussowitsch PetscCall(VecCompare(x_ref, x_test)); 207c4762a1bSJed Brown 208c4762a1bSJed Brown if (!usempiio) { 2099566063dSJacob Faibussowitsch PetscCall(HeaderlessBinaryReadCheck(dm, "dmda.pbvec")); 210c4762a1bSJed Brown } else { 2119566063dSJacob Faibussowitsch PetscCall(HeaderlessBinaryReadCheck(dm, "dmda-mpiio.pbvec")); 212c4762a1bSJed Brown } 2139566063dSJacob Faibussowitsch PetscCall(VecDestroy(&x_ref)); 2149566063dSJacob Faibussowitsch PetscCall(VecDestroy(&x_test)); 2159566063dSJacob Faibussowitsch PetscCall(DMDestroy(&dm)); 216*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 217c4762a1bSJed Brown } 218c4762a1bSJed Brown 219d71ae5a4SJacob Faibussowitsch int main(int argc, char **args) 220d71ae5a4SJacob Faibussowitsch { 221c4762a1bSJed Brown PetscBool usempiio = PETSC_FALSE; 222c4762a1bSJed Brown 223327415f7SBarry Smith PetscFunctionBeginUser; 2249566063dSJacob Faibussowitsch PetscCall(PetscInitialize(&argc, &args, (char *)0, help)); 2259566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetBool(NULL, NULL, "-usempiio", &usempiio, NULL)); 226c4762a1bSJed Brown if (!usempiio) { 2279566063dSJacob Faibussowitsch PetscCall(TestDMDAVec(PETSC_FALSE)); 228c4762a1bSJed Brown } else { 229c4762a1bSJed Brown #if defined(PETSC_HAVE_MPIIO) 2309566063dSJacob Faibussowitsch PetscCall(TestDMDAVec(PETSC_TRUE)); 231c4762a1bSJed Brown #else 2329566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Warning: Executing TestDMDAVec(PETSC_TRUE) requires a working MPI-2 implementation\n")); 233c4762a1bSJed Brown #endif 234c4762a1bSJed Brown } 2359566063dSJacob Faibussowitsch PetscCall(PetscFinalize()); 236b122ec5aSJacob Faibussowitsch return 0; 237c4762a1bSJed Brown } 238c4762a1bSJed Brown 239c4762a1bSJed Brown /*TEST 240c4762a1bSJed Brown 241c4762a1bSJed Brown test: 242c4762a1bSJed Brown 243c4762a1bSJed Brown test: 244c4762a1bSJed Brown suffix: 2 245c4762a1bSJed Brown nsize: 12 246c4762a1bSJed Brown 247c4762a1bSJed Brown test: 248c4762a1bSJed Brown suffix: 3 249c4762a1bSJed Brown nsize: 12 250dfd57a17SPierre Jolivet requires: defined(PETSC_HAVE_MPIIO) 251c4762a1bSJed Brown args: -usempiio 252c4762a1bSJed Brown 253c4762a1bSJed Brown TEST*/ 254