[pypy-commit] pypy default: Max numpy.array.{max, min} use the maximum/minimum ufuncs.
alex_gaynor
noreply at buildbot.pypy.org
Wed Aug 31 03:45:01 CEST 2011
Author: Alex Gaynor <alex.gaynor at gmail.com>
Branch:
Changeset: r46935:2e6d40cabec2
Date: 2011-08-30 21:44 -0400
http://bitbucket.org/pypy/pypy/changeset/2e6d40cabec2/
Log: Max numpy.array.{max,min} use the maximum/minimum ufuncs.
diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py
--- a/pypy/module/micronumpy/interp_numarray.py
+++ b/pypy/module/micronumpy/interp_numarray.py
@@ -97,29 +97,8 @@
descr_sum = _reduce_ufunc_impl("add")
descr_prod = _reduce_ufunc_impl("multiply")
-
- def _reduce_max_min_impl(op_name):
- reduce_driver = jit.JitDriver(greens=['signature'],
- reds = ['i', 'size', 'self', 'result', 'dtype'])
- def loop(self, result, size):
- i = 1
- dtype = self.find_dtype()
- while i < size:
- reduce_driver.jit_merge_point(signature=self.signature,
- self=self, dtype=dtype,
- size=size, i=i, result=result)
- result = getattr(dtype, op_name)(result, self.eval(i))
- i += 1
- return result
-
- def impl(self, space):
- size = self.find_size()
- if size == 0:
- raise OperationError(space.w_ValueError,
- space.wrap("Can't call %s on zero-size arrays" \
- % op_name))
- return loop(self, self.eval(0), size).wrap(space)
- return func_with_new_name(impl, "reduce_%s_impl" % op_name)
+ descr_max = _reduce_ufunc_impl("maximum")
+ descr_min = _reduce_ufunc_impl("minimum")
def _reduce_argmax_argmin_impl(op_name):
reduce_driver = jit.JitDriver(greens=['signature'],
@@ -175,8 +154,6 @@
def descr_any(self, space):
return space.wrap(self._any())
- descr_max = _reduce_max_min_impl("max")
- descr_min = _reduce_max_min_impl("min")
descr_argmax = _reduce_argmax_argmin_impl("max")
descr_argmin = _reduce_argmax_argmin_impl("min")
diff --git a/pypy/module/micronumpy/interp_ufuncs.py b/pypy/module/micronumpy/interp_ufuncs.py
--- a/pypy/module/micronumpy/interp_ufuncs.py
+++ b/pypy/module/micronumpy/interp_ufuncs.py
@@ -1,5 +1,5 @@
from pypy.interpreter.baseobjspace import Wrappable
-from pypy.interpreter.error import OperationError
+from pypy.interpreter.error import OperationError, operationerrfmt
from pypy.interpreter.gateway import interp2app
from pypy.interpreter.typedef import TypeDef, GetSetProperty, interp_attrproperty
from pypy.module.micronumpy import interp_dtype, signature
@@ -41,28 +41,36 @@
from pypy.module.micronumpy.interp_numarray import convert_to_array, Scalar
if self.argcount != 2:
- raise OperationError(space.w_ValueError, space.wrap("reduce only supported for binary functions"))
- if self.identity is None:
- raise OperationError(space.w_NotImplementedError, space.wrap("%s is missing its identity value" % self.name))
+ raise OperationError(space.w_ValueError, space.wrap("reduce only "
+ "supported for binary functions"))
assert isinstance(self, W_Ufunc2)
obj = convert_to_array(space, w_obj)
if isinstance(obj, Scalar):
- raise OperationError(space.w_TypeError, space.wrap("cannot reduce on a scalar"))
+ raise OperationError(space.w_TypeError, space.wrap("cannot reduce "
+ "on a scalar"))
size = obj.find_size()
dtype = find_unaryop_result_dtype(
space, obj.find_dtype(),
promote_to_largest=True
)
- value = self.identity.convert_to(dtype)
+ start = 0
+ if self.identity is None:
+ if size == 0:
+ raise operationerrfmt(space.w_ValueError, "zero-size array to "
+ "%s.reduce without identity", self.name)
+ value = obj.eval(0).convert_to(dtype)
+ start += 1
+ else:
+ value = self.identity.convert_to(dtype)
new_sig = signature.Signature.find_sig([
self.reduce_signature, obj.signature
])
- return self.reduce(new_sig, value, obj, dtype, size).wrap(space)
+ return self.reduce(new_sig, start, value, obj, dtype, size).wrap(space)
- def reduce(self, signature, value, obj, dtype, size):
- i = 0
+ def reduce(self, signature, start, value, obj, dtype, size):
+ i = start
while i < size:
reduce_driver.jit_merge_point(signature=signature, self=self,
value=value, obj=obj, i=i,
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
@@ -305,6 +305,9 @@
raises(TypeError, add.reduce, 1)
def test_reduce(self):
- from numpy import add
+ from numpy import add, maximum
- assert add.reduce([1, 2, 3]) == 6
\ No newline at end of file
+ assert add.reduce([1, 2, 3]) == 6
+ assert maximum.reduce([1]) == 1
+ assert maximum.reduce([1, 2, 3]) == 3
+ raises(ValueError, maximum.reduce, [])
\ No newline at end of file
diff --git a/pypy/module/micronumpy/test/test_zjit.py b/pypy/module/micronumpy/test/test_zjit.py
--- a/pypy/module/micronumpy/test/test_zjit.py
+++ b/pypy/module/micronumpy/test/test_zjit.py
@@ -90,14 +90,21 @@
def test_max(self):
space = self.space
float64_dtype = self.float64_dtype
+ int64_dtype = self.int64_dtype
def f(i):
- ar = SingleDimArray(i, dtype=NonConstant(float64_dtype))
+ if NonConstant(False):
+ dtype = int64_dtype
+ else:
+ dtype = float64_dtype
+ ar = SingleDimArray(i, dtype=dtype)
j = 0
while j < i:
ar.get_concrete().setitem(j, float64_dtype.box(float(j)))
j += 1
- return ar.descr_add(space, ar).descr_max(space).floatval
+ v = ar.descr_add(space, ar).descr_max(space)
+ assert isinstance(v, FloatObject)
+ return v.floatval
result = self.meta_interp(f, [5], listops=True, backendopt=True)
self.check_loops({"getarrayitem_raw": 2, "float_add": 1,
@@ -109,14 +116,21 @@
def test_min(self):
space = self.space
float64_dtype = self.float64_dtype
+ int64_dtype = self.int64_dtype
def f(i):
- ar = SingleDimArray(i, dtype=NonConstant(float64_dtype))
+ if NonConstant(False):
+ dtype = int64_dtype
+ else:
+ dtype = float64_dtype
+ ar = SingleDimArray(i, dtype=dtype)
j = 0
while j < i:
ar.get_concrete().setitem(j, float64_dtype.box(float(j)))
j += 1
- return ar.descr_add(space, ar).descr_min(space).floatval
+ v = ar.descr_add(space, ar).descr_min(space)
+ assert isinstance(v, FloatObject)
+ return v.floatval
result = self.meta_interp(f, [5], listops=True, backendopt=True)
self.check_loops({"getarrayitem_raw": 2, "float_add": 1,
More information about the pypy-commit
mailing list