summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--numpy/core/src/multiarray/lowlevel_strided_loops.c.src12
-rw-r--r--numpy/core/tests/test_multiarray.py38
2 files changed, 44 insertions, 6 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/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':