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