diff options
author | Sebastian Berg <sebastian@sipsolutions.net> | 2021-05-04 21:15:38 -0500 |
---|---|---|
committer | Sebastian Berg <sebastian@sipsolutions.net> | 2021-05-04 21:20:52 -0500 |
commit | 134063c0353546729f885e37aa28e2e1b13ac4ae (patch) | |
tree | e864d8746ce869051a67088b98f1996f500586b4 /numpy | |
parent | a70cb5490aaf1bcfae9b2554c3a48f33739c499e (diff) | |
download | numpy-134063c0353546729f885e37aa28e2e1b13ac4ae.tar.gz |
BUG: Add self-overlap check and tests
Previsouly we unnecessarily required contiguous inputs for
1-D "trivially iterable". That requirement was unnecessary, but
also guarded against certain self-overlaps.
This was not visible because a self-overlapping array is rarely
aligned (but for complex this happens typically).
Diffstat (limited to 'numpy')
-rw-r--r-- | numpy/core/src/umath/ufunc_object.c | 6 | ||||
-rw-r--r-- | numpy/core/tests/test_mem_overlap.py | 5 |
2 files changed, 11 insertions, 0 deletions
diff --git a/numpy/core/src/umath/ufunc_object.c b/numpy/core/src/umath/ufunc_object.c index bf8bd1a8c..b0654d7b0 100644 --- a/numpy/core/src/umath/ufunc_object.c +++ b/numpy/core/src/umath/ufunc_object.c @@ -1212,6 +1212,12 @@ try_trivial_single_output_loop(PyUFuncObject *ufunc, return -2; } } + /* Check self-overlap (non 1-D are contiguous, perfect overlap is OK) */ + if (operation_ndim == 1 && + PyArray_STRIDES(op[nin])[0] < PyArray_ITEMSIZE(op[nin]) && + PyArray_STRIDES(op[nin])[0] != 0) { + return -2; + } } /* Call the __prepare_array__ if necessary */ diff --git a/numpy/core/tests/test_mem_overlap.py b/numpy/core/tests/test_mem_overlap.py index ba73dad62..24bdf477f 100644 --- a/numpy/core/tests/test_mem_overlap.py +++ b/numpy/core/tests/test_mem_overlap.py @@ -666,6 +666,11 @@ class TestUFunc: def test_unary_ufunc_call_fuzz(self): self.check_unary_fuzz(np.invert, None, np.int16) + @pytest.mark.slow + def test_unary_ufunc_call_complex_fuzz(self): + # Complex typically has a smaller alignment than itemsize + self.check_unary_fuzz(np.negative, None, np.complex128, count=500) + def test_binary_ufunc_accumulate_fuzz(self): def get_out_axis_size(a, b, axis): if axis is None: |