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