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