[pypy-commit] pypy refactor-signature: rpythonization and test_zjit fixes

fijal noreply at buildbot.pypy.org
Mon Dec 19 18:37:11 CET 2011


Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: refactor-signature
Changeset: r50716:44fdf6f32ded
Date: 2011-12-19 19:36 +0200
http://bitbucket.org/pypy/pypy/changeset/44fdf6f32ded/

Log:	rpythonization and test_zjit fixes

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
@@ -379,18 +379,19 @@
         return space.newtuple([space.wrap(i) for i in self.shape])
 
     def descr_set_shape(self, space, w_iterable):
-        concrete = self.get_concrete()
         new_shape = get_shape_from_iterable(space,
-                            concrete.find_size(), w_iterable)
-        if isinstance(self, ConcreteArray):
-            # scalars don't have to do anything, just check if the shape
-            # is still empty
-            concrete.setshape(space, new_shape)
+                            self.find_size(), w_iterable)
+        if isinstance(self, Scalar):
+            return
+        self.get_concrete().setshape(space, new_shape)
 
     def descr_get_size(self, space):
         return space.wrap(self.find_size())
 
     def descr_copy(self, space):
+        return self.copy()
+
+    def copy(self):
         return self.get_concrete().copy()
 
     def descr_len(self, space):
@@ -506,7 +507,7 @@
 
     def descr_str(self, space):
         ret = StringBuilder()
-        concrete = self.get_concrete()
+        concrete = self.get_concrete_or_scalar()
         concrete.to_str(space, 0, ret, ' ')
         return space.wrap(ret.build())
 
@@ -679,12 +680,15 @@
         if self.find_size() > 1:
             raise OperationError(space.w_ValueError, space.wrap(
                 "The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()"))
-        concr = self.get_concrete()
+        concr = self.get_concrete_or_scalar()
         sig = concr.find_sig()
         frame = sig.create_frame(self)
         return space.wrap(space.is_true(
             sig.eval(frame, concr)))
 
+    def get_concrete_or_scalar(self):
+        return self.get_concrete()
+
     def descr_get_transpose(self, space):
         concrete = self.get_concrete()
         if len(concrete.shape) < 2:
@@ -743,9 +747,6 @@
     def find_size(self):
         return 1
 
-    def get_concrete(self):
-        return self
-
     def find_dtype(self):
         return self.dtype
 
@@ -758,14 +759,12 @@
     def copy(self):
         return Scalar(self.dtype, self.value)
 
-    def setshape(self, space, new_shape):
-        # In order to get here, we already checked that prod(new_shape) == 1,
-        # so in order to have a consistent API, let it go through.
-        pass
-
     def create_sig(self, res_shape):
         return signature.ScalarSignature(self.dtype)
 
+    def get_concrete_or_scalar(self):
+        return self
+
 class VirtualArray(BaseArray):
     """
     Class for representing virtual arrays, such as binary ops or ufuncs
@@ -935,7 +934,22 @@
             return signature.ViewSignature(self.dtype)
         return signature.ArraySignature(self.dtype)
 
-class W_NDimSlice(ConcreteArray):
+class ViewArray(ConcreteArray):
+    def copy(self):
+        array = W_NDimArray(self.size, self.shape[:], self.find_dtype())
+        iter = ViewIterator(self)
+        a_iter = ArrayIterator(array.size)
+        while not iter.done():
+            array.setitem(a_iter.offset, self.getitem(iter.offset))
+            iter = iter.next(len(self.shape))
+            a_iter = a_iter.next(len(array.shape))
+        return array
+
+    def create_sig(self, res_shape):
+        return signature.ViewSignature(self.dtype)
+    
+
+class W_NDimSlice(ViewArray):
     def __init__(self, start, strides, backstrides, shape, parent):
         if isinstance(parent, W_NDimSlice):
             parent = parent.parent
@@ -968,19 +982,6 @@
             frame.next(shapelen)
             res_iter = res_iter.next(shapelen)
 
-    def copy(self):
-        array = W_NDimArray(self.size, self.shape[:], self.find_dtype())
-        iter = ViewIterator(self)
-        a_iter = ArrayIterator(array.size)
-        while not iter.done():
-            array.setitem(a_iter.offset, self.getitem(iter.offset))
-            iter = iter.next(len(self.shape))
-            a_iter = a_iter.next(len(array.shape))
-        return array
-
-    def create_sig(self, res_shape):
-        return signature.ViewSignature(self.dtype)
-
     def setshape(self, space, new_shape):
         if len(self.shape) < 1:
             return
@@ -1180,37 +1181,31 @@
 )
 
 
-class W_FlatIterator(ConcreteArray):
+class W_FlatIterator(ViewArray):
 
     @jit.unroll_safe
     def __init__(self, arr):
         size = 1
         for sh in arr.shape:
             size *= sh
-        ConcreteArray.__init__(self, arr.get_concrete(), [arr.strides[-1]],
-                               [arr.backstrides[-1]], [size])
+        self.strides = [arr.strides[-1]]
+        self.backstrides = [arr.backstrides[-1]]
+        ConcreteArray.__init__(self, size, [size], arr.dtype, arr.order,
+                               arr)
         self.shapelen = len(arr.shape)
-        self.arr = arr
-        self.iter = OneDimIterator(self.arr.start, self.strides[0],
-                                   arr.shape[0])
-
-    def find_dtype(self):
-        return self.arr.find_dtype()
-
-    def find_size(self):
-        return self.shape[0]
+        self.iter = OneDimIterator(arr.start, self.strides[0],
+                                   self.shape[0])
 
     def descr_next(self, space):
         if self.iter.done():
             raise OperationError(space.w_StopIteration, space.w_None)
-        result = self.eval(self.iter)
+        result = self.getitem(self.iter.offset)
         self.iter = self.iter.next(self.shapelen)
         return result
 
     def descr_iter(self):
         return self
 
-
 W_FlatIterator.typedef = TypeDef(
     'flatiter',
     next = interp2app(W_FlatIterator.descr_next),
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
@@ -122,9 +122,10 @@
         self.array_no = _add_ptr_to_cache(storage, cache)
 
     def _create_iter(self, iterlist, arraylist, arr, res_shape):
-        storage = arr.get_concrete().storage
+        concr = arr.get_concrete()
+        storage = concr.storage
         if self.iter_no >= len(iterlist):
-            iterlist.append(self.allocate_iter(arr, res_shape))
+            iterlist.append(self.allocate_iter(concr, res_shape))
         if self.array_no >= len(arraylist):
             arraylist.append(storage)
 
@@ -163,6 +164,8 @@
         self.iter_no = no
 
     def allocate_iter(self, arr, res_shape):
+        if len(res_shape) == 1:
+            return OneDimIterator(arr.start, arr.strides[0], res_shape[0])
         return ViewIterator(arr, res_shape)
 
 class FlatiterSignature(ViewSignature):
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
@@ -871,7 +871,7 @@
         assert (a + a).__debug_repr__() == 'Call2(add, Array, Array)'
         assert (a[::2]).__debug_repr__() == 'Slice'
         assert (a + 2).__debug_repr__() == 'Call2(add, Array, Scalar)'
-        #assert (a + a.flat).__debug_repr__() == 'Call2(add, Array, FlatIter(Array))'
+        assert (a + a.flat).__debug_repr__() == 'Call2(add, Array, Slice)'
         assert sin(a).__debug_repr__() == 'Call1(sin, Array)'
         b = a + a
         b[0] = 3
@@ -1087,7 +1087,6 @@
         assert(b[:, 0] == a[0, :]).all()
 
     def test_flatiter(self):
-        skip("unsupported")
         from numpypy import array, flatiter
         a = array([[10, 30], [40, 60]])
         f_iter = a.flat
@@ -1103,7 +1102,6 @@
         assert s == 140
 
     def test_flatiter_array_conv(self):
-        skip("unsupported")
         from numpypy import array, dot
         a = array([1, 2, 3])
         assert dot(a.flat, a.flat) == 14
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
@@ -49,7 +49,7 @@
             interp.run(space)
             w_res = interp.results[-1]
             if isinstance(w_res, BaseArray):
-                concr = w_res.get_concrete()
+                concr = w_res.get_concrete_or_scalar()
                 sig = concr.find_sig()
                 frame = sig.create_frame(concr)
                 w_res = sig.eval(frame, concr)
@@ -83,7 +83,8 @@
         result = self.run("add")
         self.check_simple_loop({'getinteriorfield_raw': 2, 'float_add': 1,
                                 'setinteriorfield_raw': 1, 'int_add': 2,
-                                'int_ge': 1, 'guard_false': 1, 'jump': 1})
+                                'int_ge': 1, 'guard_false': 1, 'jump': 1,
+                                'arraylen_gc': 1})
         assert result == 3 + 3
 
     def define_float_add():
@@ -97,7 +98,8 @@
         assert result == 3 + 3
         self.check_simple_loop({"getinteriorfield_raw": 1, "float_add": 1,
                                 "setinteriorfield_raw": 1, "int_add": 2,
-                                "int_ge": 1, "guard_false": 1, "jump": 1})
+                                "int_ge": 1, "guard_false": 1, "jump": 1,
+                                'arraylen_gc': 1})
 
     def define_sum():
         return """
@@ -111,7 +113,7 @@
         assert result == 2 * sum(range(30))
         self.check_simple_loop({"getinteriorfield_raw": 2, "float_add": 2,
                                 "int_add": 1, "int_ge": 1, "guard_false": 1,
-                                "jump": 1})
+                                "jump": 1, 'arraylen_gc': 1})
 
     def define_prod():
         return """
@@ -128,7 +130,8 @@
         assert result == expected
         self.check_simple_loop({"getinteriorfield_raw": 2, "float_add": 1,
                                 "float_mul": 1, "int_add": 1,
-                                "int_ge": 1, "guard_false": 1, "jump": 1})
+                                "int_ge": 1, "guard_false": 1, "jump": 1,
+                                'arraylen_gc': 1})
 
     def define_max():
         return """
@@ -173,7 +176,7 @@
         self.check_simple_loop({"getinteriorfield_raw": 2, "float_add": 1,
                                 "float_ne": 1, "int_add": 1,
                                 "int_ge": 1, "jump": 1,
-                                "guard_false": 2})
+                                "guard_false": 2, 'arraylen_gc': 1})
 
     def define_already_forced():
         return """
@@ -190,12 +193,13 @@
         # This is the sum of the ops for both loops, however if you remove the
         # optimization then you end up with 2 float_adds, so we can still be
         # sure it was optimized correctly.
-        self.check_resops({'setinteriorfield_raw': 4, 'getfield_gc': 19,
-                           'getfield_gc_pure': 6,
+        self.check_resops({'setinteriorfield_raw': 4, 'getfield_gc': 20,
+                           'getarrayitem_gc_pure': 2,
+                           'getfield_gc_pure': 4,
                            'guard_class': 8, 'int_add': 8, 'float_mul': 2,
                            'jump': 4, 'int_ge': 4,
-                           'getinteriorfield_raw': 4, 'float_add': 2, 'guard_false': 4,
-                           })
+                           'getinteriorfield_raw': 4, 'float_add': 2,
+                           'guard_false': 4, 'arraylen_gc': 2})
 
     def define_ufunc():
         return """
@@ -210,7 +214,8 @@
         assert result == -6
         self.check_simple_loop({"getinteriorfield_raw": 2, "float_add": 1, "float_neg": 1,
                                 "setinteriorfield_raw": 1, "int_add": 2,
-                                "int_ge": 1, "guard_false": 1, "jump": 1})
+                                "int_ge": 1, "guard_false": 1, "jump": 1,
+                                'arraylen_gc': 1})
 
     def define_specialization():
         return """
@@ -253,7 +258,8 @@
                                 'setinteriorfield_raw': 1,
                                 'int_add': 3,
                                 'int_ge': 1, 'guard_false': 1,
-                                'jump': 1})
+                                'jump': 1,
+                                'arraylen_gc': 1})
 
     def define_slice2():
         return """
@@ -269,7 +275,8 @@
         assert result == 15
         self.check_simple_loop({'getinteriorfield_raw': 2, 'float_add': 1,
                                 'setinteriorfield_raw': 1, 'int_add': 3,
-                                'int_ge': 1, 'guard_false': 1, 'jump': 1})
+                                'int_ge': 1, 'guard_false': 1, 'jump': 1,
+                                'arraylen_gc': 1})
 
     def define_multidim():
         return """
@@ -284,8 +291,9 @@
         # int_add might be 1 here if we try slightly harder with
         # reusing indexes or some optimization
         self.check_simple_loop({'float_add': 1, 'getinteriorfield_raw': 2,
-                                'guard_false': 1, 'int_add': 3, 'int_ge': 1,
-                                'jump': 1, 'setinteriorfield_raw': 1})
+                                'guard_false': 1, 'int_add': 2, 'int_ge': 1,
+                                'jump': 1, 'setinteriorfield_raw': 1,
+                                'arraylen_gc': 1})
 
     def define_multidim_slice():
         return """
@@ -333,7 +341,8 @@
         self.check_loop_count(1)
         self.check_simple_loop({'getinteriorfield_raw': 2, 'float_add' : 1,
                                 'setinteriorfield_raw': 1, 'int_add': 3,
-                                'int_eq': 1, 'guard_false': 1, 'jump': 1})
+                                'int_lt': 1, 'guard_true': 1, 'jump': 1,
+                                'arraylen_gc': 2})
 
 class TestNumpyOld(LLJitMixin):
     def setup_class(cls):


More information about the pypy-commit mailing list