[pypy-commit] pypy set-strategies: hg merge default
arigo
noreply at buildbot.pypy.org
Mon Mar 26 19:40:32 CEST 2012
Author: Armin Rigo <arigo at tunes.org>
Branch: set-strategies
Changeset: r54003:83af076f86a8
Date: 2012-03-26 19:39 +0200
http://bitbucket.org/pypy/pypy/changeset/83af076f86a8/
Log: hg merge default
diff --git a/lib-python/modified-2.7/test/test_set.py b/lib-python/modified-2.7/test/test_set.py
--- a/lib-python/modified-2.7/test/test_set.py
+++ b/lib-python/modified-2.7/test/test_set.py
@@ -1568,7 +1568,7 @@
for meth in (s.union, s.intersection, s.difference, s.symmetric_difference, s.isdisjoint):
for g in (G, I, Ig, L, R):
expected = meth(data)
- actual = meth(G(data))
+ actual = meth(g(data))
if isinstance(expected, bool):
self.assertEqual(actual, expected)
else:
diff --git a/pypy/interpreter/astcompiler/test/test_astbuilder.py b/pypy/interpreter/astcompiler/test/test_astbuilder.py
--- a/pypy/interpreter/astcompiler/test/test_astbuilder.py
+++ b/pypy/interpreter/astcompiler/test/test_astbuilder.py
@@ -10,16 +10,6 @@
from pypy.interpreter.astcompiler import ast, consts
-try:
- all
-except NameError:
- def all(iterable):
- for x in iterable:
- if not x:
- return False
- return True
-
-
class TestAstBuilder:
def setup_class(cls):
diff --git a/pypy/module/micronumpy/app_numpy.py b/pypy/module/micronumpy/app_numpy.py
--- a/pypy/module/micronumpy/app_numpy.py
+++ b/pypy/module/micronumpy/app_numpy.py
@@ -16,7 +16,7 @@
a[i][i] = 1
return a
-def sum(a,axis=None):
+def sum(a,axis=None, out=None):
'''sum(a, axis=None)
Sum of array elements over a given axis.
@@ -43,17 +43,17 @@
# TODO: add to doc (once it's implemented): cumsum : Cumulative sum of array elements.
if not hasattr(a, "sum"):
a = _numpypy.array(a)
- return a.sum(axis)
+ return a.sum(axis=axis, out=out)
-def min(a, axis=None):
+def min(a, axis=None, out=None):
if not hasattr(a, "min"):
a = _numpypy.array(a)
- return a.min(axis)
+ return a.min(axis=axis, out=out)
-def max(a, axis=None):
+def max(a, axis=None, out=None):
if not hasattr(a, "max"):
a = _numpypy.array(a)
- return a.max(axis)
+ return a.max(axis=axis, out=out)
def arange(start, stop=None, step=1, dtype=None):
'''arange([start], stop[, step], dtype=None)
diff --git a/pypy/module/micronumpy/interp_boxes.py b/pypy/module/micronumpy/interp_boxes.py
--- a/pypy/module/micronumpy/interp_boxes.py
+++ b/pypy/module/micronumpy/interp_boxes.py
@@ -62,21 +62,24 @@
return space.wrap(dtype.itemtype.bool(self))
def _binop_impl(ufunc_name):
- def impl(self, space, w_other):
+ def impl(self, space, w_other, w_out=None):
from pypy.module.micronumpy import interp_ufuncs
- return getattr(interp_ufuncs.get(space), ufunc_name).call(space, [self, w_other])
+ return getattr(interp_ufuncs.get(space), ufunc_name).call(space,
+ [self, w_other, w_out])
return func_with_new_name(impl, "binop_%s_impl" % ufunc_name)
def _binop_right_impl(ufunc_name):
- def impl(self, space, w_other):
+ def impl(self, space, w_other, w_out=None):
from pypy.module.micronumpy import interp_ufuncs
- return getattr(interp_ufuncs.get(space), ufunc_name).call(space, [w_other, self])
+ return getattr(interp_ufuncs.get(space), ufunc_name).call(space,
+ [w_other, self, w_out])
return func_with_new_name(impl, "binop_right_%s_impl" % ufunc_name)
def _unaryop_impl(ufunc_name):
- def impl(self, space):
+ def impl(self, space, w_out=None):
from pypy.module.micronumpy import interp_ufuncs
- return getattr(interp_ufuncs.get(space), ufunc_name).call(space, [self])
+ return getattr(interp_ufuncs.get(space), ufunc_name).call(space,
+ [self, w_out])
return func_with_new_name(impl, "unaryop_%s_impl" % ufunc_name)
descr_add = _binop_impl("add")
diff --git a/pypy/module/micronumpy/interp_iter.py b/pypy/module/micronumpy/interp_iter.py
--- a/pypy/module/micronumpy/interp_iter.py
+++ b/pypy/module/micronumpy/interp_iter.py
@@ -269,7 +269,7 @@
def apply_transformations(self, arr, transformations):
v = BaseIterator.apply_transformations(self, arr, transformations)
- if len(arr.shape) == 1:
+ if len(arr.shape) == 1 and len(v.res_shape) == 1:
return OneDimIterator(self.offset, self.strides[0],
self.res_shape[0])
return v
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
@@ -83,8 +83,9 @@
return space.wrap(W_NDimArray(shape[:], dtype=dtype))
def _unaryop_impl(ufunc_name):
- def impl(self, space):
- return getattr(interp_ufuncs.get(space), ufunc_name).call(space, [self])
+ def impl(self, space, w_out=None):
+ return getattr(interp_ufuncs.get(space), ufunc_name).call(space,
+ [self, w_out])
return func_with_new_name(impl, "unaryop_%s_impl" % ufunc_name)
descr_pos = _unaryop_impl("positive")
@@ -93,8 +94,9 @@
descr_invert = _unaryop_impl("invert")
def _binop_impl(ufunc_name):
- def impl(self, space, w_other):
- return getattr(interp_ufuncs.get(space), ufunc_name).call(space, [self, w_other])
+ def impl(self, space, w_other, w_out=None):
+ return getattr(interp_ufuncs.get(space), ufunc_name).call(space,
+ [self, w_other, w_out])
return func_with_new_name(impl, "binop_%s_impl" % ufunc_name)
descr_add = _binop_impl("add")
@@ -124,12 +126,12 @@
return space.newtuple([w_quotient, w_remainder])
def _binop_right_impl(ufunc_name):
- def impl(self, space, w_other):
+ def impl(self, space, w_other, w_out=None):
w_other = scalar_w(space,
interp_ufuncs.find_dtype_for_scalar(space, w_other, self.find_dtype()),
w_other
)
- return getattr(interp_ufuncs.get(space), ufunc_name).call(space, [w_other, self])
+ return getattr(interp_ufuncs.get(space), ufunc_name).call(space, [w_other, self, w_out])
return func_with_new_name(impl, "binop_right_%s_impl" % ufunc_name)
descr_radd = _binop_right_impl("add")
@@ -152,13 +154,21 @@
return space.newtuple([w_quotient, w_remainder])
def _reduce_ufunc_impl(ufunc_name, promote_to_largest=False):
- def impl(self, space, w_axis=None):
+ def impl(self, space, w_axis=None, w_out=None):
if space.is_w(w_axis, space.w_None):
axis = -1
else:
axis = space.int_w(w_axis)
+ if space.is_w(w_out, space.w_None) or not w_out:
+ out = None
+ elif not isinstance(w_out, BaseArray):
+ raise OperationError(space.w_TypeError, space.wrap(
+ 'output must be an array'))
+ else:
+ out = w_out
return getattr(interp_ufuncs.get(space), ufunc_name).reduce(space,
- self, True, promote_to_largest, axis)
+ self, True, promote_to_largest, axis,
+ False, out)
return func_with_new_name(impl, "reduce_%s_impl" % ufunc_name)
descr_sum = _reduce_ufunc_impl("add")
@@ -213,6 +223,7 @@
def descr_dot(self, space, w_other):
other = convert_to_array(space, w_other)
if isinstance(other, Scalar):
+ #Note: w_out is not modified, this is numpy compliant.
return self.descr_mul(space, other)
elif len(self.shape) < 2 and len(other.shape) < 2:
w_res = self.descr_mul(space, other)
@@ -514,14 +525,14 @@
)
return w_result
- def descr_mean(self, space, w_axis=None):
+ def descr_mean(self, space, w_axis=None, w_out=None):
if space.is_w(w_axis, space.w_None):
w_axis = space.wrap(-1)
w_denom = space.wrap(support.product(self.shape))
else:
dim = space.int_w(w_axis)
w_denom = space.wrap(self.shape[dim])
- return space.div(self.descr_sum_promote(space, w_axis), w_denom)
+ return space.div(self.descr_sum_promote(space, w_axis, w_out), w_denom)
def descr_var(self, space, w_axis=None):
return get_appbridge_cache(space).call_method(space, '_var', self,
@@ -714,11 +725,12 @@
"""
Class for representing virtual arrays, such as binary ops or ufuncs
"""
- def __init__(self, name, shape, res_dtype):
+ def __init__(self, name, shape, res_dtype, out_arg=None):
BaseArray.__init__(self, shape)
self.forced_result = None
self.res_dtype = res_dtype
self.name = name
+ self.res = out_arg
self.size = support.product(self.shape) * res_dtype.get_size()
def _del_sources(self):
@@ -727,13 +739,18 @@
raise NotImplementedError
def compute(self):
- ra = ResultArray(self, self.shape, self.res_dtype)
+ ra = ResultArray(self, self.shape, self.res_dtype, self.res)
loop.compute(ra)
+ if self.res:
+ broadcast_dims = len(self.res.shape) - len(self.shape)
+ chunks = [Chunk(0,0,0,0)] * broadcast_dims + \
+ [Chunk(0, i, 1, i) for i in self.shape]
+ return Chunks(chunks).apply(self.res)
return ra.left
def force_if_needed(self):
if self.forced_result is None:
- self.forced_result = self.compute()
+ self.forced_result = self.compute().get_concrete()
self._del_sources()
def get_concrete(self):
@@ -773,8 +790,9 @@
class Call1(VirtualArray):
- def __init__(self, ufunc, name, shape, calc_dtype, res_dtype, values):
- VirtualArray.__init__(self, name, shape, res_dtype)
+ def __init__(self, ufunc, name, shape, calc_dtype, res_dtype, values,
+ out_arg=None):
+ VirtualArray.__init__(self, name, shape, res_dtype, out_arg)
self.values = values
self.size = values.size
self.ufunc = ufunc
@@ -786,6 +804,12 @@
def create_sig(self):
if self.forced_result is not None:
return self.forced_result.create_sig()
+ if self.shape != self.values.shape:
+ #This happens if out arg is used
+ return signature.BroadcastUfunc(self.ufunc, self.name,
+ self.calc_dtype,
+ self.values.create_sig(),
+ self.res.create_sig())
return signature.Call1(self.ufunc, self.name, self.calc_dtype,
self.values.create_sig())
@@ -793,8 +817,9 @@
"""
Intermediate class for performing binary operations.
"""
- def __init__(self, ufunc, name, shape, calc_dtype, res_dtype, left, right):
- VirtualArray.__init__(self, name, shape, res_dtype)
+ def __init__(self, ufunc, name, shape, calc_dtype, res_dtype, left, right,
+ out_arg=None):
+ VirtualArray.__init__(self, name, shape, res_dtype, out_arg)
self.ufunc = ufunc
self.left = left
self.right = right
@@ -832,8 +857,13 @@
Call2.__init__(self, None, 'assign', shape, dtype, dtype, res, child)
def create_sig(self):
- return signature.ResultSignature(self.res_dtype, self.left.create_sig(),
- self.right.create_sig())
+ if self.left.shape != self.right.shape:
+ sig = signature.BroadcastResultSignature(self.res_dtype,
+ self.left.create_sig(), self.right.create_sig())
+ else:
+ sig = signature.ResultSignature(self.res_dtype,
+ self.left.create_sig(), self.right.create_sig())
+ return sig
class ToStringArray(Call1):
def __init__(self, child):
@@ -842,9 +872,9 @@
self.s = StringBuilder(child.size * self.item_size)
Call1.__init__(self, None, 'tostring', child.shape, dtype, dtype,
child)
- self.res = W_NDimArray([1], dtype, 'C')
- self.res_casted = rffi.cast(rffi.CArrayPtr(lltype.Char),
- self.res.storage)
+ self.res_str = W_NDimArray([1], dtype, order='C')
+ self.res_str_casted = rffi.cast(rffi.CArrayPtr(lltype.Char),
+ self.res_str.storage)
def create_sig(self):
return signature.ToStringSignature(self.calc_dtype,
@@ -950,7 +980,7 @@
def setitem(self, item, value):
self.invalidated()
- self.dtype.setitem(self, item, value)
+ self.dtype.setitem(self, item, value.convert_to(self.dtype))
def calc_strides(self, shape):
dtype = self.find_dtype()
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
@@ -28,26 +28,38 @@
return self.identity
def descr_call(self, space, __args__):
+ from interp_numarray import BaseArray
args_w, kwds_w = __args__.unpack()
# it occurs to me that we don't support any datatypes that
# require casting, change it later when we do
kwds_w.pop('casting', None)
w_subok = kwds_w.pop('subok', None)
w_out = kwds_w.pop('out', space.w_None)
- if ((w_subok is not None and space.is_true(w_subok)) or
- not space.is_w(w_out, space.w_None)):
+ # Setup a default value for out
+ if space.is_w(w_out, space.w_None):
+ out = None
+ else:
+ out = w_out
+ if (w_subok is not None and space.is_true(w_subok)):
raise OperationError(space.w_NotImplementedError,
space.wrap("parameters unsupported"))
if kwds_w or len(args_w) < self.argcount:
raise OperationError(space.w_ValueError,
space.wrap("invalid number of arguments")
)
- elif len(args_w) > self.argcount:
- # The extra arguments should actually be the output array, but we
- # don't support that yet.
+ 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")
)
+ # 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 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)
@unwrap_spec(skipna=bool, keepdims=bool)
@@ -105,28 +117,33 @@
array([[ 1, 5],
[ 9, 13]])
"""
- if not space.is_w(w_out, space.w_None):
- raise OperationError(space.w_NotImplementedError, space.wrap(
- "out not supported"))
+ from pypy.module.micronumpy.interp_numarray import BaseArray
if w_axis is None:
axis = 0
elif space.is_w(w_axis, space.w_None):
axis = -1
else:
axis = space.int_w(w_axis)
- return self.reduce(space, w_obj, False, False, axis, keepdims)
+ if space.is_w(w_out, space.w_None):
+ out = None
+ elif not isinstance(w_out, BaseArray):
+ raise OperationError(space.w_TypeError, space.wrap(
+ 'output must be an array'))
+ else:
+ out = w_out
+ return self.reduce(space, w_obj, False, False, axis, keepdims, out)
- def reduce(self, space, w_obj, multidim, promote_to_largest, dim,
- keepdims=False):
+ def reduce(self, space, w_obj, multidim, promote_to_largest, axis,
+ keepdims=False, out=None):
from pypy.module.micronumpy.interp_numarray import convert_to_array, \
- Scalar, ReduceArray
+ Scalar, ReduceArray, W_NDimArray
if self.argcount != 2:
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 dim >= len(obj.shape):
- raise OperationError(space.w_ValueError, space.wrap("axis(=%d) out of bounds" % dim))
+ if axis >= len(obj.shape):
+ raise OperationError(space.w_ValueError, space.wrap("axis(=%d) out of bounds" % axis))
if isinstance(obj, Scalar):
raise OperationError(space.w_TypeError, space.wrap("cannot reduce "
"on a scalar"))
@@ -144,21 +161,55 @@
if self.identity is None and size == 0:
raise operationerrfmt(space.w_ValueError, "zero-size array to "
"%s.reduce without identity", self.name)
- if shapelen > 1 and dim >= 0:
- return self.do_axis_reduce(obj, dtype, dim, keepdims)
- arr = ReduceArray(self.func, self.name, self.identity, obj, dtype)
- return loop.compute(arr)
+ if shapelen > 1 and axis >= 0:
+ if keepdims:
+ shape = obj.shape[:axis] + [1] + obj.shape[axis + 1:]
+ else:
+ shape = obj.shape[:axis] + obj.shape[axis + 1:]
+ if out:
+ #Test for shape agreement
+ if len(out.shape) > len(shape):
+ raise operationerrfmt(space.w_ValueError,
+ 'output parameter for reduction operation %s' +
+ ' has too many dimensions', self.name)
+ elif len(out.shape) < len(shape):
+ raise operationerrfmt(space.w_ValueError,
+ 'output parameter for reduction operation %s' +
+ ' does not have enough dimensions', self.name)
+ elif out.shape != shape:
+ raise operationerrfmt(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.shape]),
+ )
+ #Test for dtype agreement, perhaps create an itermediate
+ #if out.dtype != dtype:
+ # raise OperationError(space.w_TypeError, space.wrap(
+ # "mismatched dtypes"))
+ return self.do_axis_reduce(obj, out.find_dtype(), axis, out)
+ else:
+ result = W_NDimArray(shape, dtype)
+ return self.do_axis_reduce(obj, dtype, axis, result)
+ if out:
+ if len(out.shape)>0:
+ raise operationerrfmt(space.w_ValueError, "output parameter "
+ "for reduction operation %s has too many"
+ " dimensions",self.name)
+ arr = ReduceArray(self.func, self.name, self.identity, obj,
+ out.find_dtype())
+ val = loop.compute(arr)
+ assert isinstance(out, Scalar)
+ out.value = val
+ else:
+ arr = ReduceArray(self.func, self.name, self.identity, obj, dtype)
+ val = loop.compute(arr)
+ return val
- def do_axis_reduce(self, obj, dtype, dim, keepdims):
- from pypy.module.micronumpy.interp_numarray import AxisReduce,\
- W_NDimArray
- if keepdims:
- shape = obj.shape[:dim] + [1] + obj.shape[dim + 1:]
- else:
- shape = obj.shape[:dim] + obj.shape[dim + 1:]
- result = W_NDimArray(shape, dtype)
+ def do_axis_reduce(self, obj, dtype, axis, result):
+ from pypy.module.micronumpy.interp_numarray import AxisReduce
arr = AxisReduce(self.func, self.name, self.identity, obj.shape, dtype,
- result, obj, dim)
+ result, obj, axis)
loop.compute(arr)
return arr.left
@@ -176,24 +227,55 @@
self.bool_result = bool_result
def call(self, space, args_w):
- from pypy.module.micronumpy.interp_numarray import (Call1,
- convert_to_array, Scalar)
-
- [w_obj] = args_w
+ from pypy.module.micronumpy.interp_numarray import (Call1, BaseArray,
+ convert_to_array, Scalar, shape_agreement)
+ if len(args_w)<2:
+ [w_obj] = args_w
+ out = None
+ else:
+ [w_obj, out] = args_w
+ if space.is_w(out, space.w_None):
+ out = None
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:
+ if not isinstance(out, BaseArray):
+ raise OperationError(space.w_TypeError, space.wrap(
+ 'output must be an array'))
+ 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)))
-
- w_res = Call1(self.func, self.name, w_obj.shape, calc_dtype, res_dtype,
- w_obj)
+ arr = self.func(calc_dtype, w_obj.value.convert_to(calc_dtype))
+ if isinstance(out,Scalar):
+ out.value=arr
+ elif isinstance(out, BaseArray):
+ out.fill(space, arr)
+ else:
+ out = arr
+ return space.wrap(out)
+ if out:
+ assert isinstance(out, BaseArray) # For translation
+ broadcast_shape = shape_agreement(space, w_obj.shape, out.shape)
+ if not broadcast_shape or broadcast_shape != out.shape:
+ raise operationerrfmt(space.w_ValueError,
+ 'output parameter shape mismatch, could not broadcast [%s]' +
+ ' to [%s]',
+ ",".join([str(x) for x in w_obj.shape]),
+ ",".join([str(x) for x in out.shape]),
+ )
+ w_res = Call1(self.func, self.name, out.shape, calc_dtype,
+ res_dtype, w_obj, out)
+ #Force it immediately
+ w_res.get_concrete()
+ else:
+ w_res = Call1(self.func, self.name, w_obj.shape, calc_dtype,
+ res_dtype, w_obj)
w_obj.add_invalidates(w_res)
return w_res
@@ -212,32 +294,61 @@
def call(self, space, args_w):
from pypy.module.micronumpy.interp_numarray import (Call2,
- convert_to_array, Scalar, shape_agreement)
-
- [w_lhs, w_rhs] = args_w
+ convert_to_array, Scalar, shape_agreement, BaseArray)
+ 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)
- calc_dtype = find_binop_result_dtype(space,
- w_lhs.find_dtype(), w_rhs.find_dtype(),
- int_only=self.int_only,
- promote_to_float=self.promote_to_float,
- promote_bools=self.promote_bools,
- )
+ 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(),
+ int_only=self.int_only,
+ promote_to_float=self.promote_to_float,
+ promote_bools=self.promote_bools,
+ )
+ elif not isinstance(w_out, BaseArray):
+ raise OperationError(space.w_TypeError, space.wrap(
+ 'output must be an array'))
+ else:
+ out = w_out
+ calc_dtype = out.find_dtype()
if self.comparison_func:
res_dtype = interp_dtype.get_dtype_cache(space).w_booldtype
else:
res_dtype = calc_dtype
if isinstance(w_lhs, Scalar) and isinstance(w_rhs, Scalar):
- return space.wrap(self.func(calc_dtype,
+ arr = self.func(calc_dtype,
w_lhs.value.convert_to(calc_dtype),
w_rhs.value.convert_to(calc_dtype)
- ))
+ )
+ if isinstance(out,Scalar):
+ out.value=arr
+ elif isinstance(out, BaseArray):
+ out.fill(space, arr)
+ else:
+ out = arr
+ return space.wrap(out)
new_shape = shape_agreement(space, w_lhs.shape, w_rhs.shape)
+ # Test correctness of out.shape
+ if out and out.shape != shape_agreement(space, new_shape, out.shape):
+ raise operationerrfmt(space.w_ValueError,
+ 'output parameter shape mismatch, could not broadcast [%s]' +
+ ' to [%s]',
+ ",".join([str(x) for x in new_shape]),
+ ",".join([str(x) for x in out.shape]),
+ )
w_res = Call2(self.func, self.name,
new_shape, calc_dtype,
- res_dtype, w_lhs, w_rhs)
+ res_dtype, w_lhs, w_rhs, out)
w_lhs.add_invalidates(w_res)
w_rhs.add_invalidates(w_res)
+ if out:
+ #out.add_invalidates(w_res) #causes a recursion loop
+ w_res.get_concrete()
return w_res
diff --git a/pypy/module/micronumpy/signature.py b/pypy/module/micronumpy/signature.py
--- a/pypy/module/micronumpy/signature.py
+++ b/pypy/module/micronumpy/signature.py
@@ -216,13 +216,14 @@
return self.child.eval(frame, arr.child)
class Call1(Signature):
- _immutable_fields_ = ['unfunc', 'name', 'child', 'dtype']
+ _immutable_fields_ = ['unfunc', 'name', 'child', 'res', 'dtype']
- def __init__(self, func, name, dtype, child):
+ def __init__(self, func, name, dtype, child, res=None):
self.unfunc = func
self.child = child
self.name = name
self.dtype = dtype
+ self.res = res
def hash(self):
return compute_hash(self.name) ^ intmask(self.child.hash() << 1)
@@ -256,6 +257,29 @@
v = self.child.eval(frame, arr.values).convert_to(arr.calc_dtype)
return self.unfunc(arr.calc_dtype, v)
+
+class BroadcastUfunc(Call1):
+ def _invent_numbering(self, cache, allnumbers):
+ self.res._invent_numbering(cache, allnumbers)
+ self.child._invent_numbering(new_cache(), allnumbers)
+
+ def debug_repr(self):
+ return 'BroadcastUfunc(%s, %s)' % (self.name, self.child.debug_repr())
+
+ def _create_iter(self, iterlist, arraylist, arr, transforms):
+ from pypy.module.micronumpy.interp_numarray import Call1
+
+ assert isinstance(arr, Call1)
+ vtransforms = transforms + [BroadcastTransform(arr.values.shape)]
+ self.child._create_iter(iterlist, arraylist, arr.values, vtransforms)
+ self.res._create_iter(iterlist, arraylist, arr.res, transforms)
+
+ def eval(self, frame, arr):
+ from pypy.module.micronumpy.interp_numarray import Call1
+ assert isinstance(arr, Call1)
+ v = self.child.eval(frame, arr.values).convert_to(arr.calc_dtype)
+ return self.unfunc(arr.calc_dtype, v)
+
class Call2(Signature):
_immutable_fields_ = ['binfunc', 'name', 'calc_dtype', 'left', 'right']
@@ -316,7 +340,17 @@
assert isinstance(arr, ResultArray)
offset = frame.get_final_iter().offset
- arr.left.setitem(offset, self.right.eval(frame, arr.right))
+ val = self.right.eval(frame, arr.right)
+ arr.left.setitem(offset, val)
+
+class BroadcastResultSignature(ResultSignature):
+ def _create_iter(self, iterlist, arraylist, arr, transforms):
+ from pypy.module.micronumpy.interp_numarray import ResultArray
+
+ assert isinstance(arr, ResultArray)
+ rtransforms = transforms + [BroadcastTransform(arr.left.shape)]
+ self.left._create_iter(iterlist, arraylist, arr.left, transforms)
+ self.right._create_iter(iterlist, arraylist, arr.right, rtransforms)
class ToStringSignature(Call1):
def __init__(self, dtype, child):
@@ -327,10 +361,10 @@
from pypy.module.micronumpy.interp_numarray import ToStringArray
assert isinstance(arr, ToStringArray)
- arr.res.setitem(0, self.child.eval(frame, arr.values).convert_to(
+ arr.res_str.setitem(0, self.child.eval(frame, arr.values).convert_to(
self.dtype))
for i in range(arr.item_size):
- arr.s.append(arr.res_casted[i])
+ arr.s.append(arr.res_str_casted[i])
class BroadcastLeft(Call2):
def _invent_numbering(self, cache, allnumbers):
@@ -455,6 +489,5 @@
cur = arr.left.getitem(iterator.offset)
value = self.binfunc(self.calc_dtype, cur, v)
arr.left.setitem(iterator.offset, value)
-
def debug_repr(self):
return 'AxisReduceSig(%s, %s)' % (self.name, self.right.debug_repr())
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
@@ -995,6 +995,10 @@
assert a.sum() == 5
raises(TypeError, 'a.sum(2, 3)')
+ d = array(0.)
+ b = a.sum(out=d)
+ assert b == d
+ assert isinstance(b, float)
def test_reduce_nd(self):
from numpypy import arange, array, multiply
@@ -1495,8 +1499,6 @@
a = array([[1, 2], [3, 4], [5, 6], [7, 8],
[9, 10], [11, 12], [13, 14]])
b = a[::2]
- print a
- print b
assert (b == [[1, 2], [5, 6], [9, 10], [13, 14]]).all()
c = b + b
assert c[1][1] == 12
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,126 @@
+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, sin
+ from math import sin as msin
+ a = array([[1, 2], [3, 4]])
+ c = zeros((2,2,2))
+ b = negative(a + a, out=c[1])
+ #test for view, and also test that forcing out also forces b
+ assert (c[:, :, 1] == [[0, 0], [-4, -8]]).all()
+ assert (b == [[-2, -4], [-6, -8]]).all()
+ #Test broadcast, type promotion
+ b = negative(3, out=a)
+ assert (a == -3).all()
+ c = zeros((2, 2), dtype=float)
+ b = negative(3, out=c)
+ assert b.dtype.kind == c.dtype.kind
+ assert b.shape == c.shape
+ a = array([1, 2])
+ b = sin(a, out=c)
+ assert(c == [[msin(1), msin(2)]] * 2).all()
+ b = sin(a, out=c+c)
+ assert (c == b).all()
+
+ #Test shape agreement
+ a = zeros((3,4))
+ b = zeros((3,5))
+ raises(ValueError, 'negative(a, out=b)')
+ b = zeros((1,4))
+ raises(ValueError, 'negative(a, out=b)')
+
+ def test_binfunc_out(self):
+ from _numpypy import array, add
+ a = array([[1, 2], [3, 4]])
+ out = array([[1, 2], [3, 4]])
+ c = add(a, a, out=out)
+ assert (c == out).all()
+ assert c.shape == a.shape
+ assert c.dtype is a.dtype
+ c[0,0] = 100
+ assert out[0, 0] == 100
+ out[:] = 100
+ raises(ValueError, 'c = add(a, a, out=out[1])')
+ c = add(a[0], a[1], out=out[1])
+ assert (c == out[1]).all()
+ assert (c == [4, 6]).all()
+ assert (out[0] == 100).all()
+ c = add(a[0], a[1], out=out)
+ assert (c == out[1]).all()
+ assert (c == out[0]).all()
+ out = array(16, dtype=int)
+ b = add(10, 10, out=out)
+ assert b==out
+ assert b.dtype == out.dtype
+
+ def test_applevel(self):
+ from _numpypy import array, sum, max, min
+ a = array([[1, 2], [3, 4]])
+ out = array([[0, 0], [0, 0]])
+ c = sum(a, axis=0, out=out[0])
+ assert (c == [4, 6]).all()
+ assert (c == out[0]).all()
+ assert (c != out[1]).all()
+ c = max(a, axis=1, out=out[0])
+ assert (c == [2, 4]).all()
+ assert (c == out[0]).all()
+ assert (c != out[1]).all()
+
+ def test_ufunc_cast(self):
+ from _numpypy import array, negative, add, sum
+ a = array(16, dtype = int)
+ c = array(0, dtype = float)
+ b = negative(a, out=c)
+ assert b == c
+ b = add(a, a, out=c)
+ assert b == c
+ d = array([16, 16], dtype=int)
+ b = sum(d, out=c)
+ assert b == c
+ try:
+ from _numpypy import version
+ v = version.version.split('.')
+ except:
+ v = ['1', '6', '0'] # numpypy is api compatable to what version?
+ if v[0]<'2':
+ b = negative(c, out=a)
+ assert b == a
+ b = add(c, c, out=a)
+ assert b == a
+ b = sum(array([16, 16], dtype=float), out=a)
+ assert b == a
+ else:
+ cast_error = raises(TypeError, negative, c, a)
+ assert str(cast_error.value) == \
+ "Cannot cast ufunc negative output from dtype('float64') to dtype('int64') with casting rule 'same_kind'"
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
@@ -131,7 +131,7 @@
# bogus. We need to improve the situation somehow.
self.check_simple_loop({'getinteriorfield_raw': 2,
'setinteriorfield_raw': 1,
- 'arraylen_gc': 1,
+ 'arraylen_gc': 2,
'guard_true': 1,
'int_lt': 1,
'jump': 1,
diff --git a/pypy/objspace/flow/test/test_objspace.py b/pypy/objspace/flow/test/test_objspace.py
--- a/pypy/objspace/flow/test/test_objspace.py
+++ b/pypy/objspace/flow/test/test_objspace.py
@@ -1,6 +1,6 @@
from __future__ import with_statement
import new
-import py
+import py, sys
from pypy.objspace.flow.model import Constant, Block, Link, Variable
from pypy.objspace.flow.model import mkentrymap, c_last_exception
from pypy.interpreter.argument import Arguments
@@ -893,6 +893,8 @@
""" Tests code generated by pypy-c compiled with BUILD_LIST_FROM_ARG
bytecode
"""
+ if sys.version_info < (2, 7):
+ py.test.skip("2.7 only test")
self.patch_opcodes('BUILD_LIST_FROM_ARG')
try:
def f():
diff --git a/pypy/tool/release/package.py b/pypy/tool/release/package.py
--- a/pypy/tool/release/package.py
+++ b/pypy/tool/release/package.py
@@ -58,33 +58,13 @@
binaries = [(pypy_c, rename_pypy_c)]
#
if sys.platform == 'win32':
- #What runtime do we need?
- msvc_runtime = 'msvcr80.dll' #default is studio 2005 vc8
- try:
- import subprocess
- out,err = subprocess.Popen([str(pypy_c), '-c',
- 'import sys; print sys.version'],
- stdout=subprocess.PIPE).communicate()
- indx=out.find('MSC v.') + 6
- if indx> 10:
- if out[indx:].startswith('1600'):
- msvc_runtime = 'msvcr100.dll' #studio 2010 vc10
- elif out[indx:].startwith('1500'):
- msvc_runtime = 'msvcr90.dll' #studio 2009 vc9
- elif out[indx:].startswith('1400'):
- msvc_runtime = 'msvcr80.dll' #studio 2005 vc8
- else:
- print 'Cannot determine runtime dll for pypy' \
- ' version "%s"'%out
- else:
- print 'Cannot determine runtime dll for pypy' \
- ' version "%s"'%out
- except :
- pass
+ #Don't include a mscvrXX.dll, users should get their own.
+ #Instructions are provided on the website.
+
# Can't rename a DLL: it is always called 'libpypy-c.dll'
for extra in ['libpypy-c.dll',
- 'libexpat.dll', 'sqlite3.dll', msvc_runtime,
+ 'libexpat.dll', 'sqlite3.dll',
'libeay32.dll', 'ssleay32.dll']:
p = pypy_c.dirpath().join(extra)
if not p.check():
More information about the pypy-commit
mailing list