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