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