[pypy-commit] pypy numpy-ufuncs: Make the operators on an array use the ufuncs internally.

alex_gaynor noreply at buildbot.pypy.org
Thu Jul 21 09:38:55 CEST 2011


Author: Alex Gaynor <alex.gaynor at gmail.com>
Branch: numpy-ufuncs
Changeset: r45789:cb06fc29e57c
Date: 2011-07-21 00:38 -0700
http://bitbucket.org/pypy/pypy/changeset/cb06fc29e57c/

Log:	Make the operators on an array use the ufuncs internally.

diff --git a/pypy/module/micronumpy/compile.py b/pypy/module/micronumpy/compile.py
--- a/pypy/module/micronumpy/compile.py
+++ b/pypy/module/micronumpy/compile.py
@@ -3,7 +3,7 @@
 It should not be imported by the module itself
 """
 
-from pypy.module.micronumpy.interp_numarray import FloatWrapper, SingleDimArray
+from pypy.module.micronumpy.interp_numarray import FloatWrapper, SingleDimArray, BaseArray
 
 class BogusBytecode(Exception):
     pass
@@ -18,6 +18,14 @@
     def wrap(self, x):
         return x
 
+    def issequence_w(self, w_obj):
+        # Completley wrong in the general case, but good enough for this.
+        return isinstance(w_obj, BaseArray)
+
+    def float_w(self, w_obj):
+        assert isinstance(w_obj, float)
+        return w_obj
+
 def numpy_compile(bytecode, array_size):
     space = TrivialSpace()
     stack = []
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
@@ -2,6 +2,8 @@
 from pypy.interpreter.error import OperationError, operationerrfmt
 from pypy.interpreter.gateway import interp2app, unwrap_spec
 from pypy.interpreter.typedef import TypeDef, GetSetProperty
+from pypy.module.micronumpy.interp_support import Signature
+from pypy.module.micronumpy import interp_ufuncs
 from pypy.objspace.std.floatobject import float2string as float2string_orig
 from pypy.rlib import jit
 from pypy.rlib.rfloat import DTSF_STR_PRECISION
@@ -24,16 +26,6 @@
 all_driver = jit.JitDriver(greens=['signature'], reds=['i', 'size', 'self'])
 any_driver = jit.JitDriver(greens=['signature'], reds=['i', 'size', 'self'])
 
-class Signature(object):
-    def __init__(self):
-        self.transitions = {}
-
-    def transition(self, target):
-        if target in self.transitions:
-            return self.transitions[target]
-        self.transitions[target] = new = Signature()
-        return new
-
 def pos(v):
     return v
 def neg(v):
@@ -42,16 +34,8 @@
     return abs(v)
 def add(v1, v2):
     return v1 + v2
-def sub(v1, v2):
-    return v1 - v2
 def mul(v1, v2):
     return v1 * v2
-def div(v1, v2):
-    return v1 / v2
-def power(v1, v2):
-    return math.pow(v1, v2)
-def mod(v1, v2):
-    return math.fmod(v1, v2)
 def maximum(v1, v2):
     return max(v1, v2)
 def minimum(v1, v2):
@@ -89,51 +73,30 @@
     descr_neg = _unop_impl(neg)
     descr_abs = _unop_impl(absolute)
 
-    def _binop_impl(function):
-        signature = Signature()
+    def _binop_impl(w_ufunc):
         def impl(self, space, w_other):
-            w_other = convert_to_array(space, w_other)
-            new_sig = self.signature.transition(signature)
-            res = Call2(
-                function,
-                self,
-                w_other,
-                new_sig.transition(w_other.signature)
-            )
-            w_other.invalidates.append(res)
-            self.invalidates.append(res)
-            return space.wrap(res)
-        return func_with_new_name(impl, "binop_%s_impl" % function.__name__)
+            return w_ufunc(space, self, w_other)
+        return func_with_new_name(impl, "binop_%s_impl" % w_ufunc.__name__)
 
-    descr_add = _binop_impl(add)
-    descr_sub = _binop_impl(sub)
-    descr_mul = _binop_impl(mul)
-    descr_div = _binop_impl(div)
-    descr_pow = _binop_impl(power)
-    descr_mod = _binop_impl(mod)
+    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)
 
-    def _binop_right_impl(function):
-        signature = Signature()
+    def _binop_right_impl(w_ufunc):
         def impl(self, space, w_other):
-            new_sig = self.signature.transition(signature)
             w_other = FloatWrapper(space.float_w(w_other))
-            res = Call2(
-                function,
-                w_other,
-                self,
-                new_sig.transition(w_other.signature)
-            )
-            self.invalidates.append(res)
-            return space.wrap(res)
-        return func_with_new_name(impl,
-                                  "binop_right_%s_impl" % function.__name__)
+            return w_ufunc(space, w_other, self)
+        return func_with_new_name(impl, "binop_right_%s_impl" % w_ufunc.__name__)
 
-    descr_radd = _binop_right_impl(add)
-    descr_rsub = _binop_right_impl(sub)
-    descr_rmul = _binop_right_impl(mul)
-    descr_rdiv = _binop_right_impl(div)
-    descr_rpow = _binop_right_impl(power)
-    descr_rmod = _binop_right_impl(mod)
+    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)
 
     def _reduce_sum_prod_impl(function, init):
         reduce_driver = jit.JitDriver(greens=['signature'],
diff --git a/pypy/module/micronumpy/interp_support.py b/pypy/module/micronumpy/interp_support.py
--- a/pypy/module/micronumpy/interp_support.py
+++ b/pypy/module/micronumpy/interp_support.py
@@ -1,14 +1,14 @@
-
 from pypy.rlib.rstruct.runpack import runpack
 from pypy.rpython.lltypesystem import lltype, rffi
+from pypy.interpreter.error import OperationError
 from pypy.interpreter.gateway import unwrap_spec
-from pypy.interpreter.error import OperationError
-from pypy.module.micronumpy.interp_numarray import SingleDimArray
+
 
 FLOAT_SIZE = rffi.sizeof(lltype.Float)
 
 @unwrap_spec(s=str)
 def fromstring(space, s):
+    from pypy.module.micronumpy.interp_numarray import SingleDimArray
     length = len(s)
 
     if length % FLOAT_SIZE == 0:
@@ -30,3 +30,13 @@
         end += FLOAT_SIZE
 
     return space.wrap(a)
+
+class Signature(object):
+    def __init__(self):
+        self.transitions = {}
+
+    def transition(self, target):
+        if target in self.transitions:
+            return self.transitions[target]
+        self.transitions[target] = new = Signature()
+        return new
\ No newline at end of file
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,13 +1,13 @@
 import math
 
-from pypy.module.micronumpy.interp_numarray import (Call1, Call2, Signature,
-    convert_to_array)
+from pypy.module.micronumpy.interp_support import Signature
 from pypy.rlib import rfloat
 from pypy.tool.sourcetools import func_with_new_name
 
 def ufunc(func):
     signature = Signature()
     def impl(space, w_obj):
+        from pypy.module.micronumpy.interp_numarray import Call1, convert_to_array
         if space.issequence_w(w_obj):
             w_obj_arr = convert_to_array(space, w_obj)
             w_res = Call1(func, w_obj_arr, w_obj_arr.signature.transition(signature))
@@ -20,6 +20,7 @@
 def ufunc2(func):
     signature = Signature()
     def impl(space, w_lhs, w_rhs):
+        from pypy.module.micronumpy.interp_numarray import Call2, convert_to_array
         if space.issequence_w(w_lhs) or space.issequence_w(w_rhs):
             w_lhs_arr = convert_to_array(space, w_lhs)
             w_rhs_arr = convert_to_array(space, w_rhs)
@@ -106,3 +107,11 @@
 @ufunc
 def tan(value):
     return math.tan(value)
+
+ at ufunc2
+def power(lvalue, rvalue):
+    return math.pow(lvalue, rvalue)
+
+ at ufunc2
+def mod(lvalue, rvalue):
+    return math.fmod(lvalue, rvalue)
\ No newline at end of file


More information about the pypy-commit mailing list