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