From e7104b7d50b24f6f0f2a9a02d355c53514b0c0b1 Mon Sep 17 00:00:00 2001 From: swayaminsync Date: Thu, 4 Sep 2025 19:53:05 +0530 Subject: [PATCH 1/4] precompile cache --- quaddtype/numpy_quaddtype/src/quaddtype_main.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/quaddtype/numpy_quaddtype/src/quaddtype_main.c b/quaddtype/numpy_quaddtype/src/quaddtype_main.c index e91016b0..6d68c5af 100644 --- a/quaddtype/numpy_quaddtype/src/quaddtype_main.c +++ b/quaddtype/numpy_quaddtype/src/quaddtype_main.c @@ -31,16 +31,25 @@ py_is_longdouble_128(PyObject *self, PyObject *args) } #ifdef SLEEF_QUAD_C -// Native __float128 support static const Sleef_quad SMALLEST_SUBNORMAL_VALUE = SLEEF_QUAD_DENORM_MIN; #else -// Use static union for thread-safe initialization +// Use the exact same struct layout as the original buggy code static const union { struct { +#if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) + uint64_t h, l; +#else uint64_t l, h; +#endif } parts; Sleef_quad value; -} smallest_subnormal_const = {.parts = {.l = 0x0000000000000001ULL, .h = 0x0000000000000000ULL}}; +} smallest_subnormal_const = {.parts = { +#if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) + .h = 0x0000000000000000ULL, .l = 0x0000000000000001ULL +#else + .l = 0x0000000000000001ULL, .h = 0x0000000000000000ULL +#endif + }}; #define SMALLEST_SUBNORMAL_VALUE (smallest_subnormal_const.value) #endif From ea212dde1724f6b0a6b7ded808b0480cf0c5daa8 Mon Sep 17 00:00:00 2001 From: swayaminsync Date: Thu, 4 Sep 2025 20:11:01 +0530 Subject: [PATCH 2/4] using pymutex on object creation --- quaddtype/numpy_quaddtype/src/scalar.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/quaddtype/numpy_quaddtype/src/scalar.c b/quaddtype/numpy_quaddtype/src/scalar.c index 6c2e4b51..6292423a 100644 --- a/quaddtype/numpy_quaddtype/src/scalar.c +++ b/quaddtype/numpy_quaddtype/src/scalar.c @@ -15,10 +15,22 @@ #include "scalar_ops.h" #include "dragon4.h" +#ifdef Py_GIL_DISABLED +static PyMutex quad_creation_mutex = {0}; +#endif + QuadPrecisionObject * QuadPrecision_raw_new(QuadBackendType backend) { - QuadPrecisionObject *new = PyObject_New(QuadPrecisionObject, &QuadPrecision_Type); + QuadPrecisionObject *new; +#ifdef Py_GIL_DISABLED + PyMutex_Lock(&quad_creation_mutex); +#endif + new = PyObject_New(QuadPrecisionObject, &QuadPrecision_Type); +#ifdef Py_GIL_DISABLED + PyMutex_Unlock(&quad_creation_mutex); +#endif + if (!new) return NULL; new->backend = backend; From 4b250290d494d5129f509880973cc5f62920ec4c Mon Sep 17 00:00:00 2001 From: swayaminsync Date: Thu, 4 Sep 2025 20:21:57 +0530 Subject: [PATCH 3/4] repr string building with mutex --- quaddtype/numpy_quaddtype/src/scalar.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/quaddtype/numpy_quaddtype/src/scalar.c b/quaddtype/numpy_quaddtype/src/scalar.c index 6292423a..79dbc1c6 100644 --- a/quaddtype/numpy_quaddtype/src/scalar.c +++ b/quaddtype/numpy_quaddtype/src/scalar.c @@ -16,7 +16,7 @@ #include "dragon4.h" #ifdef Py_GIL_DISABLED -static PyMutex quad_creation_mutex = {0}; +static PyMutex scalar_mutex = {0}; #endif QuadPrecisionObject * @@ -24,11 +24,11 @@ QuadPrecision_raw_new(QuadBackendType backend) { QuadPrecisionObject *new; #ifdef Py_GIL_DISABLED - PyMutex_Lock(&quad_creation_mutex); + PyMutex_Lock(&scalar_mutex); #endif new = PyObject_New(QuadPrecisionObject, &QuadPrecision_Type); #ifdef Py_GIL_DISABLED - PyMutex_Unlock(&quad_creation_mutex); + PyMutex_Unlock(&scalar_mutex); #endif if (!new) @@ -196,6 +196,9 @@ QuadPrecision_str(QuadPrecisionObject *self) static PyObject * QuadPrecision_repr(QuadPrecisionObject *self) { +#ifdef Py_GIL_DISABLED + PyMutex_Lock(&scalar_mutex); +#endif PyObject *str = QuadPrecision_str(self); if (str == NULL) { return NULL; @@ -203,6 +206,9 @@ QuadPrecision_repr(QuadPrecisionObject *self) const char *backend_str = (self->backend == BACKEND_SLEEF) ? "sleef" : "longdouble"; PyObject *res = PyUnicode_FromFormat("QuadPrecision('%S', backend='%s')", str, backend_str); Py_DECREF(str); +#ifdef Py_GIL_DISABLED + PyMutex_Unlock(&scalar_mutex); +#endif return res; } From 378e86a245624bffa4d3eb0ecf1aefd2b5e6b047 Mon Sep 17 00:00:00 2001 From: swayaminsync Date: Thu, 4 Sep 2025 20:36:55 +0530 Subject: [PATCH 4/4] repr string building with mutex --- quaddtype/numpy_quaddtype/src/scalar.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/quaddtype/numpy_quaddtype/src/scalar.c b/quaddtype/numpy_quaddtype/src/scalar.c index 79dbc1c6..07b18bf0 100644 --- a/quaddtype/numpy_quaddtype/src/scalar.c +++ b/quaddtype/numpy_quaddtype/src/scalar.c @@ -215,6 +215,9 @@ QuadPrecision_repr(QuadPrecisionObject *self) static PyObject * QuadPrecision_repr_dragon4(QuadPrecisionObject *self) { +#ifdef Py_GIL_DISABLED + PyMutex_Lock(&scalar_mutex); +#endif Dragon4_Options opt = {.scientific = 1, .digit_mode = DigitMode_Unique, .cutoff_mode = CutoffMode_TotalLength, @@ -244,6 +247,9 @@ QuadPrecision_repr_dragon4(QuadPrecisionObject *self) const char *backend_str = (self->backend == BACKEND_SLEEF) ? "sleef" : "longdouble"; PyObject *res = PyUnicode_FromFormat("QuadPrecision('%S', backend='%s')", str, backend_str); Py_DECREF(str); +#ifdef Py_GIL_DISABLED + PyMutex_Unlock(&scalar_mutex); +#endif return res; }