Actual source code: petscerror.h

  1: /*
  2:     Contains all error handling interfaces for PETSc.
  3: */
  4: #ifndef PETSCERROR_H
  5: #define PETSCERROR_H

  7: #include <petscmacros.h>
  8: #include <petscsystypes.h>

 10: #if defined(__cplusplus)
 11:   #include <exception> // std::exception
 12: #endif

 14: /* SUBMANSEC = Sys */

 16: #define SETERRQ1(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
 17: #define SETERRQ2(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
 18: #define SETERRQ3(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
 19: #define SETERRQ4(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
 20: #define SETERRQ5(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
 21: #define SETERRQ6(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
 22: #define SETERRQ7(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
 23: #define SETERRQ8(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)
 24: #define SETERRQ9(...) PETSC_DEPRECATED_MACRO("GCC warning \"Use SETERRQ() (since version 3.17)\"") SETERRQ(__VA_ARGS__)

 26: /*MC
 27:    SETERRQ - Macro to be called when an error has been detected,

 29:    Synopsis:
 30: #include <petscsys.h>
 31:    PetscErrorCode SETERRQ(MPI_Comm comm,PetscErrorCode ierr,char *message,...)

 33:    Collective

 35:    Input Parameters:
 36: +  comm - A communicator, use `PETSC_COMM_SELF` unless you know all ranks of another communicator will detect the error
 37: .  ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
 38: -  message - error message

 40:   Level: beginner

 42:    Notes:
 43:     This is rarely needed, one should use `PetscCheck()` and `PetscCall()` and friends to automatically handle error conditions.
 44:     Once the error handler is called the calling function is then returned from with the given error code.

 46:     Experienced users can set the error handler with `PetscPushErrorHandler()`.

 48:    Fortran Notes:
 49:       SETERRQ() may be called from Fortran subroutines but SETERRA() must be called from the
 50:       Fortran main program.

 52: .seealso: `PetscCheck()`, `PetscAssert()`, `PetscTraceBackErrorHandler()`, `PetscPushErrorHandler()`,
 53:           `PetscError()`, `PetscCall()`, `CHKMEMQ`, `CHKERRA()`, `PetscCallMPI()`
 54: M*/
 55: #define SETERRQ(comm, ierr, ...) \
 56:   do { \
 57:     PetscErrorCode ierr_seterrq_petsc_ = PetscError(comm, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr, PETSC_ERROR_INITIAL, __VA_ARGS__); \
 58:     return ierr_seterrq_petsc_ ? ierr_seterrq_petsc_ : PETSC_ERR_RETURN; \
 59:   } while (0)

 61: /*
 62:     Returned from PETSc functions that are called from MPI, such as related to attributes
 63:       Do not confuse PETSC_MPI_ERROR_CODE and PETSC_ERR_MPI, the first is registered with MPI and returned to MPI as
 64:       an error code, the latter is a regular PETSc error code passed within PETSc code indicating an error was detected in an MPI call.
 65: */
 66: PETSC_EXTERN PetscMPIInt PETSC_MPI_ERROR_CLASS;
 67: PETSC_EXTERN PetscMPIInt PETSC_MPI_ERROR_CODE;

 69: /*MC
 70:    SETERRMPI - Macro to be called when an error has been detected within an MPI callback function

 72:    Synopsis:
 73: #include <petscsys.h>
 74:    PetscErrorCode SETERRMPI(MPI_Comm comm,PetscErrorCode ierr,char *message,...)

 76:    Collective

 78:    Input Parameters:
 79: +  comm - A communicator, use `PETSC_COMM_SELF` unless you know all ranks of another communicator will detect the error
 80: .  ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
 81: -  message - error message

 83:   Level: developer

 85:    Notes:
 86:     This macro is FOR USE IN MPI CALLBACK FUNCTIONS ONLY, such as those passed to `MPI_Comm_create_keyval()`. It always returns the error code `PETSC_MPI_ERROR_CODE`
 87:     which is registered with `MPI_Add_error_code()` when PETSc is initialized.

 89: .seealso: `SETERRQ()`, `PetscCall()`, `PetscCallMPI()`, `PetscTraceBackErrorHandler()`, `PetscPushErrorHandler()`, `PetscError()`, `CHKMEMQ`
 90: M*/
 91: #define SETERRMPI(comm, ierr, ...) return ((void)PetscError(comm, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr, PETSC_ERROR_INITIAL, __VA_ARGS__), PETSC_MPI_ERROR_CODE)

 93: /*MC
 94:    SETERRA - Fortran-only macro that can be called when an error has been detected from the main program

 96:    Synopsis:
 97: #include <petscsys.h>
 98:    PetscErrorCode SETERRA(MPI_Comm comm,PetscErrorCode ierr,char *message)

100:    Collective

102:    Input Parameters:
103: +  comm - A communicator, so that the error can be collective
104: .  ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
105: -  message - error message in the printf format

107:   Level: beginner

109:    Notes:
110:    This should only be used with Fortran. With C/C++, use `SETERRQ()`.

112:    `SETERRQ()` may be called from Fortran subroutines but `SETERRA()` must be called from the
113:     Fortran main program.

115: .seealso: `SETERRQ()`, `SETERRABORT()`, `PetscCall()`, `CHKERRA()`, `PetscCallAbort()`
116: M*/

118: /*MC
119:    SETERRABORT - Macro that can be called when an error has been detected,

121:    Synopsis:
122: #include <petscsys.h>
123:    PetscErrorCode SETERRABORT(MPI_Comm comm,PetscErrorCode ierr,char *message,...)

125:    Collective

127:    Input Parameters:
128: +  comm - A communicator, so that the error can be collective
129: .  ierr - nonzero error code, see the list of standard error codes in include/petscerror.h
130: -  message - error message in the printf format

132:   Level: beginner

134:    Notes:
135:    This function just calls `MPI_Abort()`.

137:    This should only be called in routines that cannot return an error code, such as in C++ constructors.

139: .seealso: `SETERRQ()`, `PetscTraceBackErrorHandler()`, `PetscPushErrorHandler()`, `PetscError()`, `PetscCall()`, `CHKMEMQ`
140: M*/
141: #define SETERRABORT(comm, ierr, ...) \
142:   do { \
143:     (void)PetscError(comm, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr, PETSC_ERROR_INITIAL, __VA_ARGS__); \
144:     MPI_Abort(comm, ierr); \
145:   } while (0)

147: /*MC
148:   PetscCheck - Check that a particular condition is true

150:   Synopsis:
151: #include <petscerror.h>
152:   void PetscCheck(bool cond, MPI_Comm comm, PetscErrorCode ierr, const char *message, ...)

154:   Collective

156:   Input Parameters:
157: + cond    - The boolean condition
158: . comm    - The communicator on which the check can be collective on
159: . ierr    - A nonzero error code, see include/petscerror.h for the complete list
160: - message - Error message in printf format

162:   Level: beginner

164:   Notes:
165:   Enabled in both optimized and debug builds.

167:   Calls `SETERRQ()` if the assertion fails, so can only be called from functions returning a
168:   `PetscErrorCode` (or equivalent type after conversion).

170:  .seealso: `PetscAssert()`, `SETERRQ()`, `PetscError()`, `PetscCall()`, `PetscCheckAbort()`
171: M*/
172: #define PetscCheck(cond, comm, ierr, ...) \
173:   do { \
174:     if (PetscUnlikely(!(cond))) SETERRQ(comm, ierr, __VA_ARGS__); \
175:   } while (0)

177: /*MC
178:   PetscCheckAbort - Check that a particular condition is true, otherwise prints error and aborts

180:   Synopsis:
181: #include <petscerror.h>
182:   void PetscCheckAbort(bool cond, MPI_Comm comm, PetscErrorCode ierr, const char *message, ...)

184:   Collective

186:   Input Parameters:
187: + cond    - The boolean condition
188: . comm    - The communicator on which the check can be collective on
189: . ierr    - A nonzero error code, see include/petscerror.h for the complete list
190: - message - Error message in printf format

192:   Level: developer

194:   Notes:
195:   Enabled in both optimized and debug builds.

197:   Calls `SETERRABORT()` if the assertion fails, can be called from a function that does not return an
198:   error code, such as a C++ constructor. usually `PetscCheck()` should be used.

200: .seealso: `PetscAssertAbort()`, `PetscAssert()`, `SETERRQ()`, `PetscError()`, `PetscCall()`, `PetscCheck()`, `SETTERRABORT()`
201: M*/
202: #define PetscCheckAbort(cond, comm, ierr, ...) \
203:   do { \
204:     if (PetscUnlikely(!(cond))) SETERRABORT(comm, ierr, __VA_ARGS__); \
205:   } while (0)

207: /*MC
208:   PetscAssert - Assert that a particular condition is true

210:   Synopsis:
211: #include <petscerror.h>
212:   void PetscAssert(bool cond, MPI_Comm comm, PetscErrorCode ierr, const char *message, ...)

214:   Collective

216:   Input Parameters:
217: + cond    - The boolean condition
218: . comm    - The communicator on which the check can be collective on
219: . ierr    - A nonzero error code, see include/petscerror.h for the complete list
220: - message - Error message in printf format

222:   Level: beginner

224:   Notes:
225:   Equivalent to `PetscCheck()` if debugging is enabled, and `PetscAssume(cond)` otherwise.

227:   See `PetscCheck()` for usage and behaviour.

229:   This is needed instead of simply using `assert()` because this correctly handles the collective nature of errors under MPI

231: .seealso: `PetscCheck()`, `SETERRQ()`, `PetscError()`, `PetscAssertAbort()`
232: M*/
233: #if PetscDefined(USE_DEBUG)
234:   #define PetscAssert(cond, comm, ierr, ...) PetscCheck(cond, comm, ierr, __VA_ARGS__)
235: #else
236:   #define PetscAssert(cond, ...) PetscAssume(cond)
237: #endif

239: /*MC
240:   PetscAssertAbort - Assert that a particular condition is true, otherwise prints error and aborts

242:   Synopsis:
243: #include <petscerror.h>
244:   void PetscAssertAbort(bool cond, MPI_Comm comm, PetscErrorCode ierr, const char *message, ...)

246:   Collective

248:   Input Parameters:
249: + cond    - The boolean condition
250: . comm    - The communicator on which the check can be collective on
251: . ierr    - A nonzero error code, see include/petscerror.h for the complete list
252: - message - Error message in printf format

254:   Level: beginner

256:   Notes:
257:   Enabled only in debug builds. See `PetscCheckAbort()` for usage.

259: .seealso: `PetscCheckAbort()`, `PetscAssert()`, `PetscCheck()`, `SETERRABORT()`, `PetscError()`
260: M*/
261: #if PetscDefined(USE_DEBUG)
262:   #define PetscAssertAbort(cond, comm, ierr, ...) PetscCheckAbort(cond, comm, ierr, __VA_ARGS__)
263: #else
264:   #define PetscAssertAbort(cond, comm, ierr, ...) PetscAssume(cond)
265: #endif

267: /*MC
268:   PetscCall - Calls a PETSc function and then checks the resulting error code, if it is
269:   non-zero it calls the error handler and returns from the current function with the error
270:   code.

272:   Synopsis:
273: #include <petscerror.h>
274:   void PetscCall(PetscFunction(args))

276:   Not Collective

278:   Input Parameter:
279: . PetscFunction - any PETSc function that returns an error code

281:   Level: beginner

283:   Notes:
284:   Once the error handler is called the calling function is then returned from with the given
285:   error code. Experienced users can set the error handler with `PetscPushErrorHandler()`.

287:   `PetscCall()` cannot be used in functions returning a datatype not convertible to
288:   `PetscErrorCode`. For example, `PetscCall()` may not be used in functions returning void, use
289:   `PetscCallAbort()` or `PetscCallVoid()` in this case.

291:   Example Usage:
292: .vb
293:   PetscCall(PetscInitiailize(...)); // OK to call even when PETSc is not yet initialized!

295:   struct my_struct
296:   {
297:     void *data;
298:   } my_complex_type;

300:   struct my_struct bar(void)
301:   {
302:     PetscCall(foo(15)); // ERROR PetscErrorCode not convertible to struct my_struct!
303:   }

305:   PetscCall(bar()) // ERROR input not convertible to PetscErrorCode
306: .ve

308:   It is also possible to call this directly on a `PetscErrorCode` variable
309: .vb
310:   PetscCall(ierr);  // check if ierr is nonzero
311: .ve

313:   Should not be used to call callback functions provided by users, `PetscCallBack()` should be used in that situation.

315:   `PetscUseTypeMethod()` or `PetscTryTypeMethod()` should be used when calling functions pointers contained in a PETSc object's `ops` array

317:   Fortran Notes:
318:     The Fortran function from which this is used must declare a variable PetscErrorCode ierr and ierr must be
319:     the final argument to the PETSc function being called.

321:     In the main program and in Fortran subroutines that do not have ierr as the final return parameter one
322:     should use `PetscCallA()`

324:   Example Fortran Usage:
325: .vb
326:   PetscErrorCode ierr
327:   Vec v

329:   ...
330:   PetscCall(VecShift(v,1.0,ierr))
331:   PetscCallA(VecShift(v,1.0,ierr))
332: .ve

334: .seealso: `SETERRQ()`, `PetscCheck()`, `PetscAssert()`, `PetscTraceBackErrorHandler()`, `PetscCallMPI()`,
335:           `PetscPushErrorHandler()`, `PetscError()`, `CHKMEMQ`, `CHKERRA()`,
336:           `CHKERRMPI()`, `PetscCallBack()`, `PetscCallAbort()`, `PetscCallVoid()`
337: M*/

339: /*MC
340:   PetscCallBack - Calls a user provided PETSc callback function and then checks the resulting error code, if it is non-zero it calls the error
341:   handler and returns from the current function with the error code.

343:   Synopsis:
344: #include <petscerror.h>
345:   void PetscCallBack(const char *functionname,PetscFunction(args))

347:   Not Collective

349:   Input Parameters:
350: + functionname - the name of the function being called, this can be a string with spaces that describes the meaning of the callback
351: - PetscFunction - user provided callback function that returns an error code

353:   Example Usage:
354: .vb
355:   PetscCallBack("XXX callback to do something",a->callback(...));
356: .ve

358:   Level: developer

360:   Notes:
361:   Once the error handler is called the calling function is then returned from with the given
362:   error code. Experienced users can set the error handler with `PetscPushErrorHandler()`.

364:   `PetscCallBack()` should only be called in PETSc when a call is being made to a user provided call-back routine.

366: .seealso: `SETERRQ()`, `PetscCheck()`, `PetscCall()`, `PetscAssert()`, `PetscTraceBackErrorHandler()`, `PetscCallMPI()`
367:           `PetscPushErrorHandler()`, `PetscError()`, `CHKMEMQ`, `CHKERRA()`, `CHKERRMPI()`, `PetscCall()`
368: M*/

370: /*MC
371:   PetscCallVoid - Like `PetscCall()` but for functions returning `void`

373:   Synopsis:
374: #include <petscerror.h>
375:   void PetscCall(PetscFunction(args))

377:   Not Collective

379:   Input Parameter:
380: . PetscFunction - any PETSc function that returns an error code

382:   Example Usage:
383: .vb
384:   void foo()
385:   {
386:     KSP ksp;

388:     PetscFunctionBeginUser;
389:     // OK, properly handles PETSc error codes
390:     PetscCallVoid(KSPCreate(PETSC_COMM_WORLD, &ksp));
391:     PetscFunctionReturn(PETSC_SUCCESS);
392:   }

394:   PetscErrorCode bar()
395:   {
396:     KSP ksp;

398:     PetscFunctionBeginUser;
399:     // ERROR, Non-void function 'bar' should return a value
400:     PetscCallVoid(KSPCreate(PETSC_COMM_WORLD, &ksp));
401:     // OK, returning PetscErrorCode
402:     PetscCall(KSPCreate(PETSC_COMM_WORLD, &ksp));
403:     PetscFunctionReturn(PETSC_SUCCESS);
404:   }
405: .ve

407:   Level: beginner

409:   Notes:
410:   Has identical usage to `PetscCall()`, except that it returns `void` on error instead of a
411:   `PetscErrorCode`. See `PetscCall()` for more detailed discussion.

413:   Note that users should prefer `PetscCallAbort()` to this routine. While this routine does
414:   "handle" errors by returning from the enclosing function, it effectively gobbles the
415:   error. Since the enclosing function itself returns `void`, its callers have no way of knowing
416:   that the routine returned early due to an error. `PetscCallAbort()` at least ensures that the
417:   program crashes gracefully.

419: .seealso: `PetscCall()`, `PetscErrorCode`
420: M*/
421: #if defined(PETSC_CLANG_STATIC_ANALYZER)
422: void PetscCall(PetscErrorCode);
423: void PetscCallBack(const char *, PetscErrorCode);
424: void PetscCallVoid(PetscErrorCode);
425: #else
426:   #define PetscCall(...) \
427:     do { \
428:       PetscErrorCode ierr_petsc_call_q_; \
429:       PetscStackUpdateLine; \
430:       ierr_petsc_call_q_ = __VA_ARGS__; \
431:       if (PetscUnlikely(ierr_petsc_call_q_ != PETSC_SUCCESS)) return PetscError(PETSC_COMM_SELF, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr_petsc_call_q_, PETSC_ERROR_REPEAT, " "); \
432:     } while (0)
433:   #define PetscCallBack(function, ...) \
434:     do { \
435:       PetscErrorCode ierr_petsc_call_q_; \
436:       PetscStackUpdateLine; \
437:       PetscStackPushExternal(function); \
438:       ierr_petsc_call_q_ = __VA_ARGS__; \
439:       PetscStackPop; \
440:       if (PetscUnlikely(ierr_petsc_call_q_ != PETSC_SUCCESS)) return PetscError(PETSC_COMM_SELF, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr_petsc_call_q_, PETSC_ERROR_REPEAT, " "); \
441:     } while (0)
442:   #define PetscCallVoid(...) \
443:     do { \
444:       PetscErrorCode ierr_petsc_call_void_; \
445:       PetscStackUpdateLine; \
446:       ierr_petsc_call_void_ = __VA_ARGS__; \
447:       if (PetscUnlikely(ierr_petsc_call_void_ != PETSC_SUCCESS)) { \
448:         ierr_petsc_call_void_ = PetscError(PETSC_COMM_SELF, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr_petsc_call_void_, PETSC_ERROR_REPEAT, " "); \
449:         (void)ierr_petsc_call_void_; \
450:         return; \
451:       } \
452:     } while (0)
453: #endif

455: /*MC
456:   CHKERRQ - Checks error code returned from PETSc function

458:   Synopsis:
459: #include <petscsys.h>
460:   void CHKERRQ(PetscErrorCode ierr)

462:   Not Collective

464:   Input Parameters:
465: . ierr - nonzero error code

467:   Level: deprecated

469:   Note:
470:   Deprecated in favor of `PetscCall()`. This routine behaves identically to it.

472: .seealso: `PetscCall()`
473: M*/
474: #define CHKERRQ(...) PetscCall(__VA_ARGS__)
475: #define CHKERRV(...) PetscCallVoid(__VA_ARGS__)

477: PETSC_EXTERN void PetscMPIErrorString(PetscMPIInt, char *);

479: /*MC
480:   PetscCallMPI - Checks error code returned from MPI calls, if non-zero it calls the error
481:   handler and then returns

483:   Synopsis:
484: #include <petscerror.h>
485:   void PetscCallMPI(MPI_Function(args))

487:   Not Collective

489:   Input Parameters:
490: . MPI_Function - an MPI function that returns an MPI error code

492:   Level: beginner

494:   Notes:
495:   Always returns the error code `PETSC_ERR_MPI`; the MPI error code and string are embedded in
496:   the string error message. Do not use this to call any other routines (for example PETSc
497:   routines), it should only be used for direct MPI calls. The user may configure PETSc with the
498:   `--with-strict-petscerrorcode` option to check this at compile-time, otherwise they must
499:   check this themselves.

501:   This rouine can only be used in functions returning `PetscErrorCode` themselves. If the
502:   calling function returns a different type, use `PetscCallMPIAbort()` instead.

504:   Example Usage:
505: .vb
506:   PetscCallMPI(MPI_Comm_size(...)); // OK, calling MPI function

508:   PetscCallMPI(PetscFunction(...)); // ERROR, use PetscCall() instead!
509: .ve

511:   Fortran Notes:
512:     The Fortran function from which this is used must declare a variable `PetscErrorCode` ierr and ierr must be
513:     the final argument to the MPI function being called.

515:     In the main program and in Fortran subroutines that do not have ierr as the final return parameter one
516:     should use `PetscCallMPIA()`

518:   Fortran Usage:
519: .vb
520:   PetscErrorCode ierr or integer ierr
521:   ...
522:   PetscCallMPI(MPI_Comm_size(...,ierr))
523:   PetscCallMPIA(MPI_Comm_size(...,ierr)) ! Will abort after calling error handler

525:   PetscCallMPI(MPI_Comm_size(...,eflag)) ! ERROR, final argument must be ierr
526: .ve

528: .seealso: `SETERRMPI()`, `PetscCall()`, `SETERRQ()`, `SETERRABORT()`, `PetscCallAbort()`,
529:           `PetscCallMPIAbort()`, `PetscTraceBackErrorHandler()`, `PetscPushErrorHandler()`,
530:           `PetscError()`, `CHKMEMQ`
531: M*/

533: /*MC
534:   PetscCallMPIAbort - Like `PetscCallMPI()` but calls `MPI_Abort()` on error

536:   Synopsis:
537: #include <petscerror.h>
538:   void PetscCallMPIAbort(MPI_Comm comm, MPI_Function(args))

540:   Not Collective

542:   Input Parameters:
543: + comm         - the MPI communicator to abort on
544: - MPI_Function - an MPI function that returns an MPI error code

546:   Level: beginner

548:   Notes:
549:   Usage is identical to `PetscCallMPI()`. See `PetscCallMPI()` for detailed discussion.

551:   This routine may be used in functions returning `void` or other non-`PetscErrorCode` types.

553: .seealso: `PetscCallMPI()`, `PetscCallAbort()`, `SETERRABORT()`
554: M*/
555: #if defined(PETSC_CLANG_STATIC_ANALYZER)
556: void PetscCallMPI(PetscMPIInt);
557: void PetscCallMPIAbort(MPI_Comm, PetscMPIInt);
558: #else
559:   #define PetscCallMPI_Private(__PETSC_STACK_POP_FUNC__, __SETERR_FUNC__, __COMM__, ...) \
560:     do { \
561:       PetscMPIInt ierr_petsc_call_mpi_; \
562:       PetscStackUpdateLine; \
563:       PetscStackPushExternal("MPI function"); \
564:       { \
565:         ierr_petsc_call_mpi_ = __VA_ARGS__; \
566:       } \
567:       __PETSC_STACK_POP_FUNC__; \
568:       if (PetscUnlikely(ierr_petsc_call_mpi_ != MPI_SUCCESS)) { \
569:         char petsc_mpi_7_errorstring[2 * MPI_MAX_ERROR_STRING]; \
570:         PetscMPIErrorString(ierr_petsc_call_mpi_, (char *)petsc_mpi_7_errorstring); \
571:         __SETERR_FUNC__(__COMM__, PETSC_ERR_MPI, "MPI error %d %s", (int)ierr_petsc_call_mpi_, petsc_mpi_7_errorstring); \
572:       } \
573:     } while (0)

575:   #define PetscCallMPI(...)            PetscCallMPI_Private(PetscStackPop, SETERRQ, PETSC_COMM_SELF, __VA_ARGS__)
576:   #define PetscCallMPIAbort(comm, ...) PetscCallMPI_Private(PetscStackPopNoCheck(PETSC_FUNCTION_NAME), SETERRABORT, comm, __VA_ARGS__)
577: #endif

579: /*MC
580:   CHKERRMPI - Checks error code returned from MPI calls, if non-zero it calls the error
581:   handler and then returns

583:   Synopsis:
584: #include <petscerror.h>
585:   void CHKERRMPI(PetscErrorCode ierr)

587:   Not Collective

589:   Input Parameter:
590: . ierr - nonzero error code, see the list of standard error codes in include/petscerror.h

592:   Level: deprecated

594:   Note:
595:   Deprecated in favor of `PetscCallMPI()`. This routine behaves identically to it.

597: .seealso: `PetscCallMPI()`
598: M*/
599: #define CHKERRMPI(...) PetscCallMPI(__VA_ARGS__)

601: /*MC
602:   PetscCallAbort - Checks error code returned from PETSc function, if non-zero it aborts immediately

604:   Synopsis:
605: #include <petscerror.h>
606:   void PetscCallAbort(MPI_Comm comm, PetscErrorCode ierr)

608:   Collective

610:   Input Parameters:
611: + comm - the MPI communicator on which to abort
612: - ierr - nonzero error code, see the list of standard error codes in include/petscerror.h

614:   Level: intermediate

616:   Notes:
617:   This macro has identical type and usage semantics to `PetscCall()` with the important caveat
618:   that this macro does not return. Instead, if ierr is nonzero it calls the PETSc error handler
619:   and then immediately calls `MPI_Abort()`. It can therefore be used anywhere.

621:   As per `MPI_Abort()` semantics the communicator passed must be valid, although there is currently
622:   no attempt made at handling any potential errors from `MPI_Abort()`. Note that while
623:   `MPI_Abort()` is required to terminate only those processes which reside on comm, it is often
624:   the case that `MPI_Abort()` terminates *all* processes.

626:   Example Usage:
627: .vb
628:   PetscErrorCode boom(void) { return PETSC_ERR_MEM; }

630:   void foo(void)
631:   {
632:     PetscCallAbort(PETSC_COMM_WORLD,boom()); // OK, does not return a type
633:   }

635:   double bar(void)
636:   {
637:     PetscCallAbort(PETSC_COMM_WORLD,boom()); // OK, does not return a type
638:   }

640:   PetscCallAbort(MPI_COMM_NULL,boom()); // ERROR, communicator should be valid

642:   struct baz
643:   {
644:     baz()
645:     {
646:       PetscCallAbort(PETSC_COMM_SELF,boom()); // OK
647:     }

649:     ~baz()
650:     {
651:       PetscCallAbort(PETSC_COMM_SELF,boom()); // OK (in fact the only way to handle PETSc errors)
652:     }
653:   };
654: .ve

656: .seealso: `SETERRABORT()`, `PetscTraceBackErrorHandler()`, `PetscPushErrorHandler()`, `PetscError()`,
657:           `SETERRQ()`, `CHKMEMQ`, `PetscCallMPI()`, `PetscCallCXXAbort()`
658: M*/
659: #if defined(PETSC_CLANG_STATIC_ANALYZER)
660: void PetscCallAbort(MPI_Comm, PetscErrorCode);
661: void PetscCallContinue(PetscErrorCode);
662: #else
663:   #define PetscCallAbort(comm, ...) \
664:     do { \
665:       PetscErrorCode ierr_petsc_call_abort_; \
666:       PetscStackUpdateLine; \
667:       ierr_petsc_call_abort_ = __VA_ARGS__; \
668:       if (PetscUnlikely(ierr_petsc_call_abort_ != PETSC_SUCCESS)) { \
669:         ierr_petsc_call_abort_ = PetscError(PETSC_COMM_SELF, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr_petsc_call_abort_, PETSC_ERROR_REPEAT, " "); \
670:         (void)MPI_Abort(comm, (PetscMPIInt)ierr_petsc_call_abort_); \
671:       } \
672:     } while (0)
673:   #define PetscCallContinue(...) \
674:     do { \
675:       PetscErrorCode ierr_petsc_call_continue_; \
676:       PetscStackUpdateLine; \
677:       ierr_petsc_call_continue_ = __VA_ARGS__; \
678:       if (PetscUnlikely(ierr_petsc_call_continue_ != PETSC_SUCCESS)) { \
679:         ierr_petsc_call_continue_ = PetscError(PETSC_COMM_SELF, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr_petsc_call_continue_, PETSC_ERROR_REPEAT, " "); \
680:         (void)ierr_petsc_call_continue_; \
681:       } \
682:     } while (0)
683: #endif

685: /*MC
686:   CHKERRABORT - Checks error code returned from PETSc function. If non-zero it aborts immediately.

688:   Synopsis:
689: #include <petscerror.h>
690:   void CHKERRABORT(MPI_Comm comm, PetscErrorCode ierr)

692:   Not Collective

694:   Input Parameters:
695: + comm - the MPI communicator
696: - ierr - nonzero error code, see the list of standard error codes in include/petscerror.h

698:   Level: deprecated

700:   Note:
701:   Deprecated in favor of `PetscCallAbort()`. This routine behaves identically to it.

703: .seealso: `PetscCallAbort()`
704: M*/
705: #define CHKERRABORT(comm, ...) PetscCallAbort(comm, __VA_ARGS__)
706: #define CHKERRCONTINUE(...)    PetscCallContinue(__VA_ARGS__)

708: /*MC
709:    CHKERRA - Fortran-only replacement for use of `CHKERRQ()` in the main program, which aborts immediately

711:    Synopsis:
712: #include <petscsys.h>
713:    PetscErrorCode CHKERRA(PetscErrorCode ierr)

715:    Not Collective

717:    Input Parameters:
718: .  ierr - nonzero error code, see the list of standard error codes in include/petscerror.h

720:   Level: deprecated

722:    Note:
723:    This macro is rarely needed, normal usage is `PetscCallA()` in the main Fortran program.

725: .seealso: `PetscCall()`, `PetscCallA()`, `PetscCallAbort()`, `CHKERRQ()`, `SETERRA()`, `SETERRQ()`, `SETERRABORT()`
726: M*/

728: PETSC_EXTERN PetscBool petscwaitonerrorflg;
729: PETSC_EXTERN PetscBool petscindebugger;

731: /*MC
732:    PETSCABORT - Call `MPI_Abort()` with an informative error code

734:    Synopsis:
735: #include <petscsys.h>
736:    PETSCABORT(MPI_Comm comm, PetscErrorCode ierr)

738:    Collective

740:    Input Parameters:
741: +  comm - A communicator, so that the error can be collective
742: -  ierr - nonzero error code, see the list of standard error codes in include/petscerror.h

744:    Level: advanced

746:    Notes:
747:    If the option -start_in_debugger was used then this calls abort() to stop the program in the debugger.

749:    if `PetscCIEnabledPortableErrorOutput` is set it strives to exit cleanly without call `MPI_Abort()`

751: M*/
752: #if defined(PETSC_CLANG_STATIC_ANALYZER)
753: void PETSCABORT(MPI_Comm, PetscErrorCode);
754: #else
755:   #define PETSCABORT(comm, ...) \
756:     do { \
757:       PetscErrorCode ierr_petsc_abort_; \
758:       if (petscwaitonerrorflg) { ierr_petsc_abort_ = PetscSleep(1000); } \
759:       if (petscindebugger) { \
760:         abort(); \
761:       } else { \
762:         PetscMPIInt size_; \
763:         ierr_petsc_abort_ = __VA_ARGS__; \
764:         MPI_Comm_size(comm, &size_); \
765:         if (PetscCIEnabledPortableErrorOutput && size_ == PetscGlobalSize && ierr_petsc_abort_ != PETSC_ERR_SIG) { \
766:           MPI_Finalize(); \
767:           exit(0); \
768:         } else if (PetscCIEnabledPortableErrorOutput && PetscGlobalSize == 1) { \
769:           exit(0); \
770:         } else { \
771:           MPI_Abort(comm, (PetscMPIInt)ierr_petsc_abort_); \
772:         } \
773:       } \
774:     } while (0)
775: #endif

777: #ifdef PETSC_CLANGUAGE_CXX
778:   /*MC
779:   PetscCallThrow - Checks error code, if non-zero it calls the C++ error handler which throws
780:   an exception

782:   Synopsis:
783: #include <petscerror.h>
784:   void PetscCallThrow(PetscErrorCode ierr)

786:   Not Collective

788:   Input Parameter:
789: . ierr - nonzero error code, see the list of standard error codes in include/petscerror.h

791:   Level: beginner

793:   Notes:
794:   Requires PETSc to be configured with clanguage = c++. Throws a std::runtime_error() on error.

796:   Once the error handler throws the exception you can use `PetscCallVoid()` which returns without
797:   an error code (bad idea since the error is ignored) or `PetscCallAbort()` to have `MPI_Abort()`
798:   called immediately.

800: .seealso: `SETERRQ()`, `PetscCall()`, `SETERRABORT()`, `PetscCallAbort()`, `PetscTraceBackErrorHandler()`,
801:           `PetscPushErrorHandler()`, `PetscError()`, `CHKMEMQ`
802: M*/
803:   #define PetscCallThrow(...) \
804:     do { \
805:       PetscStackUpdateLine; \
806:       PetscErrorCode ierr_petsc_call_throw_ = __VA_ARGS__; \
807:       if (PetscUnlikely(ierr_petsc_call_throw_ != PETSC_SUCCESS)) PetscError(PETSC_COMM_SELF, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr_petsc_call_throw_, PETSC_ERROR_IN_CXX, PETSC_NULLPTR); \
808:     } while (0)

810:   /*MC
811:   CHKERRXX - Checks error code, if non-zero it calls the C++ error handler which throws an exception

813:   Synopsis:
814: #include <petscerror.h>
815:   void CHKERRXX(PetscErrorCode ierr)

817:   Not Collective

819:   Input Parameter:
820: . ierr - nonzero error code, see the list of standard error codes in include/petscerror.h

822:   Level: deprecated

824:   Note:
825:   Deprecated in favor of `PetscCallThrow()`. This routine behaves identically to it.

827: .seealso: `PetscCallThrow()`
828: M*/
829:   #define CHKERRXX(...) PetscCallThrow(__VA_ARGS__)
830: #endif

832: #define PetscCallCXX_Private(__SETERR_FUNC__, __COMM__, ...) \
833:   do { \
834:     PetscStackUpdateLine; \
835:     try { \
836:       __VA_ARGS__; \
837:     } catch (const std::exception &e) { \
838:       __SETERR_FUNC__(__COMM__, PETSC_ERR_LIB, "%s", e.what()); \
839:     } \
840:   } while (0)

842: /*MC
843:   PetscCallCXX - Checks C++ function calls and if they throw an exception, catch it and then
844:   return a PETSc error code

846:   Synopsis:
847: #include <petscerror.h>
848:   void PetscCallCXX(...) noexcept;

850:   Not Collective

852:   Input Parameter:
853: . __VA_ARGS__ - An arbitrary expression

855:   Level: beginner

857:   Notes:
858:   `PetscCallCXX(...)` is a macro replacement for
859: .vb
860:   try {
861:     __VA_ARGS__;
862:   } catch (const std::exception& e) {
863:     return ConvertToPetscErrorCode(e);
864:   }
865: .ve
866:   Due to the fact that it catches any (reasonable) exception, it is essentially noexcept.

868:   If you cannot return a `PetscErrorCode` use `PetscCallCXXAbort()` instead.

870:   Example Usage:
871: .vb
872:   void foo(void) { throw std::runtime_error("error"); }

874:   void bar()
875:   {
876:     PetscCallCXX(foo()); // ERROR bar() does not return PetscErrorCode
877:   }

879:   PetscErrorCode baz()
880:   {
881:     PetscCallCXX(foo()); // OK

883:     PetscCallCXX(
884:       bar();
885:       foo(); // OK multiple statements allowed
886:     );
887:   }

889:   struct bop
890:   {
891:     bop()
892:     {
893:       PetscCallCXX(foo()); // ERROR returns PetscErrorCode, cannot be used in constructors
894:     }
895:   };

897:   // ERROR contains do-while, cannot be used as function-try block
898:   PetscErrorCode qux() PetscCallCXX(
899:     bar();
900:     baz();
901:     foo();
902:     return 0;
903:   )
904: .ve

906: .seealso: `PetscCallCXXAbort()`, `PetscCallThrow()`, `SETERRQ()`, `PetscCall()`,
907:           `SETERRABORT()`, `PetscCallAbort()`, `PetscTraceBackErrorHandler()`, `PetscPushErrorHandler()`,
908:           `PetscError()`, `CHKMEMQ`
909: M*/
910: #define PetscCallCXX(...) PetscCallCXX_Private(SETERRQ, PETSC_COMM_SELF, __VA_ARGS__)

912: /*MC
913:   PetscCallCXXAbort - Like `PetscCallCXX()` but calls `MPI_Abort()` instead of returning an
914:   error-code

916:   Synopsis:
917: #include <petscerror.h>
918:   void PetscCallCXXAbort(MPI_Comm comm, ...) noexcept;

920:   Collective on `comm`

922:   Input Parameters:
923: + comm        - The MPI communicator to abort on
924: - __VA_ARGS__ - An arbitrary expression

926:   Level: beginner

928:   Notes:
929:   This macro may be used to check C++ expressions for exceptions in cases where you cannot
930:   return an error code. This includes constructors, destructors, copy/move assignment functions
931:   or constructors among others.

933:   If an exception is caught, the macro calls `SETERRABORT()` on `comm`. The exception must
934:   derive from `std::exception` in order to be caught.

936:   If the routine _can_ return an error-code it is highly advised to use `PetscCallCXX()`
937:   instead.

939:   See `PetscCallCXX()` for additional discussion.

941:   Fortran Note:
942:   Not available from Fortran.

944:   Example Usage:
945: .vb
946:   class Foo
947:   {
948:     std::vector<int> data_;

950:   public:
951:     // normally std::vector::reserve() may raise an exception, but since we handle it with
952:     // PetscCallCXXAbort() we may mark this routine as noexcept!
953:     Foo() noexcept
954:     {
955:       PetscCallCXXAbort(PETSC_COMM_SELF, data_.reserve(10));
956:     }
957:   };

959:   std::vector<int> bar()
960:   {
961:     std::vector<int> v;

963:     PetscFunctionBegin;
964:     // OK!
965:     PetscCallCXXAbort(PETSC_COMM_SELF, v.emplace_back(1));
966:     PetscFunctionReturn(v);
967:   }

969:   PetscErrorCode baz()
970:   {
971:     std::vector<int> v;

973:     PetscFunctionBegin;
974:     // WRONG! baz() returns a PetscErrorCode, prefer PetscCallCXX() instead
975:     PetscCallCXXAbort(PETSC_COMM_SELF, v.emplace_back(1));
976:     PetscFunctionReturn(PETSC_SUCCESS);
977:   }
978: .ve

980: .seealso: `PetscCallCXX()`, `SETERRABORT()`, `PetscCallAbort()`
981: M*/
982: #define PetscCallCXXAbort(comm, ...) PetscCallCXX_Private(SETERRABORT, comm, __VA_ARGS__)

984: /*MC
985:   CHKERRCXX - Checks C++ function calls and if they throw an exception, catch it and then
986:   return a PETSc error code

988:   Synopsis:
989: #include <petscerror.h>
990:   void CHKERRCXX(func) noexcept;

992:   Not Collective

994:   Input Parameter:
995: . func - C++ function calls

997:   Level: deprecated

999:   Note:
1000:   Deprecated in favor of `PetscCallCXX()`. This routine behaves identically to it.

1002: .seealso: `PetscCallCXX()`
1003: M*/
1004: #define CHKERRCXX(...) PetscCallCXX(__VA_ARGS__)

1006: /*MC
1007:    CHKMEMQ - Checks the memory for corruption, calls error handler if any is detected

1009:    Synopsis:
1010: #include <petscsys.h>
1011:    CHKMEMQ;

1013:    Not Collective

1015:   Level: beginner

1017:    Notes:
1018:     We highly recommend using Valgrind https://petsc.org/release/faq/#valgrind or for NVIDIA CUDA systems
1019:     https://docs.nvidia.com/cuda/cuda-memcheck/index.html for finding memory problems. The ``CHKMEMQ`` macro is useful on systems that
1020:     do not have valgrind, but is not as good as valgrind or cuda-memcheck.

1022:     Must run with the option `-malloc_debug` (`-malloc_test` in debug mode; or if `PetscMallocSetDebug()` called) to enable this option

1024:     Once the error handler is called the calling function is then returned from with the given error code.

1026:     By defaults prints location where memory that is corrupted was allocated.

1028:     Use `CHKMEMA` for functions that return void

1030: .seealso: `PetscTraceBackErrorHandler()`, `PetscPushErrorHandler()`, `PetscError()`, `SETERRQ()`, `PetscMallocValidate()`
1031: M*/
1032: #if defined(PETSC_CLANG_STATIC_ANALYZER)
1033:   #define CHKMEMQ
1034:   #define CHKMEMA
1035: #else
1036:   #define CHKMEMQ \
1037:     do { \
1038:       PetscErrorCode ierr_petsc_memq_ = PetscMallocValidate(__LINE__, PETSC_FUNCTION_NAME, __FILE__); \
1039:       if (PetscUnlikely(ierr_petsc_memq_ != PETSC_SUCCESS)) return PetscError(PETSC_COMM_SELF, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ierr_petsc_memq_, PETSC_ERROR_REPEAT, " "); \
1040:     } while (0)
1041:   #define CHKMEMA PetscMallocValidate(__LINE__, PETSC_FUNCTION_NAME, __FILE__)
1042: #endif

1044: /*E
1045:   PetscErrorType - passed to the PETSc error handling routines indicating if this is the first or a later call to the error handlers

1047:   Level: advanced

1049:   Note:
1050:   `PETSC_ERROR_IN_CXX` indicates the error was detected in C++ and an exception should be generated

1052:   Developer Note:
1053:     This is currently used to decide when to print the detailed information about the run in `PetscTraceBackErrorHandler()`

1055: .seealso: `PetscError()`, `SETERRQ()`
1056: E*/
1057: typedef enum {
1058:   PETSC_ERROR_INITIAL = 0,
1059:   PETSC_ERROR_REPEAT  = 1,
1060:   PETSC_ERROR_IN_CXX  = 2
1061: } PetscErrorType;

1063: #if defined(__clang_analyzer__)
1064: __attribute__((analyzer_noreturn))
1065: #endif
1066: PETSC_EXTERN PetscErrorCode
1067: PetscError(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, ...) PETSC_ATTRIBUTE_COLD PETSC_ATTRIBUTE_FORMAT(7, 8);

1069: PETSC_EXTERN PetscErrorCode PetscErrorPrintfInitialize(void);
1070: PETSC_EXTERN PetscErrorCode PetscErrorMessage(PetscErrorCode, const char *[], char **);
1071: PETSC_EXTERN PetscErrorCode PetscTraceBackErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD;
1072: PETSC_EXTERN PetscErrorCode PetscIgnoreErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD;
1073: PETSC_EXTERN PetscErrorCode PetscEmacsClientErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD;
1074: PETSC_EXTERN PetscErrorCode PetscMPIAbortErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD;
1075: PETSC_EXTERN PetscErrorCode PetscAbortErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD;
1076: PETSC_EXTERN PetscErrorCode PetscAttachDebuggerErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD;
1077: PETSC_EXTERN PetscErrorCode PetscReturnErrorHandler(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *) PETSC_ATTRIBUTE_COLD;
1078: PETSC_EXTERN PetscErrorCode PetscPushErrorHandler(PetscErrorCode (*handler)(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *), void *);
1079: PETSC_EXTERN PetscErrorCode PetscPopErrorHandler(void);
1080: PETSC_EXTERN PetscErrorCode PetscSignalHandlerDefault(int, void *);
1081: PETSC_EXTERN PetscErrorCode PetscPushSignalHandler(PetscErrorCode (*)(int, void *), void *);
1082: PETSC_EXTERN PetscErrorCode PetscPopSignalHandler(void);
1083: PETSC_EXTERN PetscErrorCode PetscCheckPointerSetIntensity(PetscInt);
1084: PETSC_EXTERN void           PetscSignalSegvCheckPointerOrMpi(void);
1085: PETSC_DEPRECATED_FUNCTION("Use PetscSignalSegvCheckPointerOrMpi() (since version 3.13)") static inline void PetscSignalSegvCheckPointer(void)
1086: {
1087:   PetscSignalSegvCheckPointerOrMpi();
1088: }

1090: /*MC
1091:     PetscErrorPrintf - Prints error messages.

1093:     Not Collective; No Fortran Support

1095:    Synopsis:
1096: #include <petscsys.h>
1097:      PetscErrorCode (*PetscErrorPrintf)(const char format[],...);

1099:     Input Parameter:
1100: .   format - the usual `printf()` format string

1102:    Options Database Keys:
1103: +    -error_output_stdout - cause error messages to be printed to stdout instead of the (default) stderr
1104: -    -error_output_none - to turn off all printing of error messages (does not change the way the error is handled.)

1106:    Level: developer

1108:    Notes:
1109:     Use
1110: .vb
1111:      PetscErrorPrintf = PetscErrorPrintfNone; to turn off all printing of error messages (does not change the way the
1112:                         error is handled.) and
1113:      PetscErrorPrintf = PetscErrorPrintfDefault; to turn it back on or you can use your own function
1114: .ve
1115:      Use
1116: .vb
1117:      `PETSC_STDERR` = FILE* obtained from a file open etc. to have stderr printed to the file.
1118:      `PETSC_STDOUT` = FILE* obtained from a file open etc. to have stdout printed to the file.
1119: .ve

1121:        Use
1122:       `PetscPushErrorHandler()` to provide your own error handler that determines what kind of messages to print

1124: .seealso: `PetscFPrintf()`, `PetscSynchronizedPrintf()`, `PetscHelpPrintf()`, `PetscPrintf()`, `PetscPushErrorHandler()`, `PetscVFPrintf()`, `PetscHelpPrintf()`
1125: M*/
1126: PETSC_EXTERN PetscErrorCode (*PetscErrorPrintf)(const char[], ...) PETSC_ATTRIBUTE_FORMAT(1, 2);

1128: /*E
1129:      PetscFPTrap - types of floating point exceptions that may be trapped

1131:      Currently only `PETSC_FP_TRAP_OFF` and `PETSC_FP_TRAP_ON` are handled. All others are treated as `PETSC_FP_TRAP_ON`.

1133:      Level: intermediate

1135: .seealso: `PetscSetFPTrap()`, `PetscPushFPTrap()`
1136:  E*/
1137: typedef enum {
1138:   PETSC_FP_TRAP_OFF      = 0,
1139:   PETSC_FP_TRAP_INDIV    = 1,
1140:   PETSC_FP_TRAP_FLTOPERR = 2,
1141:   PETSC_FP_TRAP_FLTOVF   = 4,
1142:   PETSC_FP_TRAP_FLTUND   = 8,
1143:   PETSC_FP_TRAP_FLTDIV   = 16,
1144:   PETSC_FP_TRAP_FLTINEX  = 32
1145: } PetscFPTrap;
1146: #define PETSC_FP_TRAP_ON (PetscFPTrap)(PETSC_FP_TRAP_INDIV | PETSC_FP_TRAP_FLTOPERR | PETSC_FP_TRAP_FLTOVF | PETSC_FP_TRAP_FLTDIV | PETSC_FP_TRAP_FLTINEX)
1147: PETSC_EXTERN PetscErrorCode PetscSetFPTrap(PetscFPTrap);
1148: PETSC_EXTERN PetscErrorCode PetscFPTrapPush(PetscFPTrap);
1149: PETSC_EXTERN PetscErrorCode PetscFPTrapPop(void);
1150: PETSC_EXTERN PetscErrorCode PetscDetermineInitialFPTrap(void);

1152: /*
1153:       Allows the code to build a stack frame as it runs
1154: */

1156: #define PETSCSTACKSIZE 64
1157: typedef struct {
1158:   const char *function[PETSCSTACKSIZE];
1159:   const char *file[PETSCSTACKSIZE];
1160:   int         line[PETSCSTACKSIZE];
1161:   int         petscroutine[PETSCSTACKSIZE]; /* 0 external called from petsc, 1 petsc functions, 2 petsc user functions */
1162:   int         currentsize;
1163:   int         hotdepth;
1164:   PetscBool   check; /* option to check for correct Push/Pop semantics, true for default petscstack but not other stacks */
1165: } PetscStack;
1166: #if defined(PETSC_USE_DEBUG) && !defined(PETSC_HAVE_THREADSAFETY)
1167: PETSC_EXTERN PetscStack petscstack;
1168: #endif

1170: #if defined(PETSC_SERIALIZE_FUNCTIONS)
1171: #include <petsc/private/petscfptimpl.h>
1172:   /*
1173:    Registers the current function into the global function pointer to function name table

1175:    Have to fix this to handle errors but cannot return error since used in PETSC_VIEWER_DRAW_() etc
1176: */
1177:   #define PetscRegister__FUNCT__() \
1178:     do { \
1179:       static PetscBool __chked = PETSC_FALSE; \
1180:       if (!__chked) { \
1181:         void *ptr; \
1182:         PetscCallAbort(PETSC_COMM_SELF, PetscDLSym(NULL, PETSC_FUNCTION_NAME, &ptr)); \
1183:         __chked = PETSC_TRUE; \
1184:       } \
1185:     } while (0)
1186: #else
1187:   #define PetscRegister__FUNCT__()
1188: #endif

1190: #if defined(PETSC_CLANG_STATIC_ANALYZER)
1191:   #define PetscStackPushNoCheck(funct, petsc_routine, hot)
1192:   #define PetscStackUpdateLine
1193:   #define PetscStackPushExternal(funct)
1194:   #define PetscStackPopNoCheck
1195:   #define PetscStackClearTop
1196:   #define PetscFunctionBegin
1197:   #define PetscFunctionBeginUser
1198:   #define PetscFunctionBeginHot
1199:   #define PetscFunctionReturn(...)  return __VA_ARGS__
1200:   #define PetscFunctionReturnVoid() return
1201:   #define PetscStackPop
1202:   #define PetscStackPush(f)
1203: #elif defined(PETSC_USE_DEBUG) && !defined(PETSC_HAVE_THREADSAFETY)

1205:   #define PetscStackPush_Private(stack__, file__, func__, line__, petsc_routine__, hot__) \
1206:     do { \
1207:       if (stack__.currentsize < PETSCSTACKSIZE) { \
1208:         stack__.function[stack__.currentsize] = func__; \
1209:         if (petsc_routine__) { \
1210:           stack__.file[stack__.currentsize] = file__; \
1211:           stack__.line[stack__.currentsize] = line__; \
1212:         } else { \
1213:           stack__.file[stack__.currentsize] = PETSC_NULLPTR; \
1214:           stack__.line[stack__.currentsize] = 0; \
1215:         } \
1216:         stack__.petscroutine[stack__.currentsize] = petsc_routine__; \
1217:       } \
1218:       ++stack__.currentsize; \
1219:       stack__.hotdepth += (hot__ || stack__.hotdepth); \
1220:     } while (0)

1222:   /* uses PetscCheckAbort() because may be used in a function that does not return an error code */
1223:   #define PetscStackPop_Private(stack__, func__) \
1224:     do { \
1225:       PetscCheckAbort(!stack__.check || stack__.currentsize > 0, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Invalid stack size %d, pop %s %s:%d.\n", stack__.currentsize, func__, __FILE__, __LINE__); \
1226:       if (--stack__.currentsize < PETSCSTACKSIZE) { \
1227:         PetscCheckAbort(!stack__.check || stack__.petscroutine[stack__.currentsize] != 1 || stack__.function[stack__.currentsize] == (const char *)(func__), PETSC_COMM_SELF, PETSC_ERR_PLIB, "Invalid stack: push from %s %s:%d. Pop from %s %s:%d.\n", \
1228:                         stack__.function[stack__.currentsize], stack__.file[stack__.currentsize], stack__.line[stack__.currentsize], func__, __FILE__, __LINE__); \
1229:         stack__.function[stack__.currentsize]     = PETSC_NULLPTR; \
1230:         stack__.file[stack__.currentsize]         = PETSC_NULLPTR; \
1231:         stack__.line[stack__.currentsize]         = 0; \
1232:         stack__.petscroutine[stack__.currentsize] = 0; \
1233:       } \
1234:       stack__.hotdepth = PetscMax(stack__.hotdepth - 1, 0); \
1235:     } while (0)

1237:   /*MC
1238:    PetscStackPushNoCheck - Pushes a new function name and line number onto the PETSc default stack that tracks where the running program is
1239:    currently in the source code.

1241:    Not Collective

1243:    Synopsis:
1244: #include <petscsys.h>
1245:    void PetscStackPushNoCheck(char *funct,int petsc_routine,PetscBool hot);

1247:    Input Parameters:
1248: +  funct - the function name
1249: .  petsc_routine - 2 user function, 1 PETSc function, 0 some other function
1250: -  hot - indicates that the function may be called often so expensive error checking should be turned off inside the function

1252:    Level: developer

1254:    Notes:
1255:    In debug mode PETSc maintains a stack of the current function calls that can be used to help to quickly see where a problem has
1256:    occurred, for example, when a signal is received without running in the debugger. It is recommended to use the debugger if extensive information is needed to
1257:    help debug the problem.

1259:    This version does not check the memory corruption (an expensive operation), use `PetscStackPush()` to check the memory.

1261:    Use `PetscStackPushExternal()` for a function call that is about to be made to a non-PETSc or user function (such as BLAS etc).

1263:    The default stack is a global variable called `petscstack`.

1265: .seealso: `PetscAttachDebugger()`, `PetscStackCopy()`, `PetscStackView()`, `PetscStackPopNoCheck()`, `PetscCall()`, `PetscFunctionBegin()`,
1266:           `PetscFunctionReturn()`, `PetscFunctionBeginHot()`, `PetscFunctionBeginUser()`, `PetscStackPush()`, `PetscStackPop`,
1267:           `PetscStackPushExternal()`
1268: M*/
1269:   #define PetscStackPushNoCheck(funct, petsc_routine, hot) \
1270:     do { \
1271:       PetscStackSAWsTakeAccess(); \
1272:       PetscStackPush_Private(petscstack, __FILE__, funct, __LINE__, petsc_routine, hot); \
1273:       PetscStackSAWsGrantAccess(); \
1274:     } while (0)

1276:   /*MC
1277:    PetscStackUpdateLine - in a function that has a `PetscFunctionBegin` or `PetscFunctionBeginUser` updates the stack line number to the
1278:    current line number.

1280:    Not Collective

1282:    Synopsis:
1283: #include <petscsys.h>
1284:    void PetscStackUpdateLine

1286:    Level: developer

1288:    Notes:
1289:    Using `PetscCall()` and friends automatically handles this process

1291:    In debug mode PETSc maintains a stack of the current function calls that can be used to help to quickly see where a problem has
1292:    occurred, for example, when a signal is received. It is recommended to use the debugger if extensive information is needed to
1293:    help debug the problem.

1295:    The default stack is a global variable called petscstack.

1297:    This is used by `PetscCall()` and is otherwise not like to be needed

1299: .seealso: `PetscAttachDebugger()`, `PetscStackCopy()`, `PetscStackView()`, `PetscStackPushNoCheck()`, `PetscStackPop`, `PetscCall()`
1300: M*/
1301:   #define PetscStackUpdateLine \
1302:     do { \
1303:       if (petscstack.currentsize > 0 && petscstack.function[petscstack.currentsize - 1] == PETSC_FUNCTION_NAME) { petscstack.line[petscstack.currentsize - 1] = __LINE__; } \
1304:     } while (0)

1306:   /*MC
1307:    PetscStackPushExternal - Pushes a new function name onto the PETSc default stack that tracks where the running program is
1308:    currently in the source code. Does not include the filename or line number since this is called by the calling routine
1309:    for non-PETSc or user functions.

1311:    Not Collective

1313:    Synopsis:
1314: #include <petscsys.h>
1315:    void PetscStackPushExternal(char *funct);

1317:    Input Parameters:
1318: .  funct - the function name

1320:    Level: developer

1322:    Notes:
1323:    Using `PetscCallExternal()` and friends automatically handles this process

1325:    In debug mode PETSc maintains a stack of the current function calls that can be used to help to quickly see where a problem has
1326:    occurred, for example, when a signal is received. It is recommended to use the debugger if extensive information is needed to
1327:    help debug the problem.

1329:    The default stack is a global variable called `petscstack`.

1331:    This is to be used when calling an external package function such as a BLAS function.

1333:    This also updates the stack line number for the current stack function.

1335: .seealso: `PetscAttachDebugger()`, `PetscStackCopy()`, `PetscStackView()`, `PetscStackPopNoCheck()`, `PetscCall()`, `PetscFunctionBegin()`,
1336:           `PetscFunctionReturn()`, `PetscFunctionBeginHot()`, `PetscFunctionBeginUser()`, `PetscStackPushNoCheck()`, `PetscStackPop`
1337: M*/
1338:   #define PetscStackPushExternal(funct) \
1339:     do { \
1340:       PetscStackUpdateLine; \
1341:       PetscStackPushNoCheck(funct, 0, PETSC_TRUE); \
1342:     } while (0);

1344:   /*MC
1345:    PetscStackPopNoCheck - Pops a function name from the PETSc default stack that tracks where the running program is
1346:    currently in the source code.

1348:    Not Collective

1350:    Synopsis:
1351: #include <petscsys.h>
1352:    void PetscStackPopNoCheck(char *funct);

1354:    Input Parameter:
1355: .   funct - the function name

1357:    Level: developer

1359:    Notes:
1360:    Using `PetscCall()`, `PetscCallExternal()`, `PetscCallBack()` and friends negates the need to call this

1362:    In debug mode PETSc maintains a stack of the current function calls that can be used to help to quickly see where a problem has
1363:    occurred, for example, when a signal is received. It is recommended to use the debugger if extensive information is needed to
1364:    help debug the problem.

1366:    The default stack is a global variable called petscstack.

1368:    Developer Note:
1369:    `PetscStackPopNoCheck()` takes a function argument while  `PetscStackPop` does not, this difference is likely just historical.

1371: .seealso: `PetscAttachDebugger()`, `PetscStackCopy()`, `PetscStackView()`, `PetscStackPushNoCheck()`, `PetscStackPop`
1372: M*/
1373:   #define PetscStackPopNoCheck(funct) \
1374:     do { \
1375:       PetscStackSAWsTakeAccess(); \
1376:       PetscStackPop_Private(petscstack, funct); \
1377:       PetscStackSAWsGrantAccess(); \
1378:     } while (0)

1380:   #define PetscStackClearTop \
1381:     do { \
1382:       PetscStackSAWsTakeAccess(); \
1383:       if (petscstack.currentsize > 0 && --petscstack.currentsize < PETSCSTACKSIZE) { \
1384:         petscstack.function[petscstack.currentsize]     = PETSC_NULLPTR; \
1385:         petscstack.file[petscstack.currentsize]         = PETSC_NULLPTR; \
1386:         petscstack.line[petscstack.currentsize]         = 0; \
1387:         petscstack.petscroutine[petscstack.currentsize] = 0; \
1388:       } \
1389:       petscstack.hotdepth = PetscMax(petscstack.hotdepth - 1, 0); \
1390:       PetscStackSAWsGrantAccess(); \
1391:     } while (0)

1393:   /*MC
1394:    PetscFunctionBegin - First executable line of each PETSc function,  used for error handling. Final
1395:       line of PETSc functions should be `PetscFunctionReturn`(0);

1397:    Synopsis:
1398: #include <petscsys.h>
1399:    void PetscFunctionBegin;

1401:    Not Collective

1403:    Usage:
1404: .vb
1405:      int something;

1407:      PetscFunctionBegin;
1408: .ve

1410:    Notes:
1411:      Use `PetscFunctionBeginUser` for application codes.

1413:      Not available in Fortran

1415:    Level: developer

1417: .seealso: `PetscFunctionReturn()`, `PetscFunctionBeginHot()`, `PetscFunctionBeginUser()`, `PetscStackPushNoCheck()`

1419: M*/
1420:   #define PetscFunctionBegin \
1421:     do { \
1422:       PetscStackPushNoCheck(PETSC_FUNCTION_NAME, 1, PETSC_FALSE); \
1423:       PetscRegister__FUNCT__(); \
1424:     } while (0)

1426:   /*MC
1427:    PetscFunctionBeginHot - Substitute for `PetscFunctionBegin` to be used in functions that are called in
1428:    performance-critical circumstances.  Use of this function allows for lighter profiling by default.

1430:    Synopsis:
1431: #include <petscsys.h>
1432:    void PetscFunctionBeginHot;

1434:    Not Collective

1436:    Usage:
1437: .vb
1438:      int something;

1440:      PetscFunctionBeginHot;
1441: .ve

1443:    Notes:
1444:      Not available in Fortran

1446:    Level: developer

1448: .seealso: `PetscFunctionBegin`, `PetscFunctionReturn()`, `PetscStackPushNoCheck()`

1450: M*/
1451:   #define PetscFunctionBeginHot \
1452:     do { \
1453:       PetscStackPushNoCheck(PETSC_FUNCTION_NAME, 1, PETSC_TRUE); \
1454:       PetscRegister__FUNCT__(); \
1455:     } while (0)

1457:   /*MC
1458:    PetscFunctionBeginUser - First executable line of user provided routines

1460:    Synopsis:
1461: #include <petscsys.h>
1462:    void PetscFunctionBeginUser;

1464:    Not Collective

1466:    Usage:
1467: .vb
1468:      int something;

1470:      PetscFunctionBeginUser;
1471: .ve

1473:    Notes:
1474:       Functions that incorporate this must call `PetscFunctionReturn()` instead of return except for main().

1476:       May be used before `PetscInitialize()`

1478:       Not available in Fortran

1480:       This is identical to `PetscFunctionBegin` except it labels the routine as a user
1481:       routine instead of as a PETSc library routine.

1483:    Level: intermediate

1485: .seealso: `PetscFunctionReturn()`, `PetscFunctionBegin`, `PetscFunctionBeginHot`, `PetscStackPushNoCheck()`

1487: M*/
1488:   #define PetscFunctionBeginUser \
1489:     do { \
1490:       PetscStackPushNoCheck(PETSC_FUNCTION_NAME, 2, PETSC_FALSE); \
1491:       PetscRegister__FUNCT__(); \
1492:     } while (0)

1494:   /*MC
1495:    PetscStackPush - Pushes a new function name and line number onto the PETSc default stack that tracks where the running program is
1496:    currently in the source code and verifies the memory is not corrupted.

1498:    Not Collective

1500:    Synopsis:
1501: #include <petscsys.h>
1502:    void PetscStackPush(char *funct)

1504:    Input Parameter:
1505: .  funct - the function name

1507:    Level: developer

1509:    Notes:
1510:    In debug mode PETSc maintains a stack of the current function calls that can be used to help to quickly see where a problem has
1511:    occurred, for example, when a signal is received. It is recommended to use the debugger if extensive information is needed to
1512:    help debug the problem.

1514:    The default stack is a global variable called petscstack.

1516: .seealso: `PetscAttachDebugger()`, `PetscStackCopy()`, `PetscStackView()`, `PetscStackPopNoCheck()`, `PetscCall()`, `PetscFunctionBegin()`,
1517:           `PetscFunctionReturn()`, `PetscFunctionBeginHot()`, `PetscFunctionBeginUser()`, `PetscStackPushNoCheck()`, `PetscStackPop`
1518: M*/
1519:   #define PetscStackPush(n) \
1520:     do { \
1521:       PetscStackPushNoCheck(n, 0, PETSC_FALSE); \
1522:       CHKMEMQ; \
1523:     } while (0)

1525:   /*MC
1526:    PetscStackPop - Pops a function name from the PETSc default stack that tracks where the running program is
1527:    currently in the source code and verifies the memory is not corrupted.

1529:    Not Collective

1531:    Synopsis:
1532: #include <petscsys.h>
1533:    void PetscStackPop

1535:    Level: developer

1537:    Notes:
1538:    In debug mode PETSc maintains a stack of the current function calls that can be used to help to quickly see where a problem has
1539:    occurred, for example, when a signal is received. It is recommended to use the debugger if extensive information is needed to
1540:    help debug the problem.

1542:    The default stack is a global variable called petscstack.

1544: .seealso: `PetscAttachDebugger()`, `PetscStackCopy()`, `PetscStackView()`, `PetscStackPushNoCheck()`, `PetscStackPopNoCheck()`, `PetscStackPush()`
1545: M*/
1546:   #define PetscStackPop \
1547:     do { \
1548:       CHKMEMQ; \
1549:       PetscStackPopNoCheck(PETSC_FUNCTION_NAME); \
1550:     } while (0)

1552:   /*MC
1553:    PetscFunctionReturn - Last executable line of each PETSc function used for error
1554:    handling. Replaces `return()`.

1556:    Synopsis:
1557: #include <petscerror.h>
1558:    void PetscFunctionReturn(...)

1560:    Not Collective; No Fortran Support

1562:    Level: beginner

1564:    Notes:
1565:    This routine is a macro, so while it does not "return" anything itself, it does return from
1566:    the function in the literal sense.

1568:    Usually the return value is the integer literal `0` (for example in any function returning
1569:    `PetscErrorCode`), however it is possible to return any arbitrary type. The arguments of
1570:    this macro are placed before the `return` statement as-is.

1572:    Any routine which returns via `PetscFunctionReturn()` must begin with a corresponding
1573:    `PetscFunctionBegin`.

1575:    For routines which return `void` use `PetscFunctionReturnVoid()` instead.

1577:    Example Usage:
1578: .vb
1579:    PetscErrorCode foo(int *x)
1580:    {
1581:      PetscFunctionBegin; // don't forget the begin!
1582:      *x = 10;
1583:      PetscFunctionReturn(PETSC_SUCCESS);
1584:    }
1585: .ve

1587:    May return any arbitrary type\:
1588: .vb
1589:   struct Foo
1590:   {
1591:     int x;
1592:   };

1594:   struct Foo make_foo(int value)
1595:   {
1596:     struct Foo f;

1598:     PetscFunctionBegin;
1599:     f.x = value;
1600:     PetscFunctionReturn(f);
1601:   }
1602: .ve

1604: .seealso: `PetscFunctionBegin`, `PetscFunctionBeginUser`, `PetscFunctionReturnVoid()`,
1605:           `PetscStackPopNoCheck()`
1606: M*/
1607:   #define PetscFunctionReturn(...) \
1608:     do { \
1609:       PetscStackPopNoCheck(PETSC_FUNCTION_NAME); \
1610:       return __VA_ARGS__; \
1611:     } while (0)

1613:   /*MC
1614:   PetscFunctionReturnVoid - Like `PetscFunctionReturn()` but returns `void`

1616:   Synopsis:
1617: #include <petscerror.h>
1618:   void PetscFunctionReturnVoid()

1620:   Not Collective

1622:   Level: beginner

1624:   Note:
1625:   Behaves identically to `PetscFunctionReturn()` except that it returns `void`. That is, this
1626:   macro culminates with `return`.

1628:   Example Usage:
1629: .vb
1630:   void foo()
1631:   {
1632:     PetscFunctionBegin; // must start with PetscFunctionBegin!
1633:     bar();
1634:     baz();
1635:     PetscFunctionReturnVoid();
1636:   }
1637: .ve

1639: .seealso: `PetscFunctionReturn()`, `PetscFunctionBegin`, PetscFunctionBeginUser`
1640: M*/
1641:   #define PetscFunctionReturnVoid() \
1642:     do { \
1643:       PetscStackPopNoCheck(PETSC_FUNCTION_NAME); \
1644:       return; \
1645:     } while (0)
1646: #else /* PETSC_USE_DEBUG */
1647:   #define PetscStackPushNoCheck(funct, petsc_routine, hot)
1648:   #define PetscStackUpdateLine
1649:   #define PetscStackPushExternal(funct)
1650:   #define PetscStackPopNoCheck(...)
1651:   #define PetscStackClearTop
1652:   #define PetscFunctionBegin
1653:   #define PetscFunctionBeginUser
1654:   #define PetscFunctionBeginHot
1655:   #define PetscFunctionReturn(...)  return __VA_ARGS__
1656:   #define PetscFunctionReturnVoid() return
1657:   #define PetscStackPop             CHKMEMQ
1658:   #define PetscStackPush(f)         CHKMEMQ
1659: #endif /* PETSC_USE_DEBUG */

1661: #if defined(PETSC_CLANG_STATIC_ANALYZER)
1662:   #define PetscStackCallExternalVoid(...)
1663: template <typename F, typename... Args>
1664: void PetscCallExternal(F, Args...);
1665: #else
1666:   /*MC
1667:     PetscStackCallExternalVoid - Calls an external library routine or user function after pushing the name of the routine on the stack.

1669:    Input Parameters:
1670: +   name - string that gives the name of the function being called
1671: -   routine - actual call to the routine, for example, functionname(a,b)

1673:    Level: developer

1675:    Note:
1676:    Often one should use `PetscCallExternal()` instead. This routine is intended for external library routines that DO NOT return error codes

1678:    In debug mode this also checks the memory for corruption at the end of the function call.

1680:    Certain external packages, such as BLAS/LAPACK may have their own macros for managing the call, error checking, etc.

1682:    Developer Note:
1683:    This is so that when a user or external library routine results in a crash or corrupts memory, they get blamed instead of PETSc.

1685: .seealso: `PetscCall()`, `PetscStackPushNoCheck()`, `PetscStackPush()`, `PetscCallExternal()`, `PetscCallBLAS()`
1686: @*/
1687:   #define PetscStackCallExternalVoid(name, ...) \
1688:     do { \
1689:       PetscStackPush(name); \
1690:       __VA_ARGS__; \
1691:       PetscStackPop; \
1692:     } while (0)

1694:   /*MC
1695:     PetscCallExternal - Calls an external library routine that returns an error code after pushing the name of the routine on the stack.

1697:    Input Parameters:
1698: +   func-  name of the routine
1699: -   args - arguments to the routine

1701:    Level: developer

1703:    Notes:
1704:    This is intended for external package routines that return error codes. Use `PetscStackCallExternalVoid()` for those that do not.

1706:    In debug mode this also checks the memory for corruption at the end of the function call.

1708:    Assumes the error return code of the function is an integer and that a value of 0 indicates success

1710:    Developer Note:
1711:    This is so that when an external package routine results in a crash or corrupts memory, they get blamed instead of PETSc.

1713: .seealso: `PetscCall()`, `PetscStackPushNoCheck()`, `PetscStackPush()`, `PetscStackCallExternalVoid()`
1714: M*/
1715:   #define PetscCallExternal(func, ...) \
1716:     do { \
1717:       PetscStackPush(PetscStringize(func)); \
1718:       int ierr_petsc_call_external_ = func(__VA_ARGS__); \
1719:       PetscStackPop; \
1720:       PetscCheck(ierr_petsc_call_external_ == 0, PETSC_COMM_SELF, PETSC_ERR_LIB, "Error in %s(): error code %d", PetscStringize(func), ierr_petsc_call_external_); \
1721:     } while (0)
1722: #endif /* PETSC_CLANG_STATIC_ANALYZER */

1724: #endif