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