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: /*
17: These are the generic error codes. These error codes are used
18: many different places in the PETSc source code. The string versions are
19: at src/sys/error/err.c any changes here must also be made there
20: These are also define in src/sys/f90-mod/petscerror.h any CHANGES here
21: must be also made there.
23: */
24: #define PETSC_ERR_MIN_VALUE 54 /* should always be one less then the smallest value */
26: #define PETSC_ERR_MEM 55 /* unable to allocate requested memory */
27: #define PETSC_ERR_SUP 56 /* no support for requested operation */
28: #define PETSC_ERR_SUP_SYS 57 /* no support for requested operation on this computer system */
29: #define PETSC_ERR_ORDER 58 /* operation done in wrong order */
30: #define PETSC_ERR_SIG 59 /* signal received */
31: #define PETSC_ERR_FP 72 /* floating point exception */
32: #define PETSC_ERR_COR 74 /* corrupted PETSc object */
33: #define PETSC_ERR_LIB 76 /* error in library called by PETSc */
34: #define PETSC_ERR_PLIB 77 /* PETSc library generated inconsistent data */
35: #define PETSC_ERR_MEMC 78 /* memory corruption */
36: #define PETSC_ERR_CONV_FAILED 82 /* iterative method (KSP or SNES) failed */
37: #define PETSC_ERR_USER 83 /* user has not provided needed function */
38: #define PETSC_ERR_SYS 88 /* error in system call */
39: #define PETSC_ERR_POINTER 70 /* pointer does not point to valid address */
40: #define PETSC_ERR_MPI_LIB_INCOMP 87 /* MPI library at runtime is not compatible with MPI user compiled with */
42: #define PETSC_ERR_ARG_SIZ 60 /* nonconforming object sizes used in operation */
43: #define PETSC_ERR_ARG_IDN 61 /* two arguments not allowed to be the same */
44: #define PETSC_ERR_ARG_WRONG 62 /* wrong argument (but object probably ok) */
45: #define PETSC_ERR_ARG_CORRUPT 64 /* null or corrupted PETSc object as argument */
46: #define PETSC_ERR_ARG_OUTOFRANGE 63 /* input argument, out of range */
47: #define PETSC_ERR_ARG_BADPTR 68 /* invalid pointer argument */
48: #define PETSC_ERR_ARG_NOTSAMETYPE 69 /* two args must be same object type */
49: #define PETSC_ERR_ARG_NOTSAMECOMM 80 /* two args must be same communicators */
50: #define PETSC_ERR_ARG_WRONGSTATE 73 /* object in argument is in wrong state, e.g. unassembled mat */
51: #define PETSC_ERR_ARG_TYPENOTSET 89 /* the type of the object has not yet been set */
52: #define PETSC_ERR_ARG_INCOMP 75 /* two arguments are incompatible */
53: #define PETSC_ERR_ARG_NULL 85 /* argument is null that should not be */
54: #define PETSC_ERR_ARG_UNKNOWN_TYPE 86 /* type name doesn't match any registered type */
56: #define PETSC_ERR_FILE_OPEN 65 /* unable to open file */
57: #define PETSC_ERR_FILE_READ 66 /* unable to read from file */
58: #define PETSC_ERR_FILE_WRITE 67 /* unable to write to file */
59: #define PETSC_ERR_FILE_UNEXPECTED 79 /* unexpected data in file */
61: #define PETSC_ERR_MAT_LU_ZRPVT 71 /* detected a zero pivot during LU factorization */
62: #define PETSC_ERR_MAT_CH_ZRPVT 81 /* detected a zero pivot during Cholesky factorization */
64: #define PETSC_ERR_INT_OVERFLOW 84
66: #define PETSC_ERR_FLOP_COUNT 90
67: #define PETSC_ERR_NOT_CONVERGED 91 /* solver did not converge */
68: #define PETSC_ERR_MISSING_FACTOR 92 /* MatGetFactor() failed */
69: #define PETSC_ERR_OPT_OVERWRITE 93 /* attempted to over write options which should not be changed */
70: #define PETSC_ERR_WRONG_MPI_SIZE 94 /* example/application run with number of MPI ranks it does not support */
71: #define PETSC_ERR_USER_INPUT 95 /* missing or incorrect user input */
72: #define PETSC_ERR_GPU_RESOURCE 96 /* unable to load a GPU resource, for example cuBLAS */
73: #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 */
74: #define PETSC_ERR_MPI 98 /* general MPI error */
75: #define PETSC_ERR_RETURN 99 /* PetscError() incorrectly returned an error code of 0 */
76: #define PETSC_ERR_MAX_VALUE 100 /* this is always the one more than the largest error code */
78: #define SETERRQ1(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
79: #define SETERRQ2(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
80: #define SETERRQ3(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
81: #define SETERRQ4(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
82: #define SETERRQ5(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
83: #define SETERRQ6(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
84: #define SETERRQ7(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
85: #define SETERRQ8(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
86: #define SETERRQ9(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
88: /*MC
89: SETERRQ - Macro to be called when an error has been detected,
91: Synopsis:
92: #include <petscsys.h>
93: PetscErrorCode SETERRQ(MPI_Comm comm,PetscErrorCode ierr,char *message,...)
95: Collective
97: Input Parameters:
98: + comm - A communicator, use `PETSC_COMM_SELF` unless you know all ranks of another communicator will detect the error
99: . ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
100: - message - error message
102: Level: beginner
104: Notes:
106: Once the error handler is called the calling function is then returned from with the given error code.
108: Experienced users can set the error handler with `PetscPushErrorHandler()`.
110: Fortran Notes:
111: SETERRQ() may be called from Fortran subroutines but SETERRA() must be called from the
112: Fortran main program.
115: `PetscError()`, `PetscCall()`, `CHKMEMQ`, `CHKERRA()`, `PetscCallMPI()`
116: M*/
117: #define SETERRQ(comm, ierr, ...) \
118: do { \
119: PetscErrorCode ierr_seterrq_petsc_ = PetscError(comm, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr, PETSC_ERROR_INITIAL, __VA_ARGS__); \
120: return ierr_seterrq_petsc_ ? ierr_seterrq_petsc_ : PETSC_ERR_RETURN; \
121: } while (0)
123: /*
124: Returned from PETSc functions that are called from MPI, such as related to attributes
125: Do not confuse PETSC_MPI_ERROR_CODE and PETSC_ERR_MPI, the first is registered with MPI and returned to MPI as
126: an error code, the latter is a regular PETSc error code passed within PETSc code indicating an error was detected in an MPI call.
127: */
128: PETSC_EXTERN PetscMPIInt PETSC_MPI_ERROR_CLASS;
129: PETSC_EXTERN PetscMPIInt PETSC_MPI_ERROR_CODE;
131: /*MC
132: SETERRMPI - Macro to be called when an error has been detected within an MPI callback function
134: Synopsis:
135: #include <petscsys.h>
136: PetscErrorCode SETERRMPI(MPI_Comm comm,PetscErrorCode ierr,char *message,...)
138: Collective
140: Input Parameters:
141: + comm - A communicator, use `PETSC_COMM_SELF` unless you know all ranks of another communicator will detect the error
142: . ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
143: - message - error message
145: Level: developer
147: Notes:
148: 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`
149: which is registered with `MPI_Add_error_code()` when PETSc is initialized.
151: .seealso: `SETERRQ()`, `PetscCall()`, `PetscCallMPI()`, `PetscTraceBackErrorHandler()`, `PetscPushErrorHandler()`, `PetscError()`, `CHKMEMQ`
152: M*/
153: #define SETERRMPI(comm, ierr, ...) return (PetscError(comm, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr, PETSC_ERROR_INITIAL, __VA_ARGS__), PETSC_MPI_ERROR_CODE)
155: /*MC
156: SETERRA - Fortran-only macro that can be called when an error has been detected from the main program
158: Synopsis:
159: #include <petscsys.h>
160: PetscErrorCode SETERRA(MPI_Comm comm,PetscErrorCode ierr,char *message)
162: Collective
164: Input Parameters:
165: + comm - A communicator, so that the error can be collective
166: . ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
167: - message - error message in the printf format
169: Level: beginner
171: Notes:
172: This should only be used with Fortran. With C/C++, use `SETERRQ()`.
174: Fortran Notes:
175: `SETERRQ()` may be called from Fortran subroutines but `SETERRA()` must be called from the
176: Fortran main program.
178: .seealso: `SETERRQ()`, `SETERRABORT()`, `PetscCall()`, `CHKERRA()`, `PetscCallAbort()`
179: M*/
181: /*MC
182: SETERRABORT - Macro that can be called when an error has been detected,
184: Synopsis:
185: #include <petscsys.h>
186: PetscErrorCode SETERRABORT(MPI_Comm comm,PetscErrorCode ierr,char *message,...)
188: Collective
190: Input Parameters:
191: + comm - A communicator, so that the error can be collective
192: . ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
193: - message - error message in the printf format
195: Level: beginner
197: Notes:
198: This function just calls `MPI_Abort()`.
200: This should only be called in routines that cannot return an error code, such as in C++ constructors.
202: .seealso: `SETERRQ()`, `PetscTraceBackErrorHandler()`, `PetscPushErrorHandler()`, `PetscError()`, `PetscCall()`, `CHKMEMQ`
203: M*/
204: #define SETERRABORT(comm, ierr, ...) \
205: do { \
206: PetscError(comm, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr, PETSC_ERROR_INITIAL, __VA_ARGS__); \
207: MPI_Abort(comm, ierr); \
208: } while (0)
210: /*MC
213: Synopsis:
214: #include <petscerror.h>
217: Collective
219: Input Parameters:
220: + cond - The boolean condition
221: . comm - The communicator on which the check can be collective on
222: . ierr - A nonzero error code, see include/petscerror.h for the complete list
223: - message - Error message in printf format
225: Notes:
226: Enabled in both optimized and debug builds.
228: Calls `SETERRQ()` if the assertion fails, so can only be called from functions returning a
229: `PetscErrorCode` (or equivalent type after conversion).
231: Level: beginner
234: M*/
236: do { \
237: if (PetscUnlikely(!(cond))) SETERRQ(comm, ierr, __VA_ARGS__); \
238: } while (0)
240: /*MC
243: Synopsis:
244: #include <petscerror.h>
247: Collective
249: Input Parameters:
250: + cond - The boolean condition
251: . comm - The communicator on which the check can be collective on
252: . ierr - A nonzero error code, see include/petscerror.h for the complete list
253: - message - Error message in printf format
255: Notes:
256: Enabled in both optimized and debug builds.
258: Calls `SETERRABORT()` if the assertion fails, can be called from a function that does not return an
261: Level: developer
264: M*/
266: do { \
267: if (PetscUnlikely(!(cond))) SETERRABORT(comm, ierr, __VA_ARGS__); \
268: } while (0)
270: /*MC
271: PetscAssert - Assert that a particular condition is true
273: Synopsis:
274: #include <petscerror.h>
275: void PetscAssert(bool cond, MPI_Comm comm, PetscErrorCode ierr, const char *message, ...)
277: Collective
279: Input Parameters:
280: + cond - The boolean condition
281: . comm - The communicator on which the check can be collective on
282: . ierr - A nonzero error code, see include/petscerror.h for the complete list
283: - message - Error message in printf format
285: Notes:
290: This is needed instead of simply using `assert()` because this correctly handles the collective nature of errors under MPI
292: Level: beginner
295: M*/
296: #if PetscDefined(USE_DEBUG)
298: #else
299: #define PetscAssert(cond, ...) PetscAssume(cond)
300: #endif
302: /*MC
303: PetscAssertAbort - Assert that a particular condition is true, otherwise prints error and aborts
305: Synopsis:
306: #include <petscerror.h>
307: void PetscAssertAbort(bool cond, MPI_Comm comm, PetscErrorCode ierr, const char *message, ...)
309: Collective
311: Input Parameters:
312: + cond - The boolean condition
313: . comm - The communicator on which the check can be collective on
314: . ierr - A nonzero error code, see include/petscerror.h for the complete list
315: - message - Error message in printf format
317: Notes:
320: Level: beginner
323: M*/
324: #define PetscAssertAbort(cond, comm, ierr, ...) \
325: do { \
326: if (PetscUnlikelyDebug(!(cond))) SETERRABORT(comm, ierr, __VA_ARGS__); \
327: } while (0)
329: /*MC
330: PetscCall - Calls a PETSc function and then checks the resulting error code, if it is non-zero it calls the error
331: handler and returns from the current function with the error code.
333: Synopsis:
334: #include <petscerror.h>
335: void PetscCall(PetscFunction(args))
337: Not Collective
339: Input Parameter:
340: . PetscFunction - any PETSc function that returns an error code
342: Notes:
343: Once the error handler is called the calling function is then returned from with the given
344: error code. Experienced users can set the error handler with `PetscPushErrorHandler()`.
346: `PetscCall()` cannot be used in functions returning a datatype not convertible to
347: `PetscErrorCode`. For example, `PetscCall()` may not be used in functions returning void, use
348: `PetscCallVoid()` in this case.
350: Example Usage:
351: .vb
352: PetscInitiailize(...); // OK to call even when PETSc is not yet initialized!
354: struct my_struct
355: {
356: void *data;
357: } my_complex_type;
359: struct my_struct bar(void)
360: {
361: foo(15); // ERROR PetscErrorCode not convertible to struct my_struct!
362: }
364: PetscCall(bar()) // ERROR input not convertible to PetscErrorCode
365: .ve
367: It is also possible to call this directly on a `PetscErrorCode` variable
368: .vb
369: ierr; // check if ierr is nonzero
370: .ve
372: Should not be used to call callback functions provided by users, `PetscCallBack()` should be used in that situation.
374: `PetscUseTypeMethod()` or `PetscTryTypeMethod()` should be used when calling functions pointers contained in a PETSc object's `ops` array
376: Fortran Notes:
377: The Fortran function from which this is used must declare a variable PetscErrorCode ierr and ierr must be
378: the final argument to the PETSc function being called.
380: In the main program and in Fortran subroutines that do not have ierr as the final return parameter one
381: should use `PetscCallA()`
383: Example Fortran Usage:
384: .vb
385: PetscErrorCode ierr
386: Vec v
388: ...
389: PetscCall(VecShift(v,1.0,ierr))
390: PetscCallA(VecShift(v,1.0,ierr))
391: .ve
393: Level: beginner
396: `PetscPushErrorHandler()`, `PetscError()`, `CHKMEMQ`, `CHKERRA()`, `CHKERRMPI()`, `PetscCallBack()`
397: M*/
399: /*MC
400: PetscCallBack - Calls a user provided PETSc callback function and then checks the resulting error code, if it is non-zero it calls the error
401: handler and returns from the current function with the error code.
403: Synopsis:
404: #include <petscerror.h>
405: void PetscCallBack(const char *functionname,PetscFunction(args))
407: Not Collective
409: Input Parameters:
410: + functionname - the name of the function being called, this can be a string with spaces that describes the meaning of the callback
411: - PetscFunction - user provided callback function that returns an error code
413: Notes:
414: Once the error handler is called the calling function is then returned from with the given
415: error code. Experienced users can set the error handler with `PetscPushErrorHandler()`.
417: `PetscCallBack()` should only be called in PETSc when a call is being made to a user provided call-back routine.
419: Example Usage:
420: .vb
421: PetscCallBack("XXX callback to do something",a->callback(...));
422: .ve
424: Level: developer
427: `PetscPushErrorHandler()`, `PetscError()`, `CHKMEMQ`, `CHKERRA()`, `CHKERRMPI()`, `PetscCall()`
428: M*/
430: #if defined(PETSC_CLANG_STATIC_ANALYZER)
431: void PetscErrorCode;
432: void PetscCallBack(const char *, PetscErrorCode);
433: void PetscErrorCode;
434: #else
435: #define PetscCall(...) \
436: do { \
437: PetscErrorCode ierr_q_; \
438: PetscStackUpdateLine; \
439: ierr_q_ = __VA_ARGS__; \
440: if (PetscUnlikely(ierr_q_)) return PetscError(PETSC_COMM_SELF, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr_q_, PETSC_ERROR_REPEAT, " "); \
441: } while (0)
442: #define PetscCallBack(function, ...) \
443: do { \
444: PetscErrorCode ierr_q_; \
445: PetscStackUpdateLine; \
446: PetscStackPushExternal(function); \
447: ierr_q_ = __VA_ARGS__; \
448: PetscStackPop; \
449: if (PetscUnlikely(ierr_q_)) return PetscError(PETSC_COMM_SELF, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr_q_, PETSC_ERROR_REPEAT, " "); \
450: } while (0)
451: #define PetscCallVoid(...) \
452: do { \
453: PetscErrorCode ierr_void_; \
454: PetscStackUpdateLine; \
455: ierr_void_ = __VA_ARGS__; \
456: if (PetscUnlikely(ierr_void_)) { \
457: (void)PetscError(PETSC_COMM_SELF, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr_void_, PETSC_ERROR_REPEAT, " "); \
458: return; \
459: } \
460: } while (0)
461: #endif
463: /*MC
464: CHKERRQ - Checks error code returned from PETSc function
466: Synopsis:
467: #include <petscsys.h>
468: void CHKERRQ(PetscErrorCode ierr)
470: Not Collective
472: Input Parameters:
473: . ierr - nonzero error code
475: Notes:
476: Deprecated in favor of `PetscCall()`. This routine behaves identically to it.
478: Level: deprecated
480: .seealso: `PetscCall()`
481: M*/
482: #define CHKERRQ(...) PetscCall(__VA_ARGS__)
483: #define CHKERRV(...) PetscCallVoid(__VA_ARGS__)
485: PETSC_EXTERN void PetscMPIErrorString(PetscMPIInt, char *);
487: /*MC
488: PetscCallMPI - Checks error code returned from MPI calls, if non-zero it calls the error
489: handler and then returns
491: Synopsis:
492: #include <petscerror.h>
493: void PetscCallMPI(MPI_Function(args))
495: Not Collective
497: Input Parameters:
498: . MPI_Function - an MPI function that returns an MPI error code
500: Notes:
501: Always returns the error code `PETSC_ERR_MPI`; the MPI error code and string are embedded in
502: the string error message. Do not use this to call any other routines (for example PETSc
503: routines), it should only be used for direct MPI calls. Due to limitations of the
504: preprocessor this can unfortunately not easily be enforced, so the user should take care to
505: check this themselves.
507: Example Usage:
508: .vb
509: MPI_Comm_size(...); // OK, calling MPI function
511: PetscFunction(...); // ERROR, use PetscCall() instead!
512: .ve
514: Fortran Notes:
515: The Fortran function from which this is used must declare a variable `PetscErrorCode` ierr and ierr must be
516: the final argument to the MPI function being called.
518: In the main program and in Fortran subroutines that do not have ierr as the final return parameter one
519: should use `PetscCallMPIA()`
521: Fortran Usage:
522: .vb
523: PetscErrorCode ierr or integer ierr
524: ...
525: PetscCallMPI(MPI_Comm_size(...,ierr))
526: PetscCallMPIA(MPI_Comm_size(...,ierr)) ! Will abort after calling error handler
528: PetscCallMPI(MPI_Comm_size(...,eflag)) ! ERROR, final argument must be ierr
529: .ve
531: Level: beginner
533: .seealso: `SETERRMPI()`, `PetscCall()`, `SETERRQ()`, `SETERRABORT()`, `PetscCallAbort()`,
534: `PetscTraceBackErrorHandler()`, `PetscPushErrorHandler()`, `PetscError()`, `CHKMEMQ`
535: M*/
536: #if defined(PETSC_CLANG_STATIC_ANALYZER)
537: void PetscMPIInt;
538: #else
539: #define PetscCallMPI(...) \
540: do { \
541: PetscMPIInt _7_errorcode; \
542: char _7_errorstring[2 * MPI_MAX_ERROR_STRING]; \
543: PetscStackUpdateLine; \
544: PetscStackPushExternal("MPI function"); \
545: { \
546: _7_errorcode = __VA_ARGS__; \
547: } \
548: PetscStackPop; \
549: if (PetscUnlikely(_7_errorcode)) { \
550: PetscMPIErrorString(_7_errorcode, (char *)_7_errorstring); \
551: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_MPI, "MPI error %d %s", (int)_7_errorcode, _7_errorstring); \
552: } \
553: } while (0)
554: #endif
556: /*MC
557: CHKERRMPI - Checks error code returned from MPI calls, if non-zero it calls the error
558: handler and then returns
560: Synopsis:
561: #include <petscerror.h>
562: void CHKERRMPI(PetscErrorCode ierr)
564: Not Collective
566: Input Parameter:
567: . ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
569: Notes:
570: Deprecated in favor of `PetscCallMPI()`. This routine behaves identically to it.
572: Level: deprecated
574: .seealso: `PetscCallMPI()`
575: M*/
576: #define CHKERRMPI(...) PetscCallMPI(__VA_ARGS__)
578: /*MC
579: PetscCallAbort - Checks error code returned from PETSc function, if non-zero it aborts immediately
581: Synopsis:
582: #include <petscerror.h>
583: void PetscCallAbort(MPI_Comm comm, PetscErrorCode ierr)
585: Collective
587: Input Parameters:
588: + comm - the MPI communicator on which to abort
589: - ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
591: Notes:
592: This macro has identical type and usage semantics to `PetscCall()` with the important caveat
593: that this macro does not return. Instead, if ierr is nonzero it calls the PETSc error handler
594: and then immediately calls `MPI_Abort()`. It can therefore be used anywhere.
596: As per `MPI_Abort()` semantics the communicator passed must be valid, although there is currently
597: no attempt made at handling any potential errors from `MPI_Abort()`. Note that while
598: `MPI_Abort()` is required to terminate only those processes which reside on comm, it is often
599: the case that `MPI_Abort()` terminates *all* processes.
601: Example Usage:
602: .vb
603: PetscErrorCode boom(void) { return PETSC_ERR_MEM; }
605: void foo(void)
606: {
607: PETSC_COMM_WORLD,boom(); // OK, does not return a type
608: }
610: double bar(void)
611: {
612: PETSC_COMM_WORLD,boom(); // OK, does not return a type
613: }
615: MPI_COMM_NULL,boom(); // ERROR, communicator should be valid
617: struct baz
618: {
619: baz()
620: {
621: PETSC_COMM_SELF,boom(); // OK
622: }
624: ~baz()
625: {
626: PETSC_COMM_SELF,boom(); // OK (in fact the only way to handle PETSc errors)
627: }
628: };
629: .ve
631: Level: intermediate
633: .seealso: `SETERRABORT()`, `PetscTraceBackErrorHandler()`, `PetscPushErrorHandler()`, `PetscError()`,
634: `SETERRQ()`, `CHKMEMQ`, `PetscCallMPI()`
635: M*/
636: #if defined(PETSC_CLANG_STATIC_ANALYZER)
637: void MPI_Comm, PetscErrorCode;
638: void PetscErrorCode;
639: #else
640: #define PetscCallAbort(comm, ...) \
641: do { \
642: PetscErrorCode ierr_abort_ = __VA_ARGS__; \
643: if (PetscUnlikely(ierr_abort_)) { \
644: PetscError(PETSC_COMM_SELF, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr_abort_, PETSC_ERROR_REPEAT, " "); \
645: MPI_Abort(comm, ierr_abort_); \
646: } \
647: } while (0)
648: #define PetscCallContinue(...) \
649: do { \
650: PetscErrorCode ierr_continue_ = __VA_ARGS__; \
651: if (PetscUnlikely(ierr_continue_)) PetscError(PETSC_COMM_SELF, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr_continue_, PETSC_ERROR_REPEAT, " "); \
652: } while (0)
653: #endif
655: /*MC
656: CHKERRABORT - Checks error code returned from PETSc function. If non-zero it aborts immediately.
658: Synopsis:
659: #include <petscerror.h>
660: void CHKERRABORT(MPI_Comm comm, PetscErrorCode ierr)
662: Not Collective
664: Input Parameters:
665: + comm - the MPI communicator
666: - ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
668: Notes:
669: Deprecated in favor of `PetscCallAbort()`. This routine behaves identically to it.
671: Level: deprecated
673: .seealso: `PetscCallAbort()`
674: M*/
675: #define CHKERRABORT(comm, ...) PetscCallAbort(comm, __VA_ARGS__)
676: #define CHKERRCONTINUE(...) PetscCallContinue(__VA_ARGS__)
678: /*MC
679: CHKERRA - Fortran-only replacement for use of `CHKERRQ()` in the main program, which aborts immediately
681: Synopsis:
682: #include <petscsys.h>
683: PetscErrorCode CHKERRA(PetscErrorCode ierr)
685: Not Collective
687: Input Parameters:
688: . ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
690: Level: deprecated
692: Note:
693: This macro is rarely needed, normal usage is `PetscCallA()` in the main Fortran program.
695: .seealso: `PetscCall()`, `PetscCallA()`, `PetscCallAbort()`, `CHKERRQ()`, `SETERRA()`, `SETERRQ()`, `SETERRABORT()`
696: M*/
698: PETSC_EXTERN PetscBool petscwaitonerrorflg;
699: PETSC_EXTERN PetscBool petscindebugger;
701: /*MC
702: PETSCABORT - Call MPI_Abort with an informative error code
704: Synopsis:
705: #include <petscsys.h>
706: PETSCABORT(MPI_Comm comm, PetscErrorCode ierr)
708: Collective
710: Input Parameters:
711: + comm - A communicator, so that the error can be collective
712: - ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
714: Level: advanced
716: Notes:
717: If the option -start_in_debugger was used then this calls abort() to stop the program in the debugger.
719: if `PetscCIEnabledPortableErrorOutput` is set it strives to exit cleanly without call `MPI_Abort()`
721: M*/
722: #define PETSCABORT(comm, ...) \
723: do { \
724: if (petscwaitonerrorflg) PetscSleep(1000); \
725: if (petscindebugger) abort(); \
726: else { \
727: PetscErrorCode ierr_petsc_abort_ = __VA_ARGS__; \
728: PetscMPIInt size; \
729: MPI_Comm_size(comm, &size); \
730: if (PetscCIEnabledPortableErrorOutput && size == PetscGlobalSize && ierr_petsc_abort_ != PETSC_ERR_SIG) { \
731: MPI_Finalize(); \
732: exit(0); \
733: } else if (PetscCIEnabledPortableErrorOutput && PetscGlobalSize == 1) { \
734: exit(0); \
735: } else { \
736: MPI_Abort(comm, (PetscMPIInt)ierr_petsc_abort_); \
737: } \
738: } \
739: } while (0)
741: #ifdef PETSC_CLANGUAGE_CXX
742: /*MC
743: PetscCallThrow - Checks error code, if non-zero it calls the C++ error handler which throws
744: an exception
746: Synopsis:
747: #include <petscerror.h>
748: void PetscCallThrow(PetscErrorCode ierr)
750: Not Collective
752: Input Parameter:
753: . ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
755: Notes:
756: Requires PETSc to be configured with clanguage = c++. Throws a std::runtime_error() on error.
758: Once the error handler throws the exception you can use `PetscCallVoid()` which returns without
759: an error code (bad idea since the error is ignored) or `PetscCallAbort()` to have `MPI_Abort()`
760: called immediately.
762: Level: beginner
764: .seealso: `SETERRQ()`, `PetscCall()`, `SETERRABORT()`, `PetscCallAbort()`, `PetscTraceBackErrorHandler()`,
765: `PetscPushErrorHandler()`, `PetscError()`, `CHKMEMQ`
766: M*/
767: #define PetscCallThrow(...) \
768: do { \
769: PetscErrorCode ierr_cxx_ = __VA_ARGS__; \
770: if (PetscUnlikely(ierr_cxx_)) PetscError(PETSC_COMM_SELF, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr_cxx_, PETSC_ERROR_IN_CXX, PETSC_NULLPTR); \
771: } while (0)
773: /*MC
774: CHKERRXX - Checks error code, if non-zero it calls the C++ error handler which throws an exception
776: Synopsis:
777: #include <petscerror.h>
778: void CHKERRXX(PetscErrorCode ierr)
780: Not Collective
782: Input Parameter:
783: . ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
785: Notes:
786: Deprecated in favor of `PetscCallThrow()`. This routine behaves identically to it.
788: Level: deprecated
790: .seealso: `PetscCallThrow()`
791: M*/
792: #define CHKERRXX(...) PetscCallThrow(__VA_ARGS__)
793: #endif
795: /*MC
796: PetscCallCXX - Checks C++ function calls and if they throw an exception, catch it and then
797: return a PETSc error code
799: Synopsis:
800: #include <petscerror.h>
801: void PetscCallCXX(expr) noexcept;
803: Not Collective
805: Input Parameter:
806: . expr - An arbitrary expression
808: Notes:
809: PetscCallCXX(expr) is a macro replacement for
810: .vb
811: try {
812: expr;
813: } catch (const std::exception& e) {
814: return ConvertToPetscErrorCode(e);
815: }
816: .ve
817: Due to the fact that it catches any (reasonable) exception, it is essentially noexcept.
819: Example Usage:
820: .vb
821: void foo(void) { throw std::runtime_error("error"); }
823: void bar()
824: {
825: foo(); // ERROR bar() does not return PetscErrorCode
826: }
828: PetscErrorCode baz()
829: {
830: foo(); // OK
832: PetscCallCXX(
833: bar();
834: foo(); // OK multiple statements allowed
835: );
836: }
838: struct bop
839: {
840: bop()
841: {
842: foo(); // ERROR returns PetscErrorCode, cannot be used in constructors
843: }
844: };
846: // ERROR contains do-while, cannot be used as function-try block
847: PetscErrorCode qux() PetscCallCXX(
848: bar();
849: baz();
850: foo();
851: return 0;
852: )
853: .ve
855: Level: beginner
857: .seealso: `PetscCallThrow()`, `SETERRQ()`, `PetscCall()`, `SETERRABORT()`, `PetscCallAbort()`,
858: `PetscTraceBackErrorHandler()`, `PetscPushErrorHandler()`, `PetscError()`, `CHKMEMQ`
859: M*/
860: #define PetscCallCXX(...) \
861: do { \
862: PetscStackUpdateLine; \
863: try { \
864: __VA_ARGS__; \
865: } catch (const std::exception &e) { \
866: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "%s", e.what()); \
867: } \
868: } while (0)
870: /*MC
871: CHKERRCXX - Checks C++ function calls and if they throw an exception, catch it and then
872: return a PETSc error code
874: Synopsis:
875: #include <petscerror.h>
876: void CHKERRCXX(func) noexcept;
878: Not Collective
880: Input Parameter:
881: . func - C++ function calls
883: Notes:
884: Deprecated in favor of `PetscCallCXX()`. This routine behaves identically to it.
886: Level: deprecated
888: .seealso: `PetscCallCXX()`
889: M*/
890: #define CHKERRCXX(...) PetscCallCXX(__VA_ARGS__)
892: /*MC
893: CHKMEMQ - Checks the memory for corruption, calls error handler if any is detected
895: Synopsis:
896: #include <petscsys.h>
897: CHKMEMQ;
899: Not Collective
901: Level: beginner
903: Notes:
904: We highly recommend using Valgrind https://petsc.org/release/faq/#valgrind or for NVIDIA CUDA systems
905: https://docs.nvidia.com/cuda/cuda-memcheck/index.html for finding memory problems. The ``CHKMEMQ`` macro is useful on systems that
906: do not have valgrind, but is not as good as valgrind or cuda-memcheck.
908: Must run with the option -malloc_debug (-malloc_test in debug mode; or if `PetscMallocSetDebug()` called) to enable this option
910: Once the error handler is called the calling function is then returned from with the given error code.
912: By defaults prints location where memory that is corrupted was allocated.
914: Use `CHKMEMA` for functions that return void
916: .seealso: `PetscTraceBackErrorHandler()`, `PetscPushErrorHandler()`, `PetscError()`, `SETERRQ()`, `PetscMallocValidate()`
917: M*/
918: #if defined(PETSC_CLANG_STATIC_ANALYZER)
919: #define CHKMEMQ
920: #define CHKMEMA
921: #else
922: #define CHKMEMQ \
923: do { \
924: PetscErrorCode ierr_memq_ = PetscMallocValidate(__LINE__, PETSC_FUNCTION_NAME, __FILE__); \
925: if (PetscUnlikely(ierr_memq_)) return PetscError(PETSC_COMM_SELF, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr_memq_, PETSC_ERROR_REPEAT, " "); \
926: } while (0)
927: #define CHKMEMA PetscMallocValidate(__LINE__, PETSC_FUNCTION_NAME, __FILE__)
928: #endif
930: /*E
931: PetscErrorType - passed to the PETSc error handling routines indicating if this is the first or a later call to the error handlers
933: Level: advanced
935: `PETSC_ERROR_IN_CXX` indicates the error was detected in C++ and an exception should be generated
937: Developer Notes:
938: This is currently used to decide when to print the detailed information about the run in PetscTraceBackErrorHandler()
940: .seealso: `PetscError()`, `SETERRQ()`
941: E*/
942: typedef enum {
943: PETSC_ERROR_INITIAL = 0,
944: PETSC_ERROR_REPEAT = 1,
945: PETSC_ERROR_IN_CXX = 2
946: } PetscErrorType;
948: #if defined(__clang_analyzer__)
949: __attribute__((analyzer_noreturn))
950: #endif
951: PETSC_EXTERN PetscErrorCode
952: PetscError(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, ...) PETSC_ATTRIBUTE_COLD PETSC_ATTRIBUTE_FORMAT(7, 8);
954: PETSC_EXTERN PetscErrorCode PetscErrorPrintfInitialize(void);
955: PETSC_EXTERN PetscErrorCode PetscErrorMessage(int, const char *[], char **);
956: PETSC_EXTERN PetscErrorCode PetscTraceBackErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD;
957: PETSC_EXTERN PetscErrorCode PetscIgnoreErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD;
958: PETSC_EXTERN PetscErrorCode PetscEmacsClientErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD;
959: PETSC_EXTERN PetscErrorCode PetscMPIAbortErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD;
960: PETSC_EXTERN PetscErrorCode PetscAbortErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD;
961: PETSC_EXTERN PetscErrorCode PetscAttachDebuggerErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD;
962: PETSC_EXTERN PetscErrorCode PetscReturnErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD;
963: PETSC_EXTERN PetscErrorCode PetscPushErrorHandler(PetscErrorCode (*handler)(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *), void *);
964: PETSC_EXTERN PetscErrorCode PetscPopErrorHandler(void);
965: PETSC_EXTERN PetscErrorCode PetscSignalHandlerDefault(int, void *);
966: PETSC_EXTERN PetscErrorCode PetscPushSignalHandler(PetscErrorCode (*)(int, void *), void *);
967: PETSC_EXTERN PetscErrorCode PetscPopSignalHandler(void);
969: PETSC_EXTERN void PetscSignalSegvCheckPointerOrMpi(void);
970: PETSC_DEPRECATED_FUNCTION("Use PetscSignalSegvCheckPointerOrMpi() (since version 3.13)") static inline void PetscSignalSegvCheckPointer(void)
971: {
972: PetscSignalSegvCheckPointerOrMpi();
973: }
975: /*MC
976: PetscErrorPrintf - Prints error messages.
978: Not Collective; No Fortran Support
980: Synopsis:
981: #include <petscsys.h>
982: PetscErrorCode (*PetscErrorPrintf)(const char format[],...);
984: Input Parameter:
985: . format - the usual `printf()` format string
987: Options Database Keys:
988: + -error_output_stdout - cause error messages to be printed to stdout instead of the (default) stderr
989: - -error_output_none - to turn off all printing of error messages (does not change the way the error is handled.)
991: Level: developer
993: Notes:
994: Use
995: $ PetscErrorPrintf = PetscErrorPrintfNone; to turn off all printing of error messages (does not change the way the
996: $ error is handled.) and
997: $ PetscErrorPrintf = PetscErrorPrintfDefault; to turn it back on or you can use your own function
999: Use
1000: `PETSC_STDERR` = FILE* obtained from a file open etc. to have stderr printed to the file.
1001: `PETSC_STDOUT` = FILE* obtained from a file open etc. to have stdout printed to the file.
1003: Use
1004: `PetscPushErrorHandler()` to provide your own error handler that determines what kind of messages to print
1006: .seealso: `PetscFPrintf()`, `PetscSynchronizedPrintf()`, `PetscHelpPrintf()`, `PetscPrintf()`, `PetscPushErrorHandler()`, `PetscVFPrintf()`, `PetscHelpPrintf()`
1007: M*/
1008: PETSC_EXTERN PetscErrorCode (*PetscErrorPrintf)(const char[], ...) PETSC_ATTRIBUTE_FORMAT(1, 2);
1010: /*E
1011: PetscFPTrap - types of floating point exceptions that may be trapped
1013: Currently only `PETSC_FP_TRAP_OFF` and `PETSC_FP_TRAP_ON` are handled. All others are treated as `PETSC_FP_TRAP_ON`.
1015: Level: intermediate
1017: .seealso: `PetscSetFPTrap()`, `PetscPushFPTrap()`
1018: E*/
1019: typedef enum {
1020: PETSC_FP_TRAP_OFF = 0,
1021: PETSC_FP_TRAP_INDIV = 1,
1022: PETSC_FP_TRAP_FLTOPERR = 2,
1023: PETSC_FP_TRAP_FLTOVF = 4,
1024: PETSC_FP_TRAP_FLTUND = 8,
1025: PETSC_FP_TRAP_FLTDIV = 16,
1026: PETSC_FP_TRAP_FLTINEX = 32
1027: } PetscFPTrap;
1028: #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)
1029: PETSC_EXTERN PetscErrorCode PetscSetFPTrap(PetscFPTrap);
1030: PETSC_EXTERN PetscErrorCode PetscFPTrapPush(PetscFPTrap);
1031: PETSC_EXTERN PetscErrorCode PetscFPTrapPop(void);
1032: PETSC_EXTERN PetscErrorCode PetscDetermineInitialFPTrap(void);
1034: /*
1035: Allows the code to build a stack frame as it runs
1036: */
1038: #if defined(PETSC_USE_DEBUG)
1039: #define PETSCSTACKSIZE 64
1040: typedef struct {
1041: const char *function[PETSCSTACKSIZE];
1042: const char *file[PETSCSTACKSIZE];
1043: int line[PETSCSTACKSIZE];
1044: int petscroutine[PETSCSTACKSIZE]; /* 0 external called from petsc, 1 petsc functions, 2 petsc user functions */
1045: int currentsize;
1046: int hotdepth;
1047: PetscBool check; /* option to check for correct Push/Pop semantics, true for default petscstack but not other stacks */
1048: } PetscStack;
1049: PETSC_EXTERN PetscStack petscstack;
1050: #else
1051: typedef struct {
1052: char Silence_empty_struct_has_size_0_in_C_size_1_in_Cpp;
1053: } PetscStack;
1054: #endif
1056: #if defined(PETSC_SERIALIZE_FUNCTIONS)
1057: #include <petsc/private/petscfptimpl.h>
1058: /*
1059: Registers the current function into the global function pointer to function name table
1061: Have to fix this to handle errors but cannot return error since used in PETSC_VIEWER_DRAW_() etc
1062: */
1063: #define PetscRegister__FUNCT__() \
1064: do { \
1065: static PetscBool __chked = PETSC_FALSE; \
1066: if (!__chked) { \
1067: void *ptr; \
1068: PetscDLSym(NULL, PETSC_FUNCTION_NAME, &ptr); \
1069: __chked = PETSC_TRUE; \
1070: } \
1071: } while (0)
1072: #else
1073: #define PetscRegister__FUNCT__()
1074: #endif
1076: #if defined(PETSC_CLANG_STATIC_ANALYZER)
1077: #define PetscStackPushNoCheck(funct, petsc_routine, hot)
1078: #define PetscStackUpdateLine
1079: #define PetscStackPushExternal(funct)
1080: #define PetscStackPopNoCheck
1081: #define PetscStackClearTop
1085: #define return a return a
1086: #define return return
1087: #define PetscStackPop
1088: #define PetscStackPush(f)
1089: #elif defined(PETSC_USE_DEBUG)
1091: #define PetscStackPush_Private(stack__, file__, func__, line__, petsc_routine__, hot__) \
1092: do { \
1093: if (stack__.currentsize < PETSCSTACKSIZE) { \
1094: stack__.function[stack__.currentsize] = func__; \
1095: if (petsc_routine__) { \
1096: stack__.file[stack__.currentsize] = file__; \
1097: stack__.line[stack__.currentsize] = line__; \
1098: } else { \
1099: stack__.file[stack__.currentsize] = PETSC_NULLPTR; \
1100: stack__.line[stack__.currentsize] = 0; \
1101: } \
1102: stack__.petscroutine[stack__.currentsize] = petsc_routine__; \
1103: } \
1104: ++stack__.currentsize; \
1105: stack__.hotdepth += (hot__ || stack__.hotdepth); \
1106: } while (0)
1109: #define PetscStackPop_Private(stack__, func__) \
1110: do { \
1112: if (--stack__.currentsize < PETSCSTACKSIZE) { \
1114: stack__.function[stack__.currentsize], stack__.file[stack__.currentsize], stack__.line[stack__.currentsize], func__, __FILE__, __LINE__); \
1115: stack__.function[stack__.currentsize] = PETSC_NULLPTR; \
1116: stack__.file[stack__.currentsize] = PETSC_NULLPTR; \
1117: stack__.line[stack__.currentsize] = 0; \
1118: stack__.petscroutine[stack__.currentsize] = 0; \
1119: } \
1120: stack__.hotdepth = PetscMax(stack__.hotdepth - 1, 0); \
1121: } while (0)
1123: /*MC
1124: PetscStackPushNoCheck - Pushes a new function name and line number onto the PETSc default stack that tracks where the running program is
1125: currently in the source code.
1127: Not Collective
1129: Synopsis:
1130: #include <petscsys.h>
1131: void PetscStackPushNoCheck(char *funct,int petsc_routine,PetscBool hot);
1133: Input Parameters:
1134: + funct - the function name
1135: . petsc_routine - 2 user function, 1 PETSc function, 0 some other function
1136: - hot - indicates that the function may be called often so expensive error checking should be turned off inside the function
1138: Level: developer
1140: Notes:
1141: 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
1142: 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
1143: help debug the problem.
1145: This version does not check the memory corruption (an expensive operation), use `PetscStackPush()` to check the memory.
1147: Use `PetscStackPushExternal()` for a function call that is about to be made to a non-PETSc or user function (such as BLAS etc).
1149: The default stack is a global variable called `petscstack`.
1153: `PetscStackPushExternal()`
1154: M*/
1155: #define PetscStackPushNoCheck(funct, petsc_routine, hot) \
1156: do { \
1157: PetscStackSAWsTakeAccess(); \
1158: PetscStackPush_Private(petscstack, __FILE__, funct, __LINE__, petsc_routine, hot); \
1159: PetscStackSAWsGrantAccess(); \
1160: } while (0)
1162: /*MC
1164: current line number.
1166: Not Collective
1168: Synopsis:
1169: #include <petscsys.h>
1170: void PetscStackUpdateLine
1172: Level: developer
1174: Notes:
1175: Using `PetscCall()` and friends automatically handles this process
1177: 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
1178: occurred, for example, when a signal is received. It is recommended to use the debugger if extensive information is needed to
1179: help debug the problem.
1181: The default stack is a global variable called petscstack.
1183: This is used by `PetscCall()` and is otherwise not like to be needed
1185: .seealso: `PetscAttachDebugger()`, `PetscStackCopy()`, `PetscStackView()`, `PetscStackPushNoCheck()`, `PetscStackPop`, `PetscCall()`
1186: M*/
1187: #define PetscStackUpdateLine \
1188: if (petscstack.currentsize > 0 && petscstack.function[petscstack.currentsize - 1] == PETSC_FUNCTION_NAME) { petscstack.line[petscstack.currentsize - 1] = __LINE__; }
1190: /*MC
1191: PetscStackPushExternal - Pushes a new function name onto the PETSc default stack that tracks where the running program is
1192: currently in the source code. Does not include the filename or line number since this is called by the calling routine
1193: for non-PETSc or user functions.
1195: Not Collective
1197: Synopsis:
1198: #include <petscsys.h>
1199: void PetscStackPushExternal(char *funct);
1201: Input Parameters:
1202: . funct - the function name
1204: Level: developer
1206: Notes:
1207: Using `PetscCallExternal()` and friends automatically handles this process
1209: 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
1210: occurred, for example, when a signal is received. It is recommended to use the debugger if extensive information is needed to
1211: help debug the problem.
1213: The default stack is a global variable called `petscstack`.
1215: This is to be used when calling an external package function such as a BLAS function.
1217: This also updates the stack line number for the current stack function.
1221: M*/
1222: #define PetscStackPushExternal(funct) \
1223: do { \
1224: PetscStackUpdateLine; \
1225: PetscStackPushNoCheck(funct, 0, PETSC_TRUE); \
1226: } while (0);
1228: /*MC
1229: PetscStackPopNoCheck - Pops a function name from the PETSc default stack that tracks where the running program is
1230: currently in the source code.
1232: Not Collective
1234: Synopsis:
1235: #include <petscsys.h>
1236: void PetscStackPopNoCheck(char *funct);
1238: Input Parameter:
1239: . funct - the function name
1241: Level: developer
1243: Notes:
1244: Using `PetscCall()`, `PetscCallExternal()`, `PetscCallBack()` and friends negates the need to call this
1246: 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
1247: occurred, for example, when a signal is received. It is recommended to use the debugger if extensive information is needed to
1248: help debug the problem.
1250: The default stack is a global variable called petscstack.
1252: Developer Note:
1253: `PetscStackPopNoCheck()` takes a function argument while `PetscStackPop` does not, this difference is likely just historical.
1255: .seealso: `PetscAttachDebugger()`, `PetscStackCopy()`, `PetscStackView()`, `PetscStackPushNoCheck()`, `PetscStackPop`
1256: M*/
1257: #define PetscStackPopNoCheck(funct) \
1258: do { \
1259: PetscStackSAWsTakeAccess(); \
1260: PetscStackPop_Private(petscstack, funct); \
1261: PetscStackSAWsGrantAccess(); \
1262: } while (0)
1264: #define PetscStackClearTop \
1265: do { \
1266: PetscStackSAWsTakeAccess(); \
1267: if (petscstack.currentsize > 0 && --petscstack.currentsize < PETSCSTACKSIZE) { \
1268: petscstack.function[petscstack.currentsize] = PETSC_NULLPTR; \
1269: petscstack.file[petscstack.currentsize] = PETSC_NULLPTR; \
1270: petscstack.line[petscstack.currentsize] = 0; \
1271: petscstack.petscroutine[petscstack.currentsize] = 0; \
1272: } \
1273: petscstack.hotdepth = PetscMax(petscstack.hotdepth - 1, 0); \
1274: PetscStackSAWsGrantAccess(); \
1275: } while (0)
1277: /*MC
1279: line of PETSc functions should be `PetscFunctionReturn`(0);
1281: Synopsis:
1282: #include <petscsys.h>
1284: Not Collective
1286: Usage:
1287: .vb
1288: int something;
1290: .ve
1292: Notes:
1295: Not available in Fortran
1297: Level: developer
1301: M*/
1303: do { \
1304: PetscStackPushNoCheck(PETSC_FUNCTION_NAME, 1, PETSC_FALSE); \
1305: PetscRegister__FUNCT__(); \
1306: } while (0)
1308: /*MC
1310: performance-critical circumstances. Use of this function allows for lighter profiling by default.
1312: Synopsis:
1313: #include <petscsys.h>
1316: Not Collective
1318: Usage:
1319: .vb
1320: int something;
1323: .ve
1325: Notes:
1326: Not available in Fortran
1328: Level: developer
1332: M*/
1334: do { \
1335: PetscStackPushNoCheck(PETSC_FUNCTION_NAME, 1, PETSC_TRUE); \
1336: PetscRegister__FUNCT__(); \
1337: } while (0)
1339: /*MC
1342: Synopsis:
1343: #include <petscsys.h>
1346: Not Collective
1348: Usage:
1349: .vb
1350: int something;
1353: .ve
1355: Notes:
1356: Functions that incorporate this must call `PetscFunctionReturn()` instead of return except for main().
1358: May be used before `PetscInitialize()`
1360: Not available in Fortran
1363: routine instead of as a PETSc library routine.
1365: Level: intermediate
1369: M*/
1371: do { \
1372: PetscStackPushNoCheck(PETSC_FUNCTION_NAME, 2, PETSC_FALSE); \
1373: PetscRegister__FUNCT__(); \
1374: } while (0)
1376: /*MC
1377: PetscStackPush - Pushes a new function name and line number onto the PETSc default stack that tracks where the running program is
1378: currently in the source code and verifies the memory is not corrupted.
1380: Not Collective
1382: Synopsis:
1383: #include <petscsys.h>
1384: void PetscStackPush(char *funct)
1386: Input Parameter:
1387: . funct - the function name
1389: Level: developer
1391: Notes:
1392: 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
1393: occurred, for example, when a signal is received. It is recommended to use the debugger if extensive information is needed to
1394: help debug the problem.
1396: The default stack is a global variable called petscstack.
1400: M*/
1401: #define PetscStackPush(n) \
1402: do { \
1403: PetscStackPushNoCheck(n, 0, PETSC_FALSE); \
1404: CHKMEMQ; \
1405: } while (0)
1407: /*MC
1408: PetscStackPop - Pops a function name from the PETSc default stack that tracks where the running program is
1409: currently in the source code and verifies the memory is not corrupted.
1411: Not Collective
1413: Synopsis:
1414: #include <petscsys.h>
1415: void PetscStackPop
1417: Level: developer
1419: Notes:
1420: 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
1421: occurred, for example, when a signal is received. It is recommended to use the debugger if extensive information is needed to
1422: help debug the problem.
1424: The default stack is a global variable called petscstack.
1426: .seealso: `PetscAttachDebugger()`, `PetscStackCopy()`, `PetscStackView()`, `PetscStackPushNoCheck()`, `PetscStackPopNoCheck()`, `PetscStackPush()`
1427: M*/
1428: #define PetscStackPop \
1429: do { \
1430: CHKMEMQ; \
1431: PetscStackPopNoCheck(PETSC_FUNCTION_NAME); \
1432: } while (0)
1434: /*MC
1435: PetscFunctionReturn - Last executable line of each PETSc function
1436: used for error handling. Replaces `return()`
1438: Synopsis:
1439: #include <petscsys.h>
1440: void return 0;
1442: Not Collective
1444: Usage:
1445: .vb
1446: ....
1447: return 0;
1448: }
1449: .ve
1451: Note:
1452: Not available in Fortran
1454: Level: developer
1458: M*/
1459: #define return a \
1460: do { \
1461: PetscStackPopNoCheck(PETSC_FUNCTION_NAME); \
1462: return a; \
1463: } while (0)
1465: #define return \
1466: do { \
1467: PetscStackPopNoCheck(PETSC_FUNCTION_NAME); \
1468: return; \
1469: } while (0)
1470: #else /* PETSC_USE_DEBUG */
1471: #define PetscStackPushNoCheck(funct, petsc_routine, hot)
1472: #define PetscStackUpdateLine
1473: #define PetscStackPushExternal(funct)
1474: #define PetscStackPopNoCheck
1475: #define PetscStackClearTop
1479: #define return a return a
1480: #define return return
1481: #define PetscStackPop CHKMEMQ
1482: #define PetscStackPush(f) CHKMEMQ
1483: #endif /* PETSC_USE_DEBUG */
1485: #if defined(PETSC_CLANG_STATIC_ANALYZER)
1486: #define PetscStackCallExternalVoid(name, routine)
1487: #define PetscCallExternal(func, ...)
1488: #else
1489: /*MC
1490: PetscStackCallExternalVoid - Calls an external library routine or user function after pushing the name of the routine on the stack.
1492: Input Parameters:
1493: + name - string that gives the name of the function being called
1494: - routine - actual call to the routine, for example, functionname(a,b)
1496: Level: developer
1498: Note:
1499: Often one should use `PetscCallExternal()` instead. This routine is intended for external library routines that DO NOT return error codes
1501: In debug mode this also checks the memory for corruption at the end of the function call.
1503: Certain external packages, such as BLAS/LAPACK may have their own macros for managing the call, error checking, etc.
1505: Developer Note:
1506: This is so that when a user or external library routine results in a crash or corrupts memory, they get blamed instead of PETSc.
1508: .seealso: `PetscCall()`, `PetscStackPushNoCheck()`, `PetscStackPush()`, `PetscCallExternal()`, `PetscCallBLAS()`
1509: @*/
1510: #define PetscStackCallExternalVoid(name, routine) \
1511: do { \
1512: PetscStackPush(name); \
1513: routine; \
1514: PetscStackPop; \
1515: } while (0)
1517: /*MC
1518: PetscCallExternal - Calls an external library routine that returns an error code after pushing the name of the routine on the stack.
1520: Input Parameters:
1521: + func- name of the routine
1522: - args - arguments to the routine
1524: Level: developer
1526: Notes:
1527: This is intended for external package routines that return error codes. Use `PetscStackCallExternalVoid()` for those that do not.
1529: In debug mode this also checks the memory for corruption at the end of the function call.
1531: Assumes the error return code of the function is an integer and that a value of 0 indicates success
1533: Developer Note:
1534: This is so that when an external package routine results in a crash or corrupts memory, they get blamed instead of PETSc.
1536: .seealso: `PetscCall()`, `PetscStackPushNoCheck()`, `PetscStackPush()`, `PetscStackCallExternalVoid()`
1537: M*/
1538: #define PetscCallExternal(func, ...) \
1539: do { \
1540: PetscStackPush(PetscStringize(func)); \
1541: PetscErrorCode __func(__VA_ARGS__); \
1542: PetscStackPop; \
1544: } while (0)
1545: #endif /* PETSC_CLANG_STATIC_ANALYZER */
1547: #endif