xref: /petsc/src/vec/is/sf/tests/ex1.c (revision 21e3ffae2f3b73c0bd738cf6d0a809700fc04bb0)
1 static const char help[] = "Test star forest communication (PetscSF)\n\n";
2 
3 #include <petscsf.h>
4 #include <petsc/private/sfimpl.h>
5 
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_MAX_INT, PETSC_COMM_SELF, PETSC_ERR_PLIB, "SF minimum leaf is not PETSC_MAX_INT");
20   PetscCheck(sf->maxleaf == PETSC_MIN_INT, PETSC_COMM_SELF, PETSC_ERR_PLIB, "SF minimum leaf is not PETSC_MIN_INT");
21   PetscFunctionReturn(PETSC_SUCCESS);
22 }
23 
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 
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 
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 
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, &degree));
194   PetscCall(PetscSFComputeDegreeEnd(sf, &degree));
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_NUMVERSION) defined(PETSC_HAVE_MPI_ONE_SIDED) defined(PETSC_HAVE_MPI_FEATURE_DYNAMIC_WINDOW)
280 
281 TEST*/
282