xref: /petsc/include/petscerror.h (revision 3fcd9f0735ebaf560729e13fbf6cfafba2c1e8d0)
1 /*
2     Contains all error handling interfaces for PETSc.
3 */
4 #if !defined(PETSCERROR_H)
5 #define PETSCERROR_H
6 
7 #include <petscmacros.h>
8 #include <petscsystypes.h>
9 
10 /*
11      These are the generic error codes. These error codes are used
12      many different places in the PETSc source code. The string versions are
13      at src/sys/error/err.c any changes here must also be made there
14      These are also define in src/sys/f90-mod/petscerror.h any CHANGES here
15      must be also made there.
16 
17 */
18 #define PETSC_ERR_MIN_VALUE        54   /* should always be one less then the smallest value */
19 
20 #define PETSC_ERR_MEM              55   /* unable to allocate requested memory */
21 #define PETSC_ERR_SUP              56   /* no support for requested operation */
22 #define PETSC_ERR_SUP_SYS          57   /* no support for requested operation on this computer system */
23 #define PETSC_ERR_ORDER            58   /* operation done in wrong order */
24 #define PETSC_ERR_SIG              59   /* signal received */
25 #define PETSC_ERR_FP               72   /* floating point exception */
26 #define PETSC_ERR_COR              74   /* corrupted PETSc object */
27 #define PETSC_ERR_LIB              76   /* error in library called by PETSc */
28 #define PETSC_ERR_PLIB             77   /* PETSc library generated inconsistent data */
29 #define PETSC_ERR_MEMC             78   /* memory corruption */
30 #define PETSC_ERR_CONV_FAILED      82   /* iterative method (KSP or SNES) failed */
31 #define PETSC_ERR_USER             83   /* user has not provided needed function */
32 #define PETSC_ERR_SYS              88   /* error in system call */
33 #define PETSC_ERR_POINTER          70   /* pointer does not point to valid address */
34 #define PETSC_ERR_MPI_LIB_INCOMP   87   /* MPI library at runtime is not compatible with MPI user compiled with */
35 
36 #define PETSC_ERR_ARG_SIZ          60   /* nonconforming object sizes used in operation */
37 #define PETSC_ERR_ARG_IDN          61   /* two arguments not allowed to be the same */
38 #define PETSC_ERR_ARG_WRONG        62   /* wrong argument (but object probably ok) */
39 #define PETSC_ERR_ARG_CORRUPT      64   /* null or corrupted PETSc object as argument */
40 #define PETSC_ERR_ARG_OUTOFRANGE   63   /* input argument, out of range */
41 #define PETSC_ERR_ARG_BADPTR       68   /* invalid pointer argument */
42 #define PETSC_ERR_ARG_NOTSAMETYPE  69   /* two args must be same object type */
43 #define PETSC_ERR_ARG_NOTSAMECOMM  80   /* two args must be same communicators */
44 #define PETSC_ERR_ARG_WRONGSTATE   73   /* object in argument is in wrong state, e.g. unassembled mat */
45 #define PETSC_ERR_ARG_TYPENOTSET   89   /* the type of the object has not yet been set */
46 #define PETSC_ERR_ARG_INCOMP       75   /* two arguments are incompatible */
47 #define PETSC_ERR_ARG_NULL         85   /* argument is null that should not be */
48 #define PETSC_ERR_ARG_UNKNOWN_TYPE 86   /* type name doesn't match any registered type */
49 
50 #define PETSC_ERR_FILE_OPEN        65   /* unable to open file */
51 #define PETSC_ERR_FILE_READ        66   /* unable to read from file */
52 #define PETSC_ERR_FILE_WRITE       67   /* unable to write to file */
53 #define PETSC_ERR_FILE_UNEXPECTED  79   /* unexpected data in file */
54 
55 #define PETSC_ERR_MAT_LU_ZRPVT     71   /* detected a zero pivot during LU factorization */
56 #define PETSC_ERR_MAT_CH_ZRPVT     81   /* detected a zero pivot during Cholesky factorization */
57 
58 #define PETSC_ERR_INT_OVERFLOW     84
59 
60 #define PETSC_ERR_FLOP_COUNT       90
61 #define PETSC_ERR_NOT_CONVERGED    91  /* solver did not converge */
62 #define PETSC_ERR_MISSING_FACTOR   92  /* MatGetFactor() failed */
63 #define PETSC_ERR_OPT_OVERWRITE    93  /* attempted to over write options which should not be changed */
64 #define PETSC_ERR_WRONG_MPI_SIZE   94  /* example/application run with number of MPI ranks it does not support */
65 #define PETSC_ERR_USER_INPUT       95  /* missing or incorrect user input */
66 #define PETSC_ERR_GPU_RESOURCE     96  /* unable to load a GPU resource, for example cuBLAS */
67 #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 */
68 #define PETSC_ERR_MPI              98  /* general MPI error */
69 #define PETSC_ERR_MAX_VALUE        99  /* this is always the one more than the largest error code */
70 
71 #define SETERRQ1(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
72 #define SETERRQ2(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
73 #define SETERRQ3(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
74 #define SETERRQ4(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
75 #define SETERRQ5(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
76 #define SETERRQ6(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
77 #define SETERRQ7(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
78 #define SETERRQ8(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
79 #define SETERRQ9(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
80 
81 /*MC
82    SETERRQ - Macro to be called when an error has been detected,
83 
84    Synopsis:
85    #include <petscsys.h>
86    PetscErrorCode SETERRQ(MPI_Comm comm,PetscErrorCode ierr,char *message,...)
87 
88    Collective
89 
90    Input Parameters:
91 +  comm - A communicator, use PETSC_COMM_SELF unless you know all ranks of another communicator will detect the error
92 .  ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
93 -  message - error message
94 
95   Level: beginner
96 
97    Notes:
98     Once the error handler is called the calling function is then returned from with the given error code.
99 
100     Experienced users can set the error handler with PetscPushErrorHandler().
101 
102    Fortran Notes:
103       SETERRQ() may be called from Fortran subroutines but SETERRA() must be called from the
104       Fortran main program.
105 
106 .seealso: PetscCheck(), PetscAssert(), PetscTraceBackErrorHandler(), PetscPushErrorHandler(),
107 PetscError(), CHKERRQ(), CHKMEMQ, CHKERRA(), CHKERRMPI()
108 M*/
109 #define SETERRQ(comm,ierr,...) return PetscError(comm,__LINE__,PETSC_FUNCTION_NAME,__FILE__,ierr,PETSC_ERROR_INITIAL,__VA_ARGS__)
110 
111 /*
112     Returned from PETSc functions that are called from MPI, such as related to attributes
113       Do not confuse PETSC_MPI_ERROR_CODE and PETSC_ERR_MPI, the first is registered with MPI and returned to MPI as
114       an error code, the latter is a regular PETSc error code passed within PETSc code indicating an error was detected in an MPI call.
115 */
116 PETSC_EXTERN PetscMPIInt PETSC_MPI_ERROR_CLASS;
117 PETSC_EXTERN PetscMPIInt PETSC_MPI_ERROR_CODE;
118 
119 /*MC
120    SETERRMPI - Macro to be called when an error has been detected within an MPI callback function
121 
122    Synopsis:
123    #include <petscsys.h>
124    PetscErrorCode SETERRMPI(MPI_Comm comm,PetscErrorCode ierr,char *message,...)
125 
126    Collective
127 
128    Input Parameters:
129 +  comm - A communicator, use PETSC_COMM_SELF unless you know all ranks of another communicator will detect the error
130 .  ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
131 -  message - error message
132 
133   Level: developer
134 
135    Notes:
136     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
137     which is registered with MPI_Add_error_code() when PETSc is initialized.
138 
139 .seealso: SETERRQ(), CHKERRQ(), CHKERRMPI(), PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), CHKMEMQ
140 M*/
141 #define SETERRMPI(comm,ierr,...) return (PetscError(comm,__LINE__,PETSC_FUNCTION_NAME,__FILE__,ierr,PETSC_ERROR_INITIAL,__VA_ARGS__),PETSC_MPI_ERROR_CODE)
142 
143 /*MC
144    SETERRA - Fortran-only macro that can be called when an error has been detected from the main program
145 
146    Synopsis:
147    #include <petscsys.h>
148    PetscErrorCode SETERRA(MPI_Comm comm,PetscErrorCode ierr,char *message)
149 
150    Collective
151 
152    Input Parameters:
153 +  comm - A communicator, so that the error can be collective
154 .  ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
155 -  message - error message in the printf format
156 
157   Level: beginner
158 
159    Notes:
160     This should only be used with Fortran. With C/C++, use SETERRQ().
161 
162    Fortran Notes:
163       SETERRQ() may be called from Fortran subroutines but SETERRA() must be called from the
164       Fortran main program.
165 
166 .seealso: SETERRQ(), SETERRABORT(), CHKERRQ(), CHKERRA(), CHKERRABORT()
167 M*/
168 
169 /*MC
170    SETERRABORT - Macro that can be called when an error has been detected,
171 
172    Synopsis:
173    #include <petscsys.h>
174    PetscErrorCode SETERRABORT(MPI_Comm comm,PetscErrorCode ierr,char *message,...)
175 
176    Collective
177 
178    Input Parameters:
179 +  comm - A communicator, so that the error can be collective
180 .  ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
181 -  message - error message in the printf format
182 
183   Level: beginner
184 
185    Notes:
186     This function just calls MPI_Abort().
187 
188 .seealso: SETERRQ(), PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), CHKERRQ(), CHKMEMQ
189 M*/
190 #define SETERRABORT(comm,ierr,...) do {                                                        \
191     PetscError(comm,__LINE__,PETSC_FUNCTION_NAME,__FILE__,ierr,PETSC_ERROR_INITIAL,__VA_ARGS__); \
192     MPI_Abort(comm,ierr);                                                                      \
193   } while (0)
194 
195 /*MC
196   PetscCheck - Check that a particular condition is true
197 
198   Synopsis:
199   #include <petscerror.h>
200   void PetscCheck(bool cond, MPI_Comm comm, PetscErrorCode ierr, const char *message, ...)
201 
202   Collective
203 
204   Input Parameters:
205 + cond    - The boolean condition
206 . comm    - The communicator on which the check can be collective on
207 . ierr    - A nonzero error code, see include/petscerror.h for the complete list
208 - message - Error message in printf format
209 
210   Notes:
211   Enabled in both optimized and debug builds.
212 
213   Calls SETERRQ() if the assertion fails, so can only be called from functions returning a
214   PetscErrorCode (or equivalent type after conversion).
215 
216   Level: beginner
217 
218 .seealso: PetscAssert(), SETERRQ(), PetscError(), CHKERRQ()
219 MC*/
220 #define PetscCheck(cond,comm,ierr,...) if (PetscUnlikely(!(cond))) SETERRQ(comm,ierr,__VA_ARGS__)
221 
222 /*MC
223   PetscCheckFalse - Check that a particular condition is false
224 
225   Synopsis:
226   #include <petscerror.h>
227   void PetscCheckFalse(bool cond, MPI_Comm comm, PetscErrorCode ierr, const char *message, ...)
228 
229   Collective
230 
231   Input Parameters:
232 + cond    - The boolean condition
233 . comm    - The communicator on which the check can be collective on
234 . ierr    - A nonzero error code, see include/petscerror.h for the complete list
235 - message - Error message in printf format
236 
237   Notes:
238   Invert your boolean condition and use PetscCheck() instead. This macro is a temporary stopgap
239   to converting to PetscCheck() and is subject to removal without deprecation in a future
240   release.
241 
242   Level: deprecated
243 
244 .seealso: PetscCheck()
245 MC*/
246 #define PetscCheckFalse(cond,comm,ierr,...) PetscCheck(!(cond),comm,ierr,__VA_ARGS__)
247 
248 /*MC
249   PetscAssert - Assert that a particular condition is true
250 
251   Synopsis:
252   #include <petscerror.h>
253   void PetscAssert(bool cond, MPI_Comm comm, PetscErrorCode ierr, const char *message, ...)
254 
255   Collective
256 
257   Input Parameters:
258 + cond    - The boolean condition
259 . comm    - The communicator on which the check can be collective on
260 . ierr    - A nonzero error code, see include/petscerror.h for the complete list
261 - message - Error message in printf format
262 
263   Notes:
264   Enabled only in debug builds. Note that any arguments to this macros are still visible to the
265   compiler optimized builds (so must still contain valid code) but are guaranteed to not be
266   executed.
267 
268   See PetscCheck() for usage and behaviour.
269 
270   Level: beginner
271 
272 .seealso: PetscCheck(), SETERRQ(), PetscError()
273 MC*/
274 #define PetscAssert(cond,comm,ierr,...) if (PetscUnlikelyDebug(!(cond))) SETERRQ(comm,ierr,__VA_ARGS__)
275 
276 /*MC
277    CHKERRQ - Checks error code returned from PETSc function, if non-zero it calls the error handler and then returns. Use CHKERRMPI() for checking errors from MPI calls
278 
279    Synopsis:
280    #include <petscsys.h>
281    PetscErrorCode CHKERRQ(PetscErrorCode ierr)
282 
283    Not Collective
284 
285    Input Parameters:
286 .  ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
287 
288   Level: beginner
289 
290    Notes:
291     Once the error handler is called the calling function is then returned from with the given error code.
292 
293     Experienced users can set the error handler with PetscPushErrorHandler().
294 
295     CHKERRQ(ierr) is fundamentally a macro replacement for
296          if (ierr) return(PetscError(...,ierr,...));
297 
298     Although typical usage resembles "void CHKERRQ(PetscErrorCode)" as described above, for certain uses it is
299     highly inappropriate to use it in this manner as it invokes return(PetscErrorCode). In particular,
300     it cannot be used in functions which return(void) or any other datatype.  In these types of functions,
301     you can use CHKERRV() which returns without an error code (bad idea since the error is ignored or
302          if (ierr) {PetscError(....); return(YourReturnType);}
303     where you may pass back a NULL to indicate an error. You can also call CHKERRABORT(comm,n) to have
304     MPI_Abort() returned immediately.
305 
306    Fortran Notes:
307       CHKERRQ() may be called from Fortran subroutines but CHKERRA() must be called from the
308       Fortran main program.
309 
310 .seealso: SETERRQ(), PetscCheck(), PetscAssert(), PetscTraceBackErrorHandler(),
311 PetscPushErrorHandler(), PetscError(), CHKMEMQ, CHKERRA()
312 M*/
313 #if defined(PETSC_CLANG_STATIC_ANALYZER)
314 void CHKERRQ(PetscErrorCode);
315 void CHKERRV(PetscErrorCode);
316 #else
317 #define CHKERRQ(...) do {                                                                      \
318     PetscErrorCode ierr_q_ = __VA_ARGS__;                                                      \
319     if (PetscUnlikely(ierr_q_)) return PetscError(PETSC_COMM_SELF,__LINE__,PETSC_FUNCTION_NAME,__FILE__,ierr_q_,PETSC_ERROR_REPEAT," "); \
320   } while (0)
321 #define CHKERRV(...) do {                                                                      \
322     PetscErrorCode ierr_void_ = __VA_ARGS__;                                                   \
323     if (PetscUnlikely(ierr_void_)) {                                                           \
324       PetscError(PETSC_COMM_SELF,__LINE__,PETSC_FUNCTION_NAME,__FILE__,ierr_void_,PETSC_ERROR_REPEAT," "); \
325       return;                                                                                  \
326     }                                                                                          \
327   } while (0)
328 #endif
329 
330 /*MC
331    CHKERRA - Fortran-only replacement for CHKERRQ in the main program, which aborts immediately
332 
333    Synopsis:
334    #include <petscsys.h>
335    PetscErrorCode CHKERRA(PetscErrorCode ierr)
336 
337    Not Collective
338 
339    Input Parameters:
340 .  ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
341 
342   Level: beginner
343 
344    Notes:
345       This should only be used with Fortran. With C/C++, use CHKERRQ() in normal usage,
346       or CHKERRABORT() if wanting to abort immediately on error.
347 
348    Fortran Notes:
349       CHKERRQ() may be called from Fortran subroutines but CHKERRA() must be called from the
350       Fortran main program.
351 
352 .seealso: CHKERRQ(), CHKERRABORT(), SETERRA(), SETERRQ(), SETERRABORT()
353 M*/
354 
355 /*MC
356    CHKERRABORT - Checks error code returned from PETSc function. If non-zero it aborts immediately.
357 
358    Synopsis:
359    #include <petscsys.h>
360    PetscErrorCode CHKERRABORT(MPI_Comm comm,PetscErrorCode ierr)
361 
362    Not Collective
363 
364    Input Parameters:
365 .  ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
366 
367   Level: intermediate
368 
369 .seealso: SETERRABORT(), PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), SETERRQ(), CHKMEMQ, CHKERRMPI()
370 M*/
371 #if defined(PETSC_CLANG_STATIC_ANALYZER)
372 void CHKERRABORT(MPI_Comm,PetscErrorCode);
373 void CHKERRCONTINUE(PetscErrorCode);
374 #else
375 #define CHKERRABORT(comm,...) do {                                                             \
376     PetscErrorCode ierr_abort_ = __VA_ARGS__;                                                  \
377     if (PetscUnlikely(ierr_abort_)) {                                                          \
378       PetscError(PETSC_COMM_SELF,__LINE__,PETSC_FUNCTION_NAME,__FILE__,ierr_abort_,PETSC_ERROR_REPEAT," "); \
379       MPI_Abort(comm,ierr_abort_);                                                             \
380     }                                                                                          \
381   } while (0)
382 #define CHKERRCONTINUE(...)   do {                                                             \
383     PetscErrorCode ierr_continue_ = __VA_ARGS__;                                               \
384     if (PetscUnlikely(ierr_continue_)) PetscError(PETSC_COMM_SELF,__LINE__,PETSC_FUNCTION_NAME,__FILE__,ierr_continue_,PETSC_ERROR_REPEAT," "); \
385   } while (0)
386 #endif
387 
388 PETSC_EXTERN PetscErrorCode PetscAbortFindSourceFile_Private(const char*,PetscInt*);
389 PETSC_EXTERN PetscBool petscwaitonerrorflg;
390 PETSC_EXTERN PetscBool petscindebugger;
391 
392 /*MC
393    PETSCABORT - Call MPI_Abort with an informative error code
394 
395    Synopsis:
396    #include <petscsys.h>
397    PETSCABORT(MPI_Comm comm, PetscErrorCode ierr)
398 
399    Collective
400 
401    Input Parameters:
402 +  comm - A communicator, so that the error can be collective
403 -  ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
404 
405    Level: advanced
406 
407    Notes:
408    We pass MPI_Abort() an error code of format XX_YYYY_ZZZ, where XX, YYYY are an index and line number of the file
409    where PETSCABORT is called, respectively. ZZZ is the PETSc error code.
410 
411    If XX is zero, this means that the call was made in the routine main().
412    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[]
413      is out of date. PETSc developers have to update it.
414    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.
415 
416    If the option -start_in_debugger was used then this calls abort() to stop the program in the debugger.
417 
418  M*/
419 #define PETSCABORT(comm,...) do {                                                              \
420     if (petscwaitonerrorflg) PetscSleep(1000);                                                 \
421     if (petscindebugger) abort();                                                              \
422     else {                                                                                     \
423       PetscErrorCode ierr_petsc_abort_ = __VA_ARGS__;                                          \
424       PetscInt       idx = 0;                                                                  \
425       PetscAbortFindSourceFile_Private(__FILE__,&idx);                                         \
426       MPI_Abort(comm,(PetscMPIInt)(0*idx*10000000 + 0*__LINE__*1000 + ierr_petsc_abort_));     \
427     }                                                                                          \
428   } while (0)
429 
430 /*MC
431    CHKERRMPI - Checks error code returned from MPI calls, if non-zero it calls the error handler and then returns
432 
433    Synopsis:
434    #include <petscsys.h>
435    PetscErrorCode CHKERRMPI(PetscErrorCode ierr)
436 
437    Not Collective
438 
439    Input Parameters:
440 .  ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
441 
442   Level: intermediate
443 
444    Notes:
445     Always returns the error code PETSC_ERR_MPI; the MPI error code and string are embedded in the string error message
446 
447 .seealso: SETERRMPI(), CHKERRQ(), SETERRQ(), SETERRABORT(), CHKERRABORT(), PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), CHKMEMQ
448 M*/
449 #if defined(PETSC_CLANG_STATIC_ANALYZER)
450 void CHKERRMPI(PetscErrorCode);
451 #else
452 #define CHKERRMPI(...) \
453 do { \
454   PetscErrorCode _7_errorcode = __VA_ARGS__; \
455   if (PetscUnlikely(_7_errorcode)) { \
456     char _7_errorstring[MPI_MAX_ERROR_STRING]; \
457     PetscMPIInt _7_resultlen; \
458     MPI_Error_string(_7_errorcode,(char*)_7_errorstring,&_7_resultlen); (void)_7_resultlen; \
459     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MPI,"MPI error %d %s",(int)_7_errorcode,_7_errorstring); \
460   } \
461 } while (0)
462 #endif
463 
464 #ifdef PETSC_CLANGUAGE_CXX
465 
466 /*MC
467    CHKERRXX - Checks error code, if non-zero it calls the C++ error handler which throws an exception
468 
469    Synopsis:
470    #include <petscsys.h>
471    void CHKERRXX(PetscErrorCode ierr)
472 
473    Not Collective
474 
475    Input Parameters:
476 .  ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
477 
478   Level: beginner
479 
480    Notes:
481     Once the error handler throws a ??? exception.
482 
483     You can use CHKERRV() which returns without an error code (bad idea since the error is ignored)
484     or CHKERRABORT(comm,n) to have MPI_Abort() returned immediately.
485 
486 .seealso: SETERRQ(), CHKERRQ(), SETERRABORT(), CHKERRABORT(), PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), CHKMEMQ
487 M*/
488 #define CHKERRXX(...)  do {                                                                    \
489     PetscErrorCode ierr_cxx_ = __VA_ARGS__;                                                    \
490     if (PetscUnlikely(ierr_cxx_)) PetscError(PETSC_COMM_SELF,__LINE__,PETSC_FUNCTION_NAME,__FILE__,ierr_cxx_,PETSC_ERROR_IN_CXX,PETSC_NULLPTR); \
491   } while (0)
492 #endif
493 
494 /*MC
495    CHKERRCXX - Checks C++ function calls and if they throw an exception, catch it and then return a PETSc error code
496 
497    Synopsis:
498    #include <petscsys.h>
499    CHKERRCXX(func);
500 
501    Not Collective
502 
503    Input Parameters:
504 .  func - C++ function calls
505 
506   Level: beginner
507 
508   Notes:
509    For example,
510 
511 $     void foo(int x) {throw std::runtime_error("error");}
512 $     CHKERRCXX(foo(1));
513 
514 .seealso: CHKERRXX(), SETERRQ(), CHKERRQ(), SETERRABORT(), CHKERRABORT(), PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), CHKMEMQ
515 M*/
516 #define CHKERRCXX(...) do {                                     \
517     try {                                                       \
518       __VA_ARGS__;                                              \
519     } catch (const std::exception& e) {                         \
520       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"%s",e.what());     \
521     }                                                           \
522   } while (0)
523 
524 /*MC
525    CHKMEMQ - Checks the memory for corruption, calls error handler if any is detected
526 
527    Synopsis:
528    #include <petscsys.h>
529    CHKMEMQ;
530 
531    Not Collective
532 
533   Level: beginner
534 
535    Notes:
536     We highly recommend using Valgrind https://petsc.org/release/faq/#valgrind or for NVIDIA CUDA systems
537     https://docs.nvidia.com/cuda/cuda-memcheck/index.html for finding memory problems. The ``CHKMEMQ`` macro is useful on systems that
538     do not have valgrind, but is not as good as valgrind or cuda-memcheck.
539 
540     Must run with the option -malloc_debug (-malloc_test in debug mode; or if PetscMallocSetDebug() called) to enable this option
541 
542     Once the error handler is called the calling function is then returned from with the given error code.
543 
544     By defaults prints location where memory that is corrupted was allocated.
545 
546     Use CHKMEMA for functions that return void
547 
548 .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), SETERRQ(), PetscMallocValidate()
549 M*/
550 #if defined(PETSC_CLANG_STATIC_ANALYZER)
551 #define CHKMEMQ
552 #define CHKMEMA
553 #else
554 #define CHKMEMQ do {PetscErrorCode _7_ierr = PetscMallocValidate(__LINE__,PETSC_FUNCTION_NAME,__FILE__);CHKERRQ(_7_ierr);} while (0)
555 #define CHKMEMA PetscMallocValidate(__LINE__,PETSC_FUNCTION_NAME,__FILE__)
556 #endif
557 /*E
558   PetscErrorType - passed to the PETSc error handling routines indicating if this is the first or a later call to the error handlers
559 
560   Level: advanced
561 
562   PETSC_ERROR_IN_CXX indicates the error was detected in C++ and an exception should be generated
563 
564   Developer Notes:
565     This is currently used to decide when to print the detailed information about the run in PetscTraceBackErrorHandler()
566 
567 .seealso: PetscError(), SETERRXX()
568 E*/
569 typedef enum {PETSC_ERROR_INITIAL=0,PETSC_ERROR_REPEAT=1,PETSC_ERROR_IN_CXX = 2} PetscErrorType;
570 
571 #if defined(__clang_analyzer__)
572 __attribute__((analyzer_noreturn))
573 #endif
574 PETSC_EXTERN PetscErrorCode PetscError(MPI_Comm,int,const char*,const char*,PetscErrorCode,PetscErrorType,const char*,...) PETSC_ATTRIBUTE_FORMAT(7,8);
575 
576 PETSC_EXTERN PetscErrorCode PetscErrorPrintfInitialize(void);
577 PETSC_EXTERN PetscErrorCode PetscErrorMessage(int,const char*[],char **);
578 PETSC_EXTERN PetscErrorCode PetscTraceBackErrorHandler(MPI_Comm,int,const char*,const char*,PetscErrorCode,PetscErrorType,const char*,void*);
579 PETSC_EXTERN PetscErrorCode PetscIgnoreErrorHandler(MPI_Comm,int,const char*,const char*,PetscErrorCode,PetscErrorType,const char*,void*);
580 PETSC_EXTERN PetscErrorCode PetscEmacsClientErrorHandler(MPI_Comm,int,const char*,const char*,PetscErrorCode,PetscErrorType,const char*,void*);
581 PETSC_EXTERN PetscErrorCode PetscMPIAbortErrorHandler(MPI_Comm,int,const char*,const char*,PetscErrorCode,PetscErrorType,const char*,void*);
582 PETSC_EXTERN PetscErrorCode PetscAbortErrorHandler(MPI_Comm,int,const char*,const char*,PetscErrorCode,PetscErrorType,const char*,void*);
583 PETSC_EXTERN PetscErrorCode PetscAttachDebuggerErrorHandler(MPI_Comm,int,const char*,const char*,PetscErrorCode,PetscErrorType,const char*,void*);
584 PETSC_EXTERN PetscErrorCode PetscReturnErrorHandler(MPI_Comm,int,const char*,const char*,PetscErrorCode,PetscErrorType,const char*,void*);
585 PETSC_EXTERN PetscErrorCode PetscPushErrorHandler(PetscErrorCode (*handler)(MPI_Comm,int,const char*,const char*,PetscErrorCode,PetscErrorType,const char*,void*),void*);
586 PETSC_EXTERN PetscErrorCode PetscPopErrorHandler(void);
587 PETSC_EXTERN PetscErrorCode PetscSignalHandlerDefault(int,void*);
588 PETSC_EXTERN PetscErrorCode PetscPushSignalHandler(PetscErrorCode (*)(int,void *),void*);
589 PETSC_EXTERN PetscErrorCode PetscPopSignalHandler(void);
590 PETSC_EXTERN PetscErrorCode PetscCheckPointerSetIntensity(PetscInt);
591 PETSC_EXTERN void PetscSignalSegvCheckPointerOrMpi(void);
592 PETSC_DEPRECATED_FUNCTION("Use PetscSignalSegvCheckPointerOrMpi() (since version 3.13)") static inline void PetscSignalSegvCheckPointer(void) {PetscSignalSegvCheckPointerOrMpi();}
593 
594 /*MC
595     PetscErrorPrintf - Prints error messages.
596 
597    Synopsis:
598     #include <petscsys.h>
599      PetscErrorCode (*PetscErrorPrintf)(const char format[],...);
600 
601     Not Collective
602 
603     Input Parameter:
604 .   format - the usual printf() format string
605 
606    Options Database Keys:
607 +    -error_output_stdout - cause error messages to be printed to stdout instead of the  (default) stderr
608 -    -error_output_none - to turn off all printing of error messages (does not change the way the error is handled.)
609 
610    Notes:
611     Use
612 $     PetscErrorPrintf = PetscErrorPrintfNone; to turn off all printing of error messages (does not change the way the
613 $                        error is handled.) and
614 $     PetscErrorPrintf = PetscErrorPrintfDefault; to turn it back on or you can use your own function
615 
616           Use
617      PETSC_STDERR = FILE* obtained from a file open etc. to have stderr printed to the file.
618      PETSC_STDOUT = FILE* obtained from a file open etc. to have stdout printed to the file.
619 
620           Use
621       PetscPushErrorHandler() to provide your own error handler that determines what kind of messages to print
622 
623    Level: developer
624 
625     Fortran Note:
626     This routine is not supported in Fortran.
627 
628 .seealso: PetscFPrintf(), PetscSynchronizedPrintf(), PetscHelpPrintf(), PetscPrintf(), PetscPushErrorHandler(), PetscVFPrintf(), PetscHelpPrintf()
629 M*/
630 PETSC_EXTERN PetscErrorCode (*PetscErrorPrintf)(const char[],...) PETSC_ATTRIBUTE_FORMAT(1,2);
631 
632 typedef enum {PETSC_FP_TRAP_OFF=0,PETSC_FP_TRAP_ON=1} PetscFPTrap;
633 PETSC_EXTERN PetscErrorCode PetscSetFPTrap(PetscFPTrap);
634 PETSC_EXTERN PetscErrorCode PetscFPTrapPush(PetscFPTrap);
635 PETSC_EXTERN PetscErrorCode PetscFPTrapPop(void);
636 PETSC_EXTERN PetscErrorCode PetscDetermineInitialFPTrap(void);
637 
638 /*
639       Allows the code to build a stack frame as it runs
640 */
641 
642 #if defined(PETSC_USE_DEBUG)
643 #define PETSCSTACKSIZE 64
644 typedef struct  {
645   const char *function[PETSCSTACKSIZE];
646   const char *file[PETSCSTACKSIZE];
647         int  line[PETSCSTACKSIZE];
648         int  petscroutine[PETSCSTACKSIZE]; /* 0 external called from petsc, 1 petsc functions, 2 petsc user functions */
649         int  currentsize;
650         int  hotdepth;
651   PetscBool  check; /* runtime option to check for correct Push/Pop semantics at runtime */
652 } PetscStack;
653 PETSC_EXTERN PetscStack petscstack;
654 #else
655 typedef struct {
656   char Silence_empty_struct_has_size_0_in_C_size_1_in_Cpp;
657 } PetscStack;
658 #endif
659 
660 #if defined(PETSC_SERIALIZE_FUNCTIONS)
661 #include <petsc/private/petscfptimpl.h>
662 /*
663    Registers the current function into the global function pointer to function name table
664 
665    Have to fix this to handle errors but cannot return error since used in PETSC_VIEWER_DRAW_() etc
666 */
667 #define PetscRegister__FUNCT__() do { \
668   static PetscBool __chked = PETSC_FALSE; \
669   if (!__chked) {\
670   void *ptr; PetscDLSym(NULL,PETSC_FUNCTION_NAME,&ptr);\
671   __chked = PETSC_TRUE;\
672   }} while (0)
673 #else
674 #define PetscRegister__FUNCT__()
675 #endif
676 
677 #if defined(PETSC_CLANG_STATIC_ANALYZER)
678 #define PetscStackPushNoCheck(funct,petsc_routine,hot)
679 #define PetscStackPopNoCheck
680 #define PetscStackClearTop
681 #define PetscFunctionBegin
682 #define PetscFunctionBeginUser
683 #define PetscFunctionBeginHot
684 #define PetscFunctionReturn(a)    return a
685 #define PetscFunctionReturnVoid() return
686 #define PetscStackPop
687 #define PetscStackPush(f)
688 #elif defined(PETSC_USE_DEBUG)
689 /* Stack handling is based on the following two "NoCheck" macros.  These should only be called directly by other error
690  * handling macros.  We record the line of the call, which may or may not be the location of the definition.  But is at
691  * least more useful than "unknown" because it can distinguish multiple calls from the same function.
692  */
693 #define PetscStackPushNoCheck(funct,petsc_routine,hot) do {             \
694     PetscStackSAWsTakeAccess();                                         \
695     if (petscstack.currentsize < PETSCSTACKSIZE) {                      \
696       petscstack.function[petscstack.currentsize]     = funct;          \
697       petscstack.file[petscstack.currentsize]         = __FILE__;       \
698       petscstack.line[petscstack.currentsize]         = __LINE__;       \
699       petscstack.petscroutine[petscstack.currentsize] = petsc_routine;  \
700     }                                                                   \
701     ++petscstack.currentsize;                                           \
702     petscstack.hotdepth += (hot || petscstack.hotdepth);                \
703     PetscStackSAWsGrantAccess();                                        \
704   } while (0)
705 
706 #define PetscStackPopNoCheck(funct)                    do {             \
707     PetscStackSAWsTakeAccess();                                         \
708     if (PetscUnlikely(petscstack.currentsize <= 0)) {                   \
709       if (PetscUnlikely(petscstack.check)) {                            \
710         printf("Invalid stack size %d, pop %s\n",                       \
711                petscstack.currentsize,funct);                           \
712       }                                                                 \
713     } else {                                                            \
714       if (--petscstack.currentsize < PETSCSTACKSIZE) {                  \
715         if (PetscUnlikely(                                              \
716               petscstack.check                                &&        \
717               petscstack.petscroutine[petscstack.currentsize] &&        \
718               (petscstack.function[petscstack.currentsize]    !=        \
719                (const char*)funct))) {                                  \
720           /* We need this string comparison because "unknown" can be defined in different static strings: */ \
721           PetscBool _cmpflg;                                            \
722           const char *_funct = petscstack.function[petscstack.currentsize]; \
723           PetscStrcmp(_funct,funct,&_cmpflg);                           \
724           if (!_cmpflg)                                                 \
725             printf("Invalid stack: push from %s, pop from %s\n", _funct,funct); \
726         }                                                               \
727         petscstack.function[petscstack.currentsize] = PETSC_NULLPTR;    \
728         petscstack.file[petscstack.currentsize]     = PETSC_NULLPTR;    \
729         petscstack.line[petscstack.currentsize]     = 0;                \
730         petscstack.petscroutine[petscstack.currentsize] = 0;            \
731       }                                                                 \
732       petscstack.hotdepth = PetscMax(petscstack.hotdepth-1,0);          \
733     }                                                                   \
734     PetscStackSAWsGrantAccess();                                        \
735   } while (0)
736 
737 #define PetscStackClearTop                             do {             \
738     PetscStackSAWsTakeAccess();                                         \
739     if (petscstack.currentsize > 0 &&                                   \
740         --petscstack.currentsize < PETSCSTACKSIZE) {                    \
741       petscstack.function[petscstack.currentsize]     = PETSC_NULLPTR;  \
742       petscstack.file[petscstack.currentsize]         = PETSC_NULLPTR;  \
743       petscstack.line[petscstack.currentsize]         = 0;              \
744       petscstack.petscroutine[petscstack.currentsize] = 0;              \
745     }                                                                   \
746     petscstack.hotdepth = PetscMax(petscstack.hotdepth-1,0);            \
747     PetscStackSAWsGrantAccess();                                        \
748   } while (0)
749 
750 /*MC
751    PetscFunctionBegin - First executable line of each PETSc function,  used for error handling. Final
752       line of PETSc functions should be PetscFunctionReturn(0);
753 
754    Synopsis:
755    #include <petscsys.h>
756    void PetscFunctionBegin;
757 
758    Not Collective
759 
760    Usage:
761 .vb
762      int something;
763 
764      PetscFunctionBegin;
765 .ve
766 
767    Notes:
768      Use PetscFunctionBeginUser for application codes.
769 
770      Not available in Fortran
771 
772    Level: developer
773 
774 .seealso: PetscFunctionReturn(), PetscFunctionBeginHot(), PetscFunctionBeginUser()
775 
776 M*/
777 #define PetscFunctionBegin do {                               \
778     PetscStackPushNoCheck(PETSC_FUNCTION_NAME,1,PETSC_FALSE); \
779     PetscRegister__FUNCT__();                                 \
780   } while (0)
781 
782 /*MC
783    PetscFunctionBeginHot - Substitute for PetscFunctionBegin to be used in functions that are called in
784    performance-critical circumstances.  Use of this function allows for lighter profiling by default.
785 
786    Synopsis:
787    #include <petscsys.h>
788    void PetscFunctionBeginHot;
789 
790    Not Collective
791 
792    Usage:
793 .vb
794      int something;
795 
796      PetscFunctionBeginHot;
797 .ve
798 
799    Notes:
800      Not available in Fortran
801 
802    Level: developer
803 
804 .seealso: PetscFunctionBegin, PetscFunctionReturn()
805 
806 M*/
807 #define PetscFunctionBeginHot do {                           \
808     PetscStackPushNoCheck(PETSC_FUNCTION_NAME,1,PETSC_TRUE); \
809     PetscRegister__FUNCT__();                                \
810   } while (0)
811 
812 /*MC
813    PetscFunctionBeginUser - First executable line of user provided PETSc routine
814 
815    Synopsis:
816    #include <petscsys.h>
817    void PetscFunctionBeginUser;
818 
819    Not Collective
820 
821    Usage:
822 .vb
823      int something;
824 
825      PetscFunctionBeginUser;
826 .ve
827 
828    Notes:
829       Final line of PETSc functions should be PetscFunctionReturn(0) except for main().
830 
831       Not available in Fortran
832 
833       This is identical to PetscFunctionBegin except it labels the routine as a user
834       routine instead of as a PETSc library routine.
835 
836    Level: intermediate
837 
838 .seealso: PetscFunctionReturn(), PetscFunctionBegin, PetscFunctionBeginHot
839 
840 M*/
841 #define PetscFunctionBeginUser do {                           \
842     PetscStackPushNoCheck(PETSC_FUNCTION_NAME,2,PETSC_FALSE); \
843     PetscRegister__FUNCT__();                                 \
844   } while (0)
845 
846 #define PetscStackPush(n)       do {        \
847     PetscStackPushNoCheck(n,0,PETSC_FALSE); \
848     CHKMEMQ;                                \
849   } while (0)
850 
851 #define PetscStackPop           do {             \
852       CHKMEMQ;                                   \
853       PetscStackPopNoCheck(PETSC_FUNCTION_NAME); \
854     } while (0)
855 
856 /*MC
857    PetscFunctionReturn - Last executable line of each PETSc function
858         used for error handling. Replaces return()
859 
860    Synopsis:
861    #include <petscsys.h>
862    void PetscFunctionReturn(0);
863 
864    Not Collective
865 
866    Usage:
867 .vb
868     ....
869      PetscFunctionReturn(0);
870    }
871 .ve
872 
873    Notes:
874      Not available in Fortran
875 
876    Level: developer
877 
878 .seealso: PetscFunctionBegin()
879 
880 M*/
881 #define PetscFunctionReturn(a)    do {          \
882     PetscStackPopNoCheck(PETSC_FUNCTION_NAME);  \
883     return a;                                   \
884   } while (0)
885 
886 #define PetscFunctionReturnVoid() do {          \
887     PetscStackPopNoCheck(PETSC_FUNCTION_NAME);  \
888     return;                                     \
889   } while (0)
890 #else /* PETSC_USE_DEBUG */
891 #define PetscStackPushNoCheck(funct,petsc_routine,hot)
892 #define PetscStackPopNoCheck
893 #define PetscStackClearTop
894 #define PetscFunctionBegin
895 #define PetscFunctionBeginUser
896 #define PetscFunctionBeginHot
897 #define PetscFunctionReturn(a)    return a
898 #define PetscFunctionReturnVoid() return
899 #define PetscStackPop             CHKMEMQ
900 #define PetscStackPush(f)         CHKMEMQ
901 #endif /* PETSC_USE_DEBUG */
902 
903 #if defined(PETSC_CLANG_STATIC_ANALYZER)
904 #define PetscStackCall(name,routine)
905 #define PetscStackCallStandard(name,...)
906 #else
907 /*
908     PetscStackCall - Calls an external library routine or user function after pushing the name of the routine on the stack.
909 
910    Input Parameters:
911 +   name - string that gives the name of the function being called
912 -   routine - actual call to the routine, including ierr = and CHKERRQ(ierr);
913 
914    Note: Often one should use PetscStackCallStandard() instead. This routine is intended for external library routines that DO NOT return error codes
915 
916    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.
917 
918 */
919 #define PetscStackCall(name,routine) do { PetscStackPush(name);routine;PetscStackPop; } while (0)
920 
921 /*
922     PetscStackCallStandard - Calls an external library routine after pushing the name of the routine on the stack.
923 
924    Input Parameters:
925 +   func-  name of the routine
926 -   args - arguments to the routine surrounded by ()
927 
928    Notes:
929     This is intended for external package routines that return error codes. Use PetscStackCall() for those that do not.
930 
931    Developer Note: this is so that when an external packge routine results in a crash or corrupts memory, they get blamed instead of PETSc.
932 
933 */
934 #define PetscStackCallStandard(func,...) do {                                                  \
935     PetscStackPush(PetscStringize(func));                                                      \
936     PetscErrorCode __ierr = func(__VA_ARGS__);                                                 \
937     PetscStackPop;                                                                             \
938     PetscCheck(!__ierr,PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in %s(): error code %d",PetscStringize(func),__ierr); \
939   } while (0)
940 #endif /* PETSC_CLANG_STATIC_ANALYZER */
941 
942 #endif
943