[pypy-commit] pypy numpypy-nditer: Implement the c_index and the f_index flags on the nditer class
rguillebert
noreply at buildbot.pypy.org
Thu Jun 13 20:02:23 CEST 2013
Author: Romain Guillebert <romain.py at gmail.com>
Branch: numpypy-nditer
Changeset: r64874:cbc60b20e6c2
Date: 2013-06-13 20:01 +0200
http://bitbucket.org/pypy/pypy/changeset/cbc60b20e6c2/
Log: Implement the c_index and the f_index flags on the nditer class
diff --git a/pypy/module/micronumpy/interp_nditer.py b/pypy/module/micronumpy/interp_nditer.py
--- a/pypy/module/micronumpy/interp_nditer.py
+++ b/pypy/module/micronumpy/interp_nditer.py
@@ -201,18 +201,52 @@
shape, backward)
return MultiDimViewIterator(imp, imp.dtype, imp.start, r[0], r[1], shape)
+def is_backward(imp, order):
+ if order == 'K' or (order == 'C' and imp.order == 'C'):
+ return False
+ elif order =='F' and imp.order == 'C':
+ return True
+ else:
+ raise NotImplementedError('not implemented yet')
+
def get_external_loop_iter(space, order, arr, shape):
imp = arr.implementation
- if order == 'K' or (order == 'C' and imp.order == 'C'):
- backward = False
- elif order =='F' and imp.order == 'C':
- backward = True
- else:
- raise OperationError(space.w_NotImplementedError, space.wrap(
- 'not implemented yet'))
+
+ backward = is_backward(imp, order)
return SliceIterator(arr, imp.strides, imp.backstrides, shape, order=order, backward=backward)
+class IndexIterator(object):
+ def __init__(self, shape, backward=False):
+ self.shape = shape
+ self.index = [0] * len(shape)
+ self.backward = backward
+ self.called = False
+
+ def next(self):
+ # TODO It's probably possible to refactor all the "next" method from each iterator
+ if not self.called:
+ self.called = True
+ return
+ for i in range(len(self.shape) - 1, -1, -1):
+ if self.index[i] < self.shape[i] - 1:
+ self.index[i] += 1
+ break
+ else:
+ self.index[i] = 0
+
+ def getvalue(self):
+ if not self.called:
+ return 0
+ if not self.backward:
+ ret = self.index[-1]
+ for i in range(len(self.shape) - 2, -1, -1):
+ ret += self.index[i] * self.shape[i - 1]
+ else:
+ ret = self.index[0]
+ for i in range(1, len(self.shape)):
+ ret += self.index[i] * self.shape[i - 1]
+ return ret
class W_NDIter(W_Root):
@@ -229,6 +263,7 @@
self.refs_ok = False
self.reduce_ok = False
self.zerosize_ok = False
+ self.index_iter = None
if space.isinstance_w(w_seq, space.w_tuple) or \
space.isinstance_w(w_seq, space.w_list):
w_seq_as_list = space.listview(w_seq)
@@ -240,6 +275,10 @@
len(self.seq), parse_op_flag)
self.iters=[]
self.shape = iter_shape = shape_agreement_multiple(space, self.seq)
+ if self.tracked_index != "":
+ if self.order == "K":
+ self.order = self.seq[0].implementation.order
+ self.index_iter = IndexIterator(iter_shape, backward=self.order != self.tracked_index)
if self.external_loop:
for i in range(len(self.seq)):
self.iters.append(ExternalLoopIterator(get_external_loop_iter(space, self.order,
@@ -271,6 +310,8 @@
else:
raise OperationError(space.w_StopIteration, space.w_None)
res = []
+ if self.index_iter:
+ self.index_iter.next()
for i in range(len(self.iters)):
res.append(self.iters[i].getitem(space, self.seq[i]))
self.iters[i].next()
@@ -324,12 +365,12 @@
'not implemented yet'))
def descr_get_has_index(self, space):
- raise OperationError(space.w_NotImplementedError, space.wrap(
- 'not implemented yet'))
+ return space.wrap(not self.tracked_index == "")
def descr_get_index(self, space):
- raise OperationError(space.w_NotImplementedError, space.wrap(
- 'not implemented yet'))
+ if self.tracked_index == "":
+ raise OperationError(space.w_ValueError, "Iterator does not have an index")
+ return space.wrap(self.index_iter.getvalue())
def descr_get_has_multi_index(self, space):
raise OperationError(space.w_NotImplementedError, space.wrap(
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
@@ -66,6 +66,24 @@
e = ex
assert e
+ def test_index(self):
+ from numpypy import arange, nditer, zeros
+ a = arange(6).reshape(2,3)
+
+ r = []
+ it = nditer(a, flags=['c_index'])
+ assert it.has_index
+ for value in it:
+ r.append((value, it.index))
+ assert r == [(0, 0), (1, 1), (2, 2), (3, 3), (4, 4), (5, 5)]
+
+ r = []
+ it = nditer(a, flags=['f_index'])
+ assert it.has_index
+ for value in it:
+ r.append((value, it.index))
+ assert r == [(0, 0), (1, 2), (2, 4), (3, 1), (4, 3), (5, 5)]
+
def test_interface(self):
from numpypy import arange, nditer, zeros
a = arange(6).reshape(2,3)
More information about the pypy-commit
mailing list