Author: mattip <[email protected]>
Branch: ufuncapi
Changeset: r71794:0262b16a53cf
Date: 2014-06-01 01:09 +0300
http://bitbucket.org/pypy/pypy/changeset/0262b16a53cf/
Log: s/argcount/nin/, add nout, signature, nargs attributes, start
W_UfuncGeneric
diff --git a/pypy/module/micronumpy/ctors.py b/pypy/module/micronumpy/ctors.py
--- a/pypy/module/micronumpy/ctors.py
+++ b/pypy/module/micronumpy/ctors.py
@@ -3,7 +3,8 @@
from rpython.rlib.rstring import strip_spaces
from rpython.rtyper.lltypesystem import lltype, rffi
from pypy.module.micronumpy import descriptor, loop
-from pypy.module.micronumpy.base import W_NDimArray, convert_to_array
+from pypy.module.micronumpy.base import convert_to_array
+from pypy.module.micronumpy.ndarray import W_NDimArray # use extended class
from pypy.module.micronumpy.converters import shape_converter
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
@@ -159,8 +159,8 @@
def get(i):
return w_result.getitem(space, [i]).value
for d in [int32_dtype, float64_dtype]:
- w_array = array(space, range(10), dtype=d)
- w_result = func(w_array)
+ w_array = array(space, space.wrap(range(10)), w_dtype=d)
+ w_result = func.call(space, [w_array])
for i in 10:
assert get(i) == 2*i
@@ -208,8 +208,17 @@
assert sin.identity is None
assert add.nin == 2
+ assert add.nout == 1
+ assert add.nargs == 3
+ assert add.signature == None
assert multiply.nin == 2
+ assert multiply.nout == 1
+ assert multiply.nargs == 3
+ assert multiply.signature == None
assert sin.nin == 1
+ assert sin.nout == 1
+ assert sin.nargs == 2
+ assert sin.signature == None
def test_wrong_arguments(self):
from numpy import add, sin
diff --git a/pypy/module/micronumpy/ufuncs.py b/pypy/module/micronumpy/ufuncs.py
--- a/pypy/module/micronumpy/ufuncs.py
+++ b/pypy/module/micronumpy/ufuncs.py
@@ -62,17 +62,17 @@
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:
+ if kwds_w or len(args_w) < self.nin:
raise OperationError(space.w_ValueError,
space.wrap("invalid number of arguments")
)
- elif (len(args_w) > self.argcount and out is not None) or \
- (len(args_w) > self.argcount + 1):
+ elif (len(args_w) > self.nin and out is not None) or \
+ (len(args_w) > self.nin + 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:
+ if len(args_w) > self.nin:
out = args_w[-1]
else:
args_w = args_w + [out]
@@ -163,7 +163,7 @@
def reduce(self, space, w_obj, w_axis, keepdims=False, out=None,
dtype=None,
cumulative=False):
- if self.argcount != 2:
+ if self.nin != 2:
raise oefmt(space.w_ValueError,
"reduce only supported for binary functions")
assert isinstance(self, W_Ufunc2)
@@ -287,7 +287,10 @@
class W_Ufunc1(W_Ufunc):
_immutable_fields_ = ["func", "bool_result"]
- argcount = 1
+ nin = 1
+ nout = 1
+ nargs = 2
+ signature = None
def __init__(self, func, name, promote_to_largest=False,
promote_to_float=False,
promote_bools=False, identity=None, bool_result=False,
int_only=False,
@@ -353,7 +356,10 @@
class W_Ufunc2(W_Ufunc):
_immutable_fields_ = ["func", "comparison_func", "done_func"]
- argcount = 2
+ nin = 2
+ nout = 1
+ nargs = 3
+ signature = None
def __init__(self, func, name, promote_to_largest=False,
promote_to_float=False,
promote_bools=False, identity=None, comparison_func=False,
int_only=False,
@@ -457,6 +463,62 @@
res_dtype, w_lhs, w_rhs, out)
+class W_UfuncGeneric(W_Ufunc):
+ _immutable_fields_ = ["funcs", "signature", "nin", "nout", "nargs",
+ "dtypes"]
+
+ def __init__(self, funcs, name, identity, nin, nout, dtypes, signature):
+ # XXX make sure funcs, signature, dtypes, nin, nout are consistent
+
+ # These don't matter, we use the signature and dtypes for determining
+ # output dtype
+ promote_to_largest = promote_to_float = promote_bools = False
+ int_only = allow_bool = allow_complex = complex_to_float = False
+ W_Ufunc.__init__(self, name, promote_to_largest, promote_to_float,
promote_bools,
+ identity, int_only, allow_bool, allow_complex,
complex_to_float)
+ self.funcs = funcs
+ self.dtypes = dtypes
+ self.nin = nin
+ self.nout = nout
+ self.nargs = nin + max(nout, 1) # ufuncs can always be called with an
out=<> kwarg
+ self.signature = signature
+
+ def reduce(self, space, w_obj, w_axis, keepdims=False, out=None,
dtype=None,
+ cumulative=False):
+ raise oefmt(space.w_NotImplementedError, 'not implemented yet')
+
+ def call(self, space, args_w):
+ out = None
+ inargs = []
+ for i in range(self.nin):
+ inargs.append(convert_to_array(space, args_w[i]))
+ outargs = []
+ for i in range(min(self.nout, len(args_w)-self.nin)):
+ out = args_w[i+self.nin]
+ if space.is_w(out, space.w_None):
+ outargs.append(None)
+ else:
+ if not isinstance(out, W_NDimArray):
+ raise oefmt(space.w_TypeError, 'output must be an array')
+ outargs.append(out)
+ index = self.alloc_outargs(space, inargs, outargs)
+ func, dims, steps = self.prep_call(space, index, inargs, outargs)
+ data = [] # allocate a ll array of pointers and
+ # initialize to [x.data for x in inargs+outargs]
+ func(data, dims, steps, None)
+
+ def alloc_outargs(self, space, inargs, outargs):
+ # Find a match for the inargs.dtype in self.dtypes,
+ # then use the result dtype to verify/allocate outargs
+ return 0
+
+ def prep_call(self, space, index, inargs, outargs):
+ # Use the index and signature to determine
+ # dims and steps for function call
+ return self.funcs[index], [inargs[0].get_shape()[0]], \
+ [inargs[0].get_strides()[0], outargs[0].get_strides()[0]]
+
+
W_Ufunc.typedef = TypeDef("numpy.ufunc",
__call__ = interp2app(W_Ufunc.descr_call),
__repr__ = interp2app(W_Ufunc.descr_repr),
@@ -464,7 +526,10 @@
identity = GetSetProperty(W_Ufunc.descr_get_identity),
accumulate = interp2app(W_Ufunc.descr_accumulate),
- nin = interp_attrproperty("argcount", cls=W_Ufunc),
+ nin = interp_attrproperty("nin", cls=W_Ufunc),
+ nout = interp_attrproperty("nout", cls=W_Ufunc),
+ nargs = interp_attrproperty("nargs", cls=W_Ufunc),
+ signature = interp_attrproperty("signature", cls=W_Ufunc),
reduce = interp2app(W_Ufunc.descr_reduce),
outer = interp2app(W_Ufunc.descr_outer),
@@ -626,7 +691,7 @@
'supported', w_obj)
-def ufunc_dtype_caller(space, ufunc_name, op_name, argcount, comparison_func,
+def ufunc_dtype_caller(space, ufunc_name, op_name, nin, comparison_func,
bool_result):
def get_op(dtype):
try:
@@ -636,13 +701,13 @@
"%s not implemented for %s",
ufunc_name, dtype.get_name())
dtype_cache = descriptor.get_dtype_cache(space)
- if argcount == 1:
+ if nin == 1:
def impl(res_dtype, value):
res = get_op(res_dtype)(value)
if bool_result:
return dtype_cache.w_booldtype.box(res)
return res
- elif argcount == 2:
+ elif nin == 2:
def impl(res_dtype, lvalue, rvalue):
res = get_op(res_dtype)(lvalue, rvalue)
if comparison_func:
@@ -757,7 +822,7 @@
]:
self.add_ufunc(space, *ufunc_def)
- def add_ufunc(self, space, ufunc_name, op_name, argcount,
extra_kwargs=None):
+ def add_ufunc(self, space, ufunc_name, op_name, nin, extra_kwargs=None):
if extra_kwargs is None:
extra_kwargs = {}
@@ -767,13 +832,13 @@
descriptor.get_dtype_cache(space).w_longdtype.box(identity)
extra_kwargs["identity"] = identity
- func = ufunc_dtype_caller(space, ufunc_name, op_name, argcount,
+ func = ufunc_dtype_caller(space, ufunc_name, op_name, nin,
comparison_func=extra_kwargs.get("comparison_func", False),
bool_result=extra_kwargs.get("bool_result", False),
)
- if argcount == 1:
+ if nin == 1:
ufunc = W_Ufunc1(func, ufunc_name, **extra_kwargs)
- elif argcount == 2:
+ elif nin == 2:
ufunc = W_Ufunc2(func, ufunc_name, **extra_kwargs)
setattr(self, ufunc_name, ufunc)
@@ -781,7 +846,7 @@
def get(space):
return space.fromcache(UfuncState)
-@unwrap_spec(nin=int, nout=int, name=str, doc=str, check_return=int,
signature=str)
-def ufunc_from_func_and_data_and_signature(w_funcs, w_data, w_types, nin, nout,
- w_identity, name, doc, check_return, signature):
+def ufunc_from_func_and_data_and_signature(funcs, data, dtypes, nin, nout,
+ identity, name, doc, check_return, signature):
+ return W_UfuncGeneric(funcs, name, identity, nin, nout, dtypes, signature)
pass
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit