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