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