[pypy-commit] pypy numpy-fixes: make astype() return contiguous ndarrays

mattip noreply at buildbot.pypy.org
Sat May 2 20:40:29 CEST 2015


Author: mattip <matti.picus at gmail.com>
Branch: numpy-fixes
Changeset: r76980:445521dede4f
Date: 2015-05-01 14:31 +0300
http://bitbucket.org/pypy/pypy/changeset/445521dede4f/

Log:	make astype() return contiguous ndarrays

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
@@ -329,13 +329,18 @@
         return ArrayBuffer(self, readonly)
 
     def astype(self, space, dtype):
-        s_elsize = self.dtype.elsize
+        # copy the general pattern of the strides
+        # but make the array storage contiguous in memory
+        shape = self.get_shape()
+        strides = self.get_strides()
+        mins = strides[0]
         t_elsize = dtype.elsize
-        strides = [s*t_elsize/s_elsize for s in self.get_strides()]
-        backstrides = calc_backstrides(strides, self.get_shape())
-        #strides, backstrides = calc_strides(self.get_shape(), dtype, self.order)
-        impl = ConcreteArray(self.get_shape(), dtype, self.order,
-                             strides, backstrides)
+        for s in strides:
+            if s < mins:
+                mins = s
+        t_strides = [s * t_elsize / mins for s in strides]
+        backstrides = calc_backstrides(t_strides, shape)
+        impl = ConcreteArray(shape, dtype, self.order, t_strides, backstrides)
         loop.setslice(space, impl.get_shape(), impl, self)
         return impl
 
diff --git a/pypy/module/micronumpy/ctors.py b/pypy/module/micronumpy/ctors.py
--- a/pypy/module/micronumpy/ctors.py
+++ b/pypy/module/micronumpy/ctors.py
@@ -133,11 +133,12 @@
             return w_arr
         else:
             imp = w_object.implementation
+            w_base = imp.base() or w_object
             with imp as storage:
                 sz = support.product(w_object.get_shape()) * dtype.elsize
                 return W_NDimArray.from_shape_and_storage(space,
                     w_object.get_shape(), storage, dtype, storage_bytes=sz, 
-                    w_base=w_object, start=imp.start)
+                    w_base=w_base, start=imp.start)
     else:
         # not an array
         shape, elems_w = strides.find_shape_and_elems(space, w_object, dtype)
diff --git a/pypy/module/micronumpy/test/test_object_arrays.py b/pypy/module/micronumpy/test/test_object_arrays.py
--- a/pypy/module/micronumpy/test/test_object_arrays.py
+++ b/pypy/module/micronumpy/test/test_object_arrays.py
@@ -167,3 +167,10 @@
         # Wrong way - should complain about writing buffer to object dtype
         raises(ValueError, np.array, [1, 'object'], dt)
 
+    def test_astype(self):
+        import numpy as np
+        a = np.arange(5, dtype=complex)
+        b = a.real
+        c = b.astype("O")
+        assert c.shape == b.shape
+        assert c.strides == (8,)


More information about the pypy-commit mailing list