Author: Brian Kearns <bdkea...@gmail.com> 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 pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit