[pypy-commit] pypy nditer-buffered: improve test by comparing to upstream, move things around until part of test passes

mattip noreply at buildbot.pypy.org
Mon Jul 20 07:43:46 CEST 2015


Author: mattip <matti.picus at gmail.com>
Branch: nditer-buffered
Changeset: r78604:f5d927f06929
Date: 2015-07-20 08:44 +0300
http://bitbucket.org/pypy/pypy/changeset/f5d927f06929/

Log:	improve test by comparing to upstream, move things around until part
	of test passes

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
@@ -18,7 +18,7 @@
 from pypy.module.micronumpy.converters import multi_axis_converter, \
     order_converter, shape_converter, searchside_converter
 from pypy.module.micronumpy.flagsobj import W_FlagsObject
-from pypy.module.micronumpy.strides import get_shape_from_iterable, \
+from pypy.module.micronumpy.strideops import get_shape_from_iterable, \
     shape_agreement, shape_agreement_multiple, is_c_contiguous, is_f_contiguous
 from pypy.module.micronumpy.casting import can_cast_array
 
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
@@ -7,8 +7,7 @@
 from pypy.module.micronumpy.base import W_NDimArray, convert_to_array, W_NumpyObject
 from pypy.module.micronumpy.descriptor import decode_w_dtype
 from pypy.module.micronumpy.iterators import ArrayIter
-from pypy.module.micronumpy.strides import (calculate_broadcast_strides,
-                                            shape_agreement, shape_agreement_multiple)
+from pypy.module.micronumpy import strideops
 from pypy.module.micronumpy.casting import find_binop_result_dtype
 
 
@@ -213,6 +212,15 @@
 def get_iter(space, order, arr, shape, dtype, op_flags, base):
     imp = arr.implementation
     backward = is_backward(imp, order)
+    if len(shape) == 1:
+        min_dim = 0
+        min_stride = 0xefffffff
+        for i in range(len(imp.shape)):
+            if imp.strides[i] < min_stride:
+                min_dim = i
+                min_stride = imp.strides[i]
+        return ConcreteIter(imp, imp.get_size(), shape, [imp.strides[i]],
+                           [imp.backstrides[i]], op_flags, base)
     if arr.is_scalar():
         return ConcreteIter(imp, 1, [], [], [], op_flags, base)
     if (abs(imp.strides[0]) < abs(imp.strides[-1]) and not backward) or \
@@ -220,19 +228,20 @@
         # flip the strides. Is this always true for multidimension?
         strides = imp.strides[:]
         backstrides = imp.backstrides[:]
-        shape = imp.shape[:]
         strides.reverse()
         backstrides.reverse()
-        shape.reverse()
+        _shape = imp.shape[:]
+        _shape.reverse()
     else:
         strides = imp.strides
         backstrides = imp.backstrides
-    r = calculate_broadcast_strides(strides, backstrides, imp.shape,
+        _shape = imp.shape
+    r = strideops.calculate_broadcast_strides(strides, backstrides, _shape,
                                     shape, backward)
     if len(shape) != len(r[0]):
         # shape can be shorter when using an external loop, just return a view
-        return ConcreteIter(imp, imp.get_size(), imp.shape, r[0], r[1], op_flags, base)
-    return ConcreteIter(imp, imp.get_size(), shape, r[0], r[1], op_flags, base)
+        return ConcreteIter(imp, imp.get_size(), _shape, r[0], r[1], op_flags, base)
+    return ConcreteIter(imp, imp.get_size(), _shape, r[0], r[1], op_flags, base)
 
 def calculate_ndim(op_in, oa_ndim):
     if oa_ndim >=0:
@@ -413,15 +422,15 @@
         outargs = [i for i in range(len(self.seq))
                    if self.seq[i] is None or self.op_flags[i].rw == 'w']
         if len(outargs) > 0:
-            out_shape = shape_agreement_multiple(space, [self.seq[i] for i in outargs])
+            out_shape = strideops.shape_agreement_multiple(space, [self.seq[i] for i in outargs])
         else:
             out_shape = None
         if space.isinstance_w(w_itershape, space.w_tuple) or \
            space.isinstance_w(w_itershape, space.w_list):
             self.shape = [space.int_w(i) for i in space.listview(w_itershape)]
         else:
-            self.shape = shape_agreement_multiple(space, self.seq,
-                                                           shape=out_shape)
+            self.shape = strideops.shape_agreement_multiple(space, self.seq,
+                                                     shape=out_shape)
         if len(outargs) > 0:
             # Make None operands writeonly and flagged for allocation
             if len(self.dtypes) > 0:
@@ -443,7 +452,7 @@
                 else:
                     if not self.op_flags[i].broadcast:
                         # Raises if ooutput cannot be broadcast
-                        shape_agreement(space, self.shape, self.seq[i], False)
+                        strideops.shape_agreement(space, self.shape, self.seq[i], False)
 
         if self.tracked_index != "":
             if self.order == "K":
@@ -453,7 +462,6 @@
             else:
                 backward = self.order != self.tracked_index
             self.index_iter = IndexIterator(self.shape, backward=backward)
-
         # handle w_op_dtypes part 2: copy where needed if possible
         if len(self.dtypes) > 0:
             for i in range(len(self.seq)):
@@ -553,7 +561,7 @@
             res.append(self.getitem(it, st))
             self.iters[i] = (it, it.next(st))
         if len(res) < 2:
-            return res[0]
+            return res[0] 
         return space.newtuple(res)
 
     def iternext(self):
@@ -648,7 +656,9 @@
         raise oefmt(space.w_NotImplementedError, "not implemented yet")
 
     def descr_get_shape(self, space):
-        raise oefmt(space.w_NotImplementedError, "not implemented yet")
+        if self.done:
+            raise oefmt(space.w_ValueError, "Iterator is past the end")
+        return space.newtuple([space.wrap(i) for i in self.shape])
 
     def descr_get_value(self, space):
         raise oefmt(space.w_NotImplementedError, "not implemented yet")
diff --git a/pypy/module/micronumpy/strides.py b/pypy/module/micronumpy/strideops.py
rename from pypy/module/micronumpy/strides.py
rename to pypy/module/micronumpy/strideops.py
--- a/pypy/module/micronumpy/strides.py
+++ b/pypy/module/micronumpy/strideops.py
@@ -3,7 +3,6 @@
 from pypy.module.micronumpy import support, constants as NPY
 from pypy.module.micronumpy.base import W_NDimArray
 
-
 # structures to describe slicing
 
 class BaseChunk(object):
diff --git a/pypy/module/micronumpy/support.py b/pypy/module/micronumpy/support.py
--- a/pypy/module/micronumpy/support.py
+++ b/pypy/module/micronumpy/support.py
@@ -11,7 +11,6 @@
            space.isinstance_w(w_obj, space.w_buffer) or
            isinstance(w_obj, W_NDimArray))
 
-
 def index_w(space, w_obj):
     try:
         return space.int_w(space.index(w_obj))
@@ -23,7 +22,6 @@
                 "ellipsis (`...`), numpy.newaxis (`None`) and integer or "
                 "boolean arrays are valid indices")
 
-
 @jit.unroll_safe
 def product(s):
     i = 1
@@ -31,7 +29,6 @@
         i = ovfcheck(i * x)
     return i
 
-
 def check_and_adjust_index(space, index, size, axis):
     if index < -size or index >= size:
         if axis >= 0:
diff --git a/pypy/module/micronumpy/test/dummy_module.py b/pypy/module/micronumpy/test/dummy_module.py
--- a/pypy/module/micronumpy/test/dummy_module.py
+++ b/pypy/module/micronumpy/test/dummy_module.py
@@ -38,3 +38,12 @@
     a = zeros(*args, **kwargs)
     a.fill(1)
     return a
+
+def shape(a):
+    try:
+        result = a.shape
+    except AttributeError:
+        result = asarray(a).shape
+    return result
+
+
diff --git a/pypy/module/micronumpy/test/test_nditer.py b/pypy/module/micronumpy/test/test_nditer.py
--- a/pypy/module/micronumpy/test/test_nditer.py
+++ b/pypy/module/micronumpy/test/test_nditer.py
@@ -149,16 +149,26 @@
         # assert str(exc.value).startswith("Iterator flag EXTERNAL_LOOP cannot")
 
     def test_buffered(self):
-        from numpy import arange, nditer, array
-        a = arange(6).reshape(2,3)
-        import sys
+        from numpy import arange, nditer, array, shape
+        a = arange(6).reshape(2, 3)
         r = []
-        for x in nditer(a, flags=['external_loop', 'buffered'], order='F'):
-            r.append(x)
-        array_r = array(r)
-        assert len(array_r.shape) == 2
-        assert array_r.shape == (1, 6)
-        assert (array_r == [0, 3, 1, 4, 2, 5]).all()
+        x = nditer(a, flags=['buffered'], order='F')
+        assert x.shape == a.shape # maybe a numpy bug, but be compatible
+        for i in x:
+            r.append(i)
+            assert x.shape == a.shape
+        assert r[0].shape == ()
+        raises(ValueError, shape, x)
+        assert len(r) == 6 # buffered flattens the iterator
+        r = []
+        assert a.shape == (2, 3)
+        x = nditer(a, flags=['external_loop', 'buffered'], order='F')
+        assert x.shape == a.shape # maybe a numpy bug, but be compatible
+        for i in x:
+            r.append(i)
+        assert len(r) == 1 # external_loop coalesces the flattened iterator
+        assert r[0].shape == (6,) 
+        assert (r[0] == [0, 3, 1, 4, 2, 5]).all() #respect the order
 
     def test_op_dtype(self):
         from numpy import arange, nditer, sqrt, array
@@ -186,7 +196,8 @@
         import sys
         a = arange(6.)
         exc = raises(TypeError, nditer, a, flags=['buffered'], op_dtypes=['float32'])
-        assert str(exc.value).startswith("Iterator operand 0 dtype could not be cast")
+        errstr = str(exc.value)
+        assert errstr.startswith("Iterator operand 0 dtype could not be cast")
         r = []
         for x in nditer(a, flags=['buffered'], op_dtypes=['float32'],
                                 casting='same_kind'):


More information about the pypy-commit mailing list