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