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 #if defined(PETSC_CLANG_STATIC_ANALYZER) 865 void PETSCABORTWITHERR_Private(MPI_Comm, PetscErrorCode); 866 #else 867 #define PETSCABORTWITHIERR_Private(comm, ierr) \ 868 do { \ 869 PetscMPIInt size_; \ 870 MPI_Comm_size(comm, &size_); \ 871 if (PetscCIEnabledPortableErrorOutput && (size_ == PetscGlobalSize || petscabortmpifinalize) && ierr != PETSC_ERR_SIG) { \ 872 MPI_Finalize(); \ 873 exit(0); \ 874 } else if (PetscCIEnabledPortableErrorOutput && PetscGlobalSize == 1) { \ 875 exit(0); \ 876 } else { \ 877 MPI_Abort(comm, (PetscMPIInt)ierr); \ 878 } \ 879 } while (0) 880 #endif 881 882 /*MC 883 PETSCABORT - Call `MPI_Abort()` with an informative error code 884 885 Synopsis: 886 #include <petscsys.h> 887 PETSCABORT(MPI_Comm comm, PetscErrorCode ierr) 888 889 Collective; No Fortran Support 890 891 Input Parameters: 892 + comm - An MPI communicator, so that the error can be collective 893 - ierr - nonzero error code, see the list of standard error codes in include/petscerror.h 894 895 Level: advanced 896 897 Notes: 898 If the option `-start_in_debugger` was used then this calls `abort()` to stop the program in the debugger. 899 900 if `PetscCIEnabledPortableErrorOutput` is set, which means the code is running in the PETSc test harness (make test), 901 and `comm` is `MPI_COMM_WORLD` it strives to exit cleanly without calling `MPI_Abort()` and instead calling `MPI_Finalize()`. 902 903 This is currently only used when an error propagates up to the C `main()` program and is detected by a `PetscCall()`, `PetscCallMPI()`, 904 or is set in `main()` with `SETERRQ()`. Abort calls such as `SETERRABORT()`, 905 `PetscCheckAbort()`, `PetscCallMPIAbort()`, and `PetscCallAbort()` always call `MPI_Abort()` and do not have any special 906 handling for the test harness. 907 908 Developer Note: 909 Should the other abort calls also pass through this call instead of calling `MPI_Abort()` directly? 910 911 .seealso: `PetscError()`, `PetscCall()`, `SETERRABORT()`, `PetscCheckAbort()`, `PetscCallMPIAbort()`, `PetscCall()`, `PetscCallMPI()`, 912 `PetscCallAbort()`, `MPI_Abort()`, `PetscErrorCode` 913 M*/ 914 #if defined(PETSC_CLANG_STATIC_ANALYZER) 915 void PETSCABORT(MPI_Comm, PetscErrorCode); 916 #else 917 #define PETSCABORT(comm, ...) \ 918 do { \ 919 PetscErrorCode ierr_petsc_abort_; \ 920 if (petscwaitonerrorflg) { ierr_petsc_abort_ = PetscSleep(1000); } \ 921 if (petscindebugger) { \ 922 abort(); \ 923 } else { \ 924 ierr_petsc_abort_ = __VA_ARGS__; \ 925 PETSCABORTWITHIERR_Private(comm, ierr_petsc_abort_); \ 926 } \ 927 } while (0) 928 #endif 929 930 #ifdef PETSC_CLANGUAGE_CXX 931 /*MC 932 PetscCallThrow - Checks error code, if non-zero it calls the C++ error handler which throws 933 an exception 934 935 Synopsis: 936 #include <petscerror.h> 937 void PetscCallThrow(PetscErrorCode ierr) 938 939 Not Collective 940 941 Input Parameter: 942 . ierr - nonzero error code, see the list of standard error codes in include/petscerror.h 943 944 Level: beginner 945 946 Notes: 947 Requires PETSc to be configured with clanguage of c++. Throws a std::runtime_error() on error. 948 949 Once the error handler throws the exception you can use `PetscCallVoid()` which returns without 950 an error code (bad idea since the error is ignored) or `PetscCallAbort()` to have `MPI_Abort()` 951 called immediately. 952 953 .seealso: `SETERRQ()`, `PetscCall()`, `SETERRABORT()`, `PetscCallAbort()`, `PetscTraceBackErrorHandler()`, 954 `PetscPushErrorHandler()`, `PetscError()`, `CHKMEMQ` 955 M*/ 956 #define PetscCallThrow(...) \ 957 do { \ 958 PetscStackUpdateLine; \ 959 PetscErrorCode ierr_petsc_call_throw_ = __VA_ARGS__; \ 960 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); \ 961 } while (0) 962 963 /*MC 964 CHKERRXX - Checks error code, if non-zero it calls the C++ error handler which throws an exception 965 966 Synopsis: 967 #include <petscerror.h> 968 void CHKERRXX(PetscErrorCode ierr) 969 970 Not Collective 971 972 Input Parameter: 973 . ierr - nonzero error code, see the list of standard error codes in include/petscerror.h 974 975 Level: deprecated 976 977 Note: 978 Deprecated in favor of `PetscCallThrow()`. This routine behaves identically to it. 979 980 .seealso: `PetscCallThrow()` 981 M*/ 982 #define CHKERRXX(...) PetscCallThrow(__VA_ARGS__) 983 #endif 984 985 #define PetscCallCXX_Private(__SETERR_FUNC__, __COMM__, ...) \ 986 do { \ 987 PetscStackUpdateLine; \ 988 try { \ 989 __VA_ARGS__; \ 990 } catch (const std::exception &e) { \ 991 __SETERR_FUNC__(__COMM__, PETSC_ERR_LIB, "%s", e.what()); \ 992 } \ 993 } while (0) 994 995 /*MC 996 PetscCallCXX - Checks C++ function calls and if they throw an exception, catch it and then 997 return a PETSc error code 998 999 Synopsis: 1000 #include <petscerror.h> 1001 void PetscCallCXX(...) noexcept; 1002 1003 Not Collective 1004 1005 Input Parameter: 1006 . __VA_ARGS__ - An arbitrary expression 1007 1008 Level: beginner 1009 1010 Notes: 1011 `PetscCallCXX(...)` is a macro replacement for 1012 .vb 1013 try { 1014 __VA_ARGS__; 1015 } catch (const std::exception& e) { 1016 return ConvertToPetscErrorCode(e); 1017 } 1018 .ve 1019 Due to the fact that it catches any (reasonable) exception, it is essentially noexcept. 1020 1021 If you cannot return a `PetscErrorCode` use `PetscCallCXXAbort()` instead. 1022 1023 Example Usage: 1024 .vb 1025 void foo(void) { throw std::runtime_error("error"); } 1026 1027 void bar() 1028 { 1029 PetscCallCXX(foo()); // ERROR bar() does not return PetscErrorCode 1030 } 1031 1032 PetscErrorCode baz() 1033 { 1034 PetscCallCXX(foo()); // OK 1035 1036 PetscCallCXX( 1037 bar(); 1038 foo(); // OK multiple statements allowed 1039 ); 1040 } 1041 1042 struct bop 1043 { 1044 bop() 1045 { 1046 PetscCallCXX(foo()); // ERROR returns PetscErrorCode, cannot be used in constructors 1047 } 1048 }; 1049 1050 // ERROR contains do-while, cannot be used as function-try block 1051 PetscErrorCode qux() PetscCallCXX( 1052 bar(); 1053 baz(); 1054 foo(); 1055 return 0; 1056 ) 1057 .ve 1058 1059 .seealso: `PetscCallCXXAbort()`, `PetscCallThrow()`, `SETERRQ()`, `PetscCall()`, 1060 `SETERRABORT()`, `PetscCallAbort()`, `PetscTraceBackErrorHandler()`, `PetscPushErrorHandler()`, 1061 `PetscError()`, `CHKMEMQ` 1062 M*/ 1063 #define PetscCallCXX(...) PetscCallCXX_Private(SETERRQ, PETSC_COMM_SELF, __VA_ARGS__) 1064 1065 /*MC 1066 PetscCallCXXAbort - Like `PetscCallCXX()` but calls `MPI_Abort()` instead of returning an 1067 error-code 1068 1069 Synopsis: 1070 #include <petscerror.h> 1071 void PetscCallCXXAbort(MPI_Comm comm, ...) noexcept; 1072 1073 Collective; No Fortran Support 1074 1075 Input Parameters: 1076 + comm - The MPI communicator to abort on 1077 - __VA_ARGS__ - An arbitrary expression 1078 1079 Level: beginner 1080 1081 Notes: 1082 This macro may be used to check C++ expressions for exceptions in cases where you cannot 1083 return an error code. This includes constructors, destructors, copy/move assignment functions 1084 or constructors among others. 1085 1086 If an exception is caught, the macro calls `SETERRABORT()` on `comm`. The exception must 1087 derive from `std::exception` in order to be caught. 1088 1089 If the routine _can_ return an error-code it is highly advised to use `PetscCallCXX()` 1090 instead. 1091 1092 See `PetscCallCXX()` for additional discussion. 1093 1094 Example Usage: 1095 .vb 1096 class Foo 1097 { 1098 std::vector<int> data_; 1099 1100 public: 1101 // normally std::vector::reserve() may raise an exception, but since we handle it with 1102 // PetscCallCXXAbort() we may mark this routine as noexcept! 1103 Foo() noexcept 1104 { 1105 PetscCallCXXAbort(PETSC_COMM_SELF, data_.reserve(10)); 1106 } 1107 }; 1108 1109 std::vector<int> bar() 1110 { 1111 std::vector<int> v; 1112 1113 PetscFunctionBegin; 1114 // OK! 1115 PetscCallCXXAbort(PETSC_COMM_SELF, v.emplace_back(1)); 1116 PetscFunctionReturn(v); 1117 } 1118 1119 PetscErrorCode baz() 1120 { 1121 std::vector<int> v; 1122 1123 PetscFunctionBegin; 1124 // WRONG! baz() returns a PetscErrorCode, prefer PetscCallCXX() instead 1125 PetscCallCXXAbort(PETSC_COMM_SELF, v.emplace_back(1)); 1126 PetscFunctionReturn(PETSC_SUCCESS); 1127 } 1128 .ve 1129 1130 .seealso: `PetscCallCXX()`, `SETERRABORT()`, `PetscCallAbort()` 1131 M*/ 1132 #define PetscCallCXXAbort(comm, ...) PetscCallCXX_Private(SETERRABORT, comm, __VA_ARGS__) 1133 1134 /*MC 1135 CHKERRCXX - Checks C++ function calls and if they throw an exception, catch it and then 1136 return a PETSc error code 1137 1138 Synopsis: 1139 #include <petscerror.h> 1140 void CHKERRCXX(func) noexcept; 1141 1142 Not Collective 1143 1144 Input Parameter: 1145 . func - C++ function calls 1146 1147 Level: deprecated 1148 1149 Note: 1150 Deprecated in favor of `PetscCallCXX()`. This routine behaves identically to it. 1151 1152 .seealso: `PetscCallCXX()` 1153 M*/ 1154 #define CHKERRCXX(...) PetscCallCXX(__VA_ARGS__) 1155 1156 /*MC 1157 CHKMEMQ - Checks the memory for corruption, calls error handler if any is detected 1158 1159 Synopsis: 1160 #include <petscsys.h> 1161 CHKMEMQ; 1162 1163 Not Collective 1164 1165 Level: beginner 1166 1167 Notes: 1168 We recommend using Valgrind <https://petsc.org/release/faq/#valgrind> or for NVIDIA CUDA systems 1169 <https://docs.nvidia.com/cuda/cuda-memcheck/index.html> for finding memory problems. The ``CHKMEMQ`` macro is useful on systems that 1170 do not have valgrind, but is not as good as valgrind or cuda-memcheck. 1171 1172 Must run with the option `-malloc_debug` (`-malloc_test` in debug mode; or if `PetscMallocSetDebug()` called) to enable this option 1173 1174 Once the error handler is called the calling function is then returned from with the given error code. 1175 1176 By defaults prints location where memory that is corrupted was allocated. 1177 1178 Use `CHKMEMA` for functions that return `void` 1179 1180 .seealso: `PetscTraceBackErrorHandler()`, `PetscPushErrorHandler()`, `PetscError()`, `SETERRQ()`, `PetscMallocValidate()` 1181 M*/ 1182 #if defined(PETSC_CLANG_STATIC_ANALYZER) 1183 #define CHKMEMQ 1184 #define CHKMEMA 1185 #else 1186 #define CHKMEMQ \ 1187 do { \ 1188 PetscErrorCode ierr_petsc_memq_ = PetscMallocValidate(__LINE__, PETSC_FUNCTION_NAME, __FILE__); \ 1189 if (PetscUnlikely(ierr_petsc_memq_ != PETSC_SUCCESS)) return PetscError(PETSC_COMM_SELF, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr_petsc_memq_, PETSC_ERROR_REPEAT, " "); \ 1190 } while (0) 1191 #define CHKMEMA PetscMallocValidate(__LINE__, PETSC_FUNCTION_NAME, __FILE__) 1192 #endif 1193 1194 /*E 1195 PetscErrorType - passed to the PETSc error handling routines indicating if this is the first or a later call to the error handlers 1196 1197 Level: advanced 1198 1199 Note: 1200 `PETSC_ERROR_IN_CXX` indicates the error was detected in C++ and an exception should be generated 1201 1202 Developer Note: 1203 This is currently used to decide when to print the detailed information about the run in `PetscTraceBackErrorHandler()` 1204 1205 .seealso: `PetscError()`, `SETERRQ()` 1206 E*/ 1207 typedef enum { 1208 PETSC_ERROR_INITIAL = 0, 1209 PETSC_ERROR_REPEAT = 1, 1210 PETSC_ERROR_IN_CXX = 2 1211 } PetscErrorType; 1212 1213 #if defined(__clang_analyzer__) 1214 __attribute__((analyzer_noreturn)) 1215 #endif 1216 PETSC_EXTERN PetscErrorCode 1217 PetscError(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, ...) PETSC_ATTRIBUTE_COLD PETSC_ATTRIBUTE_FORMAT(7, 8); 1218 1219 PETSC_EXTERN PetscErrorCode PetscErrorPrintfInitialize(void); 1220 PETSC_EXTERN PetscErrorCode PetscErrorMessage(PetscErrorCode, const char *[], char **); 1221 PETSC_EXTERN PetscErrorCode PetscTraceBackErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD; 1222 PETSC_EXTERN PetscErrorCode PetscIgnoreErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD; 1223 PETSC_EXTERN PetscErrorCode PetscEmacsClientErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD; 1224 PETSC_EXTERN PetscErrorCode PetscMPIAbortErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD; 1225 PETSC_EXTERN PetscErrorCode PetscAbortErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD; 1226 PETSC_EXTERN PetscErrorCode PetscAttachDebuggerErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD; 1227 PETSC_EXTERN PetscErrorCode PetscReturnErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD; 1228 PETSC_EXTERN PetscErrorCode PetscPushErrorHandler(PetscErrorCode (*handler)(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *), void *); 1229 PETSC_EXTERN PetscErrorCode PetscPopErrorHandler(void); 1230 PETSC_EXTERN PetscErrorCode PetscSignalHandlerDefault(int, void *); 1231 PETSC_EXTERN PetscErrorCode PetscPushSignalHandler(PetscErrorCode (*)(int, void *), void *); 1232 PETSC_EXTERN PetscErrorCode PetscPopSignalHandler(void); 1233 PETSC_EXTERN PetscErrorCode PetscCheckPointerSetIntensity(PetscInt); 1234 PETSC_EXTERN void PetscSignalSegvCheckPointerOrMpi(void); 1235 PETSC_DEPRECATED_FUNCTION(3, 13, 0, "PetscSignalSegvCheckPointerOrMpi()", ) static inline void PetscSignalSegvCheckPointer(void) 1236 { 1237 PetscSignalSegvCheckPointerOrMpi(); 1238 } 1239 1240 /*MC 1241 PetscErrorPrintf - Prints error messages. 1242 1243 Synopsis: 1244 #include <petscsys.h> 1245 PetscErrorCode (*PetscErrorPrintf)(const char format[], ...); 1246 1247 Not Collective; No Fortran Support 1248 1249 Input Parameter: 1250 . format - the usual `printf()` format string 1251 1252 Options Database Keys: 1253 + -error_output_stdout - cause error messages to be printed to stdout instead of the (default) stderr 1254 - -error_output_none - to turn off all printing of error messages (does not change the way the error is handled.) 1255 1256 Level: developer 1257 1258 Notes: 1259 Use 1260 .vb 1261 PetscErrorPrintf = PetscErrorPrintfNone; to turn off all printing of error messages (does not change the way the error is handled) and 1262 PetscErrorPrintf = PetscErrorPrintfDefault; to turn it back on or you can use your own function 1263 .ve 1264 Use 1265 .vb 1266 `PETSC_STDERR` = FILE* obtained from a file open etc. to have stderr printed to the file. 1267 `PETSC_STDOUT` = FILE* obtained from a file open etc. to have stdout printed to the file. 1268 .ve 1269 Use 1270 .vb 1271 `PetscPushErrorHandler()` to provide your own error handler that determines what kind of messages to print 1272 .ve 1273 1274 .seealso: `PetscFPrintf()`, `PetscSynchronizedPrintf()`, `PetscHelpPrintf()`, `PetscPrintf()`, `PetscPushErrorHandler()`, `PetscVFPrintf()`, `PetscHelpPrintf()` 1275 M*/ 1276 PETSC_EXTERN PetscErrorCode (*PetscErrorPrintf)(const char[], ...) PETSC_ATTRIBUTE_FORMAT(1, 2); 1277 1278 /*E 1279 PetscFPTrap - types of floating point exceptions that may be trapped 1280 1281 Currently only `PETSC_FP_TRAP_OFF` and `PETSC_FP_TRAP_ON` are handled. All others are treated as `PETSC_FP_TRAP_ON`. 1282 1283 Level: intermediate 1284 1285 .seealso: `PetscSetFPTrap()`, `PetscFPTrapPush()` 1286 E*/ 1287 typedef enum { 1288 PETSC_FP_TRAP_OFF = 0, 1289 PETSC_FP_TRAP_INDIV = 1, 1290 PETSC_FP_TRAP_FLTOPERR = 2, 1291 PETSC_FP_TRAP_FLTOVF = 4, 1292 PETSC_FP_TRAP_FLTUND = 8, 1293 PETSC_FP_TRAP_FLTDIV = 16, 1294 PETSC_FP_TRAP_FLTINEX = 32 1295 } PetscFPTrap; 1296 #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) 1297 PETSC_EXTERN PetscErrorCode PetscSetFPTrap(PetscFPTrap); 1298 PETSC_EXTERN PetscErrorCode PetscFPTrapPush(PetscFPTrap); 1299 PETSC_EXTERN PetscErrorCode PetscFPTrapPop(void); 1300 PETSC_EXTERN PetscErrorCode PetscDetermineInitialFPTrap(void); 1301 1302 /* 1303 Allows the code to build a stack frame as it runs 1304 */ 1305 1306 #define PETSCSTACKSIZE 64 1307 typedef struct { 1308 const char *function[PETSCSTACKSIZE]; 1309 const char *file[PETSCSTACKSIZE]; 1310 int line[PETSCSTACKSIZE]; 1311 int petscroutine[PETSCSTACKSIZE]; /* 0 external called from petsc, 1 petsc functions, 2 petsc user functions */ 1312 int currentsize; 1313 int hotdepth; 1314 PetscBool check; /* option to check for correct Push/Pop semantics, true for default petscstack but not other stacks */ 1315 } PetscStack; 1316 #if defined(PETSC_USE_DEBUG) && !defined(PETSC_HAVE_THREADSAFETY) 1317 PETSC_EXTERN PetscStack petscstack; 1318 #endif 1319 1320 #if defined(PETSC_SERIALIZE_FUNCTIONS) 1321 #include <petsc/private/petscfptimpl.h> 1322 /* 1323 Registers the current function into the global function pointer to function name table 1324 1325 Have to fix this to handle errors but cannot return error since used in PETSC_VIEWER_DRAW_() etc 1326 */ 1327 #define PetscRegister__FUNCT__() \ 1328 do { \ 1329 static PetscBool __chked = PETSC_FALSE; \ 1330 if (!__chked) { \ 1331 void *ptr; \ 1332 PetscCallAbort(PETSC_COMM_SELF, PetscDLSym(NULL, PETSC_FUNCTION_NAME, &ptr)); \ 1333 __chked = PETSC_TRUE; \ 1334 } \ 1335 } while (0) 1336 #else 1337 #define PetscRegister__FUNCT__() 1338 #endif 1339 1340 #if defined(PETSC_CLANG_STATIC_ANALYZER) || defined(__clang_analyzer__) 1341 #define PetscStackPushNoCheck(funct, petsc_routine, hot) 1342 #define PetscStackUpdateLine 1343 #define PetscStackPushExternal(funct) 1344 #define PetscStackPopNoCheck 1345 #define PetscStackClearTop 1346 #define PetscFunctionBegin 1347 #define PetscFunctionBeginUser 1348 #define PetscFunctionBeginHot 1349 #define PetscFunctionReturn(...) return __VA_ARGS__ 1350 #define PetscFunctionReturnVoid() return 1351 #define PetscStackPop 1352 #define PetscStackPush(f) 1353 #elif defined(PETSC_USE_DEBUG) && !defined(PETSC_HAVE_THREADSAFETY) 1354 1355 #define PetscStackPush_Private(stack__, file__, func__, line__, petsc_routine__, hot__) \ 1356 do { \ 1357 if (stack__.currentsize < PETSCSTACKSIZE) { \ 1358 stack__.function[stack__.currentsize] = func__; \ 1359 if (petsc_routine__) { \ 1360 stack__.file[stack__.currentsize] = file__; \ 1361 stack__.line[stack__.currentsize] = line__; \ 1362 } else { \ 1363 stack__.file[stack__.currentsize] = PETSC_NULLPTR; \ 1364 stack__.line[stack__.currentsize] = 0; \ 1365 } \ 1366 stack__.petscroutine[stack__.currentsize] = petsc_routine__; \ 1367 } \ 1368 ++stack__.currentsize; \ 1369 stack__.hotdepth += (hot__ || stack__.hotdepth); \ 1370 } while (0) 1371 1372 /* uses PetscCheckAbort() because may be used in a function that does not return an error code */ 1373 #define PetscStackPop_Private(stack__, func__) \ 1374 do { \ 1375 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__); \ 1376 if (--stack__.currentsize < PETSCSTACKSIZE) { \ 1377 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", \ 1378 stack__.function[stack__.currentsize], stack__.file[stack__.currentsize], stack__.line[stack__.currentsize], func__, __FILE__, __LINE__); \ 1379 stack__.function[stack__.currentsize] = PETSC_NULLPTR; \ 1380 stack__.file[stack__.currentsize] = PETSC_NULLPTR; \ 1381 stack__.line[stack__.currentsize] = 0; \ 1382 stack__.petscroutine[stack__.currentsize] = 0; \ 1383 } \ 1384 stack__.hotdepth = PetscMax(stack__.hotdepth - 1, 0); \ 1385 } while (0) 1386 1387 /*MC 1388 PetscStackPushNoCheck - Pushes a new function name and line number onto the PETSc default stack that tracks where the running program is 1389 currently in the source code. 1390 1391 Synopsis: 1392 #include <petscsys.h> 1393 void PetscStackPushNoCheck(char *funct,int petsc_routine,PetscBool hot); 1394 1395 Not Collective 1396 1397 Input Parameters: 1398 + funct - the function name 1399 . petsc_routine - 2 user function, 1 PETSc function, 0 some other function 1400 - hot - indicates that the function may be called often so expensive error checking should be turned off inside the function 1401 1402 Level: developer 1403 1404 Notes: 1405 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 1406 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 1407 help debug the problem. 1408 1409 This version does not check the memory corruption (an expensive operation), use `PetscStackPush()` to check the memory. 1410 1411 Use `PetscStackPushExternal()` for a function call that is about to be made to a non-PETSc or user function (such as BLAS etc). 1412 1413 The default stack is a global variable called `petscstack`. 1414 1415 .seealso: `PetscAttachDebugger()`, `PetscStackCopy()`, `PetscStackView()`, `PetscStackPopNoCheck()`, `PetscCall()`, `PetscFunctionBegin()`, 1416 `PetscFunctionReturn()`, `PetscFunctionBeginHot()`, `PetscFunctionBeginUser()`, `PetscStackPush()`, `PetscStackPop`, 1417 `PetscStackPushExternal()` 1418 M*/ 1419 #define PetscStackPushNoCheck(funct, petsc_routine, hot) \ 1420 do { \ 1421 PetscStackSAWsTakeAccess(); \ 1422 PetscStackPush_Private(petscstack, __FILE__, funct, __LINE__, petsc_routine, hot); \ 1423 PetscStackSAWsGrantAccess(); \ 1424 } while (0) 1425 1426 /*MC 1427 PetscStackUpdateLine - in a function that has a `PetscFunctionBegin` or `PetscFunctionBeginUser` updates the stack line number to the 1428 current line number. 1429 1430 Synopsis: 1431 #include <petscsys.h> 1432 void PetscStackUpdateLine 1433 1434 Not Collective 1435 1436 Level: developer 1437 1438 Notes: 1439 Using `PetscCall()` and friends automatically handles this process 1440 1441 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 1442 occurred, for example, when a signal is received. It is recommended to use the debugger if extensive information is needed to 1443 help debug the problem. 1444 1445 The default stack is a global variable called `petscstack`. 1446 1447 This is used by `PetscCall()` and is otherwise not like to be needed 1448 1449 .seealso: `PetscAttachDebugger()`, `PetscStackCopy()`, `PetscStackView()`, `PetscStackPushNoCheck()`, `PetscStackPop`, `PetscCall()` 1450 M*/ 1451 #define PetscStackUpdateLine \ 1452 do { \ 1453 if (petscstack.currentsize > 0 && petscstack.currentsize < PETSCSTACKSIZE && petscstack.function[petscstack.currentsize - 1] == PETSC_FUNCTION_NAME) { petscstack.line[petscstack.currentsize - 1] = __LINE__; } \ 1454 } while (0) 1455 1456 /*MC 1457 PetscStackPushExternal - Pushes a new function name onto the PETSc default stack that tracks where the running program is 1458 currently in the source code. Does not include the filename or line number since this is called by the calling routine 1459 for non-PETSc or user functions. 1460 1461 Synopsis: 1462 #include <petscsys.h> 1463 void PetscStackPushExternal(char *funct); 1464 1465 Not Collective 1466 1467 Input Parameter: 1468 . funct - the function name 1469 1470 Level: developer 1471 1472 Notes: 1473 Using `PetscCallExternal()` and friends automatically handles this process 1474 1475 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 1476 occurred, for example, when a signal is received. It is recommended to use the debugger if extensive information is needed to 1477 help debug the problem. 1478 1479 The default stack is a global variable called `petscstack`. 1480 1481 This is to be used when calling an external package function such as a BLAS function. 1482 1483 This also updates the stack line number for the current stack function. 1484 1485 .seealso: `PetscAttachDebugger()`, `PetscStackCopy()`, `PetscStackView()`, `PetscStackPopNoCheck()`, `PetscCall()`, `PetscFunctionBegin()`, 1486 `PetscFunctionReturn()`, `PetscFunctionBeginHot()`, `PetscFunctionBeginUser()`, `PetscStackPushNoCheck()`, `PetscStackPop` 1487 M*/ 1488 #define PetscStackPushExternal(funct) \ 1489 do { \ 1490 PetscStackUpdateLine; \ 1491 PetscStackPushNoCheck(funct, 0, PETSC_TRUE); \ 1492 } while (0) 1493 1494 /*MC 1495 PetscStackPopNoCheck - Pops a function name from the PETSc default stack that tracks where the running program is 1496 currently in the source code. 1497 1498 Synopsis: 1499 #include <petscsys.h> 1500 void PetscStackPopNoCheck(char *funct); 1501 1502 Not Collective 1503 1504 Input Parameter: 1505 . funct - the function name 1506 1507 Level: developer 1508 1509 Notes: 1510 Using `PetscCall()`, `PetscCallExternal()`, `PetscCallBack()` and friends negates the need to call this 1511 1512 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 1513 occurred, for example, when a signal is received. It is recommended to use the debugger if extensive information is needed to 1514 help debug the problem. 1515 1516 The default stack is a global variable called `petscstack`. 1517 1518 Developer Note: 1519 `PetscStackPopNoCheck()` takes a function argument while `PetscStackPop` does not, this difference is likely just historical. 1520 1521 .seealso: `PetscAttachDebugger()`, `PetscStackCopy()`, `PetscStackView()`, `PetscStackPushNoCheck()`, `PetscStackPop` 1522 M*/ 1523 #define PetscStackPopNoCheck(funct) \ 1524 do { \ 1525 PetscStackSAWsTakeAccess(); \ 1526 PetscStackPop_Private(petscstack, funct); \ 1527 PetscStackSAWsGrantAccess(); \ 1528 } while (0) 1529 1530 #define PetscStackClearTop \ 1531 do { \ 1532 PetscStackSAWsTakeAccess(); \ 1533 if (petscstack.currentsize > 0 && --petscstack.currentsize < PETSCSTACKSIZE) { \ 1534 petscstack.function[petscstack.currentsize] = PETSC_NULLPTR; \ 1535 petscstack.file[petscstack.currentsize] = PETSC_NULLPTR; \ 1536 petscstack.line[petscstack.currentsize] = 0; \ 1537 petscstack.petscroutine[petscstack.currentsize] = 0; \ 1538 } \ 1539 petscstack.hotdepth = PetscMax(petscstack.hotdepth - 1, 0); \ 1540 PetscStackSAWsGrantAccess(); \ 1541 } while (0) 1542 1543 /*MC 1544 PetscFunctionBegin - First executable line of each PETSc function, used for error handling. Final 1545 line of PETSc functions should be `PetscFunctionReturn`(0); 1546 1547 Synopsis: 1548 #include <petscsys.h> 1549 void PetscFunctionBegin; 1550 1551 Not Collective; No Fortran Support 1552 1553 Usage: 1554 .vb 1555 int something; 1556 1557 PetscFunctionBegin; 1558 .ve 1559 1560 Level: developer 1561 1562 Note: 1563 Use `PetscFunctionBeginUser` for application codes. 1564 1565 .seealso: `PetscFunctionReturn()`, `PetscFunctionBeginHot()`, `PetscFunctionBeginUser()`, `PetscStackPushNoCheck()` 1566 1567 M*/ 1568 #define PetscFunctionBegin \ 1569 do { \ 1570 PetscStackPushNoCheck(PETSC_FUNCTION_NAME, 1, PETSC_FALSE); \ 1571 PetscRegister__FUNCT__(); \ 1572 } while (0) 1573 1574 /*MC 1575 PetscFunctionBeginHot - Substitute for `PetscFunctionBegin` to be used in functions that are called in 1576 performance-critical circumstances. Use of this function allows for lighter profiling by default. 1577 1578 Synopsis: 1579 #include <petscsys.h> 1580 void PetscFunctionBeginHot; 1581 1582 Not Collective; No Fortran Support 1583 1584 Usage: 1585 .vb 1586 int something; 1587 1588 PetscFunctionBeginHot; 1589 .ve 1590 1591 Level: developer 1592 1593 .seealso: `PetscFunctionBegin`, `PetscFunctionReturn()`, `PetscStackPushNoCheck()` 1594 1595 M*/ 1596 #define PetscFunctionBeginHot \ 1597 do { \ 1598 PetscStackPushNoCheck(PETSC_FUNCTION_NAME, 1, PETSC_TRUE); \ 1599 PetscRegister__FUNCT__(); \ 1600 } while (0) 1601 1602 /*MC 1603 PetscFunctionBeginUser - First executable line of user provided routines 1604 1605 Synopsis: 1606 #include <petscsys.h> 1607 void PetscFunctionBeginUser; 1608 1609 Not Collective; No Fortran Support 1610 1611 Usage: 1612 .vb 1613 int something; 1614 1615 PetscFunctionBeginUser; 1616 .ve 1617 1618 Level: intermediate 1619 1620 Notes: 1621 Functions that incorporate this must call `PetscFunctionReturn()` instead of return except for main(). 1622 1623 May be used before `PetscInitialize()` 1624 1625 This is identical to `PetscFunctionBegin` except it labels the routine as a user 1626 routine instead of as a PETSc library routine. 1627 1628 .seealso: `PetscFunctionReturn()`, `PetscFunctionBegin`, `PetscFunctionBeginHot`, `PetscStackPushNoCheck()` 1629 M*/ 1630 #define PetscFunctionBeginUser \ 1631 do { \ 1632 PetscStackPushNoCheck(PETSC_FUNCTION_NAME, 2, PETSC_FALSE); \ 1633 PetscRegister__FUNCT__(); \ 1634 } while (0) 1635 1636 /*MC 1637 PetscStackPush - Pushes a new function name and line number onto the PETSc default stack that tracks where the running program is 1638 currently in the source code and verifies the memory is not corrupted. 1639 1640 Synopsis: 1641 #include <petscsys.h> 1642 void PetscStackPush(char *funct) 1643 1644 Not Collective 1645 1646 Input Parameter: 1647 . funct - the function name 1648 1649 Level: developer 1650 1651 Notes: 1652 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 1653 occurred, for example, when a signal is received. It is recommended to use the debugger if extensive information is needed to 1654 help debug the problem. 1655 1656 The default stack is a global variable called `petscstack`. 1657 1658 .seealso: `PetscAttachDebugger()`, `PetscStackCopy()`, `PetscStackView()`, `PetscStackPopNoCheck()`, `PetscCall()`, `PetscFunctionBegin()`, 1659 `PetscFunctionReturn()`, `PetscFunctionBeginHot()`, `PetscFunctionBeginUser()`, `PetscStackPushNoCheck()`, `PetscStackPop` 1660 M*/ 1661 #define PetscStackPush(n) \ 1662 do { \ 1663 PetscStackPushNoCheck(n, 0, PETSC_FALSE); \ 1664 CHKMEMQ; \ 1665 } while (0) 1666 1667 /*MC 1668 PetscStackPop - Pops a function name from the PETSc default stack that tracks where the running program is 1669 currently in the source code and verifies the memory is not corrupted. 1670 1671 Synopsis: 1672 #include <petscsys.h> 1673 void PetscStackPop 1674 1675 Not Collective 1676 1677 Level: developer 1678 1679 Notes: 1680 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 1681 occurred, for example, when a signal is received. It is recommended to use the debugger if extensive information is needed to 1682 help debug the problem. 1683 1684 The default stack is a global variable called `petscstack`. 1685 1686 .seealso: `PetscAttachDebugger()`, `PetscStackCopy()`, `PetscStackView()`, `PetscStackPushNoCheck()`, `PetscStackPopNoCheck()`, `PetscStackPush()` 1687 M*/ 1688 #define PetscStackPop \ 1689 do { \ 1690 CHKMEMQ; \ 1691 PetscStackPopNoCheck(PETSC_FUNCTION_NAME); \ 1692 } while (0) 1693 1694 /*MC 1695 PetscFunctionReturn - Last executable line of each PETSc function used for error 1696 handling. Replaces `return()`. 1697 1698 Synopsis: 1699 #include <petscerror.h> 1700 void PetscFunctionReturn(...) 1701 1702 Not Collective; No Fortran Support 1703 1704 Level: beginner 1705 1706 Notes: 1707 This routine is a macro, so while it does not "return" anything itself, it does return from 1708 the function in the literal sense. 1709 1710 Usually the return value is the integer literal `0` (for example in any function returning 1711 `PetscErrorCode`), however it is possible to return any arbitrary type. The arguments of 1712 this macro are placed before the `return` statement as-is. 1713 1714 Any routine which returns via `PetscFunctionReturn()` must begin with a corresponding 1715 `PetscFunctionBegin`. 1716 1717 For routines which return `void` use `PetscFunctionReturnVoid()` instead. 1718 1719 Example Usage: 1720 .vb 1721 PetscErrorCode foo(int *x) 1722 { 1723 PetscFunctionBegin; // don't forget the begin! 1724 *x = 10; 1725 PetscFunctionReturn(PETSC_SUCCESS); 1726 } 1727 .ve 1728 1729 May return any arbitrary type\: 1730 .vb 1731 struct Foo 1732 { 1733 int x; 1734 }; 1735 1736 struct Foo make_foo(int value) 1737 { 1738 struct Foo f; 1739 1740 PetscFunctionBegin; 1741 f.x = value; 1742 PetscFunctionReturn(f); 1743 } 1744 .ve 1745 1746 .seealso: `PetscFunctionBegin`, `PetscFunctionBeginUser`, `PetscFunctionReturnVoid()`, 1747 `PetscStackPopNoCheck()` 1748 M*/ 1749 #define PetscFunctionReturn(...) \ 1750 do { \ 1751 PetscStackPopNoCheck(PETSC_FUNCTION_NAME); \ 1752 return __VA_ARGS__; \ 1753 } while (0) 1754 1755 /*MC 1756 PetscFunctionReturnVoid - Like `PetscFunctionReturn()` but returns `void` 1757 1758 Synopsis: 1759 #include <petscerror.h> 1760 void PetscFunctionReturnVoid() 1761 1762 Not Collective 1763 1764 Level: beginner 1765 1766 Note: 1767 Behaves identically to `PetscFunctionReturn()` except that it returns `void`. That is, this 1768 macro culminates with `return`. 1769 1770 Example Usage: 1771 .vb 1772 void foo() 1773 { 1774 PetscFunctionBegin; // must start with PetscFunctionBegin! 1775 bar(); 1776 baz(); 1777 PetscFunctionReturnVoid(); 1778 } 1779 .ve 1780 1781 .seealso: `PetscFunctionReturn()`, `PetscFunctionBegin`, PetscFunctionBeginUser` 1782 M*/ 1783 #define PetscFunctionReturnVoid() \ 1784 do { \ 1785 PetscStackPopNoCheck(PETSC_FUNCTION_NAME); \ 1786 return; \ 1787 } while (0) 1788 #else /* PETSC_USE_DEBUG */ 1789 #define PetscStackPushNoCheck(funct, petsc_routine, hot) 1790 #define PetscStackUpdateLine 1791 #define PetscStackPushExternal(funct) 1792 #define PetscStackPopNoCheck(...) 1793 #define PetscStackClearTop 1794 #define PetscFunctionBegin 1795 #define PetscFunctionBeginUser 1796 #define PetscFunctionBeginHot 1797 #define PetscFunctionReturn(...) return __VA_ARGS__ 1798 #define PetscFunctionReturnVoid() return 1799 #define PetscStackPop CHKMEMQ 1800 #define PetscStackPush(f) CHKMEMQ 1801 #endif /* PETSC_USE_DEBUG */ 1802 1803 #if defined(PETSC_CLANG_STATIC_ANALYZER) 1804 #define PetscStackCallExternalVoid(...) 1805 template <typename F, typename... Args> 1806 void PetscCallExternal(F, Args...); 1807 template <typename F, typename... Args> 1808 void PetscCallExternalAbort(F, Args...); 1809 #else 1810 /*MC 1811 PetscStackCallExternalVoid - Calls an external library routine or user function after pushing the name of the routine on the stack. 1812 1813 Input Parameters: 1814 + name - string that gives the name of the function being called 1815 - routine - actual call to the routine, for example, functionname(a,b) 1816 1817 Level: developer 1818 1819 Notes: 1820 Often one should use `PetscCallExternal()` instead. This routine is intended for external library routines that DO NOT return error codes 1821 1822 In debug mode this also checks the memory for corruption at the end of the function call. 1823 1824 Certain external packages, such as BLAS/LAPACK may have their own macros, `PetscCallBLAS()` for managing the call, error checking, etc. 1825 1826 Developer Note: 1827 This is so that when a user or external library routine results in a crash or corrupts memory, they get blamed instead of PETSc. 1828 1829 .seealso: `PetscCall()`, `PetscStackPushNoCheck()`, `PetscStackPush()`, `PetscCallExternal()`, `PetscCallBLAS()` 1830 @*/ 1831 #define PetscStackCallExternalVoid(name, ...) \ 1832 do { \ 1833 PetscStackPushExternal(name); \ 1834 __VA_ARGS__; \ 1835 PetscStackPop; \ 1836 } while (0) 1837 1838 /*MC 1839 PetscCallExternal - Calls an external library routine that returns an error code after pushing the name of the routine on the stack. 1840 1841 Input Parameters: 1842 + func - name of the routine 1843 - args - arguments to the routine 1844 1845 Level: developer 1846 1847 Notes: 1848 This is intended for external package routines that return error codes. Use `PetscStackCallExternalVoid()` for those that do not. 1849 1850 In debug mode this also checks the memory for corruption at the end of the function call. 1851 1852 Assumes the error return code of the function is an integer and that a value of 0 indicates success 1853 1854 Developer Note: 1855 This is so that when an external package routine results in a crash or corrupts memory, they get blamed instead of PETSc. 1856 1857 .seealso: `PetscCall()`, `PetscStackPushNoCheck()`, `PetscStackPush()`, `PetscStackCallExternalVoid()`, `PetscCallExternalAbort()` 1858 M*/ 1859 #define PetscCallExternal(func, ...) \ 1860 do { \ 1861 PetscStackPush(PetscStringize(func)); \ 1862 int ierr_petsc_call_external_ = func(__VA_ARGS__); \ 1863 PetscStackPop; \ 1864 PetscCheck(ierr_petsc_call_external_ == 0, PETSC_COMM_SELF, PETSC_ERR_LIB, "Error in %s(): error code %d", PetscStringize(func), ierr_petsc_call_external_); \ 1865 } while (0) 1866 1867 /*MC 1868 PetscCallExternalAbort - Calls an external library routine that returns an error code after pushing the name of the routine on the stack. If the external library function return code indicates an error, this prints the error and aborts 1869 1870 Input Parameters: 1871 + func - name of the routine 1872 - args - arguments to the routine 1873 1874 Level: developer 1875 1876 Notes: 1877 This is intended for external package routines that return error codes. Use `PetscStackCallExternalVoid()` for those that do not. 1878 1879 In debug mode this also checks the memory for corruption at the end of the function call. 1880 1881 Assumes the error return code of the function is an integer and that a value of 0 indicates success 1882 1883 Developer Note: 1884 This is so that when an external package routine results in a crash or corrupts memory, they get blamed instead of PETSc. 1885 1886 .seealso: `PetscCall()`, `PetscStackPushNoCheck()`, `PetscStackPush()`, `PetscStackCallExternalVoid()`, `PetscCallExternal()` 1887 M*/ 1888 #define PetscCallExternalAbort(func, ...) \ 1889 do { \ 1890 PetscStackUpdateLine; \ 1891 int ierr_petsc_call_external_ = func(__VA_ARGS__); \ 1892 if (PetscUnlikely(ierr_petsc_call_external_ != 0)) { \ 1893 (void)PetscError(PETSC_COMM_SELF, __LINE__, PETSC_FUNCTION_NAME, __FILE__, PETSC_ERR_LIB, PETSC_ERROR_INITIAL, "Error in %s(): error code %d", PetscStringize(func), ierr_petsc_call_external_); \ 1894 PETSCABORTWITHIERR_Private(PETSC_COMM_SELF, PETSC_ERR_LIB); \ 1895 } \ 1896 } while (0) 1897 #endif /* PETSC_CLANG_STATIC_ANALYZER */ 1898