[pypy-commit] pypy numpypy-out: add more ufunc tests, try an implementation
mattip
noreply at buildbot.pypy.org
Tue Feb 14 22:13:33 CET 2012
Author: mattip
Branch: numpypy-out
Changeset: r52477:08b7ccd7985e
Date: 2012-02-14 22:46 +0200
http://bitbucket.org/pypy/pypy/changeset/08b7ccd7985e/
Log: add more ufunc tests, try an implementation
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
@@ -35,6 +35,7 @@
kwds_w.pop('casting', None)
w_subok = kwds_w.pop('subok', None)
w_out = kwds_w.pop('out', space.w_None)
+ # Setup a default value for out
if space.is_w(w_out, space.w_None):
out = None
else:
@@ -46,13 +47,17 @@
raise OperationError(space.w_ValueError,
space.wrap("invalid number of arguments")
)
- elif len(args_w) > self.argcount:
+ elif (len(args_w) > self.argcount and out is not None) or \
+ (len(args_w) > self.argcount + 1):
raise OperationError(space.w_TypeError,
space.wrap("invalid number of arguments")
)
- elif out is not None:
+ # Override the default out value, if it has been provided in w_wargs
+ if len(args_w) > self.argcount:
+ out = args_w[-1]
+ else:
args_w = args_w[:] + [out]
- if args_w[-1] and not isinstance(args_w[-1], BaseArray):
+ if out is not None and not isinstance(out, BaseArray):
raise OperationError(space.w_TypeError, space.wrap(
'output must be an array'))
return self.call(space, args_w)
@@ -223,23 +228,34 @@
def call(self, space, args_w):
from pypy.module.micronumpy.interp_numarray import (Call1,
- convert_to_array, Scalar)
+ convert_to_array, Scalar, shape_agreement)
- [w_obj, w_out] = args_w
+ if len(args_w)<2:
+ [w_obj] = args_w
+ out = None
+ else:
+ [w_obj, out] = args_w
w_obj = convert_to_array(space, w_obj)
calc_dtype = find_unaryop_result_dtype(space,
w_obj.find_dtype(),
promote_to_float=self.promote_to_float,
promote_bools=self.promote_bools)
- if self.bool_result:
+ if out:
+ ret_shape = shape_agreement(space, w_obj.shape, out.shape)
+ assert(ret_shape is not None)
+ res_dtype = out.find_dtype()
+ elif self.bool_result:
res_dtype = interp_dtype.get_dtype_cache(space).w_booldtype
else:
res_dtype = calc_dtype
if isinstance(w_obj, Scalar):
- return space.wrap(self.func(calc_dtype, w_obj.value.convert_to(calc_dtype)))
+ arr = self.func(calc_dtype, w_obj.value.convert_to(calc_dtype))
+ if isinstance(out,Scalar):
+ out.value=arr
+ return space.wrap(out)
w_res = Call1(self.func, self.name, w_obj.shape, calc_dtype, res_dtype,
- w_obj)
+ w_obj, out)
w_obj.add_invalidates(w_res)
return w_res
@@ -259,11 +275,14 @@
def call(self, space, args_w):
from pypy.module.micronumpy.interp_numarray import (Call2,
convert_to_array, Scalar, shape_agreement, BaseArray)
-
- [w_lhs, w_rhs, w_out] = args_w
+ if len(args_w)>2:
+ [w_lhs, w_rhs, w_out] = args_w
+ else:
+ [w_lhs, w_rhs] = args_w
+ w_out = None
w_lhs = convert_to_array(space, w_lhs)
w_rhs = convert_to_array(space, w_rhs)
- if space.is_w(w_out, space.w_None) or not w_out:
+ if space.is_w(w_out, space.w_None) or w_out is None:
out = None
calc_dtype = find_binop_result_dtype(space,
w_lhs.find_dtype(), w_rhs.find_dtype(),
diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py
--- a/pypy/module/micronumpy/test/test_numarray.py
+++ b/pypy/module/micronumpy/test/test_numarray.py
@@ -902,35 +902,6 @@
assert (array([[1,2],[3,4]]).prod(0) == [3, 8]).all()
assert (array([[1,2],[3,4]]).prod(1) == [2, 12]).all()
- def test_reduce_out(self):
- from numpypy import arange, zeros, array
- a = arange(15).reshape(5, 3)
- b = arange(12).reshape(4,3)
- c = a.sum(0, out=b[1])
- assert (c == [30, 35, 40]).all()
- assert (c == b[1]).all()
- raises(ValueError, 'a.prod(0, out=arange(10))')
- a=arange(12).reshape(3,2,2)
- raises(ValueError, 'a.sum(0, out=arange(12).reshape(3,2,2))')
- raises(ValueError, 'a.sum(0, out=arange(3))')
- c = array([-1, 0, 1]).sum(out=zeros([], dtype=bool))
- #You could argue that this should product False, but
- # that would require an itermediate result. Cpython numpy
- # gives True.
- assert c == True
- a = array([[-1, 0, 1], [1, 0, -1]])
- c = a.sum(0, out=zeros((3,), dtype=bool))
- assert (c == [True, False, True]).all()
- c = a.sum(1, out=zeros((2,), dtype=bool))
- assert (c == [True, True]).all()
-
- def test_reduce_intermediary(self):
- from numpypy import arange, array
- a = arange(15).reshape(5, 3)
- b = array(range(3), dtype=bool)
- c = a.prod(0, out=b)
- assert(b == [False, True, True]).all()
-
def test_identity(self):
from _numpypy import identity, array
from _numpypy import int32, float64, dtype
diff --git a/pypy/module/micronumpy/test/test_outarg.py b/pypy/module/micronumpy/test/test_outarg.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/micronumpy/test/test_outarg.py
@@ -0,0 +1,48 @@
+import py
+from pypy.module.micronumpy.test.test_base import BaseNumpyAppTest
+
+class AppTestOutArg(BaseNumpyAppTest):
+ def test_reduce_out(self):
+ from numpypy import arange, zeros, array
+ a = arange(15).reshape(5, 3)
+ b = arange(12).reshape(4,3)
+ c = a.sum(0, out=b[1])
+ assert (c == [30, 35, 40]).all()
+ assert (c == b[1]).all()
+ raises(ValueError, 'a.prod(0, out=arange(10))')
+ a=arange(12).reshape(3,2,2)
+ raises(ValueError, 'a.sum(0, out=arange(12).reshape(3,2,2))')
+ raises(ValueError, 'a.sum(0, out=arange(3))')
+ c = array([-1, 0, 1]).sum(out=zeros([], dtype=bool))
+ #You could argue that this should product False, but
+ # that would require an itermediate result. Cpython numpy
+ # gives True.
+ assert c == True
+ a = array([[-1, 0, 1], [1, 0, -1]])
+ c = a.sum(0, out=zeros((3,), dtype=bool))
+ assert (c == [True, False, True]).all()
+ c = a.sum(1, out=zeros((2,), dtype=bool))
+ assert (c == [True, True]).all()
+
+ def test_reduce_intermediary(self):
+ from numpypy import arange, array
+ a = arange(15).reshape(5, 3)
+ b = array(range(3), dtype=bool)
+ c = a.prod(0, out=b)
+ assert(b == [False, True, True]).all()
+
+ def test_ufunc_out(self):
+ from _numpypy import array, negative, zeros
+ a = array([[1, 2], [3, 4]])
+ c = zeros((2,2,2))
+ b = negative(a + a, out=c[1])
+ assert (b == [[-2, -4], [-6, -8]]).all()
+ assert (c[:, :, 1] == [[0, 0], [-4, -8]]).all()
+
+ def test_ufunc_cast(self):
+ from _numpypy import array, negative
+ cast_error = raises(TypeError, negative, array(16,dtype=float),
+ out=array(0, dtype=int))
+ assert str(cast_error.value) == \
+ "Cannot cast ufunc negative output from dtype('float64') to dtype('int64') with casting rule 'same_kind'"
+
More information about the pypy-commit
mailing list