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