xref: /petsc/include/petscerror.h (revision 707192570a8a4f1fbb5ecb489e32d5fef71915d5)
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()`, `PetscCall()`, `CHKMEMQ`, `CHKERRA()`, `PetscCallMPI()`
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()`, `PetscCall()`, `PetscCallMPI()`, `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()`, `PetscCall()`, `CHKERRA()`, `PetscCallAbort()`
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()`, `PetscCall()`, `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()`, `PetscCall()`
219 M*/
220 #define PetscCheck(cond,comm,ierr,...) if (PetscUnlikely(!(cond))) SETERRQ(comm,ierr,__VA_ARGS__)
221 
222 /*MC
223   PetscAssert - Assert that a particular condition is true
224 
225   Synopsis:
226   #include <petscerror.h>
227   void PetscAssert(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   Enabled only in debug builds. Note that any arguments to this macros are still visible to the
239   compiler optimized builds (so must still contain valid code) but are guaranteed to not be
240   executed.
241 
242   See PetscCheck() for usage and behaviour.
243 
244   Level: beginner
245 
246 .seealso: `PetscCheck()`, `SETERRQ()`, `PetscError()`
247 M*/
248 #define PetscAssert(cond,comm,ierr,...) if (PetscUnlikelyDebug(!(cond))) SETERRQ(comm,ierr,__VA_ARGS__)
249 
250 /*MC
251   PetscCall - Checks error code returned from a PETSc function, if non-zero it calls the error
252   handler and and returns from the current function.
253 
254   Synopsis:
255   #include <petscerror.h>
256   void PetscCall(PetscErrorCode ierr)
257 
258   Not Collective
259 
260   Input Parameter:
261 . ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
262 
263   Notes:
264   Once the error handler is called the calling function is then returned from with the given
265   error code. Experienced users can set the error handler with PetscPushErrorHandler().
266 
267   PetscCall(ierr) is fundamentally a macro replacement for
268 .vb
269   if (ierr) return PetscError(...,ierr,...);
270 .ve
271 
272   PetscCall() cannot be used in functions returning a datatype not convertable to
273   PetscErrorCode. For example, PetscCall() may not be used in functions returning void, use
274   PetscCallVoid() in this case.
275 
276   Fortran Notes:
277   PetscCall() may be called from Fortran subroutines but CHKERRA() must be called from the
278   Fortran main program.
279 
280   Example Usage:
281 .vb
282   PetscCall(PetscInitiailize(...)); // OK to call even when PETSc is not yet initialized!
283 
284   extern int foo(int);
285 
286   PetscCall(foo(1)); // OK if int is convertable to PetscErrorCode
287 
288   struct my_struct
289   {
290     void *data;
291   } my_complex_type;
292 
293   struct my_struct bar(void)
294   {
295     PetscCall(foo(15)); // ERROR PetscErrorCode not convertable to struct my_struct!
296   }
297 
298   PetscCall(bar()) // ERROR input not convertable to PetscErrorCode
299 .ve
300 
301   Level: beginner
302 
303 .seealso: `SETERRQ()`, `PetscCheck()`, `PetscAssert()`, `PetscTraceBackErrorHandler()`,
304           `PetscPushErrorHandler()`, `PetscError()`, `CHKMEMQ`, `CHKERRA()`
305 M*/
306 #if defined(PETSC_CLANG_STATIC_ANALYZER)
307 void PetscCall(PetscErrorCode);
308 void PetscCallVoid(PetscErrorCode);
309 #else
310 #define PetscCall(...) do {                                                                    \
311     PetscErrorCode ierr_q_ = __VA_ARGS__;                                                      \
312     if (PetscUnlikely(ierr_q_)) return PetscError(PETSC_COMM_SELF,__LINE__,PETSC_FUNCTION_NAME,__FILE__,ierr_q_,PETSC_ERROR_REPEAT," "); \
313   } while (0)
314 #define PetscCallVoid(...) do {                                                                \
315     PetscErrorCode ierr_void_ = __VA_ARGS__;                                                   \
316     if (PetscUnlikely(ierr_void_)) {                                                           \
317       (void)PetscError(PETSC_COMM_SELF,__LINE__,PETSC_FUNCTION_NAME,__FILE__,ierr_void_,PETSC_ERROR_REPEAT," "); \
318       return;                                                                                  \
319     }                                                                                          \
320   } while (0)
321 #endif
322 
323 /*MC
324   CHKERRQ - Checks error code returned from PETSc function
325 
326   Synopsis:
327   #include <petscsys.h>
328   void CHKERRQ(PetscErrorCode ierr)
329 
330   Not Collective
331 
332   Input Parameters:
333 . ierr - nonzero error code
334 
335   Notes:
336   Deprecated in favor of PetscCall(). This routine behaves identically to it.
337 
338   Level: deprecated
339 
340 .seealso: `PetscCall()`
341 M*/
342 #define CHKERRQ(...) PetscCall(__VA_ARGS__)
343 #define CHKERRV(...) PetscCallVoid(__VA_ARGS__)
344 
345 /*MC
346   PetscCallMPI - Checks error code returned from MPI calls, if non-zero it calls the error
347   handler and then returns
348 
349   Synopsis:
350   #include <petscerror.h>
351   void PetscCallMPI(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   Notes:
359   Always returns the error code PETSC_ERR_MPI; the MPI error code and string are embedded in
360   the string error message. Do not use this to call any other routines (for example PETSc
361   routines), it should only be used for direct MPI calls. Due to limitations of the
362   preprocessor this can unfortunately not easily be enforced, so the user should take care to
363   check this themselves.
364 
365   Example Usage:
366 .vb
367   PetscCallMPI(MPI_Comm_size(...)); // OK, calling MPI function
368 
369   PetscCallMPI(PetscFunction(...)); // ERROR, use PetscCall() instead!
370 .ve
371 
372   Level: beginner
373 
374 .seealso: `SETERRMPI()`, `PetscCall()`, `SETERRQ()`, `SETERRABORT()`, `PetscCallAbort()`,
375           `PetscTraceBackErrorHandler()`, `PetscPushErrorHandler()`, `PetscError()`, `CHKMEMQ`
376 M*/
377 #if defined(PETSC_CLANG_STATIC_ANALYZER)
378 void PetscCallMPI(PetscMPIInt);
379 #else
380 #define PetscCallMPI(...) do {                                                                 \
381     PetscMPIInt _7_errorcode = __VA_ARGS__;                                                    \
382     if (PetscUnlikely(_7_errorcode)) {                                                         \
383       char        _7_errorstring[MPI_MAX_ERROR_STRING];                                        \
384       PetscMPIInt _7_resultlen;                                                                \
385       MPI_Error_string(_7_errorcode,(char*)_7_errorstring,&_7_resultlen); \
386       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MPI,"MPI error %d %s Ignore the following value %d",(int)_7_errorcode,_7_errorstring,_7_resultlen); \
387     }                                                                                          \
388   } while (0)
389 #endif
390 
391 /*MC
392   CHKERRMPI - Checks error code returned from MPI calls, if non-zero it calls the error
393   handler and then returns
394 
395   Synopsis:
396   #include <petscerror.h>
397   void CHKERRMPI(PetscErrorCode ierr)
398 
399   Not Collective
400 
401   Input Parameter:
402 . ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
403 
404   Notes:
405   Deprecated in favor of PetscCallMPI(). This routine behaves identically to it.
406 
407   Level: deprecated
408 
409 .seealso: `PetscCallMPI()`
410 M*/
411 #define CHKERRMPI(...) PetscCallMPI(__VA_ARGS__)
412 
413 /*MC
414   PetscCallAbort - Checks error code returned from PETSc function, if non-zero it aborts immediately
415 
416   Synopsis:
417   #include <petscerror.h>
418   void PetscCallAbort(MPI_Comm comm, PetscErrorCode ierr)
419 
420   Collective on comm
421 
422   Input Parameters:
423 + comm - the MPI communicator on which to abort
424 - ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
425 
426   Notes:
427   This macro has identical type and usage semantics to PetscCall() with the important caveat
428   that this macro does not return. Instead, if ierr is nonzero it calls the PETSc error handler
429   and then immediately calls MPI_Abort(). It can therefore be used anywhere.
430 
431   As per MPI_Abort semantics the communicator passed must be valid, although there is currently
432   no attempt made at handling any potential errors from MPI_Abort(). Note that while
433   MPI_Abort() is required to terminate only those processes which reside on comm, it is often
434   the case that MPI_Abort() terminates *all* processes.
435 
436   Example Usage:
437 .vb
438   PetscErrorCode boom(void) { return PETSC_ERR_MEM; }
439 
440   void foo(void)
441   {
442     PetscCallAbort(PETSC_COMM_WORLD,boom()); // OK, does not return a type
443   }
444 
445   double bar(void)
446   {
447     PetscCallAbort(PETSC_COMM_WORLD,boom()); // OK, does not return a type
448   }
449 
450   PetscCallAbort(MPI_COMM_NULL,boom()); // ERROR, communicator should be valid
451 
452   struct baz
453   {
454     baz()
455     {
456       PetscCallAbort(PETSC_COMM_SELF,boom()); // OK
457     }
458 
459     ~baz()
460     {
461       PetscCallAbort(PETSC_COMM_SELF,boom()); // OK (in fact the only way to handle PETSc errors)
462     }
463   };
464 .ve
465 
466   Level: intermediate
467 
468 .seealso: `SETERRABORT()`, `PetscTraceBackErrorHandler()`, `PetscPushErrorHandler()`, `PetscError()`,
469           `SETERRQ()`, `CHKMEMQ`, `PetscCallMPI()`
470 M*/
471 #if defined(PETSC_CLANG_STATIC_ANALYZER)
472 void PetscCallAbort(MPI_Comm,PetscErrorCode);
473 void PetscCallContinue(PetscErrorCode);
474 #else
475 #define PetscCallAbort(comm,...) do {                                                          \
476     PetscErrorCode ierr_abort_ = __VA_ARGS__;                                                  \
477     if (PetscUnlikely(ierr_abort_)) {                                                          \
478       PetscError(PETSC_COMM_SELF,__LINE__,PETSC_FUNCTION_NAME,__FILE__,ierr_abort_,PETSC_ERROR_REPEAT," "); \
479       MPI_Abort(comm,ierr_abort_);                                                             \
480     }                                                                                          \
481   } while (0)
482 #define PetscCallContinue(...)   do {                                                          \
483     PetscErrorCode ierr_continue_ = __VA_ARGS__;                                               \
484     if (PetscUnlikely(ierr_continue_)) PetscError(PETSC_COMM_SELF,__LINE__,PETSC_FUNCTION_NAME,__FILE__,ierr_continue_,PETSC_ERROR_REPEAT," "); \
485   } while (0)
486 #endif
487 
488 /*MC
489   CHKERRABORT - Checks error code returned from PETSc function. If non-zero it aborts immediately.
490 
491   Synopsis:
492   #include <petscerror.h>
493   void CHKERRABORT(MPI_Comm comm, PetscErrorCode ierr)
494 
495   Not Collective
496 
497   Input Parameters:
498 + comm - the MPI communicator
499 - ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
500 
501   Notes:
502   Deprecated in favor of PetscCallAbort(). This routine behaves identically to it.
503 
504   Level: deprecated
505 
506 .seealso: `PetscCallAbort()`
507 M*/
508 #define CHKERRABORT(comm,...) PetscCallAbort(comm,__VA_ARGS__)
509 #define CHKERRCONTINUE(...)   PetscCallContinue(__VA_ARGS__)
510 
511 /*MC
512    CHKERRA - Fortran-only replacement for PetscCall in the main program, which aborts immediately
513 
514    Synopsis:
515    #include <petscsys.h>
516    PetscErrorCode CHKERRA(PetscErrorCode ierr)
517 
518    Not Collective
519 
520    Input Parameters:
521 .  ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
522 
523   Level: beginner
524 
525    Notes:
526       This should only be used with Fortran. With C/C++, use PetscCall() in normal usage,
527       or PetscCallAbort() if wanting to abort immediately on error.
528 
529    Fortran Notes:
530       PetscCall() may be called from Fortran subroutines but CHKERRA() must be called from the
531       Fortran main program.
532 
533 .seealso: `PetscCall()`, `PetscCallAbort()`, `SETERRA()`, `SETERRQ()`, `SETERRABORT()`
534 M*/
535 
536 PETSC_EXTERN PetscErrorCode PetscAbortFindSourceFile_Private(const char*,PetscInt*);
537 PETSC_EXTERN PetscBool petscwaitonerrorflg;
538 PETSC_EXTERN PetscBool petscindebugger;
539 
540 /*MC
541    PETSCABORT - Call MPI_Abort with an informative error code
542 
543    Synopsis:
544    #include <petscsys.h>
545    PETSCABORT(MPI_Comm comm, PetscErrorCode ierr)
546 
547    Collective
548 
549    Input Parameters:
550 +  comm - A communicator, so that the error can be collective
551 -  ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
552 
553    Level: advanced
554 
555    Notes:
556    We pass MPI_Abort() an error code of format XX_YYYY_ZZZ, where XX, YYYY are an index and line number of the file
557    where PETSCABORT is called, respectively. ZZZ is the PETSc error code.
558 
559    If XX is zero, this means that the call was made in the routine main().
560    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[]
561      is out of date. PETSc developers have to update it.
562    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.
563 
564    If the option -start_in_debugger was used then this calls abort() to stop the program in the debugger.
565 
566  M*/
567 #define PETSCABORT(comm,...) do {                                                              \
568     if (petscwaitonerrorflg) PetscSleep(1000);                                                 \
569     if (petscindebugger) abort();                                                              \
570     else {                                                                                     \
571       PetscErrorCode ierr_petsc_abort_ = __VA_ARGS__;                                          \
572       PetscInt       idx = 0;                                                                  \
573       PetscAbortFindSourceFile_Private(__FILE__,&idx);                                         \
574       MPI_Abort(comm,(PetscMPIInt)(0*idx*10000000 + 0*__LINE__*1000 + ierr_petsc_abort_));     \
575     }                                                                                          \
576   } while (0)
577 
578 #ifdef PETSC_CLANGUAGE_CXX
579 /*MC
580   PetscCallThrow - Checks error code, if non-zero it calls the C++ error handler which throws
581   an exception
582 
583   Synopsis:
584   #include <petscerror.h>
585   void PetscCallThrow(PetscErrorCode ierr)
586 
587   Not Collective
588 
589   Input Parameter:
590 . ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
591 
592   Notes:
593   Requires PETSc to be configured with clanguage = c++. Throws a std::runtime_error() on error.
594 
595   Once the error handler throws the exception you can use PetscCallVoid() which returns without
596   an error code (bad idea since the error is ignored) or PetscCallAbort() to have MPI_Abort()
597   called immediately.
598 
599   Level: beginner
600 
601 .seealso: `SETERRQ()`, `PetscCall()`, `SETERRABORT()`, `PetscCallAbort()`, `PetscTraceBackErrorHandler()`,
602           `PetscPushErrorHandler()`, `PetscError()`, `CHKMEMQ`
603 M*/
604 #define PetscCallThrow(...) do {                                                                    \
605     PetscErrorCode ierr_cxx_ = __VA_ARGS__;                                                    \
606     if (PetscUnlikely(ierr_cxx_)) PetscError(PETSC_COMM_SELF,__LINE__,PETSC_FUNCTION_NAME,__FILE__,ierr_cxx_,PETSC_ERROR_IN_CXX,PETSC_NULLPTR); \
607   } while (0)
608 
609 /*MC
610   CHKERRXX - Checks error code, if non-zero it calls the C++ error handler which throws an exception
611 
612   Synopsis:
613   #include <petscerror.h>
614   void CHKERRXX(PetscErrorCode ierr)
615 
616   Not Collective
617 
618   Input Parameter:
619 . ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
620 
621   Notes:
622   Deprecated in favor of PetscCallThrow(). This routine behaves identically to it.
623 
624   Level: deprecated
625 
626 .seealso: `PetscCallThrow()`
627 M*/
628 #define CHKERRXX(...) PetscCallThrow(__VA_ARGS__)
629 #endif
630 
631 /*MC
632   PetscCallCXX - Checks C++ function calls and if they throw an exception, catch it and then
633   return a PETSc error code
634 
635   Synopsis:
636   #include <petscerror.h>
637   void PetscCallCXX(expr) noexcept;
638 
639   Not Collective
640 
641   Input Parameter:
642 . expr - An arbitrary expression
643 
644   Notes:
645   PetscCallCXX(expr) is a macro replacement for
646 .vb
647   try {
648     expr;
649   } catch (const std::exception& e) {
650     return ConvertToPetscErrorCode(e);
651   }
652 .ve
653   Due to the fact that it catches any (reasonable) exception, it is essentially noexcept.
654 
655   Example Usage:
656 .vb
657   void foo(void) { throw std::runtime_error("error"); }
658 
659   void bar()
660   {
661     PetscCallCXX(foo()); // ERROR bar() does not return PetscErrorCode
662   }
663 
664   PetscErrorCode baz()
665   {
666     PetscCallCXX(foo()); // OK
667 
668     PetscCallCXX(
669       bar();
670       foo(); // OK mutliple statements allowed
671     );
672   }
673 
674   struct bop
675   {
676     bop()
677     {
678       PetscCallCXX(foo()); // ERROR returns PetscErrorCode, cannot be used in constructors
679     }
680   };
681 
682   // ERROR contains do-while, cannot be used as function-try block
683   PetscErrorCode qux() PetscCallCXX(
684     bar();
685     baz();
686     foo();
687     return 0;
688   )
689 .ve
690 
691   Level: beginner
692 
693 .seealso: `PetscCallThrow()`, `SETERRQ()`, `PetscCall()`, `SETERRABORT()`, `PetscCallAbort()`,
694           `PetscTraceBackErrorHandler()`, `PetscPushErrorHandler()`, `PetscError()`, `CHKMEMQ`
695 M*/
696 #define PetscCallCXX(...) do {                                  \
697     try {                                                       \
698       __VA_ARGS__;                                              \
699     } catch (const std::exception& e) {                         \
700       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"%s",e.what());     \
701     }                                                           \
702   } while (0)
703 
704 /*MC
705   CHKERRCXX - Checks C++ function calls and if they throw an exception, catch it and then
706   return a PETSc error code
707 
708   Synopsis:
709   #include <petscerror.h>
710   void CHKERRCXX(func) noexcept;
711 
712   Not Collective
713 
714   Input Parameter:
715 . func - C++ function calls
716 
717   Notes:
718   Deprecated in favor of PetscCallCXX(). This routine behaves identically to it.
719 
720   Level: deprecated
721 
722 .seealso: `PetscCallCXX()`
723 M*/
724 #define CHKERRCXX(...) PetscCallCXX(__VA_ARGS__)
725 
726 /*MC
727    CHKMEMQ - Checks the memory for corruption, calls error handler if any is detected
728 
729    Synopsis:
730    #include <petscsys.h>
731    CHKMEMQ;
732 
733    Not Collective
734 
735   Level: beginner
736 
737    Notes:
738     We highly recommend using Valgrind https://petsc.org/release/faq/#valgrind or for NVIDIA CUDA systems
739     https://docs.nvidia.com/cuda/cuda-memcheck/index.html for finding memory problems. The ``CHKMEMQ`` macro is useful on systems that
740     do not have valgrind, but is not as good as valgrind or cuda-memcheck.
741 
742     Must run with the option -malloc_debug (-malloc_test in debug mode; or if PetscMallocSetDebug() called) to enable this option
743 
744     Once the error handler is called the calling function is then returned from with the given error code.
745 
746     By defaults prints location where memory that is corrupted was allocated.
747 
748     Use CHKMEMA for functions that return void
749 
750 .seealso: `PetscTraceBackErrorHandler()`, `PetscPushErrorHandler()`, `PetscError()`, `SETERRQ()`, `PetscMallocValidate()`
751 M*/
752 #if defined(PETSC_CLANG_STATIC_ANALYZER)
753 #define CHKMEMQ
754 #define CHKMEMA
755 #else
756 #define CHKMEMQ PetscCall(PetscMallocValidate(__LINE__,PETSC_FUNCTION_NAME,__FILE__));
757 #define CHKMEMA PetscMallocValidate(__LINE__,PETSC_FUNCTION_NAME,__FILE__)
758 #endif
759 
760 /*E
761   PetscErrorType - passed to the PETSc error handling routines indicating if this is the first or a later call to the error handlers
762 
763   Level: advanced
764 
765   PETSC_ERROR_IN_CXX indicates the error was detected in C++ and an exception should be generated
766 
767   Developer Notes:
768     This is currently used to decide when to print the detailed information about the run in PetscTraceBackErrorHandler()
769 
770 .seealso: `PetscError()`, `SETERRXX()`
771 E*/
772 typedef enum {PETSC_ERROR_INITIAL=0,PETSC_ERROR_REPEAT=1,PETSC_ERROR_IN_CXX = 2} PetscErrorType;
773 
774 #if defined(__clang_analyzer__)
775 __attribute__((analyzer_noreturn))
776 #endif
777 PETSC_EXTERN PetscErrorCode PetscError(MPI_Comm,int,const char*,const char*,PetscErrorCode,PetscErrorType,const char*,...) PETSC_ATTRIBUTE_COLD PETSC_ATTRIBUTE_FORMAT(7,8);
778 
779 PETSC_EXTERN PetscErrorCode PetscErrorPrintfInitialize(void);
780 PETSC_EXTERN PetscErrorCode PetscErrorMessage(int,const char*[],char **);
781 PETSC_EXTERN PetscErrorCode PetscTraceBackErrorHandler(MPI_Comm,int,const char*,const char*,PetscErrorCode,PetscErrorType,const char*,void*) PETSC_ATTRIBUTE_COLD;
782 PETSC_EXTERN PetscErrorCode PetscIgnoreErrorHandler(MPI_Comm,int,const char*,const char*,PetscErrorCode,PetscErrorType,const char*,void*) PETSC_ATTRIBUTE_COLD;
783 PETSC_EXTERN PetscErrorCode PetscEmacsClientErrorHandler(MPI_Comm,int,const char*,const char*,PetscErrorCode,PetscErrorType,const char*,void*) PETSC_ATTRIBUTE_COLD;
784 PETSC_EXTERN PetscErrorCode PetscMPIAbortErrorHandler(MPI_Comm,int,const char*,const char*,PetscErrorCode,PetscErrorType,const char*,void*) PETSC_ATTRIBUTE_COLD;
785 PETSC_EXTERN PetscErrorCode PetscAbortErrorHandler(MPI_Comm,int,const char*,const char*,PetscErrorCode,PetscErrorType,const char*,void*) PETSC_ATTRIBUTE_COLD;
786 PETSC_EXTERN PetscErrorCode PetscAttachDebuggerErrorHandler(MPI_Comm,int,const char*,const char*,PetscErrorCode,PetscErrorType,const char*,void*) PETSC_ATTRIBUTE_COLD;
787 PETSC_EXTERN PetscErrorCode PetscReturnErrorHandler(MPI_Comm,int,const char*,const char*,PetscErrorCode,PetscErrorType,const char*,void*) PETSC_ATTRIBUTE_COLD;
788 PETSC_EXTERN PetscErrorCode PetscPushErrorHandler(PetscErrorCode (*handler)(MPI_Comm,int,const char*,const char*,PetscErrorCode,PetscErrorType,const char*,void*),void*);
789 PETSC_EXTERN PetscErrorCode PetscPopErrorHandler(void);
790 PETSC_EXTERN PetscErrorCode PetscSignalHandlerDefault(int,void*);
791 PETSC_EXTERN PetscErrorCode PetscPushSignalHandler(PetscErrorCode (*)(int,void *),void*);
792 PETSC_EXTERN PetscErrorCode PetscPopSignalHandler(void);
793 PETSC_EXTERN PetscErrorCode PetscCheckPointerSetIntensity(PetscInt);
794 PETSC_EXTERN void PetscSignalSegvCheckPointerOrMpi(void);
795 PETSC_DEPRECATED_FUNCTION("Use PetscSignalSegvCheckPointerOrMpi() (since version 3.13)") static inline void PetscSignalSegvCheckPointer(void) {PetscSignalSegvCheckPointerOrMpi();}
796 
797 /*MC
798     PetscErrorPrintf - Prints error messages.
799 
800    Synopsis:
801     #include <petscsys.h>
802      PetscErrorCode (*PetscErrorPrintf)(const char format[],...);
803 
804     Not Collective
805 
806     Input Parameter:
807 .   format - the usual printf() format string
808 
809    Options Database Keys:
810 +    -error_output_stdout - cause error messages to be printed to stdout instead of the  (default) stderr
811 -    -error_output_none - to turn off all printing of error messages (does not change the way the error is handled.)
812 
813    Notes:
814     Use
815 $     PetscErrorPrintf = PetscErrorPrintfNone; to turn off all printing of error messages (does not change the way the
816 $                        error is handled.) and
817 $     PetscErrorPrintf = PetscErrorPrintfDefault; to turn it back on or you can use your own function
818 
819           Use
820      PETSC_STDERR = FILE* obtained from a file open etc. to have stderr printed to the file.
821      PETSC_STDOUT = FILE* obtained from a file open etc. to have stdout printed to the file.
822 
823           Use
824       PetscPushErrorHandler() to provide your own error handler that determines what kind of messages to print
825 
826    Level: developer
827 
828     Fortran Note:
829     This routine is not supported in Fortran.
830 
831 .seealso: `PetscFPrintf()`, `PetscSynchronizedPrintf()`, `PetscHelpPrintf()`, `PetscPrintf()`, `PetscPushErrorHandler()`, `PetscVFPrintf()`, `PetscHelpPrintf()`
832 M*/
833 PETSC_EXTERN PetscErrorCode (*PetscErrorPrintf)(const char[],...) PETSC_ATTRIBUTE_FORMAT(1,2);
834 
835 typedef enum {PETSC_FP_TRAP_OFF=0,PETSC_FP_TRAP_ON=1} PetscFPTrap;
836 PETSC_EXTERN PetscErrorCode PetscSetFPTrap(PetscFPTrap);
837 PETSC_EXTERN PetscErrorCode PetscFPTrapPush(PetscFPTrap);
838 PETSC_EXTERN PetscErrorCode PetscFPTrapPop(void);
839 PETSC_EXTERN PetscErrorCode PetscDetermineInitialFPTrap(void);
840 
841 /*
842       Allows the code to build a stack frame as it runs
843 */
844 
845 #if defined(PETSC_USE_DEBUG)
846 #define PETSCSTACKSIZE 64
847 typedef struct  {
848   const char *function[PETSCSTACKSIZE];
849   const char *file[PETSCSTACKSIZE];
850         int  line[PETSCSTACKSIZE];
851         int  petscroutine[PETSCSTACKSIZE]; /* 0 external called from petsc, 1 petsc functions, 2 petsc user functions */
852         int  currentsize;
853         int  hotdepth;
854   PetscBool  check; /* runtime option to check for correct Push/Pop semantics at runtime */
855 } PetscStack;
856 PETSC_EXTERN PetscStack petscstack;
857 #else
858 typedef struct {
859   char Silence_empty_struct_has_size_0_in_C_size_1_in_Cpp;
860 } PetscStack;
861 #endif
862 
863 #if defined(PETSC_SERIALIZE_FUNCTIONS)
864 #include <petsc/private/petscfptimpl.h>
865 /*
866    Registers the current function into the global function pointer to function name table
867 
868    Have to fix this to handle errors but cannot return error since used in PETSC_VIEWER_DRAW_() etc
869 */
870 #define PetscRegister__FUNCT__() do { \
871   static PetscBool __chked = PETSC_FALSE; \
872   if (!__chked) {\
873   void *ptr; PetscDLSym(NULL,PETSC_FUNCTION_NAME,&ptr);\
874   __chked = PETSC_TRUE;\
875   }} while (0)
876 #else
877 #define PetscRegister__FUNCT__()
878 #endif
879 
880 #if defined(PETSC_CLANG_STATIC_ANALYZER)
881 #define PetscStackPushNoCheck(funct,petsc_routine,hot)
882 #define PetscStackPopNoCheck
883 #define PetscStackClearTop
884 #define PetscFunctionBegin
885 #define PetscFunctionBeginUser
886 #define PetscFunctionBeginHot
887 #define PetscFunctionReturn(a)    return a
888 #define PetscFunctionReturnVoid() return
889 #define PetscStackPop
890 #define PetscStackPush(f)
891 #elif defined(PETSC_USE_DEBUG)
892 #define PetscStackPush_Private(stack__,file__,func__,line__,petsc_routine__,hot__) do { \
893     if (stack__.currentsize < PETSCSTACKSIZE) {                                         \
894       stack__.file[stack__.currentsize]         = file__;                               \
895       stack__.function[stack__.currentsize]     = func__;                               \
896       stack__.line[stack__.currentsize]         = line__;                               \
897       stack__.petscroutine[stack__.currentsize] = petsc_routine__;                      \
898     }                                                                                   \
899     ++stack__.currentsize;                                                              \
900     stack__.hotdepth += (hot__ || stack__.hotdepth);                                    \
901   } while (0)
902 
903 #define PetscStackPop_Private(stack__,func__) do {                                             \
904     if (PetscUnlikely(stack__.currentsize <= 0)) {                                             \
905       if (PetscUnlikely(stack__.check)) {                                                      \
906         printf("Invalid stack size %d, pop %s\n",stack__.currentsize,func__);                  \
907       }                                                                                        \
908     } else {                                                                                   \
909       if (--stack__.currentsize < PETSCSTACKSIZE) {                                            \
910         if (PetscUnlikely(                                                                     \
911               stack__.check                           &&                                       \
912               stack__.petscroutine[stack__.currentsize] &&                                     \
913               (stack__.function[stack__.currentsize]    != (const char*)(func__)))) {          \
914           /* We need this string comparison because "unknown" can be defined in different static strings: */ \
915           PetscBool _cmpflg;                                                                   \
916           const char *_funct = stack__.function[stack__.currentsize];                          \
917           PetscStrcmp(_funct,func__,&_cmpflg);                                                 \
918           if (!_cmpflg) printf("Invalid stack: push from %s, pop from %s\n",_funct,func__);    \
919         }                                                                                      \
920         stack__.function[stack__.currentsize]     = PETSC_NULLPTR;                             \
921         stack__.file[stack__.currentsize]         = PETSC_NULLPTR;                             \
922         stack__.line[stack__.currentsize]         = 0;                                         \
923         stack__.petscroutine[stack__.currentsize] = 0;                                         \
924       }                                                                                        \
925       stack__.hotdepth = PetscMax(stack__.hotdepth-1,0);                                       \
926     }                                                                                          \
927   } while (0)
928 
929 /* Stack handling is based on the following two "NoCheck" macros.  These should only be called directly by other error
930  * handling macros.  We record the line of the call, which may or may not be the location of the definition.  But is at
931  * least more useful than "unknown" because it can distinguish multiple calls from the same function.
932  */
933 #define PetscStackPushNoCheck(funct,petsc_routine,hot) do {                             \
934     PetscStackSAWsTakeAccess();                                                         \
935     PetscStackPush_Private(petscstack,__FILE__,funct,__LINE__,petsc_routine,hot);       \
936     PetscStackSAWsGrantAccess();                                                        \
937   } while (0)
938 
939 #define PetscStackPopNoCheck(funct)                    do {     \
940     PetscStackSAWsTakeAccess();                                 \
941     PetscStackPop_Private(petscstack,funct);                    \
942     PetscStackSAWsGrantAccess();                                \
943   } while (0)
944 
945 #define PetscStackClearTop                             do {             \
946     PetscStackSAWsTakeAccess();                                         \
947     if (petscstack.currentsize > 0 &&                                   \
948         --petscstack.currentsize < PETSCSTACKSIZE) {                    \
949       petscstack.function[petscstack.currentsize]     = PETSC_NULLPTR;  \
950       petscstack.file[petscstack.currentsize]         = PETSC_NULLPTR;  \
951       petscstack.line[petscstack.currentsize]         = 0;              \
952       petscstack.petscroutine[petscstack.currentsize] = 0;              \
953     }                                                                   \
954     petscstack.hotdepth = PetscMax(petscstack.hotdepth-1,0);            \
955     PetscStackSAWsGrantAccess();                                        \
956   } while (0)
957 
958 /*MC
959    PetscFunctionBegin - First executable line of each PETSc function,  used for error handling. Final
960       line of PETSc functions should be PetscFunctionReturn(0);
961 
962    Synopsis:
963    #include <petscsys.h>
964    void PetscFunctionBegin;
965 
966    Not Collective
967 
968    Usage:
969 .vb
970      int something;
971 
972      PetscFunctionBegin;
973 .ve
974 
975    Notes:
976      Use PetscFunctionBeginUser for application codes.
977 
978      Not available in Fortran
979 
980    Level: developer
981 
982 .seealso: `PetscFunctionReturn()`, `PetscFunctionBeginHot()`, `PetscFunctionBeginUser()`
983 
984 M*/
985 #define PetscFunctionBegin do {                               \
986     PetscStackPushNoCheck(PETSC_FUNCTION_NAME,1,PETSC_FALSE); \
987     PetscRegister__FUNCT__();                                 \
988   } while (0)
989 
990 /*MC
991    PetscFunctionBeginHot - Substitute for PetscFunctionBegin to be used in functions that are called in
992    performance-critical circumstances.  Use of this function allows for lighter profiling by default.
993 
994    Synopsis:
995    #include <petscsys.h>
996    void PetscFunctionBeginHot;
997 
998    Not Collective
999 
1000    Usage:
1001 .vb
1002      int something;
1003 
1004      PetscFunctionBeginHot;
1005 .ve
1006 
1007    Notes:
1008      Not available in Fortran
1009 
1010    Level: developer
1011 
1012 .seealso: `PetscFunctionBegin`, `PetscFunctionReturn()`
1013 
1014 M*/
1015 #define PetscFunctionBeginHot do {                           \
1016     PetscStackPushNoCheck(PETSC_FUNCTION_NAME,1,PETSC_TRUE); \
1017     PetscRegister__FUNCT__();                                \
1018   } while (0)
1019 
1020 /*MC
1021    PetscFunctionBeginUser - First executable line of user provided PETSc routine
1022 
1023    Synopsis:
1024    #include <petscsys.h>
1025    void PetscFunctionBeginUser;
1026 
1027    Not Collective
1028 
1029    Usage:
1030 .vb
1031      int something;
1032 
1033      PetscFunctionBeginUser;
1034 .ve
1035 
1036    Notes:
1037       Final line of PETSc functions should be PetscFunctionReturn(0) except for main().
1038 
1039       Not available in Fortran
1040 
1041       This is identical to PetscFunctionBegin except it labels the routine as a user
1042       routine instead of as a PETSc library routine.
1043 
1044    Level: intermediate
1045 
1046 .seealso: `PetscFunctionReturn()`, `PetscFunctionBegin`, `PetscFunctionBeginHot`
1047 
1048 M*/
1049 #define PetscFunctionBeginUser do {                           \
1050     PetscStackPushNoCheck(PETSC_FUNCTION_NAME,2,PETSC_FALSE); \
1051     PetscRegister__FUNCT__();                                 \
1052   } while (0)
1053 
1054 #define PetscStackPush(n)       do {        \
1055     PetscStackPushNoCheck(n,0,PETSC_FALSE); \
1056     CHKMEMQ;                                \
1057   } while (0)
1058 
1059 #define PetscStackPop           do {             \
1060       CHKMEMQ;                                   \
1061       PetscStackPopNoCheck(PETSC_FUNCTION_NAME); \
1062     } while (0)
1063 
1064 /*MC
1065    PetscFunctionReturn - Last executable line of each PETSc function
1066         used for error handling. Replaces return()
1067 
1068    Synopsis:
1069    #include <petscsys.h>
1070    void PetscFunctionReturn(0);
1071 
1072    Not Collective
1073 
1074    Usage:
1075 .vb
1076     ....
1077      PetscFunctionReturn(0);
1078    }
1079 .ve
1080 
1081    Notes:
1082      Not available in Fortran
1083 
1084    Level: developer
1085 
1086 .seealso: `PetscFunctionBegin()`
1087 
1088 M*/
1089 #define PetscFunctionReturn(a)    do {          \
1090     PetscStackPopNoCheck(PETSC_FUNCTION_NAME);  \
1091     return a;                                   \
1092   } while (0)
1093 
1094 #define PetscFunctionReturnVoid() do {          \
1095     PetscStackPopNoCheck(PETSC_FUNCTION_NAME);  \
1096     return;                                     \
1097   } while (0)
1098 #else /* PETSC_USE_DEBUG */
1099 #define PetscStackPushNoCheck(funct,petsc_routine,hot)
1100 #define PetscStackPopNoCheck
1101 #define PetscStackClearTop
1102 #define PetscFunctionBegin
1103 #define PetscFunctionBeginUser
1104 #define PetscFunctionBeginHot
1105 #define PetscFunctionReturn(a)    return a
1106 #define PetscFunctionReturnVoid() return
1107 #define PetscStackPop             CHKMEMQ
1108 #define PetscStackPush(f)         CHKMEMQ
1109 #endif /* PETSC_USE_DEBUG */
1110 
1111 #if defined(PETSC_CLANG_STATIC_ANALYZER)
1112 #define PetscStackCall(name,routine)
1113 #define PetscStackCallStandard(func,...)
1114 #else
1115 /*
1116     PetscStackCall - Calls an external library routine or user function after pushing the name of the routine on the stack.
1117 
1118    Input Parameters:
1119 +   name - string that gives the name of the function being called
1120 -   routine - actual call to the routine, including ierr = and PetscCall(ierr);
1121 
1122    Note: Often one should use PetscStackCallStandard() instead. This routine is intended for external library routines that DO NOT return error codes
1123 
1124    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.
1125 
1126 */
1127 #define PetscStackCall(name,routine) do { PetscStackPush(name);routine;PetscStackPop; } while (0)
1128 
1129 /*
1130     PetscStackCallStandard - Calls an external library routine after pushing the name of the routine on the stack.
1131 
1132    Input Parameters:
1133 +   func-  name of the routine
1134 -   args - arguments to the routine surrounded by ()
1135 
1136    Notes:
1137     This is intended for external package routines that return error codes. Use PetscStackCall() for those that do not.
1138 
1139    Developer Note: this is so that when an external packge routine results in a crash or corrupts memory, they get blamed instead of PETSc.
1140 
1141 */
1142 #define PetscStackCallStandard(func,...) do {                                                  \
1143     PetscStackPush(PetscStringize(func));                                                      \
1144     PetscErrorCode __ierr = func(__VA_ARGS__);                                                 \
1145     PetscStackPop;                                                                             \
1146     PetscCheck(!__ierr,PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in %s(): error code %d",PetscStringize(func),__ierr); \
1147   } while (0)
1148 #endif /* PETSC_CLANG_STATIC_ANALYZER */
1149 
1150 #endif
1151