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