Actual source code: bm.c

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

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

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

 13:   Level: developer

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

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

 28:   Level: developer

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

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

 45:   Not Collective, No Fortran Support

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

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

 54:   Level: advanced

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

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

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

 72:   Collective

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

 77:   Level: advanced

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

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

 94:   Collective

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

 99:   Level: advanced

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

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

122:   Collective

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

127:   Level: advanced

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

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

148:   Collective

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

153:   Level: advanced

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

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

172:   Collective

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

177:   Level: advanced

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

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

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

204:   Collective

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

210:   Level: advanced

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

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

227:   Collective

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

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

237:   Level: advanced

239:   Note:
240:   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,
241:   rather `PetscOptionsCreateViewer()` should be used to construct the viewer once which can then be utilized in the heavily used routine.

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

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

257:   Collective

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

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

265:   Level: advanced

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

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

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

284:   Logically Collective

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

290:   Level: advanced

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

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

306:   Logically Collective

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

312:   Level: advanced

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

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

333:   Logically Collective

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

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

341:   Level: advanced

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

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

358:   Collective

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

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

367:   Level: advanced

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

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

380:   PetscFunctionBegin;
382:   PetscAssertPointer(type, 2);

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

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

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

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

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

407:   Not Collective

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

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

415:   Level: intermediate

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