From 3a2c5042fa85ac9b8fe398d605d6d373d27f42bb Mon Sep 17 00:00:00 2001 From: Stuart Archibald Date: Thu, 14 Oct 2021 09:35:24 +0100 Subject: [PATCH 1/7] Update build matrix for NumPy 1.21 as per NEP-029. As title. --- azure-pipelines.yml | 68 ++++++++++++++-------------- buildscripts/azure/azure-windows.yml | 8 ++-- 2 files changed, 38 insertions(+), 38 deletions(-) Index: numba-0.54.1/setup.py =================================================================== --- numba-0.54.1.orig/setup.py +++ numba-0.54.1/setup.py @@ -22,8 +22,7 @@ except ImportError: min_python_version = "3.7" max_python_version = "3.10" # exclusive min_numpy_build_version = "1.11" -min_numpy_run_version = "1.17" -max_numpy_run_version = "1.21" +min_numpy_run_version = "1.18" min_llvmlite_version = "0.37.0rc1" max_llvmlite_version = "0.38" @@ -360,7 +359,7 @@ packages = find_packages(include=["numba build_requires = ['numpy >={}'.format(min_numpy_build_version)] install_requires = [ 'llvmlite >={},<{}'.format(min_llvmlite_version, max_llvmlite_version), - 'numpy >={},<{}'.format(min_numpy_run_version, max_numpy_run_version), + 'numpy >={}'.format(min_numpy_run_version), 'setuptools', ] Index: numba-0.54.1/numba/__init__.py =================================================================== --- numba-0.54.1.orig/numba/__init__.py +++ numba-0.54.1/numba/__init__.py @@ -137,10 +137,8 @@ def _ensure_critical_deps(): if PYVERSION < (3, 7): raise ImportError("Numba needs Python 3.7 or greater") - if numpy_version < (1, 17): - raise ImportError("Numba needs NumPy 1.17 or greater") - elif numpy_version > (1, 20): - raise ImportError("Numba needs NumPy 1.20 or less") + if numpy_version < (1, 18): + raise ImportError("Numba needs NumPy 1.18 or greater") try: import scipy Index: numba-0.54.1/README.rst =================================================================== --- numba-0.54.1.orig/README.rst +++ numba-0.54.1/README.rst @@ -50,7 +50,7 @@ Dependencies * Python versions: 3.7-3.9 * llvmlite 0.37.* -* NumPy >=1.17,<1.21 (can build with 1.11 for ABI compatibility). +* NumPy >=1.18 (can build with 1.11 for ABI compatibility). Optionally: Index: numba-0.54.1/docs/source/user/5minguide.rst =================================================================== --- numba-0.54.1.orig/docs/source/user/5minguide.rst +++ numba-0.54.1/docs/source/user/5minguide.rst @@ -18,7 +18,7 @@ Out of the box Numba works with the foll support on M1/Arm64. * GPUs: Nvidia CUDA. * CPython -* NumPy 1.17 - latest +* NumPy 1.18 - latest How do I get it? ---------------- Index: numba-0.54.1/numba/np/ufunc/_internal.c =================================================================== --- numba-0.54.1.orig/numba/np/ufunc/_internal.c +++ numba-0.54.1/numba/np/ufunc/_internal.c @@ -276,6 +276,7 @@ static PyMemberDef dufunc_members[] = { */ static struct _ufunc_dispatch { + /* Note that the following may also hold `_PyCFunctionFastWithKeywords` */ PyCFunctionWithKeywords ufunc_reduce; PyCFunctionWithKeywords ufunc_accumulate; PyCFunctionWithKeywords ufunc_reduceat; @@ -286,7 +287,7 @@ static struct _ufunc_dispatch { } ufunc_dispatch; static int -init_ufunc_dispatch(void) +init_ufunc_dispatch(int *numpy_uses_fastcall) { int result = 0; PyMethodDef * crnt = PyUFunc_Type.tp_methods; @@ -329,6 +330,16 @@ init_ufunc_dispatch(void) result = -1; /* Unknown method */ } if (result < 0) break; + + /* Check whether NumPy uses fastcall (ufunc.at never uses it) */ + if (strncmp(crnt_name, "at", 3) != 0) { + if (*numpy_uses_fastcall == -1) { + *numpy_uses_fastcall = crnt->ml_flags & METH_FASTCALL; + } + else if (*numpy_uses_fastcall != (crnt->ml_flags & METH_FASTCALL)) { + return -1; + } + } } if (result == 0) { /* Sanity check. */ @@ -344,6 +355,7 @@ init_ufunc_dispatch(void) return result; } + static PyObject * dufunc_reduce(PyDUFuncObject * self, PyObject * args, PyObject *kws) { @@ -368,6 +380,47 @@ dufunc_outer(PyDUFuncObject * self, PyOb return ufunc_dispatch.ufunc_outer((PyObject*)self->ufunc, args, kws); } + +/* + * The following are the vectorcall versions of the above, since NumPy + * uses the FASTCALL/Vectorcall protocol starting with version 1.21. + * The only NumPy versions supporting vectorcall use Python 3.7 or higher. + */ +static PyObject * +dufunc_reduce_fast(PyDUFuncObject * self, + PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames) +{ + return ((_PyCFunctionFastWithKeywords)ufunc_dispatch.ufunc_reduce)( + (PyObject*)self->ufunc, args, len_args, kwnames); +} + +static PyObject * +dufunc_reduceat_fast(PyDUFuncObject * self, + PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames) +{ + return ((_PyCFunctionFastWithKeywords)ufunc_dispatch.ufunc_reduceat)( + (PyObject*)self->ufunc, args, len_args, kwnames); +} + + +static PyObject * +dufunc_accumulate_fast(PyDUFuncObject * self, + PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames) +{ + return ((_PyCFunctionFastWithKeywords)ufunc_dispatch.ufunc_accumulate)( + (PyObject*)self->ufunc, args, len_args, kwnames); +} + + +static PyObject * +dufunc_outer_fast(PyDUFuncObject * self, + PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames) +{ + return ((_PyCFunctionFastWithKeywords)ufunc_dispatch.ufunc_outer)( + (PyObject*)self->ufunc, args, len_args, kwnames); +} + + #if NPY_API_VERSION >= 0x00000008 static PyObject * dufunc_at(PyDUFuncObject * self, PyObject * args) @@ -568,6 +621,41 @@ static struct PyMethodDef dufunc_methods {NULL, NULL, 0, NULL} /* sentinel */ }; + +/* + * If Python is new enough, NumPy may use fastcall. In that case we have to + * also use fastcall for simplicity and speed. + */ +static struct PyMethodDef dufunc_methods_fast[] = { + {"reduce", + (PyCFunction)dufunc_reduce_fast, + METH_FASTCALL | METH_KEYWORDS, NULL }, + {"accumulate", + (PyCFunction)dufunc_accumulate_fast, + METH_FASTCALL | METH_KEYWORDS, NULL }, + {"reduceat", + (PyCFunction)dufunc_reduceat_fast, + METH_FASTCALL | METH_KEYWORDS, NULL }, + {"outer", + (PyCFunction)dufunc_outer_fast, + METH_FASTCALL | METH_KEYWORDS, NULL}, +#if NPY_API_VERSION >= 0x00000008 + {"at", + (PyCFunction)dufunc_at, + METH_VARARGS, NULL}, +#endif + {"_compile_for_args", + (PyCFunction)dufunc__compile_for_args, + METH_VARARGS | METH_KEYWORDS, + "Abstract method: subclasses should overload _compile_for_args() to compile the ufunc at the given arguments' types."}, + {"_add_loop", + (PyCFunction)dufunc__add_loop, + METH_VARARGS, + NULL}, + {NULL, NULL, 0, NULL} /* sentinel */ +}; + + static PyObject * dufunc_getfrozen(PyDUFuncObject * self, void * closure) { @@ -681,8 +769,15 @@ MOD_INIT(_internal) return MOD_ERROR_VAL; PyDUFunc_Type.tp_new = PyType_GenericNew; - if (init_ufunc_dispatch() <= 0) + + int numpy_uses_fastcall = -1; + if (init_ufunc_dispatch(&numpy_uses_fastcall) <= 0) return MOD_ERROR_VAL; + + if (numpy_uses_fastcall) { + PyDUFunc_Type.tp_methods = dufunc_methods_fast; + } + if (PyType_Ready(&PyDUFunc_Type) < 0) return MOD_ERROR_VAL; Py_INCREF(&PyDUFunc_Type); Index: numba-0.54.1/numba/tests/test_array_reductions.py =================================================================== --- numba-0.54.1.orig/numba/tests/test_array_reductions.py +++ numba-0.54.1/numba/tests/test_array_reductions.py @@ -725,6 +725,7 @@ class TestArrayReductions(MemoryLeakMixi self.check_npdatetime(array_argmax) self.check_nptimedelta(array_argmax) + @unittest.skip("https://github.com/numpy/numpy/issues/20376") def test_median_npdatetime(self): self.check_nptimedelta(array_median_global)