Actual source code: ex24.c
1: const char help[] = "Test overlapping PetscSF communication with empty roots and leaves";
3: #include <petscsf.h>
5: static PetscErrorCode testOverlappingCommunication(PetscSF sf)
6: {
7: PetscInt nroots, maxleaf;
8: PetscInt *leafa, *leafb, *roota, *rootb;
10: PetscFunctionBegin;
11: PetscCall(PetscSFSetUp(sf));
12: PetscCall(PetscSFGetGraph(sf, &nroots, NULL, NULL, NULL));
13: PetscCall(PetscSFGetLeafRange(sf, NULL, &maxleaf));
14: PetscCall(PetscMalloc4(nroots, &roota, nroots, &rootb, maxleaf + 1, &leafa, maxleaf + 1, &leafb));
16: // test reduce
17: for (PetscInt i = 0; i < nroots; i++) roota[i] = 0;
18: for (PetscInt i = 0; i < nroots; i++) rootb[i] = 0;
19: for (PetscInt i = 0; i < maxleaf + 1; i++) leafa[i] = (i + 1);
20: for (PetscInt i = 0; i < maxleaf + 1; i++) leafb[i] = -(i + 1);
22: PetscCall(PetscSFReduceBegin(sf, MPIU_INT, leafa, roota, MPI_REPLACE));
23: PetscCall(PetscSFReduceBegin(sf, MPIU_INT, leafb, rootb, MPI_REPLACE));
24: PetscCall(PetscSFReduceEnd(sf, MPIU_INT, leafa, roota, MPI_REPLACE));
25: PetscCall(PetscSFReduceEnd(sf, MPIU_INT, leafb, rootb, MPI_REPLACE));
26: for (PetscInt i = 0; i < nroots; i++) PetscCheck(roota[i] >= 0, PETSC_COMM_SELF, PETSC_ERR_PLIB, "PetscSFReduce in (A,B,A,B) order crosses separate reductions");
27: for (PetscInt i = 0; i < nroots; i++) PetscCheck(rootb[i] <= 0, PETSC_COMM_SELF, PETSC_ERR_PLIB, "PetscSFReduce in (A,B,A,B) order crosses separate reductions");
29: for (PetscInt i = 0; i < nroots; i++) roota[i] = 0;
30: for (PetscInt i = 0; i < nroots; i++) rootb[i] = 0;
32: PetscCall(PetscSFReduceBegin(sf, MPIU_INT, leafa, roota, MPI_REPLACE));
33: PetscCall(PetscSFReduceBegin(sf, MPIU_INT, leafb, rootb, MPI_REPLACE));
34: PetscCall(PetscSFReduceEnd(sf, MPIU_INT, leafb, rootb, MPI_REPLACE));
35: PetscCall(PetscSFReduceEnd(sf, MPIU_INT, leafa, roota, MPI_REPLACE));
37: for (PetscInt i = 0; i < nroots; i++) PetscCheck(roota[i] >= 0, PETSC_COMM_SELF, PETSC_ERR_PLIB, "PetscSFReduce in (A,B,B,A) order crosses separate reductions");
38: for (PetscInt i = 0; i < nroots; i++) PetscCheck(rootb[i] <= 0, PETSC_COMM_SELF, PETSC_ERR_PLIB, "PetscSFReduce in (A,B,B,A) order crosses separate reductions");
40: // test bcast
41: for (PetscInt i = 0; i < nroots; i++) roota[i] = (i + 1);
42: for (PetscInt i = 0; i < nroots; i++) rootb[i] = -(i + 1);
43: for (PetscInt i = 0; i < maxleaf + 1; i++) leafa[i] = 0;
44: for (PetscInt i = 0; i < maxleaf + 1; i++) leafb[i] = 0;
46: PetscCall(PetscSFBcastBegin(sf, MPIU_INT, roota, leafa, MPI_REPLACE));
47: PetscCall(PetscSFBcastBegin(sf, MPIU_INT, rootb, leafb, MPI_REPLACE));
48: PetscCall(PetscSFBcastEnd(sf, MPIU_INT, roota, leafa, MPI_REPLACE));
49: PetscCall(PetscSFBcastEnd(sf, MPIU_INT, rootb, leafb, MPI_REPLACE));
51: for (PetscInt i = 0; i < maxleaf + 1; i++) PetscCheck(leafa[i] >= 0, PETSC_COMM_SELF, PETSC_ERR_PLIB, "PetscSFBcast in (A,B,A,B) order crosses separate broadcasts");
52: for (PetscInt i = 0; i < maxleaf + 1; i++) PetscCheck(leafb[i] <= 0, PETSC_COMM_SELF, PETSC_ERR_PLIB, "PetscSFBcast in (A,B,A,B) order crosses separate broadcasts");
54: for (PetscInt i = 0; i < maxleaf + 1; i++) leafa[i] = 0;
55: for (PetscInt i = 0; i < maxleaf + 1; i++) leafb[i] = 0;
57: PetscCall(PetscSFBcastBegin(sf, MPIU_INT, roota, leafa, MPI_REPLACE));
58: PetscCall(PetscSFBcastBegin(sf, MPIU_INT, rootb, leafb, MPI_REPLACE));
59: PetscCall(PetscSFBcastEnd(sf, MPIU_INT, rootb, leafb, MPI_REPLACE));
60: PetscCall(PetscSFBcastEnd(sf, MPIU_INT, roota, leafa, MPI_REPLACE));
62: for (PetscInt i = 0; i < maxleaf + 1; i++) PetscCheck(leafa[i] >= 0, PETSC_COMM_SELF, PETSC_ERR_PLIB, "PetscSFBcast in (A,B,B,A) order crosses separate broadcasts");
63: for (PetscInt i = 0; i < maxleaf + 1; i++) PetscCheck(leafb[i] <= 0, PETSC_COMM_SELF, PETSC_ERR_PLIB, "PetscSFBcast in (A,B,B,A) order crosses separate broadcasts");
65: PetscCall(PetscFree4(roota, rootb, leafa, leafb));
66: PetscFunctionReturn(PETSC_SUCCESS);
67: }
69: static PetscErrorCode createSparseSF(MPI_Comm comm, PetscSF *sf)
70: {
71: PetscMPIInt rank;
72: PetscInt nroots, nleaves;
73: PetscSFNode remote;
75: PetscFunctionBegin;
76: PetscCallMPI(MPI_Comm_rank(comm, &rank));
77: PetscCall(PetscSFCreate(comm, sf));
78: nroots = (rank & 1) ? 1 : 0;
79: nleaves = (rank & 2) ? 1 : 0;
80: remote.rank = -1;
81: remote.index = 0;
82: if (nleaves == 1) { remote.rank = (rank & 1) ? (rank ^ 2) : (rank ^ 1); }
83: PetscCall(PetscSFSetGraph(*sf, nroots, nleaves, NULL, PETSC_COPY_VALUES, &remote, PETSC_COPY_VALUES));
84: PetscFunctionReturn(PETSC_SUCCESS);
85: }
87: int main(int argc, char **argv)
88: {
89: PetscSF sf;
91: PetscCall(PetscInitialize(&argc, &argv, NULL, help));
92: PetscCall(createSparseSF(PETSC_COMM_WORLD, &sf));
93: PetscCall(PetscSFSetFromOptions(sf));
94: PetscCall(testOverlappingCommunication(sf));
95: PetscCall(PetscSFDestroy(&sf));
96: PetscCall(PetscFinalize());
97: return 0;
98: }
100: /*TEST
102: test:
103: nsize: 4
104: suffix: 0
106: test:
107: nsize: 4
108: suffix: 0_window
109: output_file: output/ex24_0.out
110: args: -sf_type window -sf_window_sync {{fence active lock}} -sf_window_flavor {{create dynamic allocate}}
111: requires: defined(PETSC_HAVE_MPI_ONE_SIDED) defined(PETSC_HAVE_MPI_FEATURE_DYNAMIC_WINDOW)
113: TEST*/