Author: Brian Kearns <[email protected]>
Branch:
Changeset: r69208:53eef9736a3b
Date: 2014-02-19 12:41 -0500
http://bitbucket.org/pypy/pypy/changeset/53eef9736a3b/
Log: fix promote_to_largest in ufuncs (issue1663)
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
@@ -964,8 +964,7 @@
# ----------------------- reduce -------------------------------
- def _reduce_ufunc_impl(ufunc_name, promote_to_largest=False,
- cumulative=False):
+ def _reduce_ufunc_impl(ufunc_name, cumulative=False):
@unwrap_spec(keepdims=bool)
def impl(self, space, w_axis=None, w_dtype=None, w_out=None,
keepdims=False):
if space.is_none(w_out):
@@ -976,13 +975,11 @@
else:
out = w_out
return getattr(interp_ufuncs.get(space), ufunc_name).reduce(
- space, self, promote_to_largest, w_axis,
- keepdims, out, w_dtype, cumulative=cumulative)
- return func_with_new_name(impl, "reduce_%s_impl_%d_%d" % (ufunc_name,
- promote_to_largest, cumulative))
+ space, self, w_axis, keepdims, out, w_dtype,
cumulative=cumulative)
+ return func_with_new_name(impl, "reduce_%s_impl_%d" % (ufunc_name,
cumulative))
- descr_sum = _reduce_ufunc_impl("add", True)
- descr_prod = _reduce_ufunc_impl("multiply", True)
+ descr_sum = _reduce_ufunc_impl("add")
+ descr_prod = _reduce_ufunc_impl("multiply")
descr_max = _reduce_ufunc_impl("maximum")
descr_min = _reduce_ufunc_impl("minimum")
descr_all = _reduce_ufunc_impl('logical_and')
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
@@ -19,12 +19,15 @@
class W_Ufunc(W_Root):
- _immutable_fields_ = ["name", "promote_to_float", "promote_bools",
"identity",
- "int_only", "allow_bool", "allow_complex", "complex_to_float"]
+ _immutable_fields_ = [
+ "name", "promote_to_largest", "promote_to_float", "promote_bools",
+ "identity", "int_only", "allow_bool", "allow_complex",
"complex_to_float"
+ ]
- def __init__(self, name, promote_to_float, promote_bools, identity,
- int_only, allow_bool, allow_complex, complex_to_float):
+ def __init__(self, name, promote_to_largest, promote_to_float,
promote_bools,
+ identity, int_only, allow_bool, allow_complex,
complex_to_float):
self.name = name
+ self.promote_to_largest = promote_to_largest
self.promote_to_float = promote_to_float
self.promote_bools = promote_bools
self.identity = identity
@@ -88,9 +91,8 @@
'output must be an array'))
else:
out = w_out
- return self.reduce(space, w_obj, False, #do not promote_to_largest
- w_axis, True, #keepdims must be true
- out, w_dtype, cumulative=True)
+ return self.reduce(space, w_obj, w_axis, True, #keepdims must be true
+ out, w_dtype, cumulative=True)
@unwrap_spec(skipna=bool, keepdims=bool)
def descr_reduce(self, space, w_obj, w_axis=None, w_dtype=None,
@@ -154,15 +156,13 @@
out = None
elif not isinstance(w_out, W_NDimArray):
raise OperationError(space.w_TypeError, space.wrap(
- 'output must be an array'))
+ 'output must be an array'))
else:
out = w_out
- promote_to_largest = False
- return self.reduce(space, w_obj, promote_to_largest, w_axis, keepdims,
out,
- w_dtype)
+ return self.reduce(space, w_obj, w_axis, keepdims, out, w_dtype)
- def reduce(self, space, w_obj, promote_to_largest, w_axis,
- keepdims=False, out=None, dtype=None, cumulative=False):
+ def reduce(self, space, w_obj, w_axis, keepdims=False, out=None,
dtype=None,
+ cumulative=False):
if self.argcount != 2:
raise OperationError(space.w_ValueError, space.wrap("reduce only "
"supported for binary functions"))
@@ -185,7 +185,7 @@
dtype = find_unaryop_result_dtype(
space, obj.get_dtype(),
promote_to_float=self.promote_to_float,
- promote_to_largest=promote_to_largest,
+ promote_to_largest=self.promote_to_largest,
promote_bools=True
)
if self.identity is None:
@@ -263,18 +263,18 @@
return self._outer(space, __args__)
def _outer(self, space, __args__):
- raise OperationError(space.w_ValueError,
- space.wrap("outer product only supported for
binary functions"))
+ raise OperationError(space.w_ValueError, space.wrap(
+ "outer product only supported for binary functions"))
class W_Ufunc1(W_Ufunc):
_immutable_fields_ = ["func", "bool_result"]
argcount = 1
- def __init__(self, func, name, promote_to_float=False, promote_bools=False,
- identity=None, bool_result=False, int_only=False,
+ def __init__(self, func, name, promote_to_largest=False,
promote_to_float=False,
+ promote_bools=False, identity=None, bool_result=False,
int_only=False,
allow_bool=True, allow_complex=True, complex_to_float=False):
- W_Ufunc.__init__(self, name, promote_to_float, promote_bools, identity,
- int_only, allow_bool, allow_complex, complex_to_float)
+ W_Ufunc.__init__(self, name, promote_to_largest, promote_to_float,
promote_bools,
+ identity, int_only, allow_bool, allow_complex,
complex_to_float)
self.func = func
self.bool_result = bool_result
@@ -336,11 +336,11 @@
_immutable_fields_ = ["func", "comparison_func", "done_func"]
argcount = 2
- def __init__(self, func, name, promote_to_float=False, promote_bools=False,
- identity=None, comparison_func=False, int_only=False,
+ def __init__(self, func, name, promote_to_largest=False,
promote_to_float=False,
+ promote_bools=False, identity=None, comparison_func=False,
int_only=False,
allow_bool=True, allow_complex=True, complex_to_float=False):
- W_Ufunc.__init__(self, name, promote_to_float, promote_bools, identity,
- int_only, allow_bool, allow_complex, complex_to_float)
+ W_Ufunc.__init__(self, name, promote_to_largest, promote_to_float,
promote_bools,
+ identity, int_only, allow_bool, allow_complex,
complex_to_float)
self.func = func
self.comparison_func = comparison_func
if name == 'logical_and':
@@ -606,9 +606,9 @@
def __init__(self, space):
"NOT_RPYTHON"
for ufunc_def in [
- ("add", "add", 2, {"identity": 0}),
+ ("add", "add", 2, {"identity": 0, "promote_to_largest": True}),
("subtract", "sub", 2),
- ("multiply", "mul", 2, {"identity": 1}),
+ ("multiply", "mul", 2, {"identity": 1, "promote_to_largest":
True}),
("bitwise_and", "bitwise_and", 2, {"identity": 1,
"int_only": True}),
("bitwise_or", "bitwise_or", 2, {"identity": 0,
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
@@ -756,7 +756,7 @@
raises(ValueError, maximum.reduce, zeros((2, 0)), axis=1)
def test_reduce_1d(self):
- from numpypy import add, maximum, less
+ from numpypy import array, add, maximum, less, float16, complex64
assert less.reduce([5, 4, 3, 2, 1])
assert add.reduce([1, 2, 3]) == 6
@@ -764,6 +764,12 @@
assert maximum.reduce([1, 2, 3]) == 3
raises(ValueError, maximum.reduce, [])
+ assert add.reduce(array([True, False] * 200)) == 200
+ assert add.reduce(array([True, False] * 200, dtype='int8')) == 200
+ assert add.reduce(array([True, False] * 200), dtype='int8') == -56
+ assert type(add.reduce(array([True, False] * 200, dtype='float16')))
is float16
+ assert type(add.reduce(array([True, False] * 200, dtype='complex64')))
is complex64
+
def test_reduceND(self):
from numpypy import add, arange
a = arange(12).reshape(3, 4)
@@ -1025,7 +1031,7 @@
assert logaddexp2(float('inf'), float('inf')) == float('inf')
def test_accumulate(self):
- from numpypy import add, multiply, arange
+ from numpypy import add, multiply, arange, dtype
assert (add.accumulate([2, 3, 5]) == [2, 5, 10]).all()
assert (multiply.accumulate([2, 3, 5]) == [2, 6, 30]).all()
a = arange(4).reshape(2,2)
@@ -1041,6 +1047,8 @@
print b
assert (b == [[0, 0, 1], [1, 3, 5]]).all()
assert b.dtype == int
+ assert add.accumulate([True]*200)[-1] == 200
+ assert add.accumulate([True]*200).dtype == dtype('int')
def test_noncommutative_reduce_accumulate(self):
import numpypy as np
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit