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