xref: /petsc/src/sys/classes/bm/interfaces/bm.c (revision 4ad8454beace47809662cdae21ee081016eaa39a)
1 #include <petsc/private/petscimpl.h>
2 #include <petsc/private/bmimpl.h> /*I  "petscbm.h"   I*/
3 #include <petscviewer.h>
4 
5 PetscClassId             BM_CLASSID;
6 static PetscBool         PetscBenchPackageInitialized = PETSC_FALSE;
7 static PetscFunctionList PetscBenchList               = NULL;
8 
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()`.
13 
14   Level: developer
15 
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 }
25 
26 /*@C
27   PetscBenchInitializePackage - This function initializes everything in the `PetscBench` package.
28 
29   Level: developer
30 
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 }
42 
43 /*@C
44   PetscBenchRegister -  Adds a benchmark test, `PetscBenchType`, to the `PetscBench` package
45 
46   Not Collective
47 
48   Input Parameters:
49 + sname    - name of a new benchmark
50 - function - routine to create benchmark
51 
52   Level: advanced
53 
54   Note:
55   `PetscBenchRegister()` may be called multiple times
56 
57 .seealso: `PetscBenchInitializePackage()`, `PetscBenchCreate()`, `PetscBench`, `PetscBenchType`, `PetscBenchSetType()`, `PetscBenchGetType()`
58 @*/
59 PetscErrorCode PetscBenchRegister(const char sname[], PetscErrorCode (*function)(PetscBench))
60 {
61   PetscFunctionBegin;
62   PetscCall(PetscBenchInitializePackage());
63   PetscCall(PetscFunctionListAdd(&PetscBenchList, sname, function));
64   PetscFunctionReturn(PETSC_SUCCESS);
65 }
66 
67 /*@C
68   PetscBenchReset - removes all the intermediate data structures in a `PetscBench`
69 
70   Collective
71 
72   Input Parameter:
73 . bm - the `PetscBench`
74 
75   Level: advanced
76 
77 .seealso: `PetscBench`, `PetscBenchView()`, `PetscBenchSetFromOptions()`, `PetscBenchCreate()`, `PetscBenchDestroy()`, `PetscBenchSetUp()`, `PetscBenchSetType()`
78 @*/
79 PetscErrorCode PetscBenchReset(PetscBench bm)
80 {
81   PetscFunctionBegin;
82   PetscValidHeaderSpecific(bm, BM_CLASSID, 1);
83   PetscCall(PetscLogHandlerDestroy(&bm->lhdlr)); // Temporarily here until PetscLogHandlerReset() exists
84   PetscTryTypeMethod(bm, reset);
85   bm->setupcalled = PETSC_FALSE;
86   PetscFunctionReturn(PETSC_SUCCESS);
87 }
88 
89 /*@C
90   PetscBenchDestroy - Destroys a `PetscBench`
91 
92   Collective
93 
94   Input Parameter:
95 . bm - the `PetscBench`
96 
97   Level: advanced
98 
99 .seealso: `PetscBench`, `PetscBenchView()`, `PetscBenchSetFromOptions()`, `PetscBenchCreate()`
100 @*/
101 PetscErrorCode PetscBenchDestroy(PetscBench *bm)
102 {
103   PetscFunctionBegin;
104   PetscAssertPointer(bm, 1);
105   if (!*bm) PetscFunctionReturn(PETSC_SUCCESS);
106   PetscValidHeaderSpecific(*bm, BM_CLASSID, 1);
107   if (--((PetscObject)*bm)->refct > 0) {
108     *bm = NULL;
109     PetscFunctionReturn(PETSC_SUCCESS);
110   }
111   PetscCall(PetscBenchReset(*bm));
112   PetscTryTypeMethod(*bm, destroy);
113   PetscCall(PetscHeaderDestroy(bm));
114   PetscFunctionReturn(PETSC_SUCCESS);
115 }
116 
117 /*@
118   PetscBenchSetUp - sets up the `PetscBench`
119 
120   Collective
121 
122   Input Parameter:
123 . bm - the `PetscBench`
124 
125   Level: advanced
126 
127 .seealso: `PetscBench`, `PetscBenchView()`, `PetscBenchSetFromOptions()`, `PetscBenchCreate()`, `PetscBenchDestroy()`, `PetscBenchSetType()`,
128           `PetscBenchRun()`, `PetscBenchSetSize()`, `PetscBenchGetSize()`
129 @*/
130 PetscErrorCode PetscBenchSetUp(PetscBench bm)
131 {
132   PetscFunctionBegin;
133   PetscValidHeaderSpecific(bm, BM_CLASSID, 1);
134   if (bm->setupcalled) PetscFunctionReturn(PETSC_SUCCESS);
135   PetscCall(PetscLogHandlerCreate(PETSC_COMM_WORLD, &bm->lhdlr)); // Temporarily here until PetscLogHandlerReset() exists
136   PetscCall(PetscLogHandlerSetType(bm->lhdlr, PETSCLOGHANDLERDEFAULT));
137   PetscTryTypeMethod(bm, setup);
138   bm->setupcalled = PETSC_TRUE;
139   PetscTryTypeMethod(bm, run);
140   PetscFunctionReturn(PETSC_SUCCESS);
141 }
142 
143 /*@
144   PetscBenchRun - runs the `PetscBench`
145 
146   Collective
147 
148   Input Parameter:
149 . bm - the `PetscBench`
150 
151   Level: advanced
152 
153 .seealso: `PetscBench`, `PetscBenchView()`, `PetscBenchSetFromOptions()`, `PetscBenchCreate()`, `PetscBenchDestroy()`, `PetscBenchSetUp()`, `PetscBenchSetType()`,
154           `PetscBenchSetSize()`, `PetscBenchGetSize()`
155 @*/
156 PetscErrorCode PetscBenchRun(PetscBench bm)
157 {
158   PetscFunctionBegin;
159   PetscValidHeaderSpecific(bm, BM_CLASSID, 1);
160   if (!bm->setupcalled) PetscCall(PetscBenchSetUp(bm));
161   PetscCall(PetscLogHandlerStart(bm->lhdlr));
162   PetscTryTypeMethod(bm, run);
163   PetscCall(PetscLogHandlerStop(bm->lhdlr));
164   PetscFunctionReturn(PETSC_SUCCESS);
165 }
166 
167 /*@
168   PetscBenchSetFromOptions - Sets options to a `PetscBench` using the options database
169 
170   Collective
171 
172   Input Parameter:
173 . bm - the `PetscBench`
174 
175   Level: advanced
176 
177 .seealso: `PetscBench`, `PetscBenchView()`, `PetscBenchRun()`, `PetscBenchCreate()`, `PetscBenchDestroy()`, `PetscBenchSetUp()`, `PetscBenchSetType()`,
178           `PetscBenchSetSize()`, `PetscBenchGetSize()`
179 @*/
180 PetscErrorCode PetscBenchSetFromOptions(PetscBench bm)
181 {
182   char      type[256];
183   PetscBool flg;
184   PetscInt  m;
185 
186   PetscFunctionBegin;
187   PetscValidHeaderSpecific(bm, BM_CLASSID, 1);
188   PetscObjectOptionsBegin((PetscObject)bm);
189   PetscCall(PetscOptionsFList("-bm_type", "PetscBench", "PetscBenchSetType", PetscBenchList, ((PetscObject)bm)->type_name, type, sizeof(type), &flg));
190   if (flg) { PetscCall(PetscBenchSetType(bm, type)); }
191   PetscCheck(((PetscObject)bm)->type_name, PetscObjectComm((PetscObject)bm), PETSC_ERR_ARG_WRONGSTATE, "No PetscBenchType provided for PetscBench");
192   PetscCall(PetscOptionsInt("-bm_size", "Size of benchmark", "PetscBenchSetSize", bm->size, &m, &flg));
193   if (flg) PetscCall(PetscBenchSetSize(bm, m));
194   PetscTryTypeMethod(bm, setfromoptions, PetscOptionsObject);
195   PetscOptionsEnd();
196   PetscFunctionReturn(PETSC_SUCCESS);
197 }
198 
199 /*@C
200   PetscBenchView - Views a PETSc benchmark `PetscBench`
201 
202   Collective
203 
204   Input Parameters:
205 + bm     - the `PetscBench`
206 - viewer - location to view `bm`
207 
208   Level: advanced
209 
210 .seealso: `PetscBench`, `PetscBenchSetFromOptions()`, `PetscBenchRun()`, `PetscBenchCreate()`, `PetscBenchDestroy()`, `PetscBenchSetUp()`, `PetscBenchSetType()`,
211           `PetscBenchSetSize()`, `PetscBenchGetSize()`, `PetscBenchViewFromOptions()`
212 @*/
213 PetscErrorCode PetscBenchView(PetscBench bm, PetscViewer viewer)
214 {
215   PetscFunctionBegin;
216   PetscValidHeaderSpecific(bm, BM_CLASSID, 1);
217   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
218   PetscTryTypeMethod(bm, view, viewer);
219   PetscFunctionReturn(PETSC_SUCCESS);
220 }
221 
222 /*@C
223   PetscBenchViewFromOptions - Processes command line options to determine if/how a `PetscBench` is to be viewed.
224 
225   Collective
226 
227   Input Parameters:
228 + bm         - the object
229 . bobj       - optional other object that provides prefix (if `NULL` then the prefix in `bm` is used)
230 - optionname - option to activate viewing
231 
232   Level: advanced
233 
234 .seealso: `PetscBench`, `PetscBenchSetFromOptions()`, `PetscBenchRun()`, `PetscBenchCreate()`, `PetscBenchDestroy()`, `PetscBenchSetUp()`, `PetscBenchSetType()`,
235           `PetscBenchSetSize()`, `PetscBenchGetSize()`
236 @*/
237 PetscErrorCode PetscBenchViewFromOptions(PetscBench bm, PetscObject bobj, const char optionname[])
238 {
239   PetscFunctionBegin;
240   PetscValidHeaderSpecific(bm, BM_CLASSID, 1);
241   PetscCall(PetscObjectViewFromOptions((PetscObject)bm, bobj, optionname));
242   PetscFunctionReturn(PETSC_SUCCESS);
243 }
244 
245 /*@C
246   PetscBenchCreate - Create a PETSc benchmark `PetscBench` object
247 
248   Collective
249 
250   Input Parameter:
251 . comm - communicator to share the `PetscBench`
252 
253   Output Parameter:
254 . bm - the `PetscBench`
255 
256   Level: advanced
257 
258 .seealso: `PetscBench`, `PetscBenchSetFromOptions()`, `PetscBenchRun()`, `PetscBenchViewFromOptions()`, `PetscBenchDestroy()`, `PetscBenchSetUp()`, `PetscBenchSetType()`,
259           `PetscBenchSetSize()`, `PetscBenchGetSize()`
260 @*/
261 PetscErrorCode PetscBenchCreate(MPI_Comm comm, PetscBench *bm)
262 {
263   PetscFunctionBegin;
264   PetscAssertPointer(bm, 2);
265   *bm = NULL;
266   PetscCall(PetscBenchInitializePackage());
267   PetscCall(PetscHeaderCreate(*bm, BM_CLASSID, "BM", "PetscBench", "BM", comm, PetscBenchDestroy, PetscBenchView));
268   (*bm)->size = PETSC_DECIDE;
269   PetscFunctionReturn(PETSC_SUCCESS);
270 }
271 
272 /*@C
273   PetscBenchSetOptionsPrefix - Sets the prefix used for searching for all `PetscBench` items in the options database.
274 
275   Logically Collective
276 
277   Input Parameters:
278 + bm  - the `PetscBench`
279 - pre - the prefix to prepend all `PetscBench` option names
280 
281   Level: advanced
282 
283 .seealso: `PetscBench`, `PetscBenchSetFromOptions()`, `PetscBenchRun()`, `PetscBenchViewFromOptions()`, `PetscBenchDestroy()`, `PetscBenchSetUp()`, `PetscBenchSetType()`,
284           `PetscBenchSetSize()`, `PetscBenchGetSize()`
285 @*/
286 PetscErrorCode PetscBenchSetOptionsPrefix(PetscBench bm, const char pre[])
287 {
288   PetscFunctionBegin;
289   PetscValidHeaderSpecific(bm, BM_CLASSID, 1);
290   PetscCall(PetscObjectSetOptionsPrefix((PetscObject)bm, pre));
291   PetscFunctionReturn(PETSC_SUCCESS);
292 }
293 
294 /*@C
295   PetscBenchSetSize - Sets the size of the `PetscBench` benchmark to run
296 
297   Logically Collective
298 
299   Input Parameters:
300 + bm - the `PetscBench`
301 - n  - the size
302 
303   Level: advanced
304 
305 .seealso: `PetscBench`, `PetscBenchSetFromOptions()`, `PetscBenchRun()`, `PetscBenchViewFromOptions()`, `PetscBenchDestroy()`, `PetscBenchSetUp()`, `PetscBenchSetType()`,
306           `PetscBenchSetOptionsPrefix()`, `PetscBenchGetSize()`
307 @*/
308 PetscErrorCode PetscBenchSetSize(PetscBench bm, PetscInt n)
309 {
310   PetscFunctionBegin;
311   PetscValidHeaderSpecific(bm, BM_CLASSID, 1);
312   if (bm->size > 0 && bm->size != n && bm->setupcalled) {
313     PetscCall(PetscBenchReset(bm));
314     bm->setupcalled = PETSC_FALSE;
315   }
316   PetscCheck(n > 0, PetscObjectComm((PetscObject)bm), PETSC_ERR_ARG_OUTOFRANGE, "Illegal value of n. Must be > 0");
317   bm->size = n;
318   PetscFunctionReturn(PETSC_SUCCESS);
319 }
320 
321 /*@C
322   PetscBenchGetSize - Gets the size of the `PetscBench` benchmark to run
323 
324   Logically Collective
325 
326   Input Parameter:
327 . bm - the `PetscBench`
328 
329   Output Parameter:
330 . n - the size
331 
332   Level: advanced
333 
334 .seealso: `PetscBench`, `PetscBenchSetFromOptions()`, `PetscBenchRun()`, `PetscBenchViewFromOptions()`, `PetscBenchDestroy()`, `PetscBenchSetUp()`, `PetscBenchSetType()`,
335           `PetscBenchSetOptionsPrefix()`, `PetscBenchSetSize()`
336 @*/
337 PetscErrorCode PetscBenchGetSize(PetscBench bm, PetscInt *n)
338 {
339   PetscFunctionBegin;
340   PetscValidHeaderSpecific(bm, BM_CLASSID, 1);
341   PetscAssertPointer(n, 2);
342   *n = bm->size;
343   PetscFunctionReturn(PETSC_SUCCESS);
344 }
345 
346 /*@C
347   PetscBenchSetType - set the type of `PetscBench` benchmark to run
348 
349   Collective
350 
351   Input Parameters:
352 + bm   - the `PetscBench`
353 - type - a known method
354 
355   Options Database Key:
356 . -bm_type <type> - Sets `PetscBench` type
357 
358   Level: advanced
359 
360   Developer Note:
361   `PetscBenchRegister()` is used to add new benchmark types
362 
363 .seealso: `PetscBench`, `PetscBenchSetFromOptions()`, `PetscBenchRun()`, `PetscBenchViewFromOptions()`, `PetscBenchDestroy()`, `PetscBenchSetUp()`, `PetscBenchGetSize()`,
364           `PetscBenchSetOptionsPrefix()`, `PetscBenchSetSize()`, `PetscBenchGetType()`, `PetscBenchCreate()`
365 @*/
366 PetscErrorCode PetscBenchSetType(PetscBench bm, PetscBenchType type)
367 {
368   PetscBool match;
369   PetscErrorCode (*r)(PetscBench);
370 
371   PetscFunctionBegin;
372   PetscValidHeaderSpecific(bm, BM_CLASSID, 1);
373   PetscAssertPointer(type, 2);
374 
375   PetscCall(PetscObjectTypeCompare((PetscObject)bm, type, &match));
376   if (match) PetscFunctionReturn(PETSC_SUCCESS);
377 
378   PetscCall(PetscFunctionListFind(PetscBenchList, type, &r));
379   PetscCheck(r, PetscObjectComm((PetscObject)bm), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unable to find requested PetscBench type %s", type);
380   /* Destroy the previous private BM context */
381   PetscTryTypeMethod(bm, destroy);
382   bm->ops->destroy = NULL;
383   bm->data         = NULL;
384 
385   PetscCall(PetscFunctionListDestroy(&((PetscObject)bm)->qlist));
386   /* Reinitialize function pointers in PetscBenchOps structure */
387   PetscCall(PetscMemzero(bm->ops, sizeof(struct _PetscBenchOps)));
388 
389   PetscCall(PetscObjectChangeTypeName((PetscObject)bm, type));
390   PetscCall((*r)(bm));
391   PetscFunctionReturn(PETSC_SUCCESS);
392 }
393 
394 /*@C
395   PetscBenchGetType - Gets the `PetscBenchType` (as a string) from the `PetscBench`
396   context.
397 
398   Not Collective
399 
400   Input Parameter:
401 . bm - the `PetscBench`
402 
403   Output Parameter:
404 . type - name of benchmark method
405 
406   Level: intermediate
407 
408 .seealso: `PetscBench`, `PetscBenchType`, `PetscBenchSetType()`, `PetscBenchCreate()`
409 @*/
410 PetscErrorCode PetscBenchGetType(PetscBench bm, PetscBenchType *type)
411 {
412   PetscFunctionBegin;
413   PetscValidHeaderSpecific(bm, BM_CLASSID, 1);
414   PetscAssertPointer(type, 2);
415   *type = ((PetscObject)bm)->type_name;
416   PetscFunctionReturn(PETSC_SUCCESS);
417 }
418