Actual source code: ex2.c

  1: static char help[] = "Tests shared memory subcommunicators\n\n";
  2: #include <petscsys.h>
  3: #include <petscvec.h>

  5: /*
  6:    One can use petscmpiexec -n 3 -hosts localhost,Barrys-MacBook-Pro.local ./ex2 -info to mimic
  7:   having two nodes that do not share common memory
  8: */

 10: int main(int argc, char **args)
 11: {
 12:   PetscCommShared scomm;
 13:   MPI_Comm        comm;
 14:   PetscMPIInt     lrank, rank, size, i;
 15:   Vec             x, y;
 16:   VecScatter      vscat;
 17:   IS              isstride, isblock;
 18:   PetscViewer     singleton;
 19:   PetscInt        indices[] = {0, 1, 2};

 21:   PetscInitialize(&argc, &args, (char *)0, help);
 22:   PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank));
 23:   PetscCallMPI(MPI_Comm_size(PETSC_COMM_WORLD, &size));
 24:   PetscCheck(size == 3, PETSC_COMM_WORLD, PETSC_ERR_WRONG_MPI_SIZE, "This example only works for 3 processes");

 26:   PetscCall(PetscCommDuplicate(PETSC_COMM_WORLD, &comm, NULL));
 27:   PetscCall(PetscCommSharedGet(comm, &scomm));

 29:   for (i = 0; i < size; i++) {
 30:     PetscCall(PetscCommSharedGlobalToLocal(scomm, i, &lrank));
 31:     PetscCall(PetscSynchronizedPrintf(PETSC_COMM_WORLD, "[%d] Global rank %d shared memory comm rank %d\n", rank, i, lrank));
 32:   }
 33:   PetscCall(PetscSynchronizedFlush(PETSC_COMM_WORLD, stdout));
 34:   PetscCall(PetscCommDestroy(&comm));

 36:   PetscCall(VecCreateFromOptions(PETSC_COMM_WORLD, NULL, 2, 2, PETSC_DETERMINE, &x));
 37:   PetscCall(VecSetValue(x, 2 * rank, (PetscScalar)(2 * rank + 10), INSERT_VALUES));
 38:   PetscCall(VecSetValue(x, 2 * rank + 1, (PetscScalar)(2 * rank + 1 + 10), INSERT_VALUES));
 39:   PetscCall(VecAssemblyBegin(x));
 40:   PetscCall(VecAssemblyEnd(x));
 41:   PetscCall(VecView(x, PETSC_VIEWER_STDOUT_WORLD));

 43:   PetscCall(VecCreateFromOptions(PETSC_COMM_SELF, NULL, 2, 6, &y));
 44:   PetscCall(ISCreateStride(PETSC_COMM_SELF, 6, 0, 1, &isstride));
 45:   PetscCall(ISCreateBlock(PETSC_COMM_SELF, 2, 3, indices, PETSC_COPY_VALUES, &isblock));
 46:   PetscCall(VecScatterCreate(x, isblock, y, isstride, &vscat));
 47:   PetscCall(VecScatterBegin(vscat, x, y, INSERT_VALUES, SCATTER_FORWARD));
 48:   PetscCall(VecScatterEnd(vscat, x, y, INSERT_VALUES, SCATTER_FORWARD));
 49:   PetscCall(VecScatterDestroy(&vscat));
 50:   PetscCall(PetscViewerGetSubViewer(PETSC_VIEWER_STDOUT_WORLD, PETSC_COMM_SELF, &singleton));
 51:   PetscCall(VecView(y, singleton));
 52:   PetscCall(PetscViewerRestoreSubViewer(PETSC_VIEWER_STDOUT_WORLD, PETSC_COMM_SELF, &singleton));

 54:   PetscCall(ISDestroy(&isstride));
 55:   PetscCall(ISDestroy(&isblock));
 56:   PetscCall(VecDestroy(&x));
 57:   PetscCall(VecDestroy(&y));
 58:   PetscFinalize();
 59:   return 0;
 60: }