diff --git a/quaddtype/numpy_quaddtype/__init__.py b/quaddtype/numpy_quaddtype/__init__.py index abdc20e..8cbd24a 100644 --- a/quaddtype/numpy_quaddtype/__init__.py +++ b/quaddtype/numpy_quaddtype/__init__.py @@ -8,6 +8,8 @@ get_quadblas_version ) +from dataclasses import dataclass, field + __all__ = [ 'QuadPrecision', 'QuadPrecDType', 'SleefQuadPrecision', 'LongDoubleQuadPrecision', 'SleefQuadPrecDType', 'LongDoubleQuadPrecDType', 'is_longdouble_128', @@ -15,7 +17,9 @@ 'pi', 'e', 'log2e', 'log10e', 'ln2', 'ln10', 'max_value', 'epsilon', 'smallest_normal', 'smallest_subnormal', 'bits', 'precision', 'resolution', # QuadBLAS related functions - 'set_num_threads', 'get_num_threads', 'get_quadblas_version' + 'set_num_threads', 'get_num_threads', 'get_quadblas_version', + # finfo class + 'QuadPrecFinfo' ] def SleefQuadPrecision(value): @@ -43,3 +47,39 @@ def LongDoubleQuadPrecDType(): bits = get_sleef_constant("bits") precision = get_sleef_constant("precision") resolution = get_sleef_constant("resolution") + +@dataclass +class QuadPrecFinfo: + """Floating-point information for quadruple precision dtype. + + This class provides information about the floating-point representation + used by the QuadPrecDType, similar to numpy.finfo but customized for + quad precision arithmetic. + """ + bits: int = field(default_factory=lambda: bits) + eps: float = field(default_factory=lambda: epsilon) + epsneg: float = field(default_factory=lambda: epsilon) + iexp: int = field(default_factory=lambda: precision) + machar: object = None + machep: float = field(default_factory=lambda: epsilon) + max: float = field(default_factory=lambda: max_value) + maxexp: float = field(default_factory=lambda: max_value) + min: float = field(default_factory=lambda: smallest_normal) + minexp: float = field(default_factory=lambda: smallest_normal) + negep: float = field(default_factory=lambda: epsilon) + nexp: int = field(default_factory=lambda: bits - precision - 1) + nmant: int = field(default_factory=lambda: precision) + precision: int = field(default_factory=lambda: precision) + resolution: float = field(default_factory=lambda: resolution) + tiny: float = field(default_factory=lambda: smallest_normal) + smallest_normal: float = field(default_factory=lambda: smallest_normal) + smallest_subnormal: float = field(default_factory=lambda: smallest_subnormal) + + def get(self, attr): + return getattr(self, attr, None) + + def __str__(self): + return f"QuadPrecFinfo(precision={self.precision}, resolution={self.resolution})" + + def __repr__(self): + return f"QuadPrecFinfo(max={self.max}, min={self.min}, eps={self.eps}, bits={self.bits})" \ No newline at end of file diff --git a/quaddtype/numpy_quaddtype/src/dtype.c b/quaddtype/numpy_quaddtype/src/dtype.c index 7d0fad3..950f6bf 100644 --- a/quaddtype/numpy_quaddtype/src/dtype.c +++ b/quaddtype/numpy_quaddtype/src/dtype.c @@ -224,6 +224,34 @@ QuadPrecDType_str(QuadPrecDTypeObject *self) return PyUnicode_FromFormat("QuadPrecDType(backend='%s')", backend_str); } +static PyObject * +QuadPrecDType_finfo(QuadPrecDTypeObject *self, PyObject *args) +{ + PyObject *numpy_quaddtype_module = PyImport_ImportModule("numpy_quaddtype"); + if (numpy_quaddtype_module == NULL) { + return NULL; + } + + PyObject *finfo_class = PyObject_GetAttrString(numpy_quaddtype_module, "QuadPrecFinfo"); + Py_DECREF(numpy_quaddtype_module); + + if (finfo_class == NULL) { + PyErr_SetString(PyExc_AttributeError, "Could not find QuadPrecFinfo class in numpy_quaddtype module."); + return NULL; + } + + PyObject *finfo_instance = PyObject_CallNoArgs(finfo_class); + Py_DECREF(finfo_class); + + return finfo_instance; +} + +static PyMethodDef QuadPrecDType_methods[] = { + {"finfo", (PyCFunction)QuadPrecDType_finfo, METH_NOARGS, + "Return floating-point information for this QuadPrecDType"}, + {NULL, NULL, 0, NULL} +}; + PyArray_DTypeMeta QuadPrecDType = { {{ PyVarObject_HEAD_INIT(NULL, 0).tp_name = "numpy_quaddtype.QuadPrecDType", @@ -231,6 +259,7 @@ PyArray_DTypeMeta QuadPrecDType = { .tp_new = QuadPrecDType_new, .tp_repr = (reprfunc)QuadPrecDType_repr, .tp_str = (reprfunc)QuadPrecDType_str, + .tp_methods = QuadPrecDType_methods, }}, }; diff --git a/quaddtype/numpy_quaddtype/src/scalar.c b/quaddtype/numpy_quaddtype/src/scalar.c index 6d82d19..38f48b8 100644 --- a/quaddtype/numpy_quaddtype/src/scalar.c +++ b/quaddtype/numpy_quaddtype/src/scalar.c @@ -239,7 +239,7 @@ QuadPrecision_dealloc(QuadPrecisionObject *self) } PyTypeObject QuadPrecision_Type = { - PyVarObject_HEAD_INIT(NULL, 0).tp_name = "numpy_quaddtype.QuadPrecision", + PyVarObject_HEAD_INIT(NULL, 0).tp_name = "numpy_quaddtype.QuadPrecDType", .tp_basicsize = sizeof(QuadPrecisionObject), .tp_itemsize = 0, .tp_new = QuadPrecision_new, @@ -253,5 +253,6 @@ PyTypeObject QuadPrecision_Type = { int init_quadprecision_scalar(void) { + QuadPrecision_Type.tp_base = &PyFloatingArrType_Type; return PyType_Ready(&QuadPrecision_Type); } \ No newline at end of file diff --git a/quaddtype/reinstall.sh b/quaddtype/reinstall.sh index 5a028f1..a5b00ac 100755 --- a/quaddtype/reinstall.sh +++ b/quaddtype/reinstall.sh @@ -8,7 +8,7 @@ if [ -d "build/" ]; then rm -rf subprojects/sleef fi -export CFLAGS="-g -O0" -export CXXFLAGS="-g -O0" +# export CFLAGS="-g -O0" +# export CXXFLAGS="-g -O0" python -m pip uninstall -y numpy_quaddtype -python -m pip install . -v \ No newline at end of file +python -m pip install . --no-build-isolation -v 2>&1 | tee build_log.txt \ No newline at end of file