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