Skip to content

Commit

Permalink
Merge pull request #4544 from juliantaylor/unaligned-index
Browse files Browse the repository at this point in the history
BUG: fix unaligned access of new indexing
  • Loading branch information
charris committed Mar 26, 2014
2 parents 7395900 + c437672 commit 0953088
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 8 deletions.
14 changes: 6 additions & 8 deletions numpy/core/src/multiarray/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -650,14 +650,12 @@ _IsAligned(PyArrayObject *ap)
{
unsigned int i;
npy_uintp aligned;
const unsigned int alignment = PyArray_DESCR(ap)->alignment;

/* The special casing for STRING and VOID types was removed
* in accordance with http://projects.scipy.org/numpy/ticket/1227
* It used to be that IsAligned always returned True for these
* types, which is indeed the case when they are created using
* PyArray_DescrConverter(), but not necessarily when using
* PyArray_DescrAlignConverter(). */
npy_uintp alignment = PyArray_DESCR(ap)->alignment;

/* alignment 1 types should have a efficient alignment for copy loops */
if (PyArray_ISFLEXIBLE(ap) || PyArray_ISSTRING(ap)) {
alignment = 16;
}

if (alignment == 1) {
return 1;
Expand Down
11 changes: 11 additions & 0 deletions numpy/core/src/multiarray/lowlevel_strided_loops.c.src
Original file line number Diff line number Diff line change
Expand Up @@ -1429,6 +1429,7 @@ mapiter_trivial_@name@(PyArrayObject *self, PyArrayObject *ind,
default:
#endif
while (itersize--) {
assert(npy_is_aligned(ind_ptr, _ALIGN(npy_intp)));
indval = *((npy_intp*)ind_ptr);
#if @isget@
if (check_and_adjust_index(&indval, fancy_dim, 1, _save) < 0 ) {
Expand All @@ -1443,13 +1444,17 @@ mapiter_trivial_@name@(PyArrayObject *self, PyArrayObject *ind,

#if @isget@
#if @elsize@
assert(npy_is_aligned(result_ptr, _ALIGN(@copytype@)));
assert(npy_is_aligned(self_ptr, _ALIGN(@copytype@)));
*(@copytype@ *)result_ptr = *(@copytype@ *)self_ptr;
#else
copyswap(result_ptr, self_ptr, 0, self);
#endif

#else /* !@isget@ */
#if @elsize@
assert(npy_is_aligned(result_ptr, _ALIGN(@copytype@)));
assert(npy_is_aligned(self_ptr, _ALIGN(@copytype@)));
*(@copytype@ *)self_ptr = *(@copytype@ *)result_ptr;
#else
copyswap(self_ptr, result_ptr, 0, self);
Expand Down Expand Up @@ -1567,6 +1572,8 @@ mapiter_@name@(PyArrayMapIterObject *mit)
while (count--) {
self_ptr = baseoffset;
for (i=0; i < @numiter@; i++) {
assert(npy_is_aligned(outer_ptrs[i],
_ALIGN(npy_intp)));
indval = *((npy_intp*)outer_ptrs[i]);

#if @isget@ && @one_iter@
Expand All @@ -1587,12 +1594,16 @@ mapiter_@name@(PyArrayMapIterObject *mit)

#if @isget@
#if @elsize@
assert(npy_is_aligned(outer_ptrs[i], _ALIGN(@copytype@)));
assert(npy_is_aligned(self_ptr, _ALIGN(@copytype@)));
*(@copytype@ *)(outer_ptrs[i]) = *(@copytype@ *)self_ptr;
#else
copyswap(outer_ptrs[i], self_ptr, 0, array);
#endif
#else /* !@isget@ */
#if @elsize@
assert(npy_is_aligned(outer_ptrs[i], _ALIGN(@copytype@)));
assert(npy_is_aligned(self_ptr, _ALIGN(@copytype@)));
*(@copytype@ *)self_ptr = *(@copytype@ *)(outer_ptrs[i]);
#else
copyswap(self_ptr, outer_ptrs[i], 0, array);
Expand Down
22 changes: 22 additions & 0 deletions numpy/core/tests/test_indexing.py
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,28 @@ def test_small_regressions(self):

assert_equal(sys.getrefcount(np.dtype(np.intp)), refcount)

def test_unaligned(self):
v = (np.zeros(64, dtype=np.int8) + ord('a'))[1:-7]
d = v.view(np.dtype("S8"))
# unaligned source
x = (np.zeros(16, dtype=np.int8) + ord('a'))[1:-7]
x = x.view(np.dtype("S8"))
x[...] = np.array("b" * 8, dtype="S")
b = np.arange(d.size)
#trivial
assert_equal(d[b], d)
d[b] = x
# nontrivial
# unaligned index array
b = np.zeros(d.size + 1).view(np.int8)[1:-(np.intp(0).itemsize - 1)]
b = b.view(np.intp)[:d.size]
b[...] = np.arange(d.size)
assert_equal(d[b.astype(np.int16)], d)
d[b.astype(np.int16)] = x
# boolean
d[b % 2 == 0]
d[b % 2 == 0] = x[::2]


class TestFieldIndexing(TestCase):
def test_scalar_return_type(self):
Expand Down

0 comments on commit 0953088

Please sign in to comment.