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: }