Skip to content

Commit

Permalink
Merge pull request numpy#8042 from pv/fix-nditer-contig
Browse files Browse the repository at this point in the history
BUG: core: fix bug in NpyIter buffering with discontinuous arrays
  • Loading branch information
seberg authored Sep 11, 2016
2 parents 1b22317 + 21794ee commit 8d3673d
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 1 deletion.
2 changes: 1 addition & 1 deletion numpy/core/src/multiarray/nditer_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -2334,7 +2334,7 @@ npyiter_copy_to_buffers(NpyIter *iter, char **prev_dataptrs)
}
else {
/* It's all in one stride in the reduce outer loop */
if ((reduce_outerdim > 0) &&
if ((reduce_outerdim == 1) &&
(transfersize/reduce_innersize <=
NAD_SHAPE(reduce_outeraxisdata) -
NAD_INDEX(reduce_outeraxisdata))) {
Expand Down
16 changes: 16 additions & 0 deletions numpy/core/tests/test_nditer.py
Original file line number Diff line number Diff line change
Expand Up @@ -2374,6 +2374,22 @@ def test_iter_buffering_reduction():
it.reset()
assert_equal(it[0], [1, 2, 1, 2])

# Iterator inner loop should take argument contiguity into account
x = np.ones((7, 13, 8), np.int8)[4:6,1:11:6,1:5].transpose(1, 2, 0)
x[...] = np.arange(x.size).reshape(x.shape)
y_base = np.arange(4*4, dtype=np.int8).reshape(4, 4)
y_base_copy = y_base.copy()
y = y_base[::2,:,None]

it = np.nditer([y, x],
['buffered', 'external_loop', 'reduce_ok'],
[['readwrite'], ['readonly']])
for a, b in it:
a.fill(2)

assert_equal(y_base[1::2], y_base_copy[1::2])
assert_equal(y_base[::2], 2)

def test_iter_buffering_reduction_reuse_reduce_loops():
# There was a bug triggering reuse of the reduce loop inappropriately,
# which caused processing to happen in unnecessarily small chunks
Expand Down
21 changes: 21 additions & 0 deletions numpy/core/tests/test_ufunc.py
Original file line number Diff line number Diff line change
Expand Up @@ -1257,6 +1257,27 @@ def test_NotImplemented_not_returned(self):
for f in binary_funcs:
assert_raises(TypeError, f, a, b)

def test_reduce_noncontig_output(self):
# Check that reduction deals with non-contiguous output arrays
# appropriately.
#
# gh-8036

x = np.arange(7*13*8, dtype=np.int16).reshape(7, 13, 8)
x = x[4:6,1:11:6,1:5].transpose(1, 2, 0)
y_base = np.arange(4*4, dtype=np.int16).reshape(4, 4)
y = y_base[::2,:]

y_base_copy = y_base.copy()

r0 = np.add.reduce(x, out=y.copy(), axis=2)
r1 = np.add.reduce(x, out=y, axis=2)

# The results should match, and y_base shouldn't get clobbered
assert_equal(r0, r1)
assert_equal(y_base[1,:], y_base_copy[1,:])
assert_equal(y_base[3,:], y_base_copy[3,:])


if __name__ == "__main__":
run_module_suite()

0 comments on commit 8d3673d

Please sign in to comment.