[pypy-commit] pypy numpy-fixes: simplify and fix logic of strides, shapes for view()

mattip noreply at buildbot.pypy.org
Wed Apr 29 21:28:32 CEST 2015


Author: mattip <matti.picus at gmail.com>
Branch: numpy-fixes
Changeset: r76951:ad108273e79b
Date: 2015-04-29 22:28 +0300
http://bitbucket.org/pypy/pypy/changeset/ad108273e79b/

Log:	simplify and fix logic of strides, shapes for view()

diff --git a/pypy/module/micronumpy/concrete.py b/pypy/module/micronumpy/concrete.py
--- a/pypy/module/micronumpy/concrete.py
+++ b/pypy/module/micronumpy/concrete.py
@@ -90,13 +90,10 @@
                               new_shape, self, orig_array)
         return None
 
-    def get_view(self, space, orig_array, dtype, new_shape, reuse_strides=False):
-        if not reuse_strides:
+    def get_view(self, space, orig_array, dtype, new_shape, strides=None, backstrides=None):
+        if not strides:
             strides, backstrides = calc_strides(new_shape, dtype,
                                                     self.order)
-        else:
-            strides = self.get_strides()
-            backstrides = self.get_backstrides()
         return SliceArray(self.start, strides, backstrides, new_shape,
                           self, orig_array, dtype=dtype)
 
diff --git a/pypy/module/micronumpy/ndarray.py b/pypy/module/micronumpy/ndarray.py
--- a/pypy/module/micronumpy/ndarray.py
+++ b/pypy/module/micronumpy/ndarray.py
@@ -844,36 +844,35 @@
             if old_itemsize != new_itemsize:
                 raise OperationError(space.w_ValueError, space.wrap(
                     "new type not compatible with array."))
+            strides = None
+            backstrides = None
+            base = self
         else:
-            if not is_c_contiguous(impl) and not is_f_contiguous(impl):
-                if old_itemsize != new_itemsize:
+            base = impl.base()
+            if base is None:
+                base = self
+            strides = impl.get_strides()[:]
+            backstrides = impl.get_backstrides()[:]
+            if old_itemsize != new_itemsize:
+                if not is_c_contiguous(impl) and not is_f_contiguous(impl):
                     raise OperationError(space.w_ValueError, space.wrap(
                         "new type not compatible with array."))
-                # Strides, shape does not change
-                if dtype.is_object() != impl.dtype.is_object():
-                    raise oefmt(space.w_ValueError, 'expect trouble in ndarray.view,'
-                        ' one of target dtype or dtype is object dtype')
-                
-                base = impl.base()
-                if base is None:
-                    base = self
-                v = impl.get_view(space, base, dtype, self.get_shape(),
-                        reuse_strides=True)
-                return wrap_impl(space, w_type, self, v)
-            strides = impl.get_strides()
-            if dims == 1 or strides[0] <strides[-1]:
-                # Column-major, resize first dimension
-                if new_shape[0] * old_itemsize % new_itemsize != 0:
+                # Adapt the smallest dim to the new itemsize
+                minstride = strides[0]
+                mini = 0
+                for i in range(len(strides)):
+                    if strides[i] < minstride:
+                        minstride = strides[i]
+                        mini = i
+                if new_shape[mini] * old_itemsize % new_itemsize != 0:
                     raise OperationError(space.w_ValueError, space.wrap(
                         "new type not compatible with array."))
-                new_shape[0] = new_shape[0] * old_itemsize / new_itemsize
-            else:
-                # Row-major, resize last dimension
-                if new_shape[-1] * old_itemsize % new_itemsize != 0:
-                    raise OperationError(space.w_ValueError, space.wrap(
-                        "new type not compatible with array."))
-                new_shape[-1] = new_shape[-1] * old_itemsize / new_itemsize
-        v = impl.get_view(space, self, dtype, new_shape)
+                new_shape[mini] = new_shape[mini] * old_itemsize / new_itemsize
+                strides[mini] = strides[mini] * new_itemsize / old_itemsize    
+        if dtype.is_object() != impl.dtype.is_object():
+            raise oefmt(space.w_ValueError, 'expect trouble in ndarray.view,'
+                ' one of target dtype or dtype is object dtype')
+        v = impl.get_view(space, base, dtype, new_shape, strides, backstrides)
         w_ret = wrap_impl(space, w_type, self, v)
         return w_ret
 


More information about the pypy-commit mailing list