xref: /petsc/include/petscerror.h (revision 40badf4fbc550ac1f60bd080eaff6de6d55b946d)
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 #else
316 #define CHKERRQ(...) do {                                                                      \
317     PetscErrorCode ierr_q_ = __VA_ARGS__;                                                      \
318     if (PetscUnlikely(ierr_q_)) return PetscError(PETSC_COMM_SELF,__LINE__,PETSC_FUNCTION_NAME,__FILE__,ierr_q_,PETSC_ERROR_REPEAT," "); \
319   } while (0)
320 #endif
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 
329 /*MC
330    CHKERRA - Fortran-only replacement for CHKERRQ in the main program, which aborts immediately
331 
332    Synopsis:
333    #include <petscsys.h>
334    PetscErrorCode CHKERRA(PetscErrorCode ierr)
335 
336    Not Collective
337 
338    Input Parameters:
339 .  ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
340 
341   Level: beginner
342 
343    Notes:
344       This should only be used with Fortran. With C/C++, use CHKERRQ() in normal usage,
345       or CHKERRABORT() if wanting to abort immediately on error.
346 
347    Fortran Notes:
348       CHKERRQ() may be called from Fortran subroutines but CHKERRA() must be called from the
349       Fortran main program.
350 
351 .seealso: CHKERRQ(), CHKERRABORT(), SETERRA(), SETERRQ(), SETERRABORT()
352 M*/
353 
354 /*MC
355    CHKERRABORT - Checks error code returned from PETSc function. If non-zero it aborts immediately.
356 
357    Synopsis:
358    #include <petscsys.h>
359    PetscErrorCode CHKERRABORT(MPI_Comm comm,PetscErrorCode ierr)
360 
361    Not Collective
362 
363    Input Parameters:
364 .  ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
365 
366   Level: intermediate
367 
368 .seealso: SETERRABORT(), PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), SETERRQ(), CHKMEMQ, CHKERRMPI()
369 M*/
370 #define CHKERRABORT(comm,...) do {                                                             \
371     PetscErrorCode ierr_abort_ = __VA_ARGS__;                                                  \
372     if (PetscUnlikely(ierr_abort_)) {                                                          \
373       PetscError(PETSC_COMM_SELF,__LINE__,PETSC_FUNCTION_NAME,__FILE__,ierr_abort_,PETSC_ERROR_REPEAT," "); \
374       MPI_Abort(comm,ierr_abort_);                                                             \
375     }                                                                                          \
376   } while (0)
377 #define CHKERRCONTINUE(...)   do {                                                             \
378     PetscErrorCode ierr_continue_ = __VA_ARGS__;                                               \
379     if (PetscUnlikely(ierr_continue_)) PetscError(PETSC_COMM_SELF,__LINE__,PETSC_FUNCTION_NAME,__FILE__,ierr_continue_,PETSC_ERROR_REPEAT," "); \
380   } while (0)
381 
382 PETSC_EXTERN PetscErrorCode PetscAbortFindSourceFile_Private(const char*,PetscInt*);
383 PETSC_EXTERN PetscBool petscwaitonerrorflg;
384 PETSC_EXTERN PetscBool petscindebugger;
385 
386 /*MC
387    PETSCABORT - Call MPI_Abort with an informative error code
388 
389    Synopsis:
390    #include <petscsys.h>
391    PETSCABORT(MPI_Comm comm, PetscErrorCode ierr)
392 
393    Collective
394 
395    Input Parameters:
396 +  comm - A communicator, so that the error can be collective
397 -  ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
398 
399    Level: advanced
400 
401    Notes:
402    We pass MPI_Abort() an error code of format XX_YYYY_ZZZ, where XX, YYYY are an index and line number of the file
403    where PETSCABORT is called, respectively. ZZZ is the PETSc error code.
404 
405    If XX is zero, this means that the call was made in the routine main().
406    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[]
407      is out of date. PETSc developers have to update it.
408    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.
409 
410    If the option -start_in_debugger was used then this calls abort() to stop the program in the debugger.
411 
412  M*/
413 #define PETSCABORT(comm,...) do {                                                              \
414     if (petscwaitonerrorflg) PetscSleep(1000);                                                 \
415     if (petscindebugger) abort();                                                              \
416     else {                                                                                     \
417       PetscErrorCode ierr_petsc_abort_ = __VA_ARGS__;                                          \
418       PetscInt       idx = 0;                                                                  \
419       PetscAbortFindSourceFile_Private(__FILE__,&idx);                                         \
420       MPI_Abort(comm,(PetscMPIInt)(0*idx*10000000 + 0*__LINE__*1000 + ierr_petsc_abort_));     \
421     }                                                                                          \
422   } while (0)
423 
424 /*MC
425    CHKERRMPI - Checks error code returned from MPI calls, if non-zero it calls the error handler and then returns
426 
427    Synopsis:
428    #include <petscsys.h>
429    PetscErrorCode CHKERRMPI(PetscErrorCode ierr)
430 
431    Not Collective
432 
433    Input Parameters:
434 .  ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
435 
436   Level: intermediate
437 
438    Notes:
439     Always returns the error code PETSC_ERR_MPI; the MPI error code and string are embedded in the string error message
440 
441 .seealso: SETERRMPI(), CHKERRQ(), SETERRQ(), SETERRABORT(), CHKERRABORT(), PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), CHKMEMQ
442 M*/
443 #define CHKERRMPI(...) do {                                                                    \
444     PetscErrorCode _7_errorcode = __VA_ARGS__;                                                 \
445     if (PetscUnlikely(_7_errorcode)) {                                                         \
446       char        _7_errorstring[MPI_MAX_ERROR_STRING];                                        \
447       PetscMPIInt _7_resultlen;                                                                \
448       MPI_Error_string(_7_errorcode,(char*)_7_errorstring,&_7_resultlen); (void)_7_resultlen;  \
449       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MPI,"MPI error %d %s",(int)_7_errorcode,_7_errorstring); \
450     }                                                                                          \
451   } while (0)
452 
453 #ifdef PETSC_CLANGUAGE_CXX
454 
455 /*MC
456    CHKERRXX - Checks error code, if non-zero it calls the C++ error handler which throws an exception
457 
458    Synopsis:
459    #include <petscsys.h>
460    void CHKERRXX(PetscErrorCode ierr)
461 
462    Not Collective
463 
464    Input Parameters:
465 .  ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
466 
467   Level: beginner
468 
469    Notes:
470     Once the error handler throws a ??? exception.
471 
472     You can use CHKERRV() which returns without an error code (bad idea since the error is ignored)
473     or CHKERRABORT(comm,n) to have MPI_Abort() returned immediately.
474 
475 .seealso: SETERRQ(), CHKERRQ(), SETERRABORT(), CHKERRABORT(), PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), CHKMEMQ
476 M*/
477 #define CHKERRXX(...)  do {                                                                    \
478     PetscErrorCode ierr_cxx_ = __VA_ARGS__;                                                    \
479     if (PetscUnlikely(ierr_cxx_)) PetscError(PETSC_COMM_SELF,__LINE__,PETSC_FUNCTION_NAME,__FILE__,ierr_cxx_,PETSC_ERROR_IN_CXX,PETSC_NULLPTR); \
480   } while (0)
481 #endif
482 
483 /*MC
484    CHKERRCXX - Checks C++ function calls and if they throw an exception, catch it and then return a PETSc error code
485 
486    Synopsis:
487    #include <petscsys.h>
488    CHKERRCXX(func);
489 
490    Not Collective
491 
492    Input Parameters:
493 .  func - C++ function calls
494 
495   Level: beginner
496 
497   Notes:
498    For example,
499 
500 $     void foo(int x) {throw std::runtime_error("error");}
501 $     CHKERRCXX(foo(1));
502 
503 .seealso: CHKERRXX(), SETERRQ(), CHKERRQ(), SETERRABORT(), CHKERRABORT(), PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), CHKMEMQ
504 M*/
505 #define CHKERRCXX(...) do {                                     \
506     try {                                                       \
507       __VA_ARGS__;                                              \
508     } catch (const std::exception& e) {                         \
509       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"%s",e.what());     \
510     }                                                           \
511   } while (0)
512 
513 /*MC
514    CHKMEMQ - Checks the memory for corruption, calls error handler if any is detected
515 
516    Synopsis:
517    #include <petscsys.h>
518    CHKMEMQ;
519 
520    Not Collective
521 
522   Level: beginner
523 
524    Notes:
525     We highly recommend using Valgrind https://petsc.org/release/faq/#valgrind or for NVIDIA CUDA systems
526     https://docs.nvidia.com/cuda/cuda-memcheck/index.html for finding memory problems. The ``CHKMEMQ`` macro is useful on systems that
527     do not have valgrind, but is not as good as valgrind or cuda-memcheck.
528 
529     Must run with the option -malloc_debug (-malloc_test in debug mode; or if PetscMallocSetDebug() called) to enable this option
530 
531     Once the error handler is called the calling function is then returned from with the given error code.
532 
533     By defaults prints location where memory that is corrupted was allocated.
534 
535     Use CHKMEMA for functions that return void
536 
537 .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), SETERRQ(), PetscMallocValidate()
538 M*/
539 #if defined(PETSC_CLANG_STATIC_ANALYZER)
540 #define CHKMEMQ
541 #define CHKMEMA
542 #else
543 #define CHKMEMQ do CHKERRQ(PetscMallocValidate(__LINE__,PETSC_FUNCTION_NAME,__FILE__)); while (0)
544 #define CHKMEMA PetscMallocValidate(__LINE__,PETSC_FUNCTION_NAME,__FILE__)
545 #endif
546 /*E
547   PetscErrorType - passed to the PETSc error handling routines indicating if this is the first or a later call to the error handlers
548 
549   Level: advanced
550 
551   PETSC_ERROR_IN_CXX indicates the error was detected in C++ and an exception should be generated
552 
553   Developer Notes:
554     This is currently used to decide when to print the detailed information about the run in PetscTraceBackErrorHandler()
555 
556 .seealso: PetscError(), SETERRXX()
557 E*/
558 typedef enum {PETSC_ERROR_INITIAL=0,PETSC_ERROR_REPEAT=1,PETSC_ERROR_IN_CXX = 2} PetscErrorType;
559 
560 #if defined(__clang_analyzer__)
561 __attribute__((analyzer_noreturn))
562 #endif
563 PETSC_EXTERN PetscErrorCode PetscError(MPI_Comm,int,const char*,const char*,PetscErrorCode,PetscErrorType,const char*,...) PETSC_ATTRIBUTE_FORMAT(7,8);
564 
565 PETSC_EXTERN PetscErrorCode PetscErrorPrintfInitialize(void);
566 PETSC_EXTERN PetscErrorCode PetscErrorMessage(int,const char*[],char **);
567 PETSC_EXTERN PetscErrorCode PetscTraceBackErrorHandler(MPI_Comm,int,const char*,const char*,PetscErrorCode,PetscErrorType,const char*,void*);
568 PETSC_EXTERN PetscErrorCode PetscIgnoreErrorHandler(MPI_Comm,int,const char*,const char*,PetscErrorCode,PetscErrorType,const char*,void*);
569 PETSC_EXTERN PetscErrorCode PetscEmacsClientErrorHandler(MPI_Comm,int,const char*,const char*,PetscErrorCode,PetscErrorType,const char*,void*);
570 PETSC_EXTERN PetscErrorCode PetscMPIAbortErrorHandler(MPI_Comm,int,const char*,const char*,PetscErrorCode,PetscErrorType,const char*,void*);
571 PETSC_EXTERN PetscErrorCode PetscAbortErrorHandler(MPI_Comm,int,const char*,const char*,PetscErrorCode,PetscErrorType,const char*,void*);
572 PETSC_EXTERN PetscErrorCode PetscAttachDebuggerErrorHandler(MPI_Comm,int,const char*,const char*,PetscErrorCode,PetscErrorType,const char*,void*);
573 PETSC_EXTERN PetscErrorCode PetscReturnErrorHandler(MPI_Comm,int,const char*,const char*,PetscErrorCode,PetscErrorType,const char*,void*);
574 PETSC_EXTERN PetscErrorCode PetscPushErrorHandler(PetscErrorCode (*handler)(MPI_Comm,int,const char*,const char*,PetscErrorCode,PetscErrorType,const char*,void*),void*);
575 PETSC_EXTERN PetscErrorCode PetscPopErrorHandler(void);
576 PETSC_EXTERN PetscErrorCode PetscSignalHandlerDefault(int,void*);
577 PETSC_EXTERN PetscErrorCode PetscPushSignalHandler(PetscErrorCode (*)(int,void *),void*);
578 PETSC_EXTERN PetscErrorCode PetscPopSignalHandler(void);
579 PETSC_EXTERN PetscErrorCode PetscCheckPointerSetIntensity(PetscInt);
580 PETSC_EXTERN void PetscSignalSegvCheckPointerOrMpi(void);
581 PETSC_DEPRECATED_FUNCTION("Use PetscSignalSegvCheckPointerOrMpi() (since version 3.13)") static inline void PetscSignalSegvCheckPointer(void) {PetscSignalSegvCheckPointerOrMpi();}
582 
583 /*MC
584     PetscErrorPrintf - Prints error messages.
585 
586    Synopsis:
587     #include <petscsys.h>
588      PetscErrorCode (*PetscErrorPrintf)(const char format[],...);
589 
590     Not Collective
591 
592     Input Parameter:
593 .   format - the usual printf() format string
594 
595    Options Database Keys:
596 +    -error_output_stdout - cause error messages to be printed to stdout instead of the  (default) stderr
597 -    -error_output_none - to turn off all printing of error messages (does not change the way the error is handled.)
598 
599    Notes:
600     Use
601 $     PetscErrorPrintf = PetscErrorPrintfNone; to turn off all printing of error messages (does not change the way the
602 $                        error is handled.) and
603 $     PetscErrorPrintf = PetscErrorPrintfDefault; to turn it back on or you can use your own function
604 
605           Use
606      PETSC_STDERR = FILE* obtained from a file open etc. to have stderr printed to the file.
607      PETSC_STDOUT = FILE* obtained from a file open etc. to have stdout printed to the file.
608 
609           Use
610       PetscPushErrorHandler() to provide your own error handler that determines what kind of messages to print
611 
612    Level: developer
613 
614     Fortran Note:
615     This routine is not supported in Fortran.
616 
617 .seealso: PetscFPrintf(), PetscSynchronizedPrintf(), PetscHelpPrintf(), PetscPrintf(), PetscPushErrorHandler(), PetscVFPrintf(), PetscHelpPrintf()
618 M*/
619 PETSC_EXTERN PetscErrorCode (*PetscErrorPrintf)(const char[],...) PETSC_ATTRIBUTE_FORMAT(1,2);
620 
621 typedef enum {PETSC_FP_TRAP_OFF=0,PETSC_FP_TRAP_ON=1} PetscFPTrap;
622 PETSC_EXTERN PetscErrorCode PetscSetFPTrap(PetscFPTrap);
623 PETSC_EXTERN PetscErrorCode PetscFPTrapPush(PetscFPTrap);
624 PETSC_EXTERN PetscErrorCode PetscFPTrapPop(void);
625 PETSC_EXTERN PetscErrorCode PetscDetermineInitialFPTrap(void);
626 
627 /*
628       Allows the code to build a stack frame as it runs
629 */
630 
631 #if defined(PETSC_USE_DEBUG)
632 #define PETSCSTACKSIZE 64
633 typedef struct  {
634   const char *function[PETSCSTACKSIZE];
635   const char *file[PETSCSTACKSIZE];
636         int  line[PETSCSTACKSIZE];
637         int  petscroutine[PETSCSTACKSIZE]; /* 0 external called from petsc, 1 petsc functions, 2 petsc user functions */
638         int  currentsize;
639         int  hotdepth;
640   PetscBool  check; /* runtime option to check for correct Push/Pop semantics at runtime */
641 } PetscStack;
642 PETSC_EXTERN PetscStack petscstack;
643 #else
644 typedef struct {
645   char Silence_empty_struct_has_size_0_in_C_size_1_in_Cpp;
646 } PetscStack;
647 #endif
648 
649 #if defined(PETSC_SERIALIZE_FUNCTIONS)
650 #include <petsc/private/petscfptimpl.h>
651 /*
652    Registers the current function into the global function pointer to function name table
653 
654    Have to fix this to handle errors but cannot return error since used in PETSC_VIEWER_DRAW_() etc
655 */
656 #define PetscRegister__FUNCT__() do { \
657   static PetscBool __chked = PETSC_FALSE; \
658   if (!__chked) {\
659   void *ptr; PetscDLSym(NULL,PETSC_FUNCTION_NAME,&ptr);\
660   __chked = PETSC_TRUE;\
661   }} while (0)
662 #else
663 #define PetscRegister__FUNCT__()
664 #endif
665 
666 #if defined(PETSC_CLANG_STATIC_ANALYZER)
667 #define PetscStackPushNoCheck(funct,petsc_routine,hot)
668 #define PetscStackPopNoCheck
669 #define PetscStackClearTop
670 #define PetscFunctionBegin
671 #define PetscFunctionBeginUser
672 #define PetscFunctionBeginHot
673 #define PetscFunctionReturn(a)    return a
674 #define PetscFunctionReturnVoid() return
675 #define PetscStackPop
676 #define PetscStackPush(f)
677 #elif defined(PETSC_USE_DEBUG)
678 /* Stack handling is based on the following two "NoCheck" macros.  These should only be called directly by other error
679  * handling macros.  We record the line of the call, which may or may not be the location of the definition.  But is at
680  * least more useful than "unknown" because it can distinguish multiple calls from the same function.
681  */
682 #define PetscStackPushNoCheck(funct,petsc_routine,hot) do {             \
683     PetscStackSAWsTakeAccess();                                         \
684     if (petscstack.currentsize < PETSCSTACKSIZE) {                      \
685       petscstack.function[petscstack.currentsize]     = funct;          \
686       petscstack.file[petscstack.currentsize]         = __FILE__;       \
687       petscstack.line[petscstack.currentsize]         = __LINE__;       \
688       petscstack.petscroutine[petscstack.currentsize] = petsc_routine;  \
689     }                                                                   \
690     ++petscstack.currentsize;                                           \
691     petscstack.hotdepth += (hot || petscstack.hotdepth);                \
692     PetscStackSAWsGrantAccess();                                        \
693   } while (0)
694 
695 #define PetscStackPopNoCheck(funct)                    do {                                    \
696     PetscStackSAWsTakeAccess();                                                                \
697     if (PetscUnlikely(petscstack.currentsize <= 0)) {                                          \
698       if (PetscUnlikely(petscstack.check)) {                                                   \
699         printf("Invalid stack size %d, pop %s\n",petscstack.currentsize,funct);                \
700       }                                                                                        \
701     } else {                                                                                   \
702       if (--petscstack.currentsize < PETSCSTACKSIZE) {                                         \
703         if (PetscUnlikely(                                                                     \
704               petscstack.check                                &&                               \
705               petscstack.petscroutine[petscstack.currentsize] &&                               \
706               (petscstack.function[petscstack.currentsize]    !=                               \
707                (const char*)funct))) {                                                         \
708           /* We need this string comparison because "unknown" can be defined in different static strings: */ \
709           PetscBool _cmpflg;                                                                   \
710           const char *_funct = petscstack.function[petscstack.currentsize];                    \
711           PetscStrcmp(_funct,funct,&_cmpflg);                                                  \
712           if (!_cmpflg) printf("Invalid stack: push from %s, pop from %s\n", _funct,funct);    \
713         }                                                                                      \
714         petscstack.function[petscstack.currentsize]     = PETSC_NULLPTR;                       \
715         petscstack.file[petscstack.currentsize]         = PETSC_NULLPTR;                       \
716         petscstack.line[petscstack.currentsize]         = 0;                                   \
717         petscstack.petscroutine[petscstack.currentsize] = 0;                                   \
718       }                                                                                        \
719       petscstack.hotdepth = PetscMax(petscstack.hotdepth-1,0);                                 \
720     }                                                                                          \
721     PetscStackSAWsGrantAccess();                                                               \
722   } while (0)
723 
724 #define PetscStackClearTop                             do {             \
725     PetscStackSAWsTakeAccess();                                         \
726     if (petscstack.currentsize > 0 &&                                   \
727         --petscstack.currentsize < PETSCSTACKSIZE) {                    \
728       petscstack.function[petscstack.currentsize]     = PETSC_NULLPTR;  \
729       petscstack.file[petscstack.currentsize]         = PETSC_NULLPTR;  \
730       petscstack.line[petscstack.currentsize]         = 0;              \
731       petscstack.petscroutine[petscstack.currentsize] = 0;              \
732     }                                                                   \
733     petscstack.hotdepth = PetscMax(petscstack.hotdepth-1,0);            \
734     PetscStackSAWsGrantAccess();                                        \
735   } while (0)
736 
737 /*MC
738    PetscFunctionBegin - First executable line of each PETSc function,  used for error handling. Final
739       line of PETSc functions should be PetscFunctionReturn(0);
740 
741    Synopsis:
742    #include <petscsys.h>
743    void PetscFunctionBegin;
744 
745    Not Collective
746 
747    Usage:
748 .vb
749      int something;
750 
751      PetscFunctionBegin;
752 .ve
753 
754    Notes:
755      Use PetscFunctionBeginUser for application codes.
756 
757      Not available in Fortran
758 
759    Level: developer
760 
761 .seealso: PetscFunctionReturn(), PetscFunctionBeginHot(), PetscFunctionBeginUser()
762 
763 M*/
764 #define PetscFunctionBegin do {                               \
765     PetscStackPushNoCheck(PETSC_FUNCTION_NAME,1,PETSC_FALSE); \
766     PetscRegister__FUNCT__();                                 \
767   } while (0)
768 
769 /*MC
770    PetscFunctionBeginHot - Substitute for PetscFunctionBegin to be used in functions that are called in
771    performance-critical circumstances.  Use of this function allows for lighter profiling by default.
772 
773    Synopsis:
774    #include <petscsys.h>
775    void PetscFunctionBeginHot;
776 
777    Not Collective
778 
779    Usage:
780 .vb
781      int something;
782 
783      PetscFunctionBeginHot;
784 .ve
785 
786    Notes:
787      Not available in Fortran
788 
789    Level: developer
790 
791 .seealso: PetscFunctionBegin, PetscFunctionReturn()
792 
793 M*/
794 #define PetscFunctionBeginHot do {                           \
795     PetscStackPushNoCheck(PETSC_FUNCTION_NAME,1,PETSC_TRUE); \
796     PetscRegister__FUNCT__();                                \
797   } while (0)
798 
799 /*MC
800    PetscFunctionBeginUser - First executable line of user provided PETSc routine
801 
802    Synopsis:
803    #include <petscsys.h>
804    void PetscFunctionBeginUser;
805 
806    Not Collective
807 
808    Usage:
809 .vb
810      int something;
811 
812      PetscFunctionBeginUser;
813 .ve
814 
815    Notes:
816       Final line of PETSc functions should be PetscFunctionReturn(0) except for main().
817 
818       Not available in Fortran
819 
820       This is identical to PetscFunctionBegin except it labels the routine as a user
821       routine instead of as a PETSc library routine.
822 
823    Level: intermediate
824 
825 .seealso: PetscFunctionReturn(), PetscFunctionBegin, PetscFunctionBeginHot
826 
827 M*/
828 #define PetscFunctionBeginUser do {                           \
829     PetscStackPushNoCheck(PETSC_FUNCTION_NAME,2,PETSC_FALSE); \
830     PetscRegister__FUNCT__();                                 \
831   } while (0)
832 
833 #define PetscStackPush(n)       do {        \
834     PetscStackPushNoCheck(n,0,PETSC_FALSE); \
835     CHKMEMQ;                                \
836   } while (0)
837 
838 #define PetscStackPop           do {             \
839       CHKMEMQ;                                   \
840       PetscStackPopNoCheck(PETSC_FUNCTION_NAME); \
841     } while (0)
842 
843 /*MC
844    PetscFunctionReturn - Last executable line of each PETSc function
845         used for error handling. Replaces return()
846 
847    Synopsis:
848    #include <petscsys.h>
849    void PetscFunctionReturn(0);
850 
851    Not Collective
852 
853    Usage:
854 .vb
855     ....
856      PetscFunctionReturn(0);
857    }
858 .ve
859 
860    Notes:
861      Not available in Fortran
862 
863    Level: developer
864 
865 .seealso: PetscFunctionBegin()
866 
867 M*/
868 #define PetscFunctionReturn(a)    do {          \
869     PetscStackPopNoCheck(PETSC_FUNCTION_NAME);  \
870     return a;                                   \
871   } while (0)
872 
873 #define PetscFunctionReturnVoid() do {          \
874     PetscStackPopNoCheck(PETSC_FUNCTION_NAME);  \
875     return;                                     \
876   } while (0)
877 #else /* PETSC_USE_DEBUG */
878 #define PetscStackPushNoCheck(funct,petsc_routine,hot)
879 #define PetscStackPopNoCheck
880 #define PetscStackClearTop
881 #define PetscFunctionBegin
882 #define PetscFunctionBeginUser
883 #define PetscFunctionBeginHot
884 #define PetscFunctionReturn(a)    return a
885 #define PetscFunctionReturnVoid() return
886 #define PetscStackPop             CHKMEMQ
887 #define PetscStackPush(f)         CHKMEMQ
888 #endif /* PETSC_USE_DEBUG */
889 
890 #if defined(PETSC_CLANG_STATIC_ANALYZER)
891 #define PetscStackCall(name,routine)
892 #define PetscStackCallStandard(func,...)
893 #else
894 /*
895     PetscStackCall - Calls an external library routine or user function after pushing the name of the routine on the stack.
896 
897    Input Parameters:
898 +   name - string that gives the name of the function being called
899 -   routine - actual call to the routine, including ierr = and CHKERRQ(ierr);
900 
901    Note: Often one should use PetscStackCallStandard() instead. This routine is intended for external library routines that DO NOT return error codes
902 
903    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.
904 
905 */
906 #define PetscStackCall(name,routine) do { PetscStackPush(name);routine;PetscStackPop; } while (0)
907 
908 /*
909     PetscStackCallStandard - Calls an external library routine after pushing the name of the routine on the stack.
910 
911    Input Parameters:
912 +   func-  name of the routine
913 -   args - arguments to the routine surrounded by ()
914 
915    Notes:
916     This is intended for external package routines that return error codes. Use PetscStackCall() for those that do not.
917 
918    Developer Note: this is so that when an external packge routine results in a crash or corrupts memory, they get blamed instead of PETSc.
919 
920 */
921 #define PetscStackCallStandard(func,...) do {                                                  \
922     PetscStackPush(PetscStringize(func));                                                      \
923     PetscErrorCode __ierr = func(__VA_ARGS__);                                                 \
924     PetscStackPop;                                                                             \
925     PetscCheck(!__ierr,PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in %s(): error code %d",PetscStringize(func),__ierr); \
926   } while (0)
927 #endif /* PETSC_CLANG_STATIC_ANALYZER */
928 
929 #endif
930