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