From d7f29bade4902612a0580c36b2d9d21162865d71 Mon Sep 17 00:00:00 2001 From: pdmurray Date: Wed, 7 Dec 2022 15:33:41 -0800 Subject: [PATCH 1/5] Move gitignore to top level; fix debug issues --- quaddtype/.gitignore => .gitignore | 0 quaddtype/pyproject.toml | 4 ++-- quaddtype/quaddtype/src/dtype.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename quaddtype/.gitignore => .gitignore (100%) diff --git a/quaddtype/.gitignore b/.gitignore similarity index 100% rename from quaddtype/.gitignore rename to .gitignore diff --git a/quaddtype/pyproject.toml b/quaddtype/pyproject.toml index 99b5d9c3..37a3413b 100644 --- a/quaddtype/pyproject.toml +++ b/quaddtype/pyproject.toml @@ -4,7 +4,7 @@ requires = [ "meson-python", "patchelf", "wheel", - "numpy @ file:///home/pdmurray/Desktop/numpy-1.24.0.dev0+1120.gf30af6acd-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" + "numpy @ file:///home/pdmurray/Desktop/numpy-1.24.0.dev0+1342.g2aad439ee-cp311-cp311d-linux_x86_64.whl" ] build-backend = "mesonpy" @@ -16,7 +16,7 @@ readme = 'README.md' author = "Peyton Murray" requires-python = ">=3.9.0" dependencies = [ - "numpy @ file:///home/pdmurray/Desktop/numpy-1.24.0.dev0+1120.gf30af6acd-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" + "numpy @ file:///home/pdmurray/Desktop/numpy-1.24.0.dev0+1342.g2aad439ee-cp311-cp311d-linux_x86_64.whl" ] [project.optional-dependencies] diff --git a/quaddtype/quaddtype/src/dtype.c b/quaddtype/quaddtype/src/dtype.c index b70da987..703ee4fa 100644 --- a/quaddtype/quaddtype/src/dtype.c +++ b/quaddtype/quaddtype/src/dtype.c @@ -140,7 +140,7 @@ init_quad_dtype(void) // do it. You first have to create a static type, but see the note there! PyArrayMethod_Spec *casts[] = { &QuadToQuadCastSpec, - &QuadToFloat128CastSpec, + // &QuadToFloat128CastSpec, NULL, }; From 97c248fe4f9ea385fc5c4a9c6ec05ab64e9a6749 Mon Sep 17 00:00:00 2001 From: pdmurray Date: Thu, 8 Dec 2022 16:43:07 -0800 Subject: [PATCH 2/5] Added aligned, strided, and unaligned casting loops --- quaddtype/pyproject.toml | 4 +-- quaddtype/quaddtype/src/casts.c | 51 +++++++++++++++++++++++++++++++-- quaddtype/quaddtype/src/dtype.c | 12 ++++++-- 3 files changed, 60 insertions(+), 7 deletions(-) diff --git a/quaddtype/pyproject.toml b/quaddtype/pyproject.toml index 37a3413b..687b2637 100644 --- a/quaddtype/pyproject.toml +++ b/quaddtype/pyproject.toml @@ -4,7 +4,7 @@ requires = [ "meson-python", "patchelf", "wheel", - "numpy @ file:///home/pdmurray/Desktop/numpy-1.24.0.dev0+1342.g2aad439ee-cp311-cp311d-linux_x86_64.whl" + "numpy @ file:///home/pdmurray/Desktop/numpy-1.25.0.dev0+167.g4ca8204c5-cp311-cp311d-linux_x86_64.whl" ] build-backend = "mesonpy" @@ -16,7 +16,7 @@ readme = 'README.md' author = "Peyton Murray" requires-python = ">=3.9.0" dependencies = [ - "numpy @ file:///home/pdmurray/Desktop/numpy-1.24.0.dev0+1342.g2aad439ee-cp311-cp311d-linux_x86_64.whl" + "numpy @ file:///home/pdmurray/Desktop/numpy-1.25.0.dev0+167.g4ca8204c5-cp311-cp311d-linux_x86_64.whl" ] [project.optional-dependencies] diff --git a/quaddtype/quaddtype/src/casts.c b/quaddtype/quaddtype/src/casts.c index 3df6529f..bc0ee4c2 100644 --- a/quaddtype/quaddtype/src/casts.c +++ b/quaddtype/quaddtype/src/casts.c @@ -29,24 +29,69 @@ quad_to_quad_resolve_descriptors(PyObject *NPY_UNUSED(self), return NPY_SAME_KIND_CASTING; } +// Each element is a __float128 element; no casting needed static int quad_to_quad_contiguous(PyArrayMethod_Context *NPY_UNUSED(context), char *const data[], - npy_intp const dimensions[], npy_intp const strides[], void *auxdata) + npy_intp const dimensions[], npy_intp const strides[], + NpyAuxData *NPY_UNUSED(auxdata)) { + npy_intp N = dimensions[0]; + __float128 *in = (__float128 *)data[0]; + __float128 *out = (__float128 *)data[1]; + + while (N--) { + *out = *in; + out++; + in++; + } + return 0; } +// Elements are strided, e.g. +// +// x = np.linspace(40) +// x[::3] +// +// Therefore the stride needs to be used to increment the pointers inside the loop. static int quad_to_quad_strided(PyArrayMethod_Context *NPY_UNUSED(context), char *const data[], - npy_intp const dimensions[], npy_intp const strides[], void *auxdata) + npy_intp const dimensions[], npy_intp const strides[], + NpyAuxData *NPY_UNUSED(auxdata)) { + npy_intp N = dimensions[0]; + char *in = data[0]; + char *out = data[1]; + npy_intp in_stride = strides[0]; + npy_intp out_stride = strides[1]; + + while (N--) { + *(__float128 *)out = *(__float128 *)in; + in += in_stride; + out += out_stride; + } + return 0; } +// Arrays are unaligned. static int quad_to_quad_unaligned(PyArrayMethod_Context *NPY_UNUSED(context), char *const data[], - npy_intp const dimensions[], npy_intp const strides[], void *auxdata) + npy_intp const dimensions[], npy_intp const strides[], + NpyAuxData *NPY_UNUSED(auxdata)) { + npy_intp N = dimensions[0]; + char *in = data[0]; + char *out = data[1]; + npy_intp in_stride = strides[0]; + npy_intp out_stride = strides[1]; + + while (N--) { + memcpy(out, in, sizeof(__float128)); // NOLINT + in += in_stride; + out += out_stride; + } + return 0; } diff --git a/quaddtype/quaddtype/src/dtype.c b/quaddtype/quaddtype/src/dtype.c index 703ee4fa..de6897af 100644 --- a/quaddtype/quaddtype/src/dtype.c +++ b/quaddtype/quaddtype/src/dtype.c @@ -82,11 +82,19 @@ common_dtype(PyArray_DTypeMeta *self, PyArray_DTypeMeta *other) return (PyArray_DTypeMeta *)Py_NotImplemented; } +static QuadDTypeObject * +quaddtype_ensure_canonical(QuadDTypeObject *self) +{ + Py_INCREF(self); + return self; +} + static PyType_Slot QuadDType_Slots[] = {{NPY_DT_common_instance, &common_instance}, {NPY_DT_common_dtype, &common_dtype}, // {NPY_DT_discover_descr_from_pyobject, // &unit_discover_descriptor_from_pyobject}, /* The header is wrong on main :(, so we add 1 */ + {NPY_DT_ensure_canonical, &quaddtype_ensure_canonical}, {NPY_DT_setitem, &quad_setitem}, {NPY_DT_getitem, &quad_getitem}, {0, NULL}}; @@ -114,7 +122,8 @@ quaddtype_dealloc(QuadDTypeObject *self) static PyObject * quaddtype_repr(QuadDTypeObject *self) { - return PyUnicode_FromString("This is a quad (128-bit float) dtype."); + PyObject *res = PyUnicode_FromString("This is a quad (128-bit float) dtype."); + return res; } // These are the basic things that you need to create a Python Type/Class in C. @@ -140,7 +149,6 @@ init_quad_dtype(void) // do it. You first have to create a static type, but see the note there! PyArrayMethod_Spec *casts[] = { &QuadToQuadCastSpec, - // &QuadToFloat128CastSpec, NULL, }; From 752972c4f5389f33e8f8ccb8e951d5d36e2cefea Mon Sep 17 00:00:00 2001 From: pdmurray Date: Fri, 9 Dec 2022 22:52:12 -0800 Subject: [PATCH 3/5] Add discover_descr_from_pyobject --- quaddtype/pyproject.toml | 4 +-- quaddtype/quaddtype/src/dtype.c | 44 ++++++++++++++++++--------------- quaddtype/quaddtype/src/dtype.h | 5 ++++ 3 files changed, 31 insertions(+), 22 deletions(-) diff --git a/quaddtype/pyproject.toml b/quaddtype/pyproject.toml index 687b2637..27b49139 100644 --- a/quaddtype/pyproject.toml +++ b/quaddtype/pyproject.toml @@ -4,7 +4,7 @@ requires = [ "meson-python", "patchelf", "wheel", - "numpy @ file:///home/pdmurray/Desktop/numpy-1.25.0.dev0+167.g4ca8204c5-cp311-cp311d-linux_x86_64.whl" + "numpy @ file:///home/pdmurray/Desktop/numpy-1.24.0.dev0+1345.g4ca8204c5-cp311-cp311d-linux_x86_64.whl" ] build-backend = "mesonpy" @@ -16,7 +16,7 @@ readme = 'README.md' author = "Peyton Murray" requires-python = ">=3.9.0" dependencies = [ - "numpy @ file:///home/pdmurray/Desktop/numpy-1.25.0.dev0+167.g4ca8204c5-cp311-cp311d-linux_x86_64.whl" + "numpy @ file:///home/pdmurray/Desktop/numpy-1.24.0.dev0+1345.g4ca8204c5-cp311-cp311d-linux_x86_64.whl" ] [project.optional-dependencies] diff --git a/quaddtype/quaddtype/src/dtype.c b/quaddtype/quaddtype/src/dtype.c index de6897af..470245be 100644 --- a/quaddtype/quaddtype/src/dtype.c +++ b/quaddtype/quaddtype/src/dtype.c @@ -1,14 +1,5 @@ -#include - -#define PY_ARRAY_UNIQUE_SYMBOL quaddtype_ARRAY_API -#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION -#define NO_IMPORT_ARRAY -#include "numpy/arrayobject.h" -#include "numpy/experimental_dtype_api.h" -#include "numpy/ndarraytypes.h" - -#include "casts.h" #include "dtype.h" +#include "casts.h" PyTypeObject *QuadScalar_Type = NULL; @@ -17,8 +8,9 @@ new_quaddtype_instance(void) { QuadDTypeObject *new = (QuadDTypeObject *)PyArrayDescr_Type.tp_new((PyTypeObject *)&QuadDType, NULL, NULL); - if (new == NULL) + if (new == NULL) { return NULL; + } new->base.elsize = sizeof(__float128); new->base.alignment = _Alignof(__float128); @@ -89,15 +81,27 @@ quaddtype_ensure_canonical(QuadDTypeObject *self) return self; } -static PyType_Slot QuadDType_Slots[] = {{NPY_DT_common_instance, &common_instance}, - {NPY_DT_common_dtype, &common_dtype}, - // {NPY_DT_discover_descr_from_pyobject, - // &unit_discover_descriptor_from_pyobject}, - /* The header is wrong on main :(, so we add 1 */ - {NPY_DT_ensure_canonical, &quaddtype_ensure_canonical}, - {NPY_DT_setitem, &quad_setitem}, - {NPY_DT_getitem, &quad_getitem}, - {0, NULL}}; +static PyArray_Descr * +quad_discover_descriptor_from_pyobject(PyArray_DTypeMeta *NPY_UNUSED(cls), PyObject *obj) +{ + if (Py_TYPE(obj) != QuadScalar_Type) { + PyErr_SetString(PyExc_TypeError, "Can only store QuadScalars in a QuadDType array."); + return NULL; + } + + // Get the dtype attribute from the object. + return (PyArray_Descr *)PyObject_GetAttrString(obj, "dtype"); +} + +static PyType_Slot QuadDType_Slots[] = { + {NPY_DT_common_instance, &common_instance}, + {NPY_DT_common_dtype, &common_dtype}, + {NPY_DT_discover_descr_from_pyobject, &quad_discover_descriptor_from_pyobject}, + /* The header is wrong on main :(, so we add 1 */ + {NPY_DT_setitem, &quad_setitem}, + {NPY_DT_getitem, &quad_getitem}, + {NPY_DT_ensure_canonical, &quaddtype_ensure_canonical}, + {0, NULL}}; /* * The following defines everything type object related (i.e. not NumPy diff --git a/quaddtype/quaddtype/src/dtype.h b/quaddtype/quaddtype/src/dtype.h index 2427beb5..fdce9398 100644 --- a/quaddtype/quaddtype/src/dtype.h +++ b/quaddtype/quaddtype/src/dtype.h @@ -3,6 +3,10 @@ #include +#define PY_ARRAY_UNIQUE_SYMBOL quaddtype_ARRAY_API +#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION +#define NO_IMPORT_ARRAY +#include "numpy/ndarraytypes.h" #include "numpy/arrayobject.h" #include "numpy/experimental_dtype_api.h" @@ -15,6 +19,7 @@ extern PyTypeObject *QuadScalar_Type; QuadDTypeObject * new_quaddtype_instance(void); + int init_quad_dtype(void); From 9371b23bb0254e79ae3798c79f70078f982b1dd2 Mon Sep 17 00:00:00 2001 From: pdmurray Date: Fri, 9 Dec 2022 23:02:31 -0800 Subject: [PATCH 4/5] Fix the package "git describe" version --- quaddtype/pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/quaddtype/pyproject.toml b/quaddtype/pyproject.toml index 27b49139..687b2637 100644 --- a/quaddtype/pyproject.toml +++ b/quaddtype/pyproject.toml @@ -4,7 +4,7 @@ requires = [ "meson-python", "patchelf", "wheel", - "numpy @ file:///home/pdmurray/Desktop/numpy-1.24.0.dev0+1345.g4ca8204c5-cp311-cp311d-linux_x86_64.whl" + "numpy @ file:///home/pdmurray/Desktop/numpy-1.25.0.dev0+167.g4ca8204c5-cp311-cp311d-linux_x86_64.whl" ] build-backend = "mesonpy" @@ -16,7 +16,7 @@ readme = 'README.md' author = "Peyton Murray" requires-python = ">=3.9.0" dependencies = [ - "numpy @ file:///home/pdmurray/Desktop/numpy-1.24.0.dev0+1345.g4ca8204c5-cp311-cp311d-linux_x86_64.whl" + "numpy @ file:///home/pdmurray/Desktop/numpy-1.25.0.dev0+167.g4ca8204c5-cp311-cp311d-linux_x86_64.whl" ] [project.optional-dependencies] From a348a91903846c8596c61d0a638170c3b1d91bba Mon Sep 17 00:00:00 2001 From: pdmurray Date: Mon, 12 Dec 2022 12:27:34 -0800 Subject: [PATCH 5/5] Minor fixes --- quaddtype/quaddtype/src/umath.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/quaddtype/quaddtype/src/umath.c b/quaddtype/quaddtype/src/umath.c index f8fed77c..86c65171 100644 --- a/quaddtype/quaddtype/src/umath.c +++ b/quaddtype/quaddtype/src/umath.c @@ -25,7 +25,7 @@ quad_multiply_strided_loop(PyArrayMethod_Context *context, char *const data[], char *in1 = data[0], *in2 = data[1]; char *out = data[2]; npy_intp in1_stride = strides[0]; - npy_intp in2_stride = strides[0]; + npy_intp in2_stride = strides[1]; npy_intp out_stride = strides[2]; while (N--) { @@ -56,9 +56,18 @@ quad_multiply_resolve_descriptors(PyObject *self, PyArray_DTypeMeta *dtypes[], // The operand units can be used as-is; no casting required for quad types. Py_INCREF(given_descrs[0]); loop_descrs[0] = given_descrs[0]; + + if (given_descrs[1] == NULL) { + Py_INCREF(given_descrs[0]); + loop_descrs[1] = given_descrs[0]; + return NPY_NO_CASTING; + } + Py_INCREF(given_descrs[1]); + loop_descrs[1] = given_descrs[1]; + Py_INCREF(given_descrs[1]); loop_descrs[1] = given_descrs[1]; - return NPY_NO_CASTING; + return NPY_SAFE_CASTING; } // Function that adds our multiply loop to NumPy's multiply ufunc.