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