1 static const char help[] = "Test star forest communication (PetscSF)\n\n";
2
3 #include <petscsf.h>
4 #include <petsc/private/sfimpl.h>
5
CheckGraphNotSet(PetscSF sf)6 static PetscErrorCode CheckGraphNotSet(PetscSF sf)
7 {
8 PetscInt nroots, nleaves;
9 const PetscInt *ilocal;
10 const PetscSFNode *iremote;
11
12 PetscFunctionBegin;
13 PetscCheck(!sf->graphset, PETSC_COMM_SELF, PETSC_ERR_PLIB, "SF graph is set");
14 PetscCall(PetscSFGetGraph(sf, &nroots, &nleaves, &ilocal, &iremote));
15 PetscCheck(nroots < 0, PETSC_COMM_SELF, PETSC_ERR_PLIB, "SF graph is set");
16 PetscCheck(nleaves < 0, PETSC_COMM_SELF, PETSC_ERR_PLIB, "SF graph is set");
17 PetscCheck(!ilocal, PETSC_COMM_SELF, PETSC_ERR_PLIB, "SF graph is set");
18 PetscCheck(!iremote, PETSC_COMM_SELF, PETSC_ERR_PLIB, "SF graph is set");
19 PetscCheck(sf->minleaf == PETSC_INT_MAX, PETSC_COMM_SELF, PETSC_ERR_PLIB, "SF minimum leaf is not PETSC_INT_MAX");
20 PetscCheck(sf->maxleaf == PETSC_INT_MIN, PETSC_COMM_SELF, PETSC_ERR_PLIB, "SF minimum leaf is not PETSC_INT_MIN");
21 PetscFunctionReturn(PETSC_SUCCESS);
22 }
23
CheckGraphEmpty(PetscSF sf)24 static PetscErrorCode CheckGraphEmpty(PetscSF sf)
25 {
26 PetscInt nroots, nleaves;
27 const PetscInt *ilocal;
28 const PetscSFNode *iremote;
29 PetscInt minleaf, maxleaf;
30
31 PetscFunctionBegin;
32 PetscCall(PetscSFGetGraph(sf, &nroots, &nleaves, &ilocal, &iremote));
33 PetscCheck(!nroots, PETSC_COMM_SELF, PETSC_ERR_PLIB, "SF graph is not empty");
34 PetscCheck(!nleaves, PETSC_COMM_SELF, PETSC_ERR_PLIB, "SF graph is not empty");
35 PetscCheck(!ilocal, PETSC_COMM_SELF, PETSC_ERR_PLIB, "SF graph is not empty");
36 PetscCheck(!iremote, PETSC_COMM_SELF, PETSC_ERR_PLIB, "SF graph is not empty");
37 PetscCall(PetscSFGetLeafRange(sf, &minleaf, &maxleaf));
38 PetscCheck(minleaf == 0, PETSC_COMM_SELF, PETSC_ERR_PLIB, "SF minimum leaf is not 0");
39 PetscCheck(maxleaf == -1, PETSC_COMM_SELF, PETSC_ERR_PLIB, "SF maximum leaf is not -1");
40 PetscFunctionReturn(PETSC_SUCCESS);
41 }
42
CheckRanksNotSet(PetscSF sf)43 static PetscErrorCode CheckRanksNotSet(PetscSF sf)
44 {
45 PetscFunctionBegin;
46 PetscCheck(sf->nranks == -1, PETSC_COMM_SELF, PETSC_ERR_PLIB, "SF ranks are set");
47 PetscCheck(sf->ranks == NULL, PETSC_COMM_SELF, PETSC_ERR_PLIB, "SF ranks are set");
48 PetscFunctionReturn(PETSC_SUCCESS);
49 }
50
CheckRanksEmpty(PetscSF sf)51 static PetscErrorCode CheckRanksEmpty(PetscSF sf)
52 {
53 PetscFunctionBegin;
54 PetscCheck(sf->nranks == 0, PETSC_COMM_SELF, PETSC_ERR_PLIB, "SF ranks not empty");
55 PetscFunctionReturn(PETSC_SUCCESS);
56 }
57
main(int argc,char ** argv)58 int main(int argc, char **argv)
59 {
60 PetscSF sf, sfDup, sfInv, sfEmbed, sfA, sfB, sfBA;
61 const PetscInt *degree;
62 char sftype[64] = PETSCSFBASIC;
63
64 PetscFunctionBeginUser;
65 PetscCall(PetscInitialize(&argc, &argv, NULL, help));
66 PetscCall(PetscOptionsGetString(NULL, NULL, "-user_sf_type", sftype, sizeof(sftype), NULL));
67
68 PetscCall(PetscSFCreate(PETSC_COMM_WORLD, &sf));
69 PetscCall(CheckGraphNotSet(sf));
70 PetscCall(PetscSFDestroy(&sf));
71
72 PetscCall(PetscSFCreate(PETSC_COMM_WORLD, &sf));
73 PetscCall(CheckGraphNotSet(sf));
74 PetscCall(PetscSFReset(sf));
75 PetscCall(CheckGraphNotSet(sf));
76 PetscCall(PetscSFDestroy(&sf));
77
78 PetscCall(PetscSFCreate(PETSC_COMM_WORLD, &sf));
79 PetscCall(CheckGraphNotSet(sf));
80 PetscCall(PetscSFSetType(sf, sftype));
81 PetscCall(CheckGraphNotSet(sf));
82 PetscCall(PetscSFDestroy(&sf));
83
84 PetscCall(PetscSFCreate(PETSC_COMM_WORLD, &sf));
85 PetscCall(CheckGraphNotSet(sf));
86 PetscCall(PetscSFSetType(sf, sftype));
87 PetscCall(CheckGraphNotSet(sf));
88 PetscCall(PetscSFReset(sf));
89 PetscCall(CheckGraphNotSet(sf));
90 PetscCall(PetscSFDestroy(&sf));
91
92 PetscCall(PetscSFCreate(PETSC_COMM_WORLD, &sf));
93 PetscCall(PetscSFSetGraph(sf, 0, 0, NULL, PETSC_COPY_VALUES, NULL, PETSC_COPY_VALUES));
94 PetscCall(CheckGraphEmpty(sf));
95 PetscCall(PetscSFReset(sf));
96 PetscCall(CheckGraphNotSet(sf));
97 PetscCall(PetscSFDestroy(&sf));
98
99 PetscCall(PetscSFCreate(PETSC_COMM_WORLD, &sf));
100 PetscCall(PetscSFSetType(sf, sftype));
101 PetscCall(PetscSFSetGraph(sf, 0, 0, NULL, PETSC_COPY_VALUES, NULL, PETSC_COPY_VALUES));
102 PetscCall(CheckGraphEmpty(sf));
103 PetscCall(PetscSFReset(sf));
104 PetscCall(CheckGraphNotSet(sf));
105 PetscCall(PetscSFDestroy(&sf));
106
107 /* Test setup */
108 PetscCall(PetscSFCreate(PETSC_COMM_WORLD, &sf));
109 PetscCall(CheckRanksNotSet(sf));
110 PetscCall(PetscSFSetGraph(sf, 0, 0, NULL, PETSC_COPY_VALUES, NULL, PETSC_COPY_VALUES));
111 PetscCall(CheckRanksNotSet(sf));
112 PetscCall(PetscSFSetUp(sf));
113 PetscCall(CheckRanksEmpty(sf));
114 PetscCall(PetscSFDestroy(&sf));
115
116 /* Test setup then reset */
117 PetscCall(PetscSFCreate(PETSC_COMM_WORLD, &sf));
118 PetscCall(PetscSFSetGraph(sf, 0, 0, NULL, PETSC_COPY_VALUES, NULL, PETSC_COPY_VALUES));
119 PetscCall(PetscSFSetUp(sf));
120 PetscCall(PetscSFReset(sf));
121 PetscCall(CheckRanksNotSet(sf));
122 PetscCall(PetscSFDestroy(&sf));
123
124 /* Test view (no graph set, no type set) */
125 PetscCall(PetscSFCreate(PETSC_COMM_WORLD, &sf));
126 PetscCall(PetscSFView(sf, NULL));
127 PetscCall(PetscSFDestroy(&sf));
128
129 /* Test set graph then view (no type set) */
130 PetscCall(PetscSFCreate(PETSC_COMM_WORLD, &sf));
131 PetscCall(PetscSFSetGraph(sf, 0, 0, NULL, PETSC_COPY_VALUES, NULL, PETSC_COPY_VALUES));
132 PetscCall(PetscSFView(sf, NULL));
133 PetscCall(PetscSFDestroy(&sf));
134
135 /* Test set type then view (no graph set) */
136 PetscCall(PetscSFCreate(PETSC_COMM_WORLD, &sf));
137 PetscCall(PetscSFSetType(sf, sftype));
138 PetscCall(PetscSFView(sf, NULL));
139 PetscCall(PetscSFDestroy(&sf));
140
141 /* Test set type then graph then view */
142 PetscCall(PetscSFCreate(PETSC_COMM_WORLD, &sf));
143 PetscCall(PetscSFSetType(sf, sftype));
144 PetscCall(PetscSFSetGraph(sf, 0, 0, NULL, PETSC_COPY_VALUES, NULL, PETSC_COPY_VALUES));
145 PetscCall(PetscSFView(sf, NULL));
146 PetscCall(PetscSFDestroy(&sf));
147
148 /* Test set graph then type */
149 PetscCall(PetscSFCreate(PETSC_COMM_WORLD, &sf));
150 PetscCall(PetscSFSetGraph(sf, 0, 0, NULL, PETSC_COPY_VALUES, NULL, PETSC_COPY_VALUES));
151 PetscCall(PetscSFSetType(sf, sftype));
152 PetscCall(CheckGraphEmpty(sf));
153 PetscCall(PetscSFReset(sf));
154 PetscCall(CheckGraphNotSet(sf));
155 PetscCall(PetscSFDestroy(&sf));
156
157 /* Test Bcast (we call setfromoptions) */
158 PetscCall(PetscSFCreate(PETSC_COMM_WORLD, &sf));
159 PetscCall(PetscSFSetType(sf, sftype));
160 PetscCall(PetscSFSetFromOptions(sf));
161 PetscCall(PetscSFSetGraph(sf, 0, 0, NULL, PETSC_COPY_VALUES, NULL, PETSC_COPY_VALUES));
162 PetscCall(PetscSFBcastBegin(sf, MPI_INT, NULL, NULL, MPI_REPLACE));
163 PetscCall(PetscSFBcastEnd(sf, MPI_INT, NULL, NULL, MPI_REPLACE));
164 PetscCall(PetscSFDestroy(&sf));
165
166 /* From now on we also call SetFromOptions */
167
168 /* Test Reduce */
169 PetscCall(PetscSFCreate(PETSC_COMM_WORLD, &sf));
170 PetscCall(PetscSFSetType(sf, sftype));
171 PetscCall(PetscSFSetGraph(sf, 0, 0, NULL, PETSC_COPY_VALUES, NULL, PETSC_COPY_VALUES));
172 PetscCall(PetscSFSetFromOptions(sf));
173 PetscCall(PetscSFReduceBegin(sf, MPI_INT, NULL, NULL, MPI_REPLACE));
174 PetscCall(PetscSFReduceEnd(sf, MPI_INT, NULL, NULL, MPI_REPLACE));
175 PetscCall(PetscSFReduceBegin(sf, MPI_INT, NULL, NULL, MPI_SUM));
176 PetscCall(PetscSFReduceEnd(sf, MPI_INT, NULL, NULL, MPI_SUM));
177 PetscCall(PetscSFDestroy(&sf));
178
179 /* Test FetchAndOp */
180 PetscCall(PetscSFCreate(PETSC_COMM_WORLD, &sf));
181 PetscCall(PetscSFSetType(sf, sftype));
182 PetscCall(PetscSFSetGraph(sf, 0, 0, NULL, PETSC_COPY_VALUES, NULL, PETSC_COPY_VALUES));
183 PetscCall(PetscSFSetFromOptions(sf));
184 PetscCall(PetscSFFetchAndOpBegin(sf, MPI_INT, NULL, NULL, NULL, MPI_SUM));
185 PetscCall(PetscSFFetchAndOpEnd(sf, MPI_INT, NULL, NULL, NULL, MPI_SUM));
186 PetscCall(PetscSFDestroy(&sf));
187
188 /* Test ComputeDegree */
189 PetscCall(PetscSFCreate(PETSC_COMM_WORLD, &sf));
190 PetscCall(PetscSFSetType(sf, sftype));
191 PetscCall(PetscSFSetGraph(sf, 0, 0, NULL, PETSC_COPY_VALUES, NULL, PETSC_COPY_VALUES));
192 PetscCall(PetscSFSetFromOptions(sf));
193 PetscCall(PetscSFComputeDegreeBegin(sf, °ree));
194 PetscCall(PetscSFComputeDegreeEnd(sf, °ree));
195 PetscCall(PetscSFDestroy(&sf));
196
197 /* Test PetscSFDuplicate() */
198 PetscCall(PetscSFCreate(PETSC_COMM_WORLD, &sf));
199 PetscCall(PetscSFSetType(sf, sftype));
200 PetscCall(PetscSFSetGraph(sf, 0, 0, NULL, PETSC_USE_POINTER, NULL, PETSC_USE_POINTER));
201 PetscCall(PetscSFSetFromOptions(sf));
202 PetscCall(PetscSFDuplicate(sf, PETSCSF_DUPLICATE_GRAPH, &sfDup));
203 PetscCall(CheckGraphEmpty(sfDup));
204 PetscCall(PetscSFDestroy(&sfDup));
205 PetscCall(PetscSFDestroy(&sf));
206
207 /* Test PetscSFCreateInverseSF() */
208 PetscCall(PetscSFCreate(PETSC_COMM_WORLD, &sf));
209 PetscCall(PetscSFSetType(sf, sftype));
210 PetscCall(PetscSFSetGraph(sf, 0, 0, NULL, PETSC_USE_POINTER, NULL, PETSC_USE_POINTER));
211 PetscCall(PetscSFSetFromOptions(sf));
212 PetscCall(PetscSFCreateInverseSF(sf, &sfInv));
213 PetscCall(CheckGraphEmpty(sfInv));
214 PetscCall(PetscSFDestroy(&sfInv));
215 PetscCall(PetscSFDestroy(&sf));
216
217 /* Test PetscSFCreateEmbeddedRootSF() */
218 PetscCall(PetscSFCreate(PETSC_COMM_WORLD, &sf));
219 PetscCall(PetscSFSetType(sf, sftype));
220 PetscCall(PetscSFSetGraph(sf, 0, 0, NULL, PETSC_USE_POINTER, NULL, PETSC_USE_POINTER));
221 PetscCall(PetscSFSetFromOptions(sf));
222 PetscCall(PetscSFCreateEmbeddedRootSF(sf, 0, NULL, &sfEmbed));
223 PetscCall(CheckGraphEmpty(sfEmbed));
224 PetscCall(PetscSFDestroy(&sfEmbed));
225 PetscCall(PetscSFDestroy(&sf));
226
227 /* Test PetscSFCreateEmbeddedLeafSF() */
228 PetscCall(PetscSFCreate(PETSC_COMM_WORLD, &sf));
229 PetscCall(PetscSFSetType(sf, sftype));
230 PetscCall(PetscSFSetGraph(sf, 0, 0, NULL, PETSC_USE_POINTER, NULL, PETSC_USE_POINTER));
231 PetscCall(PetscSFSetFromOptions(sf));
232 PetscCall(PetscSFCreateEmbeddedLeafSF(sf, 0, NULL, &sfEmbed));
233 PetscCall(CheckGraphEmpty(sfEmbed));
234 PetscCall(PetscSFDestroy(&sfEmbed));
235 PetscCall(PetscSFDestroy(&sf));
236
237 /* Test PetscSFCompose() */
238 PetscCall(PetscSFCreate(PETSC_COMM_WORLD, &sfA));
239 PetscCall(PetscSFSetType(sfA, sftype));
240 PetscCall(PetscSFSetGraph(sfA, 0, 0, NULL, PETSC_USE_POINTER, NULL, PETSC_USE_POINTER));
241 PetscCall(PetscSFCreate(PETSC_COMM_WORLD, &sfB));
242 PetscCall(PetscSFSetType(sfB, sftype));
243 PetscCall(PetscSFSetGraph(sfB, 0, 0, NULL, PETSC_USE_POINTER, NULL, PETSC_USE_POINTER));
244 PetscCall(PetscSFCompose(sfA, sfB, &sfBA));
245 PetscCall(CheckGraphEmpty(sfBA));
246 PetscCall(PetscSFDestroy(&sfBA));
247 PetscCall(PetscSFDestroy(&sfA));
248 PetscCall(PetscSFDestroy(&sfB));
249
250 PetscCall(PetscFinalize());
251 return 0;
252 }
253
254 /*TEST
255
256 test:
257 suffix: basic_1
258 nsize: 1
259
260 test:
261 suffix: basic_2
262 nsize: 2
263
264 test:
265 suffix: basic_3
266 nsize: 3
267
268 test:
269 suffix: window
270 args: -user_sf_type window -sf_type window -sf_window_flavor {{create dynamic allocate}} -sf_window_sync {{fence active lock}}
271 nsize: {{1 2 3}separate output}
272 requires: defined(PETSC_HAVE_MPI_ONE_SIDED) defined(PETSC_HAVE_MPI_FEATURE_DYNAMIC_WINDOW)
273
274 # The nightly test suite with MPICH uses ch3:sock, which is broken when winsize == 0 in some of the processes
275 test:
276 suffix: window_shared
277 args: -user_sf_type window -sf_type window -sf_window_flavor shared -sf_window_sync {{fence active lock}}
278 nsize: {{1 2 3}separate output}
279 requires: defined(PETSC_HAVE_MPI_PROCESS_SHARED_MEMORY) !defined(PETSC_HAVE_MPICH) defined(PETSC_HAVE_MPI_ONE_SIDED) defined(PETSC_HAVE_MPI_FEATURE_DYNAMIC_WINDOW)
280
281 TEST*/
282