xref: /petsc/include/petscerror.h (revision 5a96b57da4c592d70d012b82db298d787735420a)
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 
1054a8ef01SBarry Smith /*
11329ffe3dSLois Curfman McInnes      These are the generic error codes. These error codes are used
12e2d1d2b7SBarry Smith      many different places in the PETSc source code. The string versions are
130e5e90baSSatish Balay      at src/sys/error/err.c any changes here must also be made there
14e951c290SBarry Smith      These are also define in src/sys/f90-mod/petscerror.h any CHANGES here
150f9cf654SBarry Smith      must be also made there.
1645d48df9SBarry Smith 
1754a8ef01SBarry Smith */
182a6744ebSBarry Smith #define PETSC_ERR_MIN_VALUE        54   /* should always be one less then the smallest value */
192a6744ebSBarry Smith 
2045d48df9SBarry Smith #define PETSC_ERR_MEM              55   /* unable to allocate requested memory */
2147794344SBarry Smith #define PETSC_ERR_SUP              56   /* no support for requested operation */
22e2d1d2b7SBarry Smith #define PETSC_ERR_SUP_SYS          57   /* no support for requested operation on this computer system */
23e2d1d2b7SBarry Smith #define PETSC_ERR_ORDER            58   /* operation done in wrong order */
2445d48df9SBarry Smith #define PETSC_ERR_SIG              59   /* signal received */
25f1caa5a4SBarry Smith #define PETSC_ERR_FP               72   /* floating point exception */
26a8c6a408SBarry Smith #define PETSC_ERR_COR              74   /* corrupted PETSc object */
27a8c6a408SBarry Smith #define PETSC_ERR_LIB              76   /* error in library called by PETSc */
28329ffe3dSLois Curfman McInnes #define PETSC_ERR_PLIB             77   /* PETSc library generated inconsistent data */
29329ffe3dSLois Curfman McInnes #define PETSC_ERR_MEMC             78   /* memory corruption */
30b3cc6726SBarry Smith #define PETSC_ERR_CONV_FAILED      82   /* iterative method (KSP or SNES) failed */
311302d50aSBarry Smith #define PETSC_ERR_USER             83   /* user has not provided needed function */
324e2ffeddSBarry Smith #define PETSC_ERR_SYS              88   /* error in system call */
33a8b45ee7SBarry Smith #define PETSC_ERR_POINTER          70   /* pointer does not point to valid address */
343d96e996SBarry Smith #define PETSC_ERR_MPI_LIB_INCOMP   87   /* MPI library at runtime is not compatible with MPI user compiled with */
3545d48df9SBarry Smith 
3645d48df9SBarry Smith #define PETSC_ERR_ARG_SIZ          60   /* nonconforming object sizes used in operation */
3745d48df9SBarry Smith #define PETSC_ERR_ARG_IDN          61   /* two arguments not allowed to be the same */
38a8c6a408SBarry Smith #define PETSC_ERR_ARG_WRONG        62   /* wrong argument (but object probably ok) */
3945d48df9SBarry Smith #define PETSC_ERR_ARG_CORRUPT      64   /* null or corrupted PETSc object as argument */
4045d48df9SBarry Smith #define PETSC_ERR_ARG_OUTOFRANGE   63   /* input argument, out of range */
414f227f7cSBarry Smith #define PETSC_ERR_ARG_BADPTR       68   /* invalid pointer argument */
424f227f7cSBarry Smith #define PETSC_ERR_ARG_NOTSAMETYPE  69   /* two args must be same object type */
436831982aSBarry Smith #define PETSC_ERR_ARG_NOTSAMECOMM  80   /* two args must be same communicators */
44d252947aSBarry Smith #define PETSC_ERR_ARG_WRONGSTATE   73   /* object in argument is in wrong state, e.g. unassembled mat */
458cda6cd7SBarry Smith #define PETSC_ERR_ARG_TYPENOTSET   89   /* the type of the object has not yet been set */
46a8c6a408SBarry Smith #define PETSC_ERR_ARG_INCOMP       75   /* two arguments are incompatible */
474482741eSBarry Smith #define PETSC_ERR_ARG_NULL         85   /* argument is null that should not be */
48958c9bccSBarry Smith #define PETSC_ERR_ARG_UNKNOWN_TYPE 86   /* type name doesn't match any registered type */
494f227f7cSBarry Smith 
504f227f7cSBarry Smith #define PETSC_ERR_FILE_OPEN        65   /* unable to open file */
514f227f7cSBarry Smith #define PETSC_ERR_FILE_READ        66   /* unable to read from file */
524f227f7cSBarry Smith #define PETSC_ERR_FILE_WRITE       67   /* unable to write to file */
53a8c6a408SBarry Smith #define PETSC_ERR_FILE_UNEXPECTED  79   /* unexpected data in file */
5445d48df9SBarry Smith 
55329ffe3dSLois Curfman McInnes #define PETSC_ERR_MAT_LU_ZRPVT     71   /* detected a zero pivot during LU factorization */
569e3b2f23SBarry Smith #define PETSC_ERR_MAT_CH_ZRPVT     81   /* detected a zero pivot during Cholesky factorization */
5754a8ef01SBarry Smith 
5868e69593SBarry Smith #define PETSC_ERR_INT_OVERFLOW     84
593855c12bSBarry Smith 
60bf3909cdSBarry Smith #define PETSC_ERR_FLOP_COUNT       90
61e113a28aSBarry Smith #define PETSC_ERR_NOT_CONVERGED    91  /* solver did not converge */
6292e8f287SBarry Smith #define PETSC_ERR_MISSING_FACTOR   92  /* MatGetFactor() failed */
63691b26d3SBarry Smith #define PETSC_ERR_OPT_OVERWRITE    93  /* attempted to over write options which should not be changed */
64691b26d3SBarry Smith #define PETSC_ERR_WRONG_MPI_SIZE   94  /* example/application run with number of MPI ranks it does not support */
65691b26d3SBarry Smith #define PETSC_ERR_USER_INPUT       95  /* missing or incorrect user input */
66589f383fSBarry Smith #define PETSC_ERR_GPU_RESOURCE     96  /* unable to load a GPU resource, for example cuBLAS */
67589f383fSBarry 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 */
68ffc4695bSBarry Smith #define PETSC_ERR_MPI              98  /* general MPI error */
69ffc4695bSBarry Smith #define PETSC_ERR_MAX_VALUE        99  /* this is always the one more than the largest error code */
70b9eb5ee8SHong Zhang 
7198921bdaSJacob Faibussowitsch #define SETERRQ1(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
7298921bdaSJacob Faibussowitsch #define SETERRQ2(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
7398921bdaSJacob Faibussowitsch #define SETERRQ3(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
7498921bdaSJacob Faibussowitsch #define SETERRQ4(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
7598921bdaSJacob Faibussowitsch #define SETERRQ5(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
7698921bdaSJacob Faibussowitsch #define SETERRQ6(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
7798921bdaSJacob Faibussowitsch #define SETERRQ7(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
7898921bdaSJacob Faibussowitsch #define SETERRQ8(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
7998921bdaSJacob Faibussowitsch #define SETERRQ9(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
8098921bdaSJacob Faibussowitsch 
8130de9b25SBarry Smith /*MC
821957e957SBarry Smith    SETERRQ - Macro to be called when an error has been detected,
8330de9b25SBarry Smith 
8430de9b25SBarry Smith    Synopsis:
85aaa7dc30SBarry Smith    #include <petscsys.h>
8698921bdaSJacob Faibussowitsch    PetscErrorCode SETERRQ(MPI_Comm comm,PetscErrorCode ierr,char *message,...)
8730de9b25SBarry Smith 
88d083f849SBarry Smith    Collective
8930de9b25SBarry Smith 
9030de9b25SBarry Smith    Input Parameters:
913af045c5SBarry Smith +  comm - A communicator, use PETSC_COMM_SELF unless you know all ranks of another communicator will detect the error
923af045c5SBarry Smith .  ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
9330de9b25SBarry Smith -  message - error message
9430de9b25SBarry Smith 
9530de9b25SBarry Smith   Level: beginner
9630de9b25SBarry Smith 
9730de9b25SBarry Smith    Notes:
9830de9b25SBarry Smith     Once the error handler is called the calling function is then returned from with the given error code.
9930de9b25SBarry Smith 
10030de9b25SBarry Smith     Experienced users can set the error handler with PetscPushErrorHandler().
10130de9b25SBarry Smith 
1023b1008b8SBarry Smith    Fortran Notes:
1033b1008b8SBarry Smith       SETERRQ() may be called from Fortran subroutines but SETERRA() must be called from the
1043b1008b8SBarry Smith       Fortran main program.
1053b1008b8SBarry Smith 
106db781477SPatrick Sanan .seealso: `PetscCheck()`, `PetscAssert()`, `PetscTraceBackErrorHandler()`, `PetscPushErrorHandler()`,
107db781477SPatrick Sanan           `PetscError()`, `PetscCall()`, `CHKMEMQ`, `CHKERRA()`, `PetscCallMPI()`
10830de9b25SBarry Smith M*/
10998921bdaSJacob Faibussowitsch #define SETERRQ(comm,ierr,...) return PetscError(comm,__LINE__,PETSC_FUNCTION_NAME,__FILE__,ierr,PETSC_ERROR_INITIAL,__VA_ARGS__)
110986eef2eSBarry Smith 
111ffc4695bSBarry Smith /*
112ffc4695bSBarry Smith     Returned from PETSc functions that are called from MPI, such as related to attributes
113ffc4695bSBarry Smith       Do not confuse PETSC_MPI_ERROR_CODE and PETSC_ERR_MPI, the first is registered with MPI and returned to MPI as
114888a1fb3SBarry 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.
115ffc4695bSBarry Smith */
116ffc4695bSBarry Smith PETSC_EXTERN PetscMPIInt PETSC_MPI_ERROR_CLASS;
117ffc4695bSBarry Smith PETSC_EXTERN PetscMPIInt PETSC_MPI_ERROR_CODE;
118ffc4695bSBarry Smith 
119986eef2eSBarry Smith /*MC
120986eef2eSBarry Smith    SETERRMPI - Macro to be called when an error has been detected within an MPI callback function
121986eef2eSBarry Smith 
122986eef2eSBarry Smith    Synopsis:
123986eef2eSBarry Smith    #include <petscsys.h>
12498921bdaSJacob Faibussowitsch    PetscErrorCode SETERRMPI(MPI_Comm comm,PetscErrorCode ierr,char *message,...)
125986eef2eSBarry Smith 
126d083f849SBarry Smith    Collective
127986eef2eSBarry Smith 
128986eef2eSBarry Smith    Input Parameters:
129986eef2eSBarry Smith +  comm - A communicator, use PETSC_COMM_SELF unless you know all ranks of another communicator will detect the error
130986eef2eSBarry Smith .  ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
131986eef2eSBarry Smith -  message - error message
132986eef2eSBarry Smith 
133986eef2eSBarry Smith   Level: developer
134986eef2eSBarry Smith 
135986eef2eSBarry Smith    Notes:
136888a1fb3SBarry 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
137986eef2eSBarry Smith     which is registered with MPI_Add_error_code() when PETSc is initialized.
138986eef2eSBarry Smith 
139db781477SPatrick Sanan .seealso: `SETERRQ()`, `PetscCall()`, `PetscCallMPI()`, `PetscTraceBackErrorHandler()`, `PetscPushErrorHandler()`, `PetscError()`, `CHKMEMQ`
140986eef2eSBarry Smith M*/
14198921bdaSJacob Faibussowitsch #define SETERRMPI(comm,ierr,...) return (PetscError(comm,__LINE__,PETSC_FUNCTION_NAME,__FILE__,ierr,PETSC_ERROR_INITIAL,__VA_ARGS__),PETSC_MPI_ERROR_CODE)
142ee8199e6SMatthew G. Knepley 
143ee8199e6SMatthew G. Knepley /*MC
144f388eb8bSPatrick Sanan    SETERRA - Fortran-only macro that can be called when an error has been detected from the main program
145f388eb8bSPatrick Sanan 
146f388eb8bSPatrick Sanan    Synopsis:
147f388eb8bSPatrick Sanan    #include <petscsys.h>
148f388eb8bSPatrick Sanan    PetscErrorCode SETERRA(MPI_Comm comm,PetscErrorCode ierr,char *message)
149f388eb8bSPatrick Sanan 
150f388eb8bSPatrick Sanan    Collective
151f388eb8bSPatrick Sanan 
152f388eb8bSPatrick Sanan    Input Parameters:
153f388eb8bSPatrick Sanan +  comm - A communicator, so that the error can be collective
154f388eb8bSPatrick Sanan .  ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
155f388eb8bSPatrick Sanan -  message - error message in the printf format
156f388eb8bSPatrick Sanan 
157f388eb8bSPatrick Sanan   Level: beginner
158f388eb8bSPatrick Sanan 
159f388eb8bSPatrick Sanan    Notes:
160f388eb8bSPatrick Sanan     This should only be used with Fortran. With C/C++, use SETERRQ().
161f388eb8bSPatrick Sanan 
162f388eb8bSPatrick Sanan    Fortran Notes:
163f388eb8bSPatrick Sanan       SETERRQ() may be called from Fortran subroutines but SETERRA() must be called from the
164f388eb8bSPatrick Sanan       Fortran main program.
165f388eb8bSPatrick Sanan 
166db781477SPatrick Sanan .seealso: `SETERRQ()`, `SETERRABORT()`, `PetscCall()`, `CHKERRA()`, `PetscCallAbort()`
167f388eb8bSPatrick Sanan M*/
168f388eb8bSPatrick Sanan 
169f388eb8bSPatrick Sanan /*MC
170fa190f98SMatthew G. Knepley    SETERRABORT - Macro that can be called when an error has been detected,
171fa190f98SMatthew G. Knepley 
172fa190f98SMatthew G. Knepley    Synopsis:
173fa190f98SMatthew G. Knepley    #include <petscsys.h>
17498921bdaSJacob Faibussowitsch    PetscErrorCode SETERRABORT(MPI_Comm comm,PetscErrorCode ierr,char *message,...)
175fa190f98SMatthew G. Knepley 
176d083f849SBarry Smith    Collective
177fa190f98SMatthew G. Knepley 
178fa190f98SMatthew G. Knepley    Input Parameters:
179fa190f98SMatthew G. Knepley +  comm - A communicator, so that the error can be collective
1803af045c5SBarry Smith .  ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
181fa190f98SMatthew G. Knepley -  message - error message in the printf format
182fa190f98SMatthew G. Knepley 
183fa190f98SMatthew G. Knepley   Level: beginner
184fa190f98SMatthew G. Knepley 
185fa190f98SMatthew G. Knepley    Notes:
186fa190f98SMatthew G. Knepley     This function just calls MPI_Abort().
187fa190f98SMatthew G. Knepley 
188db781477SPatrick Sanan .seealso: `SETERRQ()`, `PetscTraceBackErrorHandler()`, `PetscPushErrorHandler()`, `PetscError()`, `PetscCall()`, `CHKMEMQ`
189fa190f98SMatthew G. Knepley M*/
19098921bdaSJacob Faibussowitsch #define SETERRABORT(comm,ierr,...) do {                                                        \
19198921bdaSJacob Faibussowitsch     PetscError(comm,__LINE__,PETSC_FUNCTION_NAME,__FILE__,ierr,PETSC_ERROR_INITIAL,__VA_ARGS__); \
19298921bdaSJacob Faibussowitsch     MPI_Abort(comm,ierr);                                                                      \
19398921bdaSJacob Faibussowitsch   } while (0)
1949a00fa46SSatish Balay 
19530de9b25SBarry Smith /*MC
1962c71b3e2SJacob Faibussowitsch   PetscCheck - Check that a particular condition is true
1972c71b3e2SJacob Faibussowitsch 
1982c71b3e2SJacob Faibussowitsch   Synopsis:
1992c71b3e2SJacob Faibussowitsch   #include <petscerror.h>
2002c71b3e2SJacob Faibussowitsch   void PetscCheck(bool cond, MPI_Comm comm, PetscErrorCode ierr, const char *message, ...)
2012c71b3e2SJacob Faibussowitsch 
2022c71b3e2SJacob Faibussowitsch   Collective
2032c71b3e2SJacob Faibussowitsch 
2042c71b3e2SJacob Faibussowitsch   Input Parameters:
2052c71b3e2SJacob Faibussowitsch + cond    - The boolean condition
2062c71b3e2SJacob Faibussowitsch . comm    - The communicator on which the check can be collective on
2072c71b3e2SJacob Faibussowitsch . ierr    - A nonzero error code, see include/petscerror.h for the complete list
2082c71b3e2SJacob Faibussowitsch - message - Error message in printf format
2092c71b3e2SJacob Faibussowitsch 
2102c71b3e2SJacob Faibussowitsch   Notes:
2112c71b3e2SJacob Faibussowitsch   Enabled in both optimized and debug builds.
2122c71b3e2SJacob Faibussowitsch 
2132c71b3e2SJacob Faibussowitsch   Calls SETERRQ() if the assertion fails, so can only be called from functions returning a
2142c71b3e2SJacob Faibussowitsch   PetscErrorCode (or equivalent type after conversion).
2152c71b3e2SJacob Faibussowitsch 
2162c71b3e2SJacob Faibussowitsch   Level: beginner
2172c71b3e2SJacob Faibussowitsch 
218db781477SPatrick Sanan .seealso: `PetscAssert()`, `SETERRQ()`, `PetscError()`, `PetscCall()`
2199566063dSJacob Faibussowitsch M*/
2202c71b3e2SJacob Faibussowitsch #define PetscCheck(cond,comm,ierr,...) if (PetscUnlikely(!(cond))) SETERRQ(comm,ierr,__VA_ARGS__)
2212c71b3e2SJacob Faibussowitsch 
2222c71b3e2SJacob Faibussowitsch /*MC
2239ace16cdSJacob Faibussowitsch   PetscAssert - Assert that a particular condition is true
2249ace16cdSJacob Faibussowitsch 
2259ace16cdSJacob Faibussowitsch   Synopsis:
2269ace16cdSJacob Faibussowitsch   #include <petscerror.h>
2279ace16cdSJacob Faibussowitsch   void PetscAssert(bool cond, MPI_Comm comm, PetscErrorCode ierr, const char *message, ...)
2289ace16cdSJacob Faibussowitsch 
2299ace16cdSJacob Faibussowitsch   Collective
2309ace16cdSJacob Faibussowitsch 
2319ace16cdSJacob Faibussowitsch   Input Parameters:
2329ace16cdSJacob Faibussowitsch + cond    - The boolean condition
2339ace16cdSJacob Faibussowitsch . comm    - The communicator on which the check can be collective on
2349ace16cdSJacob Faibussowitsch . ierr    - A nonzero error code, see include/petscerror.h for the complete list
2359ace16cdSJacob Faibussowitsch - message - Error message in printf format
2369ace16cdSJacob Faibussowitsch 
2379ace16cdSJacob Faibussowitsch   Notes:
2382c71b3e2SJacob Faibussowitsch   Enabled only in debug builds. Note that any arguments to this macros are still visible to the
2392c71b3e2SJacob Faibussowitsch   compiler optimized builds (so must still contain valid code) but are guaranteed to not be
2402c71b3e2SJacob Faibussowitsch   executed.
2412c71b3e2SJacob Faibussowitsch 
2422c71b3e2SJacob Faibussowitsch   See PetscCheck() for usage and behaviour.
2439ace16cdSJacob Faibussowitsch 
2449ace16cdSJacob Faibussowitsch   Level: beginner
2459ace16cdSJacob Faibussowitsch 
246db781477SPatrick Sanan .seealso: `PetscCheck()`, `SETERRQ()`, `PetscError()`
2479566063dSJacob Faibussowitsch M*/
2482c71b3e2SJacob Faibussowitsch #define PetscAssert(cond,comm,ierr,...) if (PetscUnlikelyDebug(!(cond))) SETERRQ(comm,ierr,__VA_ARGS__)
2499ace16cdSJacob Faibussowitsch 
2509ace16cdSJacob Faibussowitsch /*MC
2519566063dSJacob Faibussowitsch   PetscCall - Checks error code returned from a PETSc function, if non-zero it calls the error
2529566063dSJacob Faibussowitsch   handler and and returns from the current function.
2539566063dSJacob Faibussowitsch 
2549566063dSJacob Faibussowitsch   Synopsis:
2559566063dSJacob Faibussowitsch   #include <petscerror.h>
2569566063dSJacob Faibussowitsch   void PetscCall(PetscErrorCode ierr)
2579566063dSJacob Faibussowitsch 
2589566063dSJacob Faibussowitsch   Not Collective
2599566063dSJacob Faibussowitsch 
2609566063dSJacob Faibussowitsch   Input Parameter:
2619566063dSJacob Faibussowitsch . ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
2629566063dSJacob Faibussowitsch 
2639566063dSJacob Faibussowitsch   Notes:
2649566063dSJacob Faibussowitsch   Once the error handler is called the calling function is then returned from with the given
2659566063dSJacob Faibussowitsch   error code. Experienced users can set the error handler with PetscPushErrorHandler().
2669566063dSJacob Faibussowitsch 
2679566063dSJacob Faibussowitsch   PetscCall(ierr) is fundamentally a macro replacement for
2689566063dSJacob Faibussowitsch .vb
2699566063dSJacob Faibussowitsch   if (ierr) return PetscError(...,ierr,...);
2709566063dSJacob Faibussowitsch .ve
2719566063dSJacob Faibussowitsch 
2729566063dSJacob Faibussowitsch   PetscCall() cannot be used in functions returning a datatype not convertable to
2739566063dSJacob Faibussowitsch   PetscErrorCode. For example, PetscCall() may not be used in functions returning void, use
2749566063dSJacob Faibussowitsch   PetscCallVoid() in this case.
2759566063dSJacob Faibussowitsch 
2769566063dSJacob Faibussowitsch   Fortran Notes:
2779566063dSJacob Faibussowitsch   PetscCall() may be called from Fortran subroutines but CHKERRA() must be called from the
2789566063dSJacob Faibussowitsch   Fortran main program.
2799566063dSJacob Faibussowitsch 
2809566063dSJacob Faibussowitsch   Example Usage:
2819566063dSJacob Faibussowitsch .vb
2829566063dSJacob Faibussowitsch   PetscCall(PetscInitiailize(...)); // OK to call even when PETSc is not yet initialized!
2839566063dSJacob Faibussowitsch 
2849566063dSJacob Faibussowitsch   extern int foo(int);
2859566063dSJacob Faibussowitsch 
2869566063dSJacob Faibussowitsch   PetscCall(foo(1)); // OK if int is convertable to PetscErrorCode
2879566063dSJacob Faibussowitsch 
2889566063dSJacob Faibussowitsch   struct my_struct
2899566063dSJacob Faibussowitsch   {
2909566063dSJacob Faibussowitsch     void *data;
2919566063dSJacob Faibussowitsch   } my_complex_type;
2929566063dSJacob Faibussowitsch 
2939566063dSJacob Faibussowitsch   struct my_struct bar(void)
2949566063dSJacob Faibussowitsch   {
2959566063dSJacob Faibussowitsch     PetscCall(foo(15)); // ERROR PetscErrorCode not convertable to struct my_struct!
2969566063dSJacob Faibussowitsch   }
2979566063dSJacob Faibussowitsch 
2989566063dSJacob Faibussowitsch   PetscCall(bar()) // ERROR input not convertable to PetscErrorCode
2999566063dSJacob Faibussowitsch .ve
3009566063dSJacob Faibussowitsch 
3019566063dSJacob Faibussowitsch   Level: beginner
3029566063dSJacob Faibussowitsch 
303db781477SPatrick Sanan .seealso: `SETERRQ()`, `PetscCheck()`, `PetscAssert()`, `PetscTraceBackErrorHandler()`,
304db781477SPatrick Sanan           `PetscPushErrorHandler()`, `PetscError()`, `CHKMEMQ`, `CHKERRA()`
3059566063dSJacob Faibussowitsch M*/
3069566063dSJacob Faibussowitsch #if defined(PETSC_CLANG_STATIC_ANALYZER)
3079566063dSJacob Faibussowitsch void PetscCall(PetscErrorCode);
3089566063dSJacob Faibussowitsch void PetscCallVoid(PetscErrorCode);
3099566063dSJacob Faibussowitsch #else
3109566063dSJacob Faibussowitsch #define PetscCall(...) do {                                                                    \
3119566063dSJacob Faibussowitsch     PetscErrorCode ierr_q_ = __VA_ARGS__;                                                      \
3129566063dSJacob Faibussowitsch     if (PetscUnlikely(ierr_q_)) return PetscError(PETSC_COMM_SELF,__LINE__,PETSC_FUNCTION_NAME,__FILE__,ierr_q_,PETSC_ERROR_REPEAT," "); \
3139566063dSJacob Faibussowitsch   } while (0)
3149566063dSJacob Faibussowitsch #define PetscCallVoid(...) do {                                                                \
3159566063dSJacob Faibussowitsch     PetscErrorCode ierr_void_ = __VA_ARGS__;                                                   \
3169566063dSJacob Faibussowitsch     if (PetscUnlikely(ierr_void_)) {                                                           \
3179566063dSJacob Faibussowitsch       (void)PetscError(PETSC_COMM_SELF,__LINE__,PETSC_FUNCTION_NAME,__FILE__,ierr_void_,PETSC_ERROR_REPEAT," "); \
3189566063dSJacob Faibussowitsch       return;                                                                                  \
3199566063dSJacob Faibussowitsch     }                                                                                          \
3209566063dSJacob Faibussowitsch   } while (0)
3219566063dSJacob Faibussowitsch #endif
3229566063dSJacob Faibussowitsch 
3239566063dSJacob Faibussowitsch /*MC
3249566063dSJacob Faibussowitsch   CHKERRQ - Checks error code returned from PETSc function
32530de9b25SBarry Smith 
32630de9b25SBarry Smith   Synopsis:
327aaa7dc30SBarry Smith   #include <petscsys.h>
3289566063dSJacob Faibussowitsch   void CHKERRQ(PetscErrorCode ierr)
3299566063dSJacob Faibussowitsch 
3309566063dSJacob Faibussowitsch   Not Collective
3319566063dSJacob Faibussowitsch 
3329566063dSJacob Faibussowitsch   Input Parameters:
3339566063dSJacob Faibussowitsch . ierr - nonzero error code
3349566063dSJacob Faibussowitsch 
3359566063dSJacob Faibussowitsch   Notes:
3369566063dSJacob Faibussowitsch   Deprecated in favor of PetscCall(). This routine behaves identically to it.
3379566063dSJacob Faibussowitsch 
3389566063dSJacob Faibussowitsch   Level: deprecated
3399566063dSJacob Faibussowitsch 
340db781477SPatrick Sanan .seealso: `PetscCall()`
3419566063dSJacob Faibussowitsch M*/
3429566063dSJacob Faibussowitsch #define CHKERRQ(...) PetscCall(__VA_ARGS__)
3439566063dSJacob Faibussowitsch #define CHKERRV(...) PetscCallVoid(__VA_ARGS__)
3449566063dSJacob Faibussowitsch 
3459566063dSJacob Faibussowitsch /*MC
3469566063dSJacob Faibussowitsch   PetscCallMPI - Checks error code returned from MPI calls, if non-zero it calls the error
3479566063dSJacob Faibussowitsch   handler and then returns
3489566063dSJacob Faibussowitsch 
3499566063dSJacob Faibussowitsch   Synopsis:
3509566063dSJacob Faibussowitsch   #include <petscerror.h>
3519566063dSJacob Faibussowitsch   void PetscCallMPI(PetscErrorCode ierr)
35230de9b25SBarry Smith 
353eca87e8dSBarry Smith   Not Collective
35430de9b25SBarry Smith 
35530de9b25SBarry Smith   Input Parameters:
3563af045c5SBarry Smith . ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
35730de9b25SBarry Smith 
3589566063dSJacob Faibussowitsch   Notes:
3599566063dSJacob Faibussowitsch   Always returns the error code PETSC_ERR_MPI; the MPI error code and string are embedded in
3609566063dSJacob Faibussowitsch   the string error message. Do not use this to call any other routines (for example PETSc
3619566063dSJacob Faibussowitsch   routines), it should only be used for direct MPI calls. Due to limitations of the
3629566063dSJacob Faibussowitsch   preprocessor this can unfortunately not easily be enforced, so the user should take care to
3639566063dSJacob Faibussowitsch   check this themselves.
3649566063dSJacob Faibussowitsch 
3659566063dSJacob Faibussowitsch   Example Usage:
3669566063dSJacob Faibussowitsch .vb
3679566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(...)); // OK, calling MPI function
3689566063dSJacob Faibussowitsch 
3699566063dSJacob Faibussowitsch   PetscCallMPI(PetscFunction(...)); // ERROR, use PetscCall() instead!
3709566063dSJacob Faibussowitsch .ve
3719566063dSJacob Faibussowitsch 
37230de9b25SBarry Smith   Level: beginner
37330de9b25SBarry Smith 
374db781477SPatrick Sanan .seealso: `SETERRMPI()`, `PetscCall()`, `SETERRQ()`, `SETERRABORT()`, `PetscCallAbort()`,
375db781477SPatrick Sanan           `PetscTraceBackErrorHandler()`, `PetscPushErrorHandler()`, `PetscError()`, `CHKMEMQ`
37630de9b25SBarry Smith M*/
3773fcd9f07SJacob Faibussowitsch #if defined(PETSC_CLANG_STATIC_ANALYZER)
37863a3b9bcSJacob Faibussowitsch void PetscCallMPI(PetscMPIInt);
379064a246eSJacob Faibussowitsch #else
3809566063dSJacob Faibussowitsch #define PetscCallMPI(...) do {                                                                 \
3819566063dSJacob Faibussowitsch     PetscMPIInt _7_errorcode = __VA_ARGS__;                                                    \
3829566063dSJacob Faibussowitsch     if (PetscUnlikely(_7_errorcode)) {                                                         \
3839566063dSJacob Faibussowitsch       char        _7_errorstring[MPI_MAX_ERROR_STRING];                                        \
3849566063dSJacob Faibussowitsch       PetscMPIInt _7_resultlen;                                                                \
385edc6e9c6SBarry Smith       MPI_Error_string(_7_errorcode,(char*)_7_errorstring,&_7_resultlen); \
386edc6e9c6SBarry Smith       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MPI,"MPI error %d %s Ignore the following value %d",(int)_7_errorcode,_7_errorstring,_7_resultlen); \
3873fcd9f07SJacob Faibussowitsch     }                                                                                          \
3883fcd9f07SJacob Faibussowitsch   } while (0)
3899566063dSJacob Faibussowitsch #endif
390064a246eSJacob Faibussowitsch 
3917037b0edSPatrick Sanan /*MC
3929566063dSJacob Faibussowitsch   CHKERRMPI - Checks error code returned from MPI calls, if non-zero it calls the error
3939566063dSJacob Faibussowitsch   handler and then returns
3949566063dSJacob Faibussowitsch 
3959566063dSJacob Faibussowitsch   Synopsis:
3969566063dSJacob Faibussowitsch   #include <petscerror.h>
3979566063dSJacob Faibussowitsch   void CHKERRMPI(PetscErrorCode ierr)
3989566063dSJacob Faibussowitsch 
3999566063dSJacob Faibussowitsch   Not Collective
4009566063dSJacob Faibussowitsch 
4019566063dSJacob Faibussowitsch   Input Parameter:
4029566063dSJacob Faibussowitsch . ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
4039566063dSJacob Faibussowitsch 
4049566063dSJacob Faibussowitsch   Notes:
4059566063dSJacob Faibussowitsch   Deprecated in favor of PetscCallMPI(). This routine behaves identically to it.
4069566063dSJacob Faibussowitsch 
4079566063dSJacob Faibussowitsch   Level: deprecated
4089566063dSJacob Faibussowitsch 
409db781477SPatrick Sanan .seealso: `PetscCallMPI()`
4109566063dSJacob Faibussowitsch M*/
4119566063dSJacob Faibussowitsch #define CHKERRMPI(...) PetscCallMPI(__VA_ARGS__)
4129566063dSJacob Faibussowitsch 
4139566063dSJacob Faibussowitsch /*MC
4149566063dSJacob Faibussowitsch   PetscCallAbort - Checks error code returned from PETSc function, if non-zero it aborts immediately
4159566063dSJacob Faibussowitsch 
4169566063dSJacob Faibussowitsch   Synopsis:
4179566063dSJacob Faibussowitsch   #include <petscerror.h>
4189566063dSJacob Faibussowitsch   void PetscCallAbort(MPI_Comm comm, PetscErrorCode ierr)
4199566063dSJacob Faibussowitsch 
4209566063dSJacob Faibussowitsch   Collective on comm
4219566063dSJacob Faibussowitsch 
4229566063dSJacob Faibussowitsch   Input Parameters:
4239566063dSJacob Faibussowitsch + comm - the MPI communicator on which to abort
4249566063dSJacob Faibussowitsch - ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
4259566063dSJacob Faibussowitsch 
4269566063dSJacob Faibussowitsch   Notes:
4279566063dSJacob Faibussowitsch   This macro has identical type and usage semantics to PetscCall() with the important caveat
4289566063dSJacob Faibussowitsch   that this macro does not return. Instead, if ierr is nonzero it calls the PETSc error handler
4299566063dSJacob Faibussowitsch   and then immediately calls MPI_Abort(). It can therefore be used anywhere.
4309566063dSJacob Faibussowitsch 
4319566063dSJacob Faibussowitsch   As per MPI_Abort semantics the communicator passed must be valid, although there is currently
4329566063dSJacob Faibussowitsch   no attempt made at handling any potential errors from MPI_Abort(). Note that while
4339566063dSJacob Faibussowitsch   MPI_Abort() is required to terminate only those processes which reside on comm, it is often
4349566063dSJacob Faibussowitsch   the case that MPI_Abort() terminates *all* processes.
4359566063dSJacob Faibussowitsch 
4369566063dSJacob Faibussowitsch   Example Usage:
4379566063dSJacob Faibussowitsch .vb
4389566063dSJacob Faibussowitsch   PetscErrorCode boom(void) { return PETSC_ERR_MEM; }
4399566063dSJacob Faibussowitsch 
4409566063dSJacob Faibussowitsch   void foo(void)
4419566063dSJacob Faibussowitsch   {
4429566063dSJacob Faibussowitsch     PetscCallAbort(PETSC_COMM_WORLD,boom()); // OK, does not return a type
4439566063dSJacob Faibussowitsch   }
4449566063dSJacob Faibussowitsch 
4459566063dSJacob Faibussowitsch   double bar(void)
4469566063dSJacob Faibussowitsch   {
4479566063dSJacob Faibussowitsch     PetscCallAbort(PETSC_COMM_WORLD,boom()); // OK, does not return a type
4489566063dSJacob Faibussowitsch   }
4499566063dSJacob Faibussowitsch 
4509566063dSJacob Faibussowitsch   PetscCallAbort(MPI_COMM_NULL,boom()); // ERROR, communicator should be valid
4519566063dSJacob Faibussowitsch 
4529566063dSJacob Faibussowitsch   struct baz
4539566063dSJacob Faibussowitsch   {
4549566063dSJacob Faibussowitsch     baz()
4559566063dSJacob Faibussowitsch     {
4569566063dSJacob Faibussowitsch       PetscCallAbort(PETSC_COMM_SELF,boom()); // OK
4579566063dSJacob Faibussowitsch     }
4589566063dSJacob Faibussowitsch 
4599566063dSJacob Faibussowitsch     ~baz()
4609566063dSJacob Faibussowitsch     {
4619566063dSJacob Faibussowitsch       PetscCallAbort(PETSC_COMM_SELF,boom()); // OK (in fact the only way to handle PETSc errors)
4629566063dSJacob Faibussowitsch     }
4639566063dSJacob Faibussowitsch   };
4649566063dSJacob Faibussowitsch .ve
4659566063dSJacob Faibussowitsch 
4669566063dSJacob Faibussowitsch   Level: intermediate
4679566063dSJacob Faibussowitsch 
468db781477SPatrick Sanan .seealso: `SETERRABORT()`, `PetscTraceBackErrorHandler()`, `PetscPushErrorHandler()`, `PetscError()`,
469db781477SPatrick Sanan           `SETERRQ()`, `CHKMEMQ`, `PetscCallMPI()`
4709566063dSJacob Faibussowitsch M*/
4719566063dSJacob Faibussowitsch #if defined(PETSC_CLANG_STATIC_ANALYZER)
4729566063dSJacob Faibussowitsch void PetscCallAbort(MPI_Comm,PetscErrorCode);
4739566063dSJacob Faibussowitsch void PetscCallContinue(PetscErrorCode);
4749566063dSJacob Faibussowitsch #else
4759566063dSJacob Faibussowitsch #define PetscCallAbort(comm,...) do {                                                          \
4769566063dSJacob Faibussowitsch     PetscErrorCode ierr_abort_ = __VA_ARGS__;                                                  \
4779566063dSJacob Faibussowitsch     if (PetscUnlikely(ierr_abort_)) {                                                          \
4789566063dSJacob Faibussowitsch       PetscError(PETSC_COMM_SELF,__LINE__,PETSC_FUNCTION_NAME,__FILE__,ierr_abort_,PETSC_ERROR_REPEAT," "); \
4799566063dSJacob Faibussowitsch       MPI_Abort(comm,ierr_abort_);                                                             \
4809566063dSJacob Faibussowitsch     }                                                                                          \
4819566063dSJacob Faibussowitsch   } while (0)
4829566063dSJacob Faibussowitsch #define PetscCallContinue(...)   do {                                                          \
4839566063dSJacob Faibussowitsch     PetscErrorCode ierr_continue_ = __VA_ARGS__;                                               \
4849566063dSJacob Faibussowitsch     if (PetscUnlikely(ierr_continue_)) PetscError(PETSC_COMM_SELF,__LINE__,PETSC_FUNCTION_NAME,__FILE__,ierr_continue_,PETSC_ERROR_REPEAT," "); \
4859566063dSJacob Faibussowitsch   } while (0)
4869566063dSJacob Faibussowitsch #endif
4879566063dSJacob Faibussowitsch 
4889566063dSJacob Faibussowitsch /*MC
4899566063dSJacob Faibussowitsch   CHKERRABORT - Checks error code returned from PETSc function. If non-zero it aborts immediately.
4909566063dSJacob Faibussowitsch 
4919566063dSJacob Faibussowitsch   Synopsis:
4929566063dSJacob Faibussowitsch   #include <petscerror.h>
4939566063dSJacob Faibussowitsch   void CHKERRABORT(MPI_Comm comm, PetscErrorCode ierr)
4949566063dSJacob Faibussowitsch 
4959566063dSJacob Faibussowitsch   Not Collective
4969566063dSJacob Faibussowitsch 
4979566063dSJacob Faibussowitsch   Input Parameters:
4989566063dSJacob Faibussowitsch + comm - the MPI communicator
4999566063dSJacob Faibussowitsch - ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
5009566063dSJacob Faibussowitsch 
5019566063dSJacob Faibussowitsch   Notes:
5029566063dSJacob Faibussowitsch   Deprecated in favor of PetscCallAbort(). This routine behaves identically to it.
5039566063dSJacob Faibussowitsch 
5049566063dSJacob Faibussowitsch   Level: deprecated
5059566063dSJacob Faibussowitsch 
506db781477SPatrick Sanan .seealso: `PetscCallAbort()`
5079566063dSJacob Faibussowitsch M*/
5089566063dSJacob Faibussowitsch #define CHKERRABORT(comm,...) PetscCallAbort(comm,__VA_ARGS__)
5099566063dSJacob Faibussowitsch #define CHKERRCONTINUE(...)   PetscCallContinue(__VA_ARGS__)
5109566063dSJacob Faibussowitsch 
5119566063dSJacob Faibussowitsch /*MC
5129566063dSJacob Faibussowitsch    CHKERRA - Fortran-only replacement for PetscCall in the main program, which aborts immediately
513f388eb8bSPatrick Sanan 
514f388eb8bSPatrick Sanan    Synopsis:
515f388eb8bSPatrick Sanan    #include <petscsys.h>
516f388eb8bSPatrick Sanan    PetscErrorCode CHKERRA(PetscErrorCode ierr)
517f388eb8bSPatrick Sanan 
518f388eb8bSPatrick Sanan    Not Collective
519f388eb8bSPatrick Sanan 
520f388eb8bSPatrick Sanan    Input Parameters:
521f388eb8bSPatrick Sanan .  ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
522f388eb8bSPatrick Sanan 
523f388eb8bSPatrick Sanan   Level: beginner
524f388eb8bSPatrick Sanan 
525f388eb8bSPatrick Sanan    Notes:
5269566063dSJacob Faibussowitsch       This should only be used with Fortran. With C/C++, use PetscCall() in normal usage,
5279566063dSJacob Faibussowitsch       or PetscCallAbort() if wanting to abort immediately on error.
528f388eb8bSPatrick Sanan 
529f388eb8bSPatrick Sanan    Fortran Notes:
5309566063dSJacob Faibussowitsch       PetscCall() may be called from Fortran subroutines but CHKERRA() must be called from the
531f388eb8bSPatrick Sanan       Fortran main program.
532f388eb8bSPatrick Sanan 
533db781477SPatrick Sanan .seealso: `PetscCall()`, `PetscCallAbort()`, `SETERRA()`, `SETERRQ()`, `SETERRABORT()`
534f388eb8bSPatrick Sanan M*/
535f388eb8bSPatrick Sanan 
5367c66cc67SJunchao Zhang PETSC_EXTERN PetscErrorCode PetscAbortFindSourceFile_Private(const char*,PetscInt*);
5371e4f893aSSatish Balay PETSC_EXTERN PetscBool petscwaitonerrorflg;
5381e4f893aSSatish Balay PETSC_EXTERN PetscBool petscindebugger;
5397c66cc67SJunchao Zhang 
5407c66cc67SJunchao Zhang /*MC
5417c66cc67SJunchao Zhang    PETSCABORT - Call MPI_Abort with an informative error code
5427c66cc67SJunchao Zhang 
5437c66cc67SJunchao Zhang    Synopsis:
5447c66cc67SJunchao Zhang    #include <petscsys.h>
5457c66cc67SJunchao Zhang    PETSCABORT(MPI_Comm comm, PetscErrorCode ierr)
5467c66cc67SJunchao Zhang 
5477c66cc67SJunchao Zhang    Collective
5487c66cc67SJunchao Zhang 
5497c66cc67SJunchao Zhang    Input Parameters:
5507c66cc67SJunchao Zhang +  comm - A communicator, so that the error can be collective
5517c66cc67SJunchao Zhang -  ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
5527c66cc67SJunchao Zhang 
553bf4d2887SBarry Smith    Level: advanced
5547c66cc67SJunchao Zhang 
555bf4d2887SBarry Smith    Notes:
556bf4d2887SBarry Smith    We pass MPI_Abort() an error code of format XX_YYYY_ZZZ, where XX, YYYY are an index and line number of the file
5577233276eSBarry Smith    where PETSCABORT is called, respectively. ZZZ is the PETSc error code.
5587c66cc67SJunchao Zhang 
5597233276eSBarry Smith    If XX is zero, this means that the call was made in the routine main().
5607233276eSBarry Smith    If XX is one, that means 1) the file is not in PETSc (it may be in users code); OR 2) the file is in PETSc but PetscAbortSourceFiles[]
5617c66cc67SJunchao Zhang      is out of date. PETSc developers have to update it.
562a0760fecSJunchao Zhang    Otherwise, look up the value of XX in the table PetscAbortSourceFiles[] in src/sys/error/err.c to map XX back to the source file where the PETSCABORT() was called.
5637233276eSBarry Smith 
564bf4d2887SBarry Smith    If the option -start_in_debugger was used then this calls abort() to stop the program in the debugger.
565bf4d2887SBarry Smith 
5667c66cc67SJunchao Zhang  M*/
5673fcd9f07SJacob Faibussowitsch #define PETSCABORT(comm,...) do {                                                              \
568baae8e41SSatish Balay     if (petscwaitonerrorflg) PetscSleep(1000);                                                 \
569bf4d2887SBarry Smith     if (petscindebugger) abort();                                                              \
5703fcd9f07SJacob Faibussowitsch     else {                                                                                     \
5713fcd9f07SJacob Faibussowitsch       PetscErrorCode ierr_petsc_abort_ = __VA_ARGS__;                                          \
5723fcd9f07SJacob Faibussowitsch       PetscInt       idx = 0;                                                                  \
5733fcd9f07SJacob Faibussowitsch       PetscAbortFindSourceFile_Private(__FILE__,&idx);                                         \
5743fcd9f07SJacob Faibussowitsch       MPI_Abort(comm,(PetscMPIInt)(0*idx*10000000 + 0*__LINE__*1000 + ierr_petsc_abort_));     \
5753fcd9f07SJacob Faibussowitsch     }                                                                                          \
5767c66cc67SJunchao Zhang   } while (0)
577986eef2eSBarry Smith 
5789566063dSJacob Faibussowitsch #ifdef PETSC_CLANGUAGE_CXX
579986eef2eSBarry Smith /*MC
5809566063dSJacob Faibussowitsch   PetscCallThrow - Checks error code, if non-zero it calls the C++ error handler which throws
5819566063dSJacob Faibussowitsch   an exception
582986eef2eSBarry Smith 
583986eef2eSBarry Smith   Synopsis:
5849566063dSJacob Faibussowitsch   #include <petscerror.h>
5859566063dSJacob Faibussowitsch   void PetscCallThrow(PetscErrorCode ierr)
586986eef2eSBarry Smith 
587986eef2eSBarry Smith   Not Collective
588986eef2eSBarry Smith 
5899566063dSJacob Faibussowitsch   Input Parameter:
590986eef2eSBarry Smith . ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
591986eef2eSBarry Smith 
592986eef2eSBarry Smith   Notes:
5939566063dSJacob Faibussowitsch   Requires PETSc to be configured with clanguage = c++. Throws a std::runtime_error() on error.
594986eef2eSBarry Smith 
5959566063dSJacob Faibussowitsch   Once the error handler throws the exception you can use PetscCallVoid() which returns without
5969566063dSJacob Faibussowitsch   an error code (bad idea since the error is ignored) or PetscCallAbort() to have MPI_Abort()
5979566063dSJacob Faibussowitsch   called immediately.
5989566063dSJacob Faibussowitsch 
5999566063dSJacob Faibussowitsch   Level: beginner
6009566063dSJacob Faibussowitsch 
601db781477SPatrick Sanan .seealso: `SETERRQ()`, `PetscCall()`, `SETERRABORT()`, `PetscCallAbort()`, `PetscTraceBackErrorHandler()`,
602db781477SPatrick Sanan           `PetscPushErrorHandler()`, `PetscError()`, `CHKMEMQ`
603986eef2eSBarry Smith M*/
6049566063dSJacob Faibussowitsch #define PetscCallThrow(...) do {                                                                    \
6059566063dSJacob Faibussowitsch     PetscErrorCode ierr_cxx_ = __VA_ARGS__;                                                    \
6069566063dSJacob Faibussowitsch     if (PetscUnlikely(ierr_cxx_)) PetscError(PETSC_COMM_SELF,__LINE__,PETSC_FUNCTION_NAME,__FILE__,ierr_cxx_,PETSC_ERROR_IN_CXX,PETSC_NULLPTR); \
607ffc4695bSBarry Smith   } while (0)
60885614651SBarry Smith 
609cc26af49SMatthew Knepley /*MC
610cc26af49SMatthew Knepley   CHKERRXX - Checks error code, if non-zero it calls the C++ error handler which throws an exception
611cc26af49SMatthew Knepley 
612cc26af49SMatthew Knepley   Synopsis:
6139566063dSJacob Faibussowitsch   #include <petscerror.h>
6143af045c5SBarry Smith   void CHKERRXX(PetscErrorCode ierr)
615cc26af49SMatthew Knepley 
616eca87e8dSBarry Smith   Not Collective
617cc26af49SMatthew Knepley 
6189566063dSJacob Faibussowitsch   Input Parameter:
6193af045c5SBarry Smith . ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
620cc26af49SMatthew Knepley 
621cc26af49SMatthew Knepley   Notes:
6229566063dSJacob Faibussowitsch   Deprecated in favor of PetscCallThrow(). This routine behaves identically to it.
623cc26af49SMatthew Knepley 
6249566063dSJacob Faibussowitsch   Level: deprecated
625cc26af49SMatthew Knepley 
626db781477SPatrick Sanan .seealso: `PetscCallThrow()`
627cc26af49SMatthew Knepley M*/
6289566063dSJacob Faibussowitsch #define CHKERRXX(...) PetscCallThrow(__VA_ARGS__)
629fd705b32SMatthew Knepley #endif
630fd705b32SMatthew Knepley 
6313f520e80SJunchao Zhang /*MC
6329566063dSJacob Faibussowitsch   PetscCallCXX - Checks C++ function calls and if they throw an exception, catch it and then
6339566063dSJacob Faibussowitsch   return a PETSc error code
6343f520e80SJunchao Zhang 
6353f520e80SJunchao Zhang   Synopsis:
6369566063dSJacob Faibussowitsch   #include <petscerror.h>
6379566063dSJacob Faibussowitsch   void PetscCallCXX(expr) noexcept;
6383f520e80SJunchao Zhang 
6393f520e80SJunchao Zhang   Not Collective
6403f520e80SJunchao Zhang 
6419566063dSJacob Faibussowitsch   Input Parameter:
6429566063dSJacob Faibussowitsch . expr - An arbitrary expression
6433f520e80SJunchao Zhang 
6443f520e80SJunchao Zhang   Notes:
6459566063dSJacob Faibussowitsch   PetscCallCXX(expr) is a macro replacement for
6469566063dSJacob Faibussowitsch .vb
6479566063dSJacob Faibussowitsch   try {
6489566063dSJacob Faibussowitsch     expr;
6499566063dSJacob Faibussowitsch   } catch (const std::exception& e) {
6509566063dSJacob Faibussowitsch     return ConvertToPetscErrorCode(e);
6519566063dSJacob Faibussowitsch   }
6529566063dSJacob Faibussowitsch .ve
6539566063dSJacob Faibussowitsch   Due to the fact that it catches any (reasonable) exception, it is essentially noexcept.
6543f520e80SJunchao Zhang 
6559566063dSJacob Faibussowitsch   Example Usage:
6569566063dSJacob Faibussowitsch .vb
6579566063dSJacob Faibussowitsch   void foo(void) { throw std::runtime_error("error"); }
6583f520e80SJunchao Zhang 
6599566063dSJacob Faibussowitsch   void bar()
6609566063dSJacob Faibussowitsch   {
661e8952933SJacob Faibussowitsch     PetscCallCXX(foo()); // ERROR bar() does not return PetscErrorCode
6629566063dSJacob Faibussowitsch   }
6639566063dSJacob Faibussowitsch 
6649566063dSJacob Faibussowitsch   PetscErrorCode baz()
6659566063dSJacob Faibussowitsch   {
6669566063dSJacob Faibussowitsch     PetscCallCXX(foo()); // OK
6679566063dSJacob Faibussowitsch 
6689566063dSJacob Faibussowitsch     PetscCallCXX(
6699566063dSJacob Faibussowitsch       bar();
670e8952933SJacob Faibussowitsch       foo(); // OK mutliple statements allowed
6719566063dSJacob Faibussowitsch     );
6729566063dSJacob Faibussowitsch   }
6739566063dSJacob Faibussowitsch 
6749566063dSJacob Faibussowitsch   struct bop
6759566063dSJacob Faibussowitsch   {
6769566063dSJacob Faibussowitsch     bop()
6779566063dSJacob Faibussowitsch     {
678e8952933SJacob Faibussowitsch       PetscCallCXX(foo()); // ERROR returns PetscErrorCode, cannot be used in constructors
6799566063dSJacob Faibussowitsch     }
6809566063dSJacob Faibussowitsch   };
6819566063dSJacob Faibussowitsch 
682e8952933SJacob Faibussowitsch   // ERROR contains do-while, cannot be used as function-try block
6839566063dSJacob Faibussowitsch   PetscErrorCode qux() PetscCallCXX(
6849566063dSJacob Faibussowitsch     bar();
6859566063dSJacob Faibussowitsch     baz();
6869566063dSJacob Faibussowitsch     foo();
6879566063dSJacob Faibussowitsch     return 0;
6889566063dSJacob Faibussowitsch   )
6899566063dSJacob Faibussowitsch .ve
6909566063dSJacob Faibussowitsch 
69149762cbcSSatish Balay   Level: beginner
69249762cbcSSatish Balay 
693db781477SPatrick Sanan .seealso: `PetscCallThrow()`, `SETERRQ()`, `PetscCall()`, `SETERRABORT()`, `PetscCallAbort()`,
694db781477SPatrick Sanan           `PetscTraceBackErrorHandler()`, `PetscPushErrorHandler()`, `PetscError()`, `CHKMEMQ`
6953f520e80SJunchao Zhang M*/
6969566063dSJacob Faibussowitsch #define PetscCallCXX(...) do {                                  \
6973fcd9f07SJacob Faibussowitsch     try {                                                       \
6983fcd9f07SJacob Faibussowitsch       __VA_ARGS__;                                              \
6993fcd9f07SJacob Faibussowitsch     } catch (const std::exception& e) {                         \
7003fcd9f07SJacob Faibussowitsch       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"%s",e.what());     \
7013fcd9f07SJacob Faibussowitsch     }                                                           \
7023fcd9f07SJacob Faibussowitsch   } while (0)
7033f520e80SJunchao Zhang 
70430de9b25SBarry Smith /*MC
7059566063dSJacob Faibussowitsch   CHKERRCXX - Checks C++ function calls and if they throw an exception, catch it and then
7069566063dSJacob Faibussowitsch   return a PETSc error code
7079566063dSJacob Faibussowitsch 
7089566063dSJacob Faibussowitsch   Synopsis:
7099566063dSJacob Faibussowitsch   #include <petscerror.h>
7109566063dSJacob Faibussowitsch   void CHKERRCXX(func) noexcept;
7119566063dSJacob Faibussowitsch 
7129566063dSJacob Faibussowitsch   Not Collective
7139566063dSJacob Faibussowitsch 
7149566063dSJacob Faibussowitsch   Input Parameter:
7159566063dSJacob Faibussowitsch . func - C++ function calls
7169566063dSJacob Faibussowitsch 
7179566063dSJacob Faibussowitsch   Notes:
7189566063dSJacob Faibussowitsch   Deprecated in favor of PetscCallCXX(). This routine behaves identically to it.
7199566063dSJacob Faibussowitsch 
7209566063dSJacob Faibussowitsch   Level: deprecated
7219566063dSJacob Faibussowitsch 
722db781477SPatrick Sanan .seealso: `PetscCallCXX()`
7239566063dSJacob Faibussowitsch M*/
7249566063dSJacob Faibussowitsch #define CHKERRCXX(...) PetscCallCXX(__VA_ARGS__)
7259566063dSJacob Faibussowitsch 
7269566063dSJacob Faibussowitsch /*MC
72730de9b25SBarry Smith    CHKMEMQ - Checks the memory for corruption, calls error handler if any is detected
72830de9b25SBarry Smith 
72930de9b25SBarry Smith    Synopsis:
730aaa7dc30SBarry Smith    #include <petscsys.h>
73191d3bdf4SKris Buschelman    CHKMEMQ;
73230de9b25SBarry Smith 
733eca87e8dSBarry Smith    Not Collective
734eca87e8dSBarry Smith 
73530de9b25SBarry Smith   Level: beginner
73630de9b25SBarry Smith 
73730de9b25SBarry Smith    Notes:
738a17b96a8SKyle Gerard Felker     We highly recommend using Valgrind https://petsc.org/release/faq/#valgrind or for NVIDIA CUDA systems
7395ed36255SBarry Smith     https://docs.nvidia.com/cuda/cuda-memcheck/index.html for finding memory problems. The ``CHKMEMQ`` macro is useful on systems that
7405ed36255SBarry Smith     do not have valgrind, but is not as good as valgrind or cuda-memcheck.
7411957e957SBarry Smith 
74279dccf82SBarry Smith     Must run with the option -malloc_debug (-malloc_test in debug mode; or if PetscMallocSetDebug() called) to enable this option
74330de9b25SBarry Smith 
74430de9b25SBarry Smith     Once the error handler is called the calling function is then returned from with the given error code.
74530de9b25SBarry Smith 
74630de9b25SBarry Smith     By defaults prints location where memory that is corrupted was allocated.
74730de9b25SBarry Smith 
748f621e05eSBarry Smith     Use CHKMEMA for functions that return void
749f621e05eSBarry Smith 
750db781477SPatrick Sanan .seealso: `PetscTraceBackErrorHandler()`, `PetscPushErrorHandler()`, `PetscError()`, `SETERRQ()`, `PetscMallocValidate()`
75130de9b25SBarry Smith M*/
7526d210af2SJacob Faibussowitsch #if defined(PETSC_CLANG_STATIC_ANALYZER)
753064a246eSJacob Faibussowitsch #define CHKMEMQ
754064a246eSJacob Faibussowitsch #define CHKMEMA
7556d210af2SJacob Faibussowitsch #else
7569566063dSJacob Faibussowitsch #define CHKMEMQ PetscCall(PetscMallocValidate(__LINE__,PETSC_FUNCTION_NAME,__FILE__));
7576d210af2SJacob Faibussowitsch #define CHKMEMA PetscMallocValidate(__LINE__,PETSC_FUNCTION_NAME,__FILE__)
758064a246eSJacob Faibussowitsch #endif
7599566063dSJacob Faibussowitsch 
760668f157eSBarry Smith /*E
761668f157eSBarry Smith   PetscErrorType - passed to the PETSc error handling routines indicating if this is the first or a later call to the error handlers
762668f157eSBarry Smith 
763668f157eSBarry Smith   Level: advanced
764668f157eSBarry Smith 
765d736bfebSBarry Smith   PETSC_ERROR_IN_CXX indicates the error was detected in C++ and an exception should be generated
766d736bfebSBarry Smith 
76795452b02SPatrick Sanan   Developer Notes:
76895452b02SPatrick Sanan     This is currently used to decide when to print the detailed information about the run in PetscTraceBackErrorHandler()
769668f157eSBarry Smith 
770db781477SPatrick Sanan .seealso: `PetscError()`, `SETERRXX()`
771668f157eSBarry Smith E*/
772d736bfebSBarry Smith typedef enum {PETSC_ERROR_INITIAL=0,PETSC_ERROR_REPEAT=1,PETSC_ERROR_IN_CXX = 2} PetscErrorType;
7734b209cf6SBarry Smith 
774eb9e708aSLisandro Dalcin #if defined(__clang_analyzer__)
775eb9e708aSLisandro Dalcin __attribute__((analyzer_noreturn))
776eb9e708aSLisandro Dalcin #endif
777d8e4614bSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscError(MPI_Comm,int,const char*,const char*,PetscErrorCode,PetscErrorType,const char*,...) PETSC_ATTRIBUTE_COLD PETSC_ATTRIBUTE_FORMAT(7,8);
778eb9e708aSLisandro Dalcin 
779014dd563SJed Brown PETSC_EXTERN PetscErrorCode PetscErrorPrintfInitialize(void);
780014dd563SJed Brown PETSC_EXTERN PetscErrorCode PetscErrorMessage(int,const char*[],char **);
781d8e4614bSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscTraceBackErrorHandler(MPI_Comm,int,const char*,const char*,PetscErrorCode,PetscErrorType,const char*,void*) PETSC_ATTRIBUTE_COLD;
782d8e4614bSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscIgnoreErrorHandler(MPI_Comm,int,const char*,const char*,PetscErrorCode,PetscErrorType,const char*,void*) PETSC_ATTRIBUTE_COLD;
783d8e4614bSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscEmacsClientErrorHandler(MPI_Comm,int,const char*,const char*,PetscErrorCode,PetscErrorType,const char*,void*) PETSC_ATTRIBUTE_COLD;
784d8e4614bSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscMPIAbortErrorHandler(MPI_Comm,int,const char*,const char*,PetscErrorCode,PetscErrorType,const char*,void*) PETSC_ATTRIBUTE_COLD;
785d8e4614bSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscAbortErrorHandler(MPI_Comm,int,const char*,const char*,PetscErrorCode,PetscErrorType,const char*,void*) PETSC_ATTRIBUTE_COLD;
786d8e4614bSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscAttachDebuggerErrorHandler(MPI_Comm,int,const char*,const char*,PetscErrorCode,PetscErrorType,const char*,void*) PETSC_ATTRIBUTE_COLD;
787d8e4614bSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscReturnErrorHandler(MPI_Comm,int,const char*,const char*,PetscErrorCode,PetscErrorType,const char*,void*) PETSC_ATTRIBUTE_COLD;
788efca3c55SSatish Balay PETSC_EXTERN PetscErrorCode PetscPushErrorHandler(PetscErrorCode (*handler)(MPI_Comm,int,const char*,const char*,PetscErrorCode,PetscErrorType,const char*,void*),void*);
789014dd563SJed Brown PETSC_EXTERN PetscErrorCode PetscPopErrorHandler(void);
7908d359177SBarry Smith PETSC_EXTERN PetscErrorCode PetscSignalHandlerDefault(int,void*);
791014dd563SJed Brown PETSC_EXTERN PetscErrorCode PetscPushSignalHandler(PetscErrorCode (*)(int,void *),void*);
792014dd563SJed Brown PETSC_EXTERN PetscErrorCode PetscPopSignalHandler(void);
79328559dc8SJed Brown PETSC_EXTERN PetscErrorCode PetscCheckPointerSetIntensity(PetscInt);
794c2a741eeSJunchao Zhang PETSC_EXTERN void PetscSignalSegvCheckPointerOrMpi(void);
7959fbee547SJacob Faibussowitsch PETSC_DEPRECATED_FUNCTION("Use PetscSignalSegvCheckPointerOrMpi() (since version 3.13)") static inline void PetscSignalSegvCheckPointer(void) {PetscSignalSegvCheckPointerOrMpi();}
796329f5518SBarry Smith 
797639ff905SBarry Smith /*MC
798639ff905SBarry Smith     PetscErrorPrintf - Prints error messages.
799639ff905SBarry Smith 
800639ff905SBarry Smith    Synopsis:
801aaa7dc30SBarry Smith     #include <petscsys.h>
802639ff905SBarry Smith      PetscErrorCode (*PetscErrorPrintf)(const char format[],...);
803639ff905SBarry Smith 
804639ff905SBarry Smith     Not Collective
805639ff905SBarry Smith 
806f899ff85SJose E. Roman     Input Parameter:
807639ff905SBarry Smith .   format - the usual printf() format string
808639ff905SBarry Smith 
809639ff905SBarry Smith    Options Database Keys:
8101957e957SBarry Smith +    -error_output_stdout - cause error messages to be printed to stdout instead of the  (default) stderr
811e1bc860dSBarry Smith -    -error_output_none - to turn off all printing of error messages (does not change the way the error is handled.)
812639ff905SBarry Smith 
81395452b02SPatrick Sanan    Notes:
81495452b02SPatrick Sanan     Use
815639ff905SBarry Smith $     PetscErrorPrintf = PetscErrorPrintfNone; to turn off all printing of error messages (does not change the way the
816639ff905SBarry Smith $                        error is handled.) and
8171957e957SBarry Smith $     PetscErrorPrintf = PetscErrorPrintfDefault; to turn it back on or you can use your own function
818639ff905SBarry Smith 
819639ff905SBarry Smith           Use
820639ff905SBarry Smith      PETSC_STDERR = FILE* obtained from a file open etc. to have stderr printed to the file.
821639ff905SBarry Smith      PETSC_STDOUT = FILE* obtained from a file open etc. to have stdout printed to the file.
822639ff905SBarry Smith 
823639ff905SBarry Smith           Use
824639ff905SBarry Smith       PetscPushErrorHandler() to provide your own error handler that determines what kind of messages to print
825639ff905SBarry Smith 
826639ff905SBarry Smith    Level: developer
827639ff905SBarry Smith 
828639ff905SBarry Smith     Fortran Note:
829639ff905SBarry Smith     This routine is not supported in Fortran.
830639ff905SBarry Smith 
831db781477SPatrick Sanan .seealso: `PetscFPrintf()`, `PetscSynchronizedPrintf()`, `PetscHelpPrintf()`, `PetscPrintf()`, `PetscPushErrorHandler()`, `PetscVFPrintf()`, `PetscHelpPrintf()`
832639ff905SBarry Smith M*/
8333ca90d2dSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode (*PetscErrorPrintf)(const char[],...) PETSC_ATTRIBUTE_FORMAT(1,2);
834639ff905SBarry Smith 
835329f5518SBarry Smith typedef enum {PETSC_FP_TRAP_OFF=0,PETSC_FP_TRAP_ON=1} PetscFPTrap;
836014dd563SJed Brown PETSC_EXTERN PetscErrorCode PetscSetFPTrap(PetscFPTrap);
837014dd563SJed Brown PETSC_EXTERN PetscErrorCode PetscFPTrapPush(PetscFPTrap);
838014dd563SJed Brown PETSC_EXTERN PetscErrorCode PetscFPTrapPop(void);
839aba4c478SBarry Smith PETSC_EXTERN PetscErrorCode PetscDetermineInitialFPTrap(void);
84054a8ef01SBarry Smith 
8413a40ed3dSBarry Smith /*
8423a40ed3dSBarry Smith       Allows the code to build a stack frame as it runs
8433a40ed3dSBarry Smith */
8443a40ed3dSBarry Smith 
84527104ee2SJacob Faibussowitsch #if defined(PETSC_USE_DEBUG)
84699cd645aSJed Brown #define PETSCSTACKSIZE 64
8473a40ed3dSBarry Smith typedef struct  {
8480e33f6ddSBarry Smith   const char *function[PETSCSTACKSIZE];
8490e33f6ddSBarry Smith   const char *file[PETSCSTACKSIZE];
850184914b5SBarry Smith         int  line[PETSCSTACKSIZE];
851362febeeSStefano Zampini         int  petscroutine[PETSCSTACKSIZE]; /* 0 external called from petsc, 1 petsc functions, 2 petsc user functions */
852184914b5SBarry Smith         int  currentsize;
853a2f94806SJed Brown         int  hotdepth;
854362febeeSStefano Zampini   PetscBool  check; /* runtime option to check for correct Push/Pop semantics at runtime */
8553a40ed3dSBarry Smith } PetscStack;
85627104ee2SJacob Faibussowitsch PETSC_EXTERN PetscStack petscstack;
85727104ee2SJacob Faibussowitsch #else
85827104ee2SJacob Faibussowitsch typedef struct {
85927104ee2SJacob Faibussowitsch   char Silence_empty_struct_has_size_0_in_C_size_1_in_Cpp;
86027104ee2SJacob Faibussowitsch } PetscStack;
86127104ee2SJacob Faibussowitsch #endif
8623a40ed3dSBarry Smith 
8635d12eec7SSatish Balay #if defined(PETSC_SERIALIZE_FUNCTIONS)
8645d12eec7SSatish Balay #include <petsc/private/petscfptimpl.h>
8655d12eec7SSatish Balay /*
8665d12eec7SSatish Balay    Registers the current function into the global function pointer to function name table
8675d12eec7SSatish Balay 
8685d12eec7SSatish Balay    Have to fix this to handle errors but cannot return error since used in PETSC_VIEWER_DRAW_() etc
8695d12eec7SSatish Balay */
8705d12eec7SSatish Balay #define PetscRegister__FUNCT__() do { \
8715d12eec7SSatish Balay   static PetscBool __chked = PETSC_FALSE; \
8725d12eec7SSatish Balay   if (!__chked) {\
8735d12eec7SSatish Balay   void *ptr; PetscDLSym(NULL,PETSC_FUNCTION_NAME,&ptr);\
8745d12eec7SSatish Balay   __chked = PETSC_TRUE;\
8755d12eec7SSatish Balay   }} while (0)
8765d12eec7SSatish Balay #else
8775d12eec7SSatish Balay #define PetscRegister__FUNCT__()
8785d12eec7SSatish Balay #endif
8795d12eec7SSatish Balay 
8806d210af2SJacob Faibussowitsch #if defined(PETSC_CLANG_STATIC_ANALYZER)
8816d210af2SJacob Faibussowitsch #define PetscStackPushNoCheck(funct,petsc_routine,hot)
8826d210af2SJacob Faibussowitsch #define PetscStackPopNoCheck
8836d210af2SJacob Faibussowitsch #define PetscStackClearTop
8846d210af2SJacob Faibussowitsch #define PetscFunctionBegin
8856d210af2SJacob Faibussowitsch #define PetscFunctionBeginUser
8866d210af2SJacob Faibussowitsch #define PetscFunctionBeginHot
8876d210af2SJacob Faibussowitsch #define PetscFunctionReturn(a)    return a
8886d210af2SJacob Faibussowitsch #define PetscFunctionReturnVoid() return
8896d210af2SJacob Faibussowitsch #define PetscStackPop
8906d210af2SJacob Faibussowitsch #define PetscStackPush(f)
8916d210af2SJacob Faibussowitsch #elif defined(PETSC_USE_DEBUG)
892*5a96b57dSJacob Faibussowitsch #define PetscStackPush_Private(stack__,file__,func__,line__,petsc_routine__,hot__) do { \
893*5a96b57dSJacob Faibussowitsch     if (stack__.currentsize < PETSCSTACKSIZE) {                                         \
894*5a96b57dSJacob Faibussowitsch       stack__.file[stack__.currentsize]         = file__;                               \
895*5a96b57dSJacob Faibussowitsch       stack__.function[stack__.currentsize]     = func__;                               \
896*5a96b57dSJacob Faibussowitsch       stack__.line[stack__.currentsize]         = line__;                               \
897*5a96b57dSJacob Faibussowitsch       stack__.petscroutine[stack__.currentsize] = petsc_routine__;                      \
898*5a96b57dSJacob Faibussowitsch     }                                                                                   \
899*5a96b57dSJacob Faibussowitsch     ++stack__.currentsize;                                                              \
900*5a96b57dSJacob Faibussowitsch     stack__.hotdepth += (hot__ || stack__.hotdepth);                                    \
901*5a96b57dSJacob Faibussowitsch   } while (0)
902*5a96b57dSJacob Faibussowitsch 
903*5a96b57dSJacob Faibussowitsch #define PetscStackPop_Private(stack__,func__) do {                                             \
904*5a96b57dSJacob Faibussowitsch     if (PetscUnlikely(stack__.currentsize <= 0)) {                                             \
905*5a96b57dSJacob Faibussowitsch       if (PetscUnlikely(stack__.check)) {                                                      \
906*5a96b57dSJacob Faibussowitsch         printf("Invalid stack size %d, pop %s\n",stack__.currentsize,func__);                  \
907*5a96b57dSJacob Faibussowitsch       }                                                                                        \
908*5a96b57dSJacob Faibussowitsch     } else {                                                                                   \
909*5a96b57dSJacob Faibussowitsch       if (--stack__.currentsize < PETSCSTACKSIZE) {                                            \
910*5a96b57dSJacob Faibussowitsch         if (PetscUnlikely(                                                                     \
911*5a96b57dSJacob Faibussowitsch               stack__.check                           &&                                       \
912*5a96b57dSJacob Faibussowitsch               stack__.petscroutine[stack__.currentsize] &&                                     \
913*5a96b57dSJacob Faibussowitsch               (stack__.function[stack__.currentsize]    != (const char*)(func__)))) {          \
914*5a96b57dSJacob Faibussowitsch           /* We need this string comparison because "unknown" can be defined in different static strings: */ \
915*5a96b57dSJacob Faibussowitsch           PetscBool _cmpflg;                                                                   \
916*5a96b57dSJacob Faibussowitsch           const char *_funct = stack__.function[stack__.currentsize];                          \
917*5a96b57dSJacob Faibussowitsch           PetscStrcmp(_funct,func__,&_cmpflg);                                                 \
918*5a96b57dSJacob Faibussowitsch           if (!_cmpflg) printf("Invalid stack: push from %s, pop from %s\n",_funct,func__);    \
919*5a96b57dSJacob Faibussowitsch         }                                                                                      \
920*5a96b57dSJacob Faibussowitsch         stack__.function[stack__.currentsize]     = PETSC_NULLPTR;                             \
921*5a96b57dSJacob Faibussowitsch         stack__.file[stack__.currentsize]         = PETSC_NULLPTR;                             \
922*5a96b57dSJacob Faibussowitsch         stack__.line[stack__.currentsize]         = 0;                                         \
923*5a96b57dSJacob Faibussowitsch         stack__.petscroutine[stack__.currentsize] = 0;                                         \
924*5a96b57dSJacob Faibussowitsch       }                                                                                        \
925*5a96b57dSJacob Faibussowitsch       stack__.hotdepth = PetscMax(stack__.hotdepth-1,0);                                       \
926*5a96b57dSJacob Faibussowitsch     }                                                                                          \
927*5a96b57dSJacob Faibussowitsch   } while (0)
928*5a96b57dSJacob Faibussowitsch 
929441dd030SJed Brown /* Stack handling is based on the following two "NoCheck" macros.  These should only be called directly by other error
930441dd030SJed Brown  * handling macros.  We record the line of the call, which may or may not be the location of the definition.  But is at
931441dd030SJed Brown  * least more useful than "unknown" because it can distinguish multiple calls from the same function.
932441dd030SJed Brown  */
93327104ee2SJacob Faibussowitsch #define PetscStackPushNoCheck(funct,petsc_routine,hot) do {                             \
934e04113cfSBarry Smith     PetscStackSAWsTakeAccess();                                                         \
935*5a96b57dSJacob Faibussowitsch     PetscStackPush_Private(petscstack,__FILE__,funct,__LINE__,petsc_routine,hot);       \
936e04113cfSBarry Smith     PetscStackSAWsGrantAccess();                                                        \
937441dd030SJed Brown   } while (0)
938441dd030SJed Brown 
93927104ee2SJacob Faibussowitsch #define PetscStackPopNoCheck(funct)                    do {     \
940362febeeSStefano Zampini     PetscStackSAWsTakeAccess();                                 \
941*5a96b57dSJacob Faibussowitsch     PetscStackPop_Private(petscstack,funct);                    \
942362febeeSStefano Zampini     PetscStackSAWsGrantAccess();                                \
943362febeeSStefano Zampini   } while (0)
944362febeeSStefano Zampini 
94527104ee2SJacob Faibussowitsch #define PetscStackClearTop                             do {             \
946e04113cfSBarry Smith     PetscStackSAWsTakeAccess();                                         \
9471724198aSStefano Zampini     if (petscstack.currentsize > 0 &&                                   \
9481724198aSStefano Zampini         --petscstack.currentsize < PETSCSTACKSIZE) {                    \
94927104ee2SJacob Faibussowitsch       petscstack.function[petscstack.currentsize]     = PETSC_NULLPTR;  \
95027104ee2SJacob Faibussowitsch       petscstack.file[petscstack.currentsize]         = PETSC_NULLPTR;  \
95127104ee2SJacob Faibussowitsch       petscstack.line[petscstack.currentsize]         = 0;              \
95227104ee2SJacob Faibussowitsch       petscstack.petscroutine[petscstack.currentsize] = 0;              \
953441dd030SJed Brown     }                                                                   \
95427104ee2SJacob Faibussowitsch     petscstack.hotdepth = PetscMax(petscstack.hotdepth-1,0);            \
955e04113cfSBarry Smith     PetscStackSAWsGrantAccess();                                        \
956441dd030SJed Brown   } while (0)
957441dd030SJed Brown 
95830de9b25SBarry Smith /*MC
9591957e957SBarry Smith    PetscFunctionBegin - First executable line of each PETSc function,  used for error handling. Final
9601957e957SBarry Smith       line of PETSc functions should be PetscFunctionReturn(0);
96130de9b25SBarry Smith 
96230de9b25SBarry Smith    Synopsis:
963aaa7dc30SBarry Smith    #include <petscsys.h>
96430de9b25SBarry Smith    void PetscFunctionBegin;
96530de9b25SBarry Smith 
966eca87e8dSBarry Smith    Not Collective
967eca87e8dSBarry Smith 
96830de9b25SBarry Smith    Usage:
96930de9b25SBarry Smith .vb
97030de9b25SBarry Smith      int something;
97130de9b25SBarry Smith 
97230de9b25SBarry Smith      PetscFunctionBegin;
97330de9b25SBarry Smith .ve
97430de9b25SBarry Smith 
97530de9b25SBarry Smith    Notes:
9761957e957SBarry Smith      Use PetscFunctionBeginUser for application codes.
9771957e957SBarry Smith 
97830de9b25SBarry Smith      Not available in Fortran
97930de9b25SBarry Smith 
98030de9b25SBarry Smith    Level: developer
98130de9b25SBarry Smith 
982db781477SPatrick Sanan .seealso: `PetscFunctionReturn()`, `PetscFunctionBeginHot()`, `PetscFunctionBeginUser()`
98330de9b25SBarry Smith 
98430de9b25SBarry Smith M*/
985441dd030SJed Brown #define PetscFunctionBegin do {                               \
986362febeeSStefano Zampini     PetscStackPushNoCheck(PETSC_FUNCTION_NAME,1,PETSC_FALSE); \
987a2f94806SJed Brown     PetscRegister__FUNCT__();                                 \
988a2f94806SJed Brown   } while (0)
989a2f94806SJed Brown 
990a2f94806SJed Brown /*MC
991a2f94806SJed Brown    PetscFunctionBeginHot - Substitute for PetscFunctionBegin to be used in functions that are called in
992a2f94806SJed Brown    performance-critical circumstances.  Use of this function allows for lighter profiling by default.
993a2f94806SJed Brown 
994a2f94806SJed Brown    Synopsis:
995aaa7dc30SBarry Smith    #include <petscsys.h>
996a2f94806SJed Brown    void PetscFunctionBeginHot;
997a2f94806SJed Brown 
998a2f94806SJed Brown    Not Collective
999a2f94806SJed Brown 
1000a2f94806SJed Brown    Usage:
1001a2f94806SJed Brown .vb
1002a2f94806SJed Brown      int something;
1003a2f94806SJed Brown 
1004a2f94806SJed Brown      PetscFunctionBeginHot;
1005a2f94806SJed Brown .ve
1006a2f94806SJed Brown 
1007a2f94806SJed Brown    Notes:
1008a2f94806SJed Brown      Not available in Fortran
1009a2f94806SJed Brown 
1010a2f94806SJed Brown    Level: developer
1011a2f94806SJed Brown 
1012db781477SPatrick Sanan .seealso: `PetscFunctionBegin`, `PetscFunctionReturn()`
1013a2f94806SJed Brown 
1014a2f94806SJed Brown M*/
1015a2f94806SJed Brown #define PetscFunctionBeginHot do {                           \
1016362febeeSStefano Zampini     PetscStackPushNoCheck(PETSC_FUNCTION_NAME,1,PETSC_TRUE); \
10172d53ad75SBarry Smith     PetscRegister__FUNCT__();                                \
101853c77d0aSJed Brown   } while (0)
101953c77d0aSJed Brown 
1020a8d2bbe5SBarry Smith /*MC
1021a8d2bbe5SBarry Smith    PetscFunctionBeginUser - First executable line of user provided PETSc routine
1022a8d2bbe5SBarry Smith 
1023a8d2bbe5SBarry Smith    Synopsis:
1024aaa7dc30SBarry Smith    #include <petscsys.h>
1025a8d2bbe5SBarry Smith    void PetscFunctionBeginUser;
1026a8d2bbe5SBarry Smith 
1027a8d2bbe5SBarry Smith    Not Collective
1028a8d2bbe5SBarry Smith 
1029a8d2bbe5SBarry Smith    Usage:
1030a8d2bbe5SBarry Smith .vb
1031a8d2bbe5SBarry Smith      int something;
1032a8d2bbe5SBarry Smith 
1033ac285190SBarry Smith      PetscFunctionBeginUser;
1034a8d2bbe5SBarry Smith .ve
1035a8d2bbe5SBarry Smith 
1036a8d2bbe5SBarry Smith    Notes:
10371957e957SBarry Smith       Final line of PETSc functions should be PetscFunctionReturn(0) except for main().
10381957e957SBarry Smith 
1039a8d2bbe5SBarry Smith       Not available in Fortran
1040a8d2bbe5SBarry Smith 
1041ac285190SBarry Smith       This is identical to PetscFunctionBegin except it labels the routine as a user
1042ac285190SBarry Smith       routine instead of as a PETSc library routine.
1043ac285190SBarry Smith 
1044a2f94806SJed Brown    Level: intermediate
1045a8d2bbe5SBarry Smith 
1046db781477SPatrick Sanan .seealso: `PetscFunctionReturn()`, `PetscFunctionBegin`, `PetscFunctionBeginHot`
1047a8d2bbe5SBarry Smith 
1048a8d2bbe5SBarry Smith M*/
104927104ee2SJacob Faibussowitsch #define PetscFunctionBeginUser do {                           \
1050362febeeSStefano Zampini     PetscStackPushNoCheck(PETSC_FUNCTION_NAME,2,PETSC_FALSE); \
1051a8d2bbe5SBarry Smith     PetscRegister__FUNCT__();                                 \
1052a8d2bbe5SBarry Smith   } while (0)
1053a8d2bbe5SBarry Smith 
105427104ee2SJacob Faibussowitsch #define PetscStackPush(n)       do {        \
1055362febeeSStefano Zampini     PetscStackPushNoCheck(n,0,PETSC_FALSE); \
105615681b3cSBarry Smith     CHKMEMQ;                                \
105715681b3cSBarry Smith   } while (0)
10583a40ed3dSBarry Smith 
105927104ee2SJacob Faibussowitsch #define PetscStackPop           do {             \
1060441dd030SJed Brown       CHKMEMQ;                                   \
1061362febeeSStefano Zampini       PetscStackPopNoCheck(PETSC_FUNCTION_NAME); \
106215681b3cSBarry Smith     } while (0)
1063d64ed03dSBarry Smith 
106430de9b25SBarry Smith /*MC
106530de9b25SBarry Smith    PetscFunctionReturn - Last executable line of each PETSc function
106630de9b25SBarry Smith         used for error handling. Replaces return()
106730de9b25SBarry Smith 
106830de9b25SBarry Smith    Synopsis:
1069aaa7dc30SBarry Smith    #include <petscsys.h>
107030de9b25SBarry Smith    void PetscFunctionReturn(0);
107130de9b25SBarry Smith 
1072eca87e8dSBarry Smith    Not Collective
1073eca87e8dSBarry Smith 
107430de9b25SBarry Smith    Usage:
107530de9b25SBarry Smith .vb
107630de9b25SBarry Smith     ....
107730de9b25SBarry Smith      PetscFunctionReturn(0);
107830de9b25SBarry Smith    }
107930de9b25SBarry Smith .ve
108030de9b25SBarry Smith 
108130de9b25SBarry Smith    Notes:
108230de9b25SBarry Smith      Not available in Fortran
108330de9b25SBarry Smith 
108430de9b25SBarry Smith    Level: developer
108530de9b25SBarry Smith 
1086db781477SPatrick Sanan .seealso: `PetscFunctionBegin()`
108730de9b25SBarry Smith 
108830de9b25SBarry Smith M*/
108927104ee2SJacob Faibussowitsch #define PetscFunctionReturn(a)    do {          \
1090362febeeSStefano Zampini     PetscStackPopNoCheck(PETSC_FUNCTION_NAME);  \
109127104ee2SJacob Faibussowitsch     return a;                                   \
109227104ee2SJacob Faibussowitsch   } while (0)
1093d64ed03dSBarry Smith 
109427104ee2SJacob Faibussowitsch #define PetscFunctionReturnVoid() do {          \
1095362febeeSStefano Zampini     PetscStackPopNoCheck(PETSC_FUNCTION_NAME);  \
109627104ee2SJacob Faibussowitsch     return;                                     \
109727104ee2SJacob Faibussowitsch   } while (0)
109827104ee2SJacob Faibussowitsch #else /* PETSC_USE_DEBUG */
109927104ee2SJacob Faibussowitsch #define PetscStackPushNoCheck(funct,petsc_routine,hot)
110027104ee2SJacob Faibussowitsch #define PetscStackPopNoCheck
110127104ee2SJacob Faibussowitsch #define PetscStackClearTop
11023a40ed3dSBarry Smith #define PetscFunctionBegin
11030bdf7c52SPeter Brune #define PetscFunctionBeginUser
1104a2f94806SJed Brown #define PetscFunctionBeginHot
110527104ee2SJacob Faibussowitsch #define PetscFunctionReturn(a)    return a
11065665465eSBarry Smith #define PetscFunctionReturnVoid() return
1107812af9f3SBarry Smith #define PetscStackPop             CHKMEMQ
1108812af9f3SBarry Smith #define PetscStackPush(f)         CHKMEMQ
110927104ee2SJacob Faibussowitsch #endif /* PETSC_USE_DEBUG */
11103a40ed3dSBarry Smith 
11116d210af2SJacob Faibussowitsch #if defined(PETSC_CLANG_STATIC_ANALYZER)
11126d210af2SJacob Faibussowitsch #define PetscStackCall(name,routine)
11135f80ce2aSJacob Faibussowitsch #define PetscStackCallStandard(func,...)
11146d210af2SJacob Faibussowitsch #else
1115eb6b5d47SBarry Smith /*
1116eb6b5d47SBarry Smith     PetscStackCall - Calls an external library routine or user function after pushing the name of the routine on the stack.
1117eb6b5d47SBarry Smith 
1118eb6b5d47SBarry Smith    Input Parameters:
1119eb6b5d47SBarry Smith +   name - string that gives the name of the function being called
11209566063dSJacob Faibussowitsch -   routine - actual call to the routine, including ierr = and PetscCall(ierr);
1121fd3f9acdSBarry Smith 
1122dbf62e16SBarry Smith    Note: Often one should use PetscStackCallStandard() instead. This routine is intended for external library routines that DO NOT return error codes
1123eb6b5d47SBarry Smith 
1124eb6b5d47SBarry Smith    Developer Note: this is so that when a user or external library routine results in a crash or corrupts memory, they get blamed instead of PETSc.
1125eb6b5d47SBarry Smith 
1126eb6b5d47SBarry Smith */
112730ecc5abSKarl Rupp #define PetscStackCall(name,routine) do { PetscStackPush(name);routine;PetscStackPop; } while (0)
1128eb6b5d47SBarry Smith 
1129fd3f9acdSBarry Smith /*
1130fd3f9acdSBarry Smith     PetscStackCallStandard - Calls an external library routine after pushing the name of the routine on the stack.
1131fd3f9acdSBarry Smith 
1132fd3f9acdSBarry Smith    Input Parameters:
1133fd3f9acdSBarry Smith +   func-  name of the routine
1134fd3f9acdSBarry Smith -   args - arguments to the routine surrounded by ()
1135fd3f9acdSBarry Smith 
113695452b02SPatrick Sanan    Notes:
113795452b02SPatrick Sanan     This is intended for external package routines that return error codes. Use PetscStackCall() for those that do not.
1138dbf62e16SBarry Smith 
1139dbf62e16SBarry Smith    Developer Note: this is so that when an external packge routine results in a crash or corrupts memory, they get blamed instead of PETSc.
1140fd3f9acdSBarry Smith 
1141fd3f9acdSBarry Smith */
1142a74df02fSJacob Faibussowitsch #define PetscStackCallStandard(func,...) do {                                                  \
1143a74df02fSJacob Faibussowitsch     PetscStackPush(PetscStringize(func));                                                      \
1144a74df02fSJacob Faibussowitsch     PetscErrorCode __ierr = func(__VA_ARGS__);                                                 \
11451d4906efSStefano Zampini     PetscStackPop;                                                                             \
114632771afcSJacob Faibussowitsch     PetscCheck(!__ierr,PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in %s(): error code %d",PetscStringize(func),__ierr); \
1147fd3f9acdSBarry Smith   } while (0)
11486d210af2SJacob Faibussowitsch #endif /* PETSC_CLANG_STATIC_ANALYZER */
114906d1fe2cSBarry Smith 
115006d1fe2cSBarry Smith #endif
1151