Author: Brian Kearns <bdkea...@gmail.com> Branch: Changeset: r69520:c4355a931db5 Date: 2014-02-27 08:28 -0500 http://bitbucket.org/pypy/pypy/changeset/c4355a931db5/
Log: kill MultiDimViewIterator 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 @@ -283,9 +283,9 @@ self.get_backstrides(), self.get_shape(), shape, backward_broadcast) - return iter.MultiDimViewIterator(self, self.start, - r[0], r[1], shape) - return iter.ArrayIterator(self) + return iter.ArrayIterator(self, shape, r[0], r[1]) + return iter.ArrayIterator(self, self.shape, self.strides, + self.backstrides) def create_axis_iter(self, shape, dim, cum): return iter.AxisIterator(self, shape, dim, cum) @@ -293,7 +293,7 @@ def create_dot_iter(self, shape, skip): r = calculate_dot_strides(self.get_strides(), self.get_backstrides(), shape, skip) - return iter.MultiDimViewIterator(self, self.start, r[0], r[1], shape) + return iter.ArrayIterator(self, shape, r[0], r[1]) def swapaxes(self, space, orig_arr, axis1, axis2): shape = self.get_shape()[:] 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 @@ -79,14 +79,17 @@ class ArrayIterator(object): - def __init__(self, array): + _immutable_fields_ = ['array', 'start', 'size', 'ndim_m1', 'shape_m1', + 'strides', 'backstrides'] + + def __init__(self, array, shape, strides, backstrides): self.array = array 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.size = support.product(shape) + self.ndim_m1 = len(shape) - 1 + self.shape_m1 = [s - 1 for s in shape] + self.strides = strides + self.backstrides = backstrides self.reset() def reset(self): @@ -106,10 +109,24 @@ self.indices[i] = 0 self.offset -= self.backstrides[i] + @jit.unroll_safe def next_skip_x(self, step): - # XXX implement - for _ in range(step): - self.next() + assert step >= 0 + if step == 0: + return + self.index += step + for i in range(self.ndim_m1, -1, -1): + if self.indices[i] < (self.shape_m1[i] + 1) - step: + self.indices[i] += step + self.offset += self.strides[i] * step + break + else: + remaining_step = (self.indices[i] + step) // (self.shape_m1[i] + 1) + this_i_step = step - remaining_step * (self.shape_m1[i] + 1) + self.indices[i] = self.indices[i] + this_i_step + self.offset += self.strides[i] * this_i_step + step = remaining_step + assert step > 0 def done(self): return self.index >= self.size @@ -124,56 +141,6 @@ self.array.setitem(self.offset, elem) -class MultiDimViewIterator(ArrayIterator): - def __init__(self, array, start, strides, backstrides, shape): - self.indexes = [0] * len(shape) - self.array = array - self.shape = shape - self.offset = start - self.shapelen = len(shape) - self._done = self.shapelen == 0 or support.product(shape) == 0 - self.strides = strides - self.backstrides = backstrides - self.size = array.size - - @jit.unroll_safe - def next(self): - offset = self.offset - for i in range(self.shapelen - 1, -1, -1): - if self.indexes[i] < self.shape[i] - 1: - self.indexes[i] += 1 - offset += self.strides[i] - break - else: - self.indexes[i] = 0 - offset -= self.backstrides[i] - else: - self._done = True - self.offset = offset - - @jit.unroll_safe - def next_skip_x(self, step): - for i in range(len(self.shape) - 1, -1, -1): - if self.indexes[i] < self.shape[i] - step: - self.indexes[i] += step - self.offset += self.strides[i] * step - break - else: - remaining_step = (self.indexes[i] + step) // self.shape[i] - this_i_step = step - remaining_step * self.shape[i] - self.offset += self.strides[i] * this_i_step - self.indexes[i] = self.indexes[i] + this_i_step - step = remaining_step - else: - self._done = True - - def done(self): - return self._done - - def reset(self): - self.offset %= self.size - - class AxisIterator(ArrayIterator): def __init__(self, array, shape, dim, cumulative): self.shape = shape diff --git a/pypy/module/micronumpy/test/test_iter.py b/pypy/module/micronumpy/test/test_iter.py --- a/pypy/module/micronumpy/test/test_iter.py +++ b/pypy/module/micronumpy/test/test_iter.py @@ -1,74 +1,73 @@ -from pypy.module.micronumpy.iter import MultiDimViewIterator +from pypy.module.micronumpy.iter import ArrayIterator class MockArray(object): size = 1 + start = 0 class TestIterDirect(object): - def test_C_viewiterator(self): + def test_iterator_basic(self): #Let's get started, simple iteration in C order with #contiguous layout => strides[-1] is 1 - start = 0 shape = [3, 5] strides = [5, 1] backstrides = [x * (y - 1) for x,y in zip(strides, shape)] assert backstrides == [10, 4] - i = MultiDimViewIterator(MockArray, start, strides, backstrides, shape) + i = ArrayIterator(MockArray, shape, strides, backstrides) i.next() i.next() i.next() assert i.offset == 3 assert not i.done() - assert i.indexes == [0,3] + assert i.indices == [0,3] #cause a dimension overflow i.next() i.next() assert i.offset == 5 - assert i.indexes == [1,0] + assert i.indices == [1,0] #Now what happens if the array is transposed? strides[-1] != 1 # therefore layout is non-contiguous strides = [1, 3] backstrides = [x * (y - 1) for x,y in zip(strides, shape)] assert backstrides == [2, 12] - i = MultiDimViewIterator(MockArray, start, strides, backstrides, shape) + i = ArrayIterator(MockArray, shape, strides, backstrides) i.next() i.next() i.next() assert i.offset == 9 assert not i.done() - assert i.indexes == [0,3] + assert i.indices == [0,3] #cause a dimension overflow i.next() i.next() assert i.offset == 1 - assert i.indexes == [1,0] + assert i.indices == [1,0] - def test_C_viewiterator_step(self): + def test_iterator_step(self): #iteration in C order with #contiguous layout => strides[-1] is 1 #skip less than the shape - start = 0 shape = [3, 5] strides = [5, 1] backstrides = [x * (y - 1) for x,y in zip(strides, shape)] assert backstrides == [10, 4] - i = MultiDimViewIterator(MockArray, start, strides, backstrides, shape) + i = ArrayIterator(MockArray, shape, strides, backstrides) i.next_skip_x(2) i.next_skip_x(2) i.next_skip_x(2) assert i.offset == 6 assert not i.done() - assert i.indexes == [1,1] + assert i.indices == [1,1] #And for some big skips i.next_skip_x(5) assert i.offset == 11 - assert i.indexes == [2,1] + assert i.indices == [2,1] i.next_skip_x(5) # Note: the offset does not overflow but recycles, # this is good for broadcast assert i.offset == 1 - assert i.indexes == [0,1] + assert i.indices == [0,1] assert i.done() #Now what happens if the array is transposed? strides[-1] != 1 @@ -76,18 +75,18 @@ strides = [1, 3] backstrides = [x * (y - 1) for x,y in zip(strides, shape)] assert backstrides == [2, 12] - i = MultiDimViewIterator(MockArray, start, strides, backstrides, shape) + i = ArrayIterator(MockArray, shape, strides, backstrides) i.next_skip_x(2) i.next_skip_x(2) i.next_skip_x(2) assert i.offset == 4 - assert i.indexes == [1,1] + assert i.indices == [1,1] assert not i.done() i.next_skip_x(5) assert i.offset == 5 - assert i.indexes == [2,1] + assert i.indices == [2,1] assert not i.done() i.next_skip_x(5) - assert i.indexes == [0,1] + assert i.indices == [0,1] assert i.offset == 3 assert i.done() _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit