xref: /petsc/include/petscerror.h (revision 0e6b6b5985dd9b1172860d21fb88bd3966bf7c54)
154a8ef01SBarry Smith /*
2f621e05eSBarry Smith     Contains all error handling interfaces for PETSc.
354a8ef01SBarry Smith */
426bd1501SBarry Smith #if !defined(PETSCERROR_H)
526bd1501SBarry Smith #define PETSCERROR_H
66c7e564aSBarry Smith 
7e1bf4ed2SJacob Faibussowitsch #include <petscmacros.h>
8e1bf4ed2SJacob Faibussowitsch #include <petscsystypes.h>
9e1bf4ed2SJacob Faibussowitsch 
10ac09b921SBarry Smith /* SUBMANSEC = Sys */
11ac09b921SBarry Smith 
1254a8ef01SBarry Smith /*
13329ffe3dSLois Curfman McInnes      These are the generic error codes. These error codes are used
14e2d1d2b7SBarry Smith      many different places in the PETSc source code. The string versions are
150e5e90baSSatish Balay      at src/sys/error/err.c any changes here must also be made there
16e951c290SBarry Smith      These are also define in src/sys/f90-mod/petscerror.h any CHANGES here
170f9cf654SBarry Smith      must be also made there.
1845d48df9SBarry Smith 
1954a8ef01SBarry Smith */
202a6744ebSBarry Smith #define PETSC_ERR_MIN_VALUE 54 /* should always be one less then the smallest value */
212a6744ebSBarry Smith 
2245d48df9SBarry Smith #define PETSC_ERR_MEM            55 /* unable to allocate requested memory */
2347794344SBarry Smith #define PETSC_ERR_SUP            56 /* no support for requested operation */
24e2d1d2b7SBarry Smith #define PETSC_ERR_SUP_SYS        57 /* no support for requested operation on this computer system */
25e2d1d2b7SBarry Smith #define PETSC_ERR_ORDER          58 /* operation done in wrong order */
2645d48df9SBarry Smith #define PETSC_ERR_SIG            59 /* signal received */
27f1caa5a4SBarry Smith #define PETSC_ERR_FP             72 /* floating point exception */
28a8c6a408SBarry Smith #define PETSC_ERR_COR            74 /* corrupted PETSc object */
29a8c6a408SBarry Smith #define PETSC_ERR_LIB            76 /* error in library called by PETSc */
30329ffe3dSLois Curfman McInnes #define PETSC_ERR_PLIB           77 /* PETSc library generated inconsistent data */
31329ffe3dSLois Curfman McInnes #define PETSC_ERR_MEMC           78 /* memory corruption */
32b3cc6726SBarry Smith #define PETSC_ERR_CONV_FAILED    82 /* iterative method (KSP or SNES) failed */
331302d50aSBarry Smith #define PETSC_ERR_USER           83 /* user has not provided needed function */
344e2ffeddSBarry Smith #define PETSC_ERR_SYS            88 /* error in system call */
35a8b45ee7SBarry Smith #define PETSC_ERR_POINTER        70 /* pointer does not point to valid address */
363d96e996SBarry Smith #define PETSC_ERR_MPI_LIB_INCOMP 87 /* MPI library at runtime is not compatible with MPI user compiled with */
3745d48df9SBarry Smith 
3845d48df9SBarry Smith #define PETSC_ERR_ARG_SIZ          60 /* nonconforming object sizes used in operation */
3945d48df9SBarry Smith #define PETSC_ERR_ARG_IDN          61 /* two arguments not allowed to be the same */
40a8c6a408SBarry Smith #define PETSC_ERR_ARG_WRONG        62 /* wrong argument (but object probably ok) */
4145d48df9SBarry Smith #define PETSC_ERR_ARG_CORRUPT      64 /* null or corrupted PETSc object as argument */
4245d48df9SBarry Smith #define PETSC_ERR_ARG_OUTOFRANGE   63 /* input argument, out of range */
434f227f7cSBarry Smith #define PETSC_ERR_ARG_BADPTR       68 /* invalid pointer argument */
444f227f7cSBarry Smith #define PETSC_ERR_ARG_NOTSAMETYPE  69 /* two args must be same object type */
456831982aSBarry Smith #define PETSC_ERR_ARG_NOTSAMECOMM  80 /* two args must be same communicators */
46d252947aSBarry Smith #define PETSC_ERR_ARG_WRONGSTATE   73 /* object in argument is in wrong state, e.g. unassembled mat */
478cda6cd7SBarry Smith #define PETSC_ERR_ARG_TYPENOTSET   89 /* the type of the object has not yet been set */
48a8c6a408SBarry Smith #define PETSC_ERR_ARG_INCOMP       75 /* two arguments are incompatible */
494482741eSBarry Smith #define PETSC_ERR_ARG_NULL         85 /* argument is null that should not be */
50958c9bccSBarry Smith #define PETSC_ERR_ARG_UNKNOWN_TYPE 86 /* type name doesn't match any registered type */
514f227f7cSBarry Smith 
524f227f7cSBarry Smith #define PETSC_ERR_FILE_OPEN       65 /* unable to open file */
534f227f7cSBarry Smith #define PETSC_ERR_FILE_READ       66 /* unable to read from file */
544f227f7cSBarry Smith #define PETSC_ERR_FILE_WRITE      67 /* unable to write to file */
55a8c6a408SBarry Smith #define PETSC_ERR_FILE_UNEXPECTED 79 /* unexpected data in file */
5645d48df9SBarry Smith 
57329ffe3dSLois Curfman McInnes #define PETSC_ERR_MAT_LU_ZRPVT 71 /* detected a zero pivot during LU factorization */
589e3b2f23SBarry Smith #define PETSC_ERR_MAT_CH_ZRPVT 81 /* detected a zero pivot during Cholesky factorization */
5954a8ef01SBarry Smith 
6068e69593SBarry Smith #define PETSC_ERR_INT_OVERFLOW 84
613855c12bSBarry Smith 
62bf3909cdSBarry Smith #define PETSC_ERR_FLOP_COUNT     90
63e113a28aSBarry Smith #define PETSC_ERR_NOT_CONVERGED  91 /* solver did not converge */
6492e8f287SBarry Smith #define PETSC_ERR_MISSING_FACTOR 92 /* MatGetFactor() failed */
65691b26d3SBarry Smith #define PETSC_ERR_OPT_OVERWRITE  93 /* attempted to over write options which should not be changed */
66691b26d3SBarry Smith #define PETSC_ERR_WRONG_MPI_SIZE 94 /* example/application run with number of MPI ranks it does not support */
67691b26d3SBarry Smith #define PETSC_ERR_USER_INPUT     95 /* missing or incorrect user input */
68589f383fSBarry Smith #define PETSC_ERR_GPU_RESOURCE   96 /* unable to load a GPU resource, for example cuBLAS */
69589f383fSBarry Smith #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 */
70ffc4695bSBarry Smith #define PETSC_ERR_MPI            98 /* general MPI error */
71ffc4695bSBarry Smith #define PETSC_ERR_MAX_VALUE      99 /* this is always the one more than the largest error code */
72b9eb5ee8SHong Zhang 
7398921bdaSJacob Faibussowitsch #define SETERRQ1(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
7498921bdaSJacob Faibussowitsch #define SETERRQ2(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
7598921bdaSJacob Faibussowitsch #define SETERRQ3(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
7698921bdaSJacob Faibussowitsch #define SETERRQ4(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
7798921bdaSJacob Faibussowitsch #define SETERRQ5(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
7898921bdaSJacob Faibussowitsch #define SETERRQ6(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
7998921bdaSJacob Faibussowitsch #define SETERRQ7(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
8098921bdaSJacob Faibussowitsch #define SETERRQ8(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
8198921bdaSJacob Faibussowitsch #define SETERRQ9(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
8298921bdaSJacob Faibussowitsch 
8330de9b25SBarry Smith /*MC
841957e957SBarry Smith    SETERRQ - Macro to be called when an error has been detected,
8530de9b25SBarry Smith 
8630de9b25SBarry Smith    Synopsis:
87aaa7dc30SBarry Smith    #include <petscsys.h>
8898921bdaSJacob Faibussowitsch    PetscErrorCode SETERRQ(MPI_Comm comm,PetscErrorCode ierr,char *message,...)
8930de9b25SBarry Smith 
90d083f849SBarry Smith    Collective
9130de9b25SBarry Smith 
9230de9b25SBarry Smith    Input Parameters:
9387497f52SBarry Smith +  comm - A communicator, use `PETSC_COMM_SELF` unless you know all ranks of another communicator will detect the error
943af045c5SBarry Smith .  ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
9530de9b25SBarry Smith -  message - error message
9630de9b25SBarry Smith 
9730de9b25SBarry Smith   Level: beginner
9830de9b25SBarry Smith 
9930de9b25SBarry Smith    Notes:
10087497f52SBarry Smith     This is rarely needed, one should use `PetscCheck()` and `PetscCall()` and friends to automatically handle error conditions.
10130de9b25SBarry Smith     Once the error handler is called the calling function is then returned from with the given error code.
10230de9b25SBarry Smith 
10387497f52SBarry Smith     Experienced users can set the error handler with `PetscPushErrorHandler()`.
10430de9b25SBarry Smith 
1053b1008b8SBarry Smith    Fortran Notes:
1063b1008b8SBarry Smith       SETERRQ() may be called from Fortran subroutines but SETERRA() must be called from the
1073b1008b8SBarry Smith       Fortran main program.
1083b1008b8SBarry Smith 
109db781477SPatrick Sanan .seealso: `PetscCheck()`, `PetscAssert()`, `PetscTraceBackErrorHandler()`, `PetscPushErrorHandler()`,
110db781477SPatrick Sanan           `PetscError()`, `PetscCall()`, `CHKMEMQ`, `CHKERRA()`, `PetscCallMPI()`
11130de9b25SBarry Smith M*/
11298921bdaSJacob Faibussowitsch #define SETERRQ(comm, ierr, ...) return PetscError(comm, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr, PETSC_ERROR_INITIAL, __VA_ARGS__)
113986eef2eSBarry Smith 
114ffc4695bSBarry Smith /*
115ffc4695bSBarry Smith     Returned from PETSc functions that are called from MPI, such as related to attributes
116ffc4695bSBarry Smith       Do not confuse PETSC_MPI_ERROR_CODE and PETSC_ERR_MPI, the first is registered with MPI and returned to MPI as
117888a1fb3SBarry Smith       an error code, the latter is a regular PETSc error code passed within PETSc code indicating an error was detected in an MPI call.
118ffc4695bSBarry Smith */
119ffc4695bSBarry Smith PETSC_EXTERN PetscMPIInt PETSC_MPI_ERROR_CLASS;
120ffc4695bSBarry Smith PETSC_EXTERN PetscMPIInt PETSC_MPI_ERROR_CODE;
121ffc4695bSBarry Smith 
122986eef2eSBarry Smith /*MC
123986eef2eSBarry Smith    SETERRMPI - Macro to be called when an error has been detected within an MPI callback function
124986eef2eSBarry Smith 
125986eef2eSBarry Smith    Synopsis:
126986eef2eSBarry Smith    #include <petscsys.h>
12798921bdaSJacob Faibussowitsch    PetscErrorCode SETERRMPI(MPI_Comm comm,PetscErrorCode ierr,char *message,...)
128986eef2eSBarry Smith 
129d083f849SBarry Smith    Collective
130986eef2eSBarry Smith 
131986eef2eSBarry Smith    Input Parameters:
13287497f52SBarry Smith +  comm - A communicator, use `PETSC_COMM_SELF` unless you know all ranks of another communicator will detect the error
133986eef2eSBarry Smith .  ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
134986eef2eSBarry Smith -  message - error message
135986eef2eSBarry Smith 
136986eef2eSBarry Smith   Level: developer
137986eef2eSBarry Smith 
138986eef2eSBarry Smith    Notes:
13987497f52SBarry Smith     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`
14087497f52SBarry Smith     which is registered with `MPI_Add_error_code()` when PETSc is initialized.
141986eef2eSBarry Smith 
142db781477SPatrick Sanan .seealso: `SETERRQ()`, `PetscCall()`, `PetscCallMPI()`, `PetscTraceBackErrorHandler()`, `PetscPushErrorHandler()`, `PetscError()`, `CHKMEMQ`
143986eef2eSBarry Smith M*/
14498921bdaSJacob Faibussowitsch #define SETERRMPI(comm, ierr, ...) return (PetscError(comm, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr, PETSC_ERROR_INITIAL, __VA_ARGS__), PETSC_MPI_ERROR_CODE)
145ee8199e6SMatthew G. Knepley 
146ee8199e6SMatthew G. Knepley /*MC
147f388eb8bSPatrick Sanan    SETERRA - Fortran-only macro that can be called when an error has been detected from the main program
148f388eb8bSPatrick Sanan 
149f388eb8bSPatrick Sanan    Synopsis:
150f388eb8bSPatrick Sanan    #include <petscsys.h>
151f388eb8bSPatrick Sanan    PetscErrorCode SETERRA(MPI_Comm comm,PetscErrorCode ierr,char *message)
152f388eb8bSPatrick Sanan 
153f388eb8bSPatrick Sanan    Collective
154f388eb8bSPatrick Sanan 
155f388eb8bSPatrick Sanan    Input Parameters:
156f388eb8bSPatrick Sanan +  comm - A communicator, so that the error can be collective
157f388eb8bSPatrick Sanan .  ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
158f388eb8bSPatrick Sanan -  message - error message in the printf format
159f388eb8bSPatrick Sanan 
160f388eb8bSPatrick Sanan   Level: beginner
161f388eb8bSPatrick Sanan 
162f388eb8bSPatrick Sanan    Notes:
16387497f52SBarry Smith     This should only be used with Fortran. With C/C++, use `SETERRQ()`.
164f388eb8bSPatrick Sanan 
165f388eb8bSPatrick Sanan    Fortran Notes:
16687497f52SBarry Smith       `SETERRQ()` may be called from Fortran subroutines but `SETERRA()` must be called from the
167f388eb8bSPatrick Sanan       Fortran main program.
168f388eb8bSPatrick Sanan 
169db781477SPatrick Sanan .seealso: `SETERRQ()`, `SETERRABORT()`, `PetscCall()`, `CHKERRA()`, `PetscCallAbort()`
170f388eb8bSPatrick Sanan M*/
171f388eb8bSPatrick Sanan 
172f388eb8bSPatrick Sanan /*MC
173fa190f98SMatthew G. Knepley    SETERRABORT - Macro that can be called when an error has been detected,
174fa190f98SMatthew G. Knepley 
175fa190f98SMatthew G. Knepley    Synopsis:
176fa190f98SMatthew G. Knepley    #include <petscsys.h>
17798921bdaSJacob Faibussowitsch    PetscErrorCode SETERRABORT(MPI_Comm comm,PetscErrorCode ierr,char *message,...)
178fa190f98SMatthew G. Knepley 
179d083f849SBarry Smith    Collective
180fa190f98SMatthew G. Knepley 
181fa190f98SMatthew G. Knepley    Input Parameters:
182fa190f98SMatthew G. Knepley +  comm - A communicator, so that the error can be collective
1833af045c5SBarry Smith .  ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
184fa190f98SMatthew G. Knepley -  message - error message in the printf format
185fa190f98SMatthew G. Knepley 
186fa190f98SMatthew G. Knepley   Level: beginner
187fa190f98SMatthew G. Knepley 
188fa190f98SMatthew G. Knepley    Notes:
18987497f52SBarry Smith     This function just calls `MPI_Abort()`.
19087497f52SBarry Smith 
19187497f52SBarry Smith     This should only be called in routines that cannot return an error code, such as in C++ constructors.
192fa190f98SMatthew G. Knepley 
193db781477SPatrick Sanan .seealso: `SETERRQ()`, `PetscTraceBackErrorHandler()`, `PetscPushErrorHandler()`, `PetscError()`, `PetscCall()`, `CHKMEMQ`
194fa190f98SMatthew G. Knepley M*/
1959371c9d4SSatish Balay #define SETERRABORT(comm, ierr, ...) \
1969371c9d4SSatish Balay   do { \
19798921bdaSJacob Faibussowitsch     PetscError(comm, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr, PETSC_ERROR_INITIAL, __VA_ARGS__); \
19898921bdaSJacob Faibussowitsch     MPI_Abort(comm, ierr); \
19998921bdaSJacob Faibussowitsch   } while (0)
2009a00fa46SSatish Balay 
20130de9b25SBarry Smith /*MC
2022c71b3e2SJacob Faibussowitsch   PetscCheck - Check that a particular condition is true
2032c71b3e2SJacob Faibussowitsch 
2042c71b3e2SJacob Faibussowitsch   Synopsis:
2052c71b3e2SJacob Faibussowitsch   #include <petscerror.h>
2062c71b3e2SJacob Faibussowitsch   void PetscCheck(bool cond, MPI_Comm comm, PetscErrorCode ierr, const char *message, ...)
2072c71b3e2SJacob Faibussowitsch 
2082c71b3e2SJacob Faibussowitsch   Collective
2092c71b3e2SJacob Faibussowitsch 
2102c71b3e2SJacob Faibussowitsch   Input Parameters:
2112c71b3e2SJacob Faibussowitsch + cond    - The boolean condition
2122c71b3e2SJacob Faibussowitsch . comm    - The communicator on which the check can be collective on
2132c71b3e2SJacob Faibussowitsch . ierr    - A nonzero error code, see include/petscerror.h for the complete list
2142c71b3e2SJacob Faibussowitsch - message - Error message in printf format
2152c71b3e2SJacob Faibussowitsch 
2162c71b3e2SJacob Faibussowitsch   Notes:
2172c71b3e2SJacob Faibussowitsch   Enabled in both optimized and debug builds.
2182c71b3e2SJacob Faibussowitsch 
21987497f52SBarry Smith   Calls `SETERRQ()` if the assertion fails, so can only be called from functions returning a
22087497f52SBarry Smith   `PetscErrorCode` (or equivalent type after conversion).
2212c71b3e2SJacob Faibussowitsch 
2222c71b3e2SJacob Faibussowitsch   Level: beginner
2232c71b3e2SJacob Faibussowitsch 
2244be741a6SBarry Smith .seealso: `PetscAssert()`, `SETERRQ()`, `PetscError()`, `PetscCall()`, `PetscCheckAbort()`
2259566063dSJacob Faibussowitsch M*/
2269371c9d4SSatish Balay #define PetscCheck(cond, comm, ierr, ...) \
2279371c9d4SSatish Balay   do { \
2289371c9d4SSatish Balay     if (PetscUnlikely(!(cond))) SETERRQ(comm, ierr, __VA_ARGS__); \
2299371c9d4SSatish Balay   } while (0)
2302c71b3e2SJacob Faibussowitsch 
2312c71b3e2SJacob Faibussowitsch /*MC
2324be741a6SBarry Smith   PetscCheckAbort - Check that a particular condition is true, otherwise prints error and aborts
2334be741a6SBarry Smith 
2344be741a6SBarry Smith   Synopsis:
2354be741a6SBarry Smith   #include <petscerror.h>
2364be741a6SBarry Smith   void PetscCheckAbort(bool cond, MPI_Comm comm, PetscErrorCode ierr, const char *message, ...)
2374be741a6SBarry Smith 
2384be741a6SBarry Smith   Collective
2394be741a6SBarry Smith 
2404be741a6SBarry Smith   Input Parameters:
2414be741a6SBarry Smith + cond    - The boolean condition
2424be741a6SBarry Smith . comm    - The communicator on which the check can be collective on
2434be741a6SBarry Smith . ierr    - A nonzero error code, see include/petscerror.h for the complete list
2444be741a6SBarry Smith - message - Error message in printf format
2454be741a6SBarry Smith 
2464be741a6SBarry Smith   Notes:
2474be741a6SBarry Smith   Enabled in both optimized and debug builds.
2484be741a6SBarry Smith 
24987497f52SBarry Smith   Calls `SETERRABORT()` if the assertion fails, can be called from a function that does not return an
25087497f52SBarry Smith   error code, such as a C++ constructor. usually `PetscCheck()` should be used.
2514be741a6SBarry Smith 
2524be741a6SBarry Smith   Level: developer
2534be741a6SBarry Smith 
254*0e6b6b59SJacob Faibussowitsch .seealso: `PetscAssertAbort()`, `PetscAssert()`, `SETERRQ()`, `PetscError()`, `PetscCall()`, `PetscCheck()`, `SETTERRABORT()`
2554be741a6SBarry Smith M*/
2569371c9d4SSatish Balay #define PetscCheckAbort(cond, comm, ierr, ...) \
257*0e6b6b59SJacob Faibussowitsch   do { \
258*0e6b6b59SJacob Faibussowitsch     if (PetscUnlikely(!(cond))) SETERRABORT(comm, ierr, __VA_ARGS__); \
259*0e6b6b59SJacob Faibussowitsch   } while (0);
2604be741a6SBarry Smith 
2614be741a6SBarry Smith /*MC
2629ace16cdSJacob Faibussowitsch   PetscAssert - Assert that a particular condition is true
2639ace16cdSJacob Faibussowitsch 
2649ace16cdSJacob Faibussowitsch   Synopsis:
2659ace16cdSJacob Faibussowitsch   #include <petscerror.h>
2669ace16cdSJacob Faibussowitsch   void PetscAssert(bool cond, MPI_Comm comm, PetscErrorCode ierr, const char *message, ...)
2679ace16cdSJacob Faibussowitsch 
2689ace16cdSJacob Faibussowitsch   Collective
2699ace16cdSJacob Faibussowitsch 
2709ace16cdSJacob Faibussowitsch   Input Parameters:
2719ace16cdSJacob Faibussowitsch + cond    - The boolean condition
2729ace16cdSJacob Faibussowitsch . comm    - The communicator on which the check can be collective on
2739ace16cdSJacob Faibussowitsch . ierr    - A nonzero error code, see include/petscerror.h for the complete list
2749ace16cdSJacob Faibussowitsch - message - Error message in printf format
2759ace16cdSJacob Faibussowitsch 
2769ace16cdSJacob Faibussowitsch   Notes:
2772c71b3e2SJacob Faibussowitsch   Enabled only in debug builds. Note that any arguments to this macros are still visible to the
2782c71b3e2SJacob Faibussowitsch   compiler optimized builds (so must still contain valid code) but are guaranteed to not be
2792c71b3e2SJacob Faibussowitsch   executed.
2802c71b3e2SJacob Faibussowitsch 
28187497f52SBarry Smith   See `PetscCheck()` for usage and behaviour.
28287497f52SBarry Smith 
28387497f52SBarry Smith   This is needed instead of simply using `assert()` because this correctly handles the collective nature of errors under MPI
2849ace16cdSJacob Faibussowitsch 
2859ace16cdSJacob Faibussowitsch   Level: beginner
2869ace16cdSJacob Faibussowitsch 
287*0e6b6b59SJacob Faibussowitsch .seealso: `PetscCheck()`, `SETERRQ()`, `PetscError()`, `PetscAssertAbort()`
2889566063dSJacob Faibussowitsch M*/
2899371c9d4SSatish Balay #define PetscAssert(cond, comm, ierr, ...) \
2909371c9d4SSatish Balay   do { \
2919371c9d4SSatish Balay     if (PetscUnlikelyDebug(!(cond))) SETERRQ(comm, ierr, __VA_ARGS__); \
2929371c9d4SSatish Balay   } while (0)
2939ace16cdSJacob Faibussowitsch 
2949ace16cdSJacob Faibussowitsch /*MC
295*0e6b6b59SJacob Faibussowitsch   PetscAssertAbort - Assert that a particular condition is true, otherwise prints error and aborts
296*0e6b6b59SJacob Faibussowitsch 
297*0e6b6b59SJacob Faibussowitsch   Synopsis:
298*0e6b6b59SJacob Faibussowitsch   #include <petscerror.h>
299*0e6b6b59SJacob Faibussowitsch   void PetscAssertAbort(bool cond, MPI_Comm comm, PetscErrorCode ierr, const char *message, ...)
300*0e6b6b59SJacob Faibussowitsch 
301*0e6b6b59SJacob Faibussowitsch   Collective
302*0e6b6b59SJacob Faibussowitsch 
303*0e6b6b59SJacob Faibussowitsch   Input Parameters:
304*0e6b6b59SJacob Faibussowitsch + cond    - The boolean condition
305*0e6b6b59SJacob Faibussowitsch . comm    - The communicator on which the check can be collective on
306*0e6b6b59SJacob Faibussowitsch . ierr    - A nonzero error code, see include/petscerror.h for the complete list
307*0e6b6b59SJacob Faibussowitsch - message - Error message in printf format
308*0e6b6b59SJacob Faibussowitsch 
309*0e6b6b59SJacob Faibussowitsch   Notes:
310*0e6b6b59SJacob Faibussowitsch   Enabled only in debug builds. See `PetscCheckAbort()` for usage.
311*0e6b6b59SJacob Faibussowitsch 
312*0e6b6b59SJacob Faibussowitsch   Level: beginner
313*0e6b6b59SJacob Faibussowitsch 
314*0e6b6b59SJacob Faibussowitsch .seealso: `PetscCheckAbort()`, `PetscAssert()`, `PetscCheck()`, `SETERRABORT()`, `PetscError()`
315*0e6b6b59SJacob Faibussowitsch M*/
316*0e6b6b59SJacob Faibussowitsch #define PetscAssertAbort(cond, comm, ierr, ...) \
317*0e6b6b59SJacob Faibussowitsch   do { \
318*0e6b6b59SJacob Faibussowitsch     if (PetscUnlikelyDebug(!(cond))) SETERRABORT(comm, ierr, __VA_ARGS__); \
319*0e6b6b59SJacob Faibussowitsch   } while (0)
320*0e6b6b59SJacob Faibussowitsch 
321*0e6b6b59SJacob Faibussowitsch /*MC
32249c86fc7SBarry Smith   PetscCall - Calls a PETSc function and then checks the resulting error code, if it is non-zero it calls the error
32349c86fc7SBarry Smith   handler and returns from the current function with the error code.
3249566063dSJacob Faibussowitsch 
3259566063dSJacob Faibussowitsch   Synopsis:
3269566063dSJacob Faibussowitsch   #include <petscerror.h>
32749c86fc7SBarry Smith   void PetscCall(PetscFunction(args))
3289566063dSJacob Faibussowitsch 
3299566063dSJacob Faibussowitsch   Not Collective
3309566063dSJacob Faibussowitsch 
3319566063dSJacob Faibussowitsch   Input Parameter:
33249c86fc7SBarry Smith . PetscFunction - any PETSc function that returns an error code
3339566063dSJacob Faibussowitsch 
3349566063dSJacob Faibussowitsch   Notes:
3359566063dSJacob Faibussowitsch   Once the error handler is called the calling function is then returned from with the given
33687497f52SBarry Smith   error code. Experienced users can set the error handler with `PetscPushErrorHandler()`.
3379566063dSJacob Faibussowitsch 
33887497f52SBarry Smith   `PetscCall()` cannot be used in functions returning a datatype not convertible to
33987497f52SBarry Smith   `PetscErrorCode`. For example, `PetscCall()` may not be used in functions returning void, use
34087497f52SBarry Smith   `PetscCallVoid()` in this case.
3419566063dSJacob Faibussowitsch 
3429566063dSJacob Faibussowitsch   Example Usage:
3439566063dSJacob Faibussowitsch .vb
3449566063dSJacob Faibussowitsch   PetscCall(PetscInitiailize(...)); // OK to call even when PETSc is not yet initialized!
3459566063dSJacob Faibussowitsch 
3469566063dSJacob Faibussowitsch   struct my_struct
3479566063dSJacob Faibussowitsch   {
3489566063dSJacob Faibussowitsch     void *data;
3499566063dSJacob Faibussowitsch   } my_complex_type;
3509566063dSJacob Faibussowitsch 
3519566063dSJacob Faibussowitsch   struct my_struct bar(void)
3529566063dSJacob Faibussowitsch   {
3536aad120cSJose E. Roman     PetscCall(foo(15)); // ERROR PetscErrorCode not convertible to struct my_struct!
3549566063dSJacob Faibussowitsch   }
3559566063dSJacob Faibussowitsch 
3566aad120cSJose E. Roman   PetscCall(bar()) // ERROR input not convertible to PetscErrorCode
3579566063dSJacob Faibussowitsch .ve
3589566063dSJacob Faibussowitsch 
35987497f52SBarry Smith   It is also possible to call this directly on a `PetscErrorCode` variable
36049c86fc7SBarry Smith .vb
36149c86fc7SBarry Smith   PetscCall(ierr);  // check if ierr is nonzero
36249c86fc7SBarry Smith .ve
36349c86fc7SBarry Smith 
364792fecdfSBarry Smith   Should not be used to call callback functions provided by users, `PetscCallBack()` should be used in that situation.
365ef1023bdSBarry Smith 
3666a8be23eSBarry Smith   `PetscUseTypeMethod()` or `PetscTryTypeMethod()` should be used when calling functions pointers contained in a PETSc object's `ops` array
3676a8be23eSBarry Smith 
36849c86fc7SBarry Smith   Fortran Notes:
36949c86fc7SBarry Smith     The Fortran function from which this is used must declare a variable PetscErrorCode ierr and ierr must be
37087497f52SBarry Smith     the final argument to the PETSc function being called.
37149c86fc7SBarry Smith 
37249c86fc7SBarry Smith     In the main program and in Fortran subroutines that do not have ierr as the final return parameter one
37387497f52SBarry Smith     should use `PetscCallA()`
37449c86fc7SBarry Smith 
37549c86fc7SBarry Smith   Example Fortran Usage:
37649c86fc7SBarry Smith .vb
37749c86fc7SBarry Smith   PetscErrorCode ierr
37849c86fc7SBarry Smith   Vec v
37949c86fc7SBarry Smith 
38049c86fc7SBarry Smith   ...
38149c86fc7SBarry Smith   PetscCall(VecShift(v,1.0,ierr))
38249c86fc7SBarry Smith   PetscCallA(VecShift(v,1.0,ierr))
38349c86fc7SBarry Smith .ve
38449c86fc7SBarry Smith 
3859566063dSJacob Faibussowitsch   Level: beginner
3869566063dSJacob Faibussowitsch 
38749c86fc7SBarry Smith .seealso: `SETERRQ()`, `PetscCheck()`, `PetscAssert()`, `PetscTraceBackErrorHandler()`, `PetscCallMPI()`
388792fecdfSBarry Smith           `PetscPushErrorHandler()`, `PetscError()`, `CHKMEMQ`, `CHKERRA()`, `CHKERRMPI()`, `PetscCallBack()`
3899566063dSJacob Faibussowitsch M*/
390ef1023bdSBarry Smith 
391ef1023bdSBarry Smith /*MC
392792fecdfSBarry Smith   PetscCallBack - Calls a user provided PETSc callback function and then checks the resulting error code, if it is non-zero it calls the error
393ef1023bdSBarry Smith   handler and returns from the current function with the error code.
394ef1023bdSBarry Smith 
395ef1023bdSBarry Smith   Synopsis:
396ef1023bdSBarry Smith   #include <petscerror.h>
397792fecdfSBarry Smith   void PetscCallBack(const char *functionname,PetscFunction(args))
398ef1023bdSBarry Smith 
399ef1023bdSBarry Smith   Not Collective
400ef1023bdSBarry Smith 
401ef1023bdSBarry Smith   Input Parameters:
402ef1023bdSBarry Smith + functionname - the name of the function being called, this can be a string with spaces that describes the meaning of the callback
40387497f52SBarry Smith - PetscFunction - user provided callback function that returns an error code
404ef1023bdSBarry Smith 
405ef1023bdSBarry Smith   Notes:
406ef1023bdSBarry Smith   Once the error handler is called the calling function is then returned from with the given
40787497f52SBarry Smith   error code. Experienced users can set the error handler with `PetscPushErrorHandler()`.
408ef1023bdSBarry Smith 
40987497f52SBarry Smith   `PetscCallBack()` should only be called in PETSc when a call is being made to a user provided call-back routine.
410ef1023bdSBarry Smith 
411ef1023bdSBarry Smith   Example Usage:
412ef1023bdSBarry Smith .vb
413792fecdfSBarry Smith   PetscCallBack("XXX callback to do something",a->callback(...));
414ef1023bdSBarry Smith .ve
415ef1023bdSBarry Smith 
416ef1023bdSBarry Smith   Level: developer
417ef1023bdSBarry Smith 
41887497f52SBarry Smith .seealso: `SETERRQ()`, `PetscCheck()`, `PetscCall()`, `PetscAssert()`, `PetscTraceBackErrorHandler()`, `PetscCallMPI()`
419ef1023bdSBarry Smith           `PetscPushErrorHandler()`, `PetscError()`, `CHKMEMQ`, `CHKERRA()`, `CHKERRMPI()`, `PetscCall()`
420ef1023bdSBarry Smith M*/
421ef1023bdSBarry Smith 
4229566063dSJacob Faibussowitsch #if defined(PETSC_CLANG_STATIC_ANALYZER)
4239566063dSJacob Faibussowitsch void PetscCall(PetscErrorCode);
424792fecdfSBarry Smith void PetscCallBack(const char *, PetscErrorCode);
4259566063dSJacob Faibussowitsch void PetscCallVoid(PetscErrorCode);
4269566063dSJacob Faibussowitsch #else
4279371c9d4SSatish Balay #define PetscCall(...) \
4289371c9d4SSatish Balay   do { \
429e33ced7fSLisandro Dalcin     PetscErrorCode ierr_q_; \
43037154d10SBarry Smith     PetscStackUpdateLine; \
431e33ced7fSLisandro Dalcin     ierr_q_ = __VA_ARGS__; \
4329566063dSJacob Faibussowitsch     if (PetscUnlikely(ierr_q_)) return PetscError(PETSC_COMM_SELF, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr_q_, PETSC_ERROR_REPEAT, " "); \
4339566063dSJacob Faibussowitsch   } while (0)
4349371c9d4SSatish Balay #define PetscCallBack(function, ...) \
4359371c9d4SSatish Balay   do { \
436e33ced7fSLisandro Dalcin     PetscErrorCode ierr_q_; \
437e33ced7fSLisandro Dalcin     PetscStackUpdateLine; \
438e33ced7fSLisandro Dalcin     PetscStackPushExternal(function); \
439e33ced7fSLisandro Dalcin     ierr_q_ = __VA_ARGS__; \
440ef1023bdSBarry Smith     PetscStackPop; \
441ef1023bdSBarry Smith     if (PetscUnlikely(ierr_q_)) return PetscError(PETSC_COMM_SELF, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr_q_, PETSC_ERROR_REPEAT, " "); \
442ef1023bdSBarry Smith   } while (0)
4439371c9d4SSatish Balay #define PetscCallVoid(...) \
4449371c9d4SSatish Balay   do { \
445e33ced7fSLisandro Dalcin     PetscErrorCode ierr_void_; \
446e33ced7fSLisandro Dalcin     PetscStackUpdateLine; \
447e33ced7fSLisandro Dalcin     ierr_void_ = __VA_ARGS__; \
4489371c9d4SSatish Balay     if (PetscUnlikely(ierr_void_)) { \
4499371c9d4SSatish Balay       (void)PetscError(PETSC_COMM_SELF, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr_void_, PETSC_ERROR_REPEAT, " "); \
4509371c9d4SSatish Balay       return; \
4519371c9d4SSatish Balay     } \
4529566063dSJacob Faibussowitsch   } while (0)
4539566063dSJacob Faibussowitsch #endif
4549566063dSJacob Faibussowitsch 
4559566063dSJacob Faibussowitsch /*MC
4569566063dSJacob Faibussowitsch   CHKERRQ - Checks error code returned from PETSc function
45730de9b25SBarry Smith 
45830de9b25SBarry Smith   Synopsis:
459aaa7dc30SBarry Smith   #include <petscsys.h>
4609566063dSJacob Faibussowitsch   void CHKERRQ(PetscErrorCode ierr)
4619566063dSJacob Faibussowitsch 
4629566063dSJacob Faibussowitsch   Not Collective
4639566063dSJacob Faibussowitsch 
4649566063dSJacob Faibussowitsch   Input Parameters:
4659566063dSJacob Faibussowitsch . ierr - nonzero error code
4669566063dSJacob Faibussowitsch 
4679566063dSJacob Faibussowitsch   Notes:
46887497f52SBarry Smith   Deprecated in favor of `PetscCall()`. This routine behaves identically to it.
4699566063dSJacob Faibussowitsch 
4709566063dSJacob Faibussowitsch   Level: deprecated
4719566063dSJacob Faibussowitsch 
472db781477SPatrick Sanan .seealso: `PetscCall()`
4739566063dSJacob Faibussowitsch M*/
4749566063dSJacob Faibussowitsch #define CHKERRQ(...) PetscCall(__VA_ARGS__)
4759566063dSJacob Faibussowitsch #define CHKERRV(...) PetscCallVoid(__VA_ARGS__)
4769566063dSJacob Faibussowitsch 
477db9cea48SBarry Smith PETSC_EXTERN void PetscMPIErrorString(PetscMPIInt, char *);
478db9cea48SBarry Smith 
4799566063dSJacob Faibussowitsch /*MC
4809566063dSJacob Faibussowitsch   PetscCallMPI - Checks error code returned from MPI calls, if non-zero it calls the error
4819566063dSJacob Faibussowitsch   handler and then returns
4829566063dSJacob Faibussowitsch 
4839566063dSJacob Faibussowitsch   Synopsis:
4849566063dSJacob Faibussowitsch   #include <petscerror.h>
48549c86fc7SBarry Smith   void PetscCallMPI(MPI_Function(args))
48630de9b25SBarry Smith 
487eca87e8dSBarry Smith   Not Collective
48830de9b25SBarry Smith 
48930de9b25SBarry Smith   Input Parameters:
49049c86fc7SBarry Smith . MPI_Function - an MPI function that returns an MPI error code
49130de9b25SBarry Smith 
4929566063dSJacob Faibussowitsch   Notes:
49387497f52SBarry Smith   Always returns the error code `PETSC_ERR_MPI`; the MPI error code and string are embedded in
4949566063dSJacob Faibussowitsch   the string error message. Do not use this to call any other routines (for example PETSc
4959566063dSJacob Faibussowitsch   routines), it should only be used for direct MPI calls. Due to limitations of the
4969566063dSJacob Faibussowitsch   preprocessor this can unfortunately not easily be enforced, so the user should take care to
4979566063dSJacob Faibussowitsch   check this themselves.
4989566063dSJacob Faibussowitsch 
4999566063dSJacob Faibussowitsch   Example Usage:
5009566063dSJacob Faibussowitsch .vb
5019566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(...)); // OK, calling MPI function
5029566063dSJacob Faibussowitsch 
5039566063dSJacob Faibussowitsch   PetscCallMPI(PetscFunction(...)); // ERROR, use PetscCall() instead!
5049566063dSJacob Faibussowitsch .ve
5059566063dSJacob Faibussowitsch 
50649c86fc7SBarry Smith   Fortran Notes:
50787497f52SBarry Smith     The Fortran function from which this is used must declare a variable `PetscErrorCode` ierr and ierr must be
50849c86fc7SBarry Smith     the final argument to the MPI function being called.
50949c86fc7SBarry Smith 
51049c86fc7SBarry Smith     In the main program and in Fortran subroutines that do not have ierr as the final return parameter one
51187497f52SBarry Smith     should use `PetscCallMPIA()`
51249c86fc7SBarry Smith 
51349c86fc7SBarry Smith   Fortran Usage:
51449c86fc7SBarry Smith .vb
51549c86fc7SBarry Smith   PetscErrorCode ierr or integer ierr
51649c86fc7SBarry Smith   ...
51749c86fc7SBarry Smith   PetscCallMPI(MPI_Comm_size(...,ierr))
51849c86fc7SBarry Smith   PetscCallMPIA(MPI_Comm_size(...,ierr)) ! Will abort after calling error handler
51949c86fc7SBarry Smith 
52049c86fc7SBarry Smith   PetscCallMPI(MPI_Comm_size(...,eflag)) ! ERROR, final argument must be ierr
52149c86fc7SBarry Smith .ve
52249c86fc7SBarry Smith 
52330de9b25SBarry Smith   Level: beginner
52430de9b25SBarry Smith 
525db781477SPatrick Sanan .seealso: `SETERRMPI()`, `PetscCall()`, `SETERRQ()`, `SETERRABORT()`, `PetscCallAbort()`,
526db781477SPatrick Sanan           `PetscTraceBackErrorHandler()`, `PetscPushErrorHandler()`, `PetscError()`, `CHKMEMQ`
52730de9b25SBarry Smith M*/
5283fcd9f07SJacob Faibussowitsch #if defined(PETSC_CLANG_STATIC_ANALYZER)
52963a3b9bcSJacob Faibussowitsch void PetscCallMPI(PetscMPIInt);
530064a246eSJacob Faibussowitsch #else
5319371c9d4SSatish Balay #define PetscCallMPI(...) \
5329371c9d4SSatish Balay   do { \
533e33ced7fSLisandro Dalcin     PetscMPIInt _7_errorcode; \
534e33ced7fSLisandro Dalcin     char        _7_errorstring[2 * MPI_MAX_ERROR_STRING]; \
535ef1023bdSBarry Smith     PetscStackUpdateLine; \
536792fecdfSBarry Smith     PetscStackPushExternal("MPI function"); \
537e33ced7fSLisandro Dalcin     { _7_errorcode = __VA_ARGS__; } \
538ef1023bdSBarry Smith     PetscStackPop; \
5399566063dSJacob Faibussowitsch     if (PetscUnlikely(_7_errorcode)) { \
540db9cea48SBarry Smith       PetscMPIErrorString(_7_errorcode, (char *)_7_errorstring); \
541db9cea48SBarry Smith       SETERRQ(PETSC_COMM_SELF, PETSC_ERR_MPI, "MPI error %d %s", (int)_7_errorcode, _7_errorstring); \
5423fcd9f07SJacob Faibussowitsch     } \
5433fcd9f07SJacob Faibussowitsch   } while (0)
5449566063dSJacob Faibussowitsch #endif
545064a246eSJacob Faibussowitsch 
5467037b0edSPatrick Sanan /*MC
5479566063dSJacob Faibussowitsch   CHKERRMPI - Checks error code returned from MPI calls, if non-zero it calls the error
5489566063dSJacob Faibussowitsch   handler and then returns
5499566063dSJacob Faibussowitsch 
5509566063dSJacob Faibussowitsch   Synopsis:
5519566063dSJacob Faibussowitsch   #include <petscerror.h>
5529566063dSJacob Faibussowitsch   void CHKERRMPI(PetscErrorCode ierr)
5539566063dSJacob Faibussowitsch 
5549566063dSJacob Faibussowitsch   Not Collective
5559566063dSJacob Faibussowitsch 
5569566063dSJacob Faibussowitsch   Input Parameter:
5579566063dSJacob Faibussowitsch . ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
5589566063dSJacob Faibussowitsch 
5599566063dSJacob Faibussowitsch   Notes:
56087497f52SBarry Smith   Deprecated in favor of `PetscCallMPI()`. This routine behaves identically to it.
5619566063dSJacob Faibussowitsch 
5629566063dSJacob Faibussowitsch   Level: deprecated
5639566063dSJacob Faibussowitsch 
564db781477SPatrick Sanan .seealso: `PetscCallMPI()`
5659566063dSJacob Faibussowitsch M*/
5669566063dSJacob Faibussowitsch #define CHKERRMPI(...) PetscCallMPI(__VA_ARGS__)
5679566063dSJacob Faibussowitsch 
5689566063dSJacob Faibussowitsch /*MC
5699566063dSJacob Faibussowitsch   PetscCallAbort - Checks error code returned from PETSc function, if non-zero it aborts immediately
5709566063dSJacob Faibussowitsch 
5719566063dSJacob Faibussowitsch   Synopsis:
5729566063dSJacob Faibussowitsch   #include <petscerror.h>
5739566063dSJacob Faibussowitsch   void PetscCallAbort(MPI_Comm comm, PetscErrorCode ierr)
5749566063dSJacob Faibussowitsch 
5759566063dSJacob Faibussowitsch   Collective on comm
5769566063dSJacob Faibussowitsch 
5779566063dSJacob Faibussowitsch   Input Parameters:
5789566063dSJacob Faibussowitsch + comm - the MPI communicator on which to abort
5799566063dSJacob Faibussowitsch - ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
5809566063dSJacob Faibussowitsch 
5819566063dSJacob Faibussowitsch   Notes:
58287497f52SBarry Smith   This macro has identical type and usage semantics to `PetscCall()` with the important caveat
5839566063dSJacob Faibussowitsch   that this macro does not return. Instead, if ierr is nonzero it calls the PETSc error handler
58487497f52SBarry Smith   and then immediately calls `MPI_Abort()`. It can therefore be used anywhere.
5859566063dSJacob Faibussowitsch 
58687497f52SBarry Smith   As per `MPI_Abort()` semantics the communicator passed must be valid, although there is currently
58787497f52SBarry Smith   no attempt made at handling any potential errors from `MPI_Abort()`. Note that while
58887497f52SBarry Smith   `MPI_Abort()` is required to terminate only those processes which reside on comm, it is often
58987497f52SBarry Smith   the case that `MPI_Abort()` terminates *all* processes.
5909566063dSJacob Faibussowitsch 
5919566063dSJacob Faibussowitsch   Example Usage:
5929566063dSJacob Faibussowitsch .vb
5939566063dSJacob Faibussowitsch   PetscErrorCode boom(void) { return PETSC_ERR_MEM; }
5949566063dSJacob Faibussowitsch 
5959566063dSJacob Faibussowitsch   void foo(void)
5969566063dSJacob Faibussowitsch   {
5979566063dSJacob Faibussowitsch     PetscCallAbort(PETSC_COMM_WORLD,boom()); // OK, does not return a type
5989566063dSJacob Faibussowitsch   }
5999566063dSJacob Faibussowitsch 
6009566063dSJacob Faibussowitsch   double bar(void)
6019566063dSJacob Faibussowitsch   {
6029566063dSJacob Faibussowitsch     PetscCallAbort(PETSC_COMM_WORLD,boom()); // OK, does not return a type
6039566063dSJacob Faibussowitsch   }
6049566063dSJacob Faibussowitsch 
6059566063dSJacob Faibussowitsch   PetscCallAbort(MPI_COMM_NULL,boom()); // ERROR, communicator should be valid
6069566063dSJacob Faibussowitsch 
6079566063dSJacob Faibussowitsch   struct baz
6089566063dSJacob Faibussowitsch   {
6099566063dSJacob Faibussowitsch     baz()
6109566063dSJacob Faibussowitsch     {
6119566063dSJacob Faibussowitsch       PetscCallAbort(PETSC_COMM_SELF,boom()); // OK
6129566063dSJacob Faibussowitsch     }
6139566063dSJacob Faibussowitsch 
6149566063dSJacob Faibussowitsch     ~baz()
6159566063dSJacob Faibussowitsch     {
6169566063dSJacob Faibussowitsch       PetscCallAbort(PETSC_COMM_SELF,boom()); // OK (in fact the only way to handle PETSc errors)
6179566063dSJacob Faibussowitsch     }
6189566063dSJacob Faibussowitsch   };
6199566063dSJacob Faibussowitsch .ve
6209566063dSJacob Faibussowitsch 
6219566063dSJacob Faibussowitsch   Level: intermediate
6229566063dSJacob Faibussowitsch 
623db781477SPatrick Sanan .seealso: `SETERRABORT()`, `PetscTraceBackErrorHandler()`, `PetscPushErrorHandler()`, `PetscError()`,
624db781477SPatrick Sanan           `SETERRQ()`, `CHKMEMQ`, `PetscCallMPI()`
6259566063dSJacob Faibussowitsch M*/
6269566063dSJacob Faibussowitsch #if defined(PETSC_CLANG_STATIC_ANALYZER)
6279566063dSJacob Faibussowitsch void PetscCallAbort(MPI_Comm, PetscErrorCode);
6289566063dSJacob Faibussowitsch void PetscCallContinue(PetscErrorCode);
6299566063dSJacob Faibussowitsch #else
6309371c9d4SSatish Balay #define PetscCallAbort(comm, ...) \
6319371c9d4SSatish Balay   do { \
6329566063dSJacob Faibussowitsch     PetscErrorCode ierr_abort_ = __VA_ARGS__; \
6339566063dSJacob Faibussowitsch     if (PetscUnlikely(ierr_abort_)) { \
6349566063dSJacob Faibussowitsch       PetscError(PETSC_COMM_SELF, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr_abort_, PETSC_ERROR_REPEAT, " "); \
6359566063dSJacob Faibussowitsch       MPI_Abort(comm, ierr_abort_); \
6369566063dSJacob Faibussowitsch     } \
6379566063dSJacob Faibussowitsch   } while (0)
6389371c9d4SSatish Balay #define PetscCallContinue(...) \
6399371c9d4SSatish Balay   do { \
6409566063dSJacob Faibussowitsch     PetscErrorCode ierr_continue_ = __VA_ARGS__; \
6419566063dSJacob Faibussowitsch     if (PetscUnlikely(ierr_continue_)) PetscError(PETSC_COMM_SELF, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr_continue_, PETSC_ERROR_REPEAT, " "); \
6429566063dSJacob Faibussowitsch   } while (0)
6439566063dSJacob Faibussowitsch #endif
6449566063dSJacob Faibussowitsch 
6459566063dSJacob Faibussowitsch /*MC
6469566063dSJacob Faibussowitsch   CHKERRABORT - Checks error code returned from PETSc function. If non-zero it aborts immediately.
6479566063dSJacob Faibussowitsch 
6489566063dSJacob Faibussowitsch   Synopsis:
6499566063dSJacob Faibussowitsch   #include <petscerror.h>
6509566063dSJacob Faibussowitsch   void CHKERRABORT(MPI_Comm comm, PetscErrorCode ierr)
6519566063dSJacob Faibussowitsch 
6529566063dSJacob Faibussowitsch   Not Collective
6539566063dSJacob Faibussowitsch 
6549566063dSJacob Faibussowitsch   Input Parameters:
6559566063dSJacob Faibussowitsch + comm - the MPI communicator
6569566063dSJacob Faibussowitsch - ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
6579566063dSJacob Faibussowitsch 
6589566063dSJacob Faibussowitsch   Notes:
65987497f52SBarry Smith   Deprecated in favor of `PetscCallAbort()`. This routine behaves identically to it.
6609566063dSJacob Faibussowitsch 
6619566063dSJacob Faibussowitsch   Level: deprecated
6629566063dSJacob Faibussowitsch 
663db781477SPatrick Sanan .seealso: `PetscCallAbort()`
6649566063dSJacob Faibussowitsch M*/
6659566063dSJacob Faibussowitsch #define CHKERRABORT(comm, ...) PetscCallAbort(comm, __VA_ARGS__)
6669566063dSJacob Faibussowitsch #define CHKERRCONTINUE(...)    PetscCallContinue(__VA_ARGS__)
6679566063dSJacob Faibussowitsch 
6689566063dSJacob Faibussowitsch /*MC
66987497f52SBarry Smith    CHKERRA - Fortran-only replacement for use of `CHKERRQ()` in the main program, which aborts immediately
670f388eb8bSPatrick Sanan 
671f388eb8bSPatrick Sanan    Synopsis:
672f388eb8bSPatrick Sanan    #include <petscsys.h>
673f388eb8bSPatrick Sanan    PetscErrorCode CHKERRA(PetscErrorCode ierr)
674f388eb8bSPatrick Sanan 
675f388eb8bSPatrick Sanan    Not Collective
676f388eb8bSPatrick Sanan 
677f388eb8bSPatrick Sanan    Input Parameters:
678f388eb8bSPatrick Sanan .  ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
679f388eb8bSPatrick Sanan 
68087497f52SBarry Smith   Level: deprecated
681f388eb8bSPatrick Sanan 
68287497f52SBarry Smith    Note:
68387497f52SBarry Smith    This macro is rarely needed, normal usage is `PetscCallA()` in the main Fortran program.
684f388eb8bSPatrick Sanan 
68587497f52SBarry Smith .seealso: `PetscCall()`, `PetscCallA()`, `PetscCallAbort()`, `CHKERRQ()`, `SETERRA()`, `SETERRQ()`, `SETERRABORT()`
686f388eb8bSPatrick Sanan M*/
687f388eb8bSPatrick Sanan 
6881e4f893aSSatish Balay PETSC_EXTERN PetscBool petscwaitonerrorflg;
6891e4f893aSSatish Balay PETSC_EXTERN PetscBool petscindebugger;
6907c66cc67SJunchao Zhang 
6917c66cc67SJunchao Zhang /*MC
6927c66cc67SJunchao Zhang    PETSCABORT - Call MPI_Abort with an informative error code
6937c66cc67SJunchao Zhang 
6947c66cc67SJunchao Zhang    Synopsis:
6957c66cc67SJunchao Zhang    #include <petscsys.h>
6967c66cc67SJunchao Zhang    PETSCABORT(MPI_Comm comm, PetscErrorCode ierr)
6977c66cc67SJunchao Zhang 
6987c66cc67SJunchao Zhang    Collective
6997c66cc67SJunchao Zhang 
7007c66cc67SJunchao Zhang    Input Parameters:
7017c66cc67SJunchao Zhang +  comm - A communicator, so that the error can be collective
7027c66cc67SJunchao Zhang -  ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
7037c66cc67SJunchao Zhang 
704bf4d2887SBarry Smith    Level: advanced
7057c66cc67SJunchao Zhang 
706bf4d2887SBarry Smith    Notes:
707bf4d2887SBarry Smith    If the option -start_in_debugger was used then this calls abort() to stop the program in the debugger.
708bf4d2887SBarry Smith 
70987497f52SBarry Smith    if `PetscCIEnabledPortableErrorOutput` is set it strives to exit cleanly without call `MPI_Abort()`
710660278c0SBarry Smith 
7117c66cc67SJunchao Zhang  M*/
7129371c9d4SSatish Balay #define PETSCABORT(comm, ...) \
7139371c9d4SSatish Balay   do { \
714baae8e41SSatish Balay     if (petscwaitonerrorflg) PetscSleep(1000); \
715bf4d2887SBarry Smith     if (petscindebugger) abort(); \
7163fcd9f07SJacob Faibussowitsch     else { \
7173fcd9f07SJacob Faibussowitsch       PetscErrorCode ierr_petsc_abort_ = __VA_ARGS__; \
718660278c0SBarry Smith       PetscMPIInt    size; \
719660278c0SBarry Smith       MPI_Comm_size(comm, &size); \
720660278c0SBarry Smith       if (PetscCIEnabledPortableErrorOutput && size == PetscGlobalSize && ierr_petsc_abort_ != PETSC_ERR_SIG) { \
7219371c9d4SSatish Balay         MPI_Finalize(); \
7229371c9d4SSatish Balay         exit(0); \
723660278c0SBarry Smith       } else if (PetscCIEnabledPortableErrorOutput && PetscGlobalSize == 1) { \
724660278c0SBarry Smith         exit(0); \
725660278c0SBarry Smith       } else { \
726660278c0SBarry Smith         MPI_Abort(comm, (PetscMPIInt)ierr_petsc_abort_); \
727660278c0SBarry Smith       } \
7283fcd9f07SJacob Faibussowitsch     } \
7297c66cc67SJunchao Zhang   } while (0)
730986eef2eSBarry Smith 
7319566063dSJacob Faibussowitsch #ifdef PETSC_CLANGUAGE_CXX
732986eef2eSBarry Smith /*MC
7339566063dSJacob Faibussowitsch   PetscCallThrow - Checks error code, if non-zero it calls the C++ error handler which throws
7349566063dSJacob Faibussowitsch   an exception
735986eef2eSBarry Smith 
736986eef2eSBarry Smith   Synopsis:
7379566063dSJacob Faibussowitsch   #include <petscerror.h>
7389566063dSJacob Faibussowitsch   void PetscCallThrow(PetscErrorCode ierr)
739986eef2eSBarry Smith 
740986eef2eSBarry Smith   Not Collective
741986eef2eSBarry Smith 
7429566063dSJacob Faibussowitsch   Input Parameter:
743986eef2eSBarry Smith . ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
744986eef2eSBarry Smith 
745986eef2eSBarry Smith   Notes:
7469566063dSJacob Faibussowitsch   Requires PETSc to be configured with clanguage = c++. Throws a std::runtime_error() on error.
747986eef2eSBarry Smith 
74887497f52SBarry Smith   Once the error handler throws the exception you can use `PetscCallVoid()` which returns without
74987497f52SBarry Smith   an error code (bad idea since the error is ignored) or `PetscCallAbort()` to have `MPI_Abort()`
7509566063dSJacob Faibussowitsch   called immediately.
7519566063dSJacob Faibussowitsch 
7529566063dSJacob Faibussowitsch   Level: beginner
7539566063dSJacob Faibussowitsch 
754db781477SPatrick Sanan .seealso: `SETERRQ()`, `PetscCall()`, `SETERRABORT()`, `PetscCallAbort()`, `PetscTraceBackErrorHandler()`,
755db781477SPatrick Sanan           `PetscPushErrorHandler()`, `PetscError()`, `CHKMEMQ`
756986eef2eSBarry Smith M*/
7579371c9d4SSatish Balay #define PetscCallThrow(...) \
7589371c9d4SSatish Balay   do { \
7599566063dSJacob Faibussowitsch     PetscErrorCode ierr_cxx_ = __VA_ARGS__; \
7609566063dSJacob Faibussowitsch     if (PetscUnlikely(ierr_cxx_)) PetscError(PETSC_COMM_SELF, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr_cxx_, PETSC_ERROR_IN_CXX, PETSC_NULLPTR); \
761ffc4695bSBarry Smith   } while (0)
76285614651SBarry Smith 
763cc26af49SMatthew Knepley /*MC
764cc26af49SMatthew Knepley   CHKERRXX - Checks error code, if non-zero it calls the C++ error handler which throws an exception
765cc26af49SMatthew Knepley 
766cc26af49SMatthew Knepley   Synopsis:
7679566063dSJacob Faibussowitsch   #include <petscerror.h>
7683af045c5SBarry Smith   void CHKERRXX(PetscErrorCode ierr)
769cc26af49SMatthew Knepley 
770eca87e8dSBarry Smith   Not Collective
771cc26af49SMatthew Knepley 
7729566063dSJacob Faibussowitsch   Input Parameter:
7733af045c5SBarry Smith . ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
774cc26af49SMatthew Knepley 
775cc26af49SMatthew Knepley   Notes:
77687497f52SBarry Smith   Deprecated in favor of `PetscCallThrow()`. This routine behaves identically to it.
777cc26af49SMatthew Knepley 
7789566063dSJacob Faibussowitsch   Level: deprecated
779cc26af49SMatthew Knepley 
780db781477SPatrick Sanan .seealso: `PetscCallThrow()`
781cc26af49SMatthew Knepley M*/
7829566063dSJacob Faibussowitsch #define CHKERRXX(...) PetscCallThrow(__VA_ARGS__)
783fd705b32SMatthew Knepley #endif
784fd705b32SMatthew Knepley 
7853f520e80SJunchao Zhang /*MC
7869566063dSJacob Faibussowitsch   PetscCallCXX - Checks C++ function calls and if they throw an exception, catch it and then
7879566063dSJacob Faibussowitsch   return a PETSc error code
7883f520e80SJunchao Zhang 
7893f520e80SJunchao Zhang   Synopsis:
7909566063dSJacob Faibussowitsch   #include <petscerror.h>
7919566063dSJacob Faibussowitsch   void PetscCallCXX(expr) noexcept;
7923f520e80SJunchao Zhang 
7933f520e80SJunchao Zhang   Not Collective
7943f520e80SJunchao Zhang 
7959566063dSJacob Faibussowitsch   Input Parameter:
7969566063dSJacob Faibussowitsch . expr - An arbitrary expression
7973f520e80SJunchao Zhang 
7983f520e80SJunchao Zhang   Notes:
7999566063dSJacob Faibussowitsch   PetscCallCXX(expr) is a macro replacement for
8009566063dSJacob Faibussowitsch .vb
8019566063dSJacob Faibussowitsch   try {
8029566063dSJacob Faibussowitsch     expr;
8039566063dSJacob Faibussowitsch   } catch (const std::exception& e) {
8049566063dSJacob Faibussowitsch     return ConvertToPetscErrorCode(e);
8059566063dSJacob Faibussowitsch   }
8069566063dSJacob Faibussowitsch .ve
8079566063dSJacob Faibussowitsch   Due to the fact that it catches any (reasonable) exception, it is essentially noexcept.
8083f520e80SJunchao Zhang 
8099566063dSJacob Faibussowitsch   Example Usage:
8109566063dSJacob Faibussowitsch .vb
8119566063dSJacob Faibussowitsch   void foo(void) { throw std::runtime_error("error"); }
8123f520e80SJunchao Zhang 
8139566063dSJacob Faibussowitsch   void bar()
8149566063dSJacob Faibussowitsch   {
815e8952933SJacob Faibussowitsch     PetscCallCXX(foo()); // ERROR bar() does not return PetscErrorCode
8169566063dSJacob Faibussowitsch   }
8179566063dSJacob Faibussowitsch 
8189566063dSJacob Faibussowitsch   PetscErrorCode baz()
8199566063dSJacob Faibussowitsch   {
8209566063dSJacob Faibussowitsch     PetscCallCXX(foo()); // OK
8219566063dSJacob Faibussowitsch 
8229566063dSJacob Faibussowitsch     PetscCallCXX(
8239566063dSJacob Faibussowitsch       bar();
824e8952933SJacob Faibussowitsch       foo(); // OK mutliple statements allowed
8259566063dSJacob Faibussowitsch     );
8269566063dSJacob Faibussowitsch   }
8279566063dSJacob Faibussowitsch 
8289566063dSJacob Faibussowitsch   struct bop
8299566063dSJacob Faibussowitsch   {
8309566063dSJacob Faibussowitsch     bop()
8319566063dSJacob Faibussowitsch     {
832e8952933SJacob Faibussowitsch       PetscCallCXX(foo()); // ERROR returns PetscErrorCode, cannot be used in constructors
8339566063dSJacob Faibussowitsch     }
8349566063dSJacob Faibussowitsch   };
8359566063dSJacob Faibussowitsch 
836e8952933SJacob Faibussowitsch   // ERROR contains do-while, cannot be used as function-try block
8379566063dSJacob Faibussowitsch   PetscErrorCode qux() PetscCallCXX(
8389566063dSJacob Faibussowitsch     bar();
8399566063dSJacob Faibussowitsch     baz();
8409566063dSJacob Faibussowitsch     foo();
8419566063dSJacob Faibussowitsch     return 0;
8429566063dSJacob Faibussowitsch   )
8439566063dSJacob Faibussowitsch .ve
8449566063dSJacob Faibussowitsch 
84549762cbcSSatish Balay   Level: beginner
84649762cbcSSatish Balay 
847db781477SPatrick Sanan .seealso: `PetscCallThrow()`, `SETERRQ()`, `PetscCall()`, `SETERRABORT()`, `PetscCallAbort()`,
848db781477SPatrick Sanan           `PetscTraceBackErrorHandler()`, `PetscPushErrorHandler()`, `PetscError()`, `CHKMEMQ`
8493f520e80SJunchao Zhang M*/
8509371c9d4SSatish Balay #define PetscCallCXX(...) \
8519371c9d4SSatish Balay   do { \
85237154d10SBarry Smith     PetscStackUpdateLine; \
8533fcd9f07SJacob Faibussowitsch     try { \
8543fcd9f07SJacob Faibussowitsch       __VA_ARGS__; \
8559371c9d4SSatish Balay     } catch (const std::exception &e) { SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "%s", e.what()); } \
8563fcd9f07SJacob Faibussowitsch   } while (0)
8573f520e80SJunchao Zhang 
85830de9b25SBarry Smith /*MC
8599566063dSJacob Faibussowitsch   CHKERRCXX - Checks C++ function calls and if they throw an exception, catch it and then
8609566063dSJacob Faibussowitsch   return a PETSc error code
8619566063dSJacob Faibussowitsch 
8629566063dSJacob Faibussowitsch   Synopsis:
8639566063dSJacob Faibussowitsch   #include <petscerror.h>
8649566063dSJacob Faibussowitsch   void CHKERRCXX(func) noexcept;
8659566063dSJacob Faibussowitsch 
8669566063dSJacob Faibussowitsch   Not Collective
8679566063dSJacob Faibussowitsch 
8689566063dSJacob Faibussowitsch   Input Parameter:
8699566063dSJacob Faibussowitsch . func - C++ function calls
8709566063dSJacob Faibussowitsch 
8719566063dSJacob Faibussowitsch   Notes:
87287497f52SBarry Smith   Deprecated in favor of `PetscCallCXX()`. This routine behaves identically to it.
8739566063dSJacob Faibussowitsch 
8749566063dSJacob Faibussowitsch   Level: deprecated
8759566063dSJacob Faibussowitsch 
876db781477SPatrick Sanan .seealso: `PetscCallCXX()`
8779566063dSJacob Faibussowitsch M*/
8789566063dSJacob Faibussowitsch #define CHKERRCXX(...) PetscCallCXX(__VA_ARGS__)
8799566063dSJacob Faibussowitsch 
8809566063dSJacob Faibussowitsch /*MC
88130de9b25SBarry Smith    CHKMEMQ - Checks the memory for corruption, calls error handler if any is detected
88230de9b25SBarry Smith 
88330de9b25SBarry Smith    Synopsis:
884aaa7dc30SBarry Smith    #include <petscsys.h>
88591d3bdf4SKris Buschelman    CHKMEMQ;
88630de9b25SBarry Smith 
887eca87e8dSBarry Smith    Not Collective
888eca87e8dSBarry Smith 
88930de9b25SBarry Smith   Level: beginner
89030de9b25SBarry Smith 
89130de9b25SBarry Smith    Notes:
892a17b96a8SKyle Gerard Felker     We highly recommend using Valgrind https://petsc.org/release/faq/#valgrind or for NVIDIA CUDA systems
8935ed36255SBarry Smith     https://docs.nvidia.com/cuda/cuda-memcheck/index.html for finding memory problems. The ``CHKMEMQ`` macro is useful on systems that
8945ed36255SBarry Smith     do not have valgrind, but is not as good as valgrind or cuda-memcheck.
8951957e957SBarry Smith 
89687497f52SBarry Smith     Must run with the option -malloc_debug (-malloc_test in debug mode; or if `PetscMallocSetDebug()` called) to enable this option
89730de9b25SBarry Smith 
89830de9b25SBarry Smith     Once the error handler is called the calling function is then returned from with the given error code.
89930de9b25SBarry Smith 
90030de9b25SBarry Smith     By defaults prints location where memory that is corrupted was allocated.
90130de9b25SBarry Smith 
90287497f52SBarry Smith     Use `CHKMEMA` for functions that return void
903f621e05eSBarry Smith 
904db781477SPatrick Sanan .seealso: `PetscTraceBackErrorHandler()`, `PetscPushErrorHandler()`, `PetscError()`, `SETERRQ()`, `PetscMallocValidate()`
90530de9b25SBarry Smith M*/
9066d210af2SJacob Faibussowitsch #if defined(PETSC_CLANG_STATIC_ANALYZER)
907064a246eSJacob Faibussowitsch #define CHKMEMQ
908064a246eSJacob Faibussowitsch #define CHKMEMA
9096d210af2SJacob Faibussowitsch #else
9109371c9d4SSatish Balay #define CHKMEMQ \
9119371c9d4SSatish Balay   do { \
91286d09637SLisandro Dalcin     PetscErrorCode ierr_memq_ = PetscMallocValidate(__LINE__, PETSC_FUNCTION_NAME, __FILE__); \
91386d09637SLisandro Dalcin     if (PetscUnlikely(ierr_memq_)) return PetscError(PETSC_COMM_SELF, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr_memq_, PETSC_ERROR_REPEAT, " "); \
91486d09637SLisandro Dalcin   } while (0)
9156d210af2SJacob Faibussowitsch #define CHKMEMA PetscMallocValidate(__LINE__, PETSC_FUNCTION_NAME, __FILE__)
916064a246eSJacob Faibussowitsch #endif
9179566063dSJacob Faibussowitsch 
918668f157eSBarry Smith /*E
919668f157eSBarry Smith   PetscErrorType - passed to the PETSc error handling routines indicating if this is the first or a later call to the error handlers
920668f157eSBarry Smith 
921668f157eSBarry Smith   Level: advanced
922668f157eSBarry Smith 
92387497f52SBarry Smith   `PETSC_ERROR_IN_CXX` indicates the error was detected in C++ and an exception should be generated
924d736bfebSBarry Smith 
92595452b02SPatrick Sanan   Developer Notes:
92695452b02SPatrick Sanan     This is currently used to decide when to print the detailed information about the run in PetscTraceBackErrorHandler()
927668f157eSBarry Smith 
92887497f52SBarry Smith .seealso: `PetscError()`, `SETERRQ()`
929668f157eSBarry Smith E*/
9309371c9d4SSatish Balay typedef enum {
9319371c9d4SSatish Balay   PETSC_ERROR_INITIAL = 0,
9329371c9d4SSatish Balay   PETSC_ERROR_REPEAT  = 1,
9339371c9d4SSatish Balay   PETSC_ERROR_IN_CXX  = 2
9349371c9d4SSatish Balay } PetscErrorType;
9354b209cf6SBarry Smith 
936eb9e708aSLisandro Dalcin #if defined(__clang_analyzer__)
937eb9e708aSLisandro Dalcin __attribute__((analyzer_noreturn))
938eb9e708aSLisandro Dalcin #endif
9399371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode
9409371c9d4SSatish Balay PetscError(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, ...) PETSC_ATTRIBUTE_COLD PETSC_ATTRIBUTE_FORMAT(7, 8);
941eb9e708aSLisandro Dalcin 
942014dd563SJed Brown PETSC_EXTERN PetscErrorCode PetscErrorPrintfInitialize(void);
943014dd563SJed Brown PETSC_EXTERN PetscErrorCode PetscErrorMessage(int, const char *[], char **);
944d8e4614bSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscTraceBackErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD;
945d8e4614bSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscIgnoreErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD;
946d8e4614bSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscEmacsClientErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD;
947d8e4614bSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscMPIAbortErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD;
948d8e4614bSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscAbortErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD;
949d8e4614bSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscAttachDebuggerErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD;
950d8e4614bSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscReturnErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD;
951efca3c55SSatish Balay PETSC_EXTERN PetscErrorCode PetscPushErrorHandler(PetscErrorCode (*handler)(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *), void *);
952014dd563SJed Brown PETSC_EXTERN PetscErrorCode PetscPopErrorHandler(void);
9538d359177SBarry Smith PETSC_EXTERN PetscErrorCode PetscSignalHandlerDefault(int, void *);
954014dd563SJed Brown PETSC_EXTERN PetscErrorCode PetscPushSignalHandler(PetscErrorCode (*)(int, void *), void *);
955014dd563SJed Brown PETSC_EXTERN PetscErrorCode PetscPopSignalHandler(void);
95628559dc8SJed Brown PETSC_EXTERN PetscErrorCode PetscCheckPointerSetIntensity(PetscInt);
957c2a741eeSJunchao Zhang PETSC_EXTERN void           PetscSignalSegvCheckPointerOrMpi(void);
9589371c9d4SSatish Balay PETSC_DEPRECATED_FUNCTION("Use PetscSignalSegvCheckPointerOrMpi() (since version 3.13)") static inline void PetscSignalSegvCheckPointer(void) {
9599371c9d4SSatish Balay   PetscSignalSegvCheckPointerOrMpi();
9609371c9d4SSatish Balay }
961329f5518SBarry Smith 
962639ff905SBarry Smith /*MC
963639ff905SBarry Smith     PetscErrorPrintf - Prints error messages.
964639ff905SBarry Smith 
965639ff905SBarry Smith    Synopsis:
966aaa7dc30SBarry Smith     #include <petscsys.h>
967639ff905SBarry Smith      PetscErrorCode (*PetscErrorPrintf)(const char format[],...);
968639ff905SBarry Smith 
969639ff905SBarry Smith     Not Collective
970639ff905SBarry Smith 
971f899ff85SJose E. Roman     Input Parameter:
972639ff905SBarry Smith .   format - the usual printf() format string
973639ff905SBarry Smith 
974639ff905SBarry Smith    Options Database Keys:
9751957e957SBarry Smith +    -error_output_stdout - cause error messages to be printed to stdout instead of the (default) stderr
976e1bc860dSBarry Smith -    -error_output_none - to turn off all printing of error messages (does not change the way the error is handled.)
977639ff905SBarry Smith 
97895452b02SPatrick Sanan    Notes:
97995452b02SPatrick Sanan     Use
980639ff905SBarry Smith $     PetscErrorPrintf = PetscErrorPrintfNone; to turn off all printing of error messages (does not change the way the
981639ff905SBarry Smith $                        error is handled.) and
9821957e957SBarry Smith $     PetscErrorPrintf = PetscErrorPrintfDefault; to turn it back on or you can use your own function
983639ff905SBarry Smith 
984639ff905SBarry Smith           Use
98587497f52SBarry Smith      `PETSC_STDERR` = FILE* obtained from a file open etc. to have stderr printed to the file.
98687497f52SBarry Smith      `PETSC_STDOUT` = FILE* obtained from a file open etc. to have stdout printed to the file.
987639ff905SBarry Smith 
988639ff905SBarry Smith           Use
98987497f52SBarry Smith       `PetscPushErrorHandler()` to provide your own error handler that determines what kind of messages to print
990639ff905SBarry Smith 
991639ff905SBarry Smith    Level: developer
992639ff905SBarry Smith 
993639ff905SBarry Smith     Fortran Note:
994639ff905SBarry Smith     This routine is not supported in Fortran.
995639ff905SBarry Smith 
996db781477SPatrick Sanan .seealso: `PetscFPrintf()`, `PetscSynchronizedPrintf()`, `PetscHelpPrintf()`, `PetscPrintf()`, `PetscPushErrorHandler()`, `PetscVFPrintf()`, `PetscHelpPrintf()`
997639ff905SBarry Smith M*/
9983ca90d2dSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode (*PetscErrorPrintf)(const char[], ...) PETSC_ATTRIBUTE_FORMAT(1, 2);
999639ff905SBarry Smith 
1000cf0818bdSBarry Smith /*E
1001cf0818bdSBarry Smith      PetscFPTrap - types of floating point exceptions that may be trapped
1002cf0818bdSBarry Smith 
100387497f52SBarry Smith      Currently only `PETSC_FP_TRAP_OFF` and `PETSC_FP_TRAP_ON` are handled. All others are treated as `PETSC_FP_TRAP_ON`.
1004cf0818bdSBarry Smith 
1005cf0818bdSBarry Smith      Level: intermediate
1006cf0818bdSBarry Smith 
1007cf0818bdSBarry Smith .seealso: `PetscSetFPTrap()`, `PetscPushFPTrap()`
1008cf0818bdSBarry Smith  E*/
10099371c9d4SSatish Balay typedef enum {
10109371c9d4SSatish Balay   PETSC_FP_TRAP_OFF      = 0,
10119371c9d4SSatish Balay   PETSC_FP_TRAP_INDIV    = 1,
10129371c9d4SSatish Balay   PETSC_FP_TRAP_FLTOPERR = 2,
10139371c9d4SSatish Balay   PETSC_FP_TRAP_FLTOVF   = 4,
10149371c9d4SSatish Balay   PETSC_FP_TRAP_FLTUND   = 8,
10159371c9d4SSatish Balay   PETSC_FP_TRAP_FLTDIV   = 16,
10169371c9d4SSatish Balay   PETSC_FP_TRAP_FLTINEX  = 32
10179371c9d4SSatish Balay } PetscFPTrap;
1018bd2b07b1SBarry Smith #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)
1019014dd563SJed Brown PETSC_EXTERN PetscErrorCode PetscSetFPTrap(PetscFPTrap);
1020014dd563SJed Brown PETSC_EXTERN PetscErrorCode PetscFPTrapPush(PetscFPTrap);
1021014dd563SJed Brown PETSC_EXTERN PetscErrorCode PetscFPTrapPop(void);
1022aba4c478SBarry Smith PETSC_EXTERN PetscErrorCode PetscDetermineInitialFPTrap(void);
102354a8ef01SBarry Smith 
10243a40ed3dSBarry Smith /*
10253a40ed3dSBarry Smith       Allows the code to build a stack frame as it runs
10263a40ed3dSBarry Smith */
10273a40ed3dSBarry Smith 
102827104ee2SJacob Faibussowitsch #if defined(PETSC_USE_DEBUG)
102999cd645aSJed Brown #define PETSCSTACKSIZE 64
10303a40ed3dSBarry Smith typedef struct {
10310e33f6ddSBarry Smith   const char *function[PETSCSTACKSIZE];
10320e33f6ddSBarry Smith   const char *file[PETSCSTACKSIZE];
1033184914b5SBarry Smith   int         line[PETSCSTACKSIZE];
1034362febeeSStefano Zampini   int         petscroutine[PETSCSTACKSIZE]; /* 0 external called from petsc, 1 petsc functions, 2 petsc user functions */
1035184914b5SBarry Smith   int         currentsize;
1036a2f94806SJed Brown   int         hotdepth;
10374be741a6SBarry Smith   PetscBool   check; /* option to check for correct Push/Pop semantics, true for default petscstack but not other stacks */
10383a40ed3dSBarry Smith } PetscStack;
103927104ee2SJacob Faibussowitsch PETSC_EXTERN PetscStack petscstack;
104027104ee2SJacob Faibussowitsch #else
104127104ee2SJacob Faibussowitsch typedef struct {
104227104ee2SJacob Faibussowitsch   char Silence_empty_struct_has_size_0_in_C_size_1_in_Cpp;
104327104ee2SJacob Faibussowitsch } PetscStack;
104427104ee2SJacob Faibussowitsch #endif
10453a40ed3dSBarry Smith 
10465d12eec7SSatish Balay #if defined(PETSC_SERIALIZE_FUNCTIONS)
10475d12eec7SSatish Balay #include <petsc/private/petscfptimpl.h>
10485d12eec7SSatish Balay /*
10495d12eec7SSatish Balay    Registers the current function into the global function pointer to function name table
10505d12eec7SSatish Balay 
10515d12eec7SSatish Balay    Have to fix this to handle errors but cannot return error since used in PETSC_VIEWER_DRAW_() etc
10525d12eec7SSatish Balay */
10539371c9d4SSatish Balay #define PetscRegister__FUNCT__() \
10549371c9d4SSatish Balay   do { \
10555d12eec7SSatish Balay     static PetscBool __chked = PETSC_FALSE; \
10565d12eec7SSatish Balay     if (!__chked) { \
10579371c9d4SSatish Balay       void *ptr; \
10589371c9d4SSatish Balay       PetscDLSym(NULL, PETSC_FUNCTION_NAME, &ptr); \
10595d12eec7SSatish Balay       __chked = PETSC_TRUE; \
10609371c9d4SSatish Balay     } \
10619371c9d4SSatish Balay   } while (0)
10625d12eec7SSatish Balay #else
10635d12eec7SSatish Balay #define PetscRegister__FUNCT__()
10645d12eec7SSatish Balay #endif
10655d12eec7SSatish Balay 
10666d210af2SJacob Faibussowitsch #if defined(PETSC_CLANG_STATIC_ANALYZER)
10676d210af2SJacob Faibussowitsch #define PetscStackPushNoCheck(funct, petsc_routine, hot)
106837154d10SBarry Smith #define PetscStackUpdateLine
1069792fecdfSBarry Smith #define PetscStackPushExternal(funct)
10706d210af2SJacob Faibussowitsch #define PetscStackPopNoCheck
10716d210af2SJacob Faibussowitsch #define PetscStackClearTop
10726d210af2SJacob Faibussowitsch #define PetscFunctionBegin
10736d210af2SJacob Faibussowitsch #define PetscFunctionBeginUser
10746d210af2SJacob Faibussowitsch #define PetscFunctionBeginHot
10756d210af2SJacob Faibussowitsch #define PetscFunctionReturn(a)    return a
10766d210af2SJacob Faibussowitsch #define PetscFunctionReturnVoid() return
10776d210af2SJacob Faibussowitsch #define PetscStackPop
10786d210af2SJacob Faibussowitsch #define PetscStackPush(f)
10796d210af2SJacob Faibussowitsch #elif defined(PETSC_USE_DEBUG)
1080660278c0SBarry Smith 
10819371c9d4SSatish Balay #define PetscStackPush_Private(stack__, file__, func__, line__, petsc_routine__, hot__) \
10829371c9d4SSatish Balay   do { \
10835a96b57dSJacob Faibussowitsch     if (stack__.currentsize < PETSCSTACKSIZE) { \
10845a96b57dSJacob Faibussowitsch       stack__.function[stack__.currentsize] = func__; \
1085ef1023bdSBarry Smith       if (petsc_routine__) { \
1086ef1023bdSBarry Smith         stack__.file[stack__.currentsize] = file__; \
10875a96b57dSJacob Faibussowitsch         stack__.line[stack__.currentsize] = line__; \
1088ef1023bdSBarry Smith       } else { \
1089648bc8c4SBarry Smith         stack__.file[stack__.currentsize] = PETSC_NULLPTR; \
1090ef1023bdSBarry Smith         stack__.line[stack__.currentsize] = 0; \
1091ef1023bdSBarry Smith       } \
10925a96b57dSJacob Faibussowitsch       stack__.petscroutine[stack__.currentsize] = petsc_routine__; \
10935a96b57dSJacob Faibussowitsch     } \
10945a96b57dSJacob Faibussowitsch     ++stack__.currentsize; \
10955a96b57dSJacob Faibussowitsch     stack__.hotdepth += (hot__ || stack__.hotdepth); \
10965a96b57dSJacob Faibussowitsch   } while (0)
10975a96b57dSJacob Faibussowitsch 
10984be741a6SBarry Smith /* uses PetscCheckAbort() because may be used in a function that does not return an error code */
10999371c9d4SSatish Balay #define PetscStackPop_Private(stack__, func__) \
11009371c9d4SSatish Balay   do { \
11014be741a6SBarry Smith     PetscCheckAbort(!stack__.check || stack__.currentsize > 0, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Invalid stack size %d, pop %s %s:%d.\n", stack__.currentsize, func__, __FILE__, __LINE__); \
11025a96b57dSJacob Faibussowitsch     if (--stack__.currentsize < PETSCSTACKSIZE) { \
11039371c9d4SSatish Balay       PetscCheckAbort(!stack__.check || stack__.petscroutine[stack__.currentsize] != 1 || stack__.function[stack__.currentsize] == (const char *)(func__), PETSC_COMM_SELF, PETSC_ERR_PLIB, "Invalid stack: push from %s %s:%d. Pop from %s %s:%d.\n", \
11049371c9d4SSatish Balay                       stack__.function[stack__.currentsize], stack__.file[stack__.currentsize], stack__.line[stack__.currentsize], func__, __FILE__, __LINE__); \
11055a96b57dSJacob Faibussowitsch       stack__.function[stack__.currentsize]     = PETSC_NULLPTR; \
11065a96b57dSJacob Faibussowitsch       stack__.file[stack__.currentsize]         = PETSC_NULLPTR; \
11075a96b57dSJacob Faibussowitsch       stack__.line[stack__.currentsize]         = 0; \
11085a96b57dSJacob Faibussowitsch       stack__.petscroutine[stack__.currentsize] = 0; \
11095a96b57dSJacob Faibussowitsch     } \
11105a96b57dSJacob Faibussowitsch     stack__.hotdepth = PetscMax(stack__.hotdepth - 1, 0); \
11115a96b57dSJacob Faibussowitsch   } while (0)
11125a96b57dSJacob Faibussowitsch 
1113586f9135SBarry Smith /*MC
1114586f9135SBarry Smith    PetscStackPushNoCheck - Pushes a new function name and line number onto the PETSc default stack that tracks where the running program is
1115586f9135SBarry Smith    currently in the source code.
1116586f9135SBarry Smith 
1117586f9135SBarry Smith    Not Collective
1118586f9135SBarry Smith 
1119586f9135SBarry Smith    Synopsis:
1120586f9135SBarry Smith    #include <petscsys.h>
1121586f9135SBarry Smith    void PetscStackPushNoCheck(char *funct,int petsc_routine,PetscBool hot);
1122586f9135SBarry Smith 
1123586f9135SBarry Smith    Input Parameters:
1124586f9135SBarry Smith +  funct - the function name
1125586f9135SBarry Smith .  petsc_routine - 2 user function, 1 PETSc function, 0 some other function
1126586f9135SBarry Smith -  hot - indicates that the function may be called often so expensive error checking should be turned off inside the function
1127586f9135SBarry Smith 
1128586f9135SBarry Smith    Level: developer
1129586f9135SBarry Smith 
1130586f9135SBarry Smith    Notes:
1131586f9135SBarry Smith    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
113287497f52SBarry Smith    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
1133586f9135SBarry Smith    help debug the problem.
1134586f9135SBarry Smith 
1135ef1023bdSBarry Smith    This version does not check the memory corruption (an expensive operation), use `PetscStackPush()` to check the memory.
1136ef1023bdSBarry Smith 
1137792fecdfSBarry Smith    Use `PetscStackPushExternal()` for a function call that is about to be made to a non-PETSc or user function (such as BLAS etc).
1138ef1023bdSBarry Smith 
1139586f9135SBarry Smith    The default stack is a global variable called `petscstack`.
1140586f9135SBarry Smith 
1141586f9135SBarry Smith .seealso: `PetscAttachDebugger()`, `PetscStackCopy()`, `PetscStackView()`, `PetscStackPopNoCheck()`, `PetscCall()`, `PetscFunctionBegin()`,
1142ef1023bdSBarry Smith           `PetscFunctionReturn()`, `PetscFunctionBeginHot()`, `PetscFunctionBeginUser()`, `PetscStackPush()`, `PetscStackPop`,
1143792fecdfSBarry Smith           `PetscStackPushExternal()`
1144586f9135SBarry Smith M*/
11459371c9d4SSatish Balay #define PetscStackPushNoCheck(funct, petsc_routine, hot) \
11469371c9d4SSatish Balay   do { \
1147e04113cfSBarry Smith     PetscStackSAWsTakeAccess(); \
11485a96b57dSJacob Faibussowitsch     PetscStackPush_Private(petscstack, __FILE__, funct, __LINE__, petsc_routine, hot); \
1149e04113cfSBarry Smith     PetscStackSAWsGrantAccess(); \
1150441dd030SJed Brown   } while (0)
1151441dd030SJed Brown 
1152586f9135SBarry Smith /*MC
115387497f52SBarry Smith    PetscStackUpdateLine - in a function that has a `PetscFunctionBegin` or `PetscFunctionBeginUser` updates the stack line number to the
115437154d10SBarry Smith    current line number.
115537154d10SBarry Smith 
115637154d10SBarry Smith    Not Collective
115737154d10SBarry Smith 
115837154d10SBarry Smith    Synopsis:
115937154d10SBarry Smith    #include <petscsys.h>
116037154d10SBarry Smith    void PetscStackUpdateLine
116137154d10SBarry Smith 
116237154d10SBarry Smith    Level: developer
116337154d10SBarry Smith 
116437154d10SBarry Smith    Notes:
116587497f52SBarry Smith    Using `PetscCall()` and friends automatically handles this process
116687497f52SBarry Smith 
116737154d10SBarry Smith    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
116837154d10SBarry Smith    occurred, for example, when a signal is received. It is recommended to use the debugger if extensive information is needed to
116937154d10SBarry Smith    help debug the problem.
117037154d10SBarry Smith 
117137154d10SBarry Smith    The default stack is a global variable called petscstack.
117237154d10SBarry Smith 
117337154d10SBarry Smith    This is used by `PetscCall()` and is otherwise not like to be needed
117437154d10SBarry Smith 
117537154d10SBarry Smith .seealso: `PetscAttachDebugger()`, `PetscStackCopy()`, `PetscStackView()`, `PetscStackPushNoCheck()`, `PetscStackPop`, `PetscCall()`
117637154d10SBarry Smith M*/
117737154d10SBarry Smith #define PetscStackUpdateLine \
11789371c9d4SSatish Balay   if (petscstack.currentsize > 0 && petscstack.function[petscstack.currentsize - 1] == PETSC_FUNCTION_NAME) { petscstack.line[petscstack.currentsize - 1] = __LINE__; }
117937154d10SBarry Smith 
118037154d10SBarry Smith /*MC
1181792fecdfSBarry Smith    PetscStackPushExternal - Pushes a new function name onto the PETSc default stack that tracks where the running program is
1182ef1023bdSBarry Smith    currently in the source code. Does not include the filename or line number since this is called by the calling routine
1183ef1023bdSBarry Smith    for non-PETSc or user functions.
1184ef1023bdSBarry Smith 
1185ef1023bdSBarry Smith    Not Collective
1186ef1023bdSBarry Smith 
1187ef1023bdSBarry Smith    Synopsis:
1188ef1023bdSBarry Smith    #include <petscsys.h>
1189792fecdfSBarry Smith    void PetscStackPushExternal(char *funct);
1190ef1023bdSBarry Smith 
1191ef1023bdSBarry Smith    Input Parameters:
1192ef1023bdSBarry Smith .  funct - the function name
1193ef1023bdSBarry Smith 
1194ef1023bdSBarry Smith    Level: developer
1195ef1023bdSBarry Smith 
1196ef1023bdSBarry Smith    Notes:
119787497f52SBarry Smith    Using `PetscCallExternal()` and friends automatically handles this process
119887497f52SBarry Smith 
1199ef1023bdSBarry Smith    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
1200ef1023bdSBarry Smith    occurred, for example, when a signal is received. It is recommended to use the debugger if extensive information is needed to
1201ef1023bdSBarry Smith    help debug the problem.
1202ef1023bdSBarry Smith 
1203ef1023bdSBarry Smith    The default stack is a global variable called `petscstack`.
1204ef1023bdSBarry Smith 
1205ef1023bdSBarry Smith    This is to be used when calling an external package function such as a BLAS function.
1206ef1023bdSBarry Smith 
1207ef1023bdSBarry Smith    This also updates the stack line number for the current stack function.
1208ef1023bdSBarry Smith 
1209ef1023bdSBarry Smith .seealso: `PetscAttachDebugger()`, `PetscStackCopy()`, `PetscStackView()`, `PetscStackPopNoCheck()`, `PetscCall()`, `PetscFunctionBegin()`,
1210ef1023bdSBarry Smith           `PetscFunctionReturn()`, `PetscFunctionBeginHot()`, `PetscFunctionBeginUser()`, `PetscStackPushNoCheck()`, `PetscStackPop`
1211ef1023bdSBarry Smith M*/
12129371c9d4SSatish Balay #define PetscStackPushExternal(funct) \
12139371c9d4SSatish Balay   do { \
12149371c9d4SSatish Balay     PetscStackUpdateLine; \
12159371c9d4SSatish Balay     PetscStackPushNoCheck(funct, 0, PETSC_TRUE); \
12169371c9d4SSatish Balay   } while (0);
1217ef1023bdSBarry Smith 
1218ef1023bdSBarry Smith /*MC
1219586f9135SBarry Smith    PetscStackPopNoCheck - Pops a function name from the PETSc default stack that tracks where the running program is
1220586f9135SBarry Smith    currently in the source code.
1221586f9135SBarry Smith 
1222586f9135SBarry Smith    Not Collective
1223586f9135SBarry Smith 
1224586f9135SBarry Smith    Synopsis:
1225586f9135SBarry Smith    #include <petscsys.h>
1226586f9135SBarry Smith    void PetscStackPopNoCheck(char *funct);
1227586f9135SBarry Smith 
1228586f9135SBarry Smith    Input Parameter:
1229586f9135SBarry Smith .   funct - the function name
1230586f9135SBarry Smith 
1231586f9135SBarry Smith    Level: developer
1232586f9135SBarry Smith 
1233586f9135SBarry Smith    Notes:
123487497f52SBarry Smith    Using `PetscCall()`, `PetscCallExternal()`, `PetscCallBack()` and friends negates the need to call this
123587497f52SBarry Smith 
1236586f9135SBarry Smith    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
1237586f9135SBarry Smith    occurred, for example, when a signal is received. It is recommended to use the debugger if extensive information is needed to
1238586f9135SBarry Smith    help debug the problem.
1239586f9135SBarry Smith 
1240586f9135SBarry Smith    The default stack is a global variable called petscstack.
1241586f9135SBarry Smith 
1242586f9135SBarry Smith    Developer Note:
1243586f9135SBarry Smith    `PetscStackPopNoCheck()` takes a function argument while  `PetscStackPop` does not, this difference is likely just historical.
1244586f9135SBarry Smith 
1245586f9135SBarry Smith .seealso: `PetscAttachDebugger()`, `PetscStackCopy()`, `PetscStackView()`, `PetscStackPushNoCheck()`, `PetscStackPop`
1246586f9135SBarry Smith M*/
12479371c9d4SSatish Balay #define PetscStackPopNoCheck(funct) \
12489371c9d4SSatish Balay   do { \
1249362febeeSStefano Zampini     PetscStackSAWsTakeAccess(); \
12505a96b57dSJacob Faibussowitsch     PetscStackPop_Private(petscstack, funct); \
1251362febeeSStefano Zampini     PetscStackSAWsGrantAccess(); \
1252362febeeSStefano Zampini   } while (0)
1253362febeeSStefano Zampini 
12549371c9d4SSatish Balay #define PetscStackClearTop \
12559371c9d4SSatish Balay   do { \
1256e04113cfSBarry Smith     PetscStackSAWsTakeAccess(); \
12579371c9d4SSatish Balay     if (petscstack.currentsize > 0 && --petscstack.currentsize < PETSCSTACKSIZE) { \
125827104ee2SJacob Faibussowitsch       petscstack.function[petscstack.currentsize]     = PETSC_NULLPTR; \
125927104ee2SJacob Faibussowitsch       petscstack.file[petscstack.currentsize]         = PETSC_NULLPTR; \
126027104ee2SJacob Faibussowitsch       petscstack.line[petscstack.currentsize]         = 0; \
126127104ee2SJacob Faibussowitsch       petscstack.petscroutine[petscstack.currentsize] = 0; \
1262441dd030SJed Brown     } \
126327104ee2SJacob Faibussowitsch     petscstack.hotdepth = PetscMax(petscstack.hotdepth - 1, 0); \
1264e04113cfSBarry Smith     PetscStackSAWsGrantAccess(); \
1265441dd030SJed Brown   } while (0)
1266441dd030SJed Brown 
126730de9b25SBarry Smith /*MC
12681957e957SBarry Smith    PetscFunctionBegin - First executable line of each PETSc function,  used for error handling. Final
126987497f52SBarry Smith       line of PETSc functions should be `PetscFunctionReturn`(0);
127030de9b25SBarry Smith 
127130de9b25SBarry Smith    Synopsis:
1272aaa7dc30SBarry Smith    #include <petscsys.h>
127330de9b25SBarry Smith    void PetscFunctionBegin;
127430de9b25SBarry Smith 
1275eca87e8dSBarry Smith    Not Collective
1276eca87e8dSBarry Smith 
127730de9b25SBarry Smith    Usage:
127830de9b25SBarry Smith .vb
127930de9b25SBarry Smith      int something;
128030de9b25SBarry Smith 
128130de9b25SBarry Smith      PetscFunctionBegin;
128230de9b25SBarry Smith .ve
128330de9b25SBarry Smith 
128430de9b25SBarry Smith    Notes:
128587497f52SBarry Smith      Use `PetscFunctionBeginUser` for application codes.
12861957e957SBarry Smith 
128730de9b25SBarry Smith      Not available in Fortran
128830de9b25SBarry Smith 
128930de9b25SBarry Smith    Level: developer
129030de9b25SBarry Smith 
1291586f9135SBarry Smith .seealso: `PetscFunctionReturn()`, `PetscFunctionBeginHot()`, `PetscFunctionBeginUser()`, `PetscStackPushNoCheck()`
129230de9b25SBarry Smith 
129330de9b25SBarry Smith M*/
12949371c9d4SSatish Balay #define PetscFunctionBegin \
12959371c9d4SSatish Balay   do { \
1296362febeeSStefano Zampini     PetscStackPushNoCheck(PETSC_FUNCTION_NAME, 1, PETSC_FALSE); \
1297a2f94806SJed Brown     PetscRegister__FUNCT__(); \
1298a2f94806SJed Brown   } while (0)
1299a2f94806SJed Brown 
1300a2f94806SJed Brown /*MC
130187497f52SBarry Smith    PetscFunctionBeginHot - Substitute for `PetscFunctionBegin` to be used in functions that are called in
1302a2f94806SJed Brown    performance-critical circumstances.  Use of this function allows for lighter profiling by default.
1303a2f94806SJed Brown 
1304a2f94806SJed Brown    Synopsis:
1305aaa7dc30SBarry Smith    #include <petscsys.h>
1306a2f94806SJed Brown    void PetscFunctionBeginHot;
1307a2f94806SJed Brown 
1308a2f94806SJed Brown    Not Collective
1309a2f94806SJed Brown 
1310a2f94806SJed Brown    Usage:
1311a2f94806SJed Brown .vb
1312a2f94806SJed Brown      int something;
1313a2f94806SJed Brown 
1314a2f94806SJed Brown      PetscFunctionBeginHot;
1315a2f94806SJed Brown .ve
1316a2f94806SJed Brown 
1317a2f94806SJed Brown    Notes:
1318a2f94806SJed Brown      Not available in Fortran
1319a2f94806SJed Brown 
1320a2f94806SJed Brown    Level: developer
1321a2f94806SJed Brown 
1322586f9135SBarry Smith .seealso: `PetscFunctionBegin`, `PetscFunctionReturn()`, `PetscStackPushNoCheck()`
1323a2f94806SJed Brown 
1324a2f94806SJed Brown M*/
13259371c9d4SSatish Balay #define PetscFunctionBeginHot \
13269371c9d4SSatish Balay   do { \
1327362febeeSStefano Zampini     PetscStackPushNoCheck(PETSC_FUNCTION_NAME, 1, PETSC_TRUE); \
13282d53ad75SBarry Smith     PetscRegister__FUNCT__(); \
132953c77d0aSJed Brown   } while (0)
133053c77d0aSJed Brown 
1331a8d2bbe5SBarry Smith /*MC
1332530d85c1SBarry Smith    PetscFunctionBeginUser - First executable line of user provided routines
1333a8d2bbe5SBarry Smith 
1334a8d2bbe5SBarry Smith    Synopsis:
1335aaa7dc30SBarry Smith    #include <petscsys.h>
1336a8d2bbe5SBarry Smith    void PetscFunctionBeginUser;
1337a8d2bbe5SBarry Smith 
1338a8d2bbe5SBarry Smith    Not Collective
1339a8d2bbe5SBarry Smith 
1340a8d2bbe5SBarry Smith    Usage:
1341a8d2bbe5SBarry Smith .vb
1342a8d2bbe5SBarry Smith      int something;
1343a8d2bbe5SBarry Smith 
1344ac285190SBarry Smith      PetscFunctionBeginUser;
1345a8d2bbe5SBarry Smith .ve
1346a8d2bbe5SBarry Smith 
1347a8d2bbe5SBarry Smith    Notes:
1348530d85c1SBarry Smith       Functions that incorporate this must call `PetscFunctionReturn()` instead of return except for main().
1349530d85c1SBarry Smith 
1350530d85c1SBarry Smith       May be used before `PetscInitialize()`
13511957e957SBarry Smith 
1352a8d2bbe5SBarry Smith       Not available in Fortran
1353a8d2bbe5SBarry Smith 
1354530d85c1SBarry Smith       This is identical to `PetscFunctionBegin` except it labels the routine as a user
1355ac285190SBarry Smith       routine instead of as a PETSc library routine.
1356ac285190SBarry Smith 
1357a2f94806SJed Brown    Level: intermediate
1358a8d2bbe5SBarry Smith 
1359586f9135SBarry Smith .seealso: `PetscFunctionReturn()`, `PetscFunctionBegin`, `PetscFunctionBeginHot`, `PetscStackPushNoCheck()`
1360a8d2bbe5SBarry Smith 
1361a8d2bbe5SBarry Smith M*/
13629371c9d4SSatish Balay #define PetscFunctionBeginUser \
13639371c9d4SSatish Balay   do { \
1364362febeeSStefano Zampini     PetscStackPushNoCheck(PETSC_FUNCTION_NAME, 2, PETSC_FALSE); \
1365a8d2bbe5SBarry Smith     PetscRegister__FUNCT__(); \
1366a8d2bbe5SBarry Smith   } while (0)
1367a8d2bbe5SBarry Smith 
1368586f9135SBarry Smith /*MC
1369586f9135SBarry Smith    PetscStackPush - Pushes a new function name and line number onto the PETSc default stack that tracks where the running program is
1370586f9135SBarry Smith    currently in the source code and verifies the memory is not corrupted.
1371586f9135SBarry Smith 
1372586f9135SBarry Smith    Not Collective
1373586f9135SBarry Smith 
1374586f9135SBarry Smith    Synopsis:
1375586f9135SBarry Smith    #include <petscsys.h>
1376586f9135SBarry Smith    void PetscStackPush(char *funct)
1377586f9135SBarry Smith 
1378586f9135SBarry Smith    Input Parameter:
1379586f9135SBarry Smith .  funct - the function name
1380586f9135SBarry Smith 
1381586f9135SBarry Smith    Level: developer
1382586f9135SBarry Smith 
1383586f9135SBarry Smith    Notes:
1384586f9135SBarry Smith    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
1385586f9135SBarry Smith    occurred, for example, when a signal is received. It is recommended to use the debugger if extensive information is needed to
1386586f9135SBarry Smith    help debug the problem.
1387586f9135SBarry Smith 
1388586f9135SBarry Smith    The default stack is a global variable called petscstack.
1389586f9135SBarry Smith 
1390586f9135SBarry Smith .seealso: `PetscAttachDebugger()`, `PetscStackCopy()`, `PetscStackView()`, `PetscStackPopNoCheck()`, `PetscCall()`, `PetscFunctionBegin()`,
1391586f9135SBarry Smith           `PetscFunctionReturn()`, `PetscFunctionBeginHot()`, `PetscFunctionBeginUser()`, `PetscStackPushNoCheck()`, `PetscStackPop`
1392586f9135SBarry Smith M*/
13939371c9d4SSatish Balay #define PetscStackPush(n) \
13949371c9d4SSatish Balay   do { \
1395362febeeSStefano Zampini     PetscStackPushNoCheck(n, 0, PETSC_FALSE); \
139615681b3cSBarry Smith     CHKMEMQ; \
139715681b3cSBarry Smith   } while (0)
13983a40ed3dSBarry Smith 
1399586f9135SBarry Smith /*MC
1400586f9135SBarry Smith    PetscStackPop - Pops a function name from the PETSc default stack that tracks where the running program is
1401586f9135SBarry Smith    currently in the source code and verifies the memory is not corrupted.
1402586f9135SBarry Smith 
1403586f9135SBarry Smith    Not Collective
1404586f9135SBarry Smith 
1405586f9135SBarry Smith    Synopsis:
1406586f9135SBarry Smith    #include <petscsys.h>
1407586f9135SBarry Smith    void PetscStackPop
1408586f9135SBarry Smith 
1409586f9135SBarry Smith    Level: developer
1410586f9135SBarry Smith 
1411586f9135SBarry Smith    Notes:
1412586f9135SBarry Smith    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
1413586f9135SBarry Smith    occurred, for example, when a signal is received. It is recommended to use the debugger if extensive information is needed to
1414586f9135SBarry Smith    help debug the problem.
1415586f9135SBarry Smith 
1416586f9135SBarry Smith    The default stack is a global variable called petscstack.
1417586f9135SBarry Smith 
1418586f9135SBarry Smith .seealso: `PetscAttachDebugger()`, `PetscStackCopy()`, `PetscStackView()`, `PetscStackPushNoCheck()`, `PetscStackPopNoCheck()`, `PetscStackPush()`
1419586f9135SBarry Smith M*/
14209371c9d4SSatish Balay #define PetscStackPop \
14219371c9d4SSatish Balay   do { \
1422441dd030SJed Brown     CHKMEMQ; \
1423362febeeSStefano Zampini     PetscStackPopNoCheck(PETSC_FUNCTION_NAME); \
142415681b3cSBarry Smith   } while (0)
1425d64ed03dSBarry Smith 
142630de9b25SBarry Smith /*MC
142730de9b25SBarry Smith    PetscFunctionReturn - Last executable line of each PETSc function
142887497f52SBarry Smith         used for error handling. Replaces `return()`
142930de9b25SBarry Smith 
143030de9b25SBarry Smith    Synopsis:
1431aaa7dc30SBarry Smith    #include <petscsys.h>
143230de9b25SBarry Smith    void PetscFunctionReturn(0);
143330de9b25SBarry Smith 
1434eca87e8dSBarry Smith    Not Collective
1435eca87e8dSBarry Smith 
143630de9b25SBarry Smith    Usage:
143730de9b25SBarry Smith .vb
143830de9b25SBarry Smith     ....
143930de9b25SBarry Smith      PetscFunctionReturn(0);
144030de9b25SBarry Smith    }
144130de9b25SBarry Smith .ve
144230de9b25SBarry Smith 
144387497f52SBarry Smith    Note:
144430de9b25SBarry Smith      Not available in Fortran
144530de9b25SBarry Smith 
144630de9b25SBarry Smith    Level: developer
144730de9b25SBarry Smith 
1448586f9135SBarry Smith .seealso: `PetscFunctionBegin()`, `PetscStackPopNoCheck()`
144930de9b25SBarry Smith 
145030de9b25SBarry Smith M*/
14519371c9d4SSatish Balay #define PetscFunctionReturn(a) \
14529371c9d4SSatish Balay   do { \
1453362febeeSStefano Zampini     PetscStackPopNoCheck(PETSC_FUNCTION_NAME); \
145427104ee2SJacob Faibussowitsch     return a; \
145527104ee2SJacob Faibussowitsch   } while (0)
1456d64ed03dSBarry Smith 
14579371c9d4SSatish Balay #define PetscFunctionReturnVoid() \
14589371c9d4SSatish Balay   do { \
1459362febeeSStefano Zampini     PetscStackPopNoCheck(PETSC_FUNCTION_NAME); \
146027104ee2SJacob Faibussowitsch     return; \
146127104ee2SJacob Faibussowitsch   } while (0)
146227104ee2SJacob Faibussowitsch #else /* PETSC_USE_DEBUG */
146327104ee2SJacob Faibussowitsch #define PetscStackPushNoCheck(funct, petsc_routine, hot)
146437154d10SBarry Smith #define PetscStackUpdateLine
1465792fecdfSBarry Smith #define PetscStackPushExternal(funct)
146627104ee2SJacob Faibussowitsch #define PetscStackPopNoCheck
146727104ee2SJacob Faibussowitsch #define PetscStackClearTop
14683a40ed3dSBarry Smith #define PetscFunctionBegin
14690bdf7c52SPeter Brune #define PetscFunctionBeginUser
1470a2f94806SJed Brown #define PetscFunctionBeginHot
147127104ee2SJacob Faibussowitsch #define PetscFunctionReturn(a)    return a
14725665465eSBarry Smith #define PetscFunctionReturnVoid() return
1473812af9f3SBarry Smith #define PetscStackPop             CHKMEMQ
1474812af9f3SBarry Smith #define PetscStackPush(f)         CHKMEMQ
147527104ee2SJacob Faibussowitsch #endif /* PETSC_USE_DEBUG */
14763a40ed3dSBarry Smith 
14776d210af2SJacob Faibussowitsch #if defined(PETSC_CLANG_STATIC_ANALYZER)
1478e77caa6dSBarry Smith #define PetscStackCallExternalVoid(name, routine)
1479792fecdfSBarry Smith #define PetscCallExternal(func, ...)
14806d210af2SJacob Faibussowitsch #else
1481586f9135SBarry Smith /*MC
1482e77caa6dSBarry Smith     PetscStackCallExternalVoid - Calls an external library routine or user function after pushing the name of the routine on the stack.
1483eb6b5d47SBarry Smith 
1484eb6b5d47SBarry Smith    Input Parameters:
1485eb6b5d47SBarry Smith +   name - string that gives the name of the function being called
1486586f9135SBarry Smith -   routine - actual call to the routine, for example, functionname(a,b)
1487fd3f9acdSBarry Smith 
1488586f9135SBarry Smith    Level: developer
1489eb6b5d47SBarry Smith 
1490586f9135SBarry Smith    Note:
1491792fecdfSBarry Smith    Often one should use `PetscCallExternal()` instead. This routine is intended for external library routines that DO NOT return error codes
1492eb6b5d47SBarry Smith 
1493586f9135SBarry Smith    In debug mode this also checks the memory for corruption at the end of the function call.
1494586f9135SBarry Smith 
1495586f9135SBarry Smith    Certain external packages, such as BLAS/LAPACK may have their own macros for managing the call, error checking, etc.
1496586f9135SBarry Smith 
1497586f9135SBarry Smith    Developer Note:
1498586f9135SBarry Smith    This is so that when a user or external library routine results in a crash or corrupts memory, they get blamed instead of PETSc.
1499586f9135SBarry Smith 
1500792fecdfSBarry Smith .seealso: `PetscCall()`, `PetscStackPushNoCheck()`, `PetscStackPush()`, `PetscCallExternal()`, `PetscCallBLAS()`
1501586f9135SBarry Smith @*/
15029371c9d4SSatish Balay #define PetscStackCallExternalVoid(name, routine) \
15039371c9d4SSatish Balay   do { \
15049371c9d4SSatish Balay     PetscStackPush(name); \
15059371c9d4SSatish Balay     routine; \
15069371c9d4SSatish Balay     PetscStackPop; \
15079371c9d4SSatish Balay   } while (0)
1508eb6b5d47SBarry Smith 
1509586f9135SBarry Smith /*MC
1510792fecdfSBarry Smith     PetscCallExternal - Calls an external library routine that returns an error code after pushing the name of the routine on the stack.
1511fd3f9acdSBarry Smith 
1512fd3f9acdSBarry Smith    Input Parameters:
1513fd3f9acdSBarry Smith +   func-  name of the routine
1514586f9135SBarry Smith -   args - arguments to the routine
1515586f9135SBarry Smith 
1516586f9135SBarry Smith    Level: developer
1517fd3f9acdSBarry Smith 
151895452b02SPatrick Sanan    Notes:
1519e77caa6dSBarry Smith    This is intended for external package routines that return error codes. Use `PetscStackCallExternalVoid()` for those that do not.
1520dbf62e16SBarry Smith 
1521586f9135SBarry Smith    In debug mode this also checks the memory for corruption at the end of the function call.
1522fd3f9acdSBarry Smith 
152387497f52SBarry Smith    Assumes the error return code of the function is an integer and that a value of 0 indicates success
152487497f52SBarry Smith 
1525586f9135SBarry Smith    Developer Note:
1526586f9135SBarry Smith    This is so that when an external packge routine results in a crash or corrupts memory, they get blamed instead of PETSc.
1527586f9135SBarry Smith 
1528e77caa6dSBarry Smith .seealso: `PetscCall()`, `PetscStackPushNoCheck()`, `PetscStackPush()`, `PetscStackCallExternalVoid()`
1529586f9135SBarry Smith M*/
15309371c9d4SSatish Balay #define PetscCallExternal(func, ...) \
15319371c9d4SSatish Balay   do { \
1532a74df02fSJacob Faibussowitsch     PetscStackPush(PetscStringize(func)); \
1533a74df02fSJacob Faibussowitsch     PetscErrorCode __ierr = func(__VA_ARGS__); \
15341d4906efSStefano Zampini     PetscStackPop; \
153532771afcSJacob Faibussowitsch     PetscCheck(!__ierr, PETSC_COMM_SELF, PETSC_ERR_LIB, "Error in %s(): error code %d", PetscStringize(func), __ierr); \
1536fd3f9acdSBarry Smith   } while (0)
15376d210af2SJacob Faibussowitsch #endif /* PETSC_CLANG_STATIC_ANALYZER */
153806d1fe2cSBarry Smith 
153906d1fe2cSBarry Smith #endif
1540