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