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