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