[pypy-commit] pypy nditer-external_loop: cleanup
mattip
noreply at buildbot.pypy.org
Fri Oct 31 00:11:20 CET 2014
Author: mattip <matti.picus at gmail.com>
Branch: nditer-external_loop
Changeset: r74310:e4b0f4a3ed16
Date: 2014-10-31 00:48 +0200
http://bitbucket.org/pypy/pypy/changeset/e4b0f4a3ed16/
Log: cleanup
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
@@ -99,6 +99,7 @@
class ArrayIter(object):
_immutable_fields_ = ['contiguous', 'array', 'size', 'ndim_m1', 'shape_m1[*]',
'strides[*]', 'backstrides[*]', 'factors[*]',
+ 'slice_shape', 'slice_stride', 'slice_backstride',
'track_index', 'operand_type', 'slice_operand_type']
track_index = True
@@ -116,6 +117,11 @@
self.shape_m1 = [s - 1 for s in shape]
self.strides = strides
self.backstrides = backstrides
+ self.slice_shape = 1
+ self.slice_stride = -1
+ if strides:
+ self.slice_stride = strides[-1]
+ self.slice_backstride = 1
self.slice_operand_type = concrete.SliceArray
ndim = len(shape)
diff --git a/pypy/module/micronumpy/nditer.py b/pypy/module/micronumpy/nditer.py
--- a/pypy/module/micronumpy/nditer.py
+++ b/pypy/module/micronumpy/nditer.py
@@ -178,61 +178,61 @@
def coalesce_axes(it, space):
# Copy logic from npyiter_coalesce_axes, used in ufunc iterators
# and in nditer's with 'external_loop' flag
- out_shape = it.shape[:]
can_coalesce = True
if it.order == 'F':
- fastest = 0
+ indxs = slice(1,None)
else:
- fastest = -1
+ indxs = slice(0,-1)
for idim in range(it.ndim - 1):
for op_it, _ in it.iters:
if op_it is None:
continue
assert isinstance(op_it, ArrayIter)
indx = len(op_it.strides)
- if op_it.array.strides[:indx] != op_it.strides:
+ if it.order == 'F':
+ aslice = slice(-indx,None)
+ else:
+ aslice = slice(None, indx)
+ # does op_it iters over array "naturally"
+ if op_it.array.strides[aslice] != op_it.strides:
+ print 'cannot coalesce array strides', op_it.array.strides,
+ print 'with iter strides', op_it.strides
can_coalesce = False
break
+ # is the resulting slice array contiguous
if can_coalesce:
- if it.order == 'F':
- last = out_shape[0]
- out_shape = out_shape[1:]
- else:
- last = out_shape[-1]
- out_shape = out_shape[:-1]
for i in range(len(it.iters)):
old_iter = it.iters[i][0]
shape = [s+1 for s in old_iter.shape_m1]
strides = old_iter.strides
backstrides = old_iter.backstrides
- new_shape = shape[:-1]
- new_strides = strides[:-1]
- new_backstrides = backstrides[:-1]
- _shape = shape[-1]
- _stride = strides[fastest]
- _backstride = backstrides[-1]
- if isinstance(old_iter, SliceIter):
- _shape *= old_iter.slice_shape
+ new_shape = shape[indxs]
+ new_strides = strides[indxs]
+ new_backstrides = backstrides[indxs]
+ # We always want the "fastest" iterator in external loops
+ if it.order == 'F':
+ fastest = 0
+ _stride = min(strides[0], old_iter.slice_stride)
+ else:
+ fastest = -1
_stride = old_iter.slice_stride
- _backstride = (_shape - 1) * _stride
- new_iter = SliceIter(old_iter.array, old_iter.size / shape[-1],
+ _shape = shape[fastest] * old_iter.slice_shape
+ _backstride = (_shape - 1) * _stride
+ new_iter = SliceIter(old_iter.array, old_iter.size / shape[fastest],
new_shape, new_strides, new_backstrides,
_shape, _stride, _backstride,
it.op_flags[i], it)
- if len(shape) > 1:
- it.shape = out_shape
+ it.iters[i] = (new_iter, new_iter.reset())
+ if len(it.shape) > 1:
+ if it.order == 'F':
+ it.shape = it.shape[1:]
else:
- it.shape = [1]
- it.iters[i] = (new_iter, new_iter.reset())
+ it.shape = it.shape[:-1]
+ else:
+ it.shape = [1]
else:
break
- # Always coalesce at least one
- if it.order == 'F':
- last = out_shape[0]
- out_shape = out_shape[1:]
- else:
- last = out_shape[-1]
- out_shape = out_shape[:-1]
+ # Always coalesce at least one
for i in range(len(it.iters)):
old_iter = it.iters[i][0]
shape = [s+1 for s in old_iter.shape_m1]
@@ -241,22 +241,23 @@
new_shape = shape[:-1]
new_strides = strides[:-1]
new_backstrides = backstrides[:-1]
- _shape = shape[-1]
- _stride = strides[-1]
- _backstride = backstrides[-1]
- if isinstance(old_iter, SliceIter):
- _shape *= old_iter.slice_shape
- _stride = old_iter.slice_stride
- _backstride = (_shape - 1) * _stride
+ _shape = shape[-1] * old_iter.slice_shape
+ # use the operand's iterator's rightmost stride,
+ # even if it is larger than minimum (for 'F' or swapped axis)
+ _stride = old_iter.slice_stride
+ _backstride = (_shape - 1) * _stride
new_iter = SliceIter(old_iter.array, old_iter.size / shape[-1],
new_shape, new_strides, new_backstrides,
_shape, _stride, _backstride,
it.op_flags[i], it)
- if len(shape) > 1:
- it.shape = out_shape
+ it.iters[i] = (new_iter, new_iter.reset())
+ if len(it.shape) > 1:
+ if it.order == 'F':
+ it.shape = it.shape[1:]
else:
- it.shape = [1]
- it.iters[i] = (new_iter, new_iter.reset())
+ it.shape = it.shape[:-1]
+ else:
+ it.shape = [1]
class IndexIterator(object):
def __init__(self, shape, backward=False):
More information about the pypy-commit
mailing list