Actual source code: bm.c

  1: #include <petsc/private/petscimpl.h>
  2: #include <petsc/private/bmimpl.h>
  3: #include <petscviewer.h>

  5: PetscClassId             BM_CLASSID;
  6: static PetscBool         PetscBenchPackageInitialized = PETSC_FALSE;
  7: static PetscFunctionList PetscBenchList               = NULL;

  9: // PetscClangLinter pragma disable: -fdoc-internal-linkage
 10: /*@
 11:   PetscBenchFinalizePackage - This function destroys everything in the `PetscBench` package. It is
 12:   called from `PetscFinalize()`.

 14:   Level: developer

 16: .seealso: `PetscFinalize()`, `PetscBenchInitializePackage()`, `PetscBenchCreate()`, `PetscBench`, `PetscBenchType`
 17: @*/
 18: static PetscErrorCode PetscBenchFinalizePackage(void)
 19: {
 20:   PetscFunctionBegin;
 21:   PetscCall(PetscFunctionListDestroy(&PetscBenchList));
 22:   PetscBenchPackageInitialized = PETSC_FALSE;
 23:   PetscFunctionReturn(PETSC_SUCCESS);
 24: }

 26: /*@
 27:   PetscBenchInitializePackage - This function initializes everything in the `PetscBench` package.

 29:   Level: developer

 31: .seealso: `PetscInitialize()`, `PetscBenchCreate()`, `PetscBench`, `PetscBenchType`
 32: @*/
 33: PetscErrorCode PetscBenchInitializePackage(void)
 34: {
 35:   PetscFunctionBegin;
 36:   if (PetscBenchPackageInitialized) PetscFunctionReturn(PETSC_SUCCESS);
 37:   PetscBenchPackageInitialized = PETSC_TRUE;
 38:   PetscCall(PetscClassIdRegister("PetscBench", &BM_CLASSID));
 39:   PetscCall(PetscRegisterFinalize(PetscBenchFinalizePackage));
 40:   PetscFunctionReturn(PETSC_SUCCESS);
 41: }

 43: /*@
 44:   PetscBenchRegister - Adds a benchmark test, `PetscBenchType`, to the `PetscBench` package

 46:   Not Collective, No Fortran Support

 48:   Input Parameters:
 49: + sname    - name of a new benchmark
 50: - function - routine to create benchmark

 52:   Calling sequence of function:
 53: . bm - the `PetscBench` to be created

 55:   Level: advanced

 57:   Note:
 58:   `PetscBenchRegister()` may be called multiple times

 60: .seealso: `PetscBenchInitializePackage()`, `PetscBenchCreate()`, `PetscBench`, `PetscBenchType`, `PetscBenchSetType()`, `PetscBenchGetType()`
 61: @*/
 62: PetscErrorCode PetscBenchRegister(const char sname[], PetscErrorCode (*function)(PetscBench bm))
 63: {
 64:   PetscFunctionBegin;
 65:   PetscCall(PetscBenchInitializePackage());
 66:   PetscCall(PetscFunctionListAdd(&PetscBenchList, sname, function));
 67:   PetscFunctionReturn(PETSC_SUCCESS);
 68: }

 70: /*@
 71:   PetscBenchReset - removes all the intermediate data structures in a `PetscBench`

 73:   Collective

 75:   Input Parameter:
 76: . bm - the `PetscBench`

 78:   Level: advanced

 80: .seealso: `PetscBench`, `PetscBenchView()`, `PetscBenchSetFromOptions()`, `PetscBenchCreate()`, `PetscBenchDestroy()`, `PetscBenchSetUp()`, `PetscBenchSetType()`
 81: @*/
 82: PetscErrorCode PetscBenchReset(PetscBench bm)
 83: {
 84:   PetscFunctionBegin;
 86:   PetscCall(PetscLogHandlerDestroy(&bm->lhdlr)); // Temporarily here until PetscLogHandlerReset() exists
 87:   PetscTryTypeMethod(bm, reset);
 88:   bm->setupcalled = PETSC_FALSE;
 89:   PetscFunctionReturn(PETSC_SUCCESS);
 90: }

 92: /*@
 93:   PetscBenchDestroy - Destroys a `PetscBench`

 95:   Collective

 97:   Input Parameter:
 98: . bm - the `PetscBench`

100:   Level: advanced

102: .seealso: `PetscBench`, `PetscBenchView()`, `PetscBenchSetFromOptions()`, `PetscBenchCreate()`
103: @*/
104: PetscErrorCode PetscBenchDestroy(PetscBench *bm)
105: {
106:   PetscFunctionBegin;
107:   PetscAssertPointer(bm, 1);
108:   if (!*bm) PetscFunctionReturn(PETSC_SUCCESS);
110:   if (--((PetscObject)*bm)->refct > 0) {
111:     *bm = NULL;
112:     PetscFunctionReturn(PETSC_SUCCESS);
113:   }
114:   PetscCall(PetscBenchReset(*bm));
115:   PetscTryTypeMethod(*bm, destroy);
116:   PetscCall(PetscHeaderDestroy(bm));
117:   PetscFunctionReturn(PETSC_SUCCESS);
118: }

120: /*@
121:   PetscBenchSetUp - sets up the `PetscBench`

123:   Collective

125:   Input Parameter:
126: . bm - the `PetscBench`

128:   Level: advanced

130: .seealso: `PetscBench`, `PetscBenchView()`, `PetscBenchSetFromOptions()`, `PetscBenchCreate()`, `PetscBenchDestroy()`, `PetscBenchSetType()`,
131:           `PetscBenchRun()`, `PetscBenchSetSize()`, `PetscBenchGetSize()`
132: @*/
133: PetscErrorCode PetscBenchSetUp(PetscBench bm)
134: {
135:   PetscFunctionBegin;
137:   if (bm->setupcalled) PetscFunctionReturn(PETSC_SUCCESS);
138:   PetscCall(PetscLogHandlerCreate(PETSC_COMM_WORLD, &bm->lhdlr)); // Temporarily here until PetscLogHandlerReset() exists
139:   PetscCall(PetscLogHandlerSetType(bm->lhdlr, PETSCLOGHANDLERDEFAULT));
140:   PetscTryTypeMethod(bm, setup);
141:   bm->setupcalled = PETSC_TRUE;
142:   PetscTryTypeMethod(bm, run);
143:   PetscFunctionReturn(PETSC_SUCCESS);
144: }

146: /*@
147:   PetscBenchRun - runs the `PetscBench`

149:   Collective

151:   Input Parameter:
152: . bm - the `PetscBench`

154:   Level: advanced

156: .seealso: `PetscBench`, `PetscBenchView()`, `PetscBenchSetFromOptions()`, `PetscBenchCreate()`, `PetscBenchDestroy()`, `PetscBenchSetUp()`, `PetscBenchSetType()`,
157:           `PetscBenchSetSize()`, `PetscBenchGetSize()`
158: @*/
159: PetscErrorCode PetscBenchRun(PetscBench bm)
160: {
161:   PetscFunctionBegin;
163:   if (!bm->setupcalled) PetscCall(PetscBenchSetUp(bm));
164:   PetscCall(PetscLogHandlerStart(bm->lhdlr));
165:   PetscTryTypeMethod(bm, run);
166:   PetscCall(PetscLogHandlerStop(bm->lhdlr));
167:   PetscFunctionReturn(PETSC_SUCCESS);
168: }

170: /*@
171:   PetscBenchSetFromOptions - Sets options to a `PetscBench` using the options database

173:   Collective

175:   Input Parameter:
176: . bm - the `PetscBench`

178:   Level: advanced

180: .seealso: `PetscBench`, `PetscBenchView()`, `PetscBenchRun()`, `PetscBenchCreate()`, `PetscBenchDestroy()`, `PetscBenchSetUp()`, `PetscBenchSetType()`,
181:           `PetscBenchSetSize()`, `PetscBenchGetSize()`
182: @*/
183: PetscErrorCode PetscBenchSetFromOptions(PetscBench bm)
184: {
185:   char      type[256];
186:   PetscBool flg;
187:   PetscInt  m;

189:   PetscFunctionBegin;
191:   PetscObjectOptionsBegin((PetscObject)bm);
192:   PetscCall(PetscOptionsFList("-bm_type", "PetscBench", "PetscBenchSetType", PetscBenchList, ((PetscObject)bm)->type_name, type, sizeof(type), &flg));
193:   if (flg) PetscCall(PetscBenchSetType(bm, type));
194:   PetscCheck(((PetscObject)bm)->type_name, PetscObjectComm((PetscObject)bm), PETSC_ERR_ARG_WRONGSTATE, "No PetscBenchType provided for PetscBench");
195:   PetscCall(PetscOptionsInt("-bm_size", "Size of benchmark", "PetscBenchSetSize", bm->size, &m, &flg));
196:   if (flg) PetscCall(PetscBenchSetSize(bm, m));
197:   PetscTryTypeMethod(bm, setfromoptions, PetscOptionsObject);
198:   PetscOptionsEnd();
199:   PetscFunctionReturn(PETSC_SUCCESS);
200: }

202: /*@
203:   PetscBenchView - Views a PETSc benchmark `PetscBench`

205:   Collective

207:   Input Parameters:
208: + bm     - the `PetscBench`
209: - viewer - location to view `bm`

211:   Level: advanced

213: .seealso: `PetscBench`, `PetscBenchSetFromOptions()`, `PetscBenchRun()`, `PetscBenchCreate()`, `PetscBenchDestroy()`, `PetscBenchSetUp()`, `PetscBenchSetType()`,
214:           `PetscBenchSetSize()`, `PetscBenchGetSize()`, `PetscBenchViewFromOptions()`
215: @*/
216: PetscErrorCode PetscBenchView(PetscBench bm, PetscViewer viewer)
217: {
218:   PetscFunctionBegin;
221:   PetscTryTypeMethod(bm, view, viewer);
222:   PetscFunctionReturn(PETSC_SUCCESS);
223: }

225: /*@
226:   PetscBenchViewFromOptions - Processes command line options to determine if/how a `PetscBench` is to be viewed.

228:   Collective

230:   Input Parameters:
231: + bm   - the object
232: . bobj - optional other object that provides prefix (if `NULL` then the prefix in `bm` is used)
233: - name - option to activate viewing

235:   Options Database Key:
236: . -name viewer_specification - See `PetscOptionsCreateViewer()` for the values of `viewer_specification`

238:   Level: advanced

240:   Note:
241:   This checks the options database, creates the viewer on-the-fly, uses it and then destroys it. Hence it should not be called in heavily used routines,
242:   rather `PetscOptionsCreateViewer()` should be used to construct the viewer once which can then be utilized in the heavily used routine.

244: .seealso: `PetscBench`, `PetscBenchSetFromOptions()`, `PetscBenchRun()`, `PetscBenchCreate()`, `PetscBenchDestroy()`, `PetscBenchSetUp()`, `PetscBenchSetType()`,
245:           `PetscBenchSetSize()`, `PetscBenchGetSize()`, `PetscObjectViewFromOptions()`, `PetscViewer`, `PetscBenchView()`, `PetscOptionsCreateViewer()`
246: @*/
247: PetscErrorCode PetscBenchViewFromOptions(PetscBench bm, PetscObject bobj, const char name[])
248: {
249:   PetscFunctionBegin;
251:   PetscCall(PetscObjectViewFromOptions((PetscObject)bm, bobj, name));
252:   PetscFunctionReturn(PETSC_SUCCESS);
253: }

255: /*@
256:   PetscBenchCreate - Create a PETSc benchmark `PetscBench` object

258:   Collective

260:   Input Parameter:
261: . comm - communicator to share the `PetscBench`

263:   Output Parameter:
264: . bm - the `PetscBench`

266:   Level: advanced

268: .seealso: `PetscBench`, `PetscBenchSetFromOptions()`, `PetscBenchRun()`, `PetscBenchViewFromOptions()`, `PetscBenchDestroy()`, `PetscBenchSetUp()`, `PetscBenchSetType()`,
269:           `PetscBenchSetSize()`, `PetscBenchGetSize()`
270: @*/
271: PetscErrorCode PetscBenchCreate(MPI_Comm comm, PetscBench *bm)
272: {
273:   PetscFunctionBegin;
274:   PetscAssertPointer(bm, 2);
275:   PetscCall(PetscBenchInitializePackage());

277:   PetscCall(PetscHeaderCreate(*bm, BM_CLASSID, "BM", "PetscBench", "BM", comm, PetscBenchDestroy, PetscBenchView));
278:   (*bm)->size = PETSC_DECIDE;
279:   PetscFunctionReturn(PETSC_SUCCESS);
280: }

282: /*@
283:   PetscBenchSetOptionsPrefix - Sets the prefix used for searching for all `PetscBench` items in the options database.

285:   Logically Collective

287:   Input Parameters:
288: + bm  - the `PetscBench`
289: - pre - the prefix to prepend all `PetscBench` option names

291:   Level: advanced

293: .seealso: `PetscBench`, `PetscBenchSetFromOptions()`, `PetscBenchRun()`, `PetscBenchViewFromOptions()`, `PetscBenchDestroy()`, `PetscBenchSetUp()`, `PetscBenchSetType()`,
294:           `PetscBenchSetSize()`, `PetscBenchGetSize()`
295: @*/
296: PetscErrorCode PetscBenchSetOptionsPrefix(PetscBench bm, const char pre[])
297: {
298:   PetscFunctionBegin;
300:   PetscCall(PetscObjectSetOptionsPrefix((PetscObject)bm, pre));
301:   PetscFunctionReturn(PETSC_SUCCESS);
302: }

304: /*@
305:   PetscBenchSetSize - Sets the size of the `PetscBench` benchmark to run

307:   Logically Collective

309:   Input Parameters:
310: + bm - the `PetscBench`
311: - n  - the size

313:   Level: advanced

315: .seealso: `PetscBench`, `PetscBenchSetFromOptions()`, `PetscBenchRun()`, `PetscBenchViewFromOptions()`, `PetscBenchDestroy()`, `PetscBenchSetUp()`, `PetscBenchSetType()`,
316:           `PetscBenchSetOptionsPrefix()`, `PetscBenchGetSize()`
317: @*/
318: PetscErrorCode PetscBenchSetSize(PetscBench bm, PetscInt n)
319: {
320:   PetscFunctionBegin;
322:   if (bm->size > 0 && bm->size != n && bm->setupcalled) {
323:     PetscCall(PetscBenchReset(bm));
324:     bm->setupcalled = PETSC_FALSE;
325:   }
326:   PetscCheck(n > 0, PetscObjectComm((PetscObject)bm), PETSC_ERR_ARG_OUTOFRANGE, "Illegal value of n. Must be > 0");
327:   bm->size = n;
328:   PetscFunctionReturn(PETSC_SUCCESS);
329: }

331: /*@
332:   PetscBenchGetSize - Gets the size of the `PetscBench` benchmark to run

334:   Logically Collective

336:   Input Parameter:
337: . bm - the `PetscBench`

339:   Output Parameter:
340: . n - the size

342:   Level: advanced

344: .seealso: `PetscBench`, `PetscBenchSetFromOptions()`, `PetscBenchRun()`, `PetscBenchViewFromOptions()`, `PetscBenchDestroy()`, `PetscBenchSetUp()`, `PetscBenchSetType()`,
345:           `PetscBenchSetOptionsPrefix()`, `PetscBenchSetSize()`
346: @*/
347: PetscErrorCode PetscBenchGetSize(PetscBench bm, PetscInt *n)
348: {
349:   PetscFunctionBegin;
351:   PetscAssertPointer(n, 2);
352:   *n = bm->size;
353:   PetscFunctionReturn(PETSC_SUCCESS);
354: }

356: /*@
357:   PetscBenchSetType - set the type of `PetscBench` benchmark to run

359:   Collective

361:   Input Parameters:
362: + bm   - the `PetscBench`
363: - type - a known method

365:   Options Database Key:
366: . -bm_type type - Sets `PetscBench` type

368:   Level: advanced

370:   Developer Note:
371:   `PetscBenchRegister()` is used to add new benchmark types

373: .seealso: `PetscBench`, `PetscBenchSetFromOptions()`, `PetscBenchRun()`, `PetscBenchViewFromOptions()`, `PetscBenchDestroy()`, `PetscBenchSetUp()`, `PetscBenchGetSize()`,
374:           `PetscBenchSetOptionsPrefix()`, `PetscBenchSetSize()`, `PetscBenchGetType()`, `PetscBenchCreate()`
375: @*/
376: PetscErrorCode PetscBenchSetType(PetscBench bm, PetscBenchType type)
377: {
378:   PetscBool match;
379:   PetscErrorCode (*r)(PetscBench);

381:   PetscFunctionBegin;
383:   PetscAssertPointer(type, 2);

385:   PetscCall(PetscObjectTypeCompare((PetscObject)bm, type, &match));
386:   if (match) PetscFunctionReturn(PETSC_SUCCESS);

388:   PetscCall(PetscFunctionListFind(PetscBenchList, type, &r));
389:   PetscCheck(r, PetscObjectComm((PetscObject)bm), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unable to find requested PetscBench type %s", type);
390:   /* Destroy the previous private BM context */
391:   PetscTryTypeMethod(bm, destroy);
392:   bm->ops->destroy = NULL;
393:   bm->data         = NULL;

395:   PetscCall(PetscFunctionListDestroy(&((PetscObject)bm)->qlist));
396:   /* Reinitialize function pointers in PetscBenchOps structure */
397:   PetscCall(PetscMemzero(bm->ops, sizeof(struct _PetscBenchOps)));

399:   PetscCall(PetscObjectChangeTypeName((PetscObject)bm, type));
400:   PetscCall((*r)(bm));
401:   PetscFunctionReturn(PETSC_SUCCESS);
402: }

404: /*@
405:   PetscBenchGetType - Gets the `PetscBenchType` (as a string) from the `PetscBench`
406:   context.

408:   Not Collective

410:   Input Parameter:
411: . bm - the `PetscBench`

413:   Output Parameter:
414: . type - name of benchmark method

416:   Level: intermediate

418: .seealso: `PetscBench`, `PetscBenchType`, `PetscBenchSetType()`, `PetscBenchCreate()`
419: @*/
420: PetscErrorCode PetscBenchGetType(PetscBench bm, PetscBenchType *type)
421: {
422:   PetscFunctionBegin;
424:   PetscAssertPointer(type, 2);
425:   *type = ((PetscObject)bm)->type_name;
426:   PetscFunctionReturn(PETSC_SUCCESS);
427: }