diff options
| author | Sebastian Berg <sebastian@sipsolutions.net> | 2022-05-01 17:57:17 +0200 |
|---|---|---|
| committer | Sebastian Berg <sebastian@sipsolutions.net> | 2022-06-13 14:13:36 -0700 |
| commit | 86f415e2992734ed3cd588c5c3138d63189c993b (patch) | |
| tree | e0df9db073d4bf21b0c34db345effbe1b9a19e03 /numpy | |
| parent | cadfd83cb1e1df466eb91eb9c38dd2775455d64d (diff) | |
| download | numpy-86f415e2992734ed3cd588c5c3138d63189c993b.tar.gz | |
MAINT: Remove FPE helper code that is unnecessary on C99/C++11
C99 and C++11 standardize `fenv.h`, so we should not need the manual
definitions for these functions for platforms that do not support it.
See e.g.: https://en.cppreference.com/w/c/numeric/fenv
If issues come up, the code can be restored.
This applies gh-21421 again, since we had to revert using the cpp file
and the change thus got lost.
Diffstat (limited to 'numpy')
| -rw-r--r-- | numpy/core/src/npymath/ieee754.c.src | 223 |
1 files changed, 4 insertions, 219 deletions
diff --git a/numpy/core/src/npymath/ieee754.c.src b/numpy/core/src/npymath/ieee754.c.src index 4e6ddb712..6dc9cf2f8 100644 --- a/numpy/core/src/npymath/ieee754.c.src +++ b/numpy/core/src/npymath/ieee754.c.src @@ -566,227 +566,13 @@ int npy_get_floatstatus() { return npy_get_floatstatus_barrier(&x); } -/* - * Functions to set the floating point status word. - */ - -#if (defined(__unix__) || defined(unix)) && !defined(USG) -#include <sys/param.h> -#endif - - -/* - * Define floating point status functions. We must define - * npy_get_floatstatus_barrier, npy_clear_floatstatus_barrier, - * npy_set_floatstatus_{divbyzero, overflow, underflow, invalid} - * for all supported platforms. - */ - - -/* Solaris --------------------------------------------------------*/ -/* --------ignoring SunOS ieee_flags approach, someone else can -** deal with that! */ -#if defined(sun) || defined(__BSD__) || defined(__OpenBSD__) || \ - (defined(__FreeBSD__) && (__FreeBSD_version < 502114)) || \ - defined(__NetBSD__) -#include <ieeefp.h> - -int npy_get_floatstatus_barrier(char * param) -{ - int fpstatus = fpgetsticky(); - /* - * By using a volatile, the compiler cannot reorder this call - */ - if (param != NULL) { - volatile char NPY_UNUSED(c) = *(char*)param; - } - return ((FP_X_DZ & fpstatus) ? NPY_FPE_DIVIDEBYZERO : 0) | - ((FP_X_OFL & fpstatus) ? NPY_FPE_OVERFLOW : 0) | - ((FP_X_UFL & fpstatus) ? NPY_FPE_UNDERFLOW : 0) | - ((FP_X_INV & fpstatus) ? NPY_FPE_INVALID : 0); -} - -int npy_clear_floatstatus_barrier(char * param) -{ - int fpstatus = npy_get_floatstatus_barrier(param); - fpsetsticky(0); - - return fpstatus; -} - -void npy_set_floatstatus_divbyzero(void) -{ - fpsetsticky(FP_X_DZ); -} - -void npy_set_floatstatus_overflow(void) -{ - fpsetsticky(FP_X_OFL); -} - -void npy_set_floatstatus_underflow(void) -{ - fpsetsticky(FP_X_UFL); -} - -void npy_set_floatstatus_invalid(void) -{ - fpsetsticky(FP_X_INV); -} - -#elif defined(_AIX) && !defined(__GNUC__) -#include <float.h> -#include <fpxcp.h> - -int npy_get_floatstatus_barrier(char *param) -{ - int fpstatus = fp_read_flag(); - /* - * By using a volatile, the compiler cannot reorder this call - */ - if (param != NULL) { - volatile char NPY_UNUSED(c) = *(char*)param; - } - return ((FP_DIV_BY_ZERO & fpstatus) ? NPY_FPE_DIVIDEBYZERO : 0) | - ((FP_OVERFLOW & fpstatus) ? NPY_FPE_OVERFLOW : 0) | - ((FP_UNDERFLOW & fpstatus) ? NPY_FPE_UNDERFLOW : 0) | - ((FP_INVALID & fpstatus) ? NPY_FPE_INVALID : 0); -} - -int npy_clear_floatstatus_barrier(char * param) -{ - int fpstatus = npy_get_floatstatus_barrier(param); - fp_swap_flag(0); - - return fpstatus; -} - -void npy_set_floatstatus_divbyzero(void) -{ - fp_raise_xcp(FP_DIV_BY_ZERO); -} - -void npy_set_floatstatus_overflow(void) -{ - fp_raise_xcp(FP_OVERFLOW); -} - -void npy_set_floatstatus_underflow(void) -{ - fp_raise_xcp(FP_UNDERFLOW); -} - -void npy_set_floatstatus_invalid(void) -{ - fp_raise_xcp(FP_INVALID); -} - -#elif defined(_MSC_VER) || (defined(__osf__) && defined(__alpha)) || \ - defined (__UCLIBC__) || (defined(__arc__) && defined(__GLIBC__)) /* - * By using a volatile floating point value, - * the compiler is forced to actually do the requested - * operations because of potential concurrency. - * - * We shouldn't write multiple values to a single - * global here, because that would cause - * a race condition. + * General C99 code for floating point error handling. These functions mainly + * exists, because `fenv.h` was not standardized in C89 so they gave better + * portability. This should be unnecessary with C99/C++11 and further + * functionality can be used from `fenv.h` directly. */ -static volatile double _npy_floatstatus_x, - _npy_floatstatus_zero = 0.0, _npy_floatstatus_big = 1e300, - _npy_floatstatus_small = 1e-300, _npy_floatstatus_inf; - -void npy_set_floatstatus_divbyzero(void) -{ - _npy_floatstatus_x = 1.0 / _npy_floatstatus_zero; -} - -void npy_set_floatstatus_overflow(void) -{ - _npy_floatstatus_x = _npy_floatstatus_big * 1e300; -} - -void npy_set_floatstatus_underflow(void) -{ - _npy_floatstatus_x = _npy_floatstatus_small * 1e-300; -} - -void npy_set_floatstatus_invalid(void) -{ - _npy_floatstatus_inf = NPY_INFINITY; - _npy_floatstatus_x = _npy_floatstatus_inf - NPY_INFINITY; -} - -/* MS Windows -----------------------------------------------------*/ -#if defined(_MSC_VER) - -#include <float.h> - -int npy_get_floatstatus_barrier(char *param) -{ - /* - * By using a volatile, the compiler cannot reorder this call - */ -#if defined(_WIN64) - int fpstatus = _statusfp(); -#else - /* windows enables sse on 32 bit, so check both flags */ - int fpstatus, fpstatus2; - _statusfp2(&fpstatus, &fpstatus2); - fpstatus |= fpstatus2; -#endif - if (param != NULL) { - volatile char NPY_UNUSED(c) = *(char*)param; - } - return ((SW_ZERODIVIDE & fpstatus) ? NPY_FPE_DIVIDEBYZERO : 0) | - ((SW_OVERFLOW & fpstatus) ? NPY_FPE_OVERFLOW : 0) | - ((SW_UNDERFLOW & fpstatus) ? NPY_FPE_UNDERFLOW : 0) | - ((SW_INVALID & fpstatus) ? NPY_FPE_INVALID : 0); -} - -int npy_clear_floatstatus_barrier(char *param) -{ - int fpstatus = npy_get_floatstatus_barrier(param); - _clearfp(); - - return fpstatus; -} - -/* OSF/Alpha (Tru64) ---------------------------------------------*/ -#elif defined(__osf__) && defined(__alpha) - -#include <machine/fpu.h> - -int npy_get_floatstatus_barrier(char *param) -{ - unsigned long fpstatus = ieee_get_fp_control(); - /* - * By using a volatile, the compiler cannot reorder this call - */ - if (param != NULL) { - volatile char NPY_UNUSED(c) = *(char*)param; - } - return ((IEEE_STATUS_DZE & fpstatus) ? NPY_FPE_DIVIDEBYZERO : 0) | - ((IEEE_STATUS_OVF & fpstatus) ? NPY_FPE_OVERFLOW : 0) | - ((IEEE_STATUS_UNF & fpstatus) ? NPY_FPE_UNDERFLOW : 0) | - ((IEEE_STATUS_INV & fpstatus) ? NPY_FPE_INVALID : 0); -} - -int npy_clear_floatstatus_barrier(char *param) -{ - int fpstatus = npy_get_floatstatus_barrier(param); - /* clear status bits as well as disable exception mode if on */ - ieee_set_fp_control(0); - - return fpstatus; -} - -#endif -/* End of defined(_MSC_VER) || (defined(__osf__) && defined(__alpha)) */ - -#else -/* General GCC code, should work on most platforms */ # include <fenv.h> int npy_get_floatstatus_barrier(char* param) @@ -839,4 +625,3 @@ void npy_set_floatstatus_invalid(void) feraiseexcept(FE_INVALID); } -#endif |
