Author: Maciej Fijalkowski <[email protected]>
Branch: refactor-signature
Changeset: r50719:2ab09b67b929
Date: 2011-12-19 22:51 +0200
http://bitbucket.org/pypy/pypy/changeset/2ab09b67b929/

Log:    implement virtualviews

diff --git a/pypy/module/micronumpy/interp_iter.py 
b/pypy/module/micronumpy/interp_iter.py
--- a/pypy/module/micronumpy/interp_iter.py
+++ b/pypy/module/micronumpy/interp_iter.py
@@ -1,6 +1,7 @@
 
 from pypy.rlib import jit
 from pypy.rlib.objectmodel import instantiate
+from pypy.module.micronumpy.strides import calculate_broadcast_strides
 
 # Iterators for arrays
 # --------------------
@@ -60,30 +61,24 @@
     def get_offset(self):
         return self.offset
 
+def view_iter_from_arr(arr):
+    return ViewIterator(arr.start, arr.strides, arr.backstrides, arr.shape)
+
 class ViewIterator(BaseIterator):
-    def __init__(self, arr, res_shape=None):
-        self.offset  = arr.start
+    def __init__(self, start, strides, backstrides, shape, res_shape=None):
+        self.offset  = start
         self._done   = False
-        if res_shape is not None and res_shape != arr.shape:
-            self.strides = []
-            self.backstrides = []
-            for i in range(len(arr.shape)):
-                if arr.shape[i] == 1:
-                    self.strides.append(0)
-                    self.backstrides.append(0)
-                else:
-                    self.strides.append(arr.strides[i])
-                    self.backstrides.append(arr.backstrides[i])
-            self.strides = [0] * (len(res_shape) - len(arr.shape)) + 
self.strides
-            self.backstrides = [0] * (len(res_shape) - len(arr.shape)) + 
self.backstrides
+        if res_shape is not None and res_shape != shape:
+            r = calculate_broadcast_strides(strides, backstrides,
+                                            shape, res_shape)
+            self.strides, self.backstrides = r
             self.res_shape = res_shape
         else:
-            self.strides = arr.strides
-            self.backstrides = arr.backstrides
-            self.res_shape = arr.shape
+            self.strides = strides
+            self.backstrides = backstrides
+            self.res_shape = shape
         self.indices = [0] * len(self.res_shape)
 
-
     @jit.unroll_safe
     def next(self, shapelen):
         offset = self.offset
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
@@ -3,12 +3,13 @@
 from pypy.interpreter.gateway import interp2app, unwrap_spec, NoneNotWrapped
 from pypy.interpreter.typedef import TypeDef, GetSetProperty
 from pypy.module.micronumpy import interp_ufuncs, interp_dtype, signature
+from pypy.module.micronumpy.strides import calculate_slice_strides
 from pypy.rlib import jit
 from pypy.rpython.lltypesystem import lltype, rffi
 from pypy.tool.sourcetools import func_with_new_name
 from pypy.rlib.rstring import StringBuilder
-from pypy.module.micronumpy.interp_iter import ArrayIterator, ViewIterator,\
-     OneDimIterator
+from pypy.module.micronumpy.interp_iter import ArrayIterator,\
+     view_iter_from_arr, OneDimIterator
 
 numpy_driver = jit.JitDriver(
     greens=['shapelen', 'sig'],
@@ -203,7 +204,7 @@
     return new_strides
 
 class BaseArray(Wrappable):
-    _attrs_ = ["invalidates", "shape"]
+    _attrs_ = ["invalidates", "shape", 'size']
 
     _immutable_fields_ = []
 
@@ -316,8 +317,7 @@
                 idx += 1
             return result
         def impl(self, space):
-            size = self.find_size()
-            if size == 0:
+            if self.size == 0:
                 raise OperationError(space.w_ValueError,
                     space.wrap("Can't call %s on zero-size arrays" % op_name))
             return space.wrap(loop(self))
@@ -380,13 +380,13 @@
 
     def descr_set_shape(self, space, w_iterable):
         new_shape = get_shape_from_iterable(space,
-                            self.find_size(), w_iterable)
+                            self.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())
+        return space.wrap(self.size)
 
     def descr_copy(self, space):
         return self.copy()
@@ -405,7 +405,7 @@
         res.append("array(")
         concrete = self.get_concrete()
         dtype = concrete.find_dtype()
-        if not concrete.find_size():
+        if not concrete.size:
             res.append('[]')
             if len(self.shape) > 1:
                 # An empty slice reports its shape
@@ -417,7 +417,7 @@
             concrete.to_str(space, 1, res, indent='       ')
         if (dtype is not interp_dtype.get_dtype_cache(space).w_float64dtype and
             dtype is not interp_dtype.get_dtype_cache(space).w_int64dtype) or \
-            not self.find_size():
+            not self.size:
             res.append(", dtype=" + dtype.name)
         res.append(")")
         return space.wrap(res.build())
@@ -428,7 +428,7 @@
         Multidimensional arrays/slices will span a number of lines,
         each line will begin with indent.
         '''
-        size = self.find_size()
+        size = self.size
         if size < 1:
             builder.append('[]')
             return
@@ -454,7 +454,7 @@
                             builder.append(indent)
                     # create_slice requires len(chunks) > 1 in order to reduce
                     # shape
-                    view = self.create_slice(space, [(i, 0, 0, 1), (0, 
self.shape[1], 1, self.shape[1])])
+                    view = self.create_slice([(i, 0, 0, 1), (0, self.shape[1], 
1, self.shape[1])])
                     view.to_str(space, comma, builder, indent=indent + ' ', 
use_ellipsis=use_ellipsis)
                 builder.append('\n' + indent + '..., ')
                 i = self.shape[0] - 3
@@ -469,7 +469,7 @@
                         builder.append(indent)
                 # create_slice requires len(chunks) > 1 in order to reduce
                 # shape
-                view = self.create_slice(space, [(i, 0, 0, 1), (0, 
self.shape[1], 1, self.shape[1])])
+                view = self.create_slice([(i, 0, 0, 1), (0, self.shape[1], 1, 
self.shape[1])])
                 view.to_str(space, comma, builder, indent=indent + ' ', 
use_ellipsis=use_ellipsis)
                 i += 1
         elif ndims == 1:
@@ -581,7 +581,7 @@
             item = concrete._index_of_single_item(space, w_idx)
             return concrete.getitem(item)
         chunks = self._prepare_slice_args(space, w_idx)
-        return space.wrap(self.create_slice(space, chunks))
+        return space.wrap(self.create_slice(chunks))
 
     def descr_setitem(self, space, w_idx, w_value):
         self.invalidated()
@@ -597,31 +597,24 @@
         if not isinstance(w_value, BaseArray):
             w_value = convert_to_array(space, w_value)
         chunks = self._prepare_slice_args(space, w_idx)
-        view = self.create_slice(space, chunks)
+        view = self.create_slice(chunks).get_concrete()
         view.setslice(space, w_value)
 
     @jit.unroll_safe
-    def create_slice(self, space, chunks):
-        #if not isinstance(self, ConcreteArray):
-        #    return VirtualSlice(self, chunks)
-        self = self.get_concrete()
+    def create_slice(self, chunks):
         shape = []
-        strides = []
-        backstrides = []
-        start = self.start
         i = -1
         for i, (start_, stop, step, lgt) in enumerate(chunks):
             if step != 0:
                 shape.append(lgt)
-                strides.append(self.strides[i] * step)
-                backstrides.append(self.strides[i] * (lgt - 1) * step)
-            start += self.strides[i] * start_
-        # add a reminder
         s = i + 1
         assert s >= 0
         shape += self.shape[s:]
-        strides += self.strides[s:]
-        backstrides += self.backstrides[s:]
+        if not isinstance(self, ConcreteArray):
+            return VirtualSlice(self, chunks, shape)
+        r = calculate_slice_strides(self.start, self.strides, self.backstrides,
+                                    chunks)
+        start, strides, backstrides = r
         return W_NDimSlice(start, strides[:], backstrides[:],
                            shape[:], self)
 
@@ -642,8 +635,7 @@
         else:
             w_shape = space.newtuple(args_w)
         concrete = self.get_concrete()
-        new_shape = get_shape_from_iterable(space,
-                                            concrete.find_size(), w_shape)
+        new_shape = get_shape_from_iterable(space, concrete.size, w_shape)
         # Since we got to here, prod(new_shape) == self.size
         new_strides = calc_new_strides(new_shape,
                                        concrete.shape, concrete.strides)
@@ -662,10 +654,10 @@
         return arr
 
     def descr_mean(self, space):
-        return space.div(self.descr_sum(space), space.wrap(self.find_size()))
+        return space.div(self.descr_sum(space), space.wrap(self.size))
 
     def descr_nonzero(self, space):
-        if self.find_size() > 1:
+        if self.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_or_scalar()
@@ -725,6 +717,7 @@
     """
     Intermediate class representing a literal.
     """
+    size = 1
     _attrs_ = ["dtype", "value", "shape"]
 
     def __init__(self, dtype, value):
@@ -733,9 +726,6 @@
         self.dtype = dtype
         self.value = value
 
-    def find_size(self):
-        return 1
-
     def find_dtype(self):
         return self.dtype
 
@@ -770,16 +760,15 @@
         raise NotImplementedError
 
     def compute(self):
-        result_size = self.find_size()
-        result = W_NDimArray(result_size, self.shape, self.find_dtype())
+        result = W_NDimArray(self.size, self.shape, self.find_dtype())
         shapelen = len(self.shape)
         sig = self.find_sig()
         frame = sig.create_frame(self)
-        ri = ArrayIterator(result_size)
+        ri = ArrayIterator(self.size)
         while not ri.done():
             numpy_driver.jit_merge_point(sig=sig,
                                          shapelen=shapelen,
-                                         result_size=result_size,
+                                         result_size=self.size,
                                          frame=frame,
                                          ri=ri,
                                          self=self, result=result)
@@ -804,33 +793,43 @@
     def setitem(self, item, value):
         return self.get_concrete().setitem(item, value)
 
-    def find_size(self):
-        if self.forced_result is not None:
-            # The result has been computed and sources may be unavailable
-            return self.forced_result.find_size()
-        return self._find_size()
-
     def find_dtype(self):
         return self.res_dtype
 
 class VirtualSlice(VirtualArray):
-    def __init__(self, parent, chunks):
-        self.parent = parent
+    def __init__(self, child, chunks, shape):
+        size = 1
+        for sh in shape:
+            size *= sh
+        self.child = child
         self.chunks = chunks
-        VirtualArray.__init__(self, 'slice', parent.shape, parent.find_dtype())
+        self.size = size
+        VirtualArray.__init__(self, 'slice', shape, child.find_dtype())
+
+    def create_sig(self, res_shape):
+        if self.forced_result is not None:
+            return self.forced_result.create_sig(res_shape)
+        return signature.VirtualSliceSignature(
+            self.child.create_sig(res_shape))
+
+    def force_if_needed(self):
+        if self.forced_result is None:
+            concr = self.child.get_concrete()
+            self.forced_result = concr.create_slice(self.chunks)
+
+    def _del_sources(self):
+        self.child = None
 
 class Call1(VirtualArray):
     def __init__(self, ufunc, name, shape, res_dtype, values):
         VirtualArray.__init__(self, name, shape, res_dtype)
         self.values = values
+        self.size = values.size
         self.ufunc = ufunc
 
     def _del_sources(self):
         self.values = None
 
-    def _find_size(self):
-        return self.values.find_size()
-
     def _find_dtype(self):
         return self.res_dtype
 
@@ -858,9 +857,6 @@
         self.left = None
         self.right = None
 
-    def _find_size(self):
-        return self.size
-
     def create_sig(self, res_shape):
         if self.forced_result is not None:
             return self.forced_result.array_sig(res_shape)
@@ -891,9 +887,6 @@
     def get_concrete(self):
         return self
 
-    def find_size(self):
-        return self.size
-
     def find_dtype(self):
         return self.dtype
 
@@ -933,7 +926,7 @@
 class ViewArray(ConcreteArray):
     def copy(self):
         array = W_NDimArray(self.size, self.shape[:], self.find_dtype())
-        iter = ViewIterator(self)
+        iter = view_iter_from_arr(self)
         a_iter = ArrayIterator(array.size)
         while not iter.done():
             array.setitem(a_iter.offset, self.getitem(iter.offset))
@@ -965,7 +958,7 @@
     def _sliceloop(self, source, res_shape):
         sig = source.find_sig(res_shape)
         frame = sig.create_frame(source, res_shape)
-        res_iter = ViewIterator(self)
+        res_iter = view_iter_from_arr(self)
         shapelen = len(res_shape)
         while not res_iter.done():
             slice_driver.jit_merge_point(sig=sig,
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
@@ -62,7 +62,7 @@
             raise OperationError(space.w_TypeError, space.wrap("cannot reduce "
                 "on a scalar"))
 
-        size = obj.find_size()
+        size = obj.size
         dtype = find_unaryop_result_dtype(
             space, obj.find_dtype(),
             promote_to_largest=True
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
@@ -2,7 +2,7 @@
 from pypy.rlib.rarithmetic import intmask
 from pypy.module.micronumpy.interp_iter import ViewIterator, ArrayIterator, \
      OneDimIterator, ConstantIterator
-from pypy.rpython.lltypesystem.llmemory import cast_ptr_to_adr
+from pypy.module.micronumpy.strides import calculate_slice_strides
 from pypy.rlib.jit import hint, unroll_safe, promote
 
 def sigeq(one, two):
@@ -92,7 +92,7 @@
         res_shape = res_shape or arr.shape
         iterlist = []
         arraylist = []
-        self._create_iter(iterlist, arraylist, arr, res_shape)
+        self._create_iter(iterlist, arraylist, arr, res_shape, [])
         return NumpyEvalFrame(iterlist, arraylist)
 
 class ConcreteSignature(Signature):
@@ -113,23 +113,39 @@
     def hash(self):
         return compute_identity_hash(self.dtype)
 
+    def allocate_view_iter(self, arr, res_shape, chunklist):
+        r = arr.start, arr.strides, arr.backstrides
+        if chunklist:
+            for chunkelem in chunklist:
+                r = calculate_slice_strides(r[0], r[1], r[2], chunkelem)
+        start, strides, backstrides = r
+        if len(res_shape) == 1:
+            return OneDimIterator(start, strides[0], res_shape[0])
+        return ViewIterator(start, strides, backstrides, arr.shape, res_shape)
+
 class ArraySignature(ConcreteSignature):
     def debug_repr(self):
         return 'Array'
 
     def _invent_array_numbering(self, arr, cache):
-        storage = arr.get_concrete().storage
-        self.array_no = _add_ptr_to_cache(storage, cache)
+        from pypy.module.micronumpy.interp_numarray import ConcreteArray
+        concr = arr.get_concrete()
+        assert isinstance(concr, ConcreteArray)
+        self.array_no = _add_ptr_to_cache(concr.storage, cache)
 
-    def _create_iter(self, iterlist, arraylist, arr, res_shape):
+    def _create_iter(self, iterlist, arraylist, arr, res_shape, chunklist):
+        from pypy.module.micronumpy.interp_numarray import ConcreteArray
         concr = arr.get_concrete()
+        assert isinstance(concr, ConcreteArray)
         storage = concr.storage
         if self.iter_no >= len(iterlist):
-            iterlist.append(self.allocate_iter(concr, res_shape))
+            iterlist.append(self.allocate_iter(concr, res_shape, chunklist))
         if self.array_no >= len(arraylist):
             arraylist.append(storage)
 
-    def allocate_iter(self, arr, res_shape):
+    def allocate_iter(self, arr, res_shape, chunklist):
+        if chunklist:
+            return self.allocate_view_iter(arr, res_shape, chunklist)
         return ArrayIterator(arr.size)
 
     def eval(self, frame, arr):
@@ -143,7 +159,7 @@
     def _invent_array_numbering(self, arr, cache):
         pass
 
-    def _create_iter(self, iterlist, arraylist, arr, res_shape):
+    def _create_iter(self, iterlist, arraylist, arr, res_shape, chunklist):
         if self.iter_no >= len(iterlist):
             iter = ConstantIterator()
             iterlist.append(iter)
@@ -163,17 +179,38 @@
         allnumbers.append(no)
         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)
+    def allocate_iter(self, arr, res_shape, chunklist):
+        return self.allocate_view_iter(arr, res_shape, chunklist)
 
-class FlatiterSignature(ViewSignature):
-    def debug_repr(self):
-        return 'FlatIter(%s)' % self.child.debug_repr()
+class VirtualSliceSignature(Signature):
+    def __init__(self, child):
+        self.child = child
 
-    def _create_iter(self, iterlist, arraylist, arr, res_shape):
-        raise NotImplementedError
+    def _invent_array_numbering(self, arr, cache):
+        from pypy.module.micronumpy.interp_numarray import VirtualSlice
+        assert isinstance(arr, VirtualSlice)
+        self.child._invent_array_numbering(arr.child, cache)
+
+    def hash(self):
+        return intmask(self.child.hash() ^ 1234)
+
+    def eq(self, other, compare_array_no=True):
+        if type(self) is not type(other):
+            return False
+        assert isinstance(other, VirtualSliceSignature)
+        return self.child.eq(other.child, compare_array_no)
+
+    def _create_iter(self, iterlist, arraylist, arr, res_shape, chunklist):
+        from pypy.module.micronumpy.interp_numarray import VirtualSlice
+        assert isinstance(arr, VirtualSlice)
+        chunklist.append(arr.chunks)
+        self.child._create_iter(iterlist, arraylist, arr.child, res_shape,
+                                chunklist)
+
+    def eval(self, frame, arr):
+        from pypy.module.micronumpy.interp_numarray import VirtualSlice
+        assert isinstance(arr, VirtualSlice)
+        return self.child.eval(frame, arr.child)
 
 class Call1(Signature):
     _immutable_fields_ = ['unfunc', 'name', 'child']
@@ -204,10 +241,11 @@
         assert isinstance(arr, Call1)
         self.child._invent_array_numbering(arr.values, cache)
 
-    def _create_iter(self, iterlist, arraylist, arr, res_shape):
+    def _create_iter(self, iterlist, arraylist, arr, res_shape, chunklist):
         from pypy.module.micronumpy.interp_numarray import Call1
         assert isinstance(arr, Call1)
-        self.child._create_iter(iterlist, arraylist, arr.values, res_shape)
+        self.child._create_iter(iterlist, arraylist, arr.values, res_shape,
+                                chunklist)
 
     def eval(self, frame, arr):
         from pypy.module.micronumpy.interp_numarray import Call1
@@ -248,12 +286,14 @@
         self.left._invent_numbering(cache, allnumbers)
         self.right._invent_numbering(cache, allnumbers)
 
-    def _create_iter(self, iterlist, arraylist, arr, res_shape):
+    def _create_iter(self, iterlist, arraylist, arr, res_shape, chunklist):
         from pypy.module.micronumpy.interp_numarray import Call2
         
         assert isinstance(arr, Call2)
-        self.left._create_iter(iterlist, arraylist, arr.left, res_shape)
-        self.right._create_iter(iterlist, arraylist, arr.right, res_shape)
+        self.left._create_iter(iterlist, arraylist, arr.left, res_shape,
+                               chunklist)
+        self.right._create_iter(iterlist, arraylist, arr.right, res_shape,
+                                chunklist)
 
     def eval(self, frame, arr):
         from pypy.module.micronumpy.interp_numarray import Call2
@@ -267,8 +307,8 @@
                                       self.right.debug_repr())
 
 class ReduceSignature(Call2):
-    def _create_iter(self, iterlist, arraylist, arr, res_shape):
-        self.right._create_iter(iterlist, arraylist, arr, res_shape)
+    def _create_iter(self, iterlist, arraylist, arr, res_shape, chunklist):
+        self.right._create_iter(iterlist, arraylist, arr, res_shape, chunklist)
 
     def _invent_numbering(self, cache, allnumbers):
         self.right._invent_numbering(cache, allnumbers)
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
@@ -57,6 +57,9 @@
         v3 = v2.descr_add(space, v1)
         v4 = v1.descr_add(space, v2)
         assert v3.find_sig() is v4.find_sig()
+        v5 = ar.descr_add(space, ar).descr_getitem(space, space.wrap(slice(1, 
3, 1)))
+        v6 = ar.descr_add(space, ar).descr_getitem(space, space.wrap(slice(1, 
4, 1)))
+        assert v5.find_sig() is v6.find_sig()
 
 class TestUfuncCoerscion(object):
     def test_binops(self, space):
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
@@ -36,92 +36,86 @@
         assert a.backstrides == [135, 12, 2]
 
     def test_create_slice_f(self):
-        space = self.space
         a = W_NDimArray(10 * 5 * 3, [10, 5, 3], MockDtype(), 'F')
-        s = a.create_slice(space, [(3, 0, 0, 1)])
+        s = a.create_slice([(3, 0, 0, 1)])
         assert s.start == 3
         assert s.strides == [10, 50]
         assert s.backstrides == [40, 100]
-        s = a.create_slice(space, [(1, 9, 2, 4)])
+        s = a.create_slice([(1, 9, 2, 4)])
         assert s.start == 1
         assert s.strides == [2, 10, 50]
         assert s.backstrides == [6, 40, 100]
-        s = a.create_slice(space, [(1, 5, 3, 2), (1, 2, 1, 1), (1, 0, 0, 1)])
+        s = a.create_slice([(1, 5, 3, 2), (1, 2, 1, 1), (1, 0, 0, 1)])
         assert s.shape == [2, 1]
         assert s.strides == [3, 10]
         assert s.backstrides == [3, 0]
-        s = a.create_slice(space, [(0, 10, 1, 10), (2, 0, 0, 1)])
+        s = a.create_slice([(0, 10, 1, 10), (2, 0, 0, 1)])
         assert s.start == 20
         assert s.shape == [10, 3]
 
     def test_create_slice_c(self):
-        space = self.space
         a = W_NDimArray(10 * 5 * 3, [10, 5, 3], MockDtype(), 'C')
-        s = a.create_slice(space, [(3, 0, 0, 1)])
+        s = a.create_slice([(3, 0, 0, 1)])
         assert s.start == 45
         assert s.strides == [3, 1]
         assert s.backstrides == [12, 2]
-        s = a.create_slice(space, [(1, 9, 2, 4)])
+        s = a.create_slice([(1, 9, 2, 4)])
         assert s.start == 15
         assert s.strides == [30, 3, 1]
         assert s.backstrides == [90, 12, 2]
-        s = a.create_slice(space, [(1, 5, 3, 2), (1, 2, 1, 1), (1, 0, 0, 1)])
+        s = a.create_slice([(1, 5, 3, 2), (1, 2, 1, 1), (1, 0, 0, 1)])
         assert s.start == 19
         assert s.shape == [2, 1]
         assert s.strides == [45, 3]
         assert s.backstrides == [45, 0]
-        s = a.create_slice(space, [(0, 10, 1, 10), (2, 0, 0, 1)])
+        s = a.create_slice([(0, 10, 1, 10), (2, 0, 0, 1)])
         assert s.start == 6
         assert s.shape == [10, 3]
 
     def test_slice_of_slice_f(self):
-        space = self.space
         a = W_NDimArray(10 * 5 * 3, [10, 5, 3], MockDtype(), 'F')
-        s = a.create_slice(space, [(5, 0, 0, 1)])
+        s = a.create_slice([(5, 0, 0, 1)])
         assert s.start == 5
-        s2 = s.create_slice(space, [(3, 0, 0, 1)])
+        s2 = s.create_slice([(3, 0, 0, 1)])
         assert s2.shape == [3]
         assert s2.strides == [50]
         assert s2.parent is a
         assert s2.backstrides == [100]
         assert s2.start == 35
-        s = a.create_slice(space, [(1, 5, 3, 2)])
-        s2 = s.create_slice(space, [(0, 2, 1, 2), (2, 0, 0, 1)])
+        s = a.create_slice([(1, 5, 3, 2)])
+        s2 = s.create_slice([(0, 2, 1, 2), (2, 0, 0, 1)])
         assert s2.shape == [2, 3]
         assert s2.strides == [3, 50]
         assert s2.backstrides == [3, 100]
         assert s2.start == 1 * 15 + 2 * 3
 
     def test_slice_of_slice_c(self):
-        space = self.space
         a = W_NDimArray(10 * 5 * 3, [10, 5, 3], MockDtype(), order='C')
-        s = a.create_slice(space, [(5, 0, 0, 1)])
+        s = a.create_slice([(5, 0, 0, 1)])
         assert s.start == 15 * 5
-        s2 = s.create_slice(space, [(3, 0, 0, 1)])
+        s2 = s.create_slice([(3, 0, 0, 1)])
         assert s2.shape == [3]
         assert s2.strides == [1]
         assert s2.parent is a
         assert s2.backstrides == [2]
         assert s2.start == 5 * 15 + 3 * 3
-        s = a.create_slice(space, [(1, 5, 3, 2)])
-        s2 = s.create_slice(space, [(0, 2, 1, 2), (2, 0, 0, 1)])
+        s = a.create_slice([(1, 5, 3, 2)])
+        s2 = s.create_slice([(0, 2, 1, 2), (2, 0, 0, 1)])
         assert s2.shape == [2, 3]
         assert s2.strides == [45, 1]
         assert s2.backstrides == [45, 2]
         assert s2.start == 1 * 15 + 2 * 3
 
     def test_negative_step_f(self):
-        space = self.space
         a = W_NDimArray(10 * 5 * 3, [10, 5, 3], MockDtype(), 'F')
-        s = a.create_slice(space, [(9, -1, -2, 5)])
+        s = a.create_slice([(9, -1, -2, 5)])
         assert s.start == 9
         assert s.strides == [-2, 10, 50]
         assert s.backstrides == [-8, 40, 100]
 
     def test_negative_step_c(self):
-        space = self.space
         a = W_NDimArray(10 * 5 * 3, [10, 5, 3], MockDtype(), order='C')
-        s = a.create_slice(space, [(9, -1, -2, 5)])
+        s = a.create_slice([(9, -1, -2, 5)])
         assert s.start == 135
         assert s.strides == [-30, 3, 1]
         assert s.backstrides == [-120, 12, 2]
@@ -130,7 +124,7 @@
         a = W_NDimArray(10 * 5 * 3, [10, 5, 3], MockDtype(), 'F')
         r = a._index_of_single_item(self.space, self.newtuple(1, 2, 2))
         assert r == 1 + 2 * 10 + 2 * 50
-        s = a.create_slice(self.space, [(0, 10, 1, 10), (2, 0, 0, 1)])
+        s = a.create_slice([(0, 10, 1, 10), (2, 0, 0, 1)])
         r = s._index_of_single_item(self.space, self.newtuple(1, 0))
         assert r == a._index_of_single_item(self.space, self.newtuple(1, 2, 0))
         r = s._index_of_single_item(self.space, self.newtuple(1, 1))
@@ -140,7 +134,7 @@
         a = W_NDimArray(10 * 5 * 3, [10, 5, 3], MockDtype(), 'C')
         r = a._index_of_single_item(self.space, self.newtuple(1, 2, 2))
         assert r == 1 * 3 * 5 + 2 * 3 + 2
-        s = a.create_slice(self.space, [(0, 10, 1, 10), (2, 0, 0, 1)])
+        s = a.create_slice([(0, 10, 1, 10), (2, 0, 0, 1)])
         r = s._index_of_single_item(self.space, self.newtuple(1, 0))
         assert r == a._index_of_single_item(self.space, self.newtuple(1, 2, 0))
         r = s._index_of_single_item(self.space, self.newtuple(1, 1))
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
@@ -193,7 +193,7 @@
         # 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': 20,
+        self.check_resops({'setinteriorfield_raw': 4, 'getfield_gc': 22,
                            'getarrayitem_gc_pure': 2,
                            'getfield_gc_pure': 4,
                            'guard_class': 8, 'int_add': 8, 'float_mul': 2,
@@ -342,7 +342,24 @@
         self.check_simple_loop({'getinteriorfield_raw': 2, 'float_add' : 1,
                                 'setinteriorfield_raw': 1, 'int_add': 3,
                                 'int_lt': 1, 'guard_true': 1, 'jump': 1,
-                                'arraylen_gc': 2})
+                                'arraylen_gc': 3})
+
+    def define_virtual_slice():
+        return """
+        a = |30|
+        c = a + a
+        d = c -> 1:20
+        d -> 1
+        """
+
+    def test_virtual_slice(self):
+        result = self.run("virtual_slice")
+        assert result == 4
+        self.check_loop_count(1)
+        self.check_simple_loop({'getinteriorfield_raw': 2, 'float_add' : 1,
+                                'setinteriorfield_raw': 1, 'int_add': 2,
+                                'int_ge': 1, 'guard_false': 1, 'jump': 1,
+                                'arraylen_gc': 1})
 
 class TestNumpyOld(LLJitMixin):
     def setup_class(cls):
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to