[pypy-commit] pypy numppy-flatitter: setitem, getitem work, add failing tests for comparison ops

mattip noreply at buildbot.pypy.org
Wed Jan 25 02:02:39 CET 2012


Author: mattip
Branch: numppy-flatitter
Changeset: r51750:d73d63090af7
Date: 2012-01-25 03:00 +0200
http://bitbucket.org/pypy/pypy/changeset/d73d63090af7/

Log:	setitem, getitem work, add failing tests for comparison ops

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
@@ -133,6 +133,13 @@
         res._done = done
         return res
 
+    @jit.unroll_safe
+    def next_skip_x(self, shapelen, step):
+        res = self.next(shapelen)
+        for x in range(step-1):
+            res = res.next(shapelen)
+        return res
+
     def apply_transformations(self, arr, transformations):
         v = BaseIterator.apply_transformations(self, arr, transformations)
         if len(arr.shape) == 1:
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
@@ -898,6 +898,7 @@
         self.size = 1
         for s in self.shape:
             self.size *= s
+        xxx
 
     def _del_sources(self):
         self.left = None
@@ -1407,6 +1408,7 @@
 )
 
 #TODO:Move all this to another file after fijal finishes reorganization
+ at jit.unroll_safe
 def _to_coords(space, arr, w_item_or_slice):
     '''Returns a start coord, step, and length.
     '''
@@ -1420,7 +1422,7 @@
     elif space.isinstance_w(w_item_or_slice, space.w_slice):
         start, stop, step, lngth = space.decode_index4(w_item_or_slice,arr.size)
     else:
-        raise OperationError(space.w_IndexError, 
+        raise OperationError(space.w_IndexError,
                              space.wrap('unsupported iterator index'))
     coords = []
     i = start
@@ -1436,9 +1438,10 @@
             i /= arr.shape[s]
     if i != 0:
         raise OperationError(space.w_IndexError, space.wrap("invalid index"))
-            
-    retval = [coords, step, lngth]
-    return retval 
+
+    retval = [coords, start, step, lngth]
+    return retval
+
 
 class W_FlatIterator(ViewArray):
 
@@ -1471,67 +1474,69 @@
         return space.newtuple([space.wrap(c) for c in coords])
 
     def descr_getitem(self, space, w_idx):
-        coords,step,lngth = _to_coords(space, self.base, w_idx)
-        if lngth > 1:
-            res = W_NDimArray(lngth, [lngth], self.base.dtype,
-                                        self.base.order)
-            # setslice would have been better, but flat[6:9] for arbitrary
-            # shapes of array a cannot be represented as a[x1:x2, y1:y2]
-            basei = ViewIterator(self.base.start, self.base.strides, 
-                                   self.base.backstrides,self.base.shape)
-            basei.indices = coords
-            ri = ArrayIterator(lngth)
-            itemsize = self.base.dtype.itemtype.get_element_size()
-            shapelen = len(self.base.shape)
-            delta = 0
-            ri_start = ri.offset
-            basei_start = basei.offset
-            bstorage = self.base.storage
-            while not ri.done():
-                # TODO: add a jit_merge_point
-
-                # This is an O(N) approach
-                #      w_val = self.base.getitemspace, c)
-                #      w_result.setitem(ri.offset,w_val)
-                # Try to do better by checking when we can use memcpy
-                # from basei_start to basei.offset
-
-                while basei.offset - delta - basei_start == 0:
-                    basei = basei.next(shapelen)
-                    ri = ri.next(shapelen)
-                    delta += 1
-                rffi.c_memcpy(
-                    rffi.ptradd(res.storage, ri_start* itemsize),
-                    rffi.ptradd(bstorage, basei_start * itemsize),
-                    delta * itemsize,
-                )
-                delta = 0
-                ri_start = ri.offset
-                basei_start = basei.offset
-            return res
-        else:
+        coords, start, step, lngth = _to_coords(space, self.base, w_idx)
+        if lngth <2:
             w_coords = space.newtuple([space.wrap(c) for c in coords])
             return self.base.descr_getitem(space, w_coords)
 
+        res = W_NDimArray(lngth, [lngth], self.base.dtype,
+                                    self.base.order)
+        # setslice would have been better, but flat[u:v] for arbitrary
+        # shapes of array a cannot be represented as a[x1:x2, y1:y2]
+        basei = ViewIterator(self.base.start, self.base.strides,
+                               self.base.backstrides,self.base.shape)
+        shapelen = len(self.base.shape)
+        if start > 0:
+            basei = basei.next_skip_x(shapelen, start)
+        ri = ArrayIterator(lngth)
+        while not ri.done():
+            # TODO: add a jit_merge_point
+            w_val = self.base.getitem(basei.offset)
+            res.setitem(ri.offset,w_val)
+            basei = basei.next_skip_x(shapelen, step)
+            ri = ri.next(shapelen)
+        return res
+
     def descr_setitem(self, space, w_idx, w_value):
-        coords, step, lngth = _to_coords(space, self.base, w_idx)
+        coords, start, step, lngth = _to_coords(space, self.base, w_idx)
         arr = convert_to_array(space, w_value)
         ai = 0
-        return
-        for c in coords:
-            v = arr.getitem(ai)
-            self.base.descr_setitem(space, c, v)
+        basei = ViewIterator(self.base.start, self.base.strides,
+                               self.base.backstrides,self.base.shape)
+        shapelen = len(self.base.shape)
+        if start > 0:
+            basei = basei.next_skip_x(shapelen, start)
+        for i in range(lngth):
+            # TODO: add jit_merge_point
+            v = arr.getitem(ai).convert_to(self.base.dtype)
+            print i, basei.offset, basei.indices, v.value
+            if basei.offset >= self.base.size:
+                xxx
+            self.base.setitem(basei.offset, v)
             # need to repeat input values until all assignments are done
             ai = (ai + 1) % arr.size
-        
+            basei = basei.next_skip_x(shapelen, step)
+
+    def descr_base(self, space):
+        return space.wrap(self.base)
+
 W_FlatIterator.typedef = TypeDef(
     'flatiter',
-    next = interp2app(W_FlatIterator.descr_next),
+    #__array__  = #MISSING
     __iter__ = interp2app(W_FlatIterator.descr_iter),
     __getitem__ = interp2app(W_FlatIterator.descr_getitem),
     __setitem__ = interp2app(W_FlatIterator.descr_setitem),
+    __eq__ = interp2app(BaseArray.descr_eq),
+    __ne__ = interp2app(BaseArray.descr_ne),
+    __lt__ = interp2app(BaseArray.descr_lt),
+    __le__ = interp2app(BaseArray.descr_le),
+    __gt__ = interp2app(BaseArray.descr_gt),
+    __ge__ = interp2app(BaseArray.descr_ge),
+    #__sizeof__ #MISSING
+    base = GetSetProperty(W_FlatIterator.descr_base),
     index = GetSetProperty(W_FlatIterator.descr_index),
     coords = GetSetProperty(W_FlatIterator.descr_coords),
+    next = interp2app(W_FlatIterator.descr_next),
 
 )
 W_FlatIterator.acceptable_as_base_class = False
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
@@ -1335,6 +1335,8 @@
         b.next()
         b.next()
         assert b[3] == 3
+        assert (b[::3] == [0, 3, 6, 9]).all()
+        assert (b[2::5] == [2, 7]).all()
         assert b[-2] == 8
         raises(IndexError, "b[11]")
         raises(IndexError, "b[-11]")
@@ -1350,9 +1352,22 @@
         b[0:2] = [[[100]]]
         assert(a[0,0] == 100)
         assert(a[1,0] == 100)
-        raises(NotImplementedError, 'b[array([10, 11])] == [-20, -40]')
-        
+        raises(IndexError, 'b[array([10, 11])] == [-20, -40]')
 
+    def test_flatiter_ops(self):
+        from _numpypy import arange, array
+        a = arange(12).reshape(3,4)
+        b = a.T.flat
+        assert (b == [0,  4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11]).all()
+        assert not (b != [0,  4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11]).any()
+        assert ((b >= range(12)) == [True, True, True,False, True, True, 
+                             False, False, True, False, False, True]).all()
+        assert ((b < range(12)) != [True, True, True,False, True, True, 
+                             False, False, True, False, False, True]).all()
+        assert ((b <= range(12)) != [False, True, True,False, True, True, 
+                            False, False, True, False, False, False]).all()
+        assert ((b > range(12)) == [False, True, True,False, True, True, 
+                            False, False, True, False, False, False]).all()
     def test_flatiter_view(self):
         from _numpypy import arange
         a = arange(10).reshape(5, 2)


More information about the pypy-commit mailing list