[pypy-commit] pypy default: merge numpy-refactor

bdkearns noreply at buildbot.pypy.org
Thu Feb 27 13:17:41 CET 2014


Author: Brian Kearns <bdkearns at gmail.com>
Branch: 
Changeset: r69512:ec929caa596e
Date: 2014-02-27 07:15 -0500
http://bitbucket.org/pypy/pypy/changeset/ec929caa596e/

Log:	merge numpy-refactor

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
@@ -8,6 +8,7 @@
     shape_agreement_multiple
 
 
+
 def where(space, w_arr, w_x=None, w_y=None):
     """where(condition, [x, y])
 
@@ -91,6 +92,7 @@
     out = W_NDimArray.from_shape(space, shape, dtype)
     return loop.where(space, out, shape, arr, x, y, dtype)
 
+
 def dot(space, w_obj1, w_obj2, w_out=None):
     w_arr = convert_to_array(space, w_obj1)
     if w_arr.is_scalar():
@@ -162,6 +164,7 @@
         axis_start += arr.get_shape()[axis]
     return res
 
+
 @unwrap_spec(repeats=int)
 def repeat(space, w_arr, repeats, w_axis):
     arr = convert_to_array(space, w_arr)
@@ -186,9 +189,11 @@
             Chunks(chunks).apply(space, w_res).implementation.setslice(space, arr)
     return w_res
 
+
 def count_nonzero(space, w_obj):
     return space.wrap(loop.count_all_true(convert_to_array(space, w_obj)))
 
+
 def choose(space, w_arr, w_choices, w_out, w_mode):
     arr = convert_to_array(space, w_arr)
     choices = [convert_to_array(space, w_item) for w_item
@@ -208,6 +213,7 @@
     loop.choose(space, arr, choices, shape, dtype, out, mode)
     return out
 
+
 def put(space, w_arr, w_indices, w_values, w_mode):
     arr = convert_to_array(space, w_arr)
     mode = clipmode_converter(space, w_mode)
@@ -256,6 +262,7 @@
 
         arr.setitem(space, [index], dtype.coerce(space, value))
 
+
 def diagonal(space, arr, offset, axis1, axis2):
     shape = arr.get_shape()
     shapelen = len(shape)
diff --git a/pypy/module/micronumpy/boxes.py b/pypy/module/micronumpy/boxes.py
--- a/pypy/module/micronumpy/boxes.py
+++ b/pypy/module/micronumpy/boxes.py
@@ -69,6 +69,7 @@
         ret = space.newtuple([scalar, space.newtuple([space.wrap(self._get_dtype(space)), space.wrap(self.raw_str())])])
         return ret
 
+
 class PrimitiveBox(Box):
     _mixin_ = True
     _immutable_fields_ = ['value']
@@ -93,6 +94,7 @@
         lltype.free(value, flavor="raw")
         return ret
 
+
 class ComplexBox(Box):
     _mixin_ = True
     _immutable_fields_ = ['real', 'imag']
@@ -360,6 +362,7 @@
         return self.get_dtype(space).itemtype.imag(self)
 
     w_flags = None
+
     def descr_get_flags(self, space):
         if self.w_flags is None:
             self.w_flags = W_FlagsObject(self)
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
@@ -276,6 +276,17 @@
                              backstrides)
         return loop.setslice(space, self.get_shape(), impl, self)
 
+    def create_iter(self, shape=None, backward_broadcast=False):
+        if shape is not None and \
+                support.product(shape) > support.product(self.get_shape()):
+            r = calculate_broadcast_strides(self.get_strides(),
+                                            self.get_backstrides(),
+                                            self.get_shape(), shape,
+                                            backward_broadcast)
+            return iter.MultiDimViewIterator(self, self.start,
+                                             r[0], r[1], shape)
+        return iter.ArrayIterator(self)
+
     def create_axis_iter(self, shape, dim, cum):
         return iter.AxisIterator(self, shape, dim, cum)
 
@@ -335,26 +346,6 @@
         self.backstrides = backstrides
         self.storage = storage
 
-    def create_iter(self, shape=None, backward_broadcast=False, require_index=False):
-        if shape is not None and \
-                support.product(shape) > support.product(self.get_shape()):
-            r = calculate_broadcast_strides(self.get_strides(),
-                                            self.get_backstrides(),
-                                            self.get_shape(), shape,
-                                            backward_broadcast)
-            return iter.MultiDimViewIterator(self, self.start,
-                                             r[0], r[1], shape)
-        if not require_index:
-            return iter.ConcreteArrayIterator(self)
-        if len(self.get_shape()) <= 1:
-            return iter.OneDimViewIterator(self, self.start,
-                                           self.get_strides(),
-                                           self.get_shape())
-        return iter.MultiDimViewIterator(self, self.start,
-                                         self.get_strides(),
-                                         self.get_backstrides(),
-                                         self.get_shape())
-
     def fill(self, space, box):
         self.dtype.itemtype.fill(self.storage, self.dtype.elsize,
                                  box, 0, self.size, 0)
@@ -440,24 +431,6 @@
     def fill(self, space, box):
         loop.fill(self, box.convert_to(space, self.dtype))
 
-    def create_iter(self, shape=None, backward_broadcast=False, require_index=False):
-        if shape is not None and \
-                support.product(shape) > support.product(self.get_shape()):
-            r = calculate_broadcast_strides(self.get_strides(),
-                                            self.get_backstrides(),
-                                            self.get_shape(), shape,
-                                            backward_broadcast)
-            return iter.MultiDimViewIterator(self, self.start,
-                                             r[0], r[1], shape)
-        if len(self.get_shape()) <= 1:
-            return iter.OneDimViewIterator(self, self.start,
-                                           self.get_strides(),
-                                           self.get_shape())
-        return iter.MultiDimViewIterator(self, self.start,
-                                         self.get_strides(),
-                                         self.get_backstrides(),
-                                         self.get_shape())
-
     def set_shape(self, space, orig_array, new_shape):
         if len(self.get_shape()) < 2 or self.size == 0:
             # TODO: this code could be refactored into calc_strides
diff --git a/pypy/module/micronumpy/constants.py b/pypy/module/micronumpy/constants.py
--- a/pypy/module/micronumpy/constants.py
+++ b/pypy/module/micronumpy/constants.py
@@ -57,7 +57,7 @@
 INTPLTR = 'p'
 UINTPLTR = 'P'
 
-GENBOOLLTR ='b'
+GENBOOLLTR = 'b'
 SIGNEDLTR = 'i'
 UNSIGNEDLTR = 'u'
 FLOATINGLTR = 'f'
diff --git a/pypy/module/micronumpy/flagsobj.py b/pypy/module/micronumpy/flagsobj.py
--- a/pypy/module/micronumpy/flagsobj.py
+++ b/pypy/module/micronumpy/flagsobj.py
@@ -6,9 +6,13 @@
 
 class W_FlagsObject(W_Root):
     def __init__(self, arr):
-        self.arr = arr
         self.flags = 0
 
+    def descr__new__(space, w_subtype):
+        self = space.allocate_instance(W_FlagsObject, w_subtype)
+        W_FlagsObject.__init__(self, None)
+        return self
+
     def descr_get_contiguous(self, space):
         return space.w_True
 
@@ -60,6 +64,8 @@
 
 W_FlagsObject.typedef = TypeDef("flagsobj",
     __module__ = "numpy",
+    __new__ = interp2app(W_FlagsObject.descr__new__.im_func),
+
     __getitem__ = interp2app(W_FlagsObject.descr_getitem),
     __setitem__ = interp2app(W_FlagsObject.descr_setitem),
     __eq__ = interp2app(W_FlagsObject.descr_eq),
diff --git a/pypy/module/micronumpy/flatiter.py b/pypy/module/micronumpy/flatiter.py
--- a/pypy/module/micronumpy/flatiter.py
+++ b/pypy/module/micronumpy/flatiter.py
@@ -19,7 +19,7 @@
     def get_shape(self):
         return self.shape
 
-    def create_iter(self, shape=None, backward_broadcast=False, require_index=False):
+    def create_iter(self, shape=None, backward_broadcast=False):
         assert isinstance(self.base(), W_NDimArray)
         return self.base().create_iter()
 
@@ -33,7 +33,6 @@
 
     def reset(self):
         self.iter = self.base.create_iter()
-        self.index = 0
 
     def descr_len(self, space):
         return space.wrap(self.base.get_size())
@@ -43,14 +42,13 @@
             raise OperationError(space.w_StopIteration, space.w_None)
         w_res = self.iter.getitem()
         self.iter.next()
-        self.index += 1
         return w_res
 
     def descr_index(self, space):
-        return space.wrap(self.index)
+        return space.wrap(self.iter.index)
 
     def descr_coords(self, space):
-        coords = self.base.to_coords(space, space.wrap(self.index))
+        coords = self.base.to_coords(space, space.wrap(self.iter.index))
         return space.newtuple([space.wrap(c) for c in coords])
 
     def descr_getitem(self, space, w_idx):
diff --git a/pypy/module/micronumpy/iter.py b/pypy/module/micronumpy/iter.py
--- a/pypy/module/micronumpy/iter.py
+++ b/pypy/module/micronumpy/iter.py
@@ -37,7 +37,7 @@
 All the calculations happen in next()
 
 next_skip_x(steps) tries to do the iteration for a number of steps at once,
-but then we cannot gaurentee that we only overflow one single shape
+but then we cannot guarantee that we only overflow one single shape
 dimension, perhaps we could overflow times in one big step.
 """
 from rpython.rlib import jit
@@ -78,28 +78,41 @@
         return [space.wrap(self.indexes[i]) for i in range(shapelen)]
 
 
-class BaseArrayIterator(object):
-    def next(self):
-        raise NotImplementedError  # purely abstract base class
-
-    def setitem(self, elem):
-        raise NotImplementedError
-
-    def set_scalar_object(self, value):
-        raise NotImplementedError  # works only on scalars
-
-
-class ConcreteArrayIterator(BaseArrayIterator):
-    _immutable_fields_ = ['array', 'skip', 'size']
-
+class ArrayIterator(object):
     def __init__(self, array):
         self.array = array
-        self.offset = 0
-        self.skip = array.dtype.elsize
-        self.size = array.size
+        self.start = array.start
+        self.size = array.get_size()
+        self.ndim_m1 = len(array.shape) - 1
+        self.shape_m1 = [s - 1 for s in array.shape]
+        self.strides = array.strides[:]
+        self.backstrides = array.backstrides[:]
+        self.reset()
 
-    def setitem(self, elem):
-        self.array.setitem(self.offset, elem)
+    def reset(self):
+        self.index = 0
+        self.indices = [0] * (self.ndim_m1 + 1)
+        self.offset = self.start
+
+    @jit.unroll_safe
+    def next(self):
+        self.index += 1
+        for i in xrange(self.ndim_m1, -1, -1):
+            if self.indices[i] < self.shape_m1[i]:
+                self.indices[i] += 1
+                self.offset += self.strides[i]
+                break
+            else:
+                self.indices[i] = 0
+                self.offset -= self.backstrides[i]
+
+    def next_skip_x(self, step):
+        # XXX implement
+        for _ in range(step):
+            self.next()
+
+    def done(self):
+        return self.index >= self.size
 
     def getitem(self):
         return self.array.getitem(self.offset)
@@ -107,52 +120,11 @@
     def getitem_bool(self):
         return self.array.getitem_bool(self.offset)
 
-    def next(self):
-        self.offset += self.skip
+    def setitem(self, elem):
+        self.array.setitem(self.offset, elem)
 
-    def next_skip_x(self, x):
-        self.offset += self.skip * x
 
-    def done(self):
-        return self.offset >= self.size
-
-    def reset(self):
-        self.offset %= self.size
-
-
-class OneDimViewIterator(ConcreteArrayIterator):
-    def __init__(self, array, start, strides, shape):
-        self.array = array
-        self.offset = start
-        self.index = 0
-        assert len(strides) == len(shape)
-        if len(shape) == 0:
-            self.skip = array.dtype.elsize
-            self.size = 1
-        else:
-            assert len(shape) == 1
-            self.skip = strides[0]
-            self.size = shape[0]
-
-    def next(self):
-        self.offset += self.skip
-        self.index += 1
-
-    def next_skip_x(self, x):
-        self.offset += self.skip * x
-        self.index += x
-
-    def done(self):
-        return self.index >= self.size
-
-    def reset(self):
-        self.offset %= self.size
-
-    def get_index(self, d):
-        return self.index
-
-
-class MultiDimViewIterator(ConcreteArrayIterator):
+class MultiDimViewIterator(ArrayIterator):
     def __init__(self, array, start, strides, backstrides, shape):
         self.indexes = [0] * len(shape)
         self.array = array
@@ -201,11 +173,8 @@
     def reset(self):
         self.offset %= self.size
 
-    def get_index(self, d):
-        return self.indexes[d]
 
-
-class AxisIterator(BaseArrayIterator):
+class AxisIterator(ArrayIterator):
     def __init__(self, array, shape, dim, cumulative):
         self.shape = shape
         strides = array.get_strides()
@@ -227,12 +196,6 @@
         self.dim = dim
         self.array = array
 
-    def setitem(self, elem):
-        self.array.setitem(self.offset, elem)
-
-    def getitem(self):
-        return self.array.getitem(self.offset)
-
     @jit.unroll_safe
     def next(self):
         for i in range(len(self.shape) - 1, -1, -1):
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
@@ -331,7 +331,7 @@
 
 def nonzero(res, arr, box):
     res_iter = res.create_iter()
-    arr_iter = arr.create_iter(require_index=True)
+    arr_iter = arr.create_iter()
     shapelen = len(arr.shape)
     dtype = arr.dtype
     dims = range(shapelen)
@@ -339,7 +339,7 @@
         nonzero_driver.jit_merge_point(shapelen=shapelen, dims=dims, dtype=dtype)
         if arr_iter.getitem_bool():
             for d in dims:
-                res_iter.setitem(box(arr_iter.get_index(d)))
+                res_iter.setitem(box(arr_iter.indices[d]))
                 res_iter.next()
         arr_iter.next()
     return res
@@ -435,8 +435,6 @@
         arr_iter.next_skip_x(step)
         length -= 1
         val_iter.next()
-        # WTF numpy?
-        val_iter.reset()
 
 fromstring_driver = jit.JitDriver(name = 'numpy_fromstring',
                                   greens = ['itemsize', '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
@@ -44,6 +44,7 @@
                                         "objects are not aligned"))
     return out_shape, right_critical_dim
 
+
 class __extend__(W_NDimArray):
     @jit.unroll_safe
     def descr_get_shape(self, space):
@@ -280,11 +281,10 @@
         s.append(suffix)
         return s.build()
 
-    def create_iter(self, shape=None, backward_broadcast=False, require_index=False):
+    def create_iter(self, shape=None, backward_broadcast=False):
         assert isinstance(self.implementation, BaseConcreteArray)
         return self.implementation.create_iter(
-            shape=shape, backward_broadcast=backward_broadcast,
-            require_index=require_index)
+            shape=shape, backward_broadcast=backward_broadcast)
 
     def create_axis_iter(self, shape, dim, cum):
         return self.implementation.create_axis_iter(shape, dim, cum)
@@ -1126,6 +1126,7 @@
         return w_obj
         pass
 
+
 @unwrap_spec(offset=int)
 def descr_new_array(space, w_subtype, w_shape, w_dtype=None, w_buffer=None,
                     offset=0, w_strides=None, w_order=None):
@@ -1176,6 +1177,7 @@
                         space.wrap('__array_finalize__')), w_subtype)
     return w_ret
 
+
 @unwrap_spec(addr=int)
 def descr__from_shape_and_storage(space, w_cls, w_shape, addr, w_dtype, w_subtype=None):
     """
diff --git a/pypy/module/micronumpy/test/test_flagsobj.py b/pypy/module/micronumpy/test/test_flagsobj.py
--- a/pypy/module/micronumpy/test/test_flagsobj.py
+++ b/pypy/module/micronumpy/test/test_flagsobj.py
@@ -2,6 +2,14 @@
 
 
 class AppTestFlagsObj(BaseNumpyAppTest):
+    def test_init(self):
+        import numpy as np
+        a = np.array([1,2,3])
+        assert a.flags['C'] is True
+        b = type(a.flags)()
+        assert b is not a.flags
+        assert b['C'] is True
+
     def test_repr(self):
         import numpy as np
         a = np.array([1,2,3])
diff --git a/pypy/module/micronumpy/ufuncs.py b/pypy/module/micronumpy/ufuncs.py
--- a/pypy/module/micronumpy/ufuncs.py
+++ b/pypy/module/micronumpy/ufuncs.py
@@ -9,9 +9,11 @@
 from pypy.module.micronumpy.base import convert_to_array, W_NDimArray
 from pypy.module.micronumpy.strides import shape_agreement
 
+
 def done_if_true(dtype, val):
     return dtype.itemtype.bool(val)
 
+
 def done_if_false(dtype, val):
     return not dtype.itemtype.bool(val)
 
@@ -544,6 +546,7 @@
         dtypenum += 2
         return descriptor.get_dtype_cache(space).dtypes_by_num[dtypenum]
 
+
 @jit.unroll_safe
 def find_unaryop_result_dtype(space, dt, promote_to_float=False,
         promote_bools=False, promote_to_largest=False):
@@ -570,6 +573,7 @@
                 return dtype
     return dt
 
+
 def find_dtype_for_scalar(space, w_obj, current_guess=None):
     bool_dtype = descriptor.get_dtype_cache(space).w_booldtype
     long_dtype = descriptor.get_dtype_cache(space).w_longdtype
@@ -611,9 +615,9 @@
                 'unable to create dtype from objects, "%T" instance not '
                 'supported', w_obj)
 
+
 def ufunc_dtype_caller(space, ufunc_name, op_name, argcount, comparison_func,
                        bool_result):
-    dtype_cache = descriptor.get_dtype_cache(space)
     def get_op(dtype):
         try:
             return getattr(dtype.itemtype, op_name)
@@ -621,6 +625,7 @@
             raise oefmt(space.w_NotImplementedError,
                         "%s not implemented for %s",
                         ufunc_name, dtype.get_name())
+    dtype_cache = descriptor.get_dtype_cache(space)
     if argcount == 1:
         def impl(res_dtype, value):
             res = get_op(res_dtype)(value)
@@ -762,6 +767,6 @@
             ufunc = W_Ufunc2(func, ufunc_name, **extra_kwargs)
         setattr(self, ufunc_name, ufunc)
 
+
 def get(space):
     return space.fromcache(UfuncState)
-


More information about the pypy-commit mailing list