Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemathinc
GitHub Repository: sagemathinc/wapython
Path: blob/main/python/py-numpy/src/patches/01-ENH-Add-support-for-platforms-with-missing-fenv-flag.patch
1067 views
1
This is from pyodide.
2
3
From 96e53641b0dd61ea9ce1749392c184d875c19359 Mon Sep 17 00:00:00 2001
4
From: Hood Chatham <[email protected]>
5
Date: Sat, 11 Jun 2022 11:19:42 -0700
6
Subject: [PATCH 1/3] ENH: Add support for platforms with missing fenv flags
7
8
For instance wasm has no fenv support. musl-libc defines all the
9
fenv functions unconditionally (fesetexcept, feclearexcept, etc)
10
but on unsupported platforms they are no-ops:
11
https://git.musl-libc.org/cgit/musl/tree/src/fenv/fenv.c
12
13
However, the platform is expected to only define flags like
14
FE_OVERFLOW if they are supported. I haven't found an explanation
15
of the design decision, but it seems to be aimed at fine-grained
16
feature detection. musl-libc-test has code that uses fenv and wants
17
it to silently decay to a no-op on platforms missing support. I
18
copied their implementation of this behavior:
19
http://nsz.repo.hu/git/?p=libc-test;a=blob;f=src/common/mtest.h;h=706c1ba23ea8989b17a2f72ed1a919e187c06b6a;hb=HEAD#l30
20
21
22
--- native/numpy/core/src/npymath/ieee754.c.src 2022-12-25 19:52:52
23
+++ wasm/numpy/core/src/npymath/ieee754.c.src 2023-02-03 08:15:20
24
@@ -387,10 +387,52 @@
25
#endif
26
27
28
+// musl-libc defines all the fenv functions unconditionally (fesetexcept,
29
+// feclearexcept, etc) but on unsupported platforms they are no-ops:
30
+// https://git.musl-libc.org/cgit/musl/tree/src/fenv/fenv.c
31
+// However, the platform is expected to only define flags like
32
+// FE_OVERFLOW if they are supported. I haven't found an explanation
33
+// of the design decision, but it seems to be aimed at fine-grained
34
+// feature detection. musl-libc-test has code that uses fenv and wants
35
+// it to silently decay to a no-op on platforms missing support. I
36
+// copied their implementation of this behavior:
37
+// http://nsz.repo.hu/git/?p=libc-test;a=blob;f=src/common/mtest.h;h=706c1ba23ea8989b17a2f72ed1a919e187c06b6a;hb=HEAD#l30
38
+#undef INEXACT
39
+#undef INVALID
40
+#undef DIVBYZERO
41
+#undef UNDERFLOW
42
+#undef OVERFLOW
43
+#ifdef FE_INEXACT
44
+#define INEXACT FE_INEXACT
45
+#else
46
+#define INEXACT 0
47
+#endif
48
+#ifdef FE_INVALID
49
+#define INVALID FE_INVALID
50
+#else
51
+#define INVALID 0
52
+#endif
53
+#ifdef FE_DIVBYZERO
54
+#define DIVBYZERO FE_DIVBYZERO
55
+#else
56
+#define DIVBYZERO 0
57
+#endif
58
+#ifdef FE_UNDERFLOW
59
+#define UNDERFLOW FE_UNDERFLOW
60
+#else
61
+#define UNDERFLOW 0
62
+#endif
63
+#ifdef FE_OVERFLOW
64
+#define OVERFLOW FE_OVERFLOW
65
+#else
66
+#define OVERFLOW 0
67
+#endif
68
+
69
+
70
int npy_get_floatstatus_barrier(char* param)
71
{
72
- int fpstatus = fetestexcept(FE_DIVBYZERO | FE_OVERFLOW |
73
- FE_UNDERFLOW | FE_INVALID);
74
+ int fpstatus = fetestexcept(DIVBYZERO | OVERFLOW |
75
+ UNDERFLOW | INVALID);
76
/*
77
* By using a volatile, the compiler cannot reorder this call
78
*/
79
@@ -398,10 +440,10 @@
80
volatile char NPY_UNUSED(c) = *(char*)param;
81
}
82
83
- return ((FE_DIVBYZERO & fpstatus) ? NPY_FPE_DIVIDEBYZERO : 0) |
84
- ((FE_OVERFLOW & fpstatus) ? NPY_FPE_OVERFLOW : 0) |
85
- ((FE_UNDERFLOW & fpstatus) ? NPY_FPE_UNDERFLOW : 0) |
86
- ((FE_INVALID & fpstatus) ? NPY_FPE_INVALID : 0);
87
+ return ((DIVBYZERO & fpstatus) ? NPY_FPE_DIVIDEBYZERO : 0) |
88
+ ((OVERFLOW & fpstatus) ? NPY_FPE_OVERFLOW : 0) |
89
+ ((UNDERFLOW & fpstatus) ? NPY_FPE_UNDERFLOW : 0) |
90
+ ((INVALID & fpstatus) ? NPY_FPE_INVALID : 0);
91
}
92
93
int npy_clear_floatstatus_barrier(char * param)
94
@@ -409,8 +451,8 @@
95
/* testing float status is 50-100 times faster than clearing on x86 */
96
int fpstatus = npy_get_floatstatus_barrier(param);
97
if (fpstatus != 0) {
98
- feclearexcept(FE_DIVBYZERO | FE_OVERFLOW |
99
- FE_UNDERFLOW | FE_INVALID);
100
+ feclearexcept(DIVBYZERO | OVERFLOW |
101
+ UNDERFLOW | INVALID);
102
}
103
104
return fpstatus;
105
@@ -419,21 +461,21 @@
106
107
void npy_set_floatstatus_divbyzero(void)
108
{
109
- feraiseexcept(FE_DIVBYZERO);
110
+ feraiseexcept(DIVBYZERO);
111
}
112
113
void npy_set_floatstatus_overflow(void)
114
{
115
- feraiseexcept(FE_OVERFLOW);
116
+ feraiseexcept(OVERFLOW);
117
}
118
119
void npy_set_floatstatus_underflow(void)
120
{
121
- feraiseexcept(FE_UNDERFLOW);
122
+ feraiseexcept(UNDERFLOW);
123
}
124
125
void npy_set_floatstatus_invalid(void)
126
{
127
- feraiseexcept(FE_INVALID);
128
+ feraiseexcept(INVALID);
129
}
130
131
132