xref: /petsc/include/petscerror.h (revision eae3dc7d82c4e75c6efc83af6cf84b0783a1b49f)
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 on `comm`
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   Fortran Note:
942   Not available from Fortran.
943 
944   Example Usage:
945 .vb
946   class Foo
947   {
948     std::vector<int> data_;
949 
950   public:
951     // normally std::vector::reserve() may raise an exception, but since we handle it with
952     // PetscCallCXXAbort() we may mark this routine as noexcept!
953     Foo() noexcept
954     {
955       PetscCallCXXAbort(PETSC_COMM_SELF, data_.reserve(10));
956     }
957   };
958 
959   std::vector<int> bar()
960   {
961     std::vector<int> v;
962 
963     PetscFunctionBegin;
964     // OK!
965     PetscCallCXXAbort(PETSC_COMM_SELF, v.emplace_back(1));
966     PetscFunctionReturn(v);
967   }
968 
969   PetscErrorCode baz()
970   {
971     std::vector<int> v;
972 
973     PetscFunctionBegin;
974     // WRONG! baz() returns a PetscErrorCode, prefer PetscCallCXX() instead
975     PetscCallCXXAbort(PETSC_COMM_SELF, v.emplace_back(1));
976     PetscFunctionReturn(PETSC_SUCCESS);
977   }
978 .ve
979 
980 .seealso: `PetscCallCXX()`, `SETERRABORT()`, `PetscCallAbort()`
981 M*/
982 #define PetscCallCXXAbort(comm, ...) PetscCallCXX_Private(SETERRABORT, comm, __VA_ARGS__)
983 
984 /*MC
985   CHKERRCXX - Checks C++ function calls and if they throw an exception, catch it and then
986   return a PETSc error code
987 
988   Synopsis:
989   #include <petscerror.h>
990   void CHKERRCXX(func) noexcept;
991 
992   Not Collective
993 
994   Input Parameter:
995 . func - C++ function calls
996 
997   Level: deprecated
998 
999   Note:
1000   Deprecated in favor of `PetscCallCXX()`. This routine behaves identically to it.
1001 
1002 .seealso: `PetscCallCXX()`
1003 M*/
1004 #define CHKERRCXX(...) PetscCallCXX(__VA_ARGS__)
1005 
1006 /*MC
1007    CHKMEMQ - Checks the memory for corruption, calls error handler if any is detected
1008 
1009    Synopsis:
1010    #include <petscsys.h>
1011    CHKMEMQ;
1012 
1013    Not Collective
1014 
1015   Level: beginner
1016 
1017    Notes:
1018     We highly recommend using Valgrind https://petsc.org/release/faq/#valgrind or for NVIDIA CUDA systems
1019     https://docs.nvidia.com/cuda/cuda-memcheck/index.html for finding memory problems. The ``CHKMEMQ`` macro is useful on systems that
1020     do not have valgrind, but is not as good as valgrind or cuda-memcheck.
1021 
1022     Must run with the option `-malloc_debug` (`-malloc_test` in debug mode; or if `PetscMallocSetDebug()` called) to enable this option
1023 
1024     Once the error handler is called the calling function is then returned from with the given error code.
1025 
1026     By defaults prints location where memory that is corrupted was allocated.
1027 
1028     Use `CHKMEMA` for functions that return void
1029 
1030 .seealso: `PetscTraceBackErrorHandler()`, `PetscPushErrorHandler()`, `PetscError()`, `SETERRQ()`, `PetscMallocValidate()`
1031 M*/
1032 #if defined(PETSC_CLANG_STATIC_ANALYZER)
1033   #define CHKMEMQ
1034   #define CHKMEMA
1035 #else
1036   #define CHKMEMQ \
1037     do { \
1038       PetscErrorCode ierr_petsc_memq_ = PetscMallocValidate(__LINE__, PETSC_FUNCTION_NAME, __FILE__); \
1039       if (PetscUnlikely(ierr_petsc_memq_ != PETSC_SUCCESS)) return PetscError(PETSC_COMM_SELF, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr_petsc_memq_, PETSC_ERROR_REPEAT, " "); \
1040     } while (0)
1041   #define CHKMEMA PetscMallocValidate(__LINE__, PETSC_FUNCTION_NAME, __FILE__)
1042 #endif
1043 
1044 /*E
1045   PetscErrorType - passed to the PETSc error handling routines indicating if this is the first or a later call to the error handlers
1046 
1047   Level: advanced
1048 
1049   Note:
1050   `PETSC_ERROR_IN_CXX` indicates the error was detected in C++ and an exception should be generated
1051 
1052   Developer Note:
1053     This is currently used to decide when to print the detailed information about the run in `PetscTraceBackErrorHandler()`
1054 
1055 .seealso: `PetscError()`, `SETERRQ()`
1056 E*/
1057 typedef enum {
1058   PETSC_ERROR_INITIAL = 0,
1059   PETSC_ERROR_REPEAT  = 1,
1060   PETSC_ERROR_IN_CXX  = 2
1061 } PetscErrorType;
1062 
1063 #if defined(__clang_analyzer__)
1064 __attribute__((analyzer_noreturn))
1065 #endif
1066 PETSC_EXTERN PetscErrorCode
1067 PetscError(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, ...) PETSC_ATTRIBUTE_COLD PETSC_ATTRIBUTE_FORMAT(7, 8);
1068 
1069 PETSC_EXTERN PetscErrorCode PetscErrorPrintfInitialize(void);
1070 PETSC_EXTERN PetscErrorCode PetscErrorMessage(PetscErrorCode, const char *[], char **);
1071 PETSC_EXTERN PetscErrorCode PetscTraceBackErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD;
1072 PETSC_EXTERN PetscErrorCode PetscIgnoreErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD;
1073 PETSC_EXTERN PetscErrorCode PetscEmacsClientErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD;
1074 PETSC_EXTERN PetscErrorCode PetscMPIAbortErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD;
1075 PETSC_EXTERN PetscErrorCode PetscAbortErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD;
1076 PETSC_EXTERN PetscErrorCode PetscAttachDebuggerErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD;
1077 PETSC_EXTERN PetscErrorCode PetscReturnErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD;
1078 PETSC_EXTERN PetscErrorCode PetscPushErrorHandler(PetscErrorCode (*handler)(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *), void *);
1079 PETSC_EXTERN PetscErrorCode PetscPopErrorHandler(void);
1080 PETSC_EXTERN PetscErrorCode PetscSignalHandlerDefault(int, void *);
1081 PETSC_EXTERN PetscErrorCode PetscPushSignalHandler(PetscErrorCode (*)(int, void *), void *);
1082 PETSC_EXTERN PetscErrorCode PetscPopSignalHandler(void);
1083 PETSC_EXTERN PetscErrorCode PetscCheckPointerSetIntensity(PetscInt);
1084 PETSC_EXTERN void           PetscSignalSegvCheckPointerOrMpi(void);
1085 PETSC_DEPRECATED_FUNCTION("Use PetscSignalSegvCheckPointerOrMpi() (since version 3.13)") static inline void PetscSignalSegvCheckPointer(void)
1086 {
1087   PetscSignalSegvCheckPointerOrMpi();
1088 }
1089 
1090 /*MC
1091     PetscErrorPrintf - Prints error messages.
1092 
1093     Not Collective; No Fortran Support
1094 
1095    Synopsis:
1096     #include <petscsys.h>
1097      PetscErrorCode (*PetscErrorPrintf)(const char format[],...);
1098 
1099     Input Parameter:
1100 .   format - the usual `printf()` format string
1101 
1102    Options Database Keys:
1103 +    -error_output_stdout - cause error messages to be printed to stdout instead of the (default) stderr
1104 -    -error_output_none - to turn off all printing of error messages (does not change the way the error is handled.)
1105 
1106    Level: developer
1107 
1108    Notes:
1109     Use
1110 .vb
1111      PetscErrorPrintf = PetscErrorPrintfNone; to turn off all printing of error messages (does not change the way the
1112                         error is handled.) and
1113      PetscErrorPrintf = PetscErrorPrintfDefault; to turn it back on or you can use your own function
1114 .ve
1115      Use
1116 .vb
1117      `PETSC_STDERR` = FILE* obtained from a file open etc. to have stderr printed to the file.
1118      `PETSC_STDOUT` = FILE* obtained from a file open etc. to have stdout printed to the file.
1119 .ve
1120 
1121        Use
1122       `PetscPushErrorHandler()` to provide your own error handler that determines what kind of messages to print
1123 
1124 .seealso: `PetscFPrintf()`, `PetscSynchronizedPrintf()`, `PetscHelpPrintf()`, `PetscPrintf()`, `PetscPushErrorHandler()`, `PetscVFPrintf()`, `PetscHelpPrintf()`
1125 M*/
1126 PETSC_EXTERN PetscErrorCode (*PetscErrorPrintf)(const char[], ...) PETSC_ATTRIBUTE_FORMAT(1, 2);
1127 
1128 /*E
1129      PetscFPTrap - types of floating point exceptions that may be trapped
1130 
1131      Currently only `PETSC_FP_TRAP_OFF` and `PETSC_FP_TRAP_ON` are handled. All others are treated as `PETSC_FP_TRAP_ON`.
1132 
1133      Level: intermediate
1134 
1135 .seealso: `PetscSetFPTrap()`, `PetscPushFPTrap()`
1136  E*/
1137 typedef enum {
1138   PETSC_FP_TRAP_OFF      = 0,
1139   PETSC_FP_TRAP_INDIV    = 1,
1140   PETSC_FP_TRAP_FLTOPERR = 2,
1141   PETSC_FP_TRAP_FLTOVF   = 4,
1142   PETSC_FP_TRAP_FLTUND   = 8,
1143   PETSC_FP_TRAP_FLTDIV   = 16,
1144   PETSC_FP_TRAP_FLTINEX  = 32
1145 } PetscFPTrap;
1146 #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)
1147 PETSC_EXTERN PetscErrorCode PetscSetFPTrap(PetscFPTrap);
1148 PETSC_EXTERN PetscErrorCode PetscFPTrapPush(PetscFPTrap);
1149 PETSC_EXTERN PetscErrorCode PetscFPTrapPop(void);
1150 PETSC_EXTERN PetscErrorCode PetscDetermineInitialFPTrap(void);
1151 
1152 /*
1153       Allows the code to build a stack frame as it runs
1154 */
1155 
1156 #define PETSCSTACKSIZE 64
1157 typedef struct {
1158   const char *function[PETSCSTACKSIZE];
1159   const char *file[PETSCSTACKSIZE];
1160   int         line[PETSCSTACKSIZE];
1161   int         petscroutine[PETSCSTACKSIZE]; /* 0 external called from petsc, 1 petsc functions, 2 petsc user functions */
1162   int         currentsize;
1163   int         hotdepth;
1164   PetscBool   check; /* option to check for correct Push/Pop semantics, true for default petscstack but not other stacks */
1165 } PetscStack;
1166 #if defined(PETSC_USE_DEBUG) && !defined(PETSC_HAVE_THREADSAFETY)
1167 PETSC_EXTERN PetscStack petscstack;
1168 #endif
1169 
1170 #if defined(PETSC_SERIALIZE_FUNCTIONS)
1171   #include <petsc/private/petscfptimpl.h>
1172   /*
1173    Registers the current function into the global function pointer to function name table
1174 
1175    Have to fix this to handle errors but cannot return error since used in PETSC_VIEWER_DRAW_() etc
1176 */
1177   #define PetscRegister__FUNCT__() \
1178     do { \
1179       static PetscBool __chked = PETSC_FALSE; \
1180       if (!__chked) { \
1181         void *ptr; \
1182         PetscCallAbort(PETSC_COMM_SELF, PetscDLSym(NULL, PETSC_FUNCTION_NAME, &ptr)); \
1183         __chked = PETSC_TRUE; \
1184       } \
1185     } while (0)
1186 #else
1187   #define PetscRegister__FUNCT__()
1188 #endif
1189 
1190 #if defined(PETSC_CLANG_STATIC_ANALYZER) || defined(__clang_analyzer__)
1191   #define PetscStackPushNoCheck(funct, petsc_routine, hot)
1192   #define PetscStackUpdateLine
1193   #define PetscStackPushExternal(funct)
1194   #define PetscStackPopNoCheck
1195   #define PetscStackClearTop
1196   #define PetscFunctionBegin
1197   #define PetscFunctionBeginUser
1198   #define PetscFunctionBeginHot
1199   #define PetscFunctionReturn(...)  return __VA_ARGS__
1200   #define PetscFunctionReturnVoid() return
1201   #define PetscStackPop
1202   #define PetscStackPush(f)
1203 #elif defined(PETSC_USE_DEBUG) && !defined(PETSC_HAVE_THREADSAFETY)
1204 
1205   #define PetscStackPush_Private(stack__, file__, func__, line__, petsc_routine__, hot__) \
1206     do { \
1207       if (stack__.currentsize < PETSCSTACKSIZE) { \
1208         stack__.function[stack__.currentsize] = func__; \
1209         if (petsc_routine__) { \
1210           stack__.file[stack__.currentsize] = file__; \
1211           stack__.line[stack__.currentsize] = line__; \
1212         } else { \
1213           stack__.file[stack__.currentsize] = PETSC_NULLPTR; \
1214           stack__.line[stack__.currentsize] = 0; \
1215         } \
1216         stack__.petscroutine[stack__.currentsize] = petsc_routine__; \
1217       } \
1218       ++stack__.currentsize; \
1219       stack__.hotdepth += (hot__ || stack__.hotdepth); \
1220     } while (0)
1221 
1222   /* uses PetscCheckAbort() because may be used in a function that does not return an error code */
1223   #define PetscStackPop_Private(stack__, func__) \
1224     do { \
1225       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__); \
1226       if (--stack__.currentsize < PETSCSTACKSIZE) { \
1227         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", \
1228                         stack__.function[stack__.currentsize], stack__.file[stack__.currentsize], stack__.line[stack__.currentsize], func__, __FILE__, __LINE__); \
1229         stack__.function[stack__.currentsize]     = PETSC_NULLPTR; \
1230         stack__.file[stack__.currentsize]         = PETSC_NULLPTR; \
1231         stack__.line[stack__.currentsize]         = 0; \
1232         stack__.petscroutine[stack__.currentsize] = 0; \
1233       } \
1234       stack__.hotdepth = PetscMax(stack__.hotdepth - 1, 0); \
1235     } while (0)
1236 
1237   /*MC
1238    PetscStackPushNoCheck - Pushes a new function name and line number onto the PETSc default stack that tracks where the running program is
1239    currently in the source code.
1240 
1241    Not Collective
1242 
1243    Synopsis:
1244    #include <petscsys.h>
1245    void PetscStackPushNoCheck(char *funct,int petsc_routine,PetscBool hot);
1246 
1247    Input Parameters:
1248 +  funct - the function name
1249 .  petsc_routine - 2 user function, 1 PETSc function, 0 some other function
1250 -  hot - indicates that the function may be called often so expensive error checking should be turned off inside the function
1251 
1252    Level: developer
1253 
1254    Notes:
1255    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
1256    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
1257    help debug the problem.
1258 
1259    This version does not check the memory corruption (an expensive operation), use `PetscStackPush()` to check the memory.
1260 
1261    Use `PetscStackPushExternal()` for a function call that is about to be made to a non-PETSc or user function (such as BLAS etc).
1262 
1263    The default stack is a global variable called `petscstack`.
1264 
1265 .seealso: `PetscAttachDebugger()`, `PetscStackCopy()`, `PetscStackView()`, `PetscStackPopNoCheck()`, `PetscCall()`, `PetscFunctionBegin()`,
1266           `PetscFunctionReturn()`, `PetscFunctionBeginHot()`, `PetscFunctionBeginUser()`, `PetscStackPush()`, `PetscStackPop`,
1267           `PetscStackPushExternal()`
1268 M*/
1269   #define PetscStackPushNoCheck(funct, petsc_routine, hot) \
1270     do { \
1271       PetscStackSAWsTakeAccess(); \
1272       PetscStackPush_Private(petscstack, __FILE__, funct, __LINE__, petsc_routine, hot); \
1273       PetscStackSAWsGrantAccess(); \
1274     } while (0)
1275 
1276   /*MC
1277    PetscStackUpdateLine - in a function that has a `PetscFunctionBegin` or `PetscFunctionBeginUser` updates the stack line number to the
1278    current line number.
1279 
1280    Not Collective
1281 
1282    Synopsis:
1283    #include <petscsys.h>
1284    void PetscStackUpdateLine
1285 
1286    Level: developer
1287 
1288    Notes:
1289    Using `PetscCall()` and friends automatically handles this process
1290 
1291    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
1292    occurred, for example, when a signal is received. It is recommended to use the debugger if extensive information is needed to
1293    help debug the problem.
1294 
1295    The default stack is a global variable called petscstack.
1296 
1297    This is used by `PetscCall()` and is otherwise not like to be needed
1298 
1299 .seealso: `PetscAttachDebugger()`, `PetscStackCopy()`, `PetscStackView()`, `PetscStackPushNoCheck()`, `PetscStackPop`, `PetscCall()`
1300 M*/
1301   #define PetscStackUpdateLine \
1302     do { \
1303       if (petscstack.currentsize > 0 && petscstack.function[petscstack.currentsize - 1] == PETSC_FUNCTION_NAME) { petscstack.line[petscstack.currentsize - 1] = __LINE__; } \
1304     } while (0)
1305 
1306   /*MC
1307    PetscStackPushExternal - Pushes a new function name onto the PETSc default stack that tracks where the running program is
1308    currently in the source code. Does not include the filename or line number since this is called by the calling routine
1309    for non-PETSc or user functions.
1310 
1311    Not Collective
1312 
1313    Synopsis:
1314    #include <petscsys.h>
1315    void PetscStackPushExternal(char *funct);
1316 
1317    Input Parameters:
1318 .  funct - the function name
1319 
1320    Level: developer
1321 
1322    Notes:
1323    Using `PetscCallExternal()` and friends automatically handles this process
1324 
1325    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
1326    occurred, for example, when a signal is received. It is recommended to use the debugger if extensive information is needed to
1327    help debug the problem.
1328 
1329    The default stack is a global variable called `petscstack`.
1330 
1331    This is to be used when calling an external package function such as a BLAS function.
1332 
1333    This also updates the stack line number for the current stack function.
1334 
1335 .seealso: `PetscAttachDebugger()`, `PetscStackCopy()`, `PetscStackView()`, `PetscStackPopNoCheck()`, `PetscCall()`, `PetscFunctionBegin()`,
1336           `PetscFunctionReturn()`, `PetscFunctionBeginHot()`, `PetscFunctionBeginUser()`, `PetscStackPushNoCheck()`, `PetscStackPop`
1337 M*/
1338   #define PetscStackPushExternal(funct) \
1339     do { \
1340       PetscStackUpdateLine; \
1341       PetscStackPushNoCheck(funct, 0, PETSC_TRUE); \
1342     } while (0);
1343 
1344   /*MC
1345    PetscStackPopNoCheck - Pops a function name from the PETSc default stack that tracks where the running program is
1346    currently in the source code.
1347 
1348    Not Collective
1349 
1350    Synopsis:
1351    #include <petscsys.h>
1352    void PetscStackPopNoCheck(char *funct);
1353 
1354    Input Parameter:
1355 .   funct - the function name
1356 
1357    Level: developer
1358 
1359    Notes:
1360    Using `PetscCall()`, `PetscCallExternal()`, `PetscCallBack()` and friends negates the need to call this
1361 
1362    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
1363    occurred, for example, when a signal is received. It is recommended to use the debugger if extensive information is needed to
1364    help debug the problem.
1365 
1366    The default stack is a global variable called petscstack.
1367 
1368    Developer Note:
1369    `PetscStackPopNoCheck()` takes a function argument while  `PetscStackPop` does not, this difference is likely just historical.
1370 
1371 .seealso: `PetscAttachDebugger()`, `PetscStackCopy()`, `PetscStackView()`, `PetscStackPushNoCheck()`, `PetscStackPop`
1372 M*/
1373   #define PetscStackPopNoCheck(funct) \
1374     do { \
1375       PetscStackSAWsTakeAccess(); \
1376       PetscStackPop_Private(petscstack, funct); \
1377       PetscStackSAWsGrantAccess(); \
1378     } while (0)
1379 
1380   #define PetscStackClearTop \
1381     do { \
1382       PetscStackSAWsTakeAccess(); \
1383       if (petscstack.currentsize > 0 && --petscstack.currentsize < PETSCSTACKSIZE) { \
1384         petscstack.function[petscstack.currentsize]     = PETSC_NULLPTR; \
1385         petscstack.file[petscstack.currentsize]         = PETSC_NULLPTR; \
1386         petscstack.line[petscstack.currentsize]         = 0; \
1387         petscstack.petscroutine[petscstack.currentsize] = 0; \
1388       } \
1389       petscstack.hotdepth = PetscMax(petscstack.hotdepth - 1, 0); \
1390       PetscStackSAWsGrantAccess(); \
1391     } while (0)
1392 
1393   /*MC
1394    PetscFunctionBegin - First executable line of each PETSc function,  used for error handling. Final
1395       line of PETSc functions should be `PetscFunctionReturn`(0);
1396 
1397    Synopsis:
1398    #include <petscsys.h>
1399    void PetscFunctionBegin;
1400 
1401    Not Collective
1402 
1403    Usage:
1404 .vb
1405      int something;
1406 
1407      PetscFunctionBegin;
1408 .ve
1409 
1410    Notes:
1411      Use `PetscFunctionBeginUser` for application codes.
1412 
1413      Not available in Fortran
1414 
1415    Level: developer
1416 
1417 .seealso: `PetscFunctionReturn()`, `PetscFunctionBeginHot()`, `PetscFunctionBeginUser()`, `PetscStackPushNoCheck()`
1418 
1419 M*/
1420   #define PetscFunctionBegin \
1421     do { \
1422       PetscStackPushNoCheck(PETSC_FUNCTION_NAME, 1, PETSC_FALSE); \
1423       PetscRegister__FUNCT__(); \
1424     } while (0)
1425 
1426   /*MC
1427    PetscFunctionBeginHot - Substitute for `PetscFunctionBegin` to be used in functions that are called in
1428    performance-critical circumstances.  Use of this function allows for lighter profiling by default.
1429 
1430    Synopsis:
1431    #include <petscsys.h>
1432    void PetscFunctionBeginHot;
1433 
1434    Not Collective
1435 
1436    Usage:
1437 .vb
1438      int something;
1439 
1440      PetscFunctionBeginHot;
1441 .ve
1442 
1443    Notes:
1444      Not available in Fortran
1445 
1446    Level: developer
1447 
1448 .seealso: `PetscFunctionBegin`, `PetscFunctionReturn()`, `PetscStackPushNoCheck()`
1449 
1450 M*/
1451   #define PetscFunctionBeginHot \
1452     do { \
1453       PetscStackPushNoCheck(PETSC_FUNCTION_NAME, 1, PETSC_TRUE); \
1454       PetscRegister__FUNCT__(); \
1455     } while (0)
1456 
1457   /*MC
1458    PetscFunctionBeginUser - First executable line of user provided routines
1459 
1460    Synopsis:
1461    #include <petscsys.h>
1462    void PetscFunctionBeginUser;
1463 
1464    Not Collective
1465 
1466    Usage:
1467 .vb
1468      int something;
1469 
1470      PetscFunctionBeginUser;
1471 .ve
1472 
1473    Notes:
1474       Functions that incorporate this must call `PetscFunctionReturn()` instead of return except for main().
1475 
1476       May be used before `PetscInitialize()`
1477 
1478       Not available in Fortran
1479 
1480       This is identical to `PetscFunctionBegin` except it labels the routine as a user
1481       routine instead of as a PETSc library routine.
1482 
1483    Level: intermediate
1484 
1485 .seealso: `PetscFunctionReturn()`, `PetscFunctionBegin`, `PetscFunctionBeginHot`, `PetscStackPushNoCheck()`
1486 
1487 M*/
1488   #define PetscFunctionBeginUser \
1489     do { \
1490       PetscStackPushNoCheck(PETSC_FUNCTION_NAME, 2, PETSC_FALSE); \
1491       PetscRegister__FUNCT__(); \
1492     } while (0)
1493 
1494   /*MC
1495    PetscStackPush - Pushes a new function name and line number onto the PETSc default stack that tracks where the running program is
1496    currently in the source code and verifies the memory is not corrupted.
1497 
1498    Not Collective
1499 
1500    Synopsis:
1501    #include <petscsys.h>
1502    void PetscStackPush(char *funct)
1503 
1504    Input Parameter:
1505 .  funct - the function name
1506 
1507    Level: developer
1508 
1509    Notes:
1510    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
1511    occurred, for example, when a signal is received. It is recommended to use the debugger if extensive information is needed to
1512    help debug the problem.
1513 
1514    The default stack is a global variable called petscstack.
1515 
1516 .seealso: `PetscAttachDebugger()`, `PetscStackCopy()`, `PetscStackView()`, `PetscStackPopNoCheck()`, `PetscCall()`, `PetscFunctionBegin()`,
1517           `PetscFunctionReturn()`, `PetscFunctionBeginHot()`, `PetscFunctionBeginUser()`, `PetscStackPushNoCheck()`, `PetscStackPop`
1518 M*/
1519   #define PetscStackPush(n) \
1520     do { \
1521       PetscStackPushNoCheck(n, 0, PETSC_FALSE); \
1522       CHKMEMQ; \
1523     } while (0)
1524 
1525   /*MC
1526    PetscStackPop - Pops a function name from the PETSc default stack that tracks where the running program is
1527    currently in the source code and verifies the memory is not corrupted.
1528 
1529    Not Collective
1530 
1531    Synopsis:
1532    #include <petscsys.h>
1533    void PetscStackPop
1534 
1535    Level: developer
1536 
1537    Notes:
1538    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
1539    occurred, for example, when a signal is received. It is recommended to use the debugger if extensive information is needed to
1540    help debug the problem.
1541 
1542    The default stack is a global variable called petscstack.
1543 
1544 .seealso: `PetscAttachDebugger()`, `PetscStackCopy()`, `PetscStackView()`, `PetscStackPushNoCheck()`, `PetscStackPopNoCheck()`, `PetscStackPush()`
1545 M*/
1546   #define PetscStackPop \
1547     do { \
1548       CHKMEMQ; \
1549       PetscStackPopNoCheck(PETSC_FUNCTION_NAME); \
1550     } while (0)
1551 
1552   /*MC
1553    PetscFunctionReturn - Last executable line of each PETSc function used for error
1554    handling. Replaces `return()`.
1555 
1556    Synopsis:
1557    #include <petscerror.h>
1558    void PetscFunctionReturn(...)
1559 
1560    Not Collective; No Fortran Support
1561 
1562    Level: beginner
1563 
1564    Notes:
1565    This routine is a macro, so while it does not "return" anything itself, it does return from
1566    the function in the literal sense.
1567 
1568    Usually the return value is the integer literal `0` (for example in any function returning
1569    `PetscErrorCode`), however it is possible to return any arbitrary type. The arguments of
1570    this macro are placed before the `return` statement as-is.
1571 
1572    Any routine which returns via `PetscFunctionReturn()` must begin with a corresponding
1573    `PetscFunctionBegin`.
1574 
1575    For routines which return `void` use `PetscFunctionReturnVoid()` instead.
1576 
1577    Example Usage:
1578 .vb
1579    PetscErrorCode foo(int *x)
1580    {
1581      PetscFunctionBegin; // don't forget the begin!
1582      *x = 10;
1583      PetscFunctionReturn(PETSC_SUCCESS);
1584    }
1585 .ve
1586 
1587    May return any arbitrary type\:
1588 .vb
1589   struct Foo
1590   {
1591     int x;
1592   };
1593 
1594   struct Foo make_foo(int value)
1595   {
1596     struct Foo f;
1597 
1598     PetscFunctionBegin;
1599     f.x = value;
1600     PetscFunctionReturn(f);
1601   }
1602 .ve
1603 
1604 .seealso: `PetscFunctionBegin`, `PetscFunctionBeginUser`, `PetscFunctionReturnVoid()`,
1605           `PetscStackPopNoCheck()`
1606 M*/
1607   #define PetscFunctionReturn(...) \
1608     do { \
1609       PetscStackPopNoCheck(PETSC_FUNCTION_NAME); \
1610       return __VA_ARGS__; \
1611     } while (0)
1612 
1613   /*MC
1614   PetscFunctionReturnVoid - Like `PetscFunctionReturn()` but returns `void`
1615 
1616   Synopsis:
1617   #include <petscerror.h>
1618   void PetscFunctionReturnVoid()
1619 
1620   Not Collective
1621 
1622   Level: beginner
1623 
1624   Note:
1625   Behaves identically to `PetscFunctionReturn()` except that it returns `void`. That is, this
1626   macro culminates with `return`.
1627 
1628   Example Usage:
1629 .vb
1630   void foo()
1631   {
1632     PetscFunctionBegin; // must start with PetscFunctionBegin!
1633     bar();
1634     baz();
1635     PetscFunctionReturnVoid();
1636   }
1637 .ve
1638 
1639 .seealso: `PetscFunctionReturn()`, `PetscFunctionBegin`, PetscFunctionBeginUser`
1640 M*/
1641   #define PetscFunctionReturnVoid() \
1642     do { \
1643       PetscStackPopNoCheck(PETSC_FUNCTION_NAME); \
1644       return; \
1645     } while (0)
1646 #else /* PETSC_USE_DEBUG */
1647   #define PetscStackPushNoCheck(funct, petsc_routine, hot)
1648   #define PetscStackUpdateLine
1649   #define PetscStackPushExternal(funct)
1650   #define PetscStackPopNoCheck(...)
1651   #define PetscStackClearTop
1652   #define PetscFunctionBegin
1653   #define PetscFunctionBeginUser
1654   #define PetscFunctionBeginHot
1655   #define PetscFunctionReturn(...)  return __VA_ARGS__
1656   #define PetscFunctionReturnVoid() return
1657   #define PetscStackPop             CHKMEMQ
1658   #define PetscStackPush(f)         CHKMEMQ
1659 #endif /* PETSC_USE_DEBUG */
1660 
1661 #if defined(PETSC_CLANG_STATIC_ANALYZER)
1662   #define PetscStackCallExternalVoid(...)
1663 template <typename F, typename... Args>
1664 void PetscCallExternal(F, Args...);
1665 #else
1666   /*MC
1667     PetscStackCallExternalVoid - Calls an external library routine or user function after pushing the name of the routine on the stack.
1668 
1669    Input Parameters:
1670 +   name - string that gives the name of the function being called
1671 -   routine - actual call to the routine, for example, functionname(a,b)
1672 
1673    Level: developer
1674 
1675    Note:
1676    Often one should use `PetscCallExternal()` instead. This routine is intended for external library routines that DO NOT return error codes
1677 
1678    In debug mode this also checks the memory for corruption at the end of the function call.
1679 
1680    Certain external packages, such as BLAS/LAPACK may have their own macros for managing the call, error checking, etc.
1681 
1682    Developer Note:
1683    This is so that when a user or external library routine results in a crash or corrupts memory, they get blamed instead of PETSc.
1684 
1685 .seealso: `PetscCall()`, `PetscStackPushNoCheck()`, `PetscStackPush()`, `PetscCallExternal()`, `PetscCallBLAS()`
1686 @*/
1687   #define PetscStackCallExternalVoid(name, ...) \
1688     do { \
1689       PetscStackPush(name); \
1690       __VA_ARGS__; \
1691       PetscStackPop; \
1692     } while (0)
1693 
1694   /*MC
1695     PetscCallExternal - Calls an external library routine that returns an error code after pushing the name of the routine on the stack.
1696 
1697    Input Parameters:
1698 +   func-  name of the routine
1699 -   args - arguments to the routine
1700 
1701    Level: developer
1702 
1703    Notes:
1704    This is intended for external package routines that return error codes. Use `PetscStackCallExternalVoid()` for those that do not.
1705 
1706    In debug mode this also checks the memory for corruption at the end of the function call.
1707 
1708    Assumes the error return code of the function is an integer and that a value of 0 indicates success
1709 
1710    Developer Note:
1711    This is so that when an external package routine results in a crash or corrupts memory, they get blamed instead of PETSc.
1712 
1713 .seealso: `PetscCall()`, `PetscStackPushNoCheck()`, `PetscStackPush()`, `PetscStackCallExternalVoid()`
1714 M*/
1715   #define PetscCallExternal(func, ...) \
1716     do { \
1717       PetscStackPush(PetscStringize(func)); \
1718       int ierr_petsc_call_external_ = func(__VA_ARGS__); \
1719       PetscStackPop; \
1720       PetscCheck(ierr_petsc_call_external_ == 0, PETSC_COMM_SELF, PETSC_ERR_LIB, "Error in %s(): error code %d", PetscStringize(func), ierr_petsc_call_external_); \
1721     } while (0)
1722 #endif /* PETSC_CLANG_STATIC_ANALYZER */
1723 
1724 #endif
1725