17d0a6c19SBarry Smith 2e5c89e4eSSatish Balay /* 30e3d61c9SBarry Smith IEEE error handler for all machines. Since each OS has 40e3d61c9SBarry Smith enough slight differences we have completely separate codes for each one. 5e5c89e4eSSatish Balay */ 6b014e56cSJed Brown 7b014e56cSJed Brown /* 8b014e56cSJed Brown This feature test macro provides FE_NOMASK_ENV on GNU. It must be defined 9b014e56cSJed Brown at the top of the file because other headers may pull in fenv.h even when 10b014e56cSJed Brown not strictly necessary. Strictly speaking, we could include ONLY petscconf.h, 11b014e56cSJed Brown check PETSC_HAVE_FENV_H, and only define _GNU_SOURCE in that case, but such 12b014e56cSJed Brown shenanigans ought to be unnecessary. 13b014e56cSJed Brown */ 14519f805aSKarl Rupp #if !defined(_GNU_SOURCE) 15b014e56cSJed Brown #define _GNU_SOURCE 1676a6984eSJed Brown #endif 17b014e56cSJed Brown 1827104ee2SJacob Faibussowitsch #include <petsc/private/petscimpl.h> /*I "petscsys.h" I*/ 19e5c89e4eSSatish Balay #include <signal.h> 20e5c89e4eSSatish Balay 21670f3ff9SJed Brown struct PetscFPTrapLink { 22670f3ff9SJed Brown PetscFPTrap trapmode; 23670f3ff9SJed Brown struct PetscFPTrapLink *next; 24670f3ff9SJed Brown }; 25aba4c478SBarry Smith static PetscFPTrap _trapmode = PETSC_FP_TRAP_OFF; /* Current trapping mode; see PetscDetermineInitialFPTrap() */ 26670f3ff9SJed Brown static struct PetscFPTrapLink *_trapstack; /* Any pushed states of _trapmode */ 27670f3ff9SJed Brown 28670f3ff9SJed Brown /*@ 29cc9df77eSBarry Smith PetscFPTrapPush - push a floating point trapping mode, restored using PetscFPTrapPop() 30670f3ff9SJed Brown 31670f3ff9SJed Brown Not Collective 32670f3ff9SJed Brown 334165533cSJose E. Roman Input Parameter: 34cf0818bdSBarry Smith . trap - PETSC_FP_TRAP_ON or PETSC_FP_TRAP_OFF or any of the values passable to `PetscSetFPTrap()` 35670f3ff9SJed Brown 36670f3ff9SJed Brown Level: advanced 37670f3ff9SJed Brown 38cc9df77eSBarry Smith Notes: 39cc9df77eSBarry Smith This only changes the trapping if the new mode is different than the current mode. 40cc9df77eSBarry Smith 41cc9df77eSBarry Smith This routine is called to turn off trapping for certain LAPACK routines that assume that dividing 42cc9df77eSBarry Smith by zero is acceptable. In particular the routine ieeeck(). 43cc9df77eSBarry Smith 44cc9df77eSBarry Smith Most systems by default have all trapping turned off, but certain Fortran compilers have 45cc9df77eSBarry Smith link flags that turn on trapping before the program begins. 46cc9df77eSBarry Smith $ gfortran -ffpe-trap=invalid,zero,overflow,underflow,denormal 47cc9df77eSBarry Smith $ ifort -fpe0 48cc9df77eSBarry Smith 49db781477SPatrick Sanan .seealso: `PetscFPTrapPop()`, `PetscSetFPTrap()`, `PetscDetermineInitialFPTrap()` 50670f3ff9SJed Brown @*/ 519371c9d4SSatish Balay PetscErrorCode PetscFPTrapPush(PetscFPTrap trap) { 52670f3ff9SJed Brown struct PetscFPTrapLink *link; 53670f3ff9SJed Brown 54670f3ff9SJed Brown PetscFunctionBegin; 559566063dSJacob Faibussowitsch PetscCall(PetscNew(&link)); 561f006be4SPierre Jolivet #if defined(PETSC_HAVE_THREADSAFETY) && defined(PETSC_HAVE_OPENMP) 571f006be4SPierre Jolivet #pragma omp critical 581f006be4SPierre Jolivet #endif 591f006be4SPierre Jolivet { 60670f3ff9SJed Brown link->trapmode = _trapmode; 61670f3ff9SJed Brown link->next = _trapstack; 62670f3ff9SJed Brown _trapstack = link; 631f006be4SPierre Jolivet } 649566063dSJacob Faibussowitsch if (trap != _trapmode) PetscCall(PetscSetFPTrap(trap)); 65670f3ff9SJed Brown PetscFunctionReturn(0); 66670f3ff9SJed Brown } 67670f3ff9SJed Brown 68670f3ff9SJed Brown /*@ 69670f3ff9SJed Brown PetscFPTrapPop - push a floating point trapping mode, to be restored using PetscFPTrapPop() 70670f3ff9SJed Brown 71670f3ff9SJed Brown Not Collective 72670f3ff9SJed Brown 73670f3ff9SJed Brown Level: advanced 74670f3ff9SJed Brown 75db781477SPatrick Sanan .seealso: `PetscFPTrapPush()`, `PetscSetFPTrap()`, `PetscDetermineInitialFPTrap()` 76670f3ff9SJed Brown @*/ 779371c9d4SSatish Balay PetscErrorCode PetscFPTrapPop(void) { 78670f3ff9SJed Brown struct PetscFPTrapLink *link; 79670f3ff9SJed Brown 80670f3ff9SJed Brown PetscFunctionBegin; 819566063dSJacob Faibussowitsch if (_trapstack->trapmode != _trapmode) PetscCall(PetscSetFPTrap(_trapstack->trapmode)); 821f006be4SPierre Jolivet #if defined(PETSC_HAVE_THREADSAFETY) && defined(PETSC_HAVE_OPENMP) 831f006be4SPierre Jolivet #pragma omp critical 841f006be4SPierre Jolivet #endif 851f006be4SPierre Jolivet { 86670f3ff9SJed Brown link = _trapstack; 87670f3ff9SJed Brown _trapstack = _trapstack->next; 881f006be4SPierre Jolivet } 899566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 90670f3ff9SJed Brown PetscFunctionReturn(0); 91670f3ff9SJed Brown } 92670f3ff9SJed Brown 93e5c89e4eSSatish Balay /*--------------------------------------- ---------------------------------------------------*/ 94e5c89e4eSSatish Balay #if defined(PETSC_HAVE_SUN4_STYLE_FPTRAP) 95e5c89e4eSSatish Balay #include <floatingpoint.h> 96e5c89e4eSSatish Balay 978cc058d9SJed Brown PETSC_EXTERN PetscErrorCode ieee_flags(char *, char *, char *, char **); 988cc058d9SJed Brown PETSC_EXTERN PetscErrorCode ieee_handler(char *, char *, sigfpe_handler_type(int, int, struct sigcontext *, char *)); 99e5c89e4eSSatish Balay 1009371c9d4SSatish Balay static struct { 1019371c9d4SSatish Balay int code_no; 1029371c9d4SSatish Balay char *name; 1039371c9d4SSatish Balay } error_codes[] = { 104e5c89e4eSSatish Balay {FPE_INTDIV_TRAP, "integer divide" }, 105e5c89e4eSSatish Balay {FPE_FLTOPERR_TRAP, "IEEE operand error" }, 106e5c89e4eSSatish Balay {FPE_FLTOVF_TRAP, "floating point overflow" }, 107e5c89e4eSSatish Balay {FPE_FLTUND_TRAP, "floating point underflow" }, 108e5c89e4eSSatish Balay {FPE_FLTDIV_TRAP, "floating pointing divide" }, 109e5c89e4eSSatish Balay {FPE_FLTINEX_TRAP, "inexact floating point result"}, 110e5c89e4eSSatish Balay {0, "unknown error" } 111e5c89e4eSSatish Balay }; 112e5c89e4eSSatish Balay #define SIGPC(scp) (scp->sc_pc) 113e5c89e4eSSatish Balay 114cf0818bdSBarry Smith /* this function gets called if a trap has occurred and been caught */ 1159371c9d4SSatish Balay sigfpe_handler_type PetscDefaultFPTrap(int sig, int code, struct sigcontext *scp, char *addr) { 1165f80ce2aSJacob Faibussowitsch int err_ind = -1; 117e5c89e4eSSatish Balay 118e5c89e4eSSatish Balay PetscFunctionBegin; 1195f80ce2aSJacob Faibussowitsch for (int j = 0; error_codes[j].code_no; j++) { 120e5c89e4eSSatish Balay if (error_codes[j].code_no == code) err_ind = j; 121e5c89e4eSSatish Balay } 122e5c89e4eSSatish Balay 123a297a907SKarl Rupp if (err_ind >= 0) (*PetscErrorPrintf)("*** %s occurred at pc=%X ***\n", error_codes[err_ind].name, SIGPC(scp)); 124a297a907SKarl Rupp else (*PetscErrorPrintf)("*** floating point error 0x%x occurred at pc=%X ***\n", code, SIGPC(scp)); 125a297a907SKarl Rupp 12649c86fc7SBarry Smith (void)PetscError(PETSC_COMM_SELF, PETSC_ERR_FP, NULL, NULL, PETSC_ERR_FP, PETSC_ERROR_REPEAT, "floating point error"); 12741e02c4dSJunchao Zhang PETSCABORT(MPI_COMM_WORLD, PETSC_ERR_FP); 128e5c89e4eSSatish Balay PetscFunctionReturn(0); 129e5c89e4eSSatish Balay } 130e5c89e4eSSatish Balay 131e30d2299SSatish Balay /*@ 132cf0818bdSBarry Smith PetscSetFPTrap - Enables traps/exceptions on common floating point errors. This option may not work on certain systems or only a 133cf0818bdSBarry Smith subset of exceptions may be trapable. 134e5c89e4eSSatish Balay 135e5c89e4eSSatish Balay Not Collective 136e5c89e4eSSatish Balay 137e5c89e4eSSatish Balay Input Parameters: 138cf0818bdSBarry Smith . flag - values are 139cf0818bdSBarry Smith .vb 140cf0818bdSBarry Smith PETSC_FP_TRAP_OFF - do not trap any exceptions 141cf0818bdSBarry Smith PETSC_FP_TRAP_ON - all exceptions that are possible on the system except underflow 142cf0818bdSBarry Smith PETSC_FP_TRAP_INDIV - integer divide by zero 143cf0818bdSBarry Smith PETSC_FP_TRAP_FLTOPERR - improper argument to function, for example with real numbers, the square root of a negative number 144cf0818bdSBarry Smith PETSC_FP_TRAP_FLTOVF - overflow 145cf0818bdSBarry Smith PETSC_FP_TRAP_FLTUND - underflow - not trapped by default on most systems 146cf0818bdSBarry Smith PETSC_FP_TRAP_FLTDIV - floating point divide by zero 147cf0818bdSBarry Smith PETSC_FP_TRAP_FLTINEX - inexact floating point result 148cf0818bdSBarry Smith .ve 149e5c89e4eSSatish Balay 150e5c89e4eSSatish Balay Options Database Keys: 151cf0818bdSBarry Smith . -fp_trap <off,on> - turn on or off trapping of floating point exceptions 152e5c89e4eSSatish Balay 153e5c89e4eSSatish Balay Level: advanced 154e5c89e4eSSatish Balay 155cf0818bdSBarry Smith Notes: 156cf0818bdSBarry Smith Currently only PETSC_FP_TRAP_OFF and PETSC_FP_TRAP_ON are handled. All others are treated as PETSC_FP_TRAP_ON. 157cf0818bdSBarry Smith 158cf0818bdSBarry Smith The values are bit values and may be |ed together in the function call 159cf0818bdSBarry Smith 160cf0818bdSBarry Smith On systems that support it this routine causes floating point 161cf0818bdSBarry Smith overflow, divide-by-zero, and invalid-operand (e.g., a NaN), but not underflow, to 162e5c89e4eSSatish Balay cause a message to be printed and the program to exit. 163e5c89e4eSSatish Balay 164cc9df77eSBarry Smith On many common systems, the floating 1657d125cddSJed Brown point exception state is not preserved from the location where the trap 1667d125cddSJed Brown occurred through to the signal handler. In this case, the signal handler 1677d125cddSJed Brown will just say that an unknown floating point exception occurred and which 1687d125cddSJed Brown function it occurred in. If you run with -fp_trap in a debugger, it will 169cc9df77eSBarry Smith break on the line where the error occurred. On systems that support C99 170cc9df77eSBarry Smith floating point exception handling You can check which 1717d125cddSJed Brown exception occurred using fetestexcept(FE_ALL_EXCEPT). See fenv.h 1727d125cddSJed Brown (usually at /usr/include/bits/fenv.h) for the enum values on your system. 1737d125cddSJed Brown 174e5c89e4eSSatish Balay Caution: 175cc9df77eSBarry Smith On certain machines, in particular the IBM PowerPC, floating point 176cc9df77eSBarry Smith trapping may be VERY slow! 177e5c89e4eSSatish Balay 178db781477SPatrick Sanan .seealso: `PetscFPTrapPush()`, `PetscFPTrapPop()`, `PetscDetermineInitialFPTrap()` 179e5c89e4eSSatish Balay @*/ 1809371c9d4SSatish Balay PetscErrorCode PetscSetFPTrap(PetscFPTrap flag) { 181e5c89e4eSSatish Balay char *out; 182e5c89e4eSSatish Balay 183e5c89e4eSSatish Balay PetscFunctionBegin; 184e5c89e4eSSatish Balay /* Clear accumulated exceptions. Used to suppress meaningless messages from f77 programs */ 185e5c89e4eSSatish Balay (void)ieee_flags("clear", "exception", "all", &out); 186*bd2b07b1SBarry Smith if (flag == PETSC_FP_TRAP_ON) { 187e5c89e4eSSatish Balay /* 188a297a907SKarl Rupp To trap more fp exceptions, including underflow, change the line below to 189e5c89e4eSSatish Balay if (ieee_handler("set","all",PetscDefaultFPTrap)) { 190e5c89e4eSSatish Balay */ 191a297a907SKarl Rupp if (ieee_handler("set", "common", PetscDefaultFPTrap)) (*PetscErrorPrintf)("Can't set floatingpoint handler\n"); 192a297a907SKarl Rupp } else if (ieee_handler("clear", "common", PetscDefaultFPTrap)) (*PetscErrorPrintf)("Can't clear floatingpoint handler\n"); 193a297a907SKarl Rupp 194670f3ff9SJed Brown _trapmode = flag; 195*bd2b07b1SBarry Smith PetscCall(PetscInfo(NULL, "Using PETSC_HAVE_SUN4_STYLE_FPTRAP\n")); 196e5c89e4eSSatish Balay PetscFunctionReturn(0); 197e5c89e4eSSatish Balay } 198e5c89e4eSSatish Balay 199cc9df77eSBarry Smith /*@ 200aba4c478SBarry Smith PetscDetermineInitialFPTrap - Attempts to determine the floating point trapping that exists when PetscInitialize() is called 201cc9df77eSBarry Smith 202cc9df77eSBarry Smith Not Collective 203cc9df77eSBarry Smith 204cc9df77eSBarry Smith Notes: 205cc9df77eSBarry Smith Currently only supported on Linux and MacOS. Checks if divide by zero is enable and if so declares that trapping is on. 206cc9df77eSBarry Smith 207ee300463SSatish Balay Level: advanced 208cc9df77eSBarry Smith 209db781477SPatrick Sanan .seealso: `PetscFPTrapPush()`, `PetscFPTrapPop()`, `PetscDetermineInitialFPTrap()` 210cc9df77eSBarry Smith @*/ 2119371c9d4SSatish Balay PetscErrorCode PetscDetermineInitialFPTrap(void) { 212cc9df77eSBarry Smith PetscFunctionBegin; 2139566063dSJacob Faibussowitsch PetscCall(PetscInfo(NULL, "Unable to determine initial floating point trapping. Assuming it is off\n")); 214cc9df77eSBarry Smith PetscFunctionReturn(0); 215cc9df77eSBarry Smith } 216cc9df77eSBarry Smith 217e5c89e4eSSatish Balay /* -------------------------------------------------------------------------------------------*/ 218e5c89e4eSSatish Balay #elif defined(PETSC_HAVE_SOLARIS_STYLE_FPTRAP) 219e5c89e4eSSatish Balay #include <sunmath.h> 220e5c89e4eSSatish Balay #include <floatingpoint.h> 221e5c89e4eSSatish Balay #include <siginfo.h> 222e5c89e4eSSatish Balay #include <ucontext.h> 223e5c89e4eSSatish Balay 2249371c9d4SSatish Balay static struct { 2259371c9d4SSatish Balay int code_no; 2269371c9d4SSatish Balay char *name; 2279371c9d4SSatish Balay } error_codes[] = { 228e5c89e4eSSatish Balay {FPE_FLTINV, "invalid floating point operand"}, 229e5c89e4eSSatish Balay {FPE_FLTRES, "inexact floating point result" }, 230e5c89e4eSSatish Balay {FPE_FLTDIV, "division-by-zero" }, 231e5c89e4eSSatish Balay {FPE_FLTUND, "floating point underflow" }, 232e5c89e4eSSatish Balay {FPE_FLTOVF, "floating point overflow" }, 233e5c89e4eSSatish Balay {0, "unknown error" } 234e5c89e4eSSatish Balay }; 235e5c89e4eSSatish Balay #define SIGPC(scp) (scp->si_addr) 236e5c89e4eSSatish Balay 2379371c9d4SSatish Balay void PetscDefaultFPTrap(int sig, siginfo_t *scp, ucontext_t *uap) { 2385f80ce2aSJacob Faibussowitsch int err_ind = -1, code = scp->si_code; 239e5c89e4eSSatish Balay 240e5c89e4eSSatish Balay PetscFunctionBegin; 2415f80ce2aSJacob Faibussowitsch for (int j = 0; error_codes[j].code_no; j++) { 242e5c89e4eSSatish Balay if (error_codes[j].code_no == code) err_ind = j; 243e5c89e4eSSatish Balay } 244e5c89e4eSSatish Balay 245a297a907SKarl Rupp if (err_ind >= 0) (*PetscErrorPrintf)("*** %s occurred at pc=%X ***\n", error_codes[err_ind].name, SIGPC(scp)); 246a297a907SKarl Rupp else (*PetscErrorPrintf)("*** floating point error 0x%x occurred at pc=%X ***\n", code, SIGPC(scp)); 247a297a907SKarl Rupp 24849c86fc7SBarry Smith (void)PetscError(PETSC_COMM_SELF, 0, NULL, NULL, PETSC_ERR_FP, PETSC_ERROR_REPEAT, "floating point error"); 24941e02c4dSJunchao Zhang PETSCABORT(MPI_COMM_WORLD, PETSC_ERR_FP); 250e5c89e4eSSatish Balay } 251e5c89e4eSSatish Balay 2529371c9d4SSatish Balay PetscErrorCode PetscSetFPTrap(PetscFPTrap flag) { 253e5c89e4eSSatish Balay char *out; 254e5c89e4eSSatish Balay 255e5c89e4eSSatish Balay PetscFunctionBegin; 256e5c89e4eSSatish Balay /* Clear accumulated exceptions. Used to suppress meaningless messages from f77 programs */ 257e5c89e4eSSatish Balay (void)ieee_flags("clear", "exception", "all", &out); 258e5c89e4eSSatish Balay if (flag == PETSC_FP_TRAP_ON) { 259a297a907SKarl Rupp if (ieee_handler("set", "common", (sigfpe_handler_type)PetscDefaultFPTrap)) (*PetscErrorPrintf)("Can't set floating point handler\n"); 260cc9df77eSBarry Smith } else { 261cc9df77eSBarry Smith if (ieee_handler("clear", "common", (sigfpe_handler_type)PetscDefaultFPTrap)) (*PetscErrorPrintf)("Can't clear floatingpoint handler\n"); 262cc9df77eSBarry Smith } 263670f3ff9SJed Brown _trapmode = flag; 264*bd2b07b1SBarry Smith PetscCall(PetscInfo(NULL,"Using PETSC_HAVE_SOLARIS_STYLE_FPTRAP\n"); 265e5c89e4eSSatish Balay PetscFunctionReturn(0); 266e5c89e4eSSatish Balay } 267e5c89e4eSSatish Balay 2689371c9d4SSatish Balay PetscErrorCode PetscDetermineInitialFPTrap(void) { 269cc9df77eSBarry Smith PetscFunctionBegin; 2709566063dSJacob Faibussowitsch PetscCall(PetscInfo(NULL, "Unable to determine initial floating point trapping. Assuming it is off\n")); 271cc9df77eSBarry Smith PetscFunctionReturn(0); 272cc9df77eSBarry Smith } 273cc9df77eSBarry Smith 274cc9df77eSBarry Smith /* ------------------------------------------------------------------------------------------*/ 275e5c89e4eSSatish Balay #elif defined(PETSC_HAVE_IRIX_STYLE_FPTRAP) 276e5c89e4eSSatish Balay #include <sigfpe.h> 2779371c9d4SSatish Balay static struct { 2789371c9d4SSatish Balay int code_no; 2799371c9d4SSatish Balay char *name; 2809371c9d4SSatish Balay } error_codes[] = { 281e5c89e4eSSatish Balay {_INVALID, "IEEE operand error" }, 282e5c89e4eSSatish Balay {_OVERFL, "floating point overflow" }, 283e5c89e4eSSatish Balay {_UNDERFL, "floating point underflow"}, 284e5c89e4eSSatish Balay {_DIVZERO, "floating point divide" }, 285e5c89e4eSSatish Balay {0, "unknown error" } 286e5c89e4eSSatish Balay }; 2879371c9d4SSatish Balay void PetscDefaultFPTrap(unsigned exception[], int val[]) { 2885f80ce2aSJacob Faibussowitsch int err_ind = -1, code = exception[0]; 289e5c89e4eSSatish Balay 290e5c89e4eSSatish Balay PetscFunctionBegin; 2915f80ce2aSJacob Faibussowitsch for (int j = 0; error_codes[j].code_no; j++) { 292e5c89e4eSSatish Balay if (error_codes[j].code_no == code) err_ind = j; 293e5c89e4eSSatish Balay } 294a297a907SKarl Rupp if (err_ind >= 0) (*PetscErrorPrintf)("*** %s occurred ***\n", error_codes[err_ind].name); 295a297a907SKarl Rupp else (*PetscErrorPrintf)("*** floating point error 0x%x occurred ***\n", code); 296a297a907SKarl Rupp 29749c86fc7SBarry Smith (void)PetscError(PETSC_COMM_SELF, 0, NULL, NULL, PETSC_ERR_FP, PETSC_ERROR_REPEAT, "floating point error"); 29841e02c4dSJunchao Zhang PETSCABORT(MPI_COMM_WORLD, PETSC_ERR_FP); 299e5c89e4eSSatish Balay } 300e5c89e4eSSatish Balay 3019371c9d4SSatish Balay PetscErrorCode PetscSetFPTrap(PetscFPTrap flag) { 302e5c89e4eSSatish Balay PetscFunctionBegin; 303*bd2b07b1SBarry Smith if (flag == PETSC_FP_TRAP_ON) handle_sigfpes(_ON, , _EN_UNDERFL | _EN_OVERFL | _EN_DIVZERO | _EN_INVALID, PetscDefaultFPTrap, _ABORT_ON_ERROR, 0); 304cc9df77eSBarry Smith else handle_sigfpes(_OFF, _EN_UNDERFL | _EN_OVERFL | _EN_DIVZERO | _EN_INVALID, 0, _ABORT_ON_ERROR, 0); 305670f3ff9SJed Brown _trapmode = flag; 306*bd2b07b1SBarry Smith PetscCall(PetscInfo(NULL, "Using PETSC_HAVE_IRIX_STYLE_FPTRAP\n")); 307cc9df77eSBarry Smith PetscFunctionReturn(0); 308cc9df77eSBarry Smith } 309cc9df77eSBarry Smith 3109371c9d4SSatish Balay PetscErrorCode PetscDetermineInitialFPTrap(void) { 311cc9df77eSBarry Smith PetscFunctionBegin; 3129566063dSJacob Faibussowitsch PetscCall(PetscInfo(NULL, "Unable to determine initial floating point trapping. Assuming it is off\n")); 313cc9df77eSBarry Smith PetscFunctionReturn(0); 314cc9df77eSBarry Smith } 315cc9df77eSBarry Smith 316cc9df77eSBarry Smith /*----------------------------------------------- --------------------------------------------*/ 317cc9df77eSBarry Smith #elif defined(PETSC_HAVE_RS6000_STYLE_FPTRAP) 318e5c89e4eSSatish Balay /* In "fast" mode, floating point traps are imprecise and ignored. 319e5c89e4eSSatish Balay This is the reason for the fptrap(FP_TRAP_SYNC) call */ 320e5c89e4eSSatish Balay struct sigcontext; 321e5c89e4eSSatish Balay #include <fpxcp.h> 322e5c89e4eSSatish Balay #include <fptrap.h> 323e5c89e4eSSatish Balay #define FPE_FLTOPERR_TRAP (fptrap_t)(0x20000000) 324e5c89e4eSSatish Balay #define FPE_FLTOVF_TRAP (fptrap_t)(0x10000000) 325e5c89e4eSSatish Balay #define FPE_FLTUND_TRAP (fptrap_t)(0x08000000) 326e5c89e4eSSatish Balay #define FPE_FLTDIV_TRAP (fptrap_t)(0x04000000) 327e5c89e4eSSatish Balay #define FPE_FLTINEX_TRAP (fptrap_t)(0x02000000) 328e5c89e4eSSatish Balay 3299371c9d4SSatish Balay static struct { 3309371c9d4SSatish Balay int code_no; 3319371c9d4SSatish Balay char *name; 3329371c9d4SSatish Balay } error_codes[] = { 333e5c89e4eSSatish Balay {FPE_FLTOPERR_TRAP, "IEEE operand error" }, 334e5c89e4eSSatish Balay {FPE_FLTOVF_TRAP, "floating point overflow" }, 335e5c89e4eSSatish Balay {FPE_FLTUND_TRAP, "floating point underflow" }, 336e5c89e4eSSatish Balay {FPE_FLTDIV_TRAP, "floating point divide" }, 337e5c89e4eSSatish Balay {FPE_FLTINEX_TRAP, "inexact floating point result"}, 338*bd2b07b1SBarry Smith < {0, "unknown error" } 339e5c89e4eSSatish Balay }; 340e5c89e4eSSatish Balay #define SIGPC(scp) (0) /* Info MIGHT be in scp->sc_jmpbuf.jmp_context.iar */ 341e5c89e4eSSatish Balay /* 342e5c89e4eSSatish Balay For some reason, scp->sc_jmpbuf does not work on the RS6000, even though 343e5c89e4eSSatish Balay it looks like it should from the include definitions. It is probably 344e5c89e4eSSatish Balay some strange interaction with the "POSIX_SOURCE" that we require. 345e5c89e4eSSatish Balay */ 346e5c89e4eSSatish Balay 3479371c9d4SSatish Balay void PetscDefaultFPTrap(int sig, int code, struct sigcontext *scp) { 348e5c89e4eSSatish Balay int err_ind, j; 349e5c89e4eSSatish Balay fp_ctx_t flt_context; 350e5c89e4eSSatish Balay 351e5c89e4eSSatish Balay PetscFunctionBegin; 352e5c89e4eSSatish Balay fp_sh_trap_info(scp, &flt_context); 353e5c89e4eSSatish Balay 354e5c89e4eSSatish Balay err_ind = -1; 355e5c89e4eSSatish Balay for (j = 0; error_codes[j].code_no; j++) { 356e5c89e4eSSatish Balay if (error_codes[j].code_no == flt_context.trap) err_ind = j; 357e5c89e4eSSatish Balay } 358e5c89e4eSSatish Balay 359a297a907SKarl Rupp if (err_ind >= 0) (*PetscErrorPrintf)("*** %s occurred ***\n", error_codes[err_ind].name); 360a297a907SKarl Rupp else (*PetscErrorPrintf)("*** floating point error 0x%x occurred ***\n", flt_context.trap); 361a297a907SKarl Rupp 36249c86fc7SBarry Smith (void)PetscError(PETSC_COMM_SELF, 0, NULL, NULL, PETSC_ERR_FP, PETSC_ERROR_REPEAT, "floating point error"); 36341e02c4dSJunchao Zhang PETSCABORT(MPI_COMM_WORLD, PETSC_ERR_FP); 364e5c89e4eSSatish Balay } 365e5c89e4eSSatish Balay 3669371c9d4SSatish Balay PetscErrorCode PetscSetFPTrap(PetscFPTrap flag) { 367e5c89e4eSSatish Balay PetscFunctionBegin; 368*bd2b07b1SBarry Smith if (flag == PETSC_FP_TRAP_ON) { 369e5c89e4eSSatish Balay signal(SIGFPE, (void (*)(int))PetscDefaultFPTrap); 370e5c89e4eSSatish Balay fp_trap(FP_TRAP_SYNC); 371*bd2b07b1SBarry Smith /* fp_enable(TRP_INVALID | TRP_DIV_BY_ZERO | TRP_OVERFLOW | TRP_UNDERFLOW); */ 372*bd2b07b1SBarry Smith fp_enable(TRP_INVALID | TRP_DIV_BY_ZERO | TRP_OVERFLOW); 373e5c89e4eSSatish Balay } else { 374e5c89e4eSSatish Balay signal(SIGFPE, SIG_DFL); 375cc9df77eSBarry Smith fp_disable(TRP_INVALID | TRP_DIV_BY_ZERO | TRP_OVERFLOW | TRP_UNDERFLOW); 376e5c89e4eSSatish Balay fp_trap(FP_TRAP_OFF); 377e5c89e4eSSatish Balay } 378cf0818bdSBarry Smith _trapmode = flag; 379*bd2b07b1SBarry Smith PetscCall(PetscInfo(NULL, "Using PETSC_HAVE_RS6000_STYLE_FPTRAP\n")); 380e5c89e4eSSatish Balay PetscFunctionReturn(0); 381e5c89e4eSSatish Balay } 382e5c89e4eSSatish Balay 3839371c9d4SSatish Balay PetscErrorCode PetscDetermineInitialFPTrap(void) { 384cc9df77eSBarry Smith PetscFunctionBegin; 3859566063dSJacob Faibussowitsch PetscCall(PetscInfo(NULL, "Unable to determine initial floating point trapping. Assuming it is off\n")); 386cc9df77eSBarry Smith PetscFunctionReturn(0); 387cc9df77eSBarry Smith } 388cc9df77eSBarry Smith 389cc9df77eSBarry Smith /* ------------------------------------------------------------*/ 390cc9df77eSBarry Smith #elif defined(PETSC_HAVE_WINDOWS_COMPILERS) 391cc9df77eSBarry Smith #include <float.h> 3929371c9d4SSatish Balay void PetscDefaultFPTrap(int sig) { 393cc9df77eSBarry Smith PetscFunctionBegin; 394cc9df77eSBarry Smith (*PetscErrorPrintf)("*** floating point error occurred ***\n"); 39549c86fc7SBarry Smith PetscError(PETSC_COMM_SELF, 0, NULL, NULL, PETSC_ERR_FP, PETSC_ERROR_REPEAT, "floating point error"); 396cc9df77eSBarry Smith PETSCABORT(MPI_COMM_WORLD, PETSC_ERR_FP); 397cc9df77eSBarry Smith } 398cc9df77eSBarry Smith 3999371c9d4SSatish Balay PetscErrorCode PetscSetFPTrap(PetscFPTrap flag) { 400cc9df77eSBarry Smith unsigned int cw; 401cc9df77eSBarry Smith 402cc9df77eSBarry Smith PetscFunctionBegin; 403*bd2b07b1SBarry Smith if (flag == PETSC_FP_TRAP_ON) { 404*bd2b07b1SBarry Smith /* cw = _EM_INVALID | _EM_ZERODIVIDE | _EM_OVERFLOW | _EM_UNDERFLOW; */ 405*bd2b07b1SBarry Smith cw = _EM_INVALID | _EM_ZERODIVIDE | _EM_OVERFLOW; 40608401ef6SPierre Jolivet PetscCheck(SIG_ERR != signal(SIGFPE, PetscDefaultFPTrap), PETSC_COMM_SELF, PETSC_ERR_LIB, "Can't set floating point handler"); 407cc9df77eSBarry Smith } else { 408cc9df77eSBarry Smith cw = 0; 40908401ef6SPierre Jolivet PetscCheck(SIG_ERR != signal(SIGFPE, SIG_DFL), PETSC_COMM_SELF, PETSC_ERR_LIB, "Can't clear floating point handler"); 410cc9df77eSBarry Smith } 411cc9df77eSBarry Smith (void)_controlfp(0, cw); 412cf0818bdSBarry Smith _trapmode = flag; 413*bd2b07b1SBarry Smith PetscCall(PetscInfo(NULL, "Using PETSC_HAVE_WINDOWS_COMPILERS FPTRAP\n")); 414cc9df77eSBarry Smith PetscFunctionReturn(0); 415cc9df77eSBarry Smith } 416cc9df77eSBarry Smith 4179371c9d4SSatish Balay PetscErrorCode PetscDetermineInitialFPTrap(void) { 418cc9df77eSBarry Smith PetscFunctionBegin; 4199566063dSJacob Faibussowitsch PetscCall(PetscInfo(NULL, "Unable to determine initial floating point trapping. Assuming it is off\n")); 420cc9df77eSBarry Smith PetscFunctionReturn(0); 421cc9df77eSBarry Smith } 422cc9df77eSBarry Smith 423cc9df77eSBarry Smith /* ------------------------------------------------------------*/ 4249a2402e9SBarry Smith #elif defined(PETSC_HAVE_FENV_H) && !defined(__cplusplus) 425b014e56cSJed Brown /* 426b014e56cSJed Brown C99 style floating point environment. 427b014e56cSJed Brown 428b014e56cSJed Brown Note that C99 merely specifies how to save, restore, and clear the floating 429b014e56cSJed Brown point environment as well as defining an enumeration of exception codes. In 430b014e56cSJed Brown particular, C99 does not specify how to make floating point exceptions raise 431b014e56cSJed Brown a signal. Glibc offers this capability through FE_NOMASK_ENV (or with finer 432b014e56cSJed Brown granularity, feenableexcept()), xmmintrin.h offers _MM_SET_EXCEPTION_MASK(). 433b014e56cSJed Brown */ 434b014e56cSJed Brown #include <fenv.h> 4359371c9d4SSatish Balay typedef struct { 4369371c9d4SSatish Balay int code; 4379371c9d4SSatish Balay const char *name; 4389371c9d4SSatish Balay } FPNode; 439b014e56cSJed Brown static const FPNode error_codes[] = { 440b014e56cSJed Brown {FE_DIVBYZERO, "divide by zero" }, 441b014e56cSJed Brown {FE_INEXACT, "inexact floating point result" }, 442b014e56cSJed Brown {FE_INVALID, "invalid floating point arguments (domain error)"}, 443b014e56cSJed Brown {FE_OVERFLOW, "floating point overflow" }, 444b014e56cSJed Brown {FE_UNDERFLOW, "floating point underflow" }, 445b014e56cSJed Brown {0, "unknown error" } 446b014e56cSJed Brown }; 44799e0435eSBarry Smith 4489371c9d4SSatish Balay void PetscDefaultFPTrap(int sig) { 449b014e56cSJed Brown const FPNode *node; 450b014e56cSJed Brown int code; 451ace3abfcSBarry Smith PetscBool matched = PETSC_FALSE; 452b014e56cSJed Brown 453b014e56cSJed Brown PetscFunctionBegin; 454b014e56cSJed Brown /* Note: While it is possible for the exception state to be preserved by the 455b014e56cSJed Brown * kernel, this seems to be rare which makes the following flag testing almost 456b014e56cSJed Brown * useless. But on a system where the flags can be preserved, it would provide 4577d125cddSJed Brown * more detail. 458b014e56cSJed Brown */ 459b014e56cSJed Brown code = fetestexcept(FE_ALL_EXCEPT); 460b014e56cSJed Brown for (node = &error_codes[0]; node->code; node++) { 461b014e56cSJed Brown if (code & node->code) { 462b014e56cSJed Brown matched = PETSC_TRUE; 463b014e56cSJed Brown (*PetscErrorPrintf)("*** floating point error \"%s\" occurred ***\n", node->name); 464b014e56cSJed Brown code &= ~node->code; /* Unset this flag since it has been processed */ 465b014e56cSJed Brown } 466b014e56cSJed Brown } 467b014e56cSJed Brown if (!matched || code) { /* If any remaining flags are set, or we didn't process any flags */ 468b014e56cSJed Brown (*PetscErrorPrintf)("*** unknown floating point error occurred ***\n"); 4697d125cddSJed Brown (*PetscErrorPrintf)("The specific exception can be determined by running in a debugger. When the\n"); 4707d125cddSJed Brown (*PetscErrorPrintf)("debugger traps the signal, the exception can be found with fetestexcept(0x%x)\n", FE_ALL_EXCEPT); 4717d125cddSJed Brown (*PetscErrorPrintf)("where the result is a bitwise OR of the following flags:\n"); 4727d125cddSJed Brown (*PetscErrorPrintf)("FE_INVALID=0x%x FE_DIVBYZERO=0x%x FE_OVERFLOW=0x%x FE_UNDERFLOW=0x%x FE_INEXACT=0x%x\n", FE_INVALID, FE_DIVBYZERO, FE_OVERFLOW, FE_UNDERFLOW, FE_INEXACT); 473b014e56cSJed Brown } 4747d125cddSJed Brown 4757d125cddSJed Brown (*PetscErrorPrintf)("Try option -start_in_debugger\n"); 47627104ee2SJacob Faibussowitsch #if PetscDefined(USE_DEBUG) 4777d125cddSJed Brown (*PetscErrorPrintf)("likely location of problem given in stack below\n"); 4787d125cddSJed Brown (*PetscErrorPrintf)("--------------------- Stack Frames ------------------------------------\n"); 479639ff905SBarry Smith PetscStackView(PETSC_STDOUT); 48027104ee2SJacob Faibussowitsch #else 4817d125cddSJed Brown (*PetscErrorPrintf)("configure using --with-debugging=yes, recompile, link, and run \n"); 4827d125cddSJed Brown (*PetscErrorPrintf)("with -start_in_debugger to get more information on the crash.\n"); 48327104ee2SJacob Faibussowitsch #endif 48449c86fc7SBarry Smith PetscError(PETSC_COMM_SELF, 0, NULL, NULL, PETSC_ERR_FP, PETSC_ERROR_INITIAL, "trapped floating point error"); 48541e02c4dSJunchao Zhang PETSCABORT(MPI_COMM_WORLD, PETSC_ERR_FP); 486b014e56cSJed Brown } 487b014e56cSJed Brown 4889371c9d4SSatish Balay PetscErrorCode PetscSetFPTrap(PetscFPTrap flag) { 489b014e56cSJed Brown PetscFunctionBegin; 490*bd2b07b1SBarry Smith if (flag == PETSC_FP_TRAP_ON) { 491b014e56cSJed Brown /* Clear any flags that are currently set so that activating trapping will not immediately call the signal handler. */ 492cc73adaaSBarry Smith PetscCheck(!feclearexcept(FE_ALL_EXCEPT), PETSC_COMM_SELF, PETSC_ERR_LIB, "Cannot clear floating point exception flags"); 493cc9df77eSBarry Smith #if defined(FE_NOMASK_ENV) 494cc9df77eSBarry Smith /* Could use fesetenv(FE_NOMASK_ENV), but that causes spurious exceptions (like gettimeofday() -> PetscLogDouble). */ 495cf0818bdSBarry Smith /* PetscCheck(feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW) != -1,PETSC_COMM_SELF,PETSC_ERR_LIB,"Cannot activate floating point exceptions"); */ 496*bd2b07b1SBarry Smith /* Doesn't work on AArch64 targets. There's a known hardware limitation. Need to detect hardware at configure time? */ 497cf0818bdSBarry Smith PetscCheck(feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW) != -1, PETSC_COMM_SELF, PETSC_ERR_LIB, "Cannot activate floating point exceptions"); 498*bd2b07b1SBarry Smith PetscCall(PetscInfo(NULL, "Using PETSC_HAVE_FENV_H FPTRAP with FE_NOMASK_ENV\n")); 499b014e56cSJed Brown #elif defined PETSC_HAVE_XMMINTRIN_H 500cc9df77eSBarry Smith _MM_SET_EXCEPTION_MASK(_MM_GET_EXCEPTION_MASK() & ~_MM_MASK_DIV_ZERO); 501*bd2b07b1SBarry Smith /* _MM_SET_EXCEPTION_MASK(_MM_GET_EXCEPTION_MASK() & ~_MM_MASK_UNDERFLOW); */ 502cc9df77eSBarry Smith _MM_SET_EXCEPTION_MASK(_MM_GET_EXCEPTION_MASK() & ~_MM_MASK_OVERFLOW); 503cc9df77eSBarry Smith _MM_SET_EXCEPTION_MASK(_MM_GET_EXCEPTION_MASK() & ~_MM_MASK_INVALID); 504*bd2b07b1SBarry Smith PetscCall(PetscInfo(NULL, "Using PETSC_HAVE_FENV_H FPTRAP with PETSC_HAVE_XMMINTRIN_H\n")); 505b014e56cSJed Brown #else 506b014e56cSJed Brown /* C99 does not provide a way to modify the environment so there is no portable way to activate trapping. */ 507*bd2b07b1SBarry Smith PetscCall(PetscInfo(NULL, "Using PETSC_HAVE_FENV_H FPTRAP\n")); 508b014e56cSJed Brown #endif 50908401ef6SPierre Jolivet PetscCheck(SIG_ERR != signal(SIGFPE, PetscDefaultFPTrap), PETSC_COMM_SELF, PETSC_ERR_LIB, "Can't set floating point handler"); 510b014e56cSJed Brown } else { 511cc73adaaSBarry Smith PetscCheck(!fesetenv(FE_DFL_ENV), PETSC_COMM_SELF, PETSC_ERR_LIB, "Cannot disable floating point exceptions"); 512cc9df77eSBarry Smith /* can use _MM_SET_EXCEPTION_MASK(_MM_GET_EXCEPTION_MASK() | _MM_MASK_UNDERFLOW); if PETSC_HAVE_XMMINTRIN_H exists */ 51308401ef6SPierre Jolivet PetscCheck(SIG_ERR != signal(SIGFPE, SIG_DFL), PETSC_COMM_SELF, PETSC_ERR_LIB, "Can't clear floating point handler"); 514b014e56cSJed Brown } 515cf0818bdSBarry Smith _trapmode = flag; 516b014e56cSJed Brown PetscFunctionReturn(0); 517b014e56cSJed Brown } 518b014e56cSJed Brown 5199371c9d4SSatish Balay PetscErrorCode PetscDetermineInitialFPTrap(void) { 520cc9df77eSBarry Smith #if defined(FE_NOMASK_ENV) || defined PETSC_HAVE_XMMINTRIN_H 521cc9df77eSBarry Smith unsigned int flags; 522cc9df77eSBarry Smith #endif 523cc9df77eSBarry Smith 524cc9df77eSBarry Smith PetscFunctionBegin; 525cc9df77eSBarry Smith #if defined(FE_NOMASK_ENV) 526cc9df77eSBarry Smith flags = fegetexcept(); 527cc9df77eSBarry Smith if (flags & FE_DIVBYZERO) { 528cc9df77eSBarry Smith #elif defined PETSC_HAVE_XMMINTRIN_H 529cc9df77eSBarry Smith flags = _MM_GET_EXCEPTION_MASK(); 530cc9df77eSBarry Smith if (!(flags & _MM_MASK_DIV_ZERO)) { 531cc9df77eSBarry Smith #else 5329566063dSJacob Faibussowitsch PetscCall(PetscInfo(NULL, "Floating point trapping unknown, assuming off\n")); 533cc9df77eSBarry Smith PetscFunctionReturn(0); 534cc9df77eSBarry Smith #endif 535cc9df77eSBarry Smith #if defined(FE_NOMASK_ENV) || defined PETSC_HAVE_XMMINTRIN_H 536cc9df77eSBarry Smith _trapmode = PETSC_FP_TRAP_ON; 5379566063dSJacob Faibussowitsch PetscCall(PetscInfo(NULL, "Floating point trapping is on by default %d\n", flags)); 538cc9df77eSBarry Smith } else { 539cc9df77eSBarry Smith _trapmode = PETSC_FP_TRAP_OFF; 5409566063dSJacob Faibussowitsch PetscCall(PetscInfo(NULL, "Floating point trapping is off by default %d\n", flags)); 541cc9df77eSBarry Smith } 542cc9df77eSBarry Smith PetscFunctionReturn(0); 543cc9df77eSBarry Smith #endif 544cc9df77eSBarry Smith } 545cc9df77eSBarry Smith 546cc9df77eSBarry Smith /* ------------------------------------------------------------*/ 547cc9df77eSBarry Smith #elif defined(PETSC_HAVE_IEEEFP_H) 548cc9df77eSBarry Smith #include <ieeefp.h> 5499371c9d4SSatish Balay void PetscDefaultFPTrap(int sig) { 550cc9df77eSBarry Smith PetscFunctionBegin; 551cc9df77eSBarry Smith (*PetscErrorPrintf)("*** floating point error occurred ***\n"); 55249c86fc7SBarry Smith PetscError(PETSC_COMM_SELF, 0, NULL, NULL, PETSC_ERR_FP, PETSC_ERROR_REPEAT, "floating point error"); 553cc9df77eSBarry Smith PETSCABORT(MPI_COMM_WORLD, PETSC_ERR_FP); 554cc9df77eSBarry Smith } 555cc9df77eSBarry Smith 5569371c9d4SSatish Balay PetscErrorCode PetscSetFPTrap(PetscFPTrap flag) { 557cc9df77eSBarry Smith PetscFunctionBegin; 558cf0818bdSBarry Smith if (flag == PETSC_FP_TRAP_ON) { 559cc9df77eSBarry Smith #if defined(PETSC_HAVE_FPPRESETSTICKY) 560cc9df77eSBarry Smith fpresetsticky(fpgetsticky()); 561cc9df77eSBarry Smith #elif defined(PETSC_HAVE_FPSETSTICKY) 562cc9df77eSBarry Smith fpsetsticky(fpgetsticky()); 563cc9df77eSBarry Smith #endif 564cc9df77eSBarry Smith fpsetmask(FP_X_INV | FP_X_DZ | FP_X_OFL | FP_X_OFL); 56508401ef6SPierre Jolivet PetscCheck(SIG_ERR != signal(SIGFPE, PetscDefaultFPTrap), PETSC_COMM_SELF, PETSC_ERR_LIB, "Can't set floating point handler"); 566cc9df77eSBarry Smith } else { 567cc9df77eSBarry Smith #if defined(PETSC_HAVE_FPPRESETSTICKY) 568cc9df77eSBarry Smith fpresetsticky(fpgetsticky()); 569cc9df77eSBarry Smith #elif defined(PETSC_HAVE_FPSETSTICKY) 570cc9df77eSBarry Smith fpsetsticky(fpgetsticky()); 571cc9df77eSBarry Smith #endif 572cc9df77eSBarry Smith fpsetmask(0); 57308401ef6SPierre Jolivet PetscCheck(SIG_ERR != signal(SIGFPE, SIG_DFL), PETSC_COMM_SELF, PETSC_ERR_LIB, "Can't clear floating point handler"); 574cc9df77eSBarry Smith } 575cf0818bdSBarry Smith _trapmode = flag; 576*bd2b07b1SBarry Smith PetscCall(PetscInfo(NULL, "Using PETSC_HAVE_IEEEFP_H FPTRAP\n")); 577cc9df77eSBarry Smith PetscFunctionReturn(0); 578cc9df77eSBarry Smith } 579cc9df77eSBarry Smith 5809371c9d4SSatish Balay PetscErrorCode PetscDetermineInitialFPTrap(void) { 581cc9df77eSBarry Smith PetscFunctionBegin; 5829566063dSJacob Faibussowitsch PetscCall(PetscInfo(NULL, "Unable to determine initial floating point trapping. Assuming it is off\n")); 583cc9df77eSBarry Smith PetscFunctionReturn(0); 584cc9df77eSBarry Smith } 585cc9df77eSBarry Smith 586e5c89e4eSSatish Balay /* -------------------------Default -----------------------------------*/ 587e5c89e4eSSatish Balay #else 58899e0435eSBarry Smith 5899371c9d4SSatish Balay void PetscDefaultFPTrap(int sig) { 590e5c89e4eSSatish Balay PetscFunctionBegin; 591e5c89e4eSSatish Balay (*PetscErrorPrintf)("*** floating point error occurred ***\n"); 59249c86fc7SBarry Smith PetscError(PETSC_COMM_SELF, 0, NULL, NULL, PETSC_ERR_FP, PETSC_ERROR_REPEAT, "floating point error"); 59341e02c4dSJunchao Zhang PETSCABORT(MPI_COMM_WORLD, PETSC_ERR_FP); 594e5c89e4eSSatish Balay } 59599e0435eSBarry Smith 5969371c9d4SSatish Balay PetscErrorCode PetscSetFPTrap(PetscFPTrap flag) { 597e5c89e4eSSatish Balay PetscFunctionBegin; 598*bd2b07b1SBarry Smith if (flag == PETSC_FP_TRAP_ON) { 599a297a907SKarl Rupp if (SIG_ERR == signal(SIGFPE, PetscDefaultFPTrap)) (*PetscErrorPrintf)("Can't set floatingpoint handler\n"); 600a297a907SKarl Rupp } else if (SIG_ERR == signal(SIGFPE, SIG_DFL)) (*PetscErrorPrintf)("Can't clear floatingpoint handler\n"); 601a297a907SKarl Rupp 602cf0818bdSBarry Smith _trapmode = flag; 603*bd2b07b1SBarry Smith PetscCall(PetscInfo(NULL, "Using default FPTRAP\n")); 604e5c89e4eSSatish Balay PetscFunctionReturn(0); 605e5c89e4eSSatish Balay } 606cc9df77eSBarry Smith 6079371c9d4SSatish Balay PetscErrorCode PetscDetermineInitialFPTrap(void) { 608cc9df77eSBarry Smith PetscFunctionBegin; 6099566063dSJacob Faibussowitsch PetscCall(PetscInfo(NULL, "Unable to determine initial floating point trapping. Assuming it is off\n")); 610cc9df77eSBarry Smith PetscFunctionReturn(0); 611cc9df77eSBarry Smith } 612e5c89e4eSSatish Balay #endif 613