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