1 /* 2 Contains all error handling interfaces for PETSc. 3 */ 4 #pragma once 5 6 #include <petscmacros.h> 7 #include <petscsystypes.h> 8 9 #if defined(__cplusplus) 10 #include <exception> // std::exception 11 #endif 12 13 /* SUBMANSEC = Sys */ 14 15 #define SETERRQ1(...) PETSC_DEPRECATED_MACRO(3, 17, 0, "SETERRQ", ) SETERRQ(__VA_ARGS__) 16 #define SETERRQ2(...) PETSC_DEPRECATED_MACRO(3, 17, 0, "SETERRQ", ) SETERRQ(__VA_ARGS__) 17 #define SETERRQ3(...) PETSC_DEPRECATED_MACRO(3, 17, 0, "SETERRQ", ) SETERRQ(__VA_ARGS__) 18 #define SETERRQ4(...) PETSC_DEPRECATED_MACRO(3, 17, 0, "SETERRQ", ) SETERRQ(__VA_ARGS__) 19 #define SETERRQ5(...) PETSC_DEPRECATED_MACRO(3, 17, 0, "SETERRQ", ) SETERRQ(__VA_ARGS__) 20 #define SETERRQ6(...) PETSC_DEPRECATED_MACRO(3, 17, 0, "SETERRQ", ) SETERRQ(__VA_ARGS__) 21 #define SETERRQ7(...) PETSC_DEPRECATED_MACRO(3, 17, 0, "SETERRQ", ) SETERRQ(__VA_ARGS__) 22 #define SETERRQ8(...) PETSC_DEPRECATED_MACRO(3, 17, 0, "SETERRQ", ) SETERRQ(__VA_ARGS__) 23 #define SETERRQ9(...) PETSC_DEPRECATED_MACRO(3, 17, 0, "SETERRQ", ) SETERRQ(__VA_ARGS__) 24 25 /*MC 26 SETERRQ - Macro to be called when an error has been detected, 27 28 Synopsis: 29 #include <petscsys.h> 30 PetscErrorCode SETERRQ(MPI_Comm comm, PetscErrorCode ierr, char *message, ...) 31 32 Collective 33 34 Input Parameters: 35 + comm - An MPI communicator, use `PETSC_COMM_SELF` unless you know all ranks of another communicator will detect the error 36 . ierr - nonzero error code, see the list of standard error codes in include/petscerror.h 37 - message - error message 38 39 Level: beginner 40 41 Notes: 42 This is rarely needed, one should use `PetscCheck()` and `PetscCall()` and friends to automatically handle error conditions. 43 Once the error handler is called the calling function is then returned from with the given error code. 44 45 Experienced users can set the error handler with `PetscPushErrorHandler()`. 46 47 Fortran Note: 48 `SETERRQ()` may be called from Fortran subroutines but `SETERRA()` must be called from the 49 Fortran main program. 50 51 .seealso: `PetscCheck()`, `PetscAssert()`, `PetscTraceBackErrorHandler()`, `PetscPushErrorHandler()`, 52 `PetscError()`, `PetscCall()`, `CHKMEMQ`, `CHKERRA()`, `PetscCallMPI()`, `PetscErrorCode` 53 M*/ 54 #define SETERRQ(comm, ierr, ...) \ 55 do { \ 56 PetscErrorCode ierr_seterrq_petsc_ = PetscError(comm, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr, PETSC_ERROR_INITIAL, __VA_ARGS__); \ 57 return ierr_seterrq_petsc_ ? ierr_seterrq_petsc_ : PETSC_ERR_RETURN; \ 58 } while (0) 59 60 #define SETERRQNULL(comm, ierr, ...) \ 61 do { \ 62 (void)PetscError(comm, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr, PETSC_ERROR_INITIAL, __VA_ARGS__); \ 63 return NULL; \ 64 } while (0) 65 66 /* 67 Returned from PETSc functions that are called from MPI, such as related to attributes 68 Do not confuse PETSC_MPI_ERROR_CODE and PETSC_ERR_MPI, the first is registered with MPI and returned to MPI as 69 an error code, the latter is a regular PETSc error code passed within PETSc code indicating an error was detected in an MPI call. 70 */ 71 PETSC_EXTERN PetscMPIInt PETSC_MPI_ERROR_CLASS; 72 PETSC_EXTERN PetscMPIInt PETSC_MPI_ERROR_CODE; 73 74 /*MC 75 SETERRMPI - Macro to be called when an error has been detected within an MPI callback function 76 77 No Fortran Support 78 79 Synopsis: 80 #include <petscsys.h> 81 PetscErrorCode SETERRMPI(MPI_Comm comm, PetscErrorCode ierr, char *message, ...) 82 83 Collective 84 85 Input Parameters: 86 + comm - An MPI communicator, use `PETSC_COMM_SELF` unless you know all ranks of another communicator will detect the error 87 . ierr - nonzero error code, see the list of standard error codes in include/petscerror.h 88 - message - error message 89 90 Level: developer 91 92 Note: 93 This macro is FOR USE IN MPI CALLBACK FUNCTIONS ONLY, such as those passed to `MPI_Comm_create_keyval()`. It always returns the error code `PETSC_MPI_ERROR_CODE` 94 which is registered with `MPI_Add_error_code()` when PETSc is initialized. 95 96 .seealso: `SETERRQ()`, `PetscCall()`, `PetscCallMPI()`, `PetscTraceBackErrorHandler()`, `PetscPushErrorHandler()`, `PetscError()`, `CHKMEMQ`, `PetscErrorCode` 97 M*/ 98 #define SETERRMPI(comm, ierr, ...) return ((void)PetscError(comm, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr, PETSC_ERROR_INITIAL, __VA_ARGS__), PETSC_MPI_ERROR_CODE) 99 100 /*MC 101 SETERRA - Fortran-only macro that can be called when an error has been detected from the main program 102 103 Synopsis: 104 #include <petscsys.h> 105 PetscErrorCode SETERRA(MPI_Comm comm, PetscErrorCode ierr, char *message) 106 107 Collective 108 109 Input Parameters: 110 + comm - An MPI communicator, so that the error can be collective 111 . ierr - nonzero error code, see the list of standard error codes in include/petscerror.h 112 - message - error message in the printf format 113 114 Level: beginner 115 116 Notes: 117 This should only be used with Fortran. With C/C++, use `SETERRQ()`. 118 119 `SETERRQ()` may be called from Fortran subroutines but `SETERRA()` must be called from the 120 Fortran main program. 121 122 .seealso: `SETERRQ()`, `SETERRABORT()`, `PetscCall()`, `CHKERRA()`, `PetscCallAbort()`, `PetscErrorCode` 123 M*/ 124 125 /*MC 126 SETERRABORT - Macro that can be called when an error has been detected, 127 128 Synopsis: 129 #include <petscsys.h> 130 PetscErrorCode SETERRABORT(MPI_Comm comm, PetscErrorCode ierr, char *message, ...) 131 132 Collective 133 134 Input Parameters: 135 + comm - An MPI communicator, so that the error can be collective 136 . ierr - nonzero error code, see the list of standard error codes in include/petscerror.h 137 - message - error message in the printf format 138 139 Level: beginner 140 141 Notes: 142 This function just calls `MPI_Abort()`. 143 144 This should only be called in routines that cannot return an error code, such as in C++ constructors. 145 146 Fortran Note: 147 Use `SETERRA()` in Fortran main program and `SETERRQ()` in Fortran subroutines 148 149 Developer Note: 150 In Fortran `SETERRA()` could be called `SETERRABORT()` since they serve the same purpose 151 152 .seealso: `SETERRQ()`, `PetscTraceBackErrorHandler()`, `PetscPushErrorHandler()`, `PetscError()`, `PetscCall()`, `CHKMEMQ`, `PetscErrorCode` 153 M*/ 154 #define SETERRABORT(comm, ierr, ...) \ 155 do { \ 156 (void)PetscError(comm, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr, PETSC_ERROR_INITIAL, __VA_ARGS__); \ 157 MPI_Abort(comm, ierr); \ 158 } while (0) 159 160 /*MC 161 PetscCheck - Checks that a particular condition is true; if not true, then returns the provided error code 162 163 Synopsis: 164 #include <petscerror.h> 165 void PetscCheck(bool cond, MPI_Comm comm, PetscErrorCode ierr, const char *message, ...) 166 167 Collective; No Fortran Support 168 169 Input Parameters: 170 + cond - The boolean condition 171 . comm - The communicator on which the check can be collective on 172 . ierr - A nonzero error code, see include/petscerror.h for the complete list 173 - message - Error message in printf format 174 175 Level: beginner 176 177 Notes: 178 Enabled in both optimized and debug builds. 179 180 As a general rule, `PetscCheck()` is used to check "usage error" (for example, passing an incorrect value as a function argument), 181 `PetscAssert()` is used to "check for bugs in PETSc" (for example, is a value in a PETSc data structure nonsensical). 182 However, for functions that are called in a "hot spot", for example, thousands of times in a loop, `PetscAssert()` should be used instead 183 of `PetscCheck()` since the former is compiled out in PETSc's optimization code. 184 185 Calls `SETERRQ()` if the assertion fails, so can only be called from functions returning a 186 `PetscErrorCode` (or equivalent type after conversion). 187 188 .seealso: `PetscAssert()`, `SETERRQ()`, `PetscError()`, `PetscCall()`, `PetscCheckAbort()`, `PetscErrorCode` 189 M*/ 190 #define PetscCheck(cond, comm, ierr, ...) \ 191 do { \ 192 if (PetscUnlikely(!(cond))) SETERRQ(comm, ierr, __VA_ARGS__); \ 193 } while (0) 194 195 /*MC 196 PetscCheckAbort - Check that a particular condition is true, otherwise prints error and aborts 197 198 Synopsis: 199 #include <petscerror.h> 200 void PetscCheckAbort(bool cond, MPI_Comm comm, PetscErrorCode ierr, const char *message, ...) 201 202 Collective; No Fortran Support 203 204 Input Parameters: 205 + cond - The boolean condition 206 . comm - The communicator on which the check can be collective on 207 . ierr - A nonzero error code, see include/petscerror.h for the complete list 208 - message - Error message in printf format 209 210 Level: developer 211 212 Notes: 213 Enabled in both optimized and debug builds. 214 215 Calls `SETERRABORT()` if the assertion fails, can be called from a function that does not return an 216 error code, such as a C++ constructor. usually `PetscCheck()` should be used. 217 218 .seealso: `PetscAssertAbort()`, `PetscAssert()`, `SETERRQ()`, `PetscError()`, `PetscCall()`, `PetscCheck()`, `SETERRABORT()`, `PetscErrorCode` 219 M*/ 220 #define PetscCheckAbort(cond, comm, ierr, ...) \ 221 do { \ 222 if (PetscUnlikely(!(cond))) SETERRABORT(comm, ierr, __VA_ARGS__); \ 223 } while (0) 224 225 /*MC 226 PetscAssert - Assert that a particular condition is true 227 228 Synopsis: 229 #include <petscerror.h> 230 void PetscAssert(bool cond, MPI_Comm comm, PetscErrorCode ierr, const char *message, ...) 231 232 Collective; No Fortran Support 233 234 Input Parameters: 235 + cond - The boolean condition 236 . comm - The communicator on which the check can be collective on 237 . ierr - A nonzero error code, see include/petscerror.h for the complete list 238 - message - Error message in `printf()` format 239 240 Level: beginner 241 242 Notes: 243 Equivalent to `PetscCheck()` if debugging is enabled, and `PetscAssume(cond)` otherwise. 244 245 See `PetscCheck()` for usage and behaviour. 246 247 This is needed instead of simply using `assert()` because this correctly handles the collective nature of errors under MPI 248 249 .seealso: `PetscCheck()`, `SETERRQ()`, `PetscError()`, `PetscAssertAbort()`, `PetscErrorCode` 250 M*/ 251 #if PetscDefined(USE_DEBUG) 252 #define PetscAssert(cond, comm, ierr, ...) PetscCheck(cond, comm, ierr, __VA_ARGS__) 253 #else 254 #define PetscAssert(cond, ...) PetscAssume(cond) 255 #endif 256 257 /*MC 258 PetscAssertAbort - Assert that a particular condition is true, otherwise prints error and aborts 259 260 Synopsis: 261 #include <petscerror.h> 262 void PetscAssertAbort(bool cond, MPI_Comm comm, PetscErrorCode ierr, const char *message, ...) 263 264 Collective; No Fortran Support 265 266 Input Parameters: 267 + cond - The boolean condition 268 . comm - The communicator on which the check can be collective on 269 . ierr - A nonzero error code, see include/petscerror.h for the complete list 270 - message - Error message in printf format 271 272 Level: beginner 273 274 Note: 275 Enabled only in debug builds. See `PetscCheckAbort()` for usage. 276 277 .seealso: `PetscCheckAbort()`, `PetscAssert()`, `PetscCheck()`, `SETERRABORT()`, `PetscError()` 278 M*/ 279 #if PetscDefined(USE_DEBUG) 280 #define PetscAssertAbort(cond, comm, ierr, ...) PetscCheckAbort(cond, comm, ierr, __VA_ARGS__) 281 #else 282 #define PetscAssertAbort(cond, comm, ierr, ...) PetscAssume(cond) 283 #endif 284 285 /*MC 286 PetscCall - Calls a PETSc function and then checks the resulting error code, if it is 287 non-zero it calls the error handler and returns from the current function with the error 288 code. 289 290 Synopsis: 291 #include <petscerror.h> 292 void PetscCall(PetscFunction(args)) 293 294 Not Collective 295 296 Input Parameter: 297 . PetscFunction - any PETSc function that returns an error code 298 299 Level: beginner 300 301 Notes: 302 Once the error handler is called the calling function is then returned from with the given 303 error code. Experienced users can set the error handler with `PetscPushErrorHandler()`. 304 305 `PetscCall()` cannot be used in functions returning a datatype not convertible to 306 `PetscErrorCode`. For example, `PetscCall()` may not be used in functions returning `void`, use 307 `PetscCallAbort()` or `PetscCallVoid()` in this case. 308 309 Example Usage: 310 .vb 311 PetscCall(PetscInitiailize(...)); // OK to call even when PETSc is not yet initialized! 312 313 struct my_struct 314 { 315 void *data; 316 } my_complex_type; 317 318 struct my_struct bar(void) 319 { 320 PetscCall(foo(15)); // ERROR PetscErrorCode not convertible to struct my_struct! 321 } 322 323 PetscCall(bar()) // ERROR input not convertible to PetscErrorCode 324 .ve 325 326 It is also possible to call this directly on a `PetscErrorCode` variable 327 .vb 328 PetscCall(ierr); // check if ierr is nonzero 329 .ve 330 331 Should not be used to call callback functions provided by users, `PetscCallBack()` should be used in that situation. 332 333 `PetscUseTypeMethod()` or `PetscTryTypeMethod()` should be used when calling functions pointers contained in a PETSc object's `ops` array 334 335 Fortran Notes: 336 The Fortran function in which this is used must declare a `PetscErrorCode` variable necessarily named `ierr`, and `ierr` must be 337 the final argument to the PETSc function being called. 338 339 In the main program and in Fortran subroutines that do not have `ierr` as the final return parameter, one 340 should use `PetscCallA()` 341 342 Example Fortran Usage: 343 .vb 344 PetscErrorCode ierr 345 Vec v 346 347 ... 348 PetscCall(VecShift(v, 1.0, ierr)) 349 PetscCallA(VecShift(v, 1.0, ierr)) 350 .ve 351 352 .seealso: `SETERRQ()`, `PetscCheck()`, `PetscAssert()`, `PetscTraceBackErrorHandler()`, `PetscCallMPI()`, 353 `PetscPushErrorHandler()`, `PetscError()`, `CHKMEMQ`, `CHKERRA()`, 354 `CHKERRMPI()`, `PetscCallBack()`, `PetscCallAbort()`, `PetscCallVoid()`, `PetscCallNull()` 355 M*/ 356 357 /*MC 358 PetscCallNull - Calls a PETSc function and then checks the resulting error code, if it is 359 non-zero it calls the error handler and returns a `NULL` 360 361 Synopsis: 362 #include <petscerror.h> 363 void PetscCallNull(PetscFunction(args)) 364 365 Not Collective; No Fortran Support 366 367 Input Parameter: 368 . PetscFunction - any PETSc function that returns something that can be returned as a `NULL` 369 370 Level: developer 371 372 .seealso: `PetscCall()`, `SETERRQ()`, `PetscCheck()`, `PetscAssert()`, `PetscTraceBackErrorHandler()`, `PetscCallMPI()`, 373 `PetscPushErrorHandler()`, `PetscError()`, `CHKMEMQ`, `CHKERRA()`, 374 `CHKERRMPI()`, `PetscCallBack()`, `PetscCallAbort()`, `PetscCallVoid()`, `PetscCall()` 375 M*/ 376 377 /*MC 378 PetscCallA - Fortran-only macro that should be used in the main program and subroutines that do not have `ierr` as the final return parameter, to call PETSc functions instead of using 379 `PetscCall()` which should be used in other Fortran subroutines 380 381 Synopsis: 382 #include <petscsys.h> 383 PetscErrorCode PetscCallA(PetscFunction(arguments, ierr)) 384 385 Collective 386 387 Input Parameter: 388 . PetscFunction(arguments,ierr) - the call to the function 389 390 Level: beginner 391 392 Notes: 393 This should only be used with Fortran. With C/C++, use `PetscCall()` always. 394 395 The Fortran function in which this is used must declare a `PetscErrorCode` variable necessarily named `ierr` 396 Use `SETERRA()` to set an error in a Fortran main program and `SETERRQ()` in Fortran subroutines 397 398 .seealso: `SETERRQ()`, `SETERRA()`, `SETERRABORT()`, `PetscCall()`, `CHKERRA()`, `PetscCallAbort()` 399 M*/ 400 401 /*MC 402 PetscCallBack - Calls a user provided PETSc callback function and then checks the resulting error code, if it is non-zero it calls the error 403 handler and returns from the current function with the error code. 404 405 Synopsis: 406 #include <petscerror.h> 407 void PetscCallBack(const char *functionname, PetscFunction(args)) 408 409 Not Collective; No Fortran Support 410 411 Input Parameters: 412 + functionname - the name of the function being called, this can be a string with spaces that describes the meaning of the callback 413 - PetscFunction - user provided callback function that returns an error code 414 415 Example Usage: 416 .vb 417 PetscCallBack("XXX callback to do something", a->callback(...)); 418 .ve 419 420 Level: developer 421 422 Notes: 423 `PetscUseTypeMethod()` and ` PetscTryTypeMethod()` are the preferred API for this functionality. But when the callback functions are associated with a 424 `DMSNES` or `DMTS` this API must be used. 425 426 Once the error handler is called the calling function is then returned from with the given 427 error code. Experienced users can set the error handler with `PetscPushErrorHandler()`. 428 429 `PetscCallBack()` should only be called in PETSc when a call is being made to a user provided call-back routine. 430 431 Developer Note: 432 It would be good to provide a new API for when the callbacks are associated with `DMSNES` or `DMTS` so this routine could be used less 433 434 .seealso: `SETERRQ()`, `PetscCheck()`, `PetscCall()`, `PetscAssert()`, `PetscTraceBackErrorHandler()`, `PetscCallMPI()` 435 `PetscPushErrorHandler()`, `PetscError()`, `CHKMEMQ`, `CHKERRA()`, `CHKERRMPI()`, `PetscCall()`, `PetscUseTypeMethod()`, `PetscTryTypeMethod()` 436 M*/ 437 438 /*MC 439 PetscCallVoid - Like `PetscCall()` but for use in functions that return `void` 440 441 Synopsis: 442 #include <petscerror.h> 443 void PetscCallVoid(PetscFunction(args)) 444 445 Not Collective; No Fortran Support 446 447 Input Parameter: 448 . PetscFunction - any PETSc function that returns an error code 449 450 Example Usage: 451 .vb 452 void foo() 453 { 454 KSP ksp; 455 456 PetscFunctionBeginUser; 457 // OK, properly handles PETSc error codes 458 PetscCallVoid(KSPCreate(PETSC_COMM_WORLD, &ksp)); 459 PetscFunctionReturnVoid(); 460 } 461 462 PetscErrorCode bar() 463 { 464 KSP ksp; 465 466 PetscFunctionBeginUser; 467 // ERROR, Non-void function 'bar' should return a value 468 PetscCallVoid(KSPCreate(PETSC_COMM_WORLD, &ksp)); 469 // OK, returning PetscErrorCode 470 PetscCall(KSPCreate(PETSC_COMM_WORLD, &ksp)); 471 PetscFunctionReturn(PETSC_SUCCESS); 472 } 473 .ve 474 475 Level: beginner 476 477 Notes: 478 Has identical usage to `PetscCall()`, except that it returns `void` on error instead of a 479 `PetscErrorCode`. See `PetscCall()` for more detailed discussion. 480 481 Note that users should prefer `PetscCallAbort()` to this routine. While this routine does 482 "handle" errors by returning from the enclosing function, it effectively gobbles the 483 error. Since the enclosing function itself returns `void`, its callers have no way of knowing 484 that the routine returned early due to an error. `PetscCallAbort()` at least ensures that the 485 program crashes gracefully. 486 487 .seealso: `PetscCall()`, `PetscErrorCode`, `PetscCallAbort()`, `PetscCallNull()` 488 M*/ 489 #if defined(PETSC_CLANG_STATIC_ANALYZER) 490 void PetscCall(PetscErrorCode); 491 void PetscCallBack(const char *, PetscErrorCode); 492 void PetscCallVoid(PetscErrorCode); 493 void PetscCallNull(PetscErrorCode); 494 #else 495 #define PetscCall(...) \ 496 do { \ 497 PetscErrorCode ierr_petsc_call_q_; \ 498 PetscStackUpdateLine; \ 499 ierr_petsc_call_q_ = __VA_ARGS__; \ 500 if (PetscUnlikely(ierr_petsc_call_q_ != PETSC_SUCCESS)) return PetscError(PETSC_COMM_SELF, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr_petsc_call_q_, PETSC_ERROR_REPEAT, " "); \ 501 } while (0) 502 #define PetscCallNull(...) \ 503 do { \ 504 PetscErrorCode ierr_petsc_call_q_; \ 505 PetscStackUpdateLine; \ 506 ierr_petsc_call_q_ = __VA_ARGS__; \ 507 if (PetscUnlikely(ierr_petsc_call_q_ != PETSC_SUCCESS)) { \ 508 (void)PetscError(PETSC_COMM_SELF, __LINE__, PETSC_FUNCTION_NAME, __FILE__, PETSC_ERR_PLIB, PETSC_ERROR_INITIAL, " "); \ 509 PetscFunctionReturn(NULL); \ 510 } \ 511 } while (0) 512 #define PetscCallBack(function, ...) \ 513 do { \ 514 PetscErrorCode ierr_petsc_call_q_; \ 515 PetscStackUpdateLine; \ 516 PetscStackPushExternal(function); \ 517 ierr_petsc_call_q_ = __VA_ARGS__; \ 518 PetscStackPop; \ 519 if (PetscUnlikely(ierr_petsc_call_q_ != PETSC_SUCCESS)) return PetscError(PETSC_COMM_SELF, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr_petsc_call_q_, PETSC_ERROR_REPEAT, " "); \ 520 } while (0) 521 #define PetscCallVoid(...) \ 522 do { \ 523 PetscErrorCode ierr_petsc_call_void_; \ 524 PetscStackUpdateLine; \ 525 ierr_petsc_call_void_ = __VA_ARGS__; \ 526 if (PetscUnlikely(ierr_petsc_call_void_ != PETSC_SUCCESS)) { \ 527 ierr_petsc_call_void_ = PetscError(PETSC_COMM_SELF, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr_petsc_call_void_, PETSC_ERROR_REPEAT, " "); \ 528 (void)ierr_petsc_call_void_; \ 529 return; \ 530 } \ 531 } while (0) 532 #endif 533 534 /*MC 535 CHKERRQ - Checks error code returned from PETSc function 536 537 Synopsis: 538 #include <petscsys.h> 539 void CHKERRQ(PetscErrorCode ierr) 540 541 Not Collective 542 543 Input Parameter: 544 . ierr - nonzero error code 545 546 Level: deprecated 547 548 Note: 549 Deprecated in favor of `PetscCall()`. This routine behaves identically to it. 550 551 .seealso: `PetscCall()` 552 M*/ 553 #define CHKERRQ(...) PetscCall(__VA_ARGS__) 554 #define CHKERRV(...) PetscCallVoid(__VA_ARGS__) 555 556 PETSC_EXTERN void PetscMPIErrorString(PetscMPIInt, size_t, char *); 557 558 /*MC 559 PetscCallMPI - Checks error code returned from MPI calls, if non-zero it calls the error 560 handler and then returns a `PetscErrorCode` 561 562 Synopsis: 563 #include <petscerror.h> 564 void PetscCallMPI(MPI_Function(args)) 565 566 Not Collective 567 568 Input Parameter: 569 . MPI_Function - an MPI function that returns an MPI error code 570 571 Level: beginner 572 573 Notes: 574 Always returns the error code `PETSC_ERR_MPI`; the MPI error code and string are embedded in 575 the string error message. Do not use this to call any other routines (for example PETSc 576 routines), it should only be used for direct MPI calls. The user may configure PETSc with the 577 `--with-strict-petscerrorcode` option to check this at compile-time, otherwise they must 578 check this themselves. 579 580 This routine can only be used in functions returning `PetscErrorCode` themselves. If the 581 calling function returns a different type, use `PetscCallMPIAbort()` instead. 582 583 Example Usage: 584 .vb 585 PetscCallMPI(MPI_Comm_size(...)); // OK, calling MPI function 586 587 PetscCallMPI(PetscFunction(...)); // ERROR, use PetscCall() instead! 588 .ve 589 590 Fortran Notes: 591 The Fortran function from which this is used must declare a variable `PetscErrorCode` ierr and ierr must be 592 the final argument to the MPI function being called. 593 594 In the main program and in Fortran subroutines that do not have ierr as the final return parameter one 595 should use `PetscCallMPIA()` 596 597 Fortran Usage: 598 .vb 599 PetscErrorCode ierr or integer ierr 600 ... 601 PetscCallMPI(MPI_Comm_size(...,ierr)) 602 PetscCallMPIA(MPI_Comm_size(...,ierr)) ! Will abort after calling error handler 603 604 PetscCallMPI(MPI_Comm_size(...,eflag)) ! ERROR, final argument must be ierr 605 .ve 606 607 .seealso: `SETERRMPI()`, `PetscCall()`, `SETERRQ()`, `SETERRABORT()`, `PetscCallAbort()`, 608 `PetscCallMPIAbort()`, `PetscTraceBackErrorHandler()`, `PetscPushErrorHandler()`, 609 `PetscError()`, `CHKMEMQ`, `PetscCallMPINull()` 610 M*/ 611 612 /*MC 613 PetscCallMPINull - Checks error code returned from MPI calls, if non-zero it calls the error 614 handler and then returns a `NULL` 615 616 Synopsis: 617 #include <petscerror.h> 618 void PetscCallMPINull(MPI_Function(args)) 619 620 Not Collective; No Fortran Support 621 622 Input Parameter: 623 . MPI_Function - an MPI function that returns an MPI error code 624 625 Level: beginner 626 627 Notes: 628 Always passes the error code `PETSC_ERR_MPI` to the error handler `PetscError()`; the MPI error code and string are embedded in 629 the string error message. Do not use this to call any other routines (for example PETSc 630 routines), it should only be used for direct MPI calls. 631 632 This routine can only be used in functions returning anything that can be returned as a `NULL` themselves. If the 633 calling function returns a different type, use `PetscCallMPIAbort()` instead. 634 635 Example Usage: 636 .vb 637 PetscCallMPINull(MPI_Comm_size(...)); // OK, calling MPI function 638 639 PetscCallMPI(PetscFunction(...)); // ERROR, use PetscCall() instead! 640 .ve 641 642 .seealso: `SETERRMPI()`, `PetscCall()`, `SETERRQ()`, `SETERRABORT()`, `PetscCallAbort()`, 643 `PetscCallMPIAbort()`, `PetscTraceBackErrorHandler()`, `PetscPushErrorHandler()`, 644 `PetscError()`, `CHKMEMQ`, `PetscCallMPI()` 645 M*/ 646 647 /*MC 648 PetscCallMPIAbort - Like `PetscCallMPI()` but calls `MPI_Abort()` on error 649 650 Synopsis: 651 #include <petscerror.h> 652 void PetscCallMPIAbort(MPI_Comm comm, MPI_Function(args)) 653 654 Not Collective 655 656 Input Parameters: 657 + comm - the MPI communicator to abort on 658 - MPI_Function - an MPI function that returns an MPI error code 659 660 Level: beginner 661 662 Notes: 663 Usage is identical to `PetscCallMPI()`. See `PetscCallMPI()` for detailed discussion. 664 665 This routine may be used in functions returning `void` or other non-`PetscErrorCode` types. 666 667 Fortran Note: 668 In Fortran this is called `PetscCallMPIA()` and is intended to be used in the main program while `PetscCallMPI()` is 669 used in Fortran subroutines. 670 671 Developer Note: 672 This should have the same name in Fortran. 673 674 .seealso: `PetscCallMPI()`, `PetscCallAbort()`, `SETERRABORT()` 675 M*/ 676 #if defined(PETSC_CLANG_STATIC_ANALYZER) 677 void PetscCallMPI(PetscMPIInt); 678 void PetscCallMPIAbort(MPI_Comm, PetscMPIInt); 679 void PetscCallMPINull(PetscMPIInt); 680 #else 681 #define PetscCallMPI_Private(__PETSC_STACK_POP_FUNC__, __SETERR_FUNC__, __COMM__, ...) \ 682 do { \ 683 PetscMPIInt ierr_petsc_call_mpi_; \ 684 PetscStackUpdateLine; \ 685 PetscStackPushExternal("MPI function"); \ 686 { \ 687 ierr_petsc_call_mpi_ = __VA_ARGS__; \ 688 } \ 689 __PETSC_STACK_POP_FUNC__; \ 690 if (PetscUnlikely(ierr_petsc_call_mpi_ != MPI_SUCCESS)) { \ 691 char petsc_mpi_7_errorstring[2 * MPI_MAX_ERROR_STRING]; \ 692 PetscMPIErrorString(ierr_petsc_call_mpi_, 2 * MPI_MAX_ERROR_STRING, (char *)petsc_mpi_7_errorstring); \ 693 __SETERR_FUNC__(__COMM__, PETSC_ERR_MPI, "MPI error %d %s", ierr_petsc_call_mpi_, petsc_mpi_7_errorstring); \ 694 } \ 695 } while (0) 696 697 #define PetscCallMPI(...) PetscCallMPI_Private(PetscStackPop, SETERRQ, PETSC_COMM_SELF, __VA_ARGS__) 698 #define PetscCallMPIAbort(comm, ...) PetscCallMPI_Private(PetscStackPopNoCheck(PETSC_FUNCTION_NAME), SETERRABORT, comm, __VA_ARGS__) 699 #define PetscCallMPINull(...) PetscCallMPI_Private(PetscStackPopNoCheck(PETSC_FUNCTION_NAME), SETERRQNULL, PETSC_COMM_SELF, __VA_ARGS__) 700 #endif 701 702 /*MC 703 CHKERRMPI - Checks error code returned from MPI calls, if non-zero it calls the error 704 handler and then returns 705 706 Synopsis: 707 #include <petscerror.h> 708 void CHKERRMPI(PetscErrorCode ierr) 709 710 Not Collective 711 712 Input Parameter: 713 . ierr - nonzero error code, see the list of standard error codes in include/petscerror.h 714 715 Level: deprecated 716 717 Note: 718 Deprecated in favor of `PetscCallMPI()`. This routine behaves identically to it. 719 720 .seealso: `PetscCallMPI()` 721 M*/ 722 #define CHKERRMPI(...) PetscCallMPI(__VA_ARGS__) 723 724 /*MC 725 PetscCallAbort - Checks error code returned from PETSc function, if non-zero it aborts immediately by calling `MPI_Abort()` 726 727 Synopsis: 728 #include <petscerror.h> 729 void PetscCallAbort(MPI_Comm comm, PetscErrorCode ierr) 730 731 Collective 732 733 Input Parameters: 734 + comm - the MPI communicator on which to abort 735 - ierr - nonzero error code, see the list of standard error codes in include/petscerror.h 736 737 Level: intermediate 738 739 Notes: 740 This macro has identical type and usage semantics to `PetscCall()` with the important caveat 741 that this macro does not return. Instead, if ierr is nonzero it calls the PETSc error handler 742 and then immediately calls `MPI_Abort()`. It can therefore be used anywhere. 743 744 As per `MPI_Abort()` semantics the communicator passed must be valid, although there is currently 745 no attempt made at handling any potential errors from `MPI_Abort()`. Note that while 746 `MPI_Abort()` is required to terminate only those processes which reside on comm, it is often 747 the case that `MPI_Abort()` terminates *all* processes. 748 749 Example Usage: 750 .vb 751 PetscErrorCode boom(void) { return PETSC_ERR_MEM; } 752 753 void foo(void) 754 { 755 PetscCallAbort(PETSC_COMM_WORLD,boom()); // OK, does not return a type 756 } 757 758 double bar(void) 759 { 760 PetscCallAbort(PETSC_COMM_WORLD,boom()); // OK, does not return a type 761 } 762 763 PetscCallAbort(MPI_COMM_NULL,boom()); // ERROR, communicator should be valid 764 765 struct baz 766 { 767 baz() 768 { 769 PetscCallAbort(PETSC_COMM_SELF,boom()); // OK 770 } 771 772 ~baz() 773 { 774 PetscCallAbort(PETSC_COMM_SELF,boom()); // OK (in fact the only way to handle PETSc errors) 775 } 776 }; 777 .ve 778 779 Fortran Note: 780 Use `PetscCallA()`. 781 782 Developer Note: 783 This should have the same name in Fortran as in C. 784 785 .seealso: `SETERRABORT()`, `PetscTraceBackErrorHandler()`, `PetscPushErrorHandler()`, `PetscError()`, 786 `SETERRQ()`, `CHKMEMQ`, `PetscCallMPI()`, `PetscCallCXXAbort()` 787 M*/ 788 #if defined(PETSC_CLANG_STATIC_ANALYZER) 789 void PetscCallAbort(MPI_Comm, PetscErrorCode); 790 void PetscCallContinue(PetscErrorCode); 791 #else 792 #define PetscCallAbort(comm, ...) \ 793 do { \ 794 PetscErrorCode ierr_petsc_call_abort_; \ 795 PetscStackUpdateLine; \ 796 ierr_petsc_call_abort_ = __VA_ARGS__; \ 797 if (PetscUnlikely(ierr_petsc_call_abort_ != PETSC_SUCCESS)) { \ 798 ierr_petsc_call_abort_ = PetscError(PETSC_COMM_SELF, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr_petsc_call_abort_, PETSC_ERROR_REPEAT, " "); \ 799 (void)MPI_Abort(comm, (PetscMPIInt)ierr_petsc_call_abort_); \ 800 } \ 801 } while (0) 802 #define PetscCallContinue(...) \ 803 do { \ 804 PetscErrorCode ierr_petsc_call_continue_; \ 805 PetscStackUpdateLine; \ 806 ierr_petsc_call_continue_ = __VA_ARGS__; \ 807 if (PetscUnlikely(ierr_petsc_call_continue_ != PETSC_SUCCESS)) { \ 808 ierr_petsc_call_continue_ = PetscError(PETSC_COMM_SELF, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr_petsc_call_continue_, PETSC_ERROR_REPEAT, " "); \ 809 (void)ierr_petsc_call_continue_; \ 810 } \ 811 } while (0) 812 #endif 813 814 /*MC 815 CHKERRABORT - Checks error code returned from PETSc function. If non-zero it aborts immediately. 816 817 Synopsis: 818 #include <petscerror.h> 819 void CHKERRABORT(MPI_Comm comm, PetscErrorCode ierr) 820 821 Not Collective 822 823 Input Parameters: 824 + comm - the MPI communicator 825 - ierr - nonzero error code, see the list of standard error codes in include/petscerror.h 826 827 Level: deprecated 828 829 Note: 830 Deprecated in favor of `PetscCallAbort()`. This routine behaves identically to it. 831 832 .seealso: `PetscCallAbort()`, `PetscErrorCode` 833 M*/ 834 #define CHKERRABORT(comm, ...) PetscCallAbort(comm, __VA_ARGS__) 835 #define CHKERRCONTINUE(...) PetscCallContinue(__VA_ARGS__) 836 837 /*MC 838 CHKERRA - Fortran-only replacement for use of `CHKERRQ()` in the main program, which aborts immediately 839 840 Synopsis: 841 #include <petscsys.h> 842 PetscErrorCode CHKERRA(PetscErrorCode ierr) 843 844 Not Collective 845 846 Input Parameter: 847 . ierr - nonzero error code, see the list of standard error codes in include/petscerror.h 848 849 Level: deprecated 850 851 Note: 852 This macro is rarely needed, normal usage is `PetscCallA()` in the main Fortran program. 853 854 Developer Note: 855 Why isn't this named `CHKERRABORT()` in Fortran? 856 857 .seealso: `PetscCall()`, `PetscCallA()`, `PetscCallAbort()`, `CHKERRQ()`, `SETERRA()`, `SETERRQ()`, `SETERRABORT()` 858 M*/ 859 860 PETSC_EXTERN PetscBool petscwaitonerrorflg; 861 PETSC_EXTERN PetscBool petscindebugger; 862 PETSC_EXTERN PetscBool petscabortmpifinalize; 863 864 /*MC 865 PETSCABORT - Call `MPI_Abort()` with an informative error code 866 867 Synopsis: 868 #include <petscsys.h> 869 PETSCABORT(MPI_Comm comm, PetscErrorCode ierr) 870 871 Collective; No Fortran Support 872 873 Input Parameters: 874 + comm - An MPI communicator, so that the error can be collective 875 - ierr - nonzero error code, see the list of standard error codes in include/petscerror.h 876 877 Level: advanced 878 879 Notes: 880 If the option `-start_in_debugger` was used then this calls `abort()` to stop the program in the debugger. 881 882 if `PetscCIEnabledPortableErrorOutput` is set, which means the code is running in the PETSc test harness (make test), 883 and `comm` is `MPI_COMM_WORLD` it strives to exit cleanly without calling `MPI_Abort()` and instead calling `MPI_Finalize()`. 884 885 This is currently only used when an error propagates up to the C `main()` program and is detected by a `PetscCall()`, `PetscCallMPI()`, 886 or is set in `main()` with `SETERRQ()`. Abort calls such as `SETERRABORT()`, 887 `PetscCheckAbort()`, `PetscCallMPIAbort()`, and `PetscCallAbort()` always call `MPI_Abort()` and do not have any special 888 handling for the test harness. 889 890 Developer Note: 891 Should the other abort calls also pass through this call instead of calling `MPI_Abort()` directly? 892 893 .seealso: `PetscError()`, `PetscCall()`, `SETERRABORT()`, `PetscCheckAbort()`, `PetscCallMPIAbort()`, `PetscCall()`, `PetscCallMPI()`, 894 `PetscCallAbort()`, `MPI_Abort()`, `PetscErrorCode` 895 M*/ 896 #if defined(PETSC_CLANG_STATIC_ANALYZER) 897 void PETSCABORT(MPI_Comm, PetscErrorCode); 898 #else 899 #define PETSCABORT(comm, ...) \ 900 do { \ 901 PetscErrorCode ierr_petsc_abort_; \ 902 if (petscwaitonerrorflg) { ierr_petsc_abort_ = PetscSleep(1000); } \ 903 if (petscindebugger) { \ 904 abort(); \ 905 } else { \ 906 PetscMPIInt size_; \ 907 ierr_petsc_abort_ = __VA_ARGS__; \ 908 MPI_Comm_size(comm, &size_); \ 909 if (PetscCIEnabledPortableErrorOutput && (size_ == PetscGlobalSize || petscabortmpifinalize) && ierr_petsc_abort_ != PETSC_ERR_SIG) { \ 910 MPI_Finalize(); \ 911 exit(0); \ 912 } else if (PetscCIEnabledPortableErrorOutput && PetscGlobalSize == 1) { \ 913 exit(0); \ 914 } else { \ 915 MPI_Abort(comm, (PetscMPIInt)ierr_petsc_abort_); \ 916 } \ 917 } \ 918 } while (0) 919 #endif 920 921 #ifdef PETSC_CLANGUAGE_CXX 922 /*MC 923 PetscCallThrow - Checks error code, if non-zero it calls the C++ error handler which throws 924 an exception 925 926 Synopsis: 927 #include <petscerror.h> 928 void PetscCallThrow(PetscErrorCode ierr) 929 930 Not Collective 931 932 Input Parameter: 933 . ierr - nonzero error code, see the list of standard error codes in include/petscerror.h 934 935 Level: beginner 936 937 Notes: 938 Requires PETSc to be configured with clanguage of c++. Throws a std::runtime_error() on error. 939 940 Once the error handler throws the exception you can use `PetscCallVoid()` which returns without 941 an error code (bad idea since the error is ignored) or `PetscCallAbort()` to have `MPI_Abort()` 942 called immediately. 943 944 .seealso: `SETERRQ()`, `PetscCall()`, `SETERRABORT()`, `PetscCallAbort()`, `PetscTraceBackErrorHandler()`, 945 `PetscPushErrorHandler()`, `PetscError()`, `CHKMEMQ` 946 M*/ 947 #define PetscCallThrow(...) \ 948 do { \ 949 PetscStackUpdateLine; \ 950 PetscErrorCode ierr_petsc_call_throw_ = __VA_ARGS__; \ 951 if (PetscUnlikely(ierr_petsc_call_throw_ != PETSC_SUCCESS)) PetscError(PETSC_COMM_SELF, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr_petsc_call_throw_, PETSC_ERROR_IN_CXX, PETSC_NULLPTR); \ 952 } while (0) 953 954 /*MC 955 CHKERRXX - Checks error code, if non-zero it calls the C++ error handler which throws an exception 956 957 Synopsis: 958 #include <petscerror.h> 959 void CHKERRXX(PetscErrorCode ierr) 960 961 Not Collective 962 963 Input Parameter: 964 . ierr - nonzero error code, see the list of standard error codes in include/petscerror.h 965 966 Level: deprecated 967 968 Note: 969 Deprecated in favor of `PetscCallThrow()`. This routine behaves identically to it. 970 971 .seealso: `PetscCallThrow()` 972 M*/ 973 #define CHKERRXX(...) PetscCallThrow(__VA_ARGS__) 974 #endif 975 976 #define PetscCallCXX_Private(__SETERR_FUNC__, __COMM__, ...) \ 977 do { \ 978 PetscStackUpdateLine; \ 979 try { \ 980 __VA_ARGS__; \ 981 } catch (const std::exception &e) { \ 982 __SETERR_FUNC__(__COMM__, PETSC_ERR_LIB, "%s", e.what()); \ 983 } \ 984 } while (0) 985 986 /*MC 987 PetscCallCXX - Checks C++ function calls and if they throw an exception, catch it and then 988 return a PETSc error code 989 990 Synopsis: 991 #include <petscerror.h> 992 void PetscCallCXX(...) noexcept; 993 994 Not Collective 995 996 Input Parameter: 997 . __VA_ARGS__ - An arbitrary expression 998 999 Level: beginner 1000 1001 Notes: 1002 `PetscCallCXX(...)` is a macro replacement for 1003 .vb 1004 try { 1005 __VA_ARGS__; 1006 } catch (const std::exception& e) { 1007 return ConvertToPetscErrorCode(e); 1008 } 1009 .ve 1010 Due to the fact that it catches any (reasonable) exception, it is essentially noexcept. 1011 1012 If you cannot return a `PetscErrorCode` use `PetscCallCXXAbort()` instead. 1013 1014 Example Usage: 1015 .vb 1016 void foo(void) { throw std::runtime_error("error"); } 1017 1018 void bar() 1019 { 1020 PetscCallCXX(foo()); // ERROR bar() does not return PetscErrorCode 1021 } 1022 1023 PetscErrorCode baz() 1024 { 1025 PetscCallCXX(foo()); // OK 1026 1027 PetscCallCXX( 1028 bar(); 1029 foo(); // OK multiple statements allowed 1030 ); 1031 } 1032 1033 struct bop 1034 { 1035 bop() 1036 { 1037 PetscCallCXX(foo()); // ERROR returns PetscErrorCode, cannot be used in constructors 1038 } 1039 }; 1040 1041 // ERROR contains do-while, cannot be used as function-try block 1042 PetscErrorCode qux() PetscCallCXX( 1043 bar(); 1044 baz(); 1045 foo(); 1046 return 0; 1047 ) 1048 .ve 1049 1050 .seealso: `PetscCallCXXAbort()`, `PetscCallThrow()`, `SETERRQ()`, `PetscCall()`, 1051 `SETERRABORT()`, `PetscCallAbort()`, `PetscTraceBackErrorHandler()`, `PetscPushErrorHandler()`, 1052 `PetscError()`, `CHKMEMQ` 1053 M*/ 1054 #define PetscCallCXX(...) PetscCallCXX_Private(SETERRQ, PETSC_COMM_SELF, __VA_ARGS__) 1055 1056 /*MC 1057 PetscCallCXXAbort - Like `PetscCallCXX()` but calls `MPI_Abort()` instead of returning an 1058 error-code 1059 1060 Synopsis: 1061 #include <petscerror.h> 1062 void PetscCallCXXAbort(MPI_Comm comm, ...) noexcept; 1063 1064 Collective; No Fortran Support 1065 1066 Input Parameters: 1067 + comm - The MPI communicator to abort on 1068 - __VA_ARGS__ - An arbitrary expression 1069 1070 Level: beginner 1071 1072 Notes: 1073 This macro may be used to check C++ expressions for exceptions in cases where you cannot 1074 return an error code. This includes constructors, destructors, copy/move assignment functions 1075 or constructors among others. 1076 1077 If an exception is caught, the macro calls `SETERRABORT()` on `comm`. The exception must 1078 derive from `std::exception` in order to be caught. 1079 1080 If the routine _can_ return an error-code it is highly advised to use `PetscCallCXX()` 1081 instead. 1082 1083 See `PetscCallCXX()` for additional discussion. 1084 1085 Example Usage: 1086 .vb 1087 class Foo 1088 { 1089 std::vector<int> data_; 1090 1091 public: 1092 // normally std::vector::reserve() may raise an exception, but since we handle it with 1093 // PetscCallCXXAbort() we may mark this routine as noexcept! 1094 Foo() noexcept 1095 { 1096 PetscCallCXXAbort(PETSC_COMM_SELF, data_.reserve(10)); 1097 } 1098 }; 1099 1100 std::vector<int> bar() 1101 { 1102 std::vector<int> v; 1103 1104 PetscFunctionBegin; 1105 // OK! 1106 PetscCallCXXAbort(PETSC_COMM_SELF, v.emplace_back(1)); 1107 PetscFunctionReturn(v); 1108 } 1109 1110 PetscErrorCode baz() 1111 { 1112 std::vector<int> v; 1113 1114 PetscFunctionBegin; 1115 // WRONG! baz() returns a PetscErrorCode, prefer PetscCallCXX() instead 1116 PetscCallCXXAbort(PETSC_COMM_SELF, v.emplace_back(1)); 1117 PetscFunctionReturn(PETSC_SUCCESS); 1118 } 1119 .ve 1120 1121 .seealso: `PetscCallCXX()`, `SETERRABORT()`, `PetscCallAbort()` 1122 M*/ 1123 #define PetscCallCXXAbort(comm, ...) PetscCallCXX_Private(SETERRABORT, comm, __VA_ARGS__) 1124 1125 /*MC 1126 CHKERRCXX - Checks C++ function calls and if they throw an exception, catch it and then 1127 return a PETSc error code 1128 1129 Synopsis: 1130 #include <petscerror.h> 1131 void CHKERRCXX(func) noexcept; 1132 1133 Not Collective 1134 1135 Input Parameter: 1136 . func - C++ function calls 1137 1138 Level: deprecated 1139 1140 Note: 1141 Deprecated in favor of `PetscCallCXX()`. This routine behaves identically to it. 1142 1143 .seealso: `PetscCallCXX()` 1144 M*/ 1145 #define CHKERRCXX(...) PetscCallCXX(__VA_ARGS__) 1146 1147 /*MC 1148 CHKMEMQ - Checks the memory for corruption, calls error handler if any is detected 1149 1150 Synopsis: 1151 #include <petscsys.h> 1152 CHKMEMQ; 1153 1154 Not Collective 1155 1156 Level: beginner 1157 1158 Notes: 1159 We recommend using Valgrind <https://petsc.org/release/faq/#valgrind> or for NVIDIA CUDA systems 1160 <https://docs.nvidia.com/cuda/cuda-memcheck/index.html> for finding memory problems. The ``CHKMEMQ`` macro is useful on systems that 1161 do not have valgrind, but is not as good as valgrind or cuda-memcheck. 1162 1163 Must run with the option `-malloc_debug` (`-malloc_test` in debug mode; or if `PetscMallocSetDebug()` called) to enable this option 1164 1165 Once the error handler is called the calling function is then returned from with the given error code. 1166 1167 By defaults prints location where memory that is corrupted was allocated. 1168 1169 Use `CHKMEMA` for functions that return `void` 1170 1171 .seealso: `PetscTraceBackErrorHandler()`, `PetscPushErrorHandler()`, `PetscError()`, `SETERRQ()`, `PetscMallocValidate()` 1172 M*/ 1173 #if defined(PETSC_CLANG_STATIC_ANALYZER) 1174 #define CHKMEMQ 1175 #define CHKMEMA 1176 #else 1177 #define CHKMEMQ \ 1178 do { \ 1179 PetscErrorCode ierr_petsc_memq_ = PetscMallocValidate(__LINE__, PETSC_FUNCTION_NAME, __FILE__); \ 1180 if (PetscUnlikely(ierr_petsc_memq_ != PETSC_SUCCESS)) return PetscError(PETSC_COMM_SELF, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr_petsc_memq_, PETSC_ERROR_REPEAT, " "); \ 1181 } while (0) 1182 #define CHKMEMA PetscMallocValidate(__LINE__, PETSC_FUNCTION_NAME, __FILE__) 1183 #endif 1184 1185 /*E 1186 PetscErrorType - passed to the PETSc error handling routines indicating if this is the first or a later call to the error handlers 1187 1188 Level: advanced 1189 1190 Note: 1191 `PETSC_ERROR_IN_CXX` indicates the error was detected in C++ and an exception should be generated 1192 1193 Developer Note: 1194 This is currently used to decide when to print the detailed information about the run in `PetscTraceBackErrorHandler()` 1195 1196 .seealso: `PetscError()`, `SETERRQ()` 1197 E*/ 1198 typedef enum { 1199 PETSC_ERROR_INITIAL = 0, 1200 PETSC_ERROR_REPEAT = 1, 1201 PETSC_ERROR_IN_CXX = 2 1202 } PetscErrorType; 1203 1204 #if defined(__clang_analyzer__) 1205 __attribute__((analyzer_noreturn)) 1206 #endif 1207 PETSC_EXTERN PetscErrorCode 1208 PetscError(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, ...) PETSC_ATTRIBUTE_COLD PETSC_ATTRIBUTE_FORMAT(7, 8); 1209 1210 PETSC_EXTERN PetscErrorCode PetscErrorPrintfInitialize(void); 1211 PETSC_EXTERN PetscErrorCode PetscErrorMessage(PetscErrorCode, const char *[], char **); 1212 PETSC_EXTERN PetscErrorCode PetscTraceBackErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD; 1213 PETSC_EXTERN PetscErrorCode PetscIgnoreErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD; 1214 PETSC_EXTERN PetscErrorCode PetscEmacsClientErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD; 1215 PETSC_EXTERN PetscErrorCode PetscMPIAbortErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD; 1216 PETSC_EXTERN PetscErrorCode PetscAbortErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD; 1217 PETSC_EXTERN PetscErrorCode PetscAttachDebuggerErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD; 1218 PETSC_EXTERN PetscErrorCode PetscReturnErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD; 1219 PETSC_EXTERN PetscErrorCode PetscPushErrorHandler(PetscErrorCode (*handler)(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *), void *); 1220 PETSC_EXTERN PetscErrorCode PetscPopErrorHandler(void); 1221 PETSC_EXTERN PetscErrorCode PetscSignalHandlerDefault(int, void *); 1222 PETSC_EXTERN PetscErrorCode PetscPushSignalHandler(PetscErrorCode (*)(int, void *), void *); 1223 PETSC_EXTERN PetscErrorCode PetscPopSignalHandler(void); 1224 PETSC_EXTERN PetscErrorCode PetscCheckPointerSetIntensity(PetscInt); 1225 PETSC_EXTERN void PetscSignalSegvCheckPointerOrMpi(void); 1226 PETSC_DEPRECATED_FUNCTION(3, 13, 0, "PetscSignalSegvCheckPointerOrMpi()", ) static inline void PetscSignalSegvCheckPointer(void) 1227 { 1228 PetscSignalSegvCheckPointerOrMpi(); 1229 } 1230 1231 /*MC 1232 PetscErrorPrintf - Prints error messages. 1233 1234 Synopsis: 1235 #include <petscsys.h> 1236 PetscErrorCode (*PetscErrorPrintf)(const char format[], ...); 1237 1238 Not Collective; No Fortran Support 1239 1240 Input Parameter: 1241 . format - the usual `printf()` format string 1242 1243 Options Database Keys: 1244 + -error_output_stdout - cause error messages to be printed to stdout instead of the (default) stderr 1245 - -error_output_none - to turn off all printing of error messages (does not change the way the error is handled.) 1246 1247 Level: developer 1248 1249 Notes: 1250 Use 1251 .vb 1252 PetscErrorPrintf = PetscErrorPrintfNone; to turn off all printing of error messages (does not change the way the error is handled) and 1253 PetscErrorPrintf = PetscErrorPrintfDefault; to turn it back on or you can use your own function 1254 .ve 1255 Use 1256 .vb 1257 `PETSC_STDERR` = FILE* obtained from a file open etc. to have stderr printed to the file. 1258 `PETSC_STDOUT` = FILE* obtained from a file open etc. to have stdout printed to the file. 1259 .ve 1260 Use 1261 .vb 1262 `PetscPushErrorHandler()` to provide your own error handler that determines what kind of messages to print 1263 .ve 1264 1265 .seealso: `PetscFPrintf()`, `PetscSynchronizedPrintf()`, `PetscHelpPrintf()`, `PetscPrintf()`, `PetscPushErrorHandler()`, `PetscVFPrintf()`, `PetscHelpPrintf()` 1266 M*/ 1267 PETSC_EXTERN PetscErrorCode (*PetscErrorPrintf)(const char[], ...) PETSC_ATTRIBUTE_FORMAT(1, 2); 1268 1269 /*E 1270 PetscFPTrap - types of floating point exceptions that may be trapped 1271 1272 Currently only `PETSC_FP_TRAP_OFF` and `PETSC_FP_TRAP_ON` are handled. All others are treated as `PETSC_FP_TRAP_ON`. 1273 1274 Level: intermediate 1275 1276 .seealso: `PetscSetFPTrap()`, `PetscFPTrapPush()` 1277 E*/ 1278 typedef enum { 1279 PETSC_FP_TRAP_OFF = 0, 1280 PETSC_FP_TRAP_INDIV = 1, 1281 PETSC_FP_TRAP_FLTOPERR = 2, 1282 PETSC_FP_TRAP_FLTOVF = 4, 1283 PETSC_FP_TRAP_FLTUND = 8, 1284 PETSC_FP_TRAP_FLTDIV = 16, 1285 PETSC_FP_TRAP_FLTINEX = 32 1286 } PetscFPTrap; 1287 #define PETSC_FP_TRAP_ON (PetscFPTrap)(PETSC_FP_TRAP_INDIV | PETSC_FP_TRAP_FLTOPERR | PETSC_FP_TRAP_FLTOVF | PETSC_FP_TRAP_FLTDIV | PETSC_FP_TRAP_FLTINEX) 1288 PETSC_EXTERN PetscErrorCode PetscSetFPTrap(PetscFPTrap); 1289 PETSC_EXTERN PetscErrorCode PetscFPTrapPush(PetscFPTrap); 1290 PETSC_EXTERN PetscErrorCode PetscFPTrapPop(void); 1291 PETSC_EXTERN PetscErrorCode PetscDetermineInitialFPTrap(void); 1292 1293 /* 1294 Allows the code to build a stack frame as it runs 1295 */ 1296 1297 #define PETSCSTACKSIZE 64 1298 typedef struct { 1299 const char *function[PETSCSTACKSIZE]; 1300 const char *file[PETSCSTACKSIZE]; 1301 int line[PETSCSTACKSIZE]; 1302 int petscroutine[PETSCSTACKSIZE]; /* 0 external called from petsc, 1 petsc functions, 2 petsc user functions */ 1303 int currentsize; 1304 int hotdepth; 1305 PetscBool check; /* option to check for correct Push/Pop semantics, true for default petscstack but not other stacks */ 1306 } PetscStack; 1307 #if defined(PETSC_USE_DEBUG) && !defined(PETSC_HAVE_THREADSAFETY) 1308 PETSC_EXTERN PetscStack petscstack; 1309 #endif 1310 1311 #if defined(PETSC_SERIALIZE_FUNCTIONS) 1312 #include <petsc/private/petscfptimpl.h> 1313 /* 1314 Registers the current function into the global function pointer to function name table 1315 1316 Have to fix this to handle errors but cannot return error since used in PETSC_VIEWER_DRAW_() etc 1317 */ 1318 #define PetscRegister__FUNCT__() \ 1319 do { \ 1320 static PetscBool __chked = PETSC_FALSE; \ 1321 if (!__chked) { \ 1322 void *ptr; \ 1323 PetscCallAbort(PETSC_COMM_SELF, PetscDLSym(NULL, PETSC_FUNCTION_NAME, &ptr)); \ 1324 __chked = PETSC_TRUE; \ 1325 } \ 1326 } while (0) 1327 #else 1328 #define PetscRegister__FUNCT__() 1329 #endif 1330 1331 #if defined(PETSC_CLANG_STATIC_ANALYZER) || defined(__clang_analyzer__) 1332 #define PetscStackPushNoCheck(funct, petsc_routine, hot) 1333 #define PetscStackUpdateLine 1334 #define PetscStackPushExternal(funct) 1335 #define PetscStackPopNoCheck 1336 #define PetscStackClearTop 1337 #define PetscFunctionBegin 1338 #define PetscFunctionBeginUser 1339 #define PetscFunctionBeginHot 1340 #define PetscFunctionReturn(...) return __VA_ARGS__ 1341 #define PetscFunctionReturnVoid() return 1342 #define PetscStackPop 1343 #define PetscStackPush(f) 1344 #elif defined(PETSC_USE_DEBUG) && !defined(PETSC_HAVE_THREADSAFETY) 1345 1346 #define PetscStackPush_Private(stack__, file__, func__, line__, petsc_routine__, hot__) \ 1347 do { \ 1348 if (stack__.currentsize < PETSCSTACKSIZE) { \ 1349 stack__.function[stack__.currentsize] = func__; \ 1350 if (petsc_routine__) { \ 1351 stack__.file[stack__.currentsize] = file__; \ 1352 stack__.line[stack__.currentsize] = line__; \ 1353 } else { \ 1354 stack__.file[stack__.currentsize] = PETSC_NULLPTR; \ 1355 stack__.line[stack__.currentsize] = 0; \ 1356 } \ 1357 stack__.petscroutine[stack__.currentsize] = petsc_routine__; \ 1358 } \ 1359 ++stack__.currentsize; \ 1360 stack__.hotdepth += (hot__ || stack__.hotdepth); \ 1361 } while (0) 1362 1363 /* uses PetscCheckAbort() because may be used in a function that does not return an error code */ 1364 #define PetscStackPop_Private(stack__, func__) \ 1365 do { \ 1366 PetscCheckAbort(!stack__.check || stack__.currentsize > 0, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Invalid stack size %d, pop %s %s:%d.\n", stack__.currentsize, func__, __FILE__, __LINE__); \ 1367 if (--stack__.currentsize < PETSCSTACKSIZE) { \ 1368 PetscCheckAbort(!stack__.check || stack__.petscroutine[stack__.currentsize] != 1 || stack__.function[stack__.currentsize] == (const char *)(func__), PETSC_COMM_SELF, PETSC_ERR_PLIB, "Invalid stack: push from %s %s:%d. Pop from %s %s:%d.\n", \ 1369 stack__.function[stack__.currentsize], stack__.file[stack__.currentsize], stack__.line[stack__.currentsize], func__, __FILE__, __LINE__); \ 1370 stack__.function[stack__.currentsize] = PETSC_NULLPTR; \ 1371 stack__.file[stack__.currentsize] = PETSC_NULLPTR; \ 1372 stack__.line[stack__.currentsize] = 0; \ 1373 stack__.petscroutine[stack__.currentsize] = 0; \ 1374 } \ 1375 stack__.hotdepth = PetscMax(stack__.hotdepth - 1, 0); \ 1376 } while (0) 1377 1378 /*MC 1379 PetscStackPushNoCheck - Pushes a new function name and line number onto the PETSc default stack that tracks where the running program is 1380 currently in the source code. 1381 1382 Synopsis: 1383 #include <petscsys.h> 1384 void PetscStackPushNoCheck(char *funct,int petsc_routine,PetscBool hot); 1385 1386 Not Collective 1387 1388 Input Parameters: 1389 + funct - the function name 1390 . petsc_routine - 2 user function, 1 PETSc function, 0 some other function 1391 - hot - indicates that the function may be called often so expensive error checking should be turned off inside the function 1392 1393 Level: developer 1394 1395 Notes: 1396 In debug mode PETSc maintains a stack of the current function calls that can be used to help to quickly see where a problem has 1397 occurred, for example, when a signal is received without running in the debugger. It is recommended to use the debugger if extensive information is needed to 1398 help debug the problem. 1399 1400 This version does not check the memory corruption (an expensive operation), use `PetscStackPush()` to check the memory. 1401 1402 Use `PetscStackPushExternal()` for a function call that is about to be made to a non-PETSc or user function (such as BLAS etc). 1403 1404 The default stack is a global variable called `petscstack`. 1405 1406 .seealso: `PetscAttachDebugger()`, `PetscStackCopy()`, `PetscStackView()`, `PetscStackPopNoCheck()`, `PetscCall()`, `PetscFunctionBegin()`, 1407 `PetscFunctionReturn()`, `PetscFunctionBeginHot()`, `PetscFunctionBeginUser()`, `PetscStackPush()`, `PetscStackPop`, 1408 `PetscStackPushExternal()` 1409 M*/ 1410 #define PetscStackPushNoCheck(funct, petsc_routine, hot) \ 1411 do { \ 1412 PetscStackSAWsTakeAccess(); \ 1413 PetscStackPush_Private(petscstack, __FILE__, funct, __LINE__, petsc_routine, hot); \ 1414 PetscStackSAWsGrantAccess(); \ 1415 } while (0) 1416 1417 /*MC 1418 PetscStackUpdateLine - in a function that has a `PetscFunctionBegin` or `PetscFunctionBeginUser` updates the stack line number to the 1419 current line number. 1420 1421 Synopsis: 1422 #include <petscsys.h> 1423 void PetscStackUpdateLine 1424 1425 Not Collective 1426 1427 Level: developer 1428 1429 Notes: 1430 Using `PetscCall()` and friends automatically handles this process 1431 1432 In debug mode PETSc maintains a stack of the current function calls that can be used to help to quickly see where a problem has 1433 occurred, for example, when a signal is received. It is recommended to use the debugger if extensive information is needed to 1434 help debug the problem. 1435 1436 The default stack is a global variable called `petscstack`. 1437 1438 This is used by `PetscCall()` and is otherwise not like to be needed 1439 1440 .seealso: `PetscAttachDebugger()`, `PetscStackCopy()`, `PetscStackView()`, `PetscStackPushNoCheck()`, `PetscStackPop`, `PetscCall()` 1441 M*/ 1442 #define PetscStackUpdateLine \ 1443 do { \ 1444 if (petscstack.currentsize > 0 && petscstack.currentsize < PETSCSTACKSIZE && petscstack.function[petscstack.currentsize - 1] == PETSC_FUNCTION_NAME) { petscstack.line[petscstack.currentsize - 1] = __LINE__; } \ 1445 } while (0) 1446 1447 /*MC 1448 PetscStackPushExternal - Pushes a new function name onto the PETSc default stack that tracks where the running program is 1449 currently in the source code. Does not include the filename or line number since this is called by the calling routine 1450 for non-PETSc or user functions. 1451 1452 Synopsis: 1453 #include <petscsys.h> 1454 void PetscStackPushExternal(char *funct); 1455 1456 Not Collective 1457 1458 Input Parameter: 1459 . funct - the function name 1460 1461 Level: developer 1462 1463 Notes: 1464 Using `PetscCallExternal()` and friends automatically handles this process 1465 1466 In debug mode PETSc maintains a stack of the current function calls that can be used to help to quickly see where a problem has 1467 occurred, for example, when a signal is received. It is recommended to use the debugger if extensive information is needed to 1468 help debug the problem. 1469 1470 The default stack is a global variable called `petscstack`. 1471 1472 This is to be used when calling an external package function such as a BLAS function. 1473 1474 This also updates the stack line number for the current stack function. 1475 1476 .seealso: `PetscAttachDebugger()`, `PetscStackCopy()`, `PetscStackView()`, `PetscStackPopNoCheck()`, `PetscCall()`, `PetscFunctionBegin()`, 1477 `PetscFunctionReturn()`, `PetscFunctionBeginHot()`, `PetscFunctionBeginUser()`, `PetscStackPushNoCheck()`, `PetscStackPop` 1478 M*/ 1479 #define PetscStackPushExternal(funct) \ 1480 do { \ 1481 PetscStackUpdateLine; \ 1482 PetscStackPushNoCheck(funct, 0, PETSC_TRUE); \ 1483 } while (0) 1484 1485 /*MC 1486 PetscStackPopNoCheck - Pops a function name from the PETSc default stack that tracks where the running program is 1487 currently in the source code. 1488 1489 Synopsis: 1490 #include <petscsys.h> 1491 void PetscStackPopNoCheck(char *funct); 1492 1493 Not Collective 1494 1495 Input Parameter: 1496 . funct - the function name 1497 1498 Level: developer 1499 1500 Notes: 1501 Using `PetscCall()`, `PetscCallExternal()`, `PetscCallBack()` and friends negates the need to call this 1502 1503 In debug mode PETSc maintains a stack of the current function calls that can be used to help to quickly see where a problem has 1504 occurred, for example, when a signal is received. It is recommended to use the debugger if extensive information is needed to 1505 help debug the problem. 1506 1507 The default stack is a global variable called `petscstack`. 1508 1509 Developer Note: 1510 `PetscStackPopNoCheck()` takes a function argument while `PetscStackPop` does not, this difference is likely just historical. 1511 1512 .seealso: `PetscAttachDebugger()`, `PetscStackCopy()`, `PetscStackView()`, `PetscStackPushNoCheck()`, `PetscStackPop` 1513 M*/ 1514 #define PetscStackPopNoCheck(funct) \ 1515 do { \ 1516 PetscStackSAWsTakeAccess(); \ 1517 PetscStackPop_Private(petscstack, funct); \ 1518 PetscStackSAWsGrantAccess(); \ 1519 } while (0) 1520 1521 #define PetscStackClearTop \ 1522 do { \ 1523 PetscStackSAWsTakeAccess(); \ 1524 if (petscstack.currentsize > 0 && --petscstack.currentsize < PETSCSTACKSIZE) { \ 1525 petscstack.function[petscstack.currentsize] = PETSC_NULLPTR; \ 1526 petscstack.file[petscstack.currentsize] = PETSC_NULLPTR; \ 1527 petscstack.line[petscstack.currentsize] = 0; \ 1528 petscstack.petscroutine[petscstack.currentsize] = 0; \ 1529 } \ 1530 petscstack.hotdepth = PetscMax(petscstack.hotdepth - 1, 0); \ 1531 PetscStackSAWsGrantAccess(); \ 1532 } while (0) 1533 1534 /*MC 1535 PetscFunctionBegin - First executable line of each PETSc function, used for error handling. Final 1536 line of PETSc functions should be `PetscFunctionReturn`(0); 1537 1538 Synopsis: 1539 #include <petscsys.h> 1540 void PetscFunctionBegin; 1541 1542 Not Collective; No Fortran Support 1543 1544 Usage: 1545 .vb 1546 int something; 1547 1548 PetscFunctionBegin; 1549 .ve 1550 1551 Level: developer 1552 1553 Note: 1554 Use `PetscFunctionBeginUser` for application codes. 1555 1556 .seealso: `PetscFunctionReturn()`, `PetscFunctionBeginHot()`, `PetscFunctionBeginUser()`, `PetscStackPushNoCheck()` 1557 1558 M*/ 1559 #define PetscFunctionBegin \ 1560 do { \ 1561 PetscStackPushNoCheck(PETSC_FUNCTION_NAME, 1, PETSC_FALSE); \ 1562 PetscRegister__FUNCT__(); \ 1563 } while (0) 1564 1565 /*MC 1566 PetscFunctionBeginHot - Substitute for `PetscFunctionBegin` to be used in functions that are called in 1567 performance-critical circumstances. Use of this function allows for lighter profiling by default. 1568 1569 Synopsis: 1570 #include <petscsys.h> 1571 void PetscFunctionBeginHot; 1572 1573 Not Collective; No Fortran Support 1574 1575 Usage: 1576 .vb 1577 int something; 1578 1579 PetscFunctionBeginHot; 1580 .ve 1581 1582 Level: developer 1583 1584 .seealso: `PetscFunctionBegin`, `PetscFunctionReturn()`, `PetscStackPushNoCheck()` 1585 1586 M*/ 1587 #define PetscFunctionBeginHot \ 1588 do { \ 1589 PetscStackPushNoCheck(PETSC_FUNCTION_NAME, 1, PETSC_TRUE); \ 1590 PetscRegister__FUNCT__(); \ 1591 } while (0) 1592 1593 /*MC 1594 PetscFunctionBeginUser - First executable line of user provided routines 1595 1596 Synopsis: 1597 #include <petscsys.h> 1598 void PetscFunctionBeginUser; 1599 1600 Not Collective; No Fortran Support 1601 1602 Usage: 1603 .vb 1604 int something; 1605 1606 PetscFunctionBeginUser; 1607 .ve 1608 1609 Level: intermediate 1610 1611 Notes: 1612 Functions that incorporate this must call `PetscFunctionReturn()` instead of return except for main(). 1613 1614 May be used before `PetscInitialize()` 1615 1616 This is identical to `PetscFunctionBegin` except it labels the routine as a user 1617 routine instead of as a PETSc library routine. 1618 1619 .seealso: `PetscFunctionReturn()`, `PetscFunctionBegin`, `PetscFunctionBeginHot`, `PetscStackPushNoCheck()` 1620 M*/ 1621 #define PetscFunctionBeginUser \ 1622 do { \ 1623 PetscStackPushNoCheck(PETSC_FUNCTION_NAME, 2, PETSC_FALSE); \ 1624 PetscRegister__FUNCT__(); \ 1625 } while (0) 1626 1627 /*MC 1628 PetscStackPush - Pushes a new function name and line number onto the PETSc default stack that tracks where the running program is 1629 currently in the source code and verifies the memory is not corrupted. 1630 1631 Synopsis: 1632 #include <petscsys.h> 1633 void PetscStackPush(char *funct) 1634 1635 Not Collective 1636 1637 Input Parameter: 1638 . funct - the function name 1639 1640 Level: developer 1641 1642 Notes: 1643 In debug mode PETSc maintains a stack of the current function calls that can be used to help to quickly see where a problem has 1644 occurred, for example, when a signal is received. It is recommended to use the debugger if extensive information is needed to 1645 help debug the problem. 1646 1647 The default stack is a global variable called `petscstack`. 1648 1649 .seealso: `PetscAttachDebugger()`, `PetscStackCopy()`, `PetscStackView()`, `PetscStackPopNoCheck()`, `PetscCall()`, `PetscFunctionBegin()`, 1650 `PetscFunctionReturn()`, `PetscFunctionBeginHot()`, `PetscFunctionBeginUser()`, `PetscStackPushNoCheck()`, `PetscStackPop` 1651 M*/ 1652 #define PetscStackPush(n) \ 1653 do { \ 1654 PetscStackPushNoCheck(n, 0, PETSC_FALSE); \ 1655 CHKMEMQ; \ 1656 } while (0) 1657 1658 /*MC 1659 PetscStackPop - Pops a function name from the PETSc default stack that tracks where the running program is 1660 currently in the source code and verifies the memory is not corrupted. 1661 1662 Synopsis: 1663 #include <petscsys.h> 1664 void PetscStackPop 1665 1666 Not Collective 1667 1668 Level: developer 1669 1670 Notes: 1671 In debug mode PETSc maintains a stack of the current function calls that can be used to help to quickly see where a problem has 1672 occurred, for example, when a signal is received. It is recommended to use the debugger if extensive information is needed to 1673 help debug the problem. 1674 1675 The default stack is a global variable called `petscstack`. 1676 1677 .seealso: `PetscAttachDebugger()`, `PetscStackCopy()`, `PetscStackView()`, `PetscStackPushNoCheck()`, `PetscStackPopNoCheck()`, `PetscStackPush()` 1678 M*/ 1679 #define PetscStackPop \ 1680 do { \ 1681 CHKMEMQ; \ 1682 PetscStackPopNoCheck(PETSC_FUNCTION_NAME); \ 1683 } while (0) 1684 1685 /*MC 1686 PetscFunctionReturn - Last executable line of each PETSc function used for error 1687 handling. Replaces `return()`. 1688 1689 Synopsis: 1690 #include <petscerror.h> 1691 void PetscFunctionReturn(...) 1692 1693 Not Collective; No Fortran Support 1694 1695 Level: beginner 1696 1697 Notes: 1698 This routine is a macro, so while it does not "return" anything itself, it does return from 1699 the function in the literal sense. 1700 1701 Usually the return value is the integer literal `0` (for example in any function returning 1702 `PetscErrorCode`), however it is possible to return any arbitrary type. The arguments of 1703 this macro are placed before the `return` statement as-is. 1704 1705 Any routine which returns via `PetscFunctionReturn()` must begin with a corresponding 1706 `PetscFunctionBegin`. 1707 1708 For routines which return `void` use `PetscFunctionReturnVoid()` instead. 1709 1710 Example Usage: 1711 .vb 1712 PetscErrorCode foo(int *x) 1713 { 1714 PetscFunctionBegin; // don't forget the begin! 1715 *x = 10; 1716 PetscFunctionReturn(PETSC_SUCCESS); 1717 } 1718 .ve 1719 1720 May return any arbitrary type\: 1721 .vb 1722 struct Foo 1723 { 1724 int x; 1725 }; 1726 1727 struct Foo make_foo(int value) 1728 { 1729 struct Foo f; 1730 1731 PetscFunctionBegin; 1732 f.x = value; 1733 PetscFunctionReturn(f); 1734 } 1735 .ve 1736 1737 .seealso: `PetscFunctionBegin`, `PetscFunctionBeginUser`, `PetscFunctionReturnVoid()`, 1738 `PetscStackPopNoCheck()` 1739 M*/ 1740 #define PetscFunctionReturn(...) \ 1741 do { \ 1742 PetscStackPopNoCheck(PETSC_FUNCTION_NAME); \ 1743 return __VA_ARGS__; \ 1744 } while (0) 1745 1746 /*MC 1747 PetscFunctionReturnVoid - Like `PetscFunctionReturn()` but returns `void` 1748 1749 Synopsis: 1750 #include <petscerror.h> 1751 void PetscFunctionReturnVoid() 1752 1753 Not Collective 1754 1755 Level: beginner 1756 1757 Note: 1758 Behaves identically to `PetscFunctionReturn()` except that it returns `void`. That is, this 1759 macro culminates with `return`. 1760 1761 Example Usage: 1762 .vb 1763 void foo() 1764 { 1765 PetscFunctionBegin; // must start with PetscFunctionBegin! 1766 bar(); 1767 baz(); 1768 PetscFunctionReturnVoid(); 1769 } 1770 .ve 1771 1772 .seealso: `PetscFunctionReturn()`, `PetscFunctionBegin`, PetscFunctionBeginUser` 1773 M*/ 1774 #define PetscFunctionReturnVoid() \ 1775 do { \ 1776 PetscStackPopNoCheck(PETSC_FUNCTION_NAME); \ 1777 return; \ 1778 } while (0) 1779 #else /* PETSC_USE_DEBUG */ 1780 #define PetscStackPushNoCheck(funct, petsc_routine, hot) 1781 #define PetscStackUpdateLine 1782 #define PetscStackPushExternal(funct) 1783 #define PetscStackPopNoCheck(...) 1784 #define PetscStackClearTop 1785 #define PetscFunctionBegin 1786 #define PetscFunctionBeginUser 1787 #define PetscFunctionBeginHot 1788 #define PetscFunctionReturn(...) return __VA_ARGS__ 1789 #define PetscFunctionReturnVoid() return 1790 #define PetscStackPop CHKMEMQ 1791 #define PetscStackPush(f) CHKMEMQ 1792 #endif /* PETSC_USE_DEBUG */ 1793 1794 #if defined(PETSC_CLANG_STATIC_ANALYZER) 1795 #define PetscStackCallExternalVoid(...) 1796 template <typename F, typename... Args> 1797 void PetscCallExternal(F, Args...); 1798 #else 1799 /*MC 1800 PetscStackCallExternalVoid - Calls an external library routine or user function after pushing the name of the routine on the stack. 1801 1802 Input Parameters: 1803 + name - string that gives the name of the function being called 1804 - routine - actual call to the routine, for example, functionname(a,b) 1805 1806 Level: developer 1807 1808 Notes: 1809 Often one should use `PetscCallExternal()` instead. This routine is intended for external library routines that DO NOT return error codes 1810 1811 In debug mode this also checks the memory for corruption at the end of the function call. 1812 1813 Certain external packages, such as BLAS/LAPACK may have their own macros, `PetscCallBLAS()` for managing the call, error checking, etc. 1814 1815 Developer Note: 1816 This is so that when a user or external library routine results in a crash or corrupts memory, they get blamed instead of PETSc. 1817 1818 .seealso: `PetscCall()`, `PetscStackPushNoCheck()`, `PetscStackPush()`, `PetscCallExternal()`, `PetscCallBLAS()` 1819 @*/ 1820 #define PetscStackCallExternalVoid(name, ...) \ 1821 do { \ 1822 PetscStackPushExternal(name); \ 1823 __VA_ARGS__; \ 1824 PetscStackPop; \ 1825 } while (0) 1826 1827 /*MC 1828 PetscCallExternal - Calls an external library routine that returns an error code after pushing the name of the routine on the stack. 1829 1830 Input Parameters: 1831 + func - name of the routine 1832 - args - arguments to the routine 1833 1834 Level: developer 1835 1836 Notes: 1837 This is intended for external package routines that return error codes. Use `PetscStackCallExternalVoid()` for those that do not. 1838 1839 In debug mode this also checks the memory for corruption at the end of the function call. 1840 1841 Assumes the error return code of the function is an integer and that a value of 0 indicates success 1842 1843 Developer Note: 1844 This is so that when an external package routine results in a crash or corrupts memory, they get blamed instead of PETSc. 1845 1846 .seealso: `PetscCall()`, `PetscStackPushNoCheck()`, `PetscStackPush()`, `PetscStackCallExternalVoid()` 1847 M*/ 1848 #define PetscCallExternal(func, ...) \ 1849 do { \ 1850 PetscStackPush(PetscStringize(func)); \ 1851 int ierr_petsc_call_external_ = func(__VA_ARGS__); \ 1852 PetscStackPop; \ 1853 PetscCheck(ierr_petsc_call_external_ == 0, PETSC_COMM_SELF, PETSC_ERR_LIB, "Error in %s(): error code %d", PetscStringize(func), ierr_petsc_call_external_); \ 1854 } while (0) 1855 #endif /* PETSC_CLANG_STATIC_ANALYZER */ 1856