Author: Ronan Lamy <[email protected]>
Branch: ufunc-reduce
Changeset: r78646:4db3dee7c611
Date: 2015-07-24 03:24 +0100
http://bitbucket.org/pypy/pypy/changeset/4db3dee7c611/
Log: Split accumulate and reduce code paths in W_Ufunc.reduce()
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
@@ -300,20 +300,66 @@
if variant == ACCUMULATE:
dtype = self.find_binop_type(space, dtype)
- else:
- _, dtype, _ = self.find_specialization(space, dtype, dtype, out,
- casting='unsafe')
- call__array_wrap__ = True
- if shapelen > 1 and axis < shapelen:
- temp = None
- if variant == ACCUMULATE:
+ call__array_wrap__ = True
+ if shapelen > 1 and axis < shapelen:
+ temp = None
shape = obj_shape[:]
temp_shape = obj_shape[:axis] + obj_shape[axis + 1:]
if out:
dtype = out.get_dtype()
temp = W_NDimArray.from_shape(space, temp_shape, dtype,
- w_instance=obj)
- elif keepdims:
+ w_instance=obj)
+ 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))
+ return out
+ loop.do_accumulate(space, shape, self.func, obj, dtype, axis,
+ out, self.identity, temp)
+ 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__:
+ out = space.call_method(obj, '__array_wrap__', out)
+ return out
+
+ _, dtype, _ = self.find_specialization(space, dtype, dtype, out,
+ casting='unsafe')
+ call__array_wrap__ = True
+ if shapelen > 1 and axis < shapelen:
+ temp = None
+ if keepdims:
shape = obj_shape[:axis] + [1] + obj_shape[axis + 1:]
else:
shape = obj_shape[:axis] + obj_shape[axis + 1:]
@@ -345,26 +391,8 @@
if self.identity is not None:
out.fill(space, self.identity.convert_to(space, dtype))
return out
- if variant == REDUCE:
- loop.do_axis_reduce(space, shape, self.func, obj, dtype, axis,
- out, self.identity)
- elif variant == ACCUMULATE:
- loop.do_accumulate(space, shape, self.func, obj, dtype, axis,
- out, self.identity, temp)
- if call__array_wrap__:
- out = space.call_method(obj, '__array_wrap__', out)
- return out
- if variant == ACCUMULATE:
- 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)
+ loop.do_axis_reduce(space, shape, self.func, obj, dtype, axis,
+ out, self.identity)
if call__array_wrap__:
out = space.call_method(obj, '__array_wrap__', out)
return out
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit