Skip to content

Commit 012e90f

Browse files
committed
Merge branch 'dragon4' into constants
2 parents 082b64b + bbc99a6 commit 012e90f

File tree

7 files changed

+109
-32
lines changed

7 files changed

+109
-32
lines changed

quaddtype/numpy_quaddtype/__init__.py

+11-12
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,27 @@
11
from ._quaddtype_main import (
22
QuadPrecision,
33
QuadPrecDType,
4-
is_longdouble_128
4+
is_longdouble_128,
5+
pi, e, log2e, log10e, ln2, ln10,
6+
sqrt2, sqrt3, egamma, phi, quad_max, quad_min, quad_epsilon, quad_denorm_min
57
)
68

7-
__all__ = ['QuadPrecision', 'QuadPrecDType', 'SleefQuadPrecision', 'LongDoubleQuadPrecision',
8-
'SleefQuadPrecDType', 'LongDoubleQuadPrecDType', 'is_longdouble_128', 'pi', 'e']
9-
10-
11-
pi = QuadPrecision.pi
12-
e = QuadPrecision.e
13-
9+
__all__ = [
10+
'QuadPrecision', 'QuadPrecDType', 'SleefQuadPrecision', 'LongDoubleQuadPrecision',
11+
'SleefQuadPrecDType', 'LongDoubleQuadPrecDType', 'is_longdouble_128',
12+
'pi', 'e', 'log2e', 'log10e', 'ln2', 'ln10',
13+
'sqrt2', 'sqrt3', 'egamma', 'phi',
14+
'quad_max', 'quad_min', 'quad_epsilon', 'quad_denorm_min'
15+
]
1416

1517
def SleefQuadPrecision(value):
1618
return QuadPrecision(value, backend='sleef')
1719

18-
1920
def LongDoubleQuadPrecision(value):
2021
return QuadPrecision(value, backend='longdouble')
2122

22-
2323
def SleefQuadPrecDType():
2424
return QuadPrecDType(backend='sleef')
2525

26-
2726
def LongDoubleQuadPrecDType():
28-
return QuadPrecDType(backend='longdouble')
27+
return QuadPrecDType(backend='longdouble')

quaddtype/numpy_quaddtype/src/dragon4.c

+5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
/*
2+
This code was extracted from NumPy and the original author was Allan Haldane(@ahaldane)
3+
Modifications are specific to support the SLEEF_QUAD
4+
*/
5+
16
#include <numpy/npy_common.h>
27
#include <math.h>
38
#include <stdio.h>

quaddtype/numpy_quaddtype/src/dtype.c

+8-3
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,15 @@ ensure_canonical(QuadPrecDTypeObject *self)
7979
static QuadPrecDTypeObject *
8080
common_instance(QuadPrecDTypeObject *dtype1, QuadPrecDTypeObject *dtype2)
8181
{
82+
// if backend mismatch then return SLEEF one (safe to cast ld to quad)
8283
if (dtype1->backend != dtype2->backend) {
83-
PyErr_SetString(PyExc_TypeError,
84-
"Cannot find common instance for QuadPrecDTypes with different backends");
85-
return NULL;
84+
if (dtype1->backend == BACKEND_SLEEF) {
85+
Py_INCREF(dtype1);
86+
return dtype1;
87+
}
88+
89+
Py_INCREF(dtype2);
90+
return dtype2;
8691
}
8792
Py_INCREF(dtype1);
8893
return dtype1;

quaddtype/numpy_quaddtype/src/quaddtype_main.c

+15
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,21 @@ PyInit__quaddtype_main(void)
6565
goto error;
6666
}
6767

68+
if (PyModule_AddObject(m, "pi", (PyObject *)QuadPrecision_pi) < 0) goto error;
69+
if (PyModule_AddObject(m, "e", (PyObject *)QuadPrecision_e) < 0) goto error;
70+
if (PyModule_AddObject(m, "log2e", (PyObject *)QuadPrecision_log2e) < 0) goto error;
71+
if (PyModule_AddObject(m, "log10e", (PyObject *)QuadPrecision_log10e) < 0) goto error;
72+
if (PyModule_AddObject(m, "ln2", (PyObject *)QuadPrecision_ln2) < 0) goto error;
73+
if (PyModule_AddObject(m, "ln10", (PyObject *)QuadPrecision_ln10) < 0) goto error;
74+
if (PyModule_AddObject(m, "sqrt2", (PyObject *)QuadPrecision_sqrt2) < 0) goto error;
75+
if (PyModule_AddObject(m, "sqrt3", (PyObject *)QuadPrecision_sqrt3) < 0) goto error;
76+
if (PyModule_AddObject(m, "egamma", (PyObject *)QuadPrecision_egamma) < 0) goto error;
77+
if (PyModule_AddObject(m, "phi", (PyObject *)QuadPrecision_phi) < 0) goto error;
78+
if (PyModule_AddObject(m, "quad_max", (PyObject *)QuadPrecision_quad_max) < 0) goto error;
79+
if (PyModule_AddObject(m, "quad_min", (PyObject *)QuadPrecision_quad_min) < 0) goto error;
80+
if (PyModule_AddObject(m, "quad_epsilon", (PyObject *)QuadPrecision_quad_epsilon) < 0) goto error;
81+
if (PyModule_AddObject(m, "quad_denorm_min", (PyObject *)QuadPrecision_quad_denorm_min) < 0) goto error;
82+
6883
return m;
6984

7085
error:

quaddtype/numpy_quaddtype/src/scalar.c

+52-14
Original file line numberDiff line numberDiff line change
@@ -76,39 +76,42 @@ QuadPrecision_from_object(PyObject *value, QuadBackendType backend)
7676
self->value.longdouble_value = (long double)val;
7777
}
7878
}
79-
else if (Py_TYPE(value) == &QuadPrecision_Type)
80-
{
81-
// todo: not working for ld backend, getting garbage value not sure why?
79+
else if (Py_TYPE(value) == &QuadPrecision_Type) {
80+
Py_DECREF(self); // discard the default one
8281
QuadPrecisionObject *quad_obj = (QuadPrecisionObject *)value;
83-
// printf("%d %d\n", quad_obj->backend, backend);
84-
// printf("%Lf\n", quad_obj->value.longdouble_value);
82+
83+
// create a new one with the same backend
84+
QuadPrecisionObject *self = QuadPrecision_raw_new(quad_obj->backend);
8585
if (quad_obj->backend == BACKEND_SLEEF) {
8686
self->value.sleef_value = quad_obj->value.sleef_value;
8787
}
8888
else {
8989
self->value.longdouble_value = quad_obj->value.longdouble_value;
9090
}
91+
92+
return self;
9193
}
9294
else {
9395
PyObject *type_str = PyObject_Str((PyObject *)Py_TYPE(value));
9496
if (type_str != NULL) {
9597
const char *type_cstr = PyUnicode_AsUTF8(type_str);
9698
if (type_cstr != NULL) {
97-
PyErr_Format(
98-
PyExc_TypeError,
99-
"QuadPrecision value must be a float, int or string, but got %s instead",
100-
type_cstr);
99+
PyErr_Format(PyExc_TypeError,
100+
"QuadPrecision value must be a quad, float, int or string, but got %s "
101+
"instead",
102+
type_cstr);
101103
}
102104
else {
103-
PyErr_SetString(PyExc_TypeError,
104-
"QuadPrecision value must be a float, int or string, but got an "
105-
"unknown type instead");
105+
PyErr_SetString(
106+
PyExc_TypeError,
107+
"QuadPrecision value must be a quad, float, int or string, but got an "
108+
"unknown type instead");
106109
}
107110
Py_DECREF(type_str);
108111
}
109112
else {
110113
PyErr_SetString(PyExc_TypeError,
111-
"QuadPrecision value must be a float, int or string, but got an "
114+
"QuadPrecision value must be a quad, float, int or string, but got an "
112115
"unknown type instead");
113116
}
114117
Py_DECREF(self);
@@ -267,9 +270,44 @@ PyTypeObject QuadPrecision_Type = {
267270
.tp_getset = QuadPrecision_getset,
268271
};
269272

273+
QuadPrecisionObject* initialize_constants(const Sleef_quad value, QuadBackendType backend)
274+
{
275+
QuadPrecisionObject * obj = QuadPrecision_raw_new(backend);
276+
if (backend == BACKEND_SLEEF) {
277+
obj->value.sleef_value = value;
278+
}
279+
else {
280+
obj->value.longdouble_value = Sleef_cast_to_doubleq1(value);
281+
}
282+
283+
return obj;
284+
}
285+
270286
int
271287
init_quadprecision_scalar(void)
272288
{
273-
// QuadPrecision_Type.tp_base = &PyFloatingArrType_Type;
289+
QuadPrecisionObject* QuadPrecision_pi = initialize_constants(SLEEF_M_PIq, BACKEND_SLEEF);
290+
QuadPrecisionObject* QuadPrecision_e = initialize_constants(SLEEF_M_Eq, BACKEND_SLEEF);
291+
QuadPrecisionObject* QuadPrecision_log2e = initialize_constants(SLEEF_M_LOG2Eq, BACKEND_SLEEF);
292+
QuadPrecisionObject* QuadPrecision_log10e = initialize_constants(SLEEF_M_LOG10Eq, BACKEND_SLEEF);
293+
QuadPrecisionObject* QuadPrecision_ln2 = initialize_constants(SLEEF_M_LN2q, BACKEND_SLEEF);
294+
QuadPrecisionObject* QuadPrecision_ln10 = initialize_constants(SLEEF_M_LN10q, BACKEND_SLEEF);
295+
QuadPrecisionObject* QuadPrecision_sqrt2 = initialize_constants(SLEEF_M_SQRT2q, BACKEND_SLEEF);
296+
QuadPrecisionObject* QuadPrecision_sqrt3 = initialize_constants(SLEEF_M_SQRT3q, BACKEND_SLEEF);
297+
QuadPrecisionObject* QuadPrecision_egamma = initialize_constants(SLEEF_M_EGAMMAq, BACKEND_SLEEF);
298+
QuadPrecisionObject* QuadPrecision_phi = initialize_constants(SLEEF_M_PHIq, BACKEND_SLEEF);
299+
QuadPrecisionObject* QuadPrecision_quad_max = initialize_constants(SLEEF_QUAD_MAX, BACKEND_SLEEF);
300+
QuadPrecisionObject* QuadPrecision_quad_min = initialize_constants(SLEEF_QUAD_MIN, BACKEND_SLEEF);
301+
QuadPrecisionObject* QuadPrecision_quad_epsilon = initialize_constants(SLEEF_QUAD_EPSILON, BACKEND_SLEEF);
302+
QuadPrecisionObject* QuadPrecision_quad_denorm_min = initialize_constants(SLEEF_QUAD_DENORM_MIN, BACKEND_SLEEF);
303+
304+
if (!QuadPrecision_pi || !QuadPrecision_e || !QuadPrecision_log2e || !QuadPrecision_log10e ||
305+
!QuadPrecision_ln2 || !QuadPrecision_ln10|| !QuadPrecision_sqrt2 || !QuadPrecision_sqrt3 ||
306+
!QuadPrecision_egamma || !QuadPrecision_phi || !QuadPrecision_quad_max || !QuadPrecision_quad_min ||
307+
!QuadPrecision_quad_epsilon || !QuadPrecision_quad_denorm_min) {
308+
PyErr_SetString(PyExc_RuntimeError, "Failed to initialize QuadPrecision constants");
309+
return -1;
310+
}
311+
274312
return PyType_Ready(&QuadPrecision_Type);
275313
}

quaddtype/numpy_quaddtype/src/scalar.h

+18
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,24 @@ PyObject* QuadPrecision_get_e(PyObject* self, void* closure);
3737
#define PyArray_IsScalar(obj, QuadPrecDType) PyObject_TypeCheck(obj, &QuadPrecision_Type)
3838
#define PyArrayScalar_VAL(obj, QuadPrecDType) (((QuadPrecisionObject *)obj)->value)
3939

40+
QuadPrecisionObject* initialize_constants(const Sleef_quad value, QuadBackendType backend);
41+
42+
// constant objects
43+
extern QuadPrecisionObject *QuadPrecision_pi;
44+
extern QuadPrecisionObject *QuadPrecision_e;
45+
extern QuadPrecisionObject *QuadPrecision_log2e;
46+
extern QuadPrecisionObject *QuadPrecision_log10e;
47+
extern QuadPrecisionObject *QuadPrecision_ln2;
48+
extern QuadPrecisionObject *QuadPrecision_ln10;
49+
extern QuadPrecisionObject *QuadPrecision_sqrt2;
50+
extern QuadPrecisionObject *QuadPrecision_sqrt3;
51+
extern QuadPrecisionObject *QuadPrecision_egamma;
52+
extern QuadPrecisionObject *QuadPrecision_phi;
53+
extern QuadPrecisionObject *QuadPrecision_quad_max;
54+
extern QuadPrecisionObject *QuadPrecision_quad_min;
55+
extern QuadPrecisionObject *QuadPrecision_quad_epsilon;
56+
extern QuadPrecisionObject *QuadPrecision_quad_denorm_min;
57+
4058
#ifdef __cplusplus
4159
}
4260
#endif

quaddtype/numpy_quaddtype/src/umath.cpp

-3
Original file line numberDiff line numberDiff line change
@@ -658,9 +658,6 @@ quad_generic_comp_strided_loop_aligned(PyArrayMethod_Context *context, char *con
658658

659659
QuadPrecDTypeObject *descr = (QuadPrecDTypeObject *)context->descriptors[0];
660660
QuadBackendType backend = descr->backend;
661-
size_t elem_size = (backend == BACKEND_SLEEF) ? sizeof(Sleef_quad) : sizeof(long double);
662-
663-
quad_value in1, in2;
664661
while (N--)
665662
{
666663
quad_value in1 = *(quad_value *)in1_ptr;

0 commit comments

Comments
 (0)