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