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