Actual source code: ex2.c


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

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

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

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

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

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

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

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

 57:   PetscCall(ISDestroy(&isstride));
 58:   PetscCall(ISDestroy(&isblock));
 59:   PetscCall(VecDestroy(&x));
 60:   PetscCall(VecDestroy(&y));
 61:   PetscFinalize();
 62:   return 0;
 63: }