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 @*/
PetscBenchFinalizePackage(void)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 @*/
PetscBenchInitializePackage(void)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, No Fortran Support
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 @*/
PetscBenchRegister(const char sname[],PetscErrorCode (* function)(PetscBench))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 /*@
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 @*/
PetscBenchReset(PetscBench bm)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 /*@
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 @*/
PetscBenchDestroy(PetscBench * bm)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 @*/
PetscBenchSetUp(PetscBench bm)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 @*/
PetscBenchRun(PetscBench bm)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 @*/
PetscBenchSetFromOptions(PetscBench bm)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 /*@
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 @*/
PetscBenchView(PetscBench bm,PetscViewer viewer)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 /*@
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 @*/
PetscBenchViewFromOptions(PetscBench bm,PetscObject bobj,const char optionname[])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 /*@
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 @*/
PetscBenchCreate(MPI_Comm comm,PetscBench * bm)261 PetscErrorCode PetscBenchCreate(MPI_Comm comm, PetscBench *bm)
262 {
263 PetscFunctionBegin;
264 PetscAssertPointer(bm, 2);
265 PetscCall(PetscBenchInitializePackage());
266
267 PetscCall(PetscHeaderCreate(*bm, BM_CLASSID, "BM", "PetscBench", "BM", comm, PetscBenchDestroy, PetscBenchView));
268 (*bm)->size = PETSC_DECIDE;
269 PetscFunctionReturn(PETSC_SUCCESS);
270 }
271
272 /*@
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 @*/
PetscBenchSetOptionsPrefix(PetscBench bm,const char pre[])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 /*@
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 @*/
PetscBenchSetSize(PetscBench bm,PetscInt n)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 /*@
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 @*/
PetscBenchGetSize(PetscBench bm,PetscInt * n)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 /*@
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 @*/
PetscBenchSetType(PetscBench bm,PetscBenchType type)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 /*@
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 @*/
PetscBenchGetType(PetscBench bm,PetscBenchType * type)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