[pypy-commit] pypy numpypy-real-as-view: discover that descr_set_real requires a true view iterator, modify View iterators to allow dtype to differ from array.dtype

mattip noreply at buildbot.pypy.org
Wed Jan 9 21:18:39 CET 2013


Author: mattip <matti.picus at gmail.com>
Branch: numpypy-real-as-view
Changeset: r59897:36d57babaa6e
Date: 2013-01-09 21:50 +0200
http://bitbucket.org/pypy/pypy/changeset/36d57babaa6e/

Log:	discover that descr_set_real requires a true view iterator, modify
	View iterators to allow dtype to differ from array.dtype

diff --git a/pypy/module/micronumpy/arrayimpl/concrete.py b/pypy/module/micronumpy/arrayimpl/concrete.py
--- a/pypy/module/micronumpy/arrayimpl/concrete.py
+++ b/pypy/module/micronumpy/arrayimpl/concrete.py
@@ -13,6 +13,7 @@
 from pypy.rlib.debug import make_sure_not_resized
 
 class ConcreteArrayIterator(base.BaseArrayIterator):
+    _immutable_fields_ = ['dtype', 'skip', 'size']
     def __init__(self, array):
         self.array = array
         self.offset = 0
@@ -21,10 +22,10 @@
         self.size = array.size
 
     def setitem(self, elem):
-        self.array.setitem(self.offset, elem)
+        self.dtype.setitem(self.array, self.offset, elem)
 
     def getitem(self):
-        return self.array.getitem(self.offset)
+        return self.dtype.getitem(self.array, self.offset)
 
     def getitem_bool(self):
         return self.dtype.getitem_bool(self.array, self.offset)
@@ -42,13 +43,16 @@
         self.offset %= self.size
 
 class OneDimViewIterator(ConcreteArrayIterator):
-    def __init__(self, array):
+    ''' The view iterator dtype can be different from the
+    array.dtype, this is what makes it a View
+    '''
+    def __init__(self, array, dtype, start, strides, shape):
         self.array = array
-        self.offset = array.start
-        self.skip = array.get_strides()[0]
-        self.dtype = array.dtype
+        self.dtype = dtype
+        self.offset = start
+        self.skip = strides[0]
         self.index = 0
-        self.size = array.get_shape()[0]
+        self.size = shape[0]
 
     def next(self):
         self.offset += self.skip
@@ -65,9 +69,13 @@
         self.offset %= self.size
 
 class MultiDimViewIterator(ConcreteArrayIterator):
-    def __init__(self, array, start, strides, backstrides, shape):
+    ''' The view iterator dtype can be different from the
+    array.dtype, this is what makes it a View
+    '''
+    def __init__(self, array, dtype, start, strides, backstrides, shape):
         self.indexes = [0] * len(shape)
         self.array = array
+        self.dtype = dtype
         self.shape = shape
         self.offset = start
         self.shapelen = len(shape)
@@ -114,7 +122,7 @@
         self.offset %= self.size
 
 class AxisIterator(base.BaseArrayIterator):
-    def __init__(self, array, shape, dim):
+    def __init__(self, array, dtype, shape, dim):
         self.shape = shape
         strides = array.get_strides()
         backstrides = array.get_backstrides()
@@ -131,12 +139,13 @@
         self.offset = array.start
         self.dim = dim
         self.array = array
+        self.dtype = array.dtype
         
     def setitem(self, elem):
-        self.array.setitem(self.offset, elem)
+        self.dtype.setitem(self.array, self.offset, elem)
 
     def getitem(self):
-        return self.array.getitem(self.offset)
+        return self.dtype.getitem(self.array, self.offset)
 
     @jit.unroll_safe
     def next(self):
@@ -403,7 +412,7 @@
     def create_dot_iter(self, shape, skip):
         r = calculate_dot_strides(self.get_strides(), self.get_backstrides(),
                                   shape, skip)
-        return MultiDimViewIterator(self, self.start, r[0], r[1], shape)
+        return MultiDimViewIterator(self, self.dtype, self.start, r[0], r[1], shape)
 
     def swapaxes(self, axis1, axis2):
         shape = self.get_shape()[:]
@@ -437,7 +446,7 @@
         r = calculate_broadcast_strides(self.get_strides(),
                                         self.get_backstrides(),
                                         self.get_shape(), shape)
-        return MultiDimViewIterator(self, 0, r[0], r[1], shape)
+        return MultiDimViewIterator(self, self.dtype, 0, r[0], r[1], shape)
 
     def fill(self, box):
         self.dtype.fill(self.storage, box, 0, self.size)
@@ -480,11 +489,12 @@
             r = calculate_broadcast_strides(self.get_strides(),
                                             self.get_backstrides(),
                                             self.get_shape(), shape)
-            return MultiDimViewIterator(self.parent,
+            return MultiDimViewIterator(self.parent, self.dtype,
                                         self.start, r[0], r[1], shape)
         if len(self.get_shape()) == 1:
-            return OneDimViewIterator(self)
-        return MultiDimViewIterator(self.parent, self.start,
+            return OneDimViewIterator(self.parent, self.dtype, self.start, 
+                    self.get_strides(), self.get_shape())
+        return MultiDimViewIterator(self.parent, self.dtype, self.start,
                                     self.get_strides(),
                                     self.get_backstrides(), self.get_shape())
 
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
@@ -245,9 +245,10 @@
         raise OperationError(space.w_NotImplementedError, 
                     space.wrap('imag not implemented for this dtype'))
 
-    def descr_set_real(self, space, w_new_val):
+    def descr_set_real(self, space, w_value):
         # copy (broadcast) values into self
-        self.implementation.descr_set_real(space, w_new_val)
+        tmp = self.implementation.get_real()
+        tmp.setslice(space, convert_to_array(space, w_value))
 
     def descr_set_imag(self, space, w_new_val):
         # if possible, copy (broadcast) values into self
diff --git a/pypy/module/micronumpy/test/test_iter.py b/pypy/module/micronumpy/test/test_iter.py
--- a/pypy/module/micronumpy/test/test_iter.py
+++ b/pypy/module/micronumpy/test/test_iter.py
@@ -12,7 +12,7 @@
         strides = [5, 1]
         backstrides = [x * (y - 1) for x,y in zip(strides, shape)]
         assert backstrides == [10, 4]
-        i = MultiDimViewIterator(MockArray, start, strides, backstrides, shape)
+        i = MultiDimViewIterator(MockArray, None, start, strides, backstrides, shape)
         i.next()
         i.next()
         i.next()
@@ -30,7 +30,7 @@
         strides = [1, 3]
         backstrides = [x * (y - 1) for x,y in zip(strides, shape)]
         assert backstrides == [2, 12]
-        i = MultiDimViewIterator(MockArray, start, strides, backstrides, shape)
+        i = MultiDimViewIterator(MockArray, None, start, strides, backstrides, shape)
         i.next()
         i.next()
         i.next()
@@ -51,7 +51,7 @@
         strides = [5, 1]
         backstrides = [x * (y - 1) for x,y in zip(strides, shape)]
         assert backstrides == [10, 4]
-        i = MultiDimViewIterator(MockArray, start, strides, backstrides, shape)
+        i = MultiDimViewIterator(MockArray, None, start, strides, backstrides, shape)
         i.next_skip_x(2)
         i.next_skip_x(2)
         i.next_skip_x(2)
@@ -74,7 +74,7 @@
         strides = [1, 3]
         backstrides = [x * (y - 1) for x,y in zip(strides, shape)]
         assert backstrides == [2, 12]
-        i = MultiDimViewIterator(MockArray, start, strides, backstrides, shape)
+        i = MultiDimViewIterator(MockArray, None, start, strides, backstrides, shape)
         i.next_skip_x(2)
         i.next_skip_x(2)
         i.next_skip_x(2)
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
@@ -1368,6 +1368,11 @@
         assert b[1,2] == -1
         b[1,2] = 30
         assert a[1,2].imag == 30
+        a.real = 13
+        assert a[1,1].real == 13
+        a=array([1+1j, 2-3j, 4+5j, -6+7j, 8-9j, -2-1j]) 
+        a.real = 13
+        assert a[3].real == 13
 
     def test_tolist_scalar(self):
         from _numpypy import int32, bool_


More information about the pypy-commit mailing list