[pypy-commit] pypy fortran-order: implement order, pass many tests

mattip noreply at buildbot.pypy.org
Wed Sep 30 22:18:08 CEST 2015


Author: mattip <matti.picus at gmail.com>
Branch: fortran-order
Changeset: r79911:a14943e46cef
Date: 2015-09-30 23:17 +0300
http://bitbucket.org/pypy/pypy/changeset/a14943e46cef/

Log:	implement order, pass many tests

diff --git a/pypy/module/micronumpy/arrayops.py b/pypy/module/micronumpy/arrayops.py
--- a/pypy/module/micronumpy/arrayops.py
+++ b/pypy/module/micronumpy/arrayops.py
@@ -108,7 +108,8 @@
         w_axis = space.wrap(0)
     if space.is_none(w_axis):
         args_w = [w_arg.reshape(space,
-                                space.newlist([w_arg.descr_get_size(space)]))
+                                space.newlist([w_arg.descr_get_size(space)]),
+                                w_arg.get_order())
                   for w_arg in args_w]
         w_axis = space.wrap(0)
     dtype = args_w[0].get_dtype()
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
@@ -92,17 +92,18 @@
     def get_storage_size(self):
         return self.size
 
-    def reshape(self, orig_array, new_shape):
+    def reshape(self, orig_array, new_shape, order=NPY.ANYORDER):
         # Since we got to here, prod(new_shape) == self.size
+        order = support.get_order_as_CF(self.order, order)
         new_strides = None
         if self.size == 0:
-            new_strides, _ = calc_strides(new_shape, self.dtype, self.order)
+            new_strides, _ = calc_strides(new_shape, self.dtype, order)
         else:
             if len(self.get_shape()) == 0:
                 new_strides = [self.dtype.elsize] * len(new_shape)
             else:
                 new_strides = calc_new_strides(new_shape, self.get_shape(),
-                                               self.get_strides(), self.order)
+                                               self.get_strides(), order)
                 if new_strides is None or len(new_strides) != len(new_shape):
                     return None
         if new_strides is not None:
@@ -306,10 +307,11 @@
         return SliceArray(self.start, strides,
                           backstrides, shape, self, orig_array)
 
-    def copy(self, space):
+    def copy(self, space, order=NPY.ANYORDER):
+        order = support.get_order_as_CF(self.order, order)
         strides, backstrides = calc_strides(self.get_shape(), self.dtype,
-                                                    self.order)
-        impl = ConcreteArray(self.get_shape(), self.dtype, self.order, strides,
+                                                    order)
+        impl = ConcreteArray(self.get_shape(), self.dtype, order, strides,
                              backstrides)
         return loop.setslice(space, self.get_shape(), impl, self)
 
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
@@ -201,6 +201,7 @@
 
 
 def _zeros_or_empty(space, w_shape, w_dtype, w_order, zero):
+    order = order_converter(space, w_order, NPY.CORDER)
     dtype = space.interp_w(descriptor.W_Dtype,
         space.call_function(space.gettypefor(descriptor.W_Dtype), w_dtype))
     if dtype.is_str_or_unicode() and dtype.elsize < 1:
@@ -214,7 +215,7 @@
         support.product_check(shape)
     except OverflowError:
         raise oefmt(space.w_ValueError, "array is too big.")
-    return W_NDimArray.from_shape(space, shape, dtype=dtype, zero=zero)
+    return W_NDimArray.from_shape(space, shape, dtype, order, zero=zero)
 
 def empty(space, w_shape, w_dtype=None, w_order=None):
     return _zeros_or_empty(space, w_shape, w_dtype, w_order, zero=False)
diff --git a/pypy/module/micronumpy/loop.py b/pypy/module/micronumpy/loop.py
--- a/pypy/module/micronumpy/loop.py
+++ b/pypy/module/micronumpy/loop.py
@@ -680,8 +680,7 @@
 def tostring(space, arr):
     builder = StringBuilder()
     iter, state = arr.create_iter()
-    w_res_str = W_NDimArray.from_shape(space, [1], arr.get_dtype(),
-                                        order=NPY.CORDER)
+    w_res_str = W_NDimArray.from_shape(space, [1], arr.get_dtype())
     itemsize = arr.get_dtype().elsize
     with w_res_str.implementation as storage:
         res_str_casted = rffi.cast(rffi.CArrayPtr(lltype.Char),
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
@@ -99,12 +99,13 @@
     def descr_tostring(self, space, w_order=None):
         try:
             order = order_converter(space, w_order, NPY.CORDER)
-        except OperationError as e:
-            raise oefmt(space.w_TypeError, "order not understood") 
-        if order == NPY.FORTRANORDER:
-            raise OperationError(space.w_NotImplementedError, space.wrap(
-                "unsupported value for order"))
-        return space.wrap(loop.tostring(space, self))
+        except:
+            raise oefmt(space.w_TypeError, "order not understood")
+        order = support.get_order_as_CF(self.get_order(), order)
+        arr = self
+        if order != arr.get_order():
+            arr = W_NDimArray(self.implementation.transpose(self, None))
+        return space.wrap(loop.tostring(space, arr))
 
     def getitem_filter(self, space, arr):
         if arr.ndims() > 1 and arr.get_shape() != self.get_shape():
@@ -374,10 +375,7 @@
             order = space.int_w(w_order)
         else:
             order = order_converter(space, w_order, NPY.KEEPORDER)
-        if order == NPY.FORTRANORDER:
-            raise OperationError(space.w_NotImplementedError, space.wrap(
-                "unsupported value for order"))
-        copy = self.implementation.copy(space)
+        copy = self.implementation.copy(space, order)
         w_subtype = space.type(self)
         return wrap_impl(space, w_subtype, self, copy)
 
@@ -400,15 +398,15 @@
                         'array does not have imaginary part to set')
         self.implementation.set_imag(space, self, w_value)
 
-    def reshape(self, space, w_shape):
+    def reshape(self, space, w_shape, order):
         new_shape = get_shape_from_iterable(space, self.get_size(), w_shape)
-        new_impl = self.implementation.reshape(self, new_shape)
+        new_impl = self.implementation.reshape(self, new_shape, order)
         if new_impl is not None:
             return wrap_impl(space, space.type(self), self, new_impl)
         # Create copy with contiguous data
-        arr = self.descr_copy(space)
+        arr = self.descr_copy(space, space.wrap(order))
         if arr.get_size() > 0:
-            new_implementation = arr.implementation.reshape(self, new_shape)
+            new_implementation = arr.implementation.reshape(self, new_shape, order)
             if new_implementation is None:
                 raise oefmt(space.w_ValueError,
                             'could not reshape array of size %d to shape %s',
@@ -442,16 +440,13 @@
         if order == NPY.KEEPORDER:
             raise OperationError(space.w_ValueError, space.wrap(
                 "order 'K' is not permitted for reshaping"))
-        if order != NPY.CORDER and order != NPY.ANYORDER:
-            raise OperationError(space.w_NotImplementedError, space.wrap(
-                "unsupported value for order"))
         if len(args_w) == 1:
             if space.is_none(args_w[0]):
                 return self.descr_view(space)
             w_shape = args_w[0]
         else:
             w_shape = space.newtuple(args_w)
-        return self.reshape(space, w_shape)
+        return self.reshape(space, w_shape, order)
 
     def descr_get_transpose(self, space, axes=None):
         return W_NDimArray(self.implementation.transpose(self, axes))
@@ -522,20 +517,8 @@
         return space.newlist(l_w)
 
     def descr_ravel(self, space, w_order=None):
-        if space.is_none(w_order):
-            order = 'C'
-        else:
-            order = space.str_w(w_order)
-        if order == 'K' and is_c_contiguous(self.implementation):
-            for s in  self.implementation.get_strides():
-                if s < 0:
-                    break
-            else:
-                order = 'C'
-        if order != 'C':
-            raise OperationError(space.w_NotImplementedError, space.wrap(
-                "order != 'C' only partially implemented"))
-        return self.reshape(space, space.wrap(-1))
+        order = order_converter(space, w_order, self.get_order())
+        return self.reshape(space, space.wrap(-1), order)
 
     @unwrap_spec(w_axis=WrappedDefault(None),
                  w_out=WrappedDefault(None),
@@ -549,14 +532,15 @@
                                  space.wrap("axis unsupported for compress"))
             arr = self
         else:
-            arr = self.reshape(space, space.wrap(-1))
+            arr = self.reshape(space, space.wrap(-1), self.get_order())
         index = convert_to_array(space, w_obj)
         return arr.getitem_filter(space, index)
 
     def descr_flatten(self, space, w_order=None):
+        order = order_converter(space, w_order, self.get_order())
         if self.is_scalar():
             # scalars have no storage
-            return self.reshape(space, space.wrap(1))
+            return self.reshape(space, space.wrap(1), order)
         w_res = self.descr_ravel(space, w_order)
         if w_res.implementation.storage == self.implementation.storage:
             return w_res.descr_copy(space)
@@ -1202,7 +1186,7 @@
             out = out_converter(space, w_out)
             if space.is_none(w_axis):
                 w_axis = space.wrap(0)
-                arr = self.reshape(space, space.wrap(-1))
+                arr = self.reshape(space, space.wrap(-1), self.get_order())
             else:
                 arr = self
             ufunc = getattr(ufuncs.get(space), ufunc_name)
diff --git a/pypy/module/micronumpy/nditer.py b/pypy/module/micronumpy/nditer.py
--- a/pypy/module/micronumpy/nditer.py
+++ b/pypy/module/micronumpy/nditer.py
@@ -144,14 +144,13 @@
             'Iterator flag EXTERNAL_LOOP cannot be used if an index or '
             'multi-index is being tracked')
 
-
-def is_backward(imp, order):
-    if order == NPY.KEEPORDER or (order == NPY.CORDER and imp.order == NPY.CORDER):
+def is_backward(imp_order, order):
+    if imp_order == order:
         return False
-    elif order == NPY.FORTRANORDER and imp.order == NPY.CORDER:
+    if order == NPY.KEEPORDER:
+        return False
+    else:
         return True
-    else:
-        raise NotImplementedError('not implemented yet')
 
 
 class OperandIter(ArrayIter):
@@ -514,7 +513,7 @@
         dtype = self.dtypes[i]
         shape = self.shape
         imp = arr.implementation
-        backward = is_backward(imp, self.order)
+        backward = is_backward(imp.order, self.order)
         if arr.is_scalar():
             return ConcreteIter(imp, 1, [], [], [], self.op_flags[i], self)
         if (abs(imp.strides[0]) < abs(imp.strides[-1]) and not backward) or \
diff --git a/pypy/module/micronumpy/test/test_ndarray.py b/pypy/module/micronumpy/test/test_ndarray.py
--- a/pypy/module/micronumpy/test/test_ndarray.py
+++ b/pypy/module/micronumpy/test/test_ndarray.py
@@ -921,6 +921,9 @@
         raises(ValueError, a.reshape, (0,), order="K")
         b = a.reshape((0,), order='F')
         assert b.shape == (0,)
+        a = array(range(24), 'uint8')
+        assert a.reshape([2, 3, 4], order=True).strides ==(1, 2, 6)
+        assert a.reshape([2, 3, 4], order=False).strides ==(12, 4, 1)
 
     def test_slice_reshape(self):
         from numpy import zeros, arange


More information about the pypy-commit mailing list