Author: Brian Kearns <[email protected]>
Branch: 
Changeset: r73850:bb3689880ac8
Date: 2014-10-08 18:42 -0400
http://bitbucket.org/pypy/pypy/changeset/bb3689880ac8/

Log:    add numpy iterator goto method

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
@@ -51,16 +51,15 @@
         if not (space.isinstance_w(w_idx, space.w_int) or
                 space.isinstance_w(w_idx, space.w_slice)):
             raise oefmt(space.w_IndexError, 'unsupported iterator index')
-        self.state = self.iter.reset(self.state)
-        start, stop, step, length = space.decode_index4(w_idx, self.iter.size)
-        self.state = self.iter.next_skip_x(self.state, start)
         try:
+            start, stop, step, length = space.decode_index4(w_idx, 
self.iter.size)
+            state = self.iter.goto(start)
             if length == 1:
-                return self.iter.getitem(self.state)
+                return self.iter.getitem(state)
             base = self.base
             res = W_NDimArray.from_shape(space, [length], base.get_dtype(),
                                          base.get_order(), w_instance=base)
-            return loop.flatiter_getitem(res, self.iter, self.state, step)
+            return loop.flatiter_getitem(res, self.iter, state, step)
         finally:
             self.state = self.iter.reset(self.state)
 
@@ -69,19 +68,18 @@
                 space.isinstance_w(w_idx, space.w_slice)):
             raise oefmt(space.w_IndexError, 'unsupported iterator index')
         start, stop, step, length = space.decode_index4(w_idx, self.iter.size)
-        self.state = self.iter.reset(self.state)
-        self.state = self.iter.next_skip_x(self.state, start)
         try:
+            state = self.iter.goto(start)
             dtype = self.base.get_dtype()
             if length == 1:
                 try:
                     val = dtype.coerce(space, w_value)
                 except OperationError:
                     raise oefmt(space.w_ValueError, "Error setting single item 
of array.")
-                self.iter.setitem(self.state, val)
+                self.iter.setitem(state, val)
                 return
             arr = convert_to_array(space, w_value)
-            loop.flatiter_setitem(space, dtype, arr, self.iter, self.state, 
step, length)
+            loop.flatiter_setitem(space, dtype, arr, self.iter, state, step, 
length)
         finally:
             self.state = self.iter.reset(self.state)
 
diff --git a/pypy/module/micronumpy/iterators.py 
b/pypy/module/micronumpy/iterators.py
--- a/pypy/module/micronumpy/iterators.py
+++ b/pypy/module/micronumpy/iterators.py
@@ -91,7 +91,7 @@
 
 class ArrayIter(object):
     _immutable_fields_ = ['array', 'size', 'ndim_m1', 'shape_m1[*]',
-                          'strides[*]', 'backstrides[*]']
+                          'strides[*]', 'backstrides[*]', 'factors[*]']
 
     def __init__(self, array, size, shape, strides, backstrides):
         assert len(shape) == len(strides) == len(backstrides)
@@ -102,6 +102,15 @@
         self.strides = strides
         self.backstrides = backstrides
 
+        ndim = len(shape)
+        factors = [0] * ndim
+        for i in xrange(ndim):
+            if i == 0:
+                factors[ndim-1] = 1
+            else:
+                factors[ndim-i-1] = factors[ndim-i] * shape[ndim-i]
+        self.factors = factors
+
     @jit.unroll_safe
     def reset(self, state=None):
         if state is None:
@@ -154,6 +163,16 @@
                 assert step > 0
         return IterState(self, index, indices, offset)
 
+    @jit.unroll_safe
+    def goto(self, index):
+        # XXX simplify if self.contiguous (offset = start + index * elsize)
+        offset = self.array.start
+        current = index
+        for i in xrange(len(self.shape_m1)):
+            offset += (current / self.factors[i]) * self.strides[i]
+            current %= self.factors[i]
+        return IterState(self, index, None, offset)
+
     def done(self, state):
         assert state.iterator is self
         return state.index >= self.size
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
@@ -435,7 +435,7 @@
     while not ri.done(rs):
         flatiter_getitem_driver.jit_merge_point(dtype=dtype)
         ri.setitem(rs, base_iter.getitem(base_state))
-        base_state = base_iter.next_skip_x(base_state, step)
+        base_state = base_iter.goto(base_state.index + step)
         rs = ri.next(rs)
     return res
 
@@ -454,7 +454,7 @@
             val = val.convert_to(space, dtype)
         arr_iter.setitem(arr_state, val)
         # need to repeat i_nput values until all assignments are done
-        arr_state = arr_iter.next_skip_x(arr_state, step)
+        arr_state = arr_iter.goto(arr_state.index + step)
         val_state = val_iter.next(val_state)
         length -= 1
 
diff --git a/pypy/module/micronumpy/test/test_iterators.py 
b/pypy/module/micronumpy/test/test_iterators.py
--- a/pypy/module/micronumpy/test/test_iterators.py
+++ b/pypy/module/micronumpy/test/test_iterators.py
@@ -98,3 +98,21 @@
         assert s.indices == [0,1]
         assert s.offset == 3
         assert i.done(s)
+
+    def test_iterator_goto(self):
+        shape = [3, 5]
+        strides = [1, 3]
+        backstrides = [x * (y - 1) for x,y in zip(strides, shape)]
+        assert backstrides == [2, 12]
+        a = MockArray()
+        a.start = 42
+        i = ArrayIter(a, support.product(shape), shape,
+                      strides, backstrides)
+        s = i.reset()
+        assert s.index == 0
+        assert s.indices == [0, 0]
+        assert s.offset == a.start
+        s = i.goto(11)
+        assert s.index == 11
+        assert s.indices is None
+        assert s.offset == a.start + 5
diff --git a/pypy/module/micronumpy/test/test_zjit.py 
b/pypy/module/micronumpy/test/test_zjit.py
--- a/pypy/module/micronumpy/test/test_zjit.py
+++ b/pypy/module/micronumpy/test/test_zjit.py
@@ -544,16 +544,23 @@
         assert result == 10.0
         self.check_trace_count(1)
         self.check_simple_loop({
-            'getarrayitem_gc': 2,
+            'arraylen_gc': 2,
+            'getarrayitem_gc': 1,
             'guard_false': 1,
-            'guard_true': 2,
-            'int_add': 6,
+            'guard_true': 1,
+            'int_add': 7,
+            'int_and': 1,
+            'int_floordiv': 1,
             'int_ge': 1,
-            'int_lt': 2,
+            'int_lt': 1,
+            'int_mod': 1,
+            'int_mul': 2,
+            'int_rshift': 2,
+            'int_sub': 1,
             'jump': 1,
             'raw_load': 1,
             'raw_store': 1,
-            'setarrayitem_gc': 2,
+            'setarrayitem_gc': 1,
         })
 
     def define_flat_setitem():
@@ -569,17 +576,23 @@
         assert result == 1.0
         self.check_trace_count(1)
         self.check_simple_loop({
-            'getarrayitem_gc': 2,
+            'arraylen_gc': 2,
+            'getarrayitem_gc': 1,
             'guard_not_invalidated': 1,
-            'guard_true': 3,
-            'int_add': 6,
+            'guard_true': 2,
+            'int_add': 7,
+            'int_and': 1,
+            'int_floordiv': 1,
             'int_gt': 1,
-            'int_lt': 2,
-            'int_sub': 1,
+            'int_lt': 1,
+            'int_mod': 1,
+            'int_mul': 2,
+            'int_rshift': 2,
+            'int_sub': 2,
             'jump': 1,
             'raw_load': 1,
             'raw_store': 1,
-            'setarrayitem_gc': 2,
+            'setarrayitem_gc': 1,
         })
 
     def define_dot():
diff --git a/pypy/module/pypyjit/test_pypy_c/test_micronumpy.py 
b/pypy/module/pypyjit/test_pypy_c/test_micronumpy.py
--- a/pypy/module/pypyjit/test_pypy_c/test_micronumpy.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_micronumpy.py
@@ -92,47 +92,50 @@
         assert log.result == 42.0
         loop, = log.loops_by_filename(self.filepath)
         assert loop.match("""
-            i123 = int_lt(i112, i44)
-            guard_true(i123, descr=...)
-            p124 = getfield_gc_pure(p121, descr=<FieldP 
pypy.module.micronumpy.iterators.IterState.inst_indices 16>)
-            setarrayitem_gc(p124, 1, 0, descr=<ArrayS 8>)
-            setarrayitem_gc(p124, 0, 0, descr=<ArrayS 8>)
-            i126 = int_lt(i112, i65)
+            i125 = int_lt(i117, i44)
+            guard_true(i125, descr=...)
+            i126 = int_lt(i117, i50)
             guard_true(i126, descr=...)
-            i127 = int_sub(i75, i112)
-            i128 = int_lt(0, i127)
-            guard_false(i128, descr=...)
-            i129 = int_floordiv(i112, i75)
-            i130 = int_mul(i129, i75)
-            i131 = int_sub(i112, i130)
-            i132 = int_rshift(i131, 63)
-            i133 = int_add(i129, i132)
-            i134 = int_mul(i133, i75)
-            i135 = int_sub(i112, i134)
-            i136 = int_mul(i91, i135)
-            i137 = int_add(i64, i136)
-            i138 = int_sub(i98, i133)
-            setarrayitem_gc(p124, 1, i135, descr=<ArrayS 8>)
-            i139 = int_lt(0, i138)
-            guard_true(i139, descr=...)
-            i140 = int_mul(i102, i133)
-            i141 = int_add(i137, i140)
-            f142 = raw_load(i108, i141, descr=<ArrayF 8>)
-            i143 = int_add(i112, 1)
-            setarrayitem_gc(p124, 1, 0, descr=<ArrayS 8>)
+            i127 = int_floordiv(i117, i61)
+            i128 = int_mul(i127, i61)
+            i129 = int_sub(i117, i128)
+            i130 = int_rshift(i129, 63)
+            i131 = int_add(i127, i130)
+            i132 = int_mul(i131, i71)
+            i133 = int_add(i55, i132)
+            i134 = int_mod(i117, i61)
+            i135 = int_rshift(i134, 63)
+            i136 = int_and(i61, i135)
+            i137 = int_add(i134, i136)
+            i138 = int_floordiv(i137, i80)
+            i139 = int_mul(i138, i80)
+            i140 = int_sub(i137, i139)
+            i141 = int_rshift(i140, 63)
+            i142 = int_add(i138, i141)
+            i143 = int_mul(i142, i88)
+            i144 = int_add(i133, i143)
+            i145 = int_mod(i137, i80)
+            i146 = int_rshift(i145, 63)
+            i147 = int_and(i80, i146)
+            i148 = int_add(i145, i147)
+            f149 = raw_load(i100, i144, descr=<ArrayF 8>)
+            p150 = getfield_gc_pure(p123, descr=<FieldP 
pypy.module.micronumpy.iterators.IterState.inst_indices 16>)
+            i151 = int_add(i117, 1)
+            setarrayitem_gc(p150, 1, 0, descr=<ArrayS 8>)
+            setarrayitem_gc(p150, 0, 0, descr=<ArrayS 8>)
             guard_not_invalidated(descr=...)
-            i144 = getfield_raw(ticker_address, descr=<FieldS 
pypysig_long_struct.c_value 0>)
-            i145 = int_lt(i144, 0)
-            guard_false(i145, descr=...)
-            p146 = new_with_vtable(...)
-            setfield_gc(p146, p49, descr=<FieldP 
pypy.module.micronumpy.iterators.IterState.inst_iterator 24>)
-            setfield_gc(p146, p124, descr=<FieldP 
pypy.module.micronumpy.iterators.IterState.inst_indices 16>)
-            setfield_gc(p146, i64, descr=<FieldS 
pypy.module.micronumpy.iterators.IterState.inst_offset 32>)
-            setfield_gc(p146, 0, descr=<FieldS 
pypy.module.micronumpy.iterators.IterState.inst_index 8>)
-            setfield_gc(p16, p146, descr=<FieldP 
pypy.module.micronumpy.flatiter.W_FlatIterator.inst_state 56>)
-            i147 = arraylen_gc(p72, descr=<ArrayS 8>)
-            i148 = arraylen_gc(p90, descr=<ArrayS 8>)
-            jump(p0, p1, p3, p6, p7, p12, p14, p16, i143, f142, p26, i44, 
p146, i65, p49, i64, i75, i91, i98, i102, i108, p72, p90, descr=...)
+            i154 = getfield_raw(ticker_address, descr=<FieldS 
pypysig_long_struct.c_value 0>)
+            i155 = int_lt(i154, 0)
+            guard_false(i155, descr=...)
+            p156 = new_with_vtable(...)
+            setfield_gc(p156, i55, descr=<FieldS 
pypy.module.micronumpy.iterators.IterState.inst_offset 32>)
+            setfield_gc(p156, 0, descr=<FieldS 
pypy.module.micronumpy.iterators.IterState.inst_index 8>)
+            setfield_gc(p156, p150, descr=<FieldP 
pypy.module.micronumpy.iterators.IterState.inst_indices 16>)
+            setfield_gc(p156, p49, descr=<FieldP 
pypy.module.micronumpy.iterators.IterState.inst_iterator 24>)
+            setfield_gc(p16, p156, descr=<FieldP 
pypy.module.micronumpy.flatiter.W_FlatIterator.inst_state 56>)
+            i157 = arraylen_gc(p60, descr=<ArrayS 8>)
+            i158 = arraylen_gc(p70, descr=<ArrayS 8>)
+            jump(p0, p1, p3, p6, p7, p12, p14, p16, i151, f149, p26, i44, i50, 
i61, i71, i55, i80, i88, i100, p156, p49, p60, p70, descr=...)
         """)
 
     def test_array_flatiter_setitem_single(self):
@@ -149,47 +152,48 @@
         assert log.result == 42.0
         loop, = log.loops_by_filename(self.filepath)
         assert loop.match("""
-            i126 = int_lt(i115, i42)
-            guard_true(i126, descr=...)
-            i127 = int_lt(i115, i48)
-            guard_true(i127, descr=...)
-            p128 = getfield_gc_pure(p124, descr=<FieldP 
pypy.module.micronumpy.iterators.IterState.inst_indices 16>)
-            i129 = int_sub(i73, i115)
-            setarrayitem_gc(p128, 1, 0, descr=<ArrayS 8>)
-            setarrayitem_gc(p128, 0, 0, descr=<ArrayS 8>)
-            i131 = int_lt(0, i129)
-            guard_false(i131, descr=...)
-            i132 = int_floordiv(i115, i73)
-            i133 = int_mul(i132, i73)
-            i134 = int_sub(i115, i133)
-            i135 = int_rshift(i134, 63)
-            i136 = int_add(i132, i135)
-            i137 = int_mul(i136, i73)
-            i138 = int_sub(i115, i137)
-            i139 = int_mul(i89, i138)
-            i140 = int_add(i66, i139)
-            i141 = int_sub(i96, i136)
-            setarrayitem_gc(p128, 1, i138, descr=<ArrayS 8>)
-            i142 = int_lt(0, i141)
-            guard_true(i142, descr=...)
-            i143 = int_mul(i100, i136)
-            i144 = int_add(i140, i143)
-            setarrayitem_gc(p128, 0, i136, descr=<ArrayS 8>)
+            i128 = int_lt(i120, i42)
+            guard_true(i128, descr=...)
+            i129 = int_lt(i120, i48)
+            guard_true(i129, descr=...)
+            i130 = int_floordiv(i120, i59)
+            i131 = int_mul(i130, i59)
+            i132 = int_sub(i120, i131)
+            i133 = int_rshift(i132, 63)
+            i134 = int_add(i130, i133)
+            i135 = int_mul(i134, i69)
+            i136 = int_add(i53, i135)
+            i137 = int_mod(i120, i59)
+            i138 = int_rshift(i137, 63)
+            i139 = int_and(i59, i138)
+            i140 = int_add(i137, i139)
+            i141 = int_floordiv(i140, i78)
+            i142 = int_mul(i141, i78)
+            i143 = int_sub(i140, i142)
+            i144 = int_rshift(i143, 63)
+            i145 = int_add(i141, i144)
+            i146 = int_mul(i145, i86)
+            i147 = int_add(i136, i146)
+            i148 = int_mod(i140, i78)
+            i149 = int_rshift(i148, 63)
+            i150 = int_and(i78, i149)
+            i151 = int_add(i148, i150)
             guard_not_invalidated(descr=...)
-            raw_store(i111, i144, 42.000000, descr=<ArrayF 8>)
-            i146 = int_add(i115, 1)
-            i147 = getfield_raw(ticker_address, descr=<FieldS 
pypysig_long_struct.c_value 0>)
-            setarrayitem_gc(p128, 1, 0, descr=<ArrayS 8>)
-            setarrayitem_gc(p128, 0, 0, descr=<ArrayS 8>)
-            i149 = int_lt(i147, 0)
-            guard_false(i149, descr=...)
-            p150 = new_with_vtable(...)
-            setfield_gc(p150, p47, descr=<FieldP 
pypy.module.micronumpy.iterators.IterState.inst_iterator 24>)
-            setfield_gc(p150, p128, descr=<FieldP 
pypy.module.micronumpy.iterators.IterState.inst_indices 16>)
-            setfield_gc(p150, i66, descr=<FieldS 
pypy.module.micronumpy.iterators.IterState.inst_offset 32>)
-            setfield_gc(p150, 0, descr=<FieldS 
pypy.module.micronumpy.iterators.IterState.inst_index 8>)
-            setfield_gc(p16, p150, descr=<FieldP 
pypy.module.micronumpy.flatiter.W_FlatIterator.inst_state 56>)
-            i151 = arraylen_gc(p70, descr=<ArrayS 8>)
-            i152 = arraylen_gc(p88, descr=<ArrayS 8>)
-            jump(p0, p1, p3, p6, p7, p12, p14, p16, i146, i42, i48, p150, i73, 
i66, p47, i89, i96, i100, i111, p70, p88, descr=...)
+            raw_store(i103, i147, 42.000000, descr=<ArrayF 8>)
+            p152 = getfield_gc_pure(p126, descr=<FieldP 
pypy.module.micronumpy.iterators.IterState.inst_indices 16>)
+            i153 = int_add(i120, 1)
+            i154 = getfield_raw(ticker_address, descr=<FieldS 
pypysig_long_struct.c_value 0>)
+            setarrayitem_gc(p152, 1, 0, descr=<ArrayS 8>)
+            setarrayitem_gc(p152, 0, 0, descr=<ArrayS 8>)
+            i157 = int_lt(i154, 0)
+            guard_false(i157, descr=...)
+            p158 = new_with_vtable(...)
+            setfield_gc(p158, i53, descr=<FieldS 
pypy.module.micronumpy.iterators.IterState.inst_offset 32>)
+            setfield_gc(p158, 0, descr=<FieldS 
pypy.module.micronumpy.iterators.IterState.inst_index 8>)
+            setfield_gc(p158, p152, descr=<FieldP 
pypy.module.micronumpy.iterators.IterState.inst_indices 16>)
+            setfield_gc(p158, p47, descr=<FieldP 
pypy.module.micronumpy.iterators.IterState.inst_iterator 24>)
+            setfield_gc(p16, p158, descr=<FieldP 
pypy.module.micronumpy.flatiter.W_FlatIterator.inst_state 56>)
+            i159 = arraylen_gc(p58, descr=<ArrayS 8>)
+            i160 = arraylen_gc(p68, descr=<ArrayS 8>)
+            jump(p0, p1, p3, p6, p7, p12, p14, p16, i153, i42, i48, i59, i69, 
i53, i78, i86, p47, i103, p158, p58, p68, descr=...)
         """)
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to