xref: /petsc/include/petscerror.h (revision a44be8dc6eeccc8754dbff0bc56030e29894a2e1)
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 /* SUBMANSEC = Sys */
11 
12 /*
13      These are the generic error codes. These error codes are used
14      many different places in the PETSc source code. The string versions are
15      at src/sys/error/err.c any changes here must also be made there
16      These are also define in src/sys/f90-mod/petscerror.h any CHANGES here
17      must be also made there.
18 
19 */
20 #define PETSC_ERR_MIN_VALUE 54 /* should always be one less then the smallest value */
21 
22 #define PETSC_ERR_MEM            55 /* unable to allocate requested memory */
23 #define PETSC_ERR_SUP            56 /* no support for requested operation */
24 #define PETSC_ERR_SUP_SYS        57 /* no support for requested operation on this computer system */
25 #define PETSC_ERR_ORDER          58 /* operation done in wrong order */
26 #define PETSC_ERR_SIG            59 /* signal received */
27 #define PETSC_ERR_FP             72 /* floating point exception */
28 #define PETSC_ERR_COR            74 /* corrupted PETSc object */
29 #define PETSC_ERR_LIB            76 /* error in library called by PETSc */
30 #define PETSC_ERR_PLIB           77 /* PETSc library generated inconsistent data */
31 #define PETSC_ERR_MEMC           78 /* memory corruption */
32 #define PETSC_ERR_CONV_FAILED    82 /* iterative method (KSP or SNES) failed */
33 #define PETSC_ERR_USER           83 /* user has not provided needed function */
34 #define PETSC_ERR_SYS            88 /* error in system call */
35 #define PETSC_ERR_POINTER        70 /* pointer does not point to valid address */
36 #define PETSC_ERR_MPI_LIB_INCOMP 87 /* MPI library at runtime is not compatible with MPI user compiled with */
37 
38 #define PETSC_ERR_ARG_SIZ          60 /* nonconforming object sizes used in operation */
39 #define PETSC_ERR_ARG_IDN          61 /* two arguments not allowed to be the same */
40 #define PETSC_ERR_ARG_WRONG        62 /* wrong argument (but object probably ok) */
41 #define PETSC_ERR_ARG_CORRUPT      64 /* null or corrupted PETSc object as argument */
42 #define PETSC_ERR_ARG_OUTOFRANGE   63 /* input argument, out of range */
43 #define PETSC_ERR_ARG_BADPTR       68 /* invalid pointer argument */
44 #define PETSC_ERR_ARG_NOTSAMETYPE  69 /* two args must be same object type */
45 #define PETSC_ERR_ARG_NOTSAMECOMM  80 /* two args must be same communicators */
46 #define PETSC_ERR_ARG_WRONGSTATE   73 /* object in argument is in wrong state, e.g. unassembled mat */
47 #define PETSC_ERR_ARG_TYPENOTSET   89 /* the type of the object has not yet been set */
48 #define PETSC_ERR_ARG_INCOMP       75 /* two arguments are incompatible */
49 #define PETSC_ERR_ARG_NULL         85 /* argument is null that should not be */
50 #define PETSC_ERR_ARG_UNKNOWN_TYPE 86 /* type name doesn't match any registered type */
51 
52 #define PETSC_ERR_FILE_OPEN       65 /* unable to open file */
53 #define PETSC_ERR_FILE_READ       66 /* unable to read from file */
54 #define PETSC_ERR_FILE_WRITE      67 /* unable to write to file */
55 #define PETSC_ERR_FILE_UNEXPECTED 79 /* unexpected data in file */
56 
57 #define PETSC_ERR_MAT_LU_ZRPVT 71 /* detected a zero pivot during LU factorization */
58 #define PETSC_ERR_MAT_CH_ZRPVT 81 /* detected a zero pivot during Cholesky factorization */
59 
60 #define PETSC_ERR_INT_OVERFLOW 84
61 
62 #define PETSC_ERR_FLOP_COUNT     90
63 #define PETSC_ERR_NOT_CONVERGED  91 /* solver did not converge */
64 #define PETSC_ERR_MISSING_FACTOR 92 /* MatGetFactor() failed */
65 #define PETSC_ERR_OPT_OVERWRITE  93 /* attempted to over write options which should not be changed */
66 #define PETSC_ERR_WRONG_MPI_SIZE 94 /* example/application run with number of MPI ranks it does not support */
67 #define PETSC_ERR_USER_INPUT     95 /* missing or incorrect user input */
68 #define PETSC_ERR_GPU_RESOURCE   96 /* unable to load a GPU resource, for example cuBLAS */
69 #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 */
70 #define PETSC_ERR_MPI            98 /* general MPI error */
71 #define PETSC_ERR_MAX_VALUE      99 /* this is always the one more than the largest error code */
72 
73 #define SETERRQ1(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
74 #define SETERRQ2(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
75 #define SETERRQ3(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
76 #define SETERRQ4(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
77 #define SETERRQ5(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
78 #define SETERRQ6(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
79 #define SETERRQ7(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
80 #define SETERRQ8(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
81 #define SETERRQ9(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
82 
83 /*MC
84    SETERRQ - Macro to be called when an error has been detected,
85 
86    Synopsis:
87    #include <petscsys.h>
88    PetscErrorCode SETERRQ(MPI_Comm comm,PetscErrorCode ierr,char *message,...)
89 
90    Collective
91 
92    Input Parameters:
93 +  comm - A communicator, use `PETSC_COMM_SELF` unless you know all ranks of another communicator will detect the error
94 .  ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
95 -  message - error message
96 
97   Level: beginner
98 
99    Notes:
100     This is rarely needed, one should use `PetscCheck()` and `PetscCall()` and friends to automatically handle error conditions.
101     Once the error handler is called the calling function is then returned from with the given error code.
102 
103     Experienced users can set the error handler with `PetscPushErrorHandler()`.
104 
105    Fortran Notes:
106       SETERRQ() may be called from Fortran subroutines but SETERRA() must be called from the
107       Fortran main program.
108 
109 .seealso: `PetscCheck()`, `PetscAssert()`, `PetscTraceBackErrorHandler()`, `PetscPushErrorHandler()`,
110           `PetscError()`, `PetscCall()`, `CHKMEMQ`, `CHKERRA()`, `PetscCallMPI()`
111 M*/
112 #define SETERRQ(comm, ierr, ...) return PetscError(comm, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr, PETSC_ERROR_INITIAL, __VA_ARGS__)
113 
114 /*
115     Returned from PETSc functions that are called from MPI, such as related to attributes
116       Do not confuse PETSC_MPI_ERROR_CODE and PETSC_ERR_MPI, the first is registered with MPI and returned to MPI as
117       an error code, the latter is a regular PETSc error code passed within PETSc code indicating an error was detected in an MPI call.
118 */
119 PETSC_EXTERN PetscMPIInt PETSC_MPI_ERROR_CLASS;
120 PETSC_EXTERN PetscMPIInt PETSC_MPI_ERROR_CODE;
121 
122 /*MC
123    SETERRMPI - Macro to be called when an error has been detected within an MPI callback function
124 
125    Synopsis:
126    #include <petscsys.h>
127    PetscErrorCode SETERRMPI(MPI_Comm comm,PetscErrorCode ierr,char *message,...)
128 
129    Collective
130 
131    Input Parameters:
132 +  comm - A communicator, use `PETSC_COMM_SELF` unless you know all ranks of another communicator will detect the error
133 .  ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
134 -  message - error message
135 
136   Level: developer
137 
138    Notes:
139     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`
140     which is registered with `MPI_Add_error_code()` when PETSc is initialized.
141 
142 .seealso: `SETERRQ()`, `PetscCall()`, `PetscCallMPI()`, `PetscTraceBackErrorHandler()`, `PetscPushErrorHandler()`, `PetscError()`, `CHKMEMQ`
143 M*/
144 #define SETERRMPI(comm, ierr, ...) return (PetscError(comm, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr, PETSC_ERROR_INITIAL, __VA_ARGS__), PETSC_MPI_ERROR_CODE)
145 
146 /*MC
147    SETERRA - Fortran-only macro that can be called when an error has been detected from the main program
148 
149    Synopsis:
150    #include <petscsys.h>
151    PetscErrorCode SETERRA(MPI_Comm comm,PetscErrorCode ierr,char *message)
152 
153    Collective
154 
155    Input Parameters:
156 +  comm - A communicator, so that the error can be collective
157 .  ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
158 -  message - error message in the printf format
159 
160   Level: beginner
161 
162    Notes:
163     This should only be used with Fortran. With C/C++, use `SETERRQ()`.
164 
165    Fortran Notes:
166       `SETERRQ()` may be called from Fortran subroutines but `SETERRA()` must be called from the
167       Fortran main program.
168 
169 .seealso: `SETERRQ()`, `SETERRABORT()`, `PetscCall()`, `CHKERRA()`, `PetscCallAbort()`
170 M*/
171 
172 /*MC
173    SETERRABORT - Macro that can be called when an error has been detected,
174 
175    Synopsis:
176    #include <petscsys.h>
177    PetscErrorCode SETERRABORT(MPI_Comm comm,PetscErrorCode ierr,char *message,...)
178 
179    Collective
180 
181    Input Parameters:
182 +  comm - A communicator, so that the error can be collective
183 .  ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
184 -  message - error message in the printf format
185 
186   Level: beginner
187 
188    Notes:
189     This function just calls `MPI_Abort()`.
190 
191     This should only be called in routines that cannot return an error code, such as in C++ constructors.
192 
193 .seealso: `SETERRQ()`, `PetscTraceBackErrorHandler()`, `PetscPushErrorHandler()`, `PetscError()`, `PetscCall()`, `CHKMEMQ`
194 M*/
195 #define SETERRABORT(comm, ierr, ...) \
196   do { \
197     PetscError(comm, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr, PETSC_ERROR_INITIAL, __VA_ARGS__); \
198     MPI_Abort(comm, ierr); \
199   } while (0)
200 
201 /*MC
202   PetscCheck - Check that a particular condition is true
203 
204   Synopsis:
205   #include <petscerror.h>
206   void PetscCheck(bool cond, MPI_Comm comm, PetscErrorCode ierr, const char *message, ...)
207 
208   Collective
209 
210   Input Parameters:
211 + cond    - The boolean condition
212 . comm    - The communicator on which the check can be collective on
213 . ierr    - A nonzero error code, see include/petscerror.h for the complete list
214 - message - Error message in printf format
215 
216   Notes:
217   Enabled in both optimized and debug builds.
218 
219   Calls `SETERRQ()` if the assertion fails, so can only be called from functions returning a
220   `PetscErrorCode` (or equivalent type after conversion).
221 
222   Level: beginner
223 
224 .seealso: `PetscAssert()`, `SETERRQ()`, `PetscError()`, `PetscCall()`, `PetscCheckAbort()`
225 M*/
226 #define PetscCheck(cond, comm, ierr, ...) \
227   do { \
228     if (PetscUnlikely(!(cond))) SETERRQ(comm, ierr, __VA_ARGS__); \
229   } while (0)
230 
231 /*MC
232   PetscCheckAbort - Check that a particular condition is true, otherwise prints error and aborts
233 
234   Synopsis:
235   #include <petscerror.h>
236   void PetscCheckAbort(bool cond, MPI_Comm comm, PetscErrorCode ierr, const char *message, ...)
237 
238   Collective
239 
240   Input Parameters:
241 + cond    - The boolean condition
242 . comm    - The communicator on which the check can be collective on
243 . ierr    - A nonzero error code, see include/petscerror.h for the complete list
244 - message - Error message in printf format
245 
246   Notes:
247   Enabled in both optimized and debug builds.
248 
249   Calls `SETERRABORT()` if the assertion fails, can be called from a function that does not return an
250   error code, such as a C++ constructor. usually `PetscCheck()` should be used.
251 
252   Level: developer
253 
254 .seealso: `PetscAssertAbort()`, `PetscAssert()`, `SETERRQ()`, `PetscError()`, `PetscCall()`, `PetscCheck()`, `SETTERRABORT()`
255 M*/
256 #define PetscCheckAbort(cond, comm, ierr, ...) \
257   do { \
258     if (PetscUnlikely(!(cond))) SETERRABORT(comm, ierr, __VA_ARGS__); \
259   } while (0);
260 
261 /*MC
262   PetscAssert - Assert that a particular condition is true
263 
264   Synopsis:
265   #include <petscerror.h>
266   void PetscAssert(bool cond, MPI_Comm comm, PetscErrorCode ierr, const char *message, ...)
267 
268   Collective
269 
270   Input Parameters:
271 + cond    - The boolean condition
272 . comm    - The communicator on which the check can be collective on
273 . ierr    - A nonzero error code, see include/petscerror.h for the complete list
274 - message - Error message in printf format
275 
276   Notes:
277   Enabled only in debug builds. Note that any arguments to this macros are still visible to the
278   compiler optimized builds (so must still contain valid code) but are guaranteed to not be
279   executed.
280 
281   See `PetscCheck()` for usage and behaviour.
282 
283   This is needed instead of simply using `assert()` because this correctly handles the collective nature of errors under MPI
284 
285   Level: beginner
286 
287 .seealso: `PetscCheck()`, `SETERRQ()`, `PetscError()`, `PetscAssertAbort()`
288 M*/
289 #define PetscAssert(cond, comm, ierr, ...) \
290   do { \
291     if (PetscUnlikelyDebug(!(cond))) SETERRQ(comm, ierr, __VA_ARGS__); \
292   } while (0)
293 
294 /*MC
295   PetscAssertAbort - Assert that a particular condition is true, otherwise prints error and aborts
296 
297   Synopsis:
298   #include <petscerror.h>
299   void PetscAssertAbort(bool cond, MPI_Comm comm, PetscErrorCode ierr, const char *message, ...)
300 
301   Collective
302 
303   Input Parameters:
304 + cond    - The boolean condition
305 . comm    - The communicator on which the check can be collective on
306 . ierr    - A nonzero error code, see include/petscerror.h for the complete list
307 - message - Error message in printf format
308 
309   Notes:
310   Enabled only in debug builds. See `PetscCheckAbort()` for usage.
311 
312   Level: beginner
313 
314 .seealso: `PetscCheckAbort()`, `PetscAssert()`, `PetscCheck()`, `SETERRABORT()`, `PetscError()`
315 M*/
316 #define PetscAssertAbort(cond, comm, ierr, ...) \
317   do { \
318     if (PetscUnlikelyDebug(!(cond))) SETERRABORT(comm, ierr, __VA_ARGS__); \
319   } while (0)
320 
321 /*MC
322   PetscCall - Calls a PETSc function and then checks the resulting error code, if it is non-zero it calls the error
323   handler and returns from the current function with the error code.
324 
325   Synopsis:
326   #include <petscerror.h>
327   void PetscCall(PetscFunction(args))
328 
329   Not Collective
330 
331   Input Parameter:
332 . PetscFunction - any PETSc function that returns an error code
333 
334   Notes:
335   Once the error handler is called the calling function is then returned from with the given
336   error code. Experienced users can set the error handler with `PetscPushErrorHandler()`.
337 
338   `PetscCall()` cannot be used in functions returning a datatype not convertible to
339   `PetscErrorCode`. For example, `PetscCall()` may not be used in functions returning void, use
340   `PetscCallVoid()` in this case.
341 
342   Example Usage:
343 .vb
344   PetscCall(PetscInitiailize(...)); // OK to call even when PETSc is not yet initialized!
345 
346   struct my_struct
347   {
348     void *data;
349   } my_complex_type;
350 
351   struct my_struct bar(void)
352   {
353     PetscCall(foo(15)); // ERROR PetscErrorCode not convertible to struct my_struct!
354   }
355 
356   PetscCall(bar()) // ERROR input not convertible to PetscErrorCode
357 .ve
358 
359   It is also possible to call this directly on a `PetscErrorCode` variable
360 .vb
361   PetscCall(ierr);  // check if ierr is nonzero
362 .ve
363 
364   Should not be used to call callback functions provided by users, `PetscCallBack()` should be used in that situation.
365 
366   `PetscUseTypeMethod()` or `PetscTryTypeMethod()` should be used when calling functions pointers contained in a PETSc object's `ops` array
367 
368   Fortran Notes:
369     The Fortran function from which this is used must declare a variable PetscErrorCode ierr and ierr must be
370     the final argument to the PETSc function being called.
371 
372     In the main program and in Fortran subroutines that do not have ierr as the final return parameter one
373     should use `PetscCallA()`
374 
375   Example Fortran Usage:
376 .vb
377   PetscErrorCode ierr
378   Vec v
379 
380   ...
381   PetscCall(VecShift(v,1.0,ierr))
382   PetscCallA(VecShift(v,1.0,ierr))
383 .ve
384 
385   Level: beginner
386 
387 .seealso: `SETERRQ()`, `PetscCheck()`, `PetscAssert()`, `PetscTraceBackErrorHandler()`, `PetscCallMPI()`
388           `PetscPushErrorHandler()`, `PetscError()`, `CHKMEMQ`, `CHKERRA()`, `CHKERRMPI()`, `PetscCallBack()`
389 M*/
390 
391 /*MC
392   PetscCallBack - Calls a user provided PETSc callback function and then checks the resulting error code, if it is non-zero it calls the error
393   handler and returns from the current function with the error code.
394 
395   Synopsis:
396   #include <petscerror.h>
397   void PetscCallBack(const char *functionname,PetscFunction(args))
398 
399   Not Collective
400 
401   Input Parameters:
402 + functionname - the name of the function being called, this can be a string with spaces that describes the meaning of the callback
403 - PetscFunction - user provided callback function that returns an error code
404 
405   Notes:
406   Once the error handler is called the calling function is then returned from with the given
407   error code. Experienced users can set the error handler with `PetscPushErrorHandler()`.
408 
409   `PetscCallBack()` should only be called in PETSc when a call is being made to a user provided call-back routine.
410 
411   Example Usage:
412 .vb
413   PetscCallBack("XXX callback to do something",a->callback(...));
414 .ve
415 
416   Level: developer
417 
418 .seealso: `SETERRQ()`, `PetscCheck()`, `PetscCall()`, `PetscAssert()`, `PetscTraceBackErrorHandler()`, `PetscCallMPI()`
419           `PetscPushErrorHandler()`, `PetscError()`, `CHKMEMQ`, `CHKERRA()`, `CHKERRMPI()`, `PetscCall()`
420 M*/
421 
422 #if defined(PETSC_CLANG_STATIC_ANALYZER)
423 void PetscCall(PetscErrorCode);
424 void PetscCallBack(const char *, PetscErrorCode);
425 void PetscCallVoid(PetscErrorCode);
426 #else
427 #define PetscCall(...) \
428   do { \
429     PetscErrorCode ierr_q_; \
430     PetscStackUpdateLine; \
431     ierr_q_ = __VA_ARGS__; \
432     if (PetscUnlikely(ierr_q_)) return PetscError(PETSC_COMM_SELF, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr_q_, PETSC_ERROR_REPEAT, " "); \
433   } while (0)
434 #define PetscCallBack(function, ...) \
435   do { \
436     PetscErrorCode ierr_q_; \
437     PetscStackUpdateLine; \
438     PetscStackPushExternal(function); \
439     ierr_q_ = __VA_ARGS__; \
440     PetscStackPop; \
441     if (PetscUnlikely(ierr_q_)) return PetscError(PETSC_COMM_SELF, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr_q_, PETSC_ERROR_REPEAT, " "); \
442   } while (0)
443 #define PetscCallVoid(...) \
444   do { \
445     PetscErrorCode ierr_void_; \
446     PetscStackUpdateLine; \
447     ierr_void_ = __VA_ARGS__; \
448     if (PetscUnlikely(ierr_void_)) { \
449       (void)PetscError(PETSC_COMM_SELF, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr_void_, PETSC_ERROR_REPEAT, " "); \
450       return; \
451     } \
452   } while (0)
453 #endif
454 
455 /*MC
456   CHKERRQ - Checks error code returned from PETSc function
457 
458   Synopsis:
459   #include <petscsys.h>
460   void CHKERRQ(PetscErrorCode ierr)
461 
462   Not Collective
463 
464   Input Parameters:
465 . ierr - nonzero error code
466 
467   Notes:
468   Deprecated in favor of `PetscCall()`. This routine behaves identically to it.
469 
470   Level: deprecated
471 
472 .seealso: `PetscCall()`
473 M*/
474 #define CHKERRQ(...) PetscCall(__VA_ARGS__)
475 #define CHKERRV(...) PetscCallVoid(__VA_ARGS__)
476 
477 PETSC_EXTERN void PetscMPIErrorString(PetscMPIInt, char *);
478 
479 /*MC
480   PetscCallMPI - Checks error code returned from MPI calls, if non-zero it calls the error
481   handler and then returns
482 
483   Synopsis:
484   #include <petscerror.h>
485   void PetscCallMPI(MPI_Function(args))
486 
487   Not Collective
488 
489   Input Parameters:
490 . MPI_Function - an MPI function that returns an MPI error code
491 
492   Notes:
493   Always returns the error code `PETSC_ERR_MPI`; the MPI error code and string are embedded in
494   the string error message. Do not use this to call any other routines (for example PETSc
495   routines), it should only be used for direct MPI calls. Due to limitations of the
496   preprocessor this can unfortunately not easily be enforced, so the user should take care to
497   check this themselves.
498 
499   Example Usage:
500 .vb
501   PetscCallMPI(MPI_Comm_size(...)); // OK, calling MPI function
502 
503   PetscCallMPI(PetscFunction(...)); // ERROR, use PetscCall() instead!
504 .ve
505 
506   Fortran Notes:
507     The Fortran function from which this is used must declare a variable `PetscErrorCode` ierr and ierr must be
508     the final argument to the MPI function being called.
509 
510     In the main program and in Fortran subroutines that do not have ierr as the final return parameter one
511     should use `PetscCallMPIA()`
512 
513   Fortran Usage:
514 .vb
515   PetscErrorCode ierr or integer ierr
516   ...
517   PetscCallMPI(MPI_Comm_size(...,ierr))
518   PetscCallMPIA(MPI_Comm_size(...,ierr)) ! Will abort after calling error handler
519 
520   PetscCallMPI(MPI_Comm_size(...,eflag)) ! ERROR, final argument must be ierr
521 .ve
522 
523   Level: beginner
524 
525 .seealso: `SETERRMPI()`, `PetscCall()`, `SETERRQ()`, `SETERRABORT()`, `PetscCallAbort()`,
526           `PetscTraceBackErrorHandler()`, `PetscPushErrorHandler()`, `PetscError()`, `CHKMEMQ`
527 M*/
528 #if defined(PETSC_CLANG_STATIC_ANALYZER)
529 void PetscCallMPI(PetscMPIInt);
530 #else
531 #define PetscCallMPI(...) \
532   do { \
533     PetscMPIInt _7_errorcode; \
534     char        _7_errorstring[2 * MPI_MAX_ERROR_STRING]; \
535     PetscStackUpdateLine; \
536     PetscStackPushExternal("MPI function"); \
537     { _7_errorcode = __VA_ARGS__; } \
538     PetscStackPop; \
539     if (PetscUnlikely(_7_errorcode)) { \
540       PetscMPIErrorString(_7_errorcode, (char *)_7_errorstring); \
541       SETERRQ(PETSC_COMM_SELF, PETSC_ERR_MPI, "MPI error %d %s", (int)_7_errorcode, _7_errorstring); \
542     } \
543   } while (0)
544 #endif
545 
546 /*MC
547   CHKERRMPI - Checks error code returned from MPI calls, if non-zero it calls the error
548   handler and then returns
549 
550   Synopsis:
551   #include <petscerror.h>
552   void CHKERRMPI(PetscErrorCode ierr)
553 
554   Not Collective
555 
556   Input Parameter:
557 . ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
558 
559   Notes:
560   Deprecated in favor of `PetscCallMPI()`. This routine behaves identically to it.
561 
562   Level: deprecated
563 
564 .seealso: `PetscCallMPI()`
565 M*/
566 #define CHKERRMPI(...) PetscCallMPI(__VA_ARGS__)
567 
568 /*MC
569   PetscCallAbort - Checks error code returned from PETSc function, if non-zero it aborts immediately
570 
571   Synopsis:
572   #include <petscerror.h>
573   void PetscCallAbort(MPI_Comm comm, PetscErrorCode ierr)
574 
575   Collective on comm
576 
577   Input Parameters:
578 + comm - the MPI communicator on which to abort
579 - ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
580 
581   Notes:
582   This macro has identical type and usage semantics to `PetscCall()` with the important caveat
583   that this macro does not return. Instead, if ierr is nonzero it calls the PETSc error handler
584   and then immediately calls `MPI_Abort()`. It can therefore be used anywhere.
585 
586   As per `MPI_Abort()` semantics the communicator passed must be valid, although there is currently
587   no attempt made at handling any potential errors from `MPI_Abort()`. Note that while
588   `MPI_Abort()` is required to terminate only those processes which reside on comm, it is often
589   the case that `MPI_Abort()` terminates *all* processes.
590 
591   Example Usage:
592 .vb
593   PetscErrorCode boom(void) { return PETSC_ERR_MEM; }
594 
595   void foo(void)
596   {
597     PetscCallAbort(PETSC_COMM_WORLD,boom()); // OK, does not return a type
598   }
599 
600   double bar(void)
601   {
602     PetscCallAbort(PETSC_COMM_WORLD,boom()); // OK, does not return a type
603   }
604 
605   PetscCallAbort(MPI_COMM_NULL,boom()); // ERROR, communicator should be valid
606 
607   struct baz
608   {
609     baz()
610     {
611       PetscCallAbort(PETSC_COMM_SELF,boom()); // OK
612     }
613 
614     ~baz()
615     {
616       PetscCallAbort(PETSC_COMM_SELF,boom()); // OK (in fact the only way to handle PETSc errors)
617     }
618   };
619 .ve
620 
621   Level: intermediate
622 
623 .seealso: `SETERRABORT()`, `PetscTraceBackErrorHandler()`, `PetscPushErrorHandler()`, `PetscError()`,
624           `SETERRQ()`, `CHKMEMQ`, `PetscCallMPI()`
625 M*/
626 #if defined(PETSC_CLANG_STATIC_ANALYZER)
627 void PetscCallAbort(MPI_Comm, PetscErrorCode);
628 void PetscCallContinue(PetscErrorCode);
629 #else
630 #define PetscCallAbort(comm, ...) \
631   do { \
632     PetscErrorCode ierr_abort_ = __VA_ARGS__; \
633     if (PetscUnlikely(ierr_abort_)) { \
634       PetscError(PETSC_COMM_SELF, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr_abort_, PETSC_ERROR_REPEAT, " "); \
635       MPI_Abort(comm, ierr_abort_); \
636     } \
637   } while (0)
638 #define PetscCallContinue(...) \
639   do { \
640     PetscErrorCode ierr_continue_ = __VA_ARGS__; \
641     if (PetscUnlikely(ierr_continue_)) PetscError(PETSC_COMM_SELF, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr_continue_, PETSC_ERROR_REPEAT, " "); \
642   } while (0)
643 #endif
644 
645 /*MC
646   CHKERRABORT - Checks error code returned from PETSc function. If non-zero it aborts immediately.
647 
648   Synopsis:
649   #include <petscerror.h>
650   void CHKERRABORT(MPI_Comm comm, PetscErrorCode ierr)
651 
652   Not Collective
653 
654   Input Parameters:
655 + comm - the MPI communicator
656 - ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
657 
658   Notes:
659   Deprecated in favor of `PetscCallAbort()`. This routine behaves identically to it.
660 
661   Level: deprecated
662 
663 .seealso: `PetscCallAbort()`
664 M*/
665 #define CHKERRABORT(comm, ...) PetscCallAbort(comm, __VA_ARGS__)
666 #define CHKERRCONTINUE(...)    PetscCallContinue(__VA_ARGS__)
667 
668 /*MC
669    CHKERRA - Fortran-only replacement for use of `CHKERRQ()` in the main program, which aborts immediately
670 
671    Synopsis:
672    #include <petscsys.h>
673    PetscErrorCode CHKERRA(PetscErrorCode ierr)
674 
675    Not Collective
676 
677    Input Parameters:
678 .  ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
679 
680   Level: deprecated
681 
682    Note:
683    This macro is rarely needed, normal usage is `PetscCallA()` in the main Fortran program.
684 
685 .seealso: `PetscCall()`, `PetscCallA()`, `PetscCallAbort()`, `CHKERRQ()`, `SETERRA()`, `SETERRQ()`, `SETERRABORT()`
686 M*/
687 
688 PETSC_EXTERN PetscBool petscwaitonerrorflg;
689 PETSC_EXTERN PetscBool petscindebugger;
690 
691 /*MC
692    PETSCABORT - Call MPI_Abort with an informative error code
693 
694    Synopsis:
695    #include <petscsys.h>
696    PETSCABORT(MPI_Comm comm, PetscErrorCode ierr)
697 
698    Collective
699 
700    Input Parameters:
701 +  comm - A communicator, so that the error can be collective
702 -  ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
703 
704    Level: advanced
705 
706    Notes:
707    If the option -start_in_debugger was used then this calls abort() to stop the program in the debugger.
708 
709    if `PetscCIEnabledPortableErrorOutput` is set it strives to exit cleanly without call `MPI_Abort()`
710 
711  M*/
712 #define PETSCABORT(comm, ...) \
713   do { \
714     if (petscwaitonerrorflg) PetscSleep(1000); \
715     if (petscindebugger) abort(); \
716     else { \
717       PetscErrorCode ierr_petsc_abort_ = __VA_ARGS__; \
718       PetscMPIInt    size; \
719       MPI_Comm_size(comm, &size); \
720       if (PetscCIEnabledPortableErrorOutput && size == PetscGlobalSize && ierr_petsc_abort_ != PETSC_ERR_SIG) { \
721         MPI_Finalize(); \
722         exit(0); \
723       } else if (PetscCIEnabledPortableErrorOutput && PetscGlobalSize == 1) { \
724         exit(0); \
725       } else { \
726         MPI_Abort(comm, (PetscMPIInt)ierr_petsc_abort_); \
727       } \
728     } \
729   } while (0)
730 
731 #ifdef PETSC_CLANGUAGE_CXX
732 /*MC
733   PetscCallThrow - Checks error code, if non-zero it calls the C++ error handler which throws
734   an exception
735 
736   Synopsis:
737   #include <petscerror.h>
738   void PetscCallThrow(PetscErrorCode ierr)
739 
740   Not Collective
741 
742   Input Parameter:
743 . ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
744 
745   Notes:
746   Requires PETSc to be configured with clanguage = c++. Throws a std::runtime_error() on error.
747 
748   Once the error handler throws the exception you can use `PetscCallVoid()` which returns without
749   an error code (bad idea since the error is ignored) or `PetscCallAbort()` to have `MPI_Abort()`
750   called immediately.
751 
752   Level: beginner
753 
754 .seealso: `SETERRQ()`, `PetscCall()`, `SETERRABORT()`, `PetscCallAbort()`, `PetscTraceBackErrorHandler()`,
755           `PetscPushErrorHandler()`, `PetscError()`, `CHKMEMQ`
756 M*/
757 #define PetscCallThrow(...) \
758   do { \
759     PetscErrorCode ierr_cxx_ = __VA_ARGS__; \
760     if (PetscUnlikely(ierr_cxx_)) PetscError(PETSC_COMM_SELF, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr_cxx_, PETSC_ERROR_IN_CXX, PETSC_NULLPTR); \
761   } while (0)
762 
763 /*MC
764   CHKERRXX - Checks error code, if non-zero it calls the C++ error handler which throws an exception
765 
766   Synopsis:
767   #include <petscerror.h>
768   void CHKERRXX(PetscErrorCode ierr)
769 
770   Not Collective
771 
772   Input Parameter:
773 . ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
774 
775   Notes:
776   Deprecated in favor of `PetscCallThrow()`. This routine behaves identically to it.
777 
778   Level: deprecated
779 
780 .seealso: `PetscCallThrow()`
781 M*/
782 #define CHKERRXX(...) PetscCallThrow(__VA_ARGS__)
783 #endif
784 
785 /*MC
786   PetscCallCXX - Checks C++ function calls and if they throw an exception, catch it and then
787   return a PETSc error code
788 
789   Synopsis:
790   #include <petscerror.h>
791   void PetscCallCXX(expr) noexcept;
792 
793   Not Collective
794 
795   Input Parameter:
796 . expr - An arbitrary expression
797 
798   Notes:
799   PetscCallCXX(expr) is a macro replacement for
800 .vb
801   try {
802     expr;
803   } catch (const std::exception& e) {
804     return ConvertToPetscErrorCode(e);
805   }
806 .ve
807   Due to the fact that it catches any (reasonable) exception, it is essentially noexcept.
808 
809   Example Usage:
810 .vb
811   void foo(void) { throw std::runtime_error("error"); }
812 
813   void bar()
814   {
815     PetscCallCXX(foo()); // ERROR bar() does not return PetscErrorCode
816   }
817 
818   PetscErrorCode baz()
819   {
820     PetscCallCXX(foo()); // OK
821 
822     PetscCallCXX(
823       bar();
824       foo(); // OK mutliple statements allowed
825     );
826   }
827 
828   struct bop
829   {
830     bop()
831     {
832       PetscCallCXX(foo()); // ERROR returns PetscErrorCode, cannot be used in constructors
833     }
834   };
835 
836   // ERROR contains do-while, cannot be used as function-try block
837   PetscErrorCode qux() PetscCallCXX(
838     bar();
839     baz();
840     foo();
841     return 0;
842   )
843 .ve
844 
845   Level: beginner
846 
847 .seealso: `PetscCallThrow()`, `SETERRQ()`, `PetscCall()`, `SETERRABORT()`, `PetscCallAbort()`,
848           `PetscTraceBackErrorHandler()`, `PetscPushErrorHandler()`, `PetscError()`, `CHKMEMQ`
849 M*/
850 #define PetscCallCXX(...) \
851   do { \
852     PetscStackUpdateLine; \
853     try { \
854       __VA_ARGS__; \
855     } catch (const std::exception &e) { SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "%s", e.what()); } \
856   } while (0)
857 
858 /*MC
859   CHKERRCXX - Checks C++ function calls and if they throw an exception, catch it and then
860   return a PETSc error code
861 
862   Synopsis:
863   #include <petscerror.h>
864   void CHKERRCXX(func) noexcept;
865 
866   Not Collective
867 
868   Input Parameter:
869 . func - C++ function calls
870 
871   Notes:
872   Deprecated in favor of `PetscCallCXX()`. This routine behaves identically to it.
873 
874   Level: deprecated
875 
876 .seealso: `PetscCallCXX()`
877 M*/
878 #define CHKERRCXX(...) PetscCallCXX(__VA_ARGS__)
879 
880 /*MC
881    CHKMEMQ - Checks the memory for corruption, calls error handler if any is detected
882 
883    Synopsis:
884    #include <petscsys.h>
885    CHKMEMQ;
886 
887    Not Collective
888 
889   Level: beginner
890 
891    Notes:
892     We highly recommend using Valgrind https://petsc.org/release/faq/#valgrind or for NVIDIA CUDA systems
893     https://docs.nvidia.com/cuda/cuda-memcheck/index.html for finding memory problems. The ``CHKMEMQ`` macro is useful on systems that
894     do not have valgrind, but is not as good as valgrind or cuda-memcheck.
895 
896     Must run with the option -malloc_debug (-malloc_test in debug mode; or if `PetscMallocSetDebug()` called) to enable this option
897 
898     Once the error handler is called the calling function is then returned from with the given error code.
899 
900     By defaults prints location where memory that is corrupted was allocated.
901 
902     Use `CHKMEMA` for functions that return void
903 
904 .seealso: `PetscTraceBackErrorHandler()`, `PetscPushErrorHandler()`, `PetscError()`, `SETERRQ()`, `PetscMallocValidate()`
905 M*/
906 #if defined(PETSC_CLANG_STATIC_ANALYZER)
907 #define CHKMEMQ
908 #define CHKMEMA
909 #else
910 #define CHKMEMQ \
911   do { \
912     PetscErrorCode ierr_memq_ = PetscMallocValidate(__LINE__, PETSC_FUNCTION_NAME, __FILE__); \
913     if (PetscUnlikely(ierr_memq_)) return PetscError(PETSC_COMM_SELF, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr_memq_, PETSC_ERROR_REPEAT, " "); \
914   } while (0)
915 #define CHKMEMA PetscMallocValidate(__LINE__, PETSC_FUNCTION_NAME, __FILE__)
916 #endif
917 
918 /*E
919   PetscErrorType - passed to the PETSc error handling routines indicating if this is the first or a later call to the error handlers
920 
921   Level: advanced
922 
923   `PETSC_ERROR_IN_CXX` indicates the error was detected in C++ and an exception should be generated
924 
925   Developer Notes:
926     This is currently used to decide when to print the detailed information about the run in PetscTraceBackErrorHandler()
927 
928 .seealso: `PetscError()`, `SETERRQ()`
929 E*/
930 typedef enum {
931   PETSC_ERROR_INITIAL = 0,
932   PETSC_ERROR_REPEAT  = 1,
933   PETSC_ERROR_IN_CXX  = 2
934 } PetscErrorType;
935 
936 #if defined(__clang_analyzer__)
937 __attribute__((analyzer_noreturn))
938 #endif
939 PETSC_EXTERN PetscErrorCode
940 PetscError(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, ...) PETSC_ATTRIBUTE_COLD PETSC_ATTRIBUTE_FORMAT(7, 8);
941 
942 PETSC_EXTERN PetscErrorCode PetscErrorPrintfInitialize(void);
943 PETSC_EXTERN PetscErrorCode PetscErrorMessage(int, const char *[], char **);
944 PETSC_EXTERN PetscErrorCode PetscTraceBackErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD;
945 PETSC_EXTERN PetscErrorCode PetscIgnoreErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD;
946 PETSC_EXTERN PetscErrorCode PetscEmacsClientErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD;
947 PETSC_EXTERN PetscErrorCode PetscMPIAbortErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD;
948 PETSC_EXTERN PetscErrorCode PetscAbortErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD;
949 PETSC_EXTERN PetscErrorCode PetscAttachDebuggerErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD;
950 PETSC_EXTERN PetscErrorCode PetscReturnErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD;
951 PETSC_EXTERN PetscErrorCode PetscPushErrorHandler(PetscErrorCode (*handler)(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *), void *);
952 PETSC_EXTERN PetscErrorCode PetscPopErrorHandler(void);
953 PETSC_EXTERN PetscErrorCode PetscSignalHandlerDefault(int, void *);
954 PETSC_EXTERN PetscErrorCode PetscPushSignalHandler(PetscErrorCode (*)(int, void *), void *);
955 PETSC_EXTERN PetscErrorCode PetscPopSignalHandler(void);
956 PETSC_EXTERN PetscErrorCode PetscCheckPointerSetIntensity(PetscInt);
957 PETSC_EXTERN void           PetscSignalSegvCheckPointerOrMpi(void);
958 PETSC_DEPRECATED_FUNCTION("Use PetscSignalSegvCheckPointerOrMpi() (since version 3.13)") static inline void PetscSignalSegvCheckPointer(void) {
959   PetscSignalSegvCheckPointerOrMpi();
960 }
961 
962 /*MC
963     PetscErrorPrintf - Prints error messages.
964 
965    Synopsis:
966     #include <petscsys.h>
967      PetscErrorCode (*PetscErrorPrintf)(const char format[],...);
968 
969     Not Collective
970 
971     Input Parameter:
972 .   format - the usual printf() format string
973 
974    Options Database Keys:
975 +    -error_output_stdout - cause error messages to be printed to stdout instead of the (default) stderr
976 -    -error_output_none - to turn off all printing of error messages (does not change the way the error is handled.)
977 
978    Notes:
979     Use
980 $     PetscErrorPrintf = PetscErrorPrintfNone; to turn off all printing of error messages (does not change the way the
981 $                        error is handled.) and
982 $     PetscErrorPrintf = PetscErrorPrintfDefault; to turn it back on or you can use your own function
983 
984           Use
985      `PETSC_STDERR` = FILE* obtained from a file open etc. to have stderr printed to the file.
986      `PETSC_STDOUT` = FILE* obtained from a file open etc. to have stdout printed to the file.
987 
988           Use
989       `PetscPushErrorHandler()` to provide your own error handler that determines what kind of messages to print
990 
991    Level: developer
992 
993     Fortran Note:
994     This routine is not supported in Fortran.
995 
996 .seealso: `PetscFPrintf()`, `PetscSynchronizedPrintf()`, `PetscHelpPrintf()`, `PetscPrintf()`, `PetscPushErrorHandler()`, `PetscVFPrintf()`, `PetscHelpPrintf()`
997 M*/
998 PETSC_EXTERN PetscErrorCode (*PetscErrorPrintf)(const char[], ...) PETSC_ATTRIBUTE_FORMAT(1, 2);
999 
1000 /*E
1001      PetscFPTrap - types of floating point exceptions that may be trapped
1002 
1003      Currently only `PETSC_FP_TRAP_OFF` and `PETSC_FP_TRAP_ON` are handled. All others are treated as `PETSC_FP_TRAP_ON`.
1004 
1005      Level: intermediate
1006 
1007 .seealso: `PetscSetFPTrap()`, `PetscPushFPTrap()`
1008  E*/
1009 typedef enum {
1010   PETSC_FP_TRAP_OFF      = 0,
1011   PETSC_FP_TRAP_INDIV    = 1,
1012   PETSC_FP_TRAP_FLTOPERR = 2,
1013   PETSC_FP_TRAP_FLTOVF   = 4,
1014   PETSC_FP_TRAP_FLTUND   = 8,
1015   PETSC_FP_TRAP_FLTDIV   = 16,
1016   PETSC_FP_TRAP_FLTINEX  = 32
1017 } PetscFPTrap;
1018 #define PETSC_FP_TRAP_ON (PetscFPTrap)(PETSC_FP_TRAP_INDIV | PETSC_FP_TRAP_FLTOPERR | PETSC_FP_TRAP_FLTOVF | PETSC_FP_TRAP_FLTDIV | PETSC_FP_TRAP_FLTINEX)
1019 PETSC_EXTERN PetscErrorCode PetscSetFPTrap(PetscFPTrap);
1020 PETSC_EXTERN PetscErrorCode PetscFPTrapPush(PetscFPTrap);
1021 PETSC_EXTERN PetscErrorCode PetscFPTrapPop(void);
1022 PETSC_EXTERN PetscErrorCode PetscDetermineInitialFPTrap(void);
1023 
1024 /*
1025       Allows the code to build a stack frame as it runs
1026 */
1027 
1028 #if defined(PETSC_USE_DEBUG)
1029 #define PETSCSTACKSIZE 64
1030 typedef struct {
1031   const char *function[PETSCSTACKSIZE];
1032   const char *file[PETSCSTACKSIZE];
1033   int         line[PETSCSTACKSIZE];
1034   int         petscroutine[PETSCSTACKSIZE]; /* 0 external called from petsc, 1 petsc functions, 2 petsc user functions */
1035   int         currentsize;
1036   int         hotdepth;
1037   PetscBool   check; /* option to check for correct Push/Pop semantics, true for default petscstack but not other stacks */
1038 } PetscStack;
1039 PETSC_EXTERN PetscStack petscstack;
1040 #else
1041 typedef struct {
1042   char Silence_empty_struct_has_size_0_in_C_size_1_in_Cpp;
1043 } PetscStack;
1044 #endif
1045 
1046 #if defined(PETSC_SERIALIZE_FUNCTIONS)
1047 #include <petsc/private/petscfptimpl.h>
1048 /*
1049    Registers the current function into the global function pointer to function name table
1050 
1051    Have to fix this to handle errors but cannot return error since used in PETSC_VIEWER_DRAW_() etc
1052 */
1053 #define PetscRegister__FUNCT__() \
1054   do { \
1055     static PetscBool __chked = PETSC_FALSE; \
1056     if (!__chked) { \
1057       void *ptr; \
1058       PetscDLSym(NULL, PETSC_FUNCTION_NAME, &ptr); \
1059       __chked = PETSC_TRUE; \
1060     } \
1061   } while (0)
1062 #else
1063 #define PetscRegister__FUNCT__()
1064 #endif
1065 
1066 #if defined(PETSC_CLANG_STATIC_ANALYZER)
1067 #define PetscStackPushNoCheck(funct, petsc_routine, hot)
1068 #define PetscStackUpdateLine
1069 #define PetscStackPushExternal(funct)
1070 #define PetscStackPopNoCheck
1071 #define PetscStackClearTop
1072 #define PetscFunctionBegin
1073 #define PetscFunctionBeginUser
1074 #define PetscFunctionBeginHot
1075 #define PetscFunctionReturn(a)    return a
1076 #define PetscFunctionReturnVoid() return
1077 #define PetscStackPop
1078 #define PetscStackPush(f)
1079 #elif defined(PETSC_USE_DEBUG)
1080 
1081 #define PetscStackPush_Private(stack__, file__, func__, line__, petsc_routine__, hot__) \
1082   do { \
1083     if (stack__.currentsize < PETSCSTACKSIZE) { \
1084       stack__.function[stack__.currentsize] = func__; \
1085       if (petsc_routine__) { \
1086         stack__.file[stack__.currentsize] = file__; \
1087         stack__.line[stack__.currentsize] = line__; \
1088       } else { \
1089         stack__.file[stack__.currentsize] = PETSC_NULLPTR; \
1090         stack__.line[stack__.currentsize] = 0; \
1091       } \
1092       stack__.petscroutine[stack__.currentsize] = petsc_routine__; \
1093     } \
1094     ++stack__.currentsize; \
1095     stack__.hotdepth += (hot__ || stack__.hotdepth); \
1096   } while (0)
1097 
1098 /* uses PetscCheckAbort() because may be used in a function that does not return an error code */
1099 #define PetscStackPop_Private(stack__, func__) \
1100   do { \
1101     PetscCheckAbort(!stack__.check || stack__.currentsize > 0, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Invalid stack size %d, pop %s %s:%d.\n", stack__.currentsize, func__, __FILE__, __LINE__); \
1102     if (--stack__.currentsize < PETSCSTACKSIZE) { \
1103       PetscCheckAbort(!stack__.check || stack__.petscroutine[stack__.currentsize] != 1 || stack__.function[stack__.currentsize] == (const char *)(func__), PETSC_COMM_SELF, PETSC_ERR_PLIB, "Invalid stack: push from %s %s:%d. Pop from %s %s:%d.\n", \
1104                       stack__.function[stack__.currentsize], stack__.file[stack__.currentsize], stack__.line[stack__.currentsize], func__, __FILE__, __LINE__); \
1105       stack__.function[stack__.currentsize]     = PETSC_NULLPTR; \
1106       stack__.file[stack__.currentsize]         = PETSC_NULLPTR; \
1107       stack__.line[stack__.currentsize]         = 0; \
1108       stack__.petscroutine[stack__.currentsize] = 0; \
1109     } \
1110     stack__.hotdepth = PetscMax(stack__.hotdepth - 1, 0); \
1111   } while (0)
1112 
1113 /*MC
1114    PetscStackPushNoCheck - Pushes a new function name and line number onto the PETSc default stack that tracks where the running program is
1115    currently in the source code.
1116 
1117    Not Collective
1118 
1119    Synopsis:
1120    #include <petscsys.h>
1121    void PetscStackPushNoCheck(char *funct,int petsc_routine,PetscBool hot);
1122 
1123    Input Parameters:
1124 +  funct - the function name
1125 .  petsc_routine - 2 user function, 1 PETSc function, 0 some other function
1126 -  hot - indicates that the function may be called often so expensive error checking should be turned off inside the function
1127 
1128    Level: developer
1129 
1130    Notes:
1131    In debug mode PETSc maintains a stack of the current function calls that can be used to help to quickly see where a problem has
1132    occurred, for example, when a signal is received without running in the debugger. It is recommended to use the debugger if extensive information is needed to
1133    help debug the problem.
1134 
1135    This version does not check the memory corruption (an expensive operation), use `PetscStackPush()` to check the memory.
1136 
1137    Use `PetscStackPushExternal()` for a function call that is about to be made to a non-PETSc or user function (such as BLAS etc).
1138 
1139    The default stack is a global variable called `petscstack`.
1140 
1141 .seealso: `PetscAttachDebugger()`, `PetscStackCopy()`, `PetscStackView()`, `PetscStackPopNoCheck()`, `PetscCall()`, `PetscFunctionBegin()`,
1142           `PetscFunctionReturn()`, `PetscFunctionBeginHot()`, `PetscFunctionBeginUser()`, `PetscStackPush()`, `PetscStackPop`,
1143           `PetscStackPushExternal()`
1144 M*/
1145 #define PetscStackPushNoCheck(funct, petsc_routine, hot) \
1146   do { \
1147     PetscStackSAWsTakeAccess(); \
1148     PetscStackPush_Private(petscstack, __FILE__, funct, __LINE__, petsc_routine, hot); \
1149     PetscStackSAWsGrantAccess(); \
1150   } while (0)
1151 
1152 /*MC
1153    PetscStackUpdateLine - in a function that has a `PetscFunctionBegin` or `PetscFunctionBeginUser` updates the stack line number to the
1154    current line number.
1155 
1156    Not Collective
1157 
1158    Synopsis:
1159    #include <petscsys.h>
1160    void PetscStackUpdateLine
1161 
1162    Level: developer
1163 
1164    Notes:
1165    Using `PetscCall()` and friends automatically handles this process
1166 
1167    In debug mode PETSc maintains a stack of the current function calls that can be used to help to quickly see where a problem has
1168    occurred, for example, when a signal is received. It is recommended to use the debugger if extensive information is needed to
1169    help debug the problem.
1170 
1171    The default stack is a global variable called petscstack.
1172 
1173    This is used by `PetscCall()` and is otherwise not like to be needed
1174 
1175 .seealso: `PetscAttachDebugger()`, `PetscStackCopy()`, `PetscStackView()`, `PetscStackPushNoCheck()`, `PetscStackPop`, `PetscCall()`
1176 M*/
1177 #define PetscStackUpdateLine \
1178   if (petscstack.currentsize > 0 && petscstack.function[petscstack.currentsize - 1] == PETSC_FUNCTION_NAME) { petscstack.line[petscstack.currentsize - 1] = __LINE__; }
1179 
1180 /*MC
1181    PetscStackPushExternal - Pushes a new function name onto the PETSc default stack that tracks where the running program is
1182    currently in the source code. Does not include the filename or line number since this is called by the calling routine
1183    for non-PETSc or user functions.
1184 
1185    Not Collective
1186 
1187    Synopsis:
1188    #include <petscsys.h>
1189    void PetscStackPushExternal(char *funct);
1190 
1191    Input Parameters:
1192 .  funct - the function name
1193 
1194    Level: developer
1195 
1196    Notes:
1197    Using `PetscCallExternal()` and friends automatically handles this process
1198 
1199    In debug mode PETSc maintains a stack of the current function calls that can be used to help to quickly see where a problem has
1200    occurred, for example, when a signal is received. It is recommended to use the debugger if extensive information is needed to
1201    help debug the problem.
1202 
1203    The default stack is a global variable called `petscstack`.
1204 
1205    This is to be used when calling an external package function such as a BLAS function.
1206 
1207    This also updates the stack line number for the current stack function.
1208 
1209 .seealso: `PetscAttachDebugger()`, `PetscStackCopy()`, `PetscStackView()`, `PetscStackPopNoCheck()`, `PetscCall()`, `PetscFunctionBegin()`,
1210           `PetscFunctionReturn()`, `PetscFunctionBeginHot()`, `PetscFunctionBeginUser()`, `PetscStackPushNoCheck()`, `PetscStackPop`
1211 M*/
1212 #define PetscStackPushExternal(funct) \
1213   do { \
1214     PetscStackUpdateLine; \
1215     PetscStackPushNoCheck(funct, 0, PETSC_TRUE); \
1216   } while (0);
1217 
1218 /*MC
1219    PetscStackPopNoCheck - Pops a function name from the PETSc default stack that tracks where the running program is
1220    currently in the source code.
1221 
1222    Not Collective
1223 
1224    Synopsis:
1225    #include <petscsys.h>
1226    void PetscStackPopNoCheck(char *funct);
1227 
1228    Input Parameter:
1229 .   funct - the function name
1230 
1231    Level: developer
1232 
1233    Notes:
1234    Using `PetscCall()`, `PetscCallExternal()`, `PetscCallBack()` and friends negates the need to call this
1235 
1236    In debug mode PETSc maintains a stack of the current function calls that can be used to help to quickly see where a problem has
1237    occurred, for example, when a signal is received. It is recommended to use the debugger if extensive information is needed to
1238    help debug the problem.
1239 
1240    The default stack is a global variable called petscstack.
1241 
1242    Developer Note:
1243    `PetscStackPopNoCheck()` takes a function argument while  `PetscStackPop` does not, this difference is likely just historical.
1244 
1245 .seealso: `PetscAttachDebugger()`, `PetscStackCopy()`, `PetscStackView()`, `PetscStackPushNoCheck()`, `PetscStackPop`
1246 M*/
1247 #define PetscStackPopNoCheck(funct) \
1248   do { \
1249     PetscStackSAWsTakeAccess(); \
1250     PetscStackPop_Private(petscstack, funct); \
1251     PetscStackSAWsGrantAccess(); \
1252   } while (0)
1253 
1254 #define PetscStackClearTop \
1255   do { \
1256     PetscStackSAWsTakeAccess(); \
1257     if (petscstack.currentsize > 0 && --petscstack.currentsize < PETSCSTACKSIZE) { \
1258       petscstack.function[petscstack.currentsize]     = PETSC_NULLPTR; \
1259       petscstack.file[petscstack.currentsize]         = PETSC_NULLPTR; \
1260       petscstack.line[petscstack.currentsize]         = 0; \
1261       petscstack.petscroutine[petscstack.currentsize] = 0; \
1262     } \
1263     petscstack.hotdepth = PetscMax(petscstack.hotdepth - 1, 0); \
1264     PetscStackSAWsGrantAccess(); \
1265   } while (0)
1266 
1267 /*MC
1268    PetscFunctionBegin - First executable line of each PETSc function,  used for error handling. Final
1269       line of PETSc functions should be `PetscFunctionReturn`(0);
1270 
1271    Synopsis:
1272    #include <petscsys.h>
1273    void PetscFunctionBegin;
1274 
1275    Not Collective
1276 
1277    Usage:
1278 .vb
1279      int something;
1280 
1281      PetscFunctionBegin;
1282 .ve
1283 
1284    Notes:
1285      Use `PetscFunctionBeginUser` for application codes.
1286 
1287      Not available in Fortran
1288 
1289    Level: developer
1290 
1291 .seealso: `PetscFunctionReturn()`, `PetscFunctionBeginHot()`, `PetscFunctionBeginUser()`, `PetscStackPushNoCheck()`
1292 
1293 M*/
1294 #define PetscFunctionBegin \
1295   do { \
1296     PetscStackPushNoCheck(PETSC_FUNCTION_NAME, 1, PETSC_FALSE); \
1297     PetscRegister__FUNCT__(); \
1298   } while (0)
1299 
1300 /*MC
1301    PetscFunctionBeginHot - Substitute for `PetscFunctionBegin` to be used in functions that are called in
1302    performance-critical circumstances.  Use of this function allows for lighter profiling by default.
1303 
1304    Synopsis:
1305    #include <petscsys.h>
1306    void PetscFunctionBeginHot;
1307 
1308    Not Collective
1309 
1310    Usage:
1311 .vb
1312      int something;
1313 
1314      PetscFunctionBeginHot;
1315 .ve
1316 
1317    Notes:
1318      Not available in Fortran
1319 
1320    Level: developer
1321 
1322 .seealso: `PetscFunctionBegin`, `PetscFunctionReturn()`, `PetscStackPushNoCheck()`
1323 
1324 M*/
1325 #define PetscFunctionBeginHot \
1326   do { \
1327     PetscStackPushNoCheck(PETSC_FUNCTION_NAME, 1, PETSC_TRUE); \
1328     PetscRegister__FUNCT__(); \
1329   } while (0)
1330 
1331 /*MC
1332    PetscFunctionBeginUser - First executable line of user provided routines
1333 
1334    Synopsis:
1335    #include <petscsys.h>
1336    void PetscFunctionBeginUser;
1337 
1338    Not Collective
1339 
1340    Usage:
1341 .vb
1342      int something;
1343 
1344      PetscFunctionBeginUser;
1345 .ve
1346 
1347    Notes:
1348       Functions that incorporate this must call `PetscFunctionReturn()` instead of return except for main().
1349 
1350       May be used before `PetscInitialize()`
1351 
1352       Not available in Fortran
1353 
1354       This is identical to `PetscFunctionBegin` except it labels the routine as a user
1355       routine instead of as a PETSc library routine.
1356 
1357    Level: intermediate
1358 
1359 .seealso: `PetscFunctionReturn()`, `PetscFunctionBegin`, `PetscFunctionBeginHot`, `PetscStackPushNoCheck()`
1360 
1361 M*/
1362 #define PetscFunctionBeginUser \
1363   do { \
1364     PetscStackPushNoCheck(PETSC_FUNCTION_NAME, 2, PETSC_FALSE); \
1365     PetscRegister__FUNCT__(); \
1366   } while (0)
1367 
1368 /*MC
1369    PetscStackPush - Pushes a new function name and line number onto the PETSc default stack that tracks where the running program is
1370    currently in the source code and verifies the memory is not corrupted.
1371 
1372    Not Collective
1373 
1374    Synopsis:
1375    #include <petscsys.h>
1376    void PetscStackPush(char *funct)
1377 
1378    Input Parameter:
1379 .  funct - the function name
1380 
1381    Level: developer
1382 
1383    Notes:
1384    In debug mode PETSc maintains a stack of the current function calls that can be used to help to quickly see where a problem has
1385    occurred, for example, when a signal is received. It is recommended to use the debugger if extensive information is needed to
1386    help debug the problem.
1387 
1388    The default stack is a global variable called petscstack.
1389 
1390 .seealso: `PetscAttachDebugger()`, `PetscStackCopy()`, `PetscStackView()`, `PetscStackPopNoCheck()`, `PetscCall()`, `PetscFunctionBegin()`,
1391           `PetscFunctionReturn()`, `PetscFunctionBeginHot()`, `PetscFunctionBeginUser()`, `PetscStackPushNoCheck()`, `PetscStackPop`
1392 M*/
1393 #define PetscStackPush(n) \
1394   do { \
1395     PetscStackPushNoCheck(n, 0, PETSC_FALSE); \
1396     CHKMEMQ; \
1397   } while (0)
1398 
1399 /*MC
1400    PetscStackPop - Pops a function name from the PETSc default stack that tracks where the running program is
1401    currently in the source code and verifies the memory is not corrupted.
1402 
1403    Not Collective
1404 
1405    Synopsis:
1406    #include <petscsys.h>
1407    void PetscStackPop
1408 
1409    Level: developer
1410 
1411    Notes:
1412    In debug mode PETSc maintains a stack of the current function calls that can be used to help to quickly see where a problem has
1413    occurred, for example, when a signal is received. It is recommended to use the debugger if extensive information is needed to
1414    help debug the problem.
1415 
1416    The default stack is a global variable called petscstack.
1417 
1418 .seealso: `PetscAttachDebugger()`, `PetscStackCopy()`, `PetscStackView()`, `PetscStackPushNoCheck()`, `PetscStackPopNoCheck()`, `PetscStackPush()`
1419 M*/
1420 #define PetscStackPop \
1421   do { \
1422     CHKMEMQ; \
1423     PetscStackPopNoCheck(PETSC_FUNCTION_NAME); \
1424   } while (0)
1425 
1426 /*MC
1427    PetscFunctionReturn - Last executable line of each PETSc function
1428         used for error handling. Replaces `return()`
1429 
1430    Synopsis:
1431    #include <petscsys.h>
1432    void PetscFunctionReturn(0);
1433 
1434    Not Collective
1435 
1436    Usage:
1437 .vb
1438     ....
1439      PetscFunctionReturn(0);
1440    }
1441 .ve
1442 
1443    Note:
1444      Not available in Fortran
1445 
1446    Level: developer
1447 
1448 .seealso: `PetscFunctionBegin()`, `PetscStackPopNoCheck()`
1449 
1450 M*/
1451 #define PetscFunctionReturn(a) \
1452   do { \
1453     PetscStackPopNoCheck(PETSC_FUNCTION_NAME); \
1454     return a; \
1455   } while (0)
1456 
1457 #define PetscFunctionReturnVoid() \
1458   do { \
1459     PetscStackPopNoCheck(PETSC_FUNCTION_NAME); \
1460     return; \
1461   } while (0)
1462 #else /* PETSC_USE_DEBUG */
1463 #define PetscStackPushNoCheck(funct, petsc_routine, hot)
1464 #define PetscStackUpdateLine
1465 #define PetscStackPushExternal(funct)
1466 #define PetscStackPopNoCheck
1467 #define PetscStackClearTop
1468 #define PetscFunctionBegin
1469 #define PetscFunctionBeginUser
1470 #define PetscFunctionBeginHot
1471 #define PetscFunctionReturn(a)    return a
1472 #define PetscFunctionReturnVoid() return
1473 #define PetscStackPop             CHKMEMQ
1474 #define PetscStackPush(f)         CHKMEMQ
1475 #endif /* PETSC_USE_DEBUG */
1476 
1477 #if defined(PETSC_CLANG_STATIC_ANALYZER)
1478 #define PetscStackCallExternalVoid(name, routine)
1479 #define PetscCallExternal(func, ...)
1480 #else
1481 /*MC
1482     PetscStackCallExternalVoid - Calls an external library routine or user function after pushing the name of the routine on the stack.
1483 
1484    Input Parameters:
1485 +   name - string that gives the name of the function being called
1486 -   routine - actual call to the routine, for example, functionname(a,b)
1487 
1488    Level: developer
1489 
1490    Note:
1491    Often one should use `PetscCallExternal()` instead. This routine is intended for external library routines that DO NOT return error codes
1492 
1493    In debug mode this also checks the memory for corruption at the end of the function call.
1494 
1495    Certain external packages, such as BLAS/LAPACK may have their own macros for managing the call, error checking, etc.
1496 
1497    Developer Note:
1498    This is so that when a user or external library routine results in a crash or corrupts memory, they get blamed instead of PETSc.
1499 
1500 .seealso: `PetscCall()`, `PetscStackPushNoCheck()`, `PetscStackPush()`, `PetscCallExternal()`, `PetscCallBLAS()`
1501 @*/
1502 #define PetscStackCallExternalVoid(name, routine) \
1503   do { \
1504     PetscStackPush(name); \
1505     routine; \
1506     PetscStackPop; \
1507   } while (0)
1508 
1509 /*MC
1510     PetscCallExternal - Calls an external library routine that returns an error code after pushing the name of the routine on the stack.
1511 
1512    Input Parameters:
1513 +   func-  name of the routine
1514 -   args - arguments to the routine
1515 
1516    Level: developer
1517 
1518    Notes:
1519    This is intended for external package routines that return error codes. Use `PetscStackCallExternalVoid()` for those that do not.
1520 
1521    In debug mode this also checks the memory for corruption at the end of the function call.
1522 
1523    Assumes the error return code of the function is an integer and that a value of 0 indicates success
1524 
1525    Developer Note:
1526    This is so that when an external packge routine results in a crash or corrupts memory, they get blamed instead of PETSc.
1527 
1528 .seealso: `PetscCall()`, `PetscStackPushNoCheck()`, `PetscStackPush()`, `PetscStackCallExternalVoid()`
1529 M*/
1530 #define PetscCallExternal(func, ...) \
1531   do { \
1532     PetscStackPush(PetscStringize(func)); \
1533     PetscErrorCode __ierr = func(__VA_ARGS__); \
1534     PetscStackPop; \
1535     PetscCheck(!__ierr, PETSC_COMM_SELF, PETSC_ERR_LIB, "Error in %s(): error code %d", PetscStringize(func), __ierr); \
1536   } while (0)
1537 #endif /* PETSC_CLANG_STATIC_ANALYZER */
1538 
1539 #endif
1540