diff options
Diffstat (limited to 'numpy/core')
-rw-r--r-- | numpy/core/src/multiarray/lowlevel_strided_loops.c.src | 12 | ||||
-rw-r--r-- | numpy/core/src/multiarray/methods.c | 2 | ||||
-rw-r--r-- | numpy/core/tests/test_multiarray.py | 38 |
3 files changed, 45 insertions, 7 deletions
diff --git a/numpy/core/src/multiarray/lowlevel_strided_loops.c.src b/numpy/core/src/multiarray/lowlevel_strided_loops.c.src index 159bb4103..896e466c8 100644 --- a/numpy/core/src/multiarray/lowlevel_strided_loops.c.src +++ b/numpy/core/src/multiarray/lowlevel_strided_loops.c.src @@ -121,8 +121,8 @@ static void { #if @is_aligned@ && @elsize@ != 16 /* sanity check */ - assert(npy_is_aligned(dst, _ALIGN(@type@))); - assert(npy_is_aligned(src, _ALIGN(@type@))); + assert(N == 0 || npy_is_aligned(dst, _ALIGN(@type@))); + assert(N == 0 || npy_is_aligned(src, _ALIGN(@type@))); #endif /*printf("fn @prefix@_@oper@_size@elsize@\n");*/ while (N > 0) { @@ -201,8 +201,8 @@ static NPY_GCC_OPT_3 void } #if @is_aligned@ && @elsize@ != 16 /* sanity check */ - assert(npy_is_aligned(dst, _ALIGN(@type@))); - assert(npy_is_aligned(src, _ALIGN(@type@))); + assert(N == 0 || npy_is_aligned(dst, _ALIGN(@type@))); + assert(N == 0 || npy_is_aligned(src, _ALIGN(@type@))); #endif #if @elsize@ == 1 && @dst_contig@ memset(dst, *src, N); @@ -809,10 +809,10 @@ static NPY_GCC_OPT_3 void #if @aligned@ /* sanity check */ # if !@is_complex1@ - assert(npy_is_aligned(src, _ALIGN(_TYPE1))); + assert(N == 0 || npy_is_aligned(src, _ALIGN(_TYPE1))); # endif # if !@is_complex2@ - assert(npy_is_aligned(dst, _ALIGN(_TYPE2))); + assert(N == 0 || npy_is_aligned(dst, _ALIGN(_TYPE2))); # endif #endif diff --git a/numpy/core/src/multiarray/methods.c b/numpy/core/src/multiarray/methods.c index 231bd86dc..6254114cc 100644 --- a/numpy/core/src/multiarray/methods.c +++ b/numpy/core/src/multiarray/methods.c @@ -187,7 +187,7 @@ array_reshape(PyArrayObject *self, PyObject *args, PyObject *kwds) } if (n <= 1) { - if (PyTuple_GET_ITEM(args, 0) == Py_None) { + if (n != 0 && PyTuple_GET_ITEM(args, 0) == Py_None) { return PyArray_View(self, NULL, NULL); } if (!PyArg_ParseTuple(args, "O&:reshape", PyArray_IntpConverter, diff --git a/numpy/core/tests/test_multiarray.py b/numpy/core/tests/test_multiarray.py index cdacdabbe..32d49df02 100644 --- a/numpy/core/tests/test_multiarray.py +++ b/numpy/core/tests/test_multiarray.py @@ -7923,6 +7923,44 @@ def test_uintalignment_and_alignment(): dst = np.zeros((2,2), dtype='c8') dst[:,1] = src[:,1] # assert in lowlevel_strided_loops fails? +class TestAlignment(object): + # adapted from scipy._lib.tests.test__util.test__aligned_zeros + # Checks that unusual memory alignments don't trip up numpy. + # In particular, check RELAXED_STRIDES don't trip alignment assertions in + # NDEBUG mode for size-0 arrays (gh-12503) + + def check(self, shape, dtype, order, align): + err_msg = repr((shape, dtype, order, align)) + x = _aligned_zeros(shape, dtype, order, align=align) + if align is None: + align = np.dtype(dtype).alignment + assert_equal(x.__array_interface__['data'][0] % align, 0) + if hasattr(shape, '__len__'): + assert_equal(x.shape, shape, err_msg) + else: + assert_equal(x.shape, (shape,), err_msg) + assert_equal(x.dtype, dtype) + if order == "C": + assert_(x.flags.c_contiguous, err_msg) + elif order == "F": + if x.size > 0: + assert_(x.flags.f_contiguous, err_msg) + elif order is None: + assert_(x.flags.c_contiguous, err_msg) + else: + raise ValueError() + + def test_various_alignments(self): + for align in [1, 2, 3, 4, 8, 16, 32, 64, None]: + for n in [0, 1, 3, 11]: + for order in ["C", "F", None]: + for dtype in np.typecodes["All"]: + if dtype == 'O': + # object dtype can't be misaligned + continue + for shape in [n, (1, 2, 3, n)]: + self.check(shape, np.dtype(dtype), order, align) + def test_getfield(): a = np.arange(32, dtype='uint16') if sys.byteorder == 'little': |