Path: blob/main/python/py-numpy/src/patches/01-ENH-Add-support-for-platforms-with-missing-fenv-flag.patch
1393 views
This is from pyodide.12From 96e53641b0dd61ea9ce1749392c184d875c19359 Mon Sep 17 00:00:00 20013From: Hood Chatham <[email protected]>4Date: Sat, 11 Jun 2022 11:19:42 -07005Subject: [PATCH 1/3] ENH: Add support for platforms with missing fenv flags67For instance wasm has no fenv support. musl-libc defines all the8fenv functions unconditionally (fesetexcept, feclearexcept, etc)9but on unsupported platforms they are no-ops:10https://git.musl-libc.org/cgit/musl/tree/src/fenv/fenv.c1112However, the platform is expected to only define flags like13FE_OVERFLOW if they are supported. I haven't found an explanation14of the design decision, but it seems to be aimed at fine-grained15feature detection. musl-libc-test has code that uses fenv and wants16it to silently decay to a no-op on platforms missing support. I17copied their implementation of this behavior:18http://nsz.repo.hu/git/?p=libc-test;a=blob;f=src/common/mtest.h;h=706c1ba23ea8989b17a2f72ed1a919e187c06b6a;hb=HEAD#l30192021--- native/numpy/core/src/npymath/ieee754.c.src 2022-12-25 19:52:5222+++ wasm/numpy/core/src/npymath/ieee754.c.src 2023-02-03 08:15:2023@@ -387,10 +387,52 @@24#endif252627+// musl-libc defines all the fenv functions unconditionally (fesetexcept,28+// feclearexcept, etc) but on unsupported platforms they are no-ops:29+// https://git.musl-libc.org/cgit/musl/tree/src/fenv/fenv.c30+// However, the platform is expected to only define flags like31+// FE_OVERFLOW if they are supported. I haven't found an explanation32+// of the design decision, but it seems to be aimed at fine-grained33+// feature detection. musl-libc-test has code that uses fenv and wants34+// it to silently decay to a no-op on platforms missing support. I35+// copied their implementation of this behavior:36+// http://nsz.repo.hu/git/?p=libc-test;a=blob;f=src/common/mtest.h;h=706c1ba23ea8989b17a2f72ed1a919e187c06b6a;hb=HEAD#l3037+#undef INEXACT38+#undef INVALID39+#undef DIVBYZERO40+#undef UNDERFLOW41+#undef OVERFLOW42+#ifdef FE_INEXACT43+#define INEXACT FE_INEXACT44+#else45+#define INEXACT 046+#endif47+#ifdef FE_INVALID48+#define INVALID FE_INVALID49+#else50+#define INVALID 051+#endif52+#ifdef FE_DIVBYZERO53+#define DIVBYZERO FE_DIVBYZERO54+#else55+#define DIVBYZERO 056+#endif57+#ifdef FE_UNDERFLOW58+#define UNDERFLOW FE_UNDERFLOW59+#else60+#define UNDERFLOW 061+#endif62+#ifdef FE_OVERFLOW63+#define OVERFLOW FE_OVERFLOW64+#else65+#define OVERFLOW 066+#endif67+68+69int npy_get_floatstatus_barrier(char* param)70{71- int fpstatus = fetestexcept(FE_DIVBYZERO | FE_OVERFLOW |72- FE_UNDERFLOW | FE_INVALID);73+ int fpstatus = fetestexcept(DIVBYZERO | OVERFLOW |74+ UNDERFLOW | INVALID);75/*76* By using a volatile, the compiler cannot reorder this call77*/78@@ -398,10 +440,10 @@79volatile char NPY_UNUSED(c) = *(char*)param;80}8182- return ((FE_DIVBYZERO & fpstatus) ? NPY_FPE_DIVIDEBYZERO : 0) |83- ((FE_OVERFLOW & fpstatus) ? NPY_FPE_OVERFLOW : 0) |84- ((FE_UNDERFLOW & fpstatus) ? NPY_FPE_UNDERFLOW : 0) |85- ((FE_INVALID & fpstatus) ? NPY_FPE_INVALID : 0);86+ return ((DIVBYZERO & fpstatus) ? NPY_FPE_DIVIDEBYZERO : 0) |87+ ((OVERFLOW & fpstatus) ? NPY_FPE_OVERFLOW : 0) |88+ ((UNDERFLOW & fpstatus) ? NPY_FPE_UNDERFLOW : 0) |89+ ((INVALID & fpstatus) ? NPY_FPE_INVALID : 0);90}9192int npy_clear_floatstatus_barrier(char * param)93@@ -409,8 +451,8 @@94/* testing float status is 50-100 times faster than clearing on x86 */95int fpstatus = npy_get_floatstatus_barrier(param);96if (fpstatus != 0) {97- feclearexcept(FE_DIVBYZERO | FE_OVERFLOW |98- FE_UNDERFLOW | FE_INVALID);99+ feclearexcept(DIVBYZERO | OVERFLOW |100+ UNDERFLOW | INVALID);101}102103return fpstatus;104@@ -419,21 +461,21 @@105106void npy_set_floatstatus_divbyzero(void)107{108- feraiseexcept(FE_DIVBYZERO);109+ feraiseexcept(DIVBYZERO);110}111112void npy_set_floatstatus_overflow(void)113{114- feraiseexcept(FE_OVERFLOW);115+ feraiseexcept(OVERFLOW);116}117118void npy_set_floatstatus_underflow(void)119{120- feraiseexcept(FE_UNDERFLOW);121+ feraiseexcept(UNDERFLOW);122}123124void npy_set_floatstatus_invalid(void)125{126- feraiseexcept(FE_INVALID);127+ feraiseexcept(INVALID);128}129130131132