From 25449096a45fc2bd4b7106dc0131ec83f14c418b Mon Sep 17 00:00:00 2001 From: jakirkham Date: Mon, 21 Oct 2024 23:02:47 -0700 Subject: [PATCH] Use Cython's `array` to back `Py_ssize_t[::1]` In `Array`, `Py_ssize_t[::1]` objects are currently backed by CPython `array`'s with some internal bits expressed in Cython. However these are not compatible with Python's Limited API and Stable ABI. To address that, switch to Cython's own`array` type. As this is baked into Cython and doesn't use anything special, it is compatible with Python's Limited API and Stable ABI. https://cython.readthedocs.io/en/latest/src/userguide/memoryviews.html#cython-arrays --- python/kvikio/kvikio/_lib/arr.pyx | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/python/kvikio/kvikio/_lib/arr.pyx b/python/kvikio/kvikio/_lib/arr.pyx index d26b139e92..1a9dea5136 100644 --- a/python/kvikio/kvikio/_lib/arr.pyx +++ b/python/kvikio/kvikio/_lib/arr.pyx @@ -4,13 +4,14 @@ # cython: language_level=3 -from cpython.array cimport array, newarrayobject from cpython.buffer cimport PyBuffer_IsContiguous +from cpython.mem cimport PyMem_Free, PyMem_Malloc from cpython.memoryview cimport PyMemoryView_FromObject, PyMemoryView_GET_BUFFER from cpython.object cimport PyObject from cpython.ref cimport Py_INCREF from cpython.tuple cimport PyTuple_New, PyTuple_SET_ITEM from cython cimport auto_pickle, boundscheck, initializedcheck, nonecheck, wraparound +from cython.view cimport array from libc.stdint cimport uintptr_t from libc.string cimport memcpy @@ -53,13 +54,14 @@ cdef dict itemsize_mapping = { } -cdef array array_Py_ssize_t = array("q") +cdef sizeof_Py_ssize_t = sizeof(Py_ssize_t) -cdef inline Py_ssize_t[::1] new_Py_ssize_t_array(Py_ssize_t n): - return newarrayobject( - (array_Py_ssize_t).ob_type, n, array_Py_ssize_t.ob_descr - ) +cdef Py_ssize_t[::1] new_Py_ssize_t_array(Py_ssize_t n): + cdef array a = array((n,), sizeof_Py_ssize_t, b"q", "c", False) + a.data = PyMem_Malloc(n * sizeof(Py_ssize_t)) + a.callback_free_data = PyMem_Free + return a @auto_pickle(False)