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