[pypy-commit] pypy numpy-refactor: next_skip_x and port test_iter
fijal
noreply at buildbot.pypy.org
Thu Sep 6 18:43:21 CEST 2012
Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: numpy-refactor
Changeset: r57184:afefaf666d03
Date: 2012-09-06 18:42 +0200
http://bitbucket.org/pypy/pypy/changeset/afefaf666d03/
Log: next_skip_x and port test_iter
diff --git a/pypy/module/micronumpy/arrayimpl/concrete.py b/pypy/module/micronumpy/arrayimpl/concrete.py
--- a/pypy/module/micronumpy/arrayimpl/concrete.py
+++ b/pypy/module/micronumpy/arrayimpl/concrete.py
@@ -29,6 +29,10 @@
def next(self):
self.offset += self.skip
+ def next_skip_x(self, x):
+ self.offset += self.skip * x
+ self.index += x
+
def done(self):
return self.offset >= self.size
@@ -45,6 +49,10 @@
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
@@ -74,6 +82,22 @@
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
diff --git a/pypy/module/micronumpy/interp_flatiter.py b/pypy/module/micronumpy/interp_flatiter.py
--- a/pypy/module/micronumpy/interp_flatiter.py
+++ b/pypy/module/micronumpy/interp_flatiter.py
@@ -6,8 +6,8 @@
class W_FlatIterator(Wrappable):
def __init__(self, arr):
- self.arr = arr
- self.iter = self.arr.create_iter()
+ self.base = arr
+ self.iter = arr.create_iter()
self.index = 0
def descr_next(self, space):
@@ -18,6 +18,38 @@
self.index += 1
return w_res
+ @jit.unroll_safe
+ def descr_getitem(self, space, w_idx):
+ if not (space.isinstance_w(w_idx, space.w_int) or
+ space.isinstance_w(w_idx, space.w_slice)):
+ raise OperationError(space.w_IndexError,
+ space.wrap('unsupported iterator index'))
+ base = self.base
+ start, stop, step, length = space.decode_index4(w_idx, base.get_size())
+ # setslice would have been better, but flat[u:v] for arbitrary
+ # shapes of array a cannot be represented as a[x1:x2, y1:y2]
+ base_iter = base.create_iter()
+ xxx
+ return base.getitem(basei.offset)
+ base_iter = ViewIterator(base.start, base.strides,
+ base.backstrides, base.shape)
+ shapelen = len(base.shape)
+ basei = basei.next_skip_x(shapelen, start)
+ res = W_NDimArray([lngth], base.dtype, base.order)
+ ri = res.create_iter()
+ while not ri.done():
+ flat_get_driver.jit_merge_point(shapelen=shapelen,
+ base=base,
+ basei=basei,
+ step=step,
+ res=res,
+ ri=ri)
+ w_val = base.getitem(basei.offset)
+ res.setitem(ri.offset, w_val)
+ basei = basei.next_skip_x(shapelen, step)
+ ri = ri.next(shapelen)
+ return res
+
def descr_iter(self):
return self
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,4 +1,4 @@
-from pypy.module.micronumpy.interp_iter import ViewIterator
+from pypy.module.micronumpy.arrayimpl.concrete import MultiDimViewIterator
class TestIterDirect(object):
def test_C_viewiterator(self):
@@ -9,36 +9,36 @@
strides = [5, 1]
backstrides = [x * (y - 1) for x,y in zip(strides, shape)]
assert backstrides == [10, 4]
- i = ViewIterator(start, strides, backstrides, shape)
- i = i.next(2)
- i = i.next(2)
- i = i.next(2)
+ i = MultiDimViewIterator(None, start, strides, backstrides, shape)
+ i.next()
+ i.next()
+ i.next()
assert i.offset == 3
assert not i.done()
- assert i.indices == [0,3]
+ assert i.indexes == [0,3]
#cause a dimension overflow
- i = i.next(2)
- i = i.next(2)
+ i.next()
+ i.next()
assert i.offset == 5
- assert i.indices == [1,0]
+ assert i.indexes == [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 = ViewIterator(start, strides, backstrides, shape)
- i = i.next(2)
- i = i.next(2)
- i = i.next(2)
+ i = MultiDimViewIterator(None, start, strides, backstrides, shape)
+ i.next()
+ i.next()
+ i.next()
assert i.offset == 9
assert not i.done()
- assert i.indices == [0,3]
+ assert i.indexes == [0,3]
#cause a dimension overflow
- i = i.next(2)
- i = i.next(2)
+ i.next()
+ i.next()
assert i.offset == 1
- assert i.indices == [1,0]
+ assert i.indexes == [1,0]
def test_C_viewiterator_step(self):
#iteration in C order with #contiguous layout => strides[-1] is 1
@@ -48,22 +48,22 @@
strides = [5, 1]
backstrides = [x * (y - 1) for x,y in zip(strides, shape)]
assert backstrides == [10, 4]
- i = ViewIterator(start, strides, backstrides, shape)
- i = i.next_skip_x(2,2)
- i = i.next_skip_x(2,2)
- i = i.next_skip_x(2,2)
+ i = MultiDimViewIterator(None, start, strides, backstrides, shape)
+ 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.indices == [1,1]
+ assert i.indexes == [1,1]
#And for some big skips
- i = i.next_skip_x(2,5)
+ i.next_skip_x(5)
assert i.offset == 11
- assert i.indices == [2,1]
- i = i.next_skip_x(2,5)
+ assert i.indexes == [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.indices == [0,1]
+ assert i.indexes == [0,1]
assert i.done()
#Now what happens if the array is transposed? strides[-1] != 1
@@ -71,18 +71,18 @@
strides = [1, 3]
backstrides = [x * (y - 1) for x,y in zip(strides, shape)]
assert backstrides == [2, 12]
- i = ViewIterator(start, strides, backstrides, shape)
- i = i.next_skip_x(2,2)
- i = i.next_skip_x(2,2)
- i = i.next_skip_x(2,2)
+ i = MultiDimViewIterator(None, start, strides, backstrides, shape)
+ i.next_skip_x(2)
+ i.next_skip_x(2)
+ i.next_skip_x(2)
assert i.offset == 4
- assert i.indices == [1,1]
+ assert i.indexes == [1,1]
assert not i.done()
- i = i.next_skip_x(2,5)
+ i.next_skip_x(5)
assert i.offset == 5
- assert i.indices == [2,1]
+ assert i.indexes == [2,1]
assert not i.done()
- i = i.next_skip_x(2,5)
- assert i.indices == [0,1]
+ i.next_skip_x(5)
+ assert i.indexes == [0,1]
assert i.offset == 3
assert i.done()
More information about the pypy-commit
mailing list