1 const char help[] = "Test overlapping PetscSF communication with empty roots and leaves";
2
3 #include <petscsf.h>
4
testOverlappingCommunication(PetscSF sf)5 static PetscErrorCode testOverlappingCommunication(PetscSF sf)
6 {
7 PetscInt nroots, maxleaf;
8 PetscInt *leafa, *leafb, *roota, *rootb;
9
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));
15
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);
21
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");
28
29 for (PetscInt i = 0; i < nroots; i++) roota[i] = 0;
30 for (PetscInt i = 0; i < nroots; i++) rootb[i] = 0;
31
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));
36
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");
39
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;
45
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));
50
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");
53
54 for (PetscInt i = 0; i < maxleaf + 1; i++) leafa[i] = 0;
55 for (PetscInt i = 0; i < maxleaf + 1; i++) leafb[i] = 0;
56
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));
61
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");
64
65 PetscCall(PetscFree4(roota, rootb, leafa, leafb));
66 PetscFunctionReturn(PETSC_SUCCESS);
67 }
68
createSparseSF(MPI_Comm comm,PetscSF * sf)69 static PetscErrorCode createSparseSF(MPI_Comm comm, PetscSF *sf)
70 {
71 PetscMPIInt rank;
72 PetscInt nroots, nleaves;
73 PetscSFNode remote;
74
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 }
86
main(int argc,char ** argv)87 int main(int argc, char **argv)
88 {
89 PetscSF sf;
90
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 }
99
100 /*TEST
101
102 test:
103 nsize: 4
104 suffix: 0
105 output_file: output/empty.out
106
107 test:
108 TODO: frequent timeout with the CI job linux-hip-cmplx
109 nsize: 4
110 suffix: 0_window
111 output_file: output/empty.out
112 args: -sf_type window -sf_window_sync {{fence active lock}} -sf_window_flavor {{create dynamic allocate}}
113 requires: defined(PETSC_HAVE_MPI_ONE_SIDED) defined(PETSC_HAVE_MPI_FEATURE_DYNAMIC_WINDOW)
114
115 TEST*/
116