Author: mattip <[email protected]>
Branch:
Changeset: r75575:7e9970164f05
Date: 2015-01-29 07:07 +0200
http://bitbucket.org/pypy/pypy/changeset/7e9970164f05/
Log: test, fix bogus shape,stride,backstride creation in SliceIterator
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
@@ -252,10 +252,6 @@
# Copy logic from npyiter_coalesce_axes, used in ufunc iterators
# and in nditer's with 'external_loop' flag
can_coalesce = True
- if it.order == 'F':
- fastest = 0
- else:
- fastest = -1
for idim in range(it.ndim - 1):
for op_it, _ in it.iters:
if op_it is None:
@@ -275,7 +271,7 @@
if can_coalesce:
for i in range(len(it.iters)):
new_iter = coalesce_iter(it.iters[i][0], it.op_flags[i], it,
- it.order, fastest)
+ it.order)
it.iters[i] = (new_iter, new_iter.reset())
if len(it.shape) > 1:
if it.order == 'F':
@@ -289,7 +285,7 @@
break
# Always coalesce at least one
for i in range(len(it.iters)):
- new_iter = coalesce_iter(it.iters[i][0], it.op_flags[i], it, 'C', -1)
+ new_iter = coalesce_iter(it.iters[i][0], it.op_flags[i], it, 'C')
it.iters[i] = (new_iter, new_iter.reset())
if len(it.shape) > 1:
if it.order == 'F':
@@ -300,12 +296,11 @@
it.shape = [1]
-def coalesce_iter(old_iter, op_flags, it, order, fastest=-1, flat=True):
+def coalesce_iter(old_iter, op_flags, it, order, flat=True):
'''
We usually iterate through an array one value at a time.
But after coalesce(), getoperand() will return a slice by removing
- the fastest varying dimension from the beginning or end of the shape.
- XXX - what happens on swapaxis arrays?
+ the fastest varying dimension(s) from the beginning or end of the shape.
If flat is true, then the slice will be 1d, otherwise stack up the shape of
the fastest varying dimension in the slice, so an iterator of a 'C' array
of shape (2,4,3) after two calls to coalesce will iterate 2 times over a
slice
@@ -319,6 +314,9 @@
new_strides = strides[1:]
new_backstrides = backstrides[1:]
_stride = old_iter.slice_stride + [strides[0]]
+ _shape = old_iter.slice_shape + [shape[0]]
+ _backstride = old_iter.slice_backstride + [strides[0] * (shape[0] - 1)]
+ fastest = shape[0]
else:
new_shape = shape[:-1]
new_strides = strides[:-1]
@@ -326,14 +324,15 @@
# use the operand's iterator's rightmost stride,
# even if it is not the fastest (for 'F' or swapped axis)
_stride = [strides[-1]] + old_iter.slice_stride
- _shape = [shape[fastest]] + old_iter.slice_shape
- _backstride = [(_shape[fastest] - 1) * _stride[0]] +
old_iter.slice_backstride
+ _shape = [shape[-1]] + old_iter.slice_shape
+ _backstride = [(shape[-1] - 1) * strides[-1]] +
old_iter.slice_backstride
+ fastest = shape[-1]
if flat:
_shape = [support.product(_shape)]
if len(_stride) > 1:
_stride = [min(_stride[0], _stride[1])]
_backstride = [(shape[0] - 1) * _stride[0]]
- return SliceIter(old_iter.array, old_iter.size / shape[fastest],
+ return SliceIter(old_iter.array, old_iter.size / fastest,
new_shape, new_strides, new_backstrides,
_shape, _stride, _backstride, op_flags, it)
diff --git a/pypy/module/micronumpy/test/test_ufuncs.py
b/pypy/module/micronumpy/test/test_ufuncs.py
--- a/pypy/module/micronumpy/test/test_ufuncs.py
+++ b/pypy/module/micronumpy/test/test_ufuncs.py
@@ -269,6 +269,26 @@
aout = ufunc_sum(ai)
assert aout.shape == (3, 3)
+ def test_frompyfunc_fortran(self):
+ import numpy as np
+ def tofrom_fortran(in0, out0):
+ out0[:] = in0.T
+
+ def lapack_like_times2(in0, out0):
+ a = np.empty(in0.T.shape, in0.dtype)
+ tofrom_fortran(in0, a)
+ a *= 2
+ tofrom_fortran(a, out0)
+
+ times2 = np.frompyfunc([lapack_like_times2], 1, 1,
+ signature='(m,n)->(m,n)',
+ dtypes=[np.dtype(float), np.dtype(float)],
+ stack_inputs=True,
+ )
+ in0 = np.arange(3300, dtype=float).reshape(100, 33)
+ out0 = times2(in0)
+ assert out0.shape == in0.shape
+ assert (out0 == in0 * 2).all()
def test_ufunc_kwargs(self):
from numpy import ufunc, frompyfunc, arange, dtype
diff --git a/pypy/module/micronumpy/ufuncs.py b/pypy/module/micronumpy/ufuncs.py
--- a/pypy/module/micronumpy/ufuncs.py
+++ b/pypy/module/micronumpy/ufuncs.py
@@ -651,14 +651,10 @@
w_op_flags, w_op_dtypes, w_casting, w_op_axes,
w_itershape)
# coalesce each iterators, according to inner_dimensions
- if nd_it.order == 'F':
- fastest = 0
- else:
- fastest = -1
for i in range(len(inargs) + len(outargs)):
for j in range(self.core_num_dims[i]):
new_iter = coalesce_iter(nd_it.iters[i][0],
nd_it.op_flags[i],
- nd_it, nd_it.order, fastest, flat=False)
+ nd_it, nd_it.order, flat=False)
nd_it.iters[i] = (new_iter, new_iter.reset())
# do the iteration
while not nd_it.done:
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit