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 Notes:
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: No Fortran Support
160: Synopsis:
161: #include <petscerror.h>
162: void PetscCheck(bool cond, MPI_Comm comm, PetscErrorCode ierr, const char *message, ...)
164: Collective
166: Input Parameters:
167: + cond - The boolean condition
168: . comm - The communicator on which the check can be collective on
169: . ierr - A nonzero error code, see include/petscerror.h for the complete list
170: - message - Error message in printf format
172: Level: beginner
174: Notes:
175: Enabled in both optimized and debug builds.
177: Calls `SETERRQ()` if the assertion fails, so can only be called from functions returning a
178: `PetscErrorCode` (or equivalent type after conversion).
180: .seealso: `PetscAssert()`, `SETERRQ()`, `PetscError()`, `PetscCall()`, `PetscCheckAbort()`
181: M*/
182: #define PetscCheck(cond, comm, ierr, ...) \
183: do { \
184: if (PetscUnlikely(!(cond))) SETERRQ(comm, ierr, __VA_ARGS__); \
185: } while (0)
187: /*MC
188: PetscCheckAbort - Check that a particular condition is true, otherwise prints error and aborts
190: No Fortran Support
192: Synopsis:
193: #include <petscerror.h>
194: void PetscCheckAbort(bool cond, MPI_Comm comm, PetscErrorCode ierr, const char *message, ...)
196: Collective
198: Input Parameters:
199: + cond - The boolean condition
200: . comm - The communicator on which the check can be collective on
201: . ierr - A nonzero error code, see include/petscerror.h for the complete list
202: - message - Error message in printf format
204: Level: developer
206: Notes:
207: Enabled in both optimized and debug builds.
209: Calls `SETERRABORT()` if the assertion fails, can be called from a function that does not return an
210: error code, such as a C++ constructor. usually `PetscCheck()` should be used.
212: .seealso: `PetscAssertAbort()`, `PetscAssert()`, `SETERRQ()`, `PetscError()`, `PetscCall()`, `PetscCheck()`, `SETERRABORT()`
213: M*/
214: #define PetscCheckAbort(cond, comm, ierr, ...) \
215: do { \
216: if (PetscUnlikely(!(cond))) SETERRABORT(comm, ierr, __VA_ARGS__); \
217: } while (0)
219: /*MC
220: PetscAssert - Assert that a particular condition is true
222: No Fortran Support
224: Synopsis:
225: #include <petscerror.h>
226: void PetscAssert(bool cond, MPI_Comm comm, PetscErrorCode ierr, const char *message, ...)
228: Collective
230: Input Parameters:
231: + cond - The boolean condition
232: . comm - The communicator on which the check can be collective on
233: . ierr - A nonzero error code, see include/petscerror.h for the complete list
234: - message - Error message in printf format
236: Level: beginner
238: Notes:
239: Equivalent to `PetscCheck()` if debugging is enabled, and `PetscAssume(cond)` otherwise.
241: See `PetscCheck()` for usage and behaviour.
243: This is needed instead of simply using `assert()` because this correctly handles the collective nature of errors under MPI
245: .seealso: `PetscCheck()`, `SETERRQ()`, `PetscError()`, `PetscAssertAbort()`
246: M*/
247: #if PetscDefined(USE_DEBUG)
248: #define PetscAssert(cond, comm, ierr, ...) PetscCheck(cond, comm, ierr, __VA_ARGS__)
249: #else
250: #define PetscAssert(cond, ...) PetscAssume(cond)
251: #endif
253: /*MC
254: PetscAssertAbort - Assert that a particular condition is true, otherwise prints error and aborts
256: No Fortran Support
258: Synopsis:
259: #include <petscerror.h>
260: void PetscAssertAbort(bool cond, MPI_Comm comm, PetscErrorCode ierr, const char *message, ...)
262: Collective
264: Input Parameters:
265: + cond - The boolean condition
266: . comm - The communicator on which the check can be collective on
267: . ierr - A nonzero error code, see include/petscerror.h for the complete list
268: - message - Error message in printf format
270: Level: beginner
272: Notes:
273: Enabled only in debug builds. See `PetscCheckAbort()` for usage.
275: .seealso: `PetscCheckAbort()`, `PetscAssert()`, `PetscCheck()`, `SETERRABORT()`, `PetscError()`
276: M*/
277: #if PetscDefined(USE_DEBUG)
278: #define PetscAssertAbort(cond, comm, ierr, ...) PetscCheckAbort(cond, comm, ierr, __VA_ARGS__)
279: #else
280: #define PetscAssertAbort(cond, comm, ierr, ...) PetscAssume(cond)
281: #endif
283: /*MC
284: PetscCall - Calls a PETSc function and then checks the resulting error code, if it is
285: non-zero it calls the error handler and returns from the current function with the error
286: code.
288: Synopsis:
289: #include <petscerror.h>
290: void PetscCall(PetscFunction(args))
292: Not Collective
294: Input Parameter:
295: . PetscFunction - any PETSc function that returns an error code
297: Level: beginner
299: Notes:
300: Once the error handler is called the calling function is then returned from with the given
301: error code. Experienced users can set the error handler with `PetscPushErrorHandler()`.
303: `PetscCall()` cannot be used in functions returning a datatype not convertible to
304: `PetscErrorCode`. For example, `PetscCall()` may not be used in functions returning void, use
305: `PetscCallAbort()` or `PetscCallVoid()` in this case.
307: Example Usage:
308: .vb
309: PetscCall(PetscInitiailize(...)); // OK to call even when PETSc is not yet initialized!
311: struct my_struct
312: {
313: void *data;
314: } my_complex_type;
316: struct my_struct bar(void)
317: {
318: PetscCall(foo(15)); // ERROR PetscErrorCode not convertible to struct my_struct!
319: }
321: PetscCall(bar()) // ERROR input not convertible to PetscErrorCode
322: .ve
324: It is also possible to call this directly on a `PetscErrorCode` variable
325: .vb
326: PetscCall(ierr); // check if ierr is nonzero
327: .ve
329: Should not be used to call callback functions provided by users, `PetscCallBack()` should be used in that situation.
331: `PetscUseTypeMethod()` or `PetscTryTypeMethod()` should be used when calling functions pointers contained in a PETSc object's `ops` array
333: Fortran Notes:
334: The Fortran function from which this is used must declare a variable PetscErrorCode ierr and ierr must be
335: the final argument to the PETSc function being called.
337: In the main program and in Fortran subroutines that do not have ierr as the final return parameter one
338: should use `PetscCallA()`
340: Example Fortran Usage:
341: .vb
342: PetscErrorCode ierr
343: Vec v
345: ...
346: PetscCall(VecShift(v,1.0,ierr))
347: PetscCallA(VecShift(v,1.0,ierr))
348: .ve
350: .seealso: `SETERRQ()`, `PetscCheck()`, `PetscAssert()`, `PetscTraceBackErrorHandler()`, `PetscCallMPI()`,
351: `PetscPushErrorHandler()`, `PetscError()`, `CHKMEMQ`, `CHKERRA()`,
352: `CHKERRMPI()`, `PetscCallBack()`, `PetscCallAbort()`, `PetscCallVoid()`
353: M*/
355: /*MC
356: PetscCallA - Fortran-only macro that should be used in the main program to call PETSc functions instead of using
357: PetscCall() which should be used in other Fortran subroutines
359: Synopsis:
360: #include <petscsys.h>
361: PetscErrorCode PetscCallA(PetscFunction(arguments,ierr))
363: Collective
365: Input Parameter:
366: . PetscFunction(arguments,ierr) - the call to the function
368: Level: beginner
370: Notes:
371: This should only be used with Fortran. With C/C++, use `PetscCall()` always.
373: Use `SETERRA()` to set an error in a Fortran main program and `SETERRQ()` in Fortran subroutines
375: .seealso: `SETERRQ()`, `SETERRA()`, `SETERRABORT()`, `PetscCall()`, `CHKERRA()`, `PetscCallAbort()`
376: M*/
378: /*MC
379: PetscCallBack - Calls a user provided PETSc callback function and then checks the resulting error code, if it is non-zero it calls the error
380: handler and returns from the current function with the error code.
382: No Fortran Support
384: Synopsis:
385: #include <petscerror.h>
386: void PetscCallBack(const char *functionname,PetscFunction(args))
388: Not Collective
390: Input Parameters:
391: + functionname - the name of the function being called, this can be a string with spaces that describes the meaning of the callback
392: - PetscFunction - user provided callback function that returns an error code
394: Example Usage:
395: .vb
396: PetscCallBack("XXX callback to do something",a->callback(...));
397: .ve
399: Level: developer
401: Notes:
402: Once the error handler is called the calling function is then returned from with the given
403: error code. Experienced users can set the error handler with `PetscPushErrorHandler()`.
405: `PetscCallBack()` should only be called in PETSc when a call is being made to a user provided call-back routine.
407: .seealso: `SETERRQ()`, `PetscCheck()`, `PetscCall()`, `PetscAssert()`, `PetscTraceBackErrorHandler()`, `PetscCallMPI()`
408: `PetscPushErrorHandler()`, `PetscError()`, `CHKMEMQ`, `CHKERRA()`, `CHKERRMPI()`, `PetscCall()`
409: M*/
411: /*MC
412: PetscCallVoid - Like `PetscCall()` but for functions returning `void`
414: No Fortran Support
416: Synopsis:
417: #include <petscerror.h>
418: void PetscCall(PetscFunction(args))
420: Not Collective
422: Input Parameter:
423: . PetscFunction - any PETSc function that returns an error code
425: Example Usage:
426: .vb
427: void foo()
428: {
429: KSP ksp;
431: PetscFunctionBeginUser;
432: // OK, properly handles PETSc error codes
433: PetscCallVoid(KSPCreate(PETSC_COMM_WORLD, &ksp));
434: PetscFunctionReturn(PETSC_SUCCESS);
435: }
437: PetscErrorCode bar()
438: {
439: KSP ksp;
441: PetscFunctionBeginUser;
442: // ERROR, Non-void function 'bar' should return a value
443: PetscCallVoid(KSPCreate(PETSC_COMM_WORLD, &ksp));
444: // OK, returning PetscErrorCode
445: PetscCall(KSPCreate(PETSC_COMM_WORLD, &ksp));
446: PetscFunctionReturn(PETSC_SUCCESS);
447: }
448: .ve
450: Level: beginner
452: Notes:
453: Has identical usage to `PetscCall()`, except that it returns `void` on error instead of a
454: `PetscErrorCode`. See `PetscCall()` for more detailed discussion.
456: Note that users should prefer `PetscCallAbort()` to this routine. While this routine does
457: "handle" errors by returning from the enclosing function, it effectively gobbles the
458: error. Since the enclosing function itself returns `void`, its callers have no way of knowing
459: that the routine returned early due to an error. `PetscCallAbort()` at least ensures that the
460: program crashes gracefully.
462: .seealso: `PetscCall()`, `PetscErrorCode`
463: M*/
464: #if defined(PETSC_CLANG_STATIC_ANALYZER)
465: void PetscCall(PetscErrorCode);
466: void PetscCallBack(const char *, PetscErrorCode);
467: void PetscCallVoid(PetscErrorCode);
468: #else
469: #define PetscCall(...) \
470: do { \
471: PetscErrorCode ierr_petsc_call_q_; \
472: PetscStackUpdateLine; \
473: ierr_petsc_call_q_ = __VA_ARGS__; \
474: 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, " "); \
475: } while (0)
476: #define PetscCallBack(function, ...) \
477: do { \
478: PetscErrorCode ierr_petsc_call_q_; \
479: PetscStackUpdateLine; \
480: PetscStackPushExternal(function); \
481: ierr_petsc_call_q_ = __VA_ARGS__; \
482: PetscStackPop; \
483: 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, " "); \
484: } while (0)
485: #define PetscCallVoid(...) \
486: do { \
487: PetscErrorCode ierr_petsc_call_void_; \
488: PetscStackUpdateLine; \
489: ierr_petsc_call_void_ = __VA_ARGS__; \
490: if (PetscUnlikely(ierr_petsc_call_void_ != PETSC_SUCCESS)) { \
491: ierr_petsc_call_void_ = PetscError(PETSC_COMM_SELF, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr_petsc_call_void_, PETSC_ERROR_REPEAT, " "); \
492: (void)ierr_petsc_call_void_; \
493: return; \
494: } \
495: } while (0)
496: #endif
498: /*MC
499: CHKERRQ - Checks error code returned from PETSc function
501: Synopsis:
502: #include <petscsys.h>
503: void CHKERRQ(PetscErrorCode ierr)
505: Not Collective
507: Input Parameter:
508: . ierr - nonzero error code
510: Level: deprecated
512: Note:
513: Deprecated in favor of `PetscCall()`. This routine behaves identically to it.
515: .seealso: `PetscCall()`
516: M*/
517: #define CHKERRQ(...) PetscCall(__VA_ARGS__)
518: #define CHKERRV(...) PetscCallVoid(__VA_ARGS__)
520: PETSC_EXTERN void PetscMPIErrorString(PetscMPIInt, char *);
522: /*MC
523: PetscCallMPI - Checks error code returned from MPI calls, if non-zero it calls the error
524: handler and then returns
526: Synopsis:
527: #include <petscerror.h>
528: void PetscCallMPI(MPI_Function(args))
530: Not Collective
532: Input Parameter:
533: . MPI_Function - an MPI function that returns an MPI error code
535: Level: beginner
537: Notes:
538: Always returns the error code `PETSC_ERR_MPI`; the MPI error code and string are embedded in
539: the string error message. Do not use this to call any other routines (for example PETSc
540: routines), it should only be used for direct MPI calls. The user may configure PETSc with the
541: `--with-strict-petscerrorcode` option to check this at compile-time, otherwise they must
542: check this themselves.
544: This rouine can only be used in functions returning `PetscErrorCode` themselves. If the
545: calling function returns a different type, use `PetscCallMPIAbort()` instead.
547: Example Usage:
548: .vb
549: PetscCallMPI(MPI_Comm_size(...)); // OK, calling MPI function
551: PetscCallMPI(PetscFunction(...)); // ERROR, use PetscCall() instead!
552: .ve
554: Fortran Notes:
555: The Fortran function from which this is used must declare a variable `PetscErrorCode` ierr and ierr must be
556: the final argument to the MPI function being called.
558: In the main program and in Fortran subroutines that do not have ierr as the final return parameter one
559: should use `PetscCallMPIA()`
561: Fortran Usage:
562: .vb
563: PetscErrorCode ierr or integer ierr
564: ...
565: PetscCallMPI(MPI_Comm_size(...,ierr))
566: PetscCallMPIA(MPI_Comm_size(...,ierr)) ! Will abort after calling error handler
568: PetscCallMPI(MPI_Comm_size(...,eflag)) ! ERROR, final argument must be ierr
569: .ve
571: .seealso: `SETERRMPI()`, `PetscCall()`, `SETERRQ()`, `SETERRABORT()`, `PetscCallAbort()`,
572: `PetscCallMPIAbort()`, `PetscTraceBackErrorHandler()`, `PetscPushErrorHandler()`,
573: `PetscError()`, `CHKMEMQ`
574: M*/
576: /*MC
577: PetscCallMPIAbort - Like `PetscCallMPI()` but calls `MPI_Abort()` on error
579: Synopsis:
580: #include <petscerror.h>
581: void PetscCallMPIAbort(MPI_Comm comm, MPI_Function(args))
583: Not Collective
585: Input Parameters:
586: + comm - the MPI communicator to abort on
587: - MPI_Function - an MPI function that returns an MPI error code
589: Level: beginner
591: Notes:
592: Usage is identical to `PetscCallMPI()`. See `PetscCallMPI()` for detailed discussion.
594: This routine may be used in functions returning `void` or other non-`PetscErrorCode` types.
596: Fortran Note:
597: In Fortran this is called `PetscCallMPIA()` and is intended to be used in the main program while `PetscCallMPI()` is
598: used in Fortran subroutines.
600: Developer Note:
601: This should have the same name in Fortran.
603: .seealso: `PetscCallMPI()`, `PetscCallAbort()`, `SETERRABORT()`
604: M*/
605: #if defined(PETSC_CLANG_STATIC_ANALYZER)
606: void PetscCallMPI(PetscMPIInt);
607: void PetscCallMPIAbort(MPI_Comm, PetscMPIInt);
608: #else
609: #define PetscCallMPI_Private(__PETSC_STACK_POP_FUNC__, __SETERR_FUNC__, __COMM__, ...) \
610: do { \
611: PetscMPIInt ierr_petsc_call_mpi_; \
612: PetscStackUpdateLine; \
613: PetscStackPushExternal("MPI function"); \
614: { \
615: ierr_petsc_call_mpi_ = __VA_ARGS__; \
616: } \
617: __PETSC_STACK_POP_FUNC__; \
618: if (PetscUnlikely(ierr_petsc_call_mpi_ != MPI_SUCCESS)) { \
619: char petsc_mpi_7_errorstring[2 * MPI_MAX_ERROR_STRING]; \
620: PetscMPIErrorString(ierr_petsc_call_mpi_, (char *)petsc_mpi_7_errorstring); \
621: __SETERR_FUNC__(__COMM__, PETSC_ERR_MPI, "MPI error %d %s", (int)ierr_petsc_call_mpi_, petsc_mpi_7_errorstring); \
622: } \
623: } while (0)
625: #define PetscCallMPI(...) PetscCallMPI_Private(PetscStackPop, SETERRQ, PETSC_COMM_SELF, __VA_ARGS__)
626: #define PetscCallMPIAbort(comm, ...) PetscCallMPI_Private(PetscStackPopNoCheck(PETSC_FUNCTION_NAME), SETERRABORT, comm, __VA_ARGS__)
627: #endif
629: /*MC
630: CHKERRMPI - Checks error code returned from MPI calls, if non-zero it calls the error
631: handler and then returns
633: Synopsis:
634: #include <petscerror.h>
635: void CHKERRMPI(PetscErrorCode ierr)
637: Not Collective
639: Input Parameter:
640: . ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
642: Level: deprecated
644: Note:
645: Deprecated in favor of `PetscCallMPI()`. This routine behaves identically to it.
647: .seealso: `PetscCallMPI()`
648: M*/
649: #define CHKERRMPI(...) PetscCallMPI(__VA_ARGS__)
651: /*MC
652: PetscCallAbort - Checks error code returned from PETSc function, if non-zero it aborts immediately by calling `MPI_Abort()`
654: Synopsis:
655: #include <petscerror.h>
656: void PetscCallAbort(MPI_Comm comm, PetscErrorCode ierr)
658: Collective
660: Input Parameters:
661: + comm - the MPI communicator on which to abort
662: - ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
664: Level: intermediate
666: Notes:
667: This macro has identical type and usage semantics to `PetscCall()` with the important caveat
668: that this macro does not return. Instead, if ierr is nonzero it calls the PETSc error handler
669: and then immediately calls `MPI_Abort()`. It can therefore be used anywhere.
671: As per `MPI_Abort()` semantics the communicator passed must be valid, although there is currently
672: no attempt made at handling any potential errors from `MPI_Abort()`. Note that while
673: `MPI_Abort()` is required to terminate only those processes which reside on comm, it is often
674: the case that `MPI_Abort()` terminates *all* processes.
676: Example Usage:
677: .vb
678: PetscErrorCode boom(void) { return PETSC_ERR_MEM; }
680: void foo(void)
681: {
682: PetscCallAbort(PETSC_COMM_WORLD,boom()); // OK, does not return a type
683: }
685: double bar(void)
686: {
687: PetscCallAbort(PETSC_COMM_WORLD,boom()); // OK, does not return a type
688: }
690: PetscCallAbort(MPI_COMM_NULL,boom()); // ERROR, communicator should be valid
692: struct baz
693: {
694: baz()
695: {
696: PetscCallAbort(PETSC_COMM_SELF,boom()); // OK
697: }
699: ~baz()
700: {
701: PetscCallAbort(PETSC_COMM_SELF,boom()); // OK (in fact the only way to handle PETSc errors)
702: }
703: };
704: .ve
706: Fortran Note:
707: Use `PetscCallA()`.
709: Developer Note:
710: This should have the same name in Fortran as in C.
712: .seealso: `SETERRABORT()`, `PetscTraceBackErrorHandler()`, `PetscPushErrorHandler()`, `PetscError()`,
713: `SETERRQ()`, `CHKMEMQ`, `PetscCallMPI()`, `PetscCallCXXAbort()`
714: M*/
715: #if defined(PETSC_CLANG_STATIC_ANALYZER)
716: void PetscCallAbort(MPI_Comm, PetscErrorCode);
717: void PetscCallContinue(PetscErrorCode);
718: #else
719: #define PetscCallAbort(comm, ...) \
720: do { \
721: PetscErrorCode ierr_petsc_call_abort_; \
722: PetscStackUpdateLine; \
723: ierr_petsc_call_abort_ = __VA_ARGS__; \
724: if (PetscUnlikely(ierr_petsc_call_abort_ != PETSC_SUCCESS)) { \
725: ierr_petsc_call_abort_ = PetscError(PETSC_COMM_SELF, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr_petsc_call_abort_, PETSC_ERROR_REPEAT, " "); \
726: (void)MPI_Abort(comm, (PetscMPIInt)ierr_petsc_call_abort_); \
727: } \
728: } while (0)
729: #define PetscCallContinue(...) \
730: do { \
731: PetscErrorCode ierr_petsc_call_continue_; \
732: PetscStackUpdateLine; \
733: ierr_petsc_call_continue_ = __VA_ARGS__; \
734: if (PetscUnlikely(ierr_petsc_call_continue_ != PETSC_SUCCESS)) { \
735: ierr_petsc_call_continue_ = PetscError(PETSC_COMM_SELF, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr_petsc_call_continue_, PETSC_ERROR_REPEAT, " "); \
736: (void)ierr_petsc_call_continue_; \
737: } \
738: } while (0)
739: #endif
741: /*MC
742: CHKERRABORT - Checks error code returned from PETSc function. If non-zero it aborts immediately.
744: Synopsis:
745: #include <petscerror.h>
746: void CHKERRABORT(MPI_Comm comm, PetscErrorCode ierr)
748: Not Collective
750: Input Parameters:
751: + comm - the MPI communicator
752: - ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
754: Level: deprecated
756: Note:
757: Deprecated in favor of `PetscCallAbort()`. This routine behaves identically to it.
759: .seealso: `PetscCallAbort()`
760: M*/
761: #define CHKERRABORT(comm, ...) PetscCallAbort(comm, __VA_ARGS__)
762: #define CHKERRCONTINUE(...) PetscCallContinue(__VA_ARGS__)
764: /*MC
765: CHKERRA - Fortran-only replacement for use of `CHKERRQ()` in the main program, which aborts immediately
767: Synopsis:
768: #include <petscsys.h>
769: PetscErrorCode CHKERRA(PetscErrorCode ierr)
771: Not Collective
773: Input Parameter:
774: . ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
776: Level: deprecated
778: Note:
779: This macro is rarely needed, normal usage is `PetscCallA()` in the main Fortran program.
781: Developer Note:
782: Why isn't this named `CHKERRABORT()` in Fortran?
784: .seealso: `PetscCall()`, `PetscCallA()`, `PetscCallAbort()`, `CHKERRQ()`, `SETERRA()`, `SETERRQ()`, `SETERRABORT()`
785: M*/
787: PETSC_EXTERN PetscBool petscwaitonerrorflg;
788: PETSC_EXTERN PetscBool petscindebugger;
790: /*MC
791: PETSCABORT - Call `MPI_Abort()` with an informative error code
793: No Fortran Support
795: Synopsis:
796: #include <petscsys.h>
797: PETSCABORT(MPI_Comm comm, PetscErrorCode ierr)
799: Collective
801: Input Parameters:
802: + comm - A communicator, so that the error can be collective
803: - ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
805: Level: advanced
807: Notes:
808: If the option `-start_in_debugger` was used then this calls `abort()` to stop the program in the debugger.
810: if `PetscCIEnabledPortableErrorOutput` is set, which means the code is running in the PETSc test harness (make test),
811: and `comm` is `MPI_COMM_WORLD` it strives to exit cleanly without calling `MPI_Abort()` and instead calling `MPI_Finalize()`.
813: This is currently only used when an error propagates up to the C `main()` program and is detected by a `PetscCall()`, `PetscCallMPI()`,
814: or is set in `main()` with `SETERRQ()`. Abort calls such as `SETERRABORT()`,
815: `PetscCheckAbort()`, `PetscCallMPIAbort()`, and `PetscCallAbort()` always call `MPI_Abort()` and do not have any special
816: handling for the test harness.
818: Developer Note:
819: Should the other abort calls also pass through this call instead of calling `MPI_Abort()` directly?
821: .seealso: `PetscError()`, `PetscCall()`, `SETERRABORT()`, `PetscCheckAbort()`, `PetscCallMPIAbort()`, `PetscCall()`, `PetscCallMPI()`,
822: `PetscCallAbort()`, `MPI_Abort()`
823: M*/
824: #if defined(PETSC_CLANG_STATIC_ANALYZER)
825: void PETSCABORT(MPI_Comm, PetscErrorCode);
826: #else
827: #define PETSCABORT(comm, ...) \
828: do { \
829: PetscErrorCode ierr_petsc_abort_; \
830: if (petscwaitonerrorflg) { ierr_petsc_abort_ = PetscSleep(1000); } \
831: if (petscindebugger) { \
832: abort(); \
833: } else { \
834: PetscMPIInt size_; \
835: ierr_petsc_abort_ = __VA_ARGS__; \
836: MPI_Comm_size(comm, &size_); \
837: if (PetscCIEnabledPortableErrorOutput && size_ == PetscGlobalSize && ierr_petsc_abort_ != PETSC_ERR_SIG) { \
838: MPI_Finalize(); \
839: exit(0); \
840: } else if (PetscCIEnabledPortableErrorOutput && PetscGlobalSize == 1) { \
841: exit(0); \
842: } else { \
843: MPI_Abort(comm, (PetscMPIInt)ierr_petsc_abort_); \
844: } \
845: } \
846: } while (0)
847: #endif
849: #ifdef PETSC_CLANGUAGE_CXX
850: /*MC
851: PetscCallThrow - Checks error code, if non-zero it calls the C++ error handler which throws
852: an exception
854: Synopsis:
855: #include <petscerror.h>
856: void PetscCallThrow(PetscErrorCode ierr)
858: Not Collective
860: Input Parameter:
861: . ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
863: Level: beginner
865: Notes:
866: Requires PETSc to be configured with clanguage = c++. Throws a std::runtime_error() on error.
868: Once the error handler throws the exception you can use `PetscCallVoid()` which returns without
869: an error code (bad idea since the error is ignored) or `PetscCallAbort()` to have `MPI_Abort()`
870: called immediately.
872: .seealso: `SETERRQ()`, `PetscCall()`, `SETERRABORT()`, `PetscCallAbort()`, `PetscTraceBackErrorHandler()`,
873: `PetscPushErrorHandler()`, `PetscError()`, `CHKMEMQ`
874: M*/
875: #define PetscCallThrow(...) \
876: do { \
877: PetscStackUpdateLine; \
878: PetscErrorCode ierr_petsc_call_throw_ = __VA_ARGS__; \
879: 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); \
880: } while (0)
882: /*MC
883: CHKERRXX - Checks error code, if non-zero it calls the C++ error handler which throws an exception
885: Synopsis:
886: #include <petscerror.h>
887: void CHKERRXX(PetscErrorCode ierr)
889: Not Collective
891: Input Parameter:
892: . ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
894: Level: deprecated
896: Note:
897: Deprecated in favor of `PetscCallThrow()`. This routine behaves identically to it.
899: .seealso: `PetscCallThrow()`
900: M*/
901: #define CHKERRXX(...) PetscCallThrow(__VA_ARGS__)
902: #endif
904: #define PetscCallCXX_Private(__SETERR_FUNC__, __COMM__, ...) \
905: do { \
906: PetscStackUpdateLine; \
907: try { \
908: __VA_ARGS__; \
909: } catch (const std::exception &e) { \
910: __SETERR_FUNC__(__COMM__, PETSC_ERR_LIB, "%s", e.what()); \
911: } \
912: } while (0)
914: /*MC
915: PetscCallCXX - Checks C++ function calls and if they throw an exception, catch it and then
916: return a PETSc error code
918: Synopsis:
919: #include <petscerror.h>
920: void PetscCallCXX(...) noexcept;
922: Not Collective
924: Input Parameter:
925: . __VA_ARGS__ - An arbitrary expression
927: Level: beginner
929: Notes:
930: `PetscCallCXX(...)` is a macro replacement for
931: .vb
932: try {
933: __VA_ARGS__;
934: } catch (const std::exception& e) {
935: return ConvertToPetscErrorCode(e);
936: }
937: .ve
938: Due to the fact that it catches any (reasonable) exception, it is essentially noexcept.
940: If you cannot return a `PetscErrorCode` use `PetscCallCXXAbort()` instead.
942: Example Usage:
943: .vb
944: void foo(void) { throw std::runtime_error("error"); }
946: void bar()
947: {
948: PetscCallCXX(foo()); // ERROR bar() does not return PetscErrorCode
949: }
951: PetscErrorCode baz()
952: {
953: PetscCallCXX(foo()); // OK
955: PetscCallCXX(
956: bar();
957: foo(); // OK multiple statements allowed
958: );
959: }
961: struct bop
962: {
963: bop()
964: {
965: PetscCallCXX(foo()); // ERROR returns PetscErrorCode, cannot be used in constructors
966: }
967: };
969: // ERROR contains do-while, cannot be used as function-try block
970: PetscErrorCode qux() PetscCallCXX(
971: bar();
972: baz();
973: foo();
974: return 0;
975: )
976: .ve
978: .seealso: `PetscCallCXXAbort()`, `PetscCallThrow()`, `SETERRQ()`, `PetscCall()`,
979: `SETERRABORT()`, `PetscCallAbort()`, `PetscTraceBackErrorHandler()`, `PetscPushErrorHandler()`,
980: `PetscError()`, `CHKMEMQ`
981: M*/
982: #define PetscCallCXX(...) PetscCallCXX_Private(SETERRQ, PETSC_COMM_SELF, __VA_ARGS__)
984: /*MC
985: PetscCallCXXAbort - Like `PetscCallCXX()` but calls `MPI_Abort()` instead of returning an
986: error-code
988: Synopsis:
989: #include <petscerror.h>
990: void PetscCallCXXAbort(MPI_Comm comm, ...) noexcept;
992: Collective; No Fortran Support
994: Input Parameters:
995: + comm - The MPI communicator to abort on
996: - __VA_ARGS__ - An arbitrary expression
998: Level: beginner
1000: Notes:
1001: This macro may be used to check C++ expressions for exceptions in cases where you cannot
1002: return an error code. This includes constructors, destructors, copy/move assignment functions
1003: or constructors among others.
1005: If an exception is caught, the macro calls `SETERRABORT()` on `comm`. The exception must
1006: derive from `std::exception` in order to be caught.
1008: If the routine _can_ return an error-code it is highly advised to use `PetscCallCXX()`
1009: instead.
1011: See `PetscCallCXX()` for additional discussion.
1013: Example Usage:
1014: .vb
1015: class Foo
1016: {
1017: std::vector<int> data_;
1019: public:
1020: // normally std::vector::reserve() may raise an exception, but since we handle it with
1021: // PetscCallCXXAbort() we may mark this routine as noexcept!
1022: Foo() noexcept
1023: {
1024: PetscCallCXXAbort(PETSC_COMM_SELF, data_.reserve(10));
1025: }
1026: };
1028: std::vector<int> bar()
1029: {
1030: std::vector<int> v;
1032: PetscFunctionBegin;
1033: // OK!
1034: PetscCallCXXAbort(PETSC_COMM_SELF, v.emplace_back(1));
1035: PetscFunctionReturn(v);
1036: }
1038: PetscErrorCode baz()
1039: {
1040: std::vector<int> v;
1042: PetscFunctionBegin;
1043: // WRONG! baz() returns a PetscErrorCode, prefer PetscCallCXX() instead
1044: PetscCallCXXAbort(PETSC_COMM_SELF, v.emplace_back(1));
1045: PetscFunctionReturn(PETSC_SUCCESS);
1046: }
1047: .ve
1049: .seealso: `PetscCallCXX()`, `SETERRABORT()`, `PetscCallAbort()`
1050: M*/
1051: #define PetscCallCXXAbort(comm, ...) PetscCallCXX_Private(SETERRABORT, comm, __VA_ARGS__)
1053: /*MC
1054: CHKERRCXX - Checks C++ function calls and if they throw an exception, catch it and then
1055: return a PETSc error code
1057: Synopsis:
1058: #include <petscerror.h>
1059: void CHKERRCXX(func) noexcept;
1061: Not Collective
1063: Input Parameter:
1064: . func - C++ function calls
1066: Level: deprecated
1068: Note:
1069: Deprecated in favor of `PetscCallCXX()`. This routine behaves identically to it.
1071: .seealso: `PetscCallCXX()`
1072: M*/
1073: #define CHKERRCXX(...) PetscCallCXX(__VA_ARGS__)
1075: /*MC
1076: CHKMEMQ - Checks the memory for corruption, calls error handler if any is detected
1078: Synopsis:
1079: #include <petscsys.h>
1080: CHKMEMQ;
1082: Not Collective
1084: Level: beginner
1086: Notes:
1087: We highly recommend using Valgrind https://petsc.org/release/faq/#valgrind or for NVIDIA CUDA systems
1088: https://docs.nvidia.com/cuda/cuda-memcheck/index.html for finding memory problems. The ``CHKMEMQ`` macro is useful on systems that
1089: do not have valgrind, but is not as good as valgrind or cuda-memcheck.
1091: Must run with the option `-malloc_debug` (`-malloc_test` in debug mode; or if `PetscMallocSetDebug()` called) to enable this option
1093: Once the error handler is called the calling function is then returned from with the given error code.
1095: By defaults prints location where memory that is corrupted was allocated.
1097: Use `CHKMEMA` for functions that return void
1099: .seealso: `PetscTraceBackErrorHandler()`, `PetscPushErrorHandler()`, `PetscError()`, `SETERRQ()`, `PetscMallocValidate()`
1100: M*/
1101: #if defined(PETSC_CLANG_STATIC_ANALYZER)
1102: #define CHKMEMQ
1103: #define CHKMEMA
1104: #else
1105: #define CHKMEMQ \
1106: do { \
1107: PetscErrorCode ierr_petsc_memq_ = PetscMallocValidate(__LINE__, PETSC_FUNCTION_NAME, __FILE__); \
1108: if (PetscUnlikely(ierr_petsc_memq_ != PETSC_SUCCESS)) return PetscError(PETSC_COMM_SELF, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr_petsc_memq_, PETSC_ERROR_REPEAT, " "); \
1109: } while (0)
1110: #define CHKMEMA PetscMallocValidate(__LINE__, PETSC_FUNCTION_NAME, __FILE__)
1111: #endif
1113: /*E
1114: PetscErrorType - passed to the PETSc error handling routines indicating if this is the first or a later call to the error handlers
1116: Level: advanced
1118: Note:
1119: `PETSC_ERROR_IN_CXX` indicates the error was detected in C++ and an exception should be generated
1121: Developer Note:
1122: This is currently used to decide when to print the detailed information about the run in `PetscTraceBackErrorHandler()`
1124: .seealso: `PetscError()`, `SETERRQ()`
1125: E*/
1126: typedef enum {
1127: PETSC_ERROR_INITIAL = 0,
1128: PETSC_ERROR_REPEAT = 1,
1129: PETSC_ERROR_IN_CXX = 2
1130: } PetscErrorType;
1132: #if defined(__clang_analyzer__)
1133: __attribute__((analyzer_noreturn))
1134: #endif
1135: PETSC_EXTERN PetscErrorCode
1136: PetscError(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, ...) PETSC_ATTRIBUTE_COLD PETSC_ATTRIBUTE_FORMAT(7, 8);
1138: PETSC_EXTERN PetscErrorCode PetscErrorPrintfInitialize(void);
1139: PETSC_EXTERN PetscErrorCode PetscErrorMessage(PetscErrorCode, const char *[], char **);
1140: PETSC_EXTERN PetscErrorCode PetscTraceBackErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD;
1141: PETSC_EXTERN PetscErrorCode PetscIgnoreErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD;
1142: PETSC_EXTERN PetscErrorCode PetscEmacsClientErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD;
1143: PETSC_EXTERN PetscErrorCode PetscMPIAbortErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD;
1144: PETSC_EXTERN PetscErrorCode PetscAbortErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD;
1145: PETSC_EXTERN PetscErrorCode PetscAttachDebuggerErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD;
1146: PETSC_EXTERN PetscErrorCode PetscReturnErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD;
1147: PETSC_EXTERN PetscErrorCode PetscPushErrorHandler(PetscErrorCode (*handler)(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *), void *);
1148: PETSC_EXTERN PetscErrorCode PetscPopErrorHandler(void);
1149: PETSC_EXTERN PetscErrorCode PetscSignalHandlerDefault(int, void *);
1150: PETSC_EXTERN PetscErrorCode PetscPushSignalHandler(PetscErrorCode (*)(int, void *), void *);
1151: PETSC_EXTERN PetscErrorCode PetscPopSignalHandler(void);
1152: PETSC_EXTERN PetscErrorCode PetscCheckPointerSetIntensity(PetscInt);
1153: PETSC_EXTERN void PetscSignalSegvCheckPointerOrMpi(void);
1154: PETSC_DEPRECATED_FUNCTION("Use PetscSignalSegvCheckPointerOrMpi() (since version 3.13)") static inline void PetscSignalSegvCheckPointer(void)
1155: {
1156: PetscSignalSegvCheckPointerOrMpi();
1157: }
1159: /*MC
1160: PetscErrorPrintf - Prints error messages.
1162: Not Collective; No Fortran Support
1164: Synopsis:
1165: #include <petscsys.h>
1166: PetscErrorCode (*PetscErrorPrintf)(const char format[],...);
1168: Input Parameter:
1169: . format - the usual `printf()` format string
1171: Options Database Keys:
1172: + -error_output_stdout - cause error messages to be printed to stdout instead of the (default) stderr
1173: - -error_output_none - to turn off all printing of error messages (does not change the way the error is handled.)
1175: Level: developer
1177: Notes:
1178: Use
1179: .vb
1180: PetscErrorPrintf = PetscErrorPrintfNone; to turn off all printing of error messages (does not change the way the
1181: error is handled.) and
1182: PetscErrorPrintf = PetscErrorPrintfDefault; to turn it back on or you can use your own function
1183: .ve
1184: Use
1185: .vb
1186: `PETSC_STDERR` = FILE* obtained from a file open etc. to have stderr printed to the file.
1187: `PETSC_STDOUT` = FILE* obtained from a file open etc. to have stdout printed to the file.
1188: .ve
1190: Use
1191: `PetscPushErrorHandler()` to provide your own error handler that determines what kind of messages to print
1193: .seealso: `PetscFPrintf()`, `PetscSynchronizedPrintf()`, `PetscHelpPrintf()`, `PetscPrintf()`, `PetscPushErrorHandler()`, `PetscVFPrintf()`, `PetscHelpPrintf()`
1194: M*/
1195: PETSC_EXTERN PetscErrorCode (*PetscErrorPrintf)(const char[], ...) PETSC_ATTRIBUTE_FORMAT(1, 2);
1197: /*E
1198: PetscFPTrap - types of floating point exceptions that may be trapped
1200: Currently only `PETSC_FP_TRAP_OFF` and `PETSC_FP_TRAP_ON` are handled. All others are treated as `PETSC_FP_TRAP_ON`.
1202: Level: intermediate
1204: .seealso: `PetscSetFPTrap()`, `PetscPushFPTrap()`
1205: E*/
1206: typedef enum {
1207: PETSC_FP_TRAP_OFF = 0,
1208: PETSC_FP_TRAP_INDIV = 1,
1209: PETSC_FP_TRAP_FLTOPERR = 2,
1210: PETSC_FP_TRAP_FLTOVF = 4,
1211: PETSC_FP_TRAP_FLTUND = 8,
1212: PETSC_FP_TRAP_FLTDIV = 16,
1213: PETSC_FP_TRAP_FLTINEX = 32
1214: } PetscFPTrap;
1215: #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)
1216: PETSC_EXTERN PetscErrorCode PetscSetFPTrap(PetscFPTrap);
1217: PETSC_EXTERN PetscErrorCode PetscFPTrapPush(PetscFPTrap);
1218: PETSC_EXTERN PetscErrorCode PetscFPTrapPop(void);
1219: PETSC_EXTERN PetscErrorCode PetscDetermineInitialFPTrap(void);
1221: /*
1222: Allows the code to build a stack frame as it runs
1223: */
1225: #define PETSCSTACKSIZE 64
1226: typedef struct {
1227: const char *function[PETSCSTACKSIZE];
1228: const char *file[PETSCSTACKSIZE];
1229: int line[PETSCSTACKSIZE];
1230: int petscroutine[PETSCSTACKSIZE]; /* 0 external called from petsc, 1 petsc functions, 2 petsc user functions */
1231: int currentsize;
1232: int hotdepth;
1233: PetscBool check; /* option to check for correct Push/Pop semantics, true for default petscstack but not other stacks */
1234: } PetscStack;
1235: #if defined(PETSC_USE_DEBUG) && !defined(PETSC_HAVE_THREADSAFETY)
1236: PETSC_EXTERN PetscStack petscstack;
1237: #endif
1239: #if defined(PETSC_SERIALIZE_FUNCTIONS)
1240: #include <petsc/private/petscfptimpl.h>
1241: /*
1242: Registers the current function into the global function pointer to function name table
1244: Have to fix this to handle errors but cannot return error since used in PETSC_VIEWER_DRAW_() etc
1245: */
1246: #define PetscRegister__FUNCT__() \
1247: do { \
1248: static PetscBool __chked = PETSC_FALSE; \
1249: if (!__chked) { \
1250: void *ptr; \
1251: PetscCallAbort(PETSC_COMM_SELF, PetscDLSym(NULL, PETSC_FUNCTION_NAME, &ptr)); \
1252: __chked = PETSC_TRUE; \
1253: } \
1254: } while (0)
1255: #else
1256: #define PetscRegister__FUNCT__()
1257: #endif
1259: #if defined(PETSC_CLANG_STATIC_ANALYZER) || defined(__clang_analyzer__)
1260: #define PetscStackPushNoCheck(funct, petsc_routine, hot)
1261: #define PetscStackUpdateLine
1262: #define PetscStackPushExternal(funct)
1263: #define PetscStackPopNoCheck
1264: #define PetscStackClearTop
1265: #define PetscFunctionBegin
1266: #define PetscFunctionBeginUser
1267: #define PetscFunctionBeginHot
1268: #define PetscFunctionReturn(...) return __VA_ARGS__
1269: #define PetscFunctionReturnVoid() return
1270: #define PetscStackPop
1271: #define PetscStackPush(f)
1272: #elif defined(PETSC_USE_DEBUG) && !defined(PETSC_HAVE_THREADSAFETY)
1274: #define PetscStackPush_Private(stack__, file__, func__, line__, petsc_routine__, hot__) \
1275: do { \
1276: if (stack__.currentsize < PETSCSTACKSIZE) { \
1277: stack__.function[stack__.currentsize] = func__; \
1278: if (petsc_routine__) { \
1279: stack__.file[stack__.currentsize] = file__; \
1280: stack__.line[stack__.currentsize] = line__; \
1281: } else { \
1282: stack__.file[stack__.currentsize] = PETSC_NULLPTR; \
1283: stack__.line[stack__.currentsize] = 0; \
1284: } \
1285: stack__.petscroutine[stack__.currentsize] = petsc_routine__; \
1286: } \
1287: ++stack__.currentsize; \
1288: stack__.hotdepth += (hot__ || stack__.hotdepth); \
1289: } while (0)
1291: /* uses PetscCheckAbort() because may be used in a function that does not return an error code */
1292: #define PetscStackPop_Private(stack__, func__) \
1293: do { \
1294: 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__); \
1295: if (--stack__.currentsize < PETSCSTACKSIZE) { \
1296: 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", \
1297: stack__.function[stack__.currentsize], stack__.file[stack__.currentsize], stack__.line[stack__.currentsize], func__, __FILE__, __LINE__); \
1298: stack__.function[stack__.currentsize] = PETSC_NULLPTR; \
1299: stack__.file[stack__.currentsize] = PETSC_NULLPTR; \
1300: stack__.line[stack__.currentsize] = 0; \
1301: stack__.petscroutine[stack__.currentsize] = 0; \
1302: } \
1303: stack__.hotdepth = PetscMax(stack__.hotdepth - 1, 0); \
1304: } while (0)
1306: /*MC
1307: PetscStackPushNoCheck - Pushes a new function name and line number onto the PETSc default stack that tracks where the running program is
1308: currently in the source code.
1310: Not Collective
1312: Synopsis:
1313: #include <petscsys.h>
1314: void PetscStackPushNoCheck(char *funct,int petsc_routine,PetscBool hot);
1316: Input Parameters:
1317: + funct - the function name
1318: . petsc_routine - 2 user function, 1 PETSc function, 0 some other function
1319: - hot - indicates that the function may be called often so expensive error checking should be turned off inside the function
1321: Level: developer
1323: Notes:
1324: 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
1325: 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
1326: help debug the problem.
1328: This version does not check the memory corruption (an expensive operation), use `PetscStackPush()` to check the memory.
1330: Use `PetscStackPushExternal()` for a function call that is about to be made to a non-PETSc or user function (such as BLAS etc).
1332: The default stack is a global variable called `petscstack`.
1334: .seealso: `PetscAttachDebugger()`, `PetscStackCopy()`, `PetscStackView()`, `PetscStackPopNoCheck()`, `PetscCall()`, `PetscFunctionBegin()`,
1335: `PetscFunctionReturn()`, `PetscFunctionBeginHot()`, `PetscFunctionBeginUser()`, `PetscStackPush()`, `PetscStackPop`,
1336: `PetscStackPushExternal()`
1337: M*/
1338: #define PetscStackPushNoCheck(funct, petsc_routine, hot) \
1339: do { \
1340: PetscStackSAWsTakeAccess(); \
1341: PetscStackPush_Private(petscstack, __FILE__, funct, __LINE__, petsc_routine, hot); \
1342: PetscStackSAWsGrantAccess(); \
1343: } while (0)
1345: /*MC
1346: PetscStackUpdateLine - in a function that has a `PetscFunctionBegin` or `PetscFunctionBeginUser` updates the stack line number to the
1347: current line number.
1349: Not Collective
1351: Synopsis:
1352: #include <petscsys.h>
1353: void PetscStackUpdateLine
1355: Level: developer
1357: Notes:
1358: Using `PetscCall()` and friends automatically handles this process
1360: 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
1361: occurred, for example, when a signal is received. It is recommended to use the debugger if extensive information is needed to
1362: help debug the problem.
1364: The default stack is a global variable called petscstack.
1366: This is used by `PetscCall()` and is otherwise not like to be needed
1368: .seealso: `PetscAttachDebugger()`, `PetscStackCopy()`, `PetscStackView()`, `PetscStackPushNoCheck()`, `PetscStackPop`, `PetscCall()`
1369: M*/
1370: #define PetscStackUpdateLine \
1371: do { \
1372: if (petscstack.currentsize > 0 && petscstack.function[petscstack.currentsize - 1] == PETSC_FUNCTION_NAME) { petscstack.line[petscstack.currentsize - 1] = __LINE__; } \
1373: } while (0)
1375: /*MC
1376: PetscStackPushExternal - Pushes a new function name onto the PETSc default stack that tracks where the running program is
1377: currently in the source code. Does not include the filename or line number since this is called by the calling routine
1378: for non-PETSc or user functions.
1380: Not Collective
1382: Synopsis:
1383: #include <petscsys.h>
1384: void PetscStackPushExternal(char *funct);
1386: Input Parameter:
1387: . funct - the function name
1389: Level: developer
1391: Notes:
1392: Using `PetscCallExternal()` and friends automatically handles this process
1394: 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
1395: occurred, for example, when a signal is received. It is recommended to use the debugger if extensive information is needed to
1396: help debug the problem.
1398: The default stack is a global variable called `petscstack`.
1400: This is to be used when calling an external package function such as a BLAS function.
1402: This also updates the stack line number for the current stack function.
1404: .seealso: `PetscAttachDebugger()`, `PetscStackCopy()`, `PetscStackView()`, `PetscStackPopNoCheck()`, `PetscCall()`, `PetscFunctionBegin()`,
1405: `PetscFunctionReturn()`, `PetscFunctionBeginHot()`, `PetscFunctionBeginUser()`, `PetscStackPushNoCheck()`, `PetscStackPop`
1406: M*/
1407: #define PetscStackPushExternal(funct) \
1408: do { \
1409: PetscStackUpdateLine; \
1410: PetscStackPushNoCheck(funct, 0, PETSC_TRUE); \
1411: } while (0);
1413: /*MC
1414: PetscStackPopNoCheck - Pops a function name from the PETSc default stack that tracks where the running program is
1415: currently in the source code.
1417: Not Collective
1419: Synopsis:
1420: #include <petscsys.h>
1421: void PetscStackPopNoCheck(char *funct);
1423: Input Parameter:
1424: . funct - the function name
1426: Level: developer
1428: Notes:
1429: Using `PetscCall()`, `PetscCallExternal()`, `PetscCallBack()` and friends negates the need to call this
1431: 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
1432: occurred, for example, when a signal is received. It is recommended to use the debugger if extensive information is needed to
1433: help debug the problem.
1435: The default stack is a global variable called petscstack.
1437: Developer Note:
1438: `PetscStackPopNoCheck()` takes a function argument while `PetscStackPop` does not, this difference is likely just historical.
1440: .seealso: `PetscAttachDebugger()`, `PetscStackCopy()`, `PetscStackView()`, `PetscStackPushNoCheck()`, `PetscStackPop`
1441: M*/
1442: #define PetscStackPopNoCheck(funct) \
1443: do { \
1444: PetscStackSAWsTakeAccess(); \
1445: PetscStackPop_Private(petscstack, funct); \
1446: PetscStackSAWsGrantAccess(); \
1447: } while (0)
1449: #define PetscStackClearTop \
1450: do { \
1451: PetscStackSAWsTakeAccess(); \
1452: if (petscstack.currentsize > 0 && --petscstack.currentsize < PETSCSTACKSIZE) { \
1453: petscstack.function[petscstack.currentsize] = PETSC_NULLPTR; \
1454: petscstack.file[petscstack.currentsize] = PETSC_NULLPTR; \
1455: petscstack.line[petscstack.currentsize] = 0; \
1456: petscstack.petscroutine[petscstack.currentsize] = 0; \
1457: } \
1458: petscstack.hotdepth = PetscMax(petscstack.hotdepth - 1, 0); \
1459: PetscStackSAWsGrantAccess(); \
1460: } while (0)
1462: /*MC
1463: PetscFunctionBegin - First executable line of each PETSc function, used for error handling. Final
1464: line of PETSc functions should be `PetscFunctionReturn`(0);
1466: Synopsis:
1467: #include <petscsys.h>
1468: void PetscFunctionBegin;
1470: Not Collective; No Fortran Support
1472: Usage:
1473: .vb
1474: int something;
1476: PetscFunctionBegin;
1477: .ve
1479: Level: developer
1481: Note:
1482: Use `PetscFunctionBeginUser` for application codes.
1484: .seealso: `PetscFunctionReturn()`, `PetscFunctionBeginHot()`, `PetscFunctionBeginUser()`, `PetscStackPushNoCheck()`
1486: M*/
1487: #define PetscFunctionBegin \
1488: do { \
1489: PetscStackPushNoCheck(PETSC_FUNCTION_NAME, 1, PETSC_FALSE); \
1490: PetscRegister__FUNCT__(); \
1491: } while (0)
1493: /*MC
1494: PetscFunctionBeginHot - Substitute for `PetscFunctionBegin` to be used in functions that are called in
1495: performance-critical circumstances. Use of this function allows for lighter profiling by default.
1497: Synopsis:
1498: #include <petscsys.h>
1499: void PetscFunctionBeginHot;
1501: Not Collective; No Fortran Support
1503: Usage:
1504: .vb
1505: int something;
1507: PetscFunctionBeginHot;
1508: .ve
1510: Level: developer
1512: .seealso: `PetscFunctionBegin`, `PetscFunctionReturn()`, `PetscStackPushNoCheck()`
1514: M*/
1515: #define PetscFunctionBeginHot \
1516: do { \
1517: PetscStackPushNoCheck(PETSC_FUNCTION_NAME, 1, PETSC_TRUE); \
1518: PetscRegister__FUNCT__(); \
1519: } while (0)
1521: /*MC
1522: PetscFunctionBeginUser - First executable line of user provided routines
1524: Synopsis:
1525: #include <petscsys.h>
1526: void PetscFunctionBeginUser;
1528: Not Collective; No Fortran Support
1530: Usage:
1531: .vb
1532: int something;
1534: PetscFunctionBeginUser;
1535: .ve
1537: Level: intermediate
1539: Notes:
1540: Functions that incorporate this must call `PetscFunctionReturn()` instead of return except for main().
1542: May be used before `PetscInitialize()`
1544: This is identical to `PetscFunctionBegin` except it labels the routine as a user
1545: routine instead of as a PETSc library routine.
1547: .seealso: `PetscFunctionReturn()`, `PetscFunctionBegin`, `PetscFunctionBeginHot`, `PetscStackPushNoCheck()`
1549: M*/
1550: #define PetscFunctionBeginUser \
1551: do { \
1552: PetscStackPushNoCheck(PETSC_FUNCTION_NAME, 2, PETSC_FALSE); \
1553: PetscRegister__FUNCT__(); \
1554: } while (0)
1556: /*MC
1557: PetscStackPush - Pushes a new function name and line number onto the PETSc default stack that tracks where the running program is
1558: currently in the source code and verifies the memory is not corrupted.
1560: Not Collective
1562: Synopsis:
1563: #include <petscsys.h>
1564: void PetscStackPush(char *funct)
1566: Input Parameter:
1567: . funct - the function name
1569: Level: developer
1571: Notes:
1572: 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
1573: occurred, for example, when a signal is received. It is recommended to use the debugger if extensive information is needed to
1574: help debug the problem.
1576: The default stack is a global variable called petscstack.
1578: .seealso: `PetscAttachDebugger()`, `PetscStackCopy()`, `PetscStackView()`, `PetscStackPopNoCheck()`, `PetscCall()`, `PetscFunctionBegin()`,
1579: `PetscFunctionReturn()`, `PetscFunctionBeginHot()`, `PetscFunctionBeginUser()`, `PetscStackPushNoCheck()`, `PetscStackPop`
1580: M*/
1581: #define PetscStackPush(n) \
1582: do { \
1583: PetscStackPushNoCheck(n, 0, PETSC_FALSE); \
1584: CHKMEMQ; \
1585: } while (0)
1587: /*MC
1588: PetscStackPop - Pops a function name from the PETSc default stack that tracks where the running program is
1589: currently in the source code and verifies the memory is not corrupted.
1591: Not Collective
1593: Synopsis:
1594: #include <petscsys.h>
1595: void PetscStackPop
1597: Level: developer
1599: Notes:
1600: 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
1601: occurred, for example, when a signal is received. It is recommended to use the debugger if extensive information is needed to
1602: help debug the problem.
1604: The default stack is a global variable called petscstack.
1606: .seealso: `PetscAttachDebugger()`, `PetscStackCopy()`, `PetscStackView()`, `PetscStackPushNoCheck()`, `PetscStackPopNoCheck()`, `PetscStackPush()`
1607: M*/
1608: #define PetscStackPop \
1609: do { \
1610: CHKMEMQ; \
1611: PetscStackPopNoCheck(PETSC_FUNCTION_NAME); \
1612: } while (0)
1614: /*MC
1615: PetscFunctionReturn - Last executable line of each PETSc function used for error
1616: handling. Replaces `return()`.
1618: Synopsis:
1619: #include <petscerror.h>
1620: void PetscFunctionReturn(...)
1622: Not Collective; No Fortran Support
1624: Level: beginner
1626: Notes:
1627: This routine is a macro, so while it does not "return" anything itself, it does return from
1628: the function in the literal sense.
1630: Usually the return value is the integer literal `0` (for example in any function returning
1631: `PetscErrorCode`), however it is possible to return any arbitrary type. The arguments of
1632: this macro are placed before the `return` statement as-is.
1634: Any routine which returns via `PetscFunctionReturn()` must begin with a corresponding
1635: `PetscFunctionBegin`.
1637: For routines which return `void` use `PetscFunctionReturnVoid()` instead.
1639: Example Usage:
1640: .vb
1641: PetscErrorCode foo(int *x)
1642: {
1643: PetscFunctionBegin; // don't forget the begin!
1644: *x = 10;
1645: PetscFunctionReturn(PETSC_SUCCESS);
1646: }
1647: .ve
1649: May return any arbitrary type\:
1650: .vb
1651: struct Foo
1652: {
1653: int x;
1654: };
1656: struct Foo make_foo(int value)
1657: {
1658: struct Foo f;
1660: PetscFunctionBegin;
1661: f.x = value;
1662: PetscFunctionReturn(f);
1663: }
1664: .ve
1666: .seealso: `PetscFunctionBegin`, `PetscFunctionBeginUser`, `PetscFunctionReturnVoid()`,
1667: `PetscStackPopNoCheck()`
1668: M*/
1669: #define PetscFunctionReturn(...) \
1670: do { \
1671: PetscStackPopNoCheck(PETSC_FUNCTION_NAME); \
1672: return __VA_ARGS__; \
1673: } while (0)
1675: /*MC
1676: PetscFunctionReturnVoid - Like `PetscFunctionReturn()` but returns `void`
1678: Synopsis:
1679: #include <petscerror.h>
1680: void PetscFunctionReturnVoid()
1682: Not Collective
1684: Level: beginner
1686: Note:
1687: Behaves identically to `PetscFunctionReturn()` except that it returns `void`. That is, this
1688: macro culminates with `return`.
1690: Example Usage:
1691: .vb
1692: void foo()
1693: {
1694: PetscFunctionBegin; // must start with PetscFunctionBegin!
1695: bar();
1696: baz();
1697: PetscFunctionReturnVoid();
1698: }
1699: .ve
1701: .seealso: `PetscFunctionReturn()`, `PetscFunctionBegin`, PetscFunctionBeginUser`
1702: M*/
1703: #define PetscFunctionReturnVoid() \
1704: do { \
1705: PetscStackPopNoCheck(PETSC_FUNCTION_NAME); \
1706: return; \
1707: } while (0)
1708: #else /* PETSC_USE_DEBUG */
1709: #define PetscStackPushNoCheck(funct, petsc_routine, hot)
1710: #define PetscStackUpdateLine
1711: #define PetscStackPushExternal(funct)
1712: #define PetscStackPopNoCheck(...)
1713: #define PetscStackClearTop
1714: #define PetscFunctionBegin
1715: #define PetscFunctionBeginUser
1716: #define PetscFunctionBeginHot
1717: #define PetscFunctionReturn(...) return __VA_ARGS__
1718: #define PetscFunctionReturnVoid() return
1719: #define PetscStackPop CHKMEMQ
1720: #define PetscStackPush(f) CHKMEMQ
1721: #endif /* PETSC_USE_DEBUG */
1723: #if defined(PETSC_CLANG_STATIC_ANALYZER)
1724: #define PetscStackCallExternalVoid(...)
1725: template <typename F, typename... Args>
1726: void PetscCallExternal(F, Args...);
1727: #else
1728: /*MC
1729: PetscStackCallExternalVoid - Calls an external library routine or user function after pushing the name of the routine on the stack.
1731: Input Parameters:
1732: + name - string that gives the name of the function being called
1733: - routine - actual call to the routine, for example, functionname(a,b)
1735: Level: developer
1737: Note:
1738: Often one should use `PetscCallExternal()` instead. This routine is intended for external library routines that DO NOT return error codes
1740: In debug mode this also checks the memory for corruption at the end of the function call.
1742: Certain external packages, such as BLAS/LAPACK may have their own macros for managing the call, error checking, etc.
1744: Developer Note:
1745: This is so that when a user or external library routine results in a crash or corrupts memory, they get blamed instead of PETSc.
1747: .seealso: `PetscCall()`, `PetscStackPushNoCheck()`, `PetscStackPush()`, `PetscCallExternal()`, `PetscCallBLAS()`
1748: @*/
1749: #define PetscStackCallExternalVoid(name, ...) \
1750: do { \
1751: PetscStackPush(name); \
1752: __VA_ARGS__; \
1753: PetscStackPop; \
1754: } while (0)
1756: /*MC
1757: PetscCallExternal - Calls an external library routine that returns an error code after pushing the name of the routine on the stack.
1759: Input Parameters:
1760: + func- name of the routine
1761: - args - arguments to the routine
1763: Level: developer
1765: Notes:
1766: This is intended for external package routines that return error codes. Use `PetscStackCallExternalVoid()` for those that do not.
1768: In debug mode this also checks the memory for corruption at the end of the function call.
1770: Assumes the error return code of the function is an integer and that a value of 0 indicates success
1772: Developer Note:
1773: This is so that when an external package routine results in a crash or corrupts memory, they get blamed instead of PETSc.
1775: .seealso: `PetscCall()`, `PetscStackPushNoCheck()`, `PetscStackPush()`, `PetscStackCallExternalVoid()`
1776: M*/
1777: #define PetscCallExternal(func, ...) \
1778: do { \
1779: PetscStackPush(PetscStringize(func)); \
1780: int ierr_petsc_call_external_ = func(__VA_ARGS__); \
1781: PetscStackPop; \
1782: PetscCheck(ierr_petsc_call_external_ == 0, PETSC_COMM_SELF, PETSC_ERR_LIB, "Error in %s(): error code %d", PetscStringize(func), ierr_petsc_call_external_); \
1783: } while (0)
1784: #endif /* PETSC_CLANG_STATIC_ANALYZER */
1786: #endif