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