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: /* SUBMANSEC = Sys */
12: /*
13: These are the generic error codes. These error codes are used
14: many different places in the PETSc source code. The string versions are
15: at src/sys/error/err.c any changes here must also be made there
16: These are also define in src/sys/f90-mod/petscerror.h any CHANGES here
17: must be also made there.
19: */
20: #define PETSC_ERR_MIN_VALUE 54 /* should always be one less then the smallest value */
22: #define PETSC_ERR_MEM 55 /* unable to allocate requested memory */
23: #define PETSC_ERR_SUP 56 /* no support for requested operation */
24: #define PETSC_ERR_SUP_SYS 57 /* no support for requested operation on this computer system */
25: #define PETSC_ERR_ORDER 58 /* operation done in wrong order */
26: #define PETSC_ERR_SIG 59 /* signal received */
27: #define PETSC_ERR_FP 72 /* floating point exception */
28: #define PETSC_ERR_COR 74 /* corrupted PETSc object */
29: #define PETSC_ERR_LIB 76 /* error in library called by PETSc */
30: #define PETSC_ERR_PLIB 77 /* PETSc library generated inconsistent data */
31: #define PETSC_ERR_MEMC 78 /* memory corruption */
32: #define PETSC_ERR_CONV_FAILED 82 /* iterative method (KSP or SNES) failed */
33: #define PETSC_ERR_USER 83 /* user has not provided needed function */
34: #define PETSC_ERR_SYS 88 /* error in system call */
35: #define PETSC_ERR_POINTER 70 /* pointer does not point to valid address */
36: #define PETSC_ERR_MPI_LIB_INCOMP 87 /* MPI library at runtime is not compatible with MPI user compiled with */
38: #define PETSC_ERR_ARG_SIZ 60 /* nonconforming object sizes used in operation */
39: #define PETSC_ERR_ARG_IDN 61 /* two arguments not allowed to be the same */
40: #define PETSC_ERR_ARG_WRONG 62 /* wrong argument (but object probably ok) */
41: #define PETSC_ERR_ARG_CORRUPT 64 /* null or corrupted PETSc object as argument */
42: #define PETSC_ERR_ARG_OUTOFRANGE 63 /* input argument, out of range */
43: #define PETSC_ERR_ARG_BADPTR 68 /* invalid pointer argument */
44: #define PETSC_ERR_ARG_NOTSAMETYPE 69 /* two args must be same object type */
45: #define PETSC_ERR_ARG_NOTSAMECOMM 80 /* two args must be same communicators */
46: #define PETSC_ERR_ARG_WRONGSTATE 73 /* object in argument is in wrong state, e.g. unassembled mat */
47: #define PETSC_ERR_ARG_TYPENOTSET 89 /* the type of the object has not yet been set */
48: #define PETSC_ERR_ARG_INCOMP 75 /* two arguments are incompatible */
49: #define PETSC_ERR_ARG_NULL 85 /* argument is null that should not be */
50: #define PETSC_ERR_ARG_UNKNOWN_TYPE 86 /* type name doesn't match any registered type */
52: #define PETSC_ERR_FILE_OPEN 65 /* unable to open file */
53: #define PETSC_ERR_FILE_READ 66 /* unable to read from file */
54: #define PETSC_ERR_FILE_WRITE 67 /* unable to write to file */
55: #define PETSC_ERR_FILE_UNEXPECTED 79 /* unexpected data in file */
57: #define PETSC_ERR_MAT_LU_ZRPVT 71 /* detected a zero pivot during LU factorization */
58: #define PETSC_ERR_MAT_CH_ZRPVT 81 /* detected a zero pivot during Cholesky factorization */
60: #define PETSC_ERR_INT_OVERFLOW 84
62: #define PETSC_ERR_FLOP_COUNT 90
63: #define PETSC_ERR_NOT_CONVERGED 91 /* solver did not converge */
64: #define PETSC_ERR_MISSING_FACTOR 92 /* MatGetFactor() failed */
65: #define PETSC_ERR_OPT_OVERWRITE 93 /* attempted to over write options which should not be changed */
66: #define PETSC_ERR_WRONG_MPI_SIZE 94 /* example/application run with number of MPI ranks it does not support */
67: #define PETSC_ERR_USER_INPUT 95 /* missing or incorrect user input */
68: #define PETSC_ERR_GPU_RESOURCE 96 /* unable to load a GPU resource, for example cuBLAS */
69: #define PETSC_ERR_GPU 97 /* An error from a GPU call, this may be due to lack of resources on the GPU or a true error in the call */
70: #define PETSC_ERR_MPI 98 /* general MPI error */
71: #define PETSC_ERR_RETURN 99 /* PetscError() incorrectly returned an error code of 0 */
72: #define PETSC_ERR_MAX_VALUE 100 /* this is always the one more than the largest error code */
74: #define SETERRQ1(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
75: #define SETERRQ2(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
76: #define SETERRQ3(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
77: #define SETERRQ4(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
78: #define SETERRQ5(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
79: #define SETERRQ6(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
80: #define SETERRQ7(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
81: #define SETERRQ8(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
82: #define SETERRQ9(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
84: /*MC
85: SETERRQ - Macro to be called when an error has been detected,
87: Synopsis:
88: #include <petscsys.h>
89: PetscErrorCode SETERRQ(MPI_Comm comm,PetscErrorCode ierr,char *message,...)
91: Collective
93: Input Parameters:
94: + comm - A communicator, use `PETSC_COMM_SELF` unless you know all ranks of another communicator will detect the error
95: . ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
96: - message - error message
98: Level: beginner
100: Notes:
102: Once the error handler is called the calling function is then returned from with the given error code.
104: Experienced users can set the error handler with `PetscPushErrorHandler()`.
106: Fortran Notes:
107: SETERRQ() may be called from Fortran subroutines but SETERRA() must be called from the
108: Fortran main program.
111: `PetscError()`, `PetscCall()`, `CHKMEMQ`, `CHKERRA()`, `PetscCallMPI()`
112: M*/
113: #define SETERRQ(comm, ierr, ...) \
114: do { \
115: PetscErrorCode ierr_seterrq_petsc_ = PetscError(comm, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr, PETSC_ERROR_INITIAL, __VA_ARGS__); \
116: return ierr_seterrq_petsc_ ? ierr_seterrq_petsc_ : PETSC_ERR_RETURN; \
117: } while (0)
119: /*
120: Returned from PETSc functions that are called from MPI, such as related to attributes
121: Do not confuse PETSC_MPI_ERROR_CODE and PETSC_ERR_MPI, the first is registered with MPI and returned to MPI as
122: an error code, the latter is a regular PETSc error code passed within PETSc code indicating an error was detected in an MPI call.
123: */
124: PETSC_EXTERN PetscMPIInt PETSC_MPI_ERROR_CLASS;
125: PETSC_EXTERN PetscMPIInt PETSC_MPI_ERROR_CODE;
127: /*MC
128: SETERRMPI - Macro to be called when an error has been detected within an MPI callback function
130: Synopsis:
131: #include <petscsys.h>
132: PetscErrorCode SETERRMPI(MPI_Comm comm,PetscErrorCode ierr,char *message,...)
134: Collective
136: Input Parameters:
137: + comm - A communicator, use `PETSC_COMM_SELF` unless you know all ranks of another communicator will detect the error
138: . ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
139: - message - error message
141: Level: developer
143: Notes:
144: 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`
145: which is registered with `MPI_Add_error_code()` when PETSc is initialized.
147: .seealso: `SETERRQ()`, `PetscCall()`, `PetscCallMPI()`, `PetscTraceBackErrorHandler()`, `PetscPushErrorHandler()`, `PetscError()`, `CHKMEMQ`
148: M*/
149: #define SETERRMPI(comm, ierr, ...) return (PetscError(comm, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr, PETSC_ERROR_INITIAL, __VA_ARGS__), PETSC_MPI_ERROR_CODE)
151: /*MC
152: SETERRA - Fortran-only macro that can be called when an error has been detected from the main program
154: Synopsis:
155: #include <petscsys.h>
156: PetscErrorCode SETERRA(MPI_Comm comm,PetscErrorCode ierr,char *message)
158: Collective
160: Input Parameters:
161: + comm - A communicator, so that the error can be collective
162: . ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
163: - message - error message in the printf format
165: Level: beginner
167: Notes:
168: This should only be used with Fortran. With C/C++, use `SETERRQ()`.
170: Fortran Notes:
171: `SETERRQ()` may be called from Fortran subroutines but `SETERRA()` must be called from the
172: Fortran main program.
174: .seealso: `SETERRQ()`, `SETERRABORT()`, `PetscCall()`, `CHKERRA()`, `PetscCallAbort()`
175: M*/
177: /*MC
178: SETERRABORT - Macro that can be called when an error has been detected,
180: Synopsis:
181: #include <petscsys.h>
182: PetscErrorCode SETERRABORT(MPI_Comm comm,PetscErrorCode ierr,char *message,...)
184: Collective
186: Input Parameters:
187: + comm - A communicator, so that the error can be collective
188: . ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
189: - message - error message in the printf format
191: Level: beginner
193: Notes:
194: This function just calls `MPI_Abort()`.
196: This should only be called in routines that cannot return an error code, such as in C++ constructors.
198: .seealso: `SETERRQ()`, `PetscTraceBackErrorHandler()`, `PetscPushErrorHandler()`, `PetscError()`, `PetscCall()`, `CHKMEMQ`
199: M*/
200: #define SETERRABORT(comm, ierr, ...) \
201: do { \
202: PetscError(comm, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr, PETSC_ERROR_INITIAL, __VA_ARGS__); \
203: MPI_Abort(comm, ierr); \
204: } while (0)
206: /*MC
209: Synopsis:
210: #include <petscerror.h>
213: Collective
215: Input Parameters:
216: + cond - The boolean condition
217: . comm - The communicator on which the check can be collective on
218: . ierr - A nonzero error code, see include/petscerror.h for the complete list
219: - message - Error message in printf format
221: Notes:
222: Enabled in both optimized and debug builds.
224: Calls `SETERRQ()` if the assertion fails, so can only be called from functions returning a
225: `PetscErrorCode` (or equivalent type after conversion).
227: Level: beginner
230: M*/
232: do { \
233: if (PetscUnlikely(!(cond))) SETERRQ(comm, ierr, __VA_ARGS__); \
234: } while (0)
236: /*MC
239: Synopsis:
240: #include <petscerror.h>
243: Collective
245: Input Parameters:
246: + cond - The boolean condition
247: . comm - The communicator on which the check can be collective on
248: . ierr - A nonzero error code, see include/petscerror.h for the complete list
249: - message - Error message in printf format
251: Notes:
252: Enabled in both optimized and debug builds.
254: Calls `SETERRABORT()` if the assertion fails, can be called from a function that does not return an
257: Level: developer
260: M*/
262: do { \
263: if (PetscUnlikely(!(cond))) SETERRABORT(comm, ierr, __VA_ARGS__); \
264: } while (0)
266: /*MC
267: PetscAssert - Assert that a particular condition is true
269: Synopsis:
270: #include <petscerror.h>
271: void PetscAssert(bool cond, MPI_Comm comm, PetscErrorCode ierr, const char *message, ...)
273: Collective
275: Input Parameters:
276: + cond - The boolean condition
277: . comm - The communicator on which the check can be collective on
278: . ierr - A nonzero error code, see include/petscerror.h for the complete list
279: - message - Error message in printf format
281: Notes:
286: This is needed instead of simply using `assert()` because this correctly handles the collective nature of errors under MPI
288: Level: beginner
291: M*/
292: #if PetscDefined(USE_DEBUG)
294: #else
295: #define PetscAssert(cond, ...) PetscAssume(cond)
296: #endif
298: /*MC
299: PetscAssertAbort - Assert that a particular condition is true, otherwise prints error and aborts
301: Synopsis:
302: #include <petscerror.h>
303: void PetscAssertAbort(bool cond, MPI_Comm comm, PetscErrorCode ierr, const char *message, ...)
305: Collective
307: Input Parameters:
308: + cond - The boolean condition
309: . comm - The communicator on which the check can be collective on
310: . ierr - A nonzero error code, see include/petscerror.h for the complete list
311: - message - Error message in printf format
313: Notes:
316: Level: beginner
319: M*/
320: #define PetscAssertAbort(cond, comm, ierr, ...) \
321: do { \
322: if (PetscUnlikelyDebug(!(cond))) SETERRABORT(comm, ierr, __VA_ARGS__); \
323: } while (0)
325: /*MC
326: PetscCall - Calls a PETSc function and then checks the resulting error code, if it is non-zero it calls the error
327: handler and returns from the current function with the error code.
329: Synopsis:
330: #include <petscerror.h>
331: void PetscCall(PetscFunction(args))
333: Not Collective
335: Input Parameter:
336: . PetscFunction - any PETSc function that returns an error code
338: Notes:
339: Once the error handler is called the calling function is then returned from with the given
340: error code. Experienced users can set the error handler with `PetscPushErrorHandler()`.
342: `PetscCall()` cannot be used in functions returning a datatype not convertible to
343: `PetscErrorCode`. For example, `PetscCall()` may not be used in functions returning void, use
344: `PetscCallVoid()` in this case.
346: Example Usage:
347: .vb
348: PetscInitiailize(...); // OK to call even when PETSc is not yet initialized!
350: struct my_struct
351: {
352: void *data;
353: } my_complex_type;
355: struct my_struct bar(void)
356: {
357: foo(15); // ERROR PetscErrorCode not convertible to struct my_struct!
358: }
360: PetscCall(bar()) // ERROR input not convertible to PetscErrorCode
361: .ve
363: It is also possible to call this directly on a `PetscErrorCode` variable
364: .vb
365: ierr; // check if ierr is nonzero
366: .ve
368: Should not be used to call callback functions provided by users, `PetscCallBack()` should be used in that situation.
370: `PetscUseTypeMethod()` or `PetscTryTypeMethod()` should be used when calling functions pointers contained in a PETSc object's `ops` array
372: Fortran Notes:
373: The Fortran function from which this is used must declare a variable PetscErrorCode ierr and ierr must be
374: the final argument to the PETSc function being called.
376: In the main program and in Fortran subroutines that do not have ierr as the final return parameter one
377: should use `PetscCallA()`
379: Example Fortran Usage:
380: .vb
381: PetscErrorCode ierr
382: Vec v
384: ...
385: PetscCall(VecShift(v,1.0,ierr))
386: PetscCallA(VecShift(v,1.0,ierr))
387: .ve
389: Level: beginner
392: `PetscPushErrorHandler()`, `PetscError()`, `CHKMEMQ`, `CHKERRA()`, `CHKERRMPI()`, `PetscCallBack()`
393: M*/
395: /*MC
396: PetscCallBack - Calls a user provided PETSc callback function and then checks the resulting error code, if it is non-zero it calls the error
397: handler and returns from the current function with the error code.
399: Synopsis:
400: #include <petscerror.h>
401: void PetscCallBack(const char *functionname,PetscFunction(args))
403: Not Collective
405: Input Parameters:
406: + functionname - the name of the function being called, this can be a string with spaces that describes the meaning of the callback
407: - PetscFunction - user provided callback function that returns an error code
409: Notes:
410: Once the error handler is called the calling function is then returned from with the given
411: error code. Experienced users can set the error handler with `PetscPushErrorHandler()`.
413: `PetscCallBack()` should only be called in PETSc when a call is being made to a user provided call-back routine.
415: Example Usage:
416: .vb
417: PetscCallBack("XXX callback to do something",a->callback(...));
418: .ve
420: Level: developer
423: `PetscPushErrorHandler()`, `PetscError()`, `CHKMEMQ`, `CHKERRA()`, `CHKERRMPI()`, `PetscCall()`
424: M*/
426: #if defined(PETSC_CLANG_STATIC_ANALYZER)
427: void PetscErrorCode;
428: void PetscCallBack(const char *, PetscErrorCode);
429: void PetscErrorCode;
430: #else
431: #define PetscCall(...) \
432: do { \
433: PetscErrorCode ierr_q_; \
434: PetscStackUpdateLine; \
435: ierr_q_ = __VA_ARGS__; \
436: if (PetscUnlikely(ierr_q_)) return PetscError(PETSC_COMM_SELF, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr_q_, PETSC_ERROR_REPEAT, " "); \
437: } while (0)
438: #define PetscCallBack(function, ...) \
439: do { \
440: PetscErrorCode ierr_q_; \
441: PetscStackUpdateLine; \
442: PetscStackPushExternal(function); \
443: ierr_q_ = __VA_ARGS__; \
444: PetscStackPop; \
445: if (PetscUnlikely(ierr_q_)) return PetscError(PETSC_COMM_SELF, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr_q_, PETSC_ERROR_REPEAT, " "); \
446: } while (0)
447: #define PetscCallVoid(...) \
448: do { \
449: PetscErrorCode ierr_void_; \
450: PetscStackUpdateLine; \
451: ierr_void_ = __VA_ARGS__; \
452: if (PetscUnlikely(ierr_void_)) { \
453: (void)PetscError(PETSC_COMM_SELF, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr_void_, PETSC_ERROR_REPEAT, " "); \
454: return; \
455: } \
456: } while (0)
457: #endif
459: /*MC
460: CHKERRQ - Checks error code returned from PETSc function
462: Synopsis:
463: #include <petscsys.h>
464: void CHKERRQ(PetscErrorCode ierr)
466: Not Collective
468: Input Parameters:
469: . ierr - nonzero error code
471: Notes:
472: Deprecated in favor of `PetscCall()`. This routine behaves identically to it.
474: Level: deprecated
476: .seealso: `PetscCall()`
477: M*/
478: #define CHKERRQ(...) PetscCall(__VA_ARGS__)
479: #define CHKERRV(...) PetscCallVoid(__VA_ARGS__)
481: PETSC_EXTERN void PetscMPIErrorString(PetscMPIInt, char *);
483: /*MC
484: PetscCallMPI - Checks error code returned from MPI calls, if non-zero it calls the error
485: handler and then returns
487: Synopsis:
488: #include <petscerror.h>
489: void PetscCallMPI(MPI_Function(args))
491: Not Collective
493: Input Parameters:
494: . MPI_Function - an MPI function that returns an MPI error code
496: Notes:
497: Always returns the error code `PETSC_ERR_MPI`; the MPI error code and string are embedded in
498: the string error message. Do not use this to call any other routines (for example PETSc
499: routines), it should only be used for direct MPI calls. Due to limitations of the
500: preprocessor this can unfortunately not easily be enforced, so the user should take care to
501: check this themselves.
503: Example Usage:
504: .vb
505: MPI_Comm_size(...); // OK, calling MPI function
507: PetscFunction(...); // ERROR, use PetscCall() instead!
508: .ve
510: Fortran Notes:
511: The Fortran function from which this is used must declare a variable `PetscErrorCode` ierr and ierr must be
512: the final argument to the MPI function being called.
514: In the main program and in Fortran subroutines that do not have ierr as the final return parameter one
515: should use `PetscCallMPIA()`
517: Fortran Usage:
518: .vb
519: PetscErrorCode ierr or integer ierr
520: ...
521: PetscCallMPI(MPI_Comm_size(...,ierr))
522: PetscCallMPIA(MPI_Comm_size(...,ierr)) ! Will abort after calling error handler
524: PetscCallMPI(MPI_Comm_size(...,eflag)) ! ERROR, final argument must be ierr
525: .ve
527: Level: beginner
529: .seealso: `SETERRMPI()`, `PetscCall()`, `SETERRQ()`, `SETERRABORT()`, `PetscCallAbort()`,
530: `PetscTraceBackErrorHandler()`, `PetscPushErrorHandler()`, `PetscError()`, `CHKMEMQ`
531: M*/
532: #if defined(PETSC_CLANG_STATIC_ANALYZER)
533: void PetscMPIInt;
534: #else
535: #define PetscCallMPI(...) \
536: do { \
537: PetscMPIInt _7_errorcode; \
538: char _7_errorstring[2 * MPI_MAX_ERROR_STRING]; \
539: PetscStackUpdateLine; \
540: PetscStackPushExternal("MPI function"); \
541: { \
542: _7_errorcode = __VA_ARGS__; \
543: } \
544: PetscStackPop; \
545: if (PetscUnlikely(_7_errorcode)) { \
546: PetscMPIErrorString(_7_errorcode, (char *)_7_errorstring); \
547: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_MPI, "MPI error %d %s", (int)_7_errorcode, _7_errorstring); \
548: } \
549: } while (0)
550: #endif
552: /*MC
553: CHKERRMPI - Checks error code returned from MPI calls, if non-zero it calls the error
554: handler and then returns
556: Synopsis:
557: #include <petscerror.h>
558: void CHKERRMPI(PetscErrorCode ierr)
560: Not Collective
562: Input Parameter:
563: . ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
565: Notes:
566: Deprecated in favor of `PetscCallMPI()`. This routine behaves identically to it.
568: Level: deprecated
570: .seealso: `PetscCallMPI()`
571: M*/
572: #define CHKERRMPI(...) PetscCallMPI(__VA_ARGS__)
574: /*MC
575: PetscCallAbort - Checks error code returned from PETSc function, if non-zero it aborts immediately
577: Synopsis:
578: #include <petscerror.h>
579: void PetscCallAbort(MPI_Comm comm, PetscErrorCode ierr)
581: Collective on comm
583: Input Parameters:
584: + comm - the MPI communicator on which to abort
585: - ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
587: Notes:
588: This macro has identical type and usage semantics to `PetscCall()` with the important caveat
589: that this macro does not return. Instead, if ierr is nonzero it calls the PETSc error handler
590: and then immediately calls `MPI_Abort()`. It can therefore be used anywhere.
592: As per `MPI_Abort()` semantics the communicator passed must be valid, although there is currently
593: no attempt made at handling any potential errors from `MPI_Abort()`. Note that while
594: `MPI_Abort()` is required to terminate only those processes which reside on comm, it is often
595: the case that `MPI_Abort()` terminates *all* processes.
597: Example Usage:
598: .vb
599: PetscErrorCode boom(void) { return PETSC_ERR_MEM; }
601: void foo(void)
602: {
603: PETSC_COMM_WORLD,boom(); // OK, does not return a type
604: }
606: double bar(void)
607: {
608: PETSC_COMM_WORLD,boom(); // OK, does not return a type
609: }
611: MPI_COMM_NULL,boom(); // ERROR, communicator should be valid
613: struct baz
614: {
615: baz()
616: {
617: PETSC_COMM_SELF,boom(); // OK
618: }
620: ~baz()
621: {
622: PETSC_COMM_SELF,boom(); // OK (in fact the only way to handle PETSc errors)
623: }
624: };
625: .ve
627: Level: intermediate
629: .seealso: `SETERRABORT()`, `PetscTraceBackErrorHandler()`, `PetscPushErrorHandler()`, `PetscError()`,
630: `SETERRQ()`, `CHKMEMQ`, `PetscCallMPI()`
631: M*/
632: #if defined(PETSC_CLANG_STATIC_ANALYZER)
633: void MPI_Comm, PetscErrorCode;
634: void PetscErrorCode;
635: #else
636: #define PetscCallAbort(comm, ...) \
637: do { \
638: PetscErrorCode ierr_abort_ = __VA_ARGS__; \
639: if (PetscUnlikely(ierr_abort_)) { \
640: PetscError(PETSC_COMM_SELF, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr_abort_, PETSC_ERROR_REPEAT, " "); \
641: MPI_Abort(comm, ierr_abort_); \
642: } \
643: } while (0)
644: #define PetscCallContinue(...) \
645: do { \
646: PetscErrorCode ierr_continue_ = __VA_ARGS__; \
647: if (PetscUnlikely(ierr_continue_)) PetscError(PETSC_COMM_SELF, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr_continue_, PETSC_ERROR_REPEAT, " "); \
648: } while (0)
649: #endif
651: /*MC
652: CHKERRABORT - Checks error code returned from PETSc function. If non-zero it aborts immediately.
654: Synopsis:
655: #include <petscerror.h>
656: void CHKERRABORT(MPI_Comm comm, PetscErrorCode ierr)
658: Not Collective
660: Input Parameters:
661: + comm - the MPI communicator
662: - ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
664: Notes:
665: Deprecated in favor of `PetscCallAbort()`. This routine behaves identically to it.
667: Level: deprecated
669: .seealso: `PetscCallAbort()`
670: M*/
671: #define CHKERRABORT(comm, ...) PetscCallAbort(comm, __VA_ARGS__)
672: #define CHKERRCONTINUE(...) PetscCallContinue(__VA_ARGS__)
674: /*MC
675: CHKERRA - Fortran-only replacement for use of `CHKERRQ()` in the main program, which aborts immediately
677: Synopsis:
678: #include <petscsys.h>
679: PetscErrorCode CHKERRA(PetscErrorCode ierr)
681: Not Collective
683: Input Parameters:
684: . ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
686: Level: deprecated
688: Note:
689: This macro is rarely needed, normal usage is `PetscCallA()` in the main Fortran program.
691: .seealso: `PetscCall()`, `PetscCallA()`, `PetscCallAbort()`, `CHKERRQ()`, `SETERRA()`, `SETERRQ()`, `SETERRABORT()`
692: M*/
694: PETSC_EXTERN PetscBool petscwaitonerrorflg;
695: PETSC_EXTERN PetscBool petscindebugger;
697: /*MC
698: PETSCABORT - Call MPI_Abort with an informative error code
700: Synopsis:
701: #include <petscsys.h>
702: PETSCABORT(MPI_Comm comm, PetscErrorCode ierr)
704: Collective
706: Input Parameters:
707: + comm - A communicator, so that the error can be collective
708: - ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
710: Level: advanced
712: Notes:
713: If the option -start_in_debugger was used then this calls abort() to stop the program in the debugger.
715: if `PetscCIEnabledPortableErrorOutput` is set it strives to exit cleanly without call `MPI_Abort()`
717: M*/
718: #define PETSCABORT(comm, ...) \
719: do { \
720: if (petscwaitonerrorflg) PetscSleep(1000); \
721: if (petscindebugger) abort(); \
722: else { \
723: PetscErrorCode ierr_petsc_abort_ = __VA_ARGS__; \
724: PetscMPIInt size; \
725: MPI_Comm_size(comm, &size); \
726: if (PetscCIEnabledPortableErrorOutput && size == PetscGlobalSize && ierr_petsc_abort_ != PETSC_ERR_SIG) { \
727: MPI_Finalize(); \
728: exit(0); \
729: } else if (PetscCIEnabledPortableErrorOutput && PetscGlobalSize == 1) { \
730: exit(0); \
731: } else { \
732: MPI_Abort(comm, (PetscMPIInt)ierr_petsc_abort_); \
733: } \
734: } \
735: } while (0)
737: #ifdef PETSC_CLANGUAGE_CXX
738: /*MC
739: PetscCallThrow - Checks error code, if non-zero it calls the C++ error handler which throws
740: an exception
742: Synopsis:
743: #include <petscerror.h>
744: void PetscCallThrow(PetscErrorCode ierr)
746: Not Collective
748: Input Parameter:
749: . ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
751: Notes:
752: Requires PETSc to be configured with clanguage = c++. Throws a std::runtime_error() on error.
754: Once the error handler throws the exception you can use `PetscCallVoid()` which returns without
755: an error code (bad idea since the error is ignored) or `PetscCallAbort()` to have `MPI_Abort()`
756: called immediately.
758: Level: beginner
760: .seealso: `SETERRQ()`, `PetscCall()`, `SETERRABORT()`, `PetscCallAbort()`, `PetscTraceBackErrorHandler()`,
761: `PetscPushErrorHandler()`, `PetscError()`, `CHKMEMQ`
762: M*/
763: #define PetscCallThrow(...) \
764: do { \
765: PetscErrorCode ierr_cxx_ = __VA_ARGS__; \
766: if (PetscUnlikely(ierr_cxx_)) PetscError(PETSC_COMM_SELF, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr_cxx_, PETSC_ERROR_IN_CXX, PETSC_NULLPTR); \
767: } while (0)
769: /*MC
770: CHKERRXX - Checks error code, if non-zero it calls the C++ error handler which throws an exception
772: Synopsis:
773: #include <petscerror.h>
774: void CHKERRXX(PetscErrorCode ierr)
776: Not Collective
778: Input Parameter:
779: . ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
781: Notes:
782: Deprecated in favor of `PetscCallThrow()`. This routine behaves identically to it.
784: Level: deprecated
786: .seealso: `PetscCallThrow()`
787: M*/
788: #define CHKERRXX(...) PetscCallThrow(__VA_ARGS__)
789: #endif
791: /*MC
792: PetscCallCXX - Checks C++ function calls and if they throw an exception, catch it and then
793: return a PETSc error code
795: Synopsis:
796: #include <petscerror.h>
797: void PetscCallCXX(expr) noexcept;
799: Not Collective
801: Input Parameter:
802: . expr - An arbitrary expression
804: Notes:
805: PetscCallCXX(expr) is a macro replacement for
806: .vb
807: try {
808: expr;
809: } catch (const std::exception& e) {
810: return ConvertToPetscErrorCode(e);
811: }
812: .ve
813: Due to the fact that it catches any (reasonable) exception, it is essentially noexcept.
815: Example Usage:
816: .vb
817: void foo(void) { throw std::runtime_error("error"); }
819: void bar()
820: {
821: foo(); // ERROR bar() does not return PetscErrorCode
822: }
824: PetscErrorCode baz()
825: {
826: foo(); // OK
828: PetscCallCXX(
829: bar();
830: foo(); // OK mutliple statements allowed
831: );
832: }
834: struct bop
835: {
836: bop()
837: {
838: foo(); // ERROR returns PetscErrorCode, cannot be used in constructors
839: }
840: };
842: // ERROR contains do-while, cannot be used as function-try block
843: PetscErrorCode qux() PetscCallCXX(
844: bar();
845: baz();
846: foo();
847: return 0;
848: )
849: .ve
851: Level: beginner
853: .seealso: `PetscCallThrow()`, `SETERRQ()`, `PetscCall()`, `SETERRABORT()`, `PetscCallAbort()`,
854: `PetscTraceBackErrorHandler()`, `PetscPushErrorHandler()`, `PetscError()`, `CHKMEMQ`
855: M*/
856: #define PetscCallCXX(...) \
857: do { \
858: PetscStackUpdateLine; \
859: try { \
860: __VA_ARGS__; \
861: } catch (const std::exception &e) { \
862: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "%s", e.what()); \
863: } \
864: } while (0)
866: /*MC
867: CHKERRCXX - Checks C++ function calls and if they throw an exception, catch it and then
868: return a PETSc error code
870: Synopsis:
871: #include <petscerror.h>
872: void CHKERRCXX(func) noexcept;
874: Not Collective
876: Input Parameter:
877: . func - C++ function calls
879: Notes:
880: Deprecated in favor of `PetscCallCXX()`. This routine behaves identically to it.
882: Level: deprecated
884: .seealso: `PetscCallCXX()`
885: M*/
886: #define CHKERRCXX(...) PetscCallCXX(__VA_ARGS__)
888: /*MC
889: CHKMEMQ - Checks the memory for corruption, calls error handler if any is detected
891: Synopsis:
892: #include <petscsys.h>
893: CHKMEMQ;
895: Not Collective
897: Level: beginner
899: Notes:
900: We highly recommend using Valgrind https://petsc.org/release/faq/#valgrind or for NVIDIA CUDA systems
901: https://docs.nvidia.com/cuda/cuda-memcheck/index.html for finding memory problems. The ``CHKMEMQ`` macro is useful on systems that
902: do not have valgrind, but is not as good as valgrind or cuda-memcheck.
904: Must run with the option -malloc_debug (-malloc_test in debug mode; or if `PetscMallocSetDebug()` called) to enable this option
906: Once the error handler is called the calling function is then returned from with the given error code.
908: By defaults prints location where memory that is corrupted was allocated.
910: Use `CHKMEMA` for functions that return void
912: .seealso: `PetscTraceBackErrorHandler()`, `PetscPushErrorHandler()`, `PetscError()`, `SETERRQ()`, `PetscMallocValidate()`
913: M*/
914: #if defined(PETSC_CLANG_STATIC_ANALYZER)
915: #define CHKMEMQ
916: #define CHKMEMA
917: #else
918: #define CHKMEMQ \
919: do { \
920: PetscErrorCode ierr_memq_ = PetscMallocValidate(__LINE__, PETSC_FUNCTION_NAME, __FILE__); \
921: if (PetscUnlikely(ierr_memq_)) return PetscError(PETSC_COMM_SELF, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr_memq_, PETSC_ERROR_REPEAT, " "); \
922: } while (0)
923: #define CHKMEMA PetscMallocValidate(__LINE__, PETSC_FUNCTION_NAME, __FILE__)
924: #endif
926: /*E
927: PetscErrorType - passed to the PETSc error handling routines indicating if this is the first or a later call to the error handlers
929: Level: advanced
931: `PETSC_ERROR_IN_CXX` indicates the error was detected in C++ and an exception should be generated
933: Developer Notes:
934: This is currently used to decide when to print the detailed information about the run in PetscTraceBackErrorHandler()
936: .seealso: `PetscError()`, `SETERRQ()`
937: E*/
938: typedef enum {
939: PETSC_ERROR_INITIAL = 0,
940: PETSC_ERROR_REPEAT = 1,
941: PETSC_ERROR_IN_CXX = 2
942: } PetscErrorType;
944: #if defined(__clang_analyzer__)
945: __attribute__((analyzer_noreturn))
946: #endif
947: PETSC_EXTERN PetscErrorCode
948: PetscError(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, ...) PETSC_ATTRIBUTE_COLD PETSC_ATTRIBUTE_FORMAT(7, 8);
950: PETSC_EXTERN PetscErrorCode PetscErrorPrintfInitialize(void);
951: PETSC_EXTERN PetscErrorCode PetscErrorMessage(int, const char *[], char **);
952: PETSC_EXTERN PetscErrorCode PetscTraceBackErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD;
953: PETSC_EXTERN PetscErrorCode PetscIgnoreErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD;
954: PETSC_EXTERN PetscErrorCode PetscEmacsClientErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD;
955: PETSC_EXTERN PetscErrorCode PetscMPIAbortErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD;
956: PETSC_EXTERN PetscErrorCode PetscAbortErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD;
957: PETSC_EXTERN PetscErrorCode PetscAttachDebuggerErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD;
958: PETSC_EXTERN PetscErrorCode PetscReturnErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD;
959: PETSC_EXTERN PetscErrorCode PetscPushErrorHandler(PetscErrorCode (*handler)(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *), void *);
960: PETSC_EXTERN PetscErrorCode PetscPopErrorHandler(void);
961: PETSC_EXTERN PetscErrorCode PetscSignalHandlerDefault(int, void *);
962: PETSC_EXTERN PetscErrorCode PetscPushSignalHandler(PetscErrorCode (*)(int, void *), void *);
963: PETSC_EXTERN PetscErrorCode PetscPopSignalHandler(void);
965: PETSC_EXTERN void PetscSignalSegvCheckPointerOrMpi(void);
966: PETSC_DEPRECATED_FUNCTION("Use PetscSignalSegvCheckPointerOrMpi() (since version 3.13)") static inline void PetscSignalSegvCheckPointer(void)
967: {
968: PetscSignalSegvCheckPointerOrMpi();
969: }
971: /*MC
972: PetscErrorPrintf - Prints error messages.
974: Synopsis:
975: #include <petscsys.h>
976: PetscErrorCode (*PetscErrorPrintf)(const char format[],...);
978: Not Collective
980: Input Parameter:
981: . format - the usual printf() format string
983: Options Database Keys:
984: + -error_output_stdout - cause error messages to be printed to stdout instead of the (default) stderr
985: - -error_output_none - to turn off all printing of error messages (does not change the way the error is handled.)
987: Notes:
988: Use
989: $ PetscErrorPrintf = PetscErrorPrintfNone; to turn off all printing of error messages (does not change the way the
990: $ error is handled.) and
991: $ PetscErrorPrintf = PetscErrorPrintfDefault; to turn it back on or you can use your own function
993: Use
994: `PETSC_STDERR` = FILE* obtained from a file open etc. to have stderr printed to the file.
995: `PETSC_STDOUT` = FILE* obtained from a file open etc. to have stdout printed to the file.
997: Use
998: `PetscPushErrorHandler()` to provide your own error handler that determines what kind of messages to print
1000: Level: developer
1002: Fortran Note:
1003: This routine is not supported in Fortran.
1005: .seealso: `PetscFPrintf()`, `PetscSynchronizedPrintf()`, `PetscHelpPrintf()`, `PetscPrintf()`, `PetscPushErrorHandler()`, `PetscVFPrintf()`, `PetscHelpPrintf()`
1006: M*/
1007: PETSC_EXTERN PetscErrorCode (*PetscErrorPrintf)(const char[], ...) PETSC_ATTRIBUTE_FORMAT(1, 2);
1009: /*E
1010: PetscFPTrap - types of floating point exceptions that may be trapped
1012: Currently only `PETSC_FP_TRAP_OFF` and `PETSC_FP_TRAP_ON` are handled. All others are treated as `PETSC_FP_TRAP_ON`.
1014: Level: intermediate
1016: .seealso: `PetscSetFPTrap()`, `PetscPushFPTrap()`
1017: E*/
1018: typedef enum {
1019: PETSC_FP_TRAP_OFF = 0,
1020: PETSC_FP_TRAP_INDIV = 1,
1021: PETSC_FP_TRAP_FLTOPERR = 2,
1022: PETSC_FP_TRAP_FLTOVF = 4,
1023: PETSC_FP_TRAP_FLTUND = 8,
1024: PETSC_FP_TRAP_FLTDIV = 16,
1025: PETSC_FP_TRAP_FLTINEX = 32
1026: } PetscFPTrap;
1027: #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)
1028: PETSC_EXTERN PetscErrorCode PetscSetFPTrap(PetscFPTrap);
1029: PETSC_EXTERN PetscErrorCode PetscFPTrapPush(PetscFPTrap);
1030: PETSC_EXTERN PetscErrorCode PetscFPTrapPop(void);
1031: PETSC_EXTERN PetscErrorCode PetscDetermineInitialFPTrap(void);
1033: /*
1034: Allows the code to build a stack frame as it runs
1035: */
1037: #if defined(PETSC_USE_DEBUG)
1038: #define PETSCSTACKSIZE 64
1039: typedef struct {
1040: const char *function[PETSCSTACKSIZE];
1041: const char *file[PETSCSTACKSIZE];
1042: int line[PETSCSTACKSIZE];
1043: int petscroutine[PETSCSTACKSIZE]; /* 0 external called from petsc, 1 petsc functions, 2 petsc user functions */
1044: int currentsize;
1045: int hotdepth;
1046: PetscBool check; /* option to check for correct Push/Pop semantics, true for default petscstack but not other stacks */
1047: } PetscStack;
1048: PETSC_EXTERN PetscStack petscstack;
1049: #else
1050: typedef struct {
1051: char Silence_empty_struct_has_size_0_in_C_size_1_in_Cpp;
1052: } PetscStack;
1053: #endif
1055: #if defined(PETSC_SERIALIZE_FUNCTIONS)
1056: #include <petsc/private/petscfptimpl.h>
1057: /*
1058: Registers the current function into the global function pointer to function name table
1060: Have to fix this to handle errors but cannot return error since used in PETSC_VIEWER_DRAW_() etc
1061: */
1062: #define PetscRegister__FUNCT__() \
1063: do { \
1064: static PetscBool __chked = PETSC_FALSE; \
1065: if (!__chked) { \
1066: void *ptr; \
1067: PetscDLSym(NULL, PETSC_FUNCTION_NAME, &ptr); \
1068: __chked = PETSC_TRUE; \
1069: } \
1070: } while (0)
1071: #else
1072: #define PetscRegister__FUNCT__()
1073: #endif
1075: #if defined(PETSC_CLANG_STATIC_ANALYZER)
1076: #define PetscStackPushNoCheck(funct, petsc_routine, hot)
1077: #define PetscStackUpdateLine
1078: #define PetscStackPushExternal(funct)
1079: #define PetscStackPopNoCheck
1080: #define PetscStackClearTop
1084: #define return a return a
1085: #define return return
1086: #define PetscStackPop
1087: #define PetscStackPush(f)
1088: #elif defined(PETSC_USE_DEBUG)
1090: #define PetscStackPush_Private(stack__, file__, func__, line__, petsc_routine__, hot__) \
1091: do { \
1092: if (stack__.currentsize < PETSCSTACKSIZE) { \
1093: stack__.function[stack__.currentsize] = func__; \
1094: if (petsc_routine__) { \
1095: stack__.file[stack__.currentsize] = file__; \
1096: stack__.line[stack__.currentsize] = line__; \
1097: } else { \
1098: stack__.file[stack__.currentsize] = PETSC_NULLPTR; \
1099: stack__.line[stack__.currentsize] = 0; \
1100: } \
1101: stack__.petscroutine[stack__.currentsize] = petsc_routine__; \
1102: } \
1103: ++stack__.currentsize; \
1104: stack__.hotdepth += (hot__ || stack__.hotdepth); \
1105: } while (0)
1108: #define PetscStackPop_Private(stack__, func__) \
1109: do { \
1111: if (--stack__.currentsize < PETSCSTACKSIZE) { \
1113: stack__.function[stack__.currentsize], stack__.file[stack__.currentsize], stack__.line[stack__.currentsize], func__, __FILE__, __LINE__); \
1114: stack__.function[stack__.currentsize] = PETSC_NULLPTR; \
1115: stack__.file[stack__.currentsize] = PETSC_NULLPTR; \
1116: stack__.line[stack__.currentsize] = 0; \
1117: stack__.petscroutine[stack__.currentsize] = 0; \
1118: } \
1119: stack__.hotdepth = PetscMax(stack__.hotdepth - 1, 0); \
1120: } while (0)
1122: /*MC
1123: PetscStackPushNoCheck - Pushes a new function name and line number onto the PETSc default stack that tracks where the running program is
1124: currently in the source code.
1126: Not Collective
1128: Synopsis:
1129: #include <petscsys.h>
1130: void PetscStackPushNoCheck(char *funct,int petsc_routine,PetscBool hot);
1132: Input Parameters:
1133: + funct - the function name
1134: . petsc_routine - 2 user function, 1 PETSc function, 0 some other function
1135: - hot - indicates that the function may be called often so expensive error checking should be turned off inside the function
1137: Level: developer
1139: Notes:
1140: 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
1141: 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
1142: help debug the problem.
1144: This version does not check the memory corruption (an expensive operation), use `PetscStackPush()` to check the memory.
1146: Use `PetscStackPushExternal()` for a function call that is about to be made to a non-PETSc or user function (such as BLAS etc).
1148: The default stack is a global variable called `petscstack`.
1152: `PetscStackPushExternal()`
1153: M*/
1154: #define PetscStackPushNoCheck(funct, petsc_routine, hot) \
1155: do { \
1156: PetscStackSAWsTakeAccess(); \
1157: PetscStackPush_Private(petscstack, __FILE__, funct, __LINE__, petsc_routine, hot); \
1158: PetscStackSAWsGrantAccess(); \
1159: } while (0)
1161: /*MC
1163: current line number.
1165: Not Collective
1167: Synopsis:
1168: #include <petscsys.h>
1169: void PetscStackUpdateLine
1171: Level: developer
1173: Notes:
1174: Using `PetscCall()` and friends automatically handles this process
1176: 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
1177: occurred, for example, when a signal is received. It is recommended to use the debugger if extensive information is needed to
1178: help debug the problem.
1180: The default stack is a global variable called petscstack.
1182: This is used by `PetscCall()` and is otherwise not like to be needed
1184: .seealso: `PetscAttachDebugger()`, `PetscStackCopy()`, `PetscStackView()`, `PetscStackPushNoCheck()`, `PetscStackPop`, `PetscCall()`
1185: M*/
1186: #define PetscStackUpdateLine \
1187: if (petscstack.currentsize > 0 && petscstack.function[petscstack.currentsize - 1] == PETSC_FUNCTION_NAME) { petscstack.line[petscstack.currentsize - 1] = __LINE__; }
1189: /*MC
1190: PetscStackPushExternal - Pushes a new function name onto the PETSc default stack that tracks where the running program is
1191: currently in the source code. Does not include the filename or line number since this is called by the calling routine
1192: for non-PETSc or user functions.
1194: Not Collective
1196: Synopsis:
1197: #include <petscsys.h>
1198: void PetscStackPushExternal(char *funct);
1200: Input Parameters:
1201: . funct - the function name
1203: Level: developer
1205: Notes:
1206: Using `PetscCallExternal()` and friends automatically handles this process
1208: 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
1209: occurred, for example, when a signal is received. It is recommended to use the debugger if extensive information is needed to
1210: help debug the problem.
1212: The default stack is a global variable called `petscstack`.
1214: This is to be used when calling an external package function such as a BLAS function.
1216: This also updates the stack line number for the current stack function.
1220: M*/
1221: #define PetscStackPushExternal(funct) \
1222: do { \
1223: PetscStackUpdateLine; \
1224: PetscStackPushNoCheck(funct, 0, PETSC_TRUE); \
1225: } while (0);
1227: /*MC
1228: PetscStackPopNoCheck - Pops a function name from the PETSc default stack that tracks where the running program is
1229: currently in the source code.
1231: Not Collective
1233: Synopsis:
1234: #include <petscsys.h>
1235: void PetscStackPopNoCheck(char *funct);
1237: Input Parameter:
1238: . funct - the function name
1240: Level: developer
1242: Notes:
1243: Using `PetscCall()`, `PetscCallExternal()`, `PetscCallBack()` and friends negates the need to call this
1245: 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
1246: occurred, for example, when a signal is received. It is recommended to use the debugger if extensive information is needed to
1247: help debug the problem.
1249: The default stack is a global variable called petscstack.
1251: Developer Note:
1252: `PetscStackPopNoCheck()` takes a function argument while `PetscStackPop` does not, this difference is likely just historical.
1254: .seealso: `PetscAttachDebugger()`, `PetscStackCopy()`, `PetscStackView()`, `PetscStackPushNoCheck()`, `PetscStackPop`
1255: M*/
1256: #define PetscStackPopNoCheck(funct) \
1257: do { \
1258: PetscStackSAWsTakeAccess(); \
1259: PetscStackPop_Private(petscstack, funct); \
1260: PetscStackSAWsGrantAccess(); \
1261: } while (0)
1263: #define PetscStackClearTop \
1264: do { \
1265: PetscStackSAWsTakeAccess(); \
1266: if (petscstack.currentsize > 0 && --petscstack.currentsize < PETSCSTACKSIZE) { \
1267: petscstack.function[petscstack.currentsize] = PETSC_NULLPTR; \
1268: petscstack.file[petscstack.currentsize] = PETSC_NULLPTR; \
1269: petscstack.line[petscstack.currentsize] = 0; \
1270: petscstack.petscroutine[petscstack.currentsize] = 0; \
1271: } \
1272: petscstack.hotdepth = PetscMax(petscstack.hotdepth - 1, 0); \
1273: PetscStackSAWsGrantAccess(); \
1274: } while (0)
1276: /*MC
1278: line of PETSc functions should be `PetscFunctionReturn`(0);
1280: Synopsis:
1281: #include <petscsys.h>
1283: Not Collective
1285: Usage:
1286: .vb
1287: int something;
1289: .ve
1291: Notes:
1294: Not available in Fortran
1296: Level: developer
1300: M*/
1302: do { \
1303: PetscStackPushNoCheck(PETSC_FUNCTION_NAME, 1, PETSC_FALSE); \
1304: PetscRegister__FUNCT__(); \
1305: } while (0)
1307: /*MC
1309: performance-critical circumstances. Use of this function allows for lighter profiling by default.
1311: Synopsis:
1312: #include <petscsys.h>
1315: Not Collective
1317: Usage:
1318: .vb
1319: int something;
1322: .ve
1324: Notes:
1325: Not available in Fortran
1327: Level: developer
1331: M*/
1333: do { \
1334: PetscStackPushNoCheck(PETSC_FUNCTION_NAME, 1, PETSC_TRUE); \
1335: PetscRegister__FUNCT__(); \
1336: } while (0)
1338: /*MC
1341: Synopsis:
1342: #include <petscsys.h>
1345: Not Collective
1347: Usage:
1348: .vb
1349: int something;
1352: .ve
1354: Notes:
1355: Functions that incorporate this must call `PetscFunctionReturn()` instead of return except for main().
1357: May be used before `PetscInitialize()`
1359: Not available in Fortran
1362: routine instead of as a PETSc library routine.
1364: Level: intermediate
1368: M*/
1370: do { \
1371: PetscStackPushNoCheck(PETSC_FUNCTION_NAME, 2, PETSC_FALSE); \
1372: PetscRegister__FUNCT__(); \
1373: } while (0)
1375: /*MC
1376: PetscStackPush - Pushes a new function name and line number onto the PETSc default stack that tracks where the running program is
1377: currently in the source code and verifies the memory is not corrupted.
1379: Not Collective
1381: Synopsis:
1382: #include <petscsys.h>
1383: void PetscStackPush(char *funct)
1385: Input Parameter:
1386: . funct - the function name
1388: Level: developer
1390: Notes:
1391: 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
1392: occurred, for example, when a signal is received. It is recommended to use the debugger if extensive information is needed to
1393: help debug the problem.
1395: The default stack is a global variable called petscstack.
1399: M*/
1400: #define PetscStackPush(n) \
1401: do { \
1402: PetscStackPushNoCheck(n, 0, PETSC_FALSE); \
1403: CHKMEMQ; \
1404: } while (0)
1406: /*MC
1407: PetscStackPop - Pops a function name from the PETSc default stack that tracks where the running program is
1408: currently in the source code and verifies the memory is not corrupted.
1410: Not Collective
1412: Synopsis:
1413: #include <petscsys.h>
1414: void PetscStackPop
1416: Level: developer
1418: Notes:
1419: 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
1420: occurred, for example, when a signal is received. It is recommended to use the debugger if extensive information is needed to
1421: help debug the problem.
1423: The default stack is a global variable called petscstack.
1425: .seealso: `PetscAttachDebugger()`, `PetscStackCopy()`, `PetscStackView()`, `PetscStackPushNoCheck()`, `PetscStackPopNoCheck()`, `PetscStackPush()`
1426: M*/
1427: #define PetscStackPop \
1428: do { \
1429: CHKMEMQ; \
1430: PetscStackPopNoCheck(PETSC_FUNCTION_NAME); \
1431: } while (0)
1433: /*MC
1434: PetscFunctionReturn - Last executable line of each PETSc function
1435: used for error handling. Replaces `return()`
1437: Synopsis:
1438: #include <petscsys.h>
1439: void return 0;
1441: Not Collective
1443: Usage:
1444: .vb
1445: ....
1446: return 0;
1447: }
1448: .ve
1450: Note:
1451: Not available in Fortran
1453: Level: developer
1457: M*/
1458: #define return a \
1459: do { \
1460: PetscStackPopNoCheck(PETSC_FUNCTION_NAME); \
1461: return a; \
1462: } while (0)
1464: #define return \
1465: do { \
1466: PetscStackPopNoCheck(PETSC_FUNCTION_NAME); \
1467: return; \
1468: } while (0)
1469: #else /* PETSC_USE_DEBUG */
1470: #define PetscStackPushNoCheck(funct, petsc_routine, hot)
1471: #define PetscStackUpdateLine
1472: #define PetscStackPushExternal(funct)
1473: #define PetscStackPopNoCheck
1474: #define PetscStackClearTop
1478: #define return a return a
1479: #define return return
1480: #define PetscStackPop CHKMEMQ
1481: #define PetscStackPush(f) CHKMEMQ
1482: #endif /* PETSC_USE_DEBUG */
1484: #if defined(PETSC_CLANG_STATIC_ANALYZER)
1485: #define PetscStackCallExternalVoid(name, routine)
1486: #define PetscCallExternal(func, ...)
1487: #else
1488: /*MC
1489: PetscStackCallExternalVoid - Calls an external library routine or user function after pushing the name of the routine on the stack.
1491: Input Parameters:
1492: + name - string that gives the name of the function being called
1493: - routine - actual call to the routine, for example, functionname(a,b)
1495: Level: developer
1497: Note:
1498: Often one should use `PetscCallExternal()` instead. This routine is intended for external library routines that DO NOT return error codes
1500: In debug mode this also checks the memory for corruption at the end of the function call.
1502: Certain external packages, such as BLAS/LAPACK may have their own macros for managing the call, error checking, etc.
1504: Developer Note:
1505: This is so that when a user or external library routine results in a crash or corrupts memory, they get blamed instead of PETSc.
1507: .seealso: `PetscCall()`, `PetscStackPushNoCheck()`, `PetscStackPush()`, `PetscCallExternal()`, `PetscCallBLAS()`
1508: @*/
1509: #define PetscStackCallExternalVoid(name, routine) \
1510: do { \
1511: PetscStackPush(name); \
1512: routine; \
1513: PetscStackPop; \
1514: } while (0)
1516: /*MC
1517: PetscCallExternal - Calls an external library routine that returns an error code after pushing the name of the routine on the stack.
1519: Input Parameters:
1520: + func- name of the routine
1521: - args - arguments to the routine
1523: Level: developer
1525: Notes:
1526: This is intended for external package routines that return error codes. Use `PetscStackCallExternalVoid()` for those that do not.
1528: In debug mode this also checks the memory for corruption at the end of the function call.
1530: Assumes the error return code of the function is an integer and that a value of 0 indicates success
1532: Developer Note:
1533: This is so that when an external packge routine results in a crash or corrupts memory, they get blamed instead of PETSc.
1535: .seealso: `PetscCall()`, `PetscStackPushNoCheck()`, `PetscStackPush()`, `PetscStackCallExternalVoid()`
1536: M*/
1537: #define PetscCallExternal(func, ...) \
1538: do { \
1539: PetscStackPush(PetscStringize(func)); \
1540: PetscErrorCode __func(__VA_ARGS__); \
1541: PetscStackPop; \
1543: } while (0)
1544: #endif /* PETSC_CLANG_STATIC_ANALYZER */
1546: #endif