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: }