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