diff options
author | Matti Picus <matti.picus@gmail.com> | 2022-01-06 09:15:30 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-01-06 09:15:30 +0200 |
commit | e967f51d19576e10ac741ff664c34d1116f1fc58 (patch) | |
tree | f9f775f1bf364a45af9f0b147f67c0257f5149aa | |
parent | 550d54926738c737cf354db95ce4e3eaaa159d03 (diff) | |
parent | 975a94623b1c84979ef9bfe620745299f420315a (diff) | |
download | numpy-e967f51d19576e10ac741ff664c34d1116f1fc58.tar.gz |
Merge pull request #20729 from seberg/relax-reduce-dtype-identity-check
BUG: Relax dtype identity check in reductions
-rw-r--r-- | numpy/core/src/umath/ufunc_object.c | 8 | ||||
-rw-r--r-- | numpy/core/tests/test_ufunc.py | 11 |
2 files changed, 17 insertions, 2 deletions
diff --git a/numpy/core/src/umath/ufunc_object.c b/numpy/core/src/umath/ufunc_object.c index 52b354353..83e18a363 100644 --- a/numpy/core/src/umath/ufunc_object.c +++ b/numpy/core/src/umath/ufunc_object.c @@ -2764,9 +2764,13 @@ reducelike_promote_and_resolve(PyUFuncObject *ufunc, * The first operand and output should be the same array, so they should * be identical. The second argument can be different for reductions, * but is checked to be identical for accumulate and reduceat. + * Ideally, the type-resolver ensures that all are identical, but we do + * not enforce this here strictly. Otherwise correct handling of + * byte-order changes (or metadata) requires a lot of care; see gh-20699. */ - if (out_descrs[0] != out_descrs[2] || ( - enforce_uniform_args && out_descrs[0] != out_descrs[1])) { + if (!PyArray_EquivTypes(out_descrs[0], out_descrs[2]) || ( + enforce_uniform_args && !PyArray_EquivTypes( + out_descrs[0], out_descrs[1]))) { PyErr_Format(PyExc_TypeError, "the resolved dtypes are not compatible with %s.%s. " "Resolved (%R, %R, %R)", diff --git a/numpy/core/tests/test_ufunc.py b/numpy/core/tests/test_ufunc.py index 76e4cdcfd..9a9d46da0 100644 --- a/numpy/core/tests/test_ufunc.py +++ b/numpy/core/tests/test_ufunc.py @@ -2148,6 +2148,17 @@ class TestUfunc: # It would be safe, but not equiv casting: ufunc(a, c, out=out, casting="equiv") + def test_reducelike_byteorder_resolution(self): + # See gh-20699, byte-order changes need some extra care in the type + # resolution to make the following succeed: + arr_be = np.arange(10, dtype=">i8") + arr_le = np.arange(10, dtype="<i8") + + assert np.add.reduce(arr_be) == np.add.reduce(arr_le) + assert_array_equal(np.add.accumulate(arr_be), np.add.accumulate(arr_le)) + assert_array_equal( + np.add.reduceat(arr_be, [1]), np.add.reduceat(arr_le, [1])) + def test_reducelike_out_promotes(self): # Check that the out argument to reductions is considered for # promotion. See also gh-20455. |