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_INT_MAX, PETSC_COMM_SELF, PETSC_ERR_PLIB, "SF minimum leaf is not PETSC_INT_MAX");
 20:   PetscCheck(sf->maxleaf == PETSC_INT_MIN, PETSC_COMM_SELF, PETSC_ERR_PLIB, "SF minimum leaf is not PETSC_INT_MIN");
 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, &degree));
194:   PetscCall(PetscSFComputeDegreeEnd(sf, &degree));
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) defined(PETSC_HAVE_MPI_ONE_SIDED) defined(PETSC_HAVE_MPI_FEATURE_DYNAMIC_WINDOW)

281: TEST*/