[pypy-commit] pypy ufuncapi: test broadcasting, add necessary but failing nditer itershape tests
mattip
noreply at buildbot.pypy.org
Sat Jan 10 22:55:33 CET 2015
Author: mattip <matti.picus at gmail.com>
Branch: ufuncapi
Changeset: r75293:a249b7e1b6ae
Date: 2015-01-10 23:55 +0200
http://bitbucket.org/pypy/pypy/changeset/a249b7e1b6ae/
Log: test broadcasting, add necessary but failing nditer itershape tests
diff --git a/pypy/module/micronumpy/test/test_nditer.py b/pypy/module/micronumpy/test/test_nditer.py
--- a/pypy/module/micronumpy/test/test_nditer.py
+++ b/pypy/module/micronumpy/test/test_nditer.py
@@ -167,7 +167,8 @@
exc = raises(TypeError, nditer, a, op_dtypes=['complex'])
assert str(exc.value).startswith("Iterator operand required copying or buffering")
exc = raises(ValueError, nditer, a, op_flags=['copy'], op_dtypes=['complex128'])
- assert str(exc.value) == "None of the iterator flags READWRITE, READONLY, or WRITEONLY were specified for an operand"
+ assert str(exc.value) == "None of the iterator flags READWRITE," \
+ " READONLY, or WRITEONLY were specified for an operand"
r = []
for x in nditer(a, op_flags=['readonly','copy'],
op_dtypes=['complex128']):
@@ -320,3 +321,34 @@
assert res == [(0, (0, 0)), (1, (0, 1)),
(2, (0, 2)), (3, (1, 0)),
(4, (1, 1)), (5, (1, 2))]
+
+ def test_itershape(self):
+ # Check that allocated outputs work with a specified shape
+ from numpy import nditer, arange
+ a = arange(6, dtype='i2').reshape(2,3)
+ i = nditer([a, None], [], [['readonly'], ['writeonly','allocate']],
+ op_axes=[[0,1,None], None],
+ itershape=(-1,-1,4))
+ assert_equal(i.operands[1].shape, (2,3,4))
+ assert_equal(i.operands[1].strides, (24,8,2))
+
+ i = nditer([a.T, None], [], [['readonly'], ['writeonly','allocate']],
+ op_axes=[[0,1,None], None],
+ itershape=(-1,-1,4))
+ assert_equal(i.operands[1].shape, (3,2,4))
+ assert_equal(i.operands[1].strides, (8,24,2))
+
+ i = nditer([a.T, None], [], [['readonly'], ['writeonly','allocate']],
+ order='F',
+ op_axes=[[0,1,None], None],
+ itershape=(-1,-1,4))
+ assert_equal(i.operands[1].shape, (3,2,4))
+ assert_equal(i.operands[1].strides, (2,6,12))
+
+ # If we specify 1 in the itershape, it shouldn't allow broadcasting
+ # of that dimension to a bigger value
+ assert_raises(ValueError, nditer, [a, None], [],
+ [['readonly'], ['writeonly','allocate']],
+ op_axes=[[0,1,None], None],
+ itershape=(-1,1,4))
+
diff --git a/pypy/module/micronumpy/test/test_ufuncs.py b/pypy/module/micronumpy/test/test_ufuncs.py
--- a/pypy/module/micronumpy/test/test_ufuncs.py
+++ b/pypy/module/micronumpy/test/test_ufuncs.py
@@ -245,6 +245,31 @@
ai2 = ufunc(ai)
assert (ai2 == ai * 2).all()
+ def test_frompyfunc_sig_broadcast(self):
+ def sum_along_0(in_array, out_array):
+ out_array[...] = in_array.sum(axis=0)
+
+ def add_two(in0, in1, out):
+ out[...] = in0 + in1
+
+ from numpy import frompyfunc, dtype, arange
+ ufunc_add = frompyfunc(add_two, 2, 1,
+ signature='(m,n),(m,n)->(m,n)',
+ dtypes=[dtype(int), dtype(int), dtype(int)],
+ stack_inputs=True,
+ )
+ ufunc_sum = frompyfunc([sum_along_0], 1, 1,
+ signature='(m,n)->(n)',
+ dtypes=[dtype(int), dtype(int)],
+ stack_inputs=True,
+ )
+ ai = arange(18, dtype=int).reshape(3,2,3)
+ aout = ufunc_add(ai, ai[0,:,:])
+ assert aout.shape == (3, 2, 3)
+ aout = ufunc_sum(ai)
+ assert aout.shape == (3, 3)
+
+
def test_ufunc_kwargs(self):
from numpy import ufunc, frompyfunc, arange, dtype
def adder(a, b):
diff --git a/pypy/module/micronumpy/ufuncs.py b/pypy/module/micronumpy/ufuncs.py
--- a/pypy/module/micronumpy/ufuncs.py
+++ b/pypy/module/micronumpy/ufuncs.py
@@ -869,7 +869,7 @@
self.name, name, _i, j, x, y)
iter_shape[offset + j] = max(x, y)
#print 'Find or verify signature ixs',self.core_dim_ixs,
- #print 'starting',dim_offset,'n',num_dims,'matching',dims_to_match
+ #print 'starting',dim_offset,'n',n,'num_dims',num_dims,'matching',dims_to_match
for j in range(num_dims):
core_dim_index = self.core_dim_ixs[dim_offset + j]
if core_dim_index > len(dims_to_match):
@@ -886,7 +886,13 @@
self.name, name, _i, j,
self.signature, matched_dims[core_dim_index],
dims_to_match[core_dim_index])
- arg_shapes.append(iter_shape + dims_to_match)
+ #print 'adding',iter_shape,'+',dims_to_match,'to arg_shapes'
+ if n < len(iter_shape):
+ #Broadcast over the len(iter_shape) - n dims of iter_shape
+ broadcast_dims = len(iter_shape) - n
+ arg_shapes.append(iter_shape[:-broadcast_dims] + [1] * broadcast_dims + dims_to_match)
+ else:
+ arg_shapes.append(iter_shape + dims_to_match)
# TODO once we support obejct dtypes,
# FAIL with NotImplementedError if the other object has
# the __r<op>__ method and has a higher priority than
More information about the pypy-commit
mailing list