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