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