Author: Maciej Fijalkowski <[email protected]>
Branch: refactor-signature
Changeset: r50500:a3a1fac3df73
Date: 2011-12-14 14:00 +0200
http://bitbucket.org/pypy/pypy/changeset/a3a1fac3df73/

Log:    enough to make test_sum pass. Reduce seems to nicely work

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
@@ -10,7 +10,7 @@
 from pypy.module.micronumpy.interp_iter import ArrayIterator
 
 numpy_driver = jit.JitDriver(
-    greens=['shapelen', 'signature'],
+    greens=['shapelen', 'sig'],
     virtualizables=['frame'],
     reds=['result_size', 'frame', 'ri', 'self', 'result']
 )
@@ -708,19 +708,13 @@
     def getitem(self, item):
         raise NotImplementedError
 
-    def start_iter(self, res_shape=None):
-        all_iters = self.signature.create_iter(self, {}, res_shape)
-        return NumpyEvalFrame(all_iters)
-
     def descr_debug_repr(self, space):
         return space.wrap(self.signature.debug_repr())
 
     def find_sig(self):
         """ find a correct signature for the array
         """
-        sig = self.create_sig()
-        sig.invent_numbering()
-        return signature.find_sig(sig)
+        return signature.find_sig(self.create_sig())
 
 def convert_to_array(space, w_obj):
     if isinstance(w_obj, BaseArray):
@@ -791,18 +785,18 @@
         result_size = self.find_size()
         result = W_NDimArray(result_size, self.shape, self.find_dtype())
         shapelen = len(self.shape)
-        signature = self.find_sig()
-        frame = signature.create_frame(self)
+        sig = self.find_sig()
+        frame = sig.create_frame(self)
         ri = ArrayIterator(result_size)
         while not ri.done():
-            numpy_driver.jit_merge_point(signature=signature,
+            numpy_driver.jit_merge_point(sig=sig,
                                          shapelen=shapelen,
                                          result_size=result_size,
                                          frame=frame,
                                          ri=ri,
                                          self=self, result=result)
             result.dtype.setitem(result.storage, ri.offset,
-                                 signature.eval(frame, self))
+                                 sig.eval(frame, self))
             frame.next(shapelen)
             ri = ri.next(shapelen)
         return result
@@ -987,13 +981,6 @@
             source_iter = source_iter.next(shapelen)
             res_iter = res_iter.next(shapelen)
 
-    # def start_iter(self, res_shape=None):
-    #     if res_shape is not None and res_shape != self.shape:
-    #         return BroadcastIterator(self, res_shape)
-    #     if len(self.shape) == 1:
-    #         return OneDimIterator(self.start, self.strides[0], self.shape[0])
-    #     return ViewIterator(self)
-
     def setitem(self, item, value):
         self.parent.setitem(item, value)
 
@@ -1054,13 +1041,6 @@
         self.invalidated()
         self.dtype.setitem(self.storage, item, value)
 
-    # def start_iter(self, res_shape=None):
-    #     if self.order == 'C':
-    #         if res_shape is not None and res_shape != self.shape:
-    #             return BroadcastIterator(self, res_shape)
-    #         return ArrayIterator(self.size)
-    #     raise NotImplementedError  # use ViewIterator simply, test it
-
     def setshape(self, space, new_shape):
         self.shape = new_shape
         self.calc_strides(new_shape)
@@ -1226,12 +1206,6 @@
         self.arr = arr
         self.iter = self.start_iter()
 
-    # def start_iter(self, res_shape=None):
-    #     if res_shape is not None and res_shape != self.shape:
-    #         return BroadcastIterator(self, res_shape)
-    #     return OneDimIterator(self.arr.start, self.strides[0],
-    #                           self.shape[0])
-
     def find_dtype(self):
         return self.arr.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
@@ -2,15 +2,16 @@
 from pypy.interpreter.error import OperationError, operationerrfmt
 from pypy.interpreter.gateway import interp2app, unwrap_spec
 from pypy.interpreter.typedef import TypeDef, GetSetProperty, 
interp_attrproperty
-from pypy.module.micronumpy import interp_boxes, interp_dtype, signature, types
+from pypy.module.micronumpy import interp_boxes, interp_dtype, types
+from pypy.module.micronumpy.signature import ReduceSignature, ScalarSignature, 
find_sig
 from pypy.rlib import jit
 from pypy.rlib.rarithmetic import LONG_BIT
 from pypy.tool.sourcetools import func_with_new_name
 
-
 reduce_driver = jit.JitDriver(
-    greens = ['shapelen', "signature"],
-    reds = ["i", "self", "dtype", "value", "obj"]
+    greens = ['shapelen', "sig"],
+    virtualizables = ["frame"],
+    reds = ["frame", "self", "dtype", "value", "obj"]
 )
 
 class W_Ufunc(Wrappable):
@@ -49,7 +50,8 @@
         return self.reduce(space, w_obj, multidim=False)
 
     def reduce(self, space, w_obj, multidim):
-        from pypy.module.micronumpy.interp_numarray import convert_to_array, 
Scalar
+        from pypy.module.micronumpy.interp_numarray import convert_to_array, 
Scalar, Call2
+        
         if self.argcount != 2:
             raise OperationError(space.w_ValueError, space.wrap("reduce only "
                 "supported for binary functions"))
@@ -65,8 +67,10 @@
             space, obj.find_dtype(),
             promote_to_largest=True
         )
-        start = obj.start_iter(obj.shape)
         shapelen = len(obj.shape)
+        sig = find_sig(ReduceSignature(self.func, ScalarSignature(dtype),
+                                       obj.create_sig()))
+        frame = sig.create_frame(obj)
         if shapelen > 1 and not multidim:
             raise OperationError(space.w_NotImplementedError,
                 space.wrap("not implemented yet"))
@@ -74,24 +78,20 @@
             if size == 0:
                 raise operationerrfmt(space.w_ValueError, "zero-size array to "
                     "%s.reduce without identity", self.name)
-            value = obj.eval(start).convert_to(dtype)
-            start = start.next(shapelen)
+            value = sig.eval(frame, obj).convert_to(dtype)
+            frame.next(shapelen)
         else:
             value = self.identity.convert_to(dtype)
-        new_sig = signature.find_sig(
-            signature.ReduceSignature(self.func, self.name,
-                                      dtype.scalar_signature,
-                                      obj.signature))
-        return self.reduce_loop(new_sig, shapelen, start, value, obj, dtype)
+        return self.reduce_loop(shapelen, sig, frame, value, obj, dtype)
 
-    def reduce_loop(self, signature, shapelen, i, value, obj, dtype):
-        while not i.done():
-            reduce_driver.jit_merge_point(signature=signature,
+    def reduce_loop(self, shapelen, sig, frame, value, obj, dtype):
+        while not frame.done():
+            reduce_driver.jit_merge_point(sig=sig,
                                           shapelen=shapelen, self=self,
-                                          value=value, obj=obj, i=i,
+                                          value=value, obj=obj, frame=frame,
                                           dtype=dtype)
-            value = self.func(dtype, value, obj.eval(i).convert_to(dtype))
-            i = i.next(shapelen)
+            value = self.func(dtype, value, sig.eval(frame, 
obj).convert_to(dtype))
+            frame.next(shapelen)
         return value
 
 class W_Ufunc1(W_Ufunc):
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
@@ -27,7 +27,12 @@
 known_sigs = r_dict(sigeq, sighash)
 
 def find_sig(sig):
-    return known_sigs.setdefault(sig, sig)
+    try:
+        return known_sigs[sig]
+    except KeyError:
+        sig.invent_numbering()
+        known_sigs[sig] = sig
+        return sig
 
 class NumpyEvalFrame(object):
     _virtualizable2_ = ['iterators[*]']
@@ -35,6 +40,16 @@
     def __init__(self, iterators):
         self = hint(self, access_directly=True)
         self.iterators = iterators
+        self.final_iter = None
+        for i, iter in enumerate(self.iterators):
+            if not isinstance(iter, ConstantIterator) or not isinstance(iter, 
BroadcastIterator):
+                self.final_iter = i
+                break
+        else:
+            raise Exception("Cannot find a non-broadcast non-constant iter")
+
+    def done(self):
+        return self.iterators[self.final_iter].done()
 
     @unroll_safe
     def next(self, shapelen):
@@ -185,4 +200,11 @@
                                       self.right.debug_repr())
 
 class ReduceSignature(Call2):
-    pass
+    def _create_iter(self, iterlist, arr, res_shape):
+        self.right._create_iter(iterlist, arr, res_shape)
+
+    def _invent_numbering(self, cache):
+        self.right._invent_numbering(cache)
+
+    def eval(self, frame, arr):
+        return self.right.eval(frame, arr)
diff --git a/pypy/module/micronumpy/test/test_base.py 
b/pypy/module/micronumpy/test/test_base.py
--- a/pypy/module/micronumpy/test/test_base.py
+++ b/pypy/module/micronumpy/test/test_base.py
@@ -4,7 +4,6 @@
 from pypy.module.micronumpy.interp_ufuncs import (find_binop_result_dtype,
         find_unaryop_result_dtype)
 
-
 class BaseNumpyAppTest(object):
     def setup_class(cls):
         cls.space = gettestobjspace(usemodules=['micronumpy'])
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to