Skip to content

Commit 6ed27b9

Browse files
committed
refactoring finfo support
1 parent 90e77de commit 6ed27b9

File tree

2 files changed

+70
-34
lines changed

2 files changed

+70
-34
lines changed

quaddtype/numpy_quaddtype/__init__.py

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,18 @@
88
get_quadblas_version
99
)
1010

11+
from dataclasses import dataclass
12+
1113
__all__ = [
1214
'QuadPrecision', 'QuadPrecDType', 'SleefQuadPrecision', 'LongDoubleQuadPrecision',
1315
'SleefQuadPrecDType', 'LongDoubleQuadPrecDType', 'is_longdouble_128',
1416
# Constants
1517
'pi', 'e', 'log2e', 'log10e', 'ln2', 'ln10', 'max_value', 'epsilon',
1618
'smallest_normal', 'smallest_subnormal', 'bits', 'precision', 'resolution',
1719
# QuadBLAS related functions
18-
'set_num_threads', 'get_num_threads', 'get_quadblas_version'
20+
'set_num_threads', 'get_num_threads', 'get_quadblas_version',
21+
# finfo class
22+
'QuadPrecFinfo'
1923
]
2024

2125
def SleefQuadPrecision(value):
@@ -43,3 +47,39 @@ def LongDoubleQuadPrecDType():
4347
bits = get_sleef_constant("bits")
4448
precision = get_sleef_constant("precision")
4549
resolution = get_sleef_constant("resolution")
50+
51+
@dataclass
52+
class QuadPrecFinfo:
53+
"""Floating-point information for quadruple precision dtype.
54+
55+
This class provides information about the floating-point representation
56+
used by the QuadPrecDType, similar to numpy.finfo but customized for
57+
quad precision arithmetic.
58+
"""
59+
bits: int = int(bits)
60+
eps: float = float(epsilon)
61+
epsneg: float = float(epsilon)
62+
iexp: int = int(precision)
63+
machar: object = None
64+
machep: float = float(epsilon)
65+
max: float = float(max_value)
66+
maxexp: float = float(max_value)
67+
min: float = float(smallest_normal)
68+
minexp: float = float(smallest_normal)
69+
negep: float = float(epsilon)
70+
nexp: int = int(bits) - int(precision) - 1
71+
nmant: int = int(precision)
72+
precision: int = int(precision)
73+
resolution: float = float(resolution)
74+
tiny: float = float(smallest_normal)
75+
smallest_normal: float = float(smallest_normal)
76+
smallest_subnormal: float = float(smallest_subnormal)
77+
78+
def get(self, attr):
79+
return getattr(self, attr, None)
80+
81+
def __str__(self):
82+
return f"QuadPrecFinfo(precision={self.precision}, resolution={self.resolution})"
83+
84+
def __repr__(self):
85+
return f"QuadPrecFinfo(max={self.max}, min={self.min}, eps={self.eps}, bits={self.bits})"

quaddtype/numpy_quaddtype/src/dtype.c

Lines changed: 29 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -176,38 +176,6 @@ quadprec_default_descr(PyArray_DTypeMeta *cls)
176176
return (PyArray_Descr *)temp;
177177
}
178178

179-
static PyObject *
180-
quad_finfo(PyArray_Descr *descr, NPY_DTYPE_INFO_TYPE info_type)
181-
{
182-
183-
// Handle the different info types
184-
switch (info_type) {
185-
case NPY_DTYPE_INFO_FLOAT:
186-
{
187-
PyObject *finfo_dict = PyDict_New();
188-
if (!finfo_dict) return NULL;
189-
190-
PyDict_SetItemString(finfo_dict, "precision", PyLong_FromLong(34));
191-
PyDict_SetItemString(finfo_dict, "bits", PyLong_FromLong(128));
192-
// more fields
193-
return finfo_dict;
194-
}
195-
case NPY_DTYPE_INFO_INTEGER:
196-
// Not implemented yet, could add iinfo support later
197-
PyErr_SetString(PyExc_NotImplementedError,
198-
"Integer info not implemented for this dtype");
199-
return NULL;
200-
case NPY_DTYPE_INFO_GENERIC:
201-
// Not implemented yet, could add generic info later
202-
PyErr_SetString(PyExc_NotImplementedError,
203-
"Generic info not implemented for this dtype");
204-
return NULL;
205-
default:
206-
PyErr_SetString(PyExc_ValueError, "Unknown dtype info type");
207-
return NULL;
208-
}
209-
}
210-
211179
static PyType_Slot QuadPrecDType_Slots[] = {
212180
{NPY_DT_ensure_canonical, &ensure_canonical},
213181
{NPY_DT_common_instance, &common_instance},
@@ -217,7 +185,6 @@ static PyType_Slot QuadPrecDType_Slots[] = {
217185
{NPY_DT_getitem, &quadprec_getitem},
218186
{NPY_DT_default_descr, &quadprec_default_descr},
219187
{NPY_DT_PyArray_ArrFuncs_dotfunc, NULL},
220-
{NPY_DT_get_dtype_info, &quad_finfo},
221188
{0, NULL}};
222189

223190
static PyObject *
@@ -257,13 +224,42 @@ QuadPrecDType_str(QuadPrecDTypeObject *self)
257224
return PyUnicode_FromFormat("QuadPrecDType(backend='%s')", backend_str);
258225
}
259226

227+
static PyObject *
228+
QuadPrecDType_finfo(QuadPrecDTypeObject *self, PyObject *args)
229+
{
230+
PyObject *numpy_quaddtype_module = PyImport_ImportModule("numpy_quaddtype");
231+
if (numpy_quaddtype_module == NULL) {
232+
return NULL;
233+
}
234+
235+
PyObject *finfo_class = PyObject_GetAttrString(numpy_quaddtype_module, "QuadPrecFinfo");
236+
Py_DECREF(numpy_quaddtype_module);
237+
238+
if (finfo_class == NULL) {
239+
PyErr_SetString(PyExc_AttributeError, "Could not find QuadPrecFinfo class in numpy_quaddtype module.");
240+
return NULL;
241+
}
242+
243+
PyObject *finfo_instance = PyObject_CallNoArgs(finfo_class);
244+
Py_DECREF(finfo_class);
245+
246+
return finfo_instance;
247+
}
248+
249+
static PyMethodDef QuadPrecDType_methods[] = {
250+
{"finfo", (PyCFunction)QuadPrecDType_finfo, METH_NOARGS,
251+
"Return floating-point information for this QuadPrecDType"},
252+
{NULL, NULL, 0, NULL}
253+
};
254+
260255
PyArray_DTypeMeta QuadPrecDType = {
261256
{{
262257
PyVarObject_HEAD_INIT(NULL, 0).tp_name = "numpy_quaddtype.QuadPrecDType",
263258
.tp_basicsize = sizeof(QuadPrecDTypeObject),
264259
.tp_new = QuadPrecDType_new,
265260
.tp_repr = (reprfunc)QuadPrecDType_repr,
266261
.tp_str = (reprfunc)QuadPrecDType_str,
262+
.tp_methods = QuadPrecDType_methods,
267263
}},
268264
};
269265

0 commit comments

Comments
 (0)