[pypy-commit] pypy numpy-ufunc-object: refactored ufuncs into objects successfully (well, pending translation). now need to fix test_zjit.
alex_gaynor
noreply at buildbot.pypy.org
Tue Aug 30 16:49:05 CEST 2011
Author: Alex Gaynor <alex.gaynor at gmail.com>
Branch: numpy-ufunc-object
Changeset: r46921:2a49d4ebb30e
Date: 2011-08-30 10:48 -0400
http://bitbucket.org/pypy/pypy/changeset/2a49d4ebb30e/
Log: refactored ufuncs into objects successfully (well, pending
translation). now need to fix test_zjit.
diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py
--- a/pypy/module/micronumpy/__init__.py
+++ b/pypy/module/micronumpy/__init__.py
@@ -1,8 +1,7 @@
-
from pypy.interpreter.mixedmodule import MixedModule
+
class Module(MixedModule):
-
applevel_name = 'numpy'
interpleveldefs = {
@@ -14,30 +13,33 @@
'empty': 'interp_numarray.zeros',
'ones': 'interp_numarray.ones',
'fromstring': 'interp_support.fromstring',
+ }
- # ufuncs
- 'abs': 'interp_ufuncs.absolute',
- 'absolute': 'interp_ufuncs.absolute',
- 'add': 'interp_ufuncs.add',
- 'copysign': 'interp_ufuncs.copysign',
- 'divide': 'interp_ufuncs.divide',
- 'exp': 'interp_ufuncs.exp',
- 'fabs': 'interp_ufuncs.fabs',
- 'floor': 'interp_ufuncs.floor',
- 'maximum': 'interp_ufuncs.maximum',
- 'minimum': 'interp_ufuncs.minimum',
- 'multiply': 'interp_ufuncs.multiply',
- 'negative': 'interp_ufuncs.negative',
- 'reciprocal': 'interp_ufuncs.reciprocal',
- 'sign': 'interp_ufuncs.sign',
- 'subtract': 'interp_ufuncs.subtract',
- 'sin': 'interp_ufuncs.sin',
- 'cos': 'interp_ufuncs.cos',
- 'tan': 'interp_ufuncs.tan',
- 'arcsin': 'interp_ufuncs.arcsin',
- 'arccos': 'interp_ufuncs.arccos',
- 'arctan': 'interp_ufuncs.arctan',
- }
+ # ufuncs
+ for exposed, impl in [
+ ("abs", "absolute"),
+ ("absolute", "absolute"),
+ ("add", "add"),
+ ("arccos", "arccos"),
+ ("arcsin", "arcsin"),
+ ("arctan", "arctan"),
+ ("copysign", "copysign"),
+ ("cos", "cos"),
+ ("divide", "divide"),
+ ("exp", "exp"),
+ ("fabs", "fabs"),
+ ("floor", "floor"),
+ ("maximum", "maximum"),
+ ("minimum", "minimum"),
+ ("multiply", "multiply"),
+ ("negative", "negative"),
+ ("reciprocal", "reciprocal"),
+ ("sign", "sign"),
+ ("sin", "sin"),
+ ("subtract", "subtract"),
+ ("tan", "tan"),
+ ]:
+ interpleveldefs[exposed] = "interp_ufuncs.get(space).%s" % impl
appleveldefs = {
'average': 'app_numpy.average',
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
@@ -53,42 +53,42 @@
i += 1
return arr
- def _unaryop_impl(w_ufunc):
+ def _unaryop_impl(ufunc_name):
def impl(self, space):
- return w_ufunc(space, self)
- return func_with_new_name(impl, "unaryop_%s_impl" % w_ufunc.name)
+ return getattr(interp_ufuncs.get(space), ufunc_name).call(space, [self])
+ return func_with_new_name(impl, "unaryop_%s_impl" % ufunc_name)
- descr_pos = _unaryop_impl(interp_ufuncs.positive)
- descr_neg = _unaryop_impl(interp_ufuncs.negative)
- descr_abs = _unaryop_impl(interp_ufuncs.absolute)
+ descr_pos = _unaryop_impl("positive")
+ descr_neg = _unaryop_impl("negative")
+ descr_abs = _unaryop_impl("absolute")
- def _binop_impl(w_ufunc):
+ def _binop_impl(ufunc_name):
def impl(self, space, w_other):
- return w_ufunc(space, self, w_other)
- return func_with_new_name(impl, "binop_%s_impl" % w_ufunc.name)
+ return getattr(interp_ufuncs.get(space), ufunc_name).call(space, [self, w_other])
+ return func_with_new_name(impl, "binop_%s_impl" % ufunc_name)
- descr_add = _binop_impl(interp_ufuncs.add)
- descr_sub = _binop_impl(interp_ufuncs.subtract)
- descr_mul = _binop_impl(interp_ufuncs.multiply)
- descr_div = _binop_impl(interp_ufuncs.divide)
- descr_pow = _binop_impl(interp_ufuncs.power)
- descr_mod = _binop_impl(interp_ufuncs.mod)
+ descr_add = _binop_impl("add")
+ descr_sub = _binop_impl("subtract")
+ descr_mul = _binop_impl("multiply")
+ descr_div = _binop_impl("divide")
+ descr_pow = _binop_impl("power")
+ descr_mod = _binop_impl("mod")
- def _binop_right_impl(w_ufunc):
+ def _binop_right_impl(ufunc_name):
def impl(self, space, w_other):
w_other = scalar_w(space,
interp_ufuncs.find_dtype_for_scalar(space, w_other, self.find_dtype()),
w_other
)
- return w_ufunc(space, w_other, self)
- return func_with_new_name(impl, "binop_right_%s_impl" % w_ufunc.name)
+ return getattr(interp_ufuncs.get(space), ufunc_name).call(space, [w_other, self])
+ return func_with_new_name(impl, "binop_right_%s_impl" % ufunc_name)
- descr_radd = _binop_right_impl(interp_ufuncs.add)
- descr_rsub = _binop_right_impl(interp_ufuncs.subtract)
- descr_rmul = _binop_right_impl(interp_ufuncs.multiply)
- descr_rdiv = _binop_right_impl(interp_ufuncs.divide)
- descr_rpow = _binop_right_impl(interp_ufuncs.power)
- descr_rmod = _binop_right_impl(interp_ufuncs.mod)
+ descr_radd = _binop_right_impl("add")
+ descr_rsub = _binop_right_impl("subtract")
+ descr_rmul = _binop_right_impl("multiply")
+ descr_rdiv = _binop_right_impl("divide")
+ descr_rpow = _binop_right_impl("power")
+ descr_rmod = _binop_right_impl("mod")
def _reduce_sum_prod_impl(op_name, init):
reduce_driver = jit.JitDriver(greens=['signature'],
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
@@ -1,6 +1,6 @@
from pypy.interpreter.baseobjspace import Wrappable
from pypy.interpreter.gateway import interp2app
-from pypy.interpreter.typedef import TypeDef
+from pypy.interpreter.typedef import TypeDef, GetSetProperty, interp_attrproperty
from pypy.module.micronumpy import interp_dtype, signature
from pypy.tool.sourcetools import func_with_new_name
@@ -16,76 +16,88 @@
def descr_repr(self, space):
return space.wrap("<ufunc '%s'>" % self.name)
+ def descr_get_identity(self, space):
+ if self.identity is None:
+ return space.w_None
+ return self.identity.wrap(space)
+
+ def descr_call(self, space, __args__):
+ args_w = __args__.fixedunpack(self.argcount)
+ return self.call(space, args_w)
+
class W_Ufunc1(W_Ufunc):
+ argcount = 1
+
def __init__(self, func, name, promote_to_float=False, promote_bools=False,
identity=None):
W_Ufunc.__init__(self, name, promote_to_float, promote_bools, identity)
self.func = func
+ self.signature = signature.Call1(func)
+
+ def call(self, space, args_w):
+ from pypy.module.micronumpy.interp_numarray import (Call1,
+ convert_to_array, Scalar)
+
+ [w_obj] = args_w
+ w_obj = convert_to_array(space, w_obj)
+ res_dtype = find_unaryop_result_dtype(space,
+ w_obj.find_dtype(),
+ promote_to_float=self.promote_to_float,
+ promote_bools=self.promote_bools,
+ )
+ if isinstance(w_obj, Scalar):
+ return self.func(res_dtype, w_obj.value.convert_to(res_dtype)).wrap(space)
+
+ new_sig = signature.Signature.find_sig([self.signature, w_obj.signature])
+ w_res = Call1(new_sig, res_dtype, w_obj)
+ w_obj.add_invalidates(w_res)
+ return w_res
+
class W_Ufunc2(W_Ufunc):
+ argcount = 2
+
def __init__(self, func, name, promote_to_float=False, promote_bools=False,
identity=None):
W_Ufunc.__init__(self, name, promote_to_float, promote_bools, identity)
self.func = func
+ self.signature = signature.Call2(func)
-W_Ufunc.typedef = TypeDef("ufunc",
- __module__ = "numpy",
-
- __repr__ = interp2app(W_Ufunc.descr_repr),
-)
-
-def ufunc(func=None, promote_to_float=False, promote_bools=False):
- if func is None:
- return lambda func: ufunc(func, promote_to_float, promote_bools)
- call_sig = signature.Call1(func)
- def impl(space, w_obj):
- from pypy.module.micronumpy.interp_numarray import (Call1,
- convert_to_array, Scalar)
-
- w_obj = convert_to_array(space, w_obj)
- res_dtype = find_unaryop_result_dtype(space,
- w_obj.find_dtype(),
- promote_to_float=promote_to_float,
- promote_bools=promote_bools,
- )
- if isinstance(w_obj, Scalar):
- return func(res_dtype, w_obj.value.convert_to(res_dtype)).wrap(space)
-
- new_sig = signature.Signature.find_sig([call_sig, w_obj.signature])
- w_res = Call1(new_sig, res_dtype, w_obj)
- w_obj.add_invalidates(w_res)
- return w_res
- return func_with_new_name(impl, "%s_dispatcher" % func.__name__)
-
-def ufunc2(func=None, promote_to_float=False, promote_bools=False):
- if func is None:
- return lambda func: ufunc2(func, promote_to_float, promote_bools)
-
- call_sig = signature.Call2(func)
- def impl(space, w_lhs, w_rhs):
+ def call(self, space, args_w):
from pypy.module.micronumpy.interp_numarray import (Call2,
convert_to_array, Scalar)
+ [w_lhs, w_rhs] = args_w
w_lhs = convert_to_array(space, w_lhs)
w_rhs = convert_to_array(space, w_rhs)
res_dtype = find_binop_result_dtype(space,
w_lhs.find_dtype(), w_rhs.find_dtype(),
- promote_to_float=promote_to_float,
- promote_bools=promote_bools,
+ promote_to_float=self.promote_to_float,
+ promote_bools=self.promote_bools,
)
if isinstance(w_lhs, Scalar) and isinstance(w_rhs, Scalar):
- return func(res_dtype, w_lhs.value, w_rhs.value).wrap(space)
+ return self.func(res_dtype, w_lhs.value, w_rhs.value).wrap(space)
new_sig = signature.Signature.find_sig([
- call_sig, w_lhs.signature, w_rhs.signature
+ self.signature, w_lhs.signature, w_rhs.signature
])
w_res = Call2(new_sig, res_dtype, w_lhs, w_rhs)
w_lhs.add_invalidates(w_res)
w_rhs.add_invalidates(w_res)
return w_res
- return func_with_new_name(impl, "%s_dispatcher" % func.__name__)
+
+
+W_Ufunc.typedef = TypeDef("ufunc",
+ __module__ = "numpy",
+
+ __call__ = interp2app(W_Ufunc.descr_call),
+ __repr__ = interp2app(W_Ufunc.descr_repr),
+
+ identity = GetSetProperty(W_Ufunc.descr_get_identity),
+ nin = interp_attrproperty("argcount", cls=W_Ufunc)
+)
def find_binop_result_dtype(space, dt1, dt2, promote_to_float=False,
promote_bools=False):
@@ -140,7 +152,7 @@
return space.fromcache(interp_dtype.W_Float64Dtype)
-def ufunc_dtype_caller(ufunc_name, op_name, argcount, **kwargs):
+def ufunc_dtype_caller(ufunc_name, op_name, argcount):
if argcount == 1:
def impl(res_dtype, value):
return getattr(res_dtype, op_name)(value)
@@ -149,47 +161,56 @@
return getattr(res_dtype, op_name)(lvalue, rvalue)
return func_with_new_name(impl, ufunc_name)
-for ufunc_def in [
- ("add", "add", 2, {"identity": 0}),
- ("subtract", "sub", 2),
- ("multiply", "mul", 2),
- ("divide", "div", 2, {"promote_bools": True}),
- ("mod", "mod", 2, {"promote_bools": True}),
- ("power", "pow", 2, {"promote_bools": True}),
+class UfuncState(object):
+ def __init__(self, space):
+ "NOT_RPYTHON"
+ for ufunc_def in [
+ ("add", "add", 2, {"identity": 0}),
+ ("subtract", "sub", 2),
+ ("multiply", "mul", 2, {"identity": 1}),
+ ("divide", "div", 2, {"promote_bools": True}),
+ ("mod", "mod", 2, {"promote_bools": True}),
+ ("power", "pow", 2, {"promote_bools": True}),
- ("maximum", "max", 2),
- ("minimum", "min", 2),
+ ("maximum", "max", 2),
+ ("minimum", "min", 2),
- ("copysign", "copysign", 2, {"promote_to_float": True}),
+ ("copysign", "copysign", 2, {"promote_to_float": True}),
- ("positive", "pos", 1),
- ("negative", "neg", 1),
- ("absolute", "abs", 1),
- ("sign", "sign", 1, {"promote_bools": True}),
- ("reciprocal", "reciprocal", 1),
+ ("positive", "pos", 1),
+ ("negative", "neg", 1),
+ ("absolute", "abs", 1),
+ ("sign", "sign", 1, {"promote_bools": True}),
+ ("reciprocal", "reciprocal", 1),
- ("fabs", "fabs", 1, {"promote_to_float": True}),
- ("floor", "floor", 1, {"promote_to_float": True}),
- ("exp", "exp", 1, {"promote_to_float": True}),
+ ("fabs", "fabs", 1, {"promote_to_float": True}),
+ ("floor", "floor", 1, {"promote_to_float": True}),
+ ("exp", "exp", 1, {"promote_to_float": True}),
- ("sin", "sin", 1, {"promote_to_float": True}),
- ("cos", "cos", 1, {"promote_to_float": True}),
- ("tan", "tan", 1, {"promote_to_float": True}),
- ("arcsin", "arcsin", 1, {"promote_to_float": True}),
- ("arccos", "arccos", 1, {"promote_to_float": True}),
- ("arctan", "arctan", 1, {"promote_to_float": True}),
-]:
- ufunc_name = ufunc_def[0]
- op_name = ufunc_def[1]
- argcount = ufunc_def[2]
- try:
- extra_kwargs = ufunc_def[3]
- except IndexError:
- extra_kwargs = {}
+ ("sin", "sin", 1, {"promote_to_float": True}),
+ ("cos", "cos", 1, {"promote_to_float": True}),
+ ("tan", "tan", 1, {"promote_to_float": True}),
+ ("arcsin", "arcsin", 1, {"promote_to_float": True}),
+ ("arccos", "arccos", 1, {"promote_to_float": True}),
+ ("arctan", "arctan", 1, {"promote_to_float": True}),
+ ]:
+ self.add_ufunc(space, *ufunc_def)
- func = ufunc_dtype_caller(ufunc_name, op_name, argcount)
- if argcount == 1:
- ufunc = W_Ufunc1(func, ufunc_name, **extra_kwargs)
- elif argcount == 2:
- ufunc = W_Ufunc2(func, ufunc_name, **extra_kwargs)
- globals()[ufunc_name] = ufunc
+ def add_ufunc(self, space, ufunc_name, op_name, argcount, extra_kwargs=None):
+ if extra_kwargs is None:
+ extra_kwargs = {}
+
+ identity = extra_kwargs.get("identity")
+ if identity is not None:
+ identity = space.fromcache(interp_dtype.W_Int64Dtype).adapt_val(identity)
+ extra_kwargs["identity"] = identity
+
+ func = ufunc_dtype_caller(ufunc_name, op_name, argcount)
+ if argcount == 1:
+ ufunc = W_Ufunc1(func, ufunc_name, **extra_kwargs)
+ elif argcount == 2:
+ ufunc = W_Ufunc2(func, ufunc_name, **extra_kwargs)
+ setattr(self, ufunc_name, ufunc)
+
+def get(space):
+ return space.fromcache(UfuncState)
\ No newline at end of file
More information about the pypy-commit
mailing list