[pypy-commit] pypy ufunc-reduce: Clean up shape handling in ufunc.accumulate()
rlamy
noreply at buildbot.pypy.org
Sun Aug 2 20:30:35 CEST 2015
Author: Ronan Lamy <ronan.lamy at gmail.com>
Branch: ufunc-reduce
Changeset: r78749:8586b501eab6
Date: 2015-08-02 19:30 +0100
http://bitbucket.org/pypy/pypy/changeset/8586b501eab6/
Log: Clean up shape handling in ufunc.accumulate()
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
@@ -1338,6 +1338,26 @@
assert subtract.accumulate([True]*200).dtype == dtype('bool')
assert divide.accumulate([True]*200).dtype == dtype('int8')
+ def test_accumulate_shapes(self):
+ import numpy as np
+ a = np.arange(6).reshape(2, 1, 3)
+ assert np.add.accumulate(a).shape == (2, 1, 3)
+ raises(ValueError, "np.add.accumulate(a, out=np.zeros((3, 1, 3)))")
+ raises(ValueError, "np.add.accumulate(a, out=np.zeros((2, 3)))")
+ raises(ValueError, "np.add.accumulate(a, out=np.zeros((2, 3, 1)))")
+ b = np.zeros((2, 1, 3))
+ np.add.accumulate(a, out=b, axis=2)
+ assert b[0, 0, 2] == 3
+
+ def test_accumulate_shapes_2(self):
+ import sys
+ if '__pypy__' not in sys.builtin_module_names:
+ skip('PyPy-specific behavior in np.ufunc.accumulate')
+ import numpy as np
+ a = np.arange(6).reshape(2, 1, 3)
+ raises(ValueError, "np.add.accumulate(a, out=np.zeros((2, 1, 3, 2)))")
+
+
def test_noncommutative_reduce_accumulate(self):
import numpy as np
tosubtract = np.arange(5)
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
@@ -247,33 +247,25 @@
axis = axes[0]
assert axis >= 0
dtype = self.find_binop_type(space, dtype)
- call__array_wrap__ = True
+ shape = obj_shape[:]
+ if out:
+ # There appears to be a lot of accidental complexity in what
+ # shapes cnumpy allows for out.
+ # We simply require out.shape == obj.shape
+ if out.get_shape() != obj_shape:
+ raise oefmt(space.w_ValueError,
+ "output parameter shape mismatch, expecting "
+ "[%s], got [%s]",
+ ",".join([str(x) for x in shape]),
+ ",".join([str(x) for x in out.get_shape()]),
+ )
+ dtype = out.get_dtype()
+ call__array_wrap__ = False
+ else:
+ out = W_NDimArray.from_shape(space, shape, dtype,
+ w_instance=obj)
+ call__array_wrap__ = True
if shapelen > 1:
- shape = obj_shape[:]
- if out:
- # Test for shape agreement
- # XXX maybe we need to do broadcasting here, although I must
- # say I don't understand the details for axis reduce
- if out.ndims() > len(shape):
- raise oefmt(space.w_ValueError,
- "output parameter for reduction operation %s "
- "has too many dimensions", self.name)
- elif out.ndims() < len(shape):
- raise oefmt(space.w_ValueError,
- "output parameter for reduction operation %s "
- "does not have enough dimensions", self.name)
- elif out.get_shape() != shape:
- raise oefmt(space.w_ValueError,
- "output parameter shape mismatch, expecting "
- "[%s], got [%s]",
- ",".join([str(x) for x in shape]),
- ",".join([str(x) for x in out.get_shape()]),
- )
- call__array_wrap__ = False
- dtype = out.get_dtype()
- else:
- out = W_NDimArray.from_shape(space, shape, dtype,
- w_instance=obj)
if obj.get_size() == 0:
if self.identity is not None:
out.fill(space, self.identity.convert_to(space, dtype))
@@ -281,14 +273,6 @@
loop.do_accumulate(space, self.func, obj, dtype, axis,
out, self.identity)
else:
- if out:
- call__array_wrap__ = False
- if out.get_shape() != [obj.get_size()]:
- raise OperationError(space.w_ValueError, space.wrap(
- "out of incompatible size"))
- else:
- out = W_NDimArray.from_shape(space, [obj.get_size()], dtype,
- w_instance=obj)
loop.compute_reduce_cumulative(space, obj, out, dtype, self.func,
self.identity)
if call__array_wrap__:
More information about the pypy-commit
mailing list