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: /*@C
 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: /*@C
 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: /*@C
 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 [viewertype][:...] - option name and values. See `PetscObjectViewFromOptions()` for the possible arguments

238:   Level: advanced

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

251: /*@
252:   PetscBenchCreate - Create a PETSc benchmark `PetscBench` object

254:   Collective

256:   Input Parameter:
257: . comm - communicator to share the `PetscBench`

259:   Output Parameter:
260: . bm - the `PetscBench`

262:   Level: advanced

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

273:   PetscCall(PetscHeaderCreate(*bm, BM_CLASSID, "BM", "PetscBench", "BM", comm, PetscBenchDestroy, PetscBenchView));
274:   (*bm)->size = PETSC_DECIDE;
275:   PetscFunctionReturn(PETSC_SUCCESS);
276: }

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

281:   Logically Collective

283:   Input Parameters:
284: + bm  - the `PetscBench`
285: - pre - the prefix to prepend all `PetscBench` option names

287:   Level: advanced

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

300: /*@
301:   PetscBenchSetSize - Sets the size of the `PetscBench` benchmark to run

303:   Logically Collective

305:   Input Parameters:
306: + bm - the `PetscBench`
307: - n  - the size

309:   Level: advanced

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

327: /*@
328:   PetscBenchGetSize - Gets the size of the `PetscBench` benchmark to run

330:   Logically Collective

332:   Input Parameter:
333: . bm - the `PetscBench`

335:   Output Parameter:
336: . n - the size

338:   Level: advanced

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

352: /*@
353:   PetscBenchSetType - set the type of `PetscBench` benchmark to run

355:   Collective

357:   Input Parameters:
358: + bm   - the `PetscBench`
359: - type - a known method

361:   Options Database Key:
362: . -bm_type type - Sets `PetscBench` type

364:   Level: advanced

366:   Developer Note:
367:   `PetscBenchRegister()` is used to add new benchmark types

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

377:   PetscFunctionBegin;
379:   PetscAssertPointer(type, 2);

381:   PetscCall(PetscObjectTypeCompare((PetscObject)bm, type, &match));
382:   if (match) PetscFunctionReturn(PETSC_SUCCESS);

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

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

395:   PetscCall(PetscObjectChangeTypeName((PetscObject)bm, type));
396:   PetscCall((*r)(bm));
397:   PetscFunctionReturn(PETSC_SUCCESS);
398: }

400: /*@
401:   PetscBenchGetType - Gets the `PetscBenchType` (as a string) from the `PetscBench`
402:   context.

404:   Not Collective

406:   Input Parameter:
407: . bm - the `PetscBench`

409:   Output Parameter:
410: . type - name of benchmark method

412:   Level: intermediate

414: .seealso: `PetscBench`, `PetscBenchType`, `PetscBenchSetType()`, `PetscBenchCreate()`
415: @*/
416: PetscErrorCode PetscBenchGetType(PetscBench bm, PetscBenchType *type)
417: {
418:   PetscFunctionBegin;
420:   PetscAssertPointer(type, 2);
421:   *type = ((PetscObject)bm)->type_name;
422:   PetscFunctionReturn(PETSC_SUCCESS);
423: }