[pypy-commit] pypy default: (mattip) merge numpypy-reshape-bug
fijal
noreply at buildbot.pypy.org
Mon Jan 23 01:05:35 CET 2012
Author: Maciej Fijalkowski <fijall at gmail.com>
Branch:
Changeset: r51672:d246547e90d8
Date: 2012-01-23 02:04 +0200
http://bitbucket.org/pypy/pypy/changeset/d246547e90d8/
Log: (mattip) merge numpypy-reshape-bug
diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py
--- a/pypy/module/micronumpy/interp_numarray.py
+++ b/pypy/module/micronumpy/interp_numarray.py
@@ -174,15 +174,17 @@
# fits the new shape, using those steps. If there is a shape/step mismatch
# (meaning that the realignment of elements crosses from one step into another)
# return None so that the caller can raise an exception.
-def calc_new_strides(new_shape, old_shape, old_strides):
+def calc_new_strides(new_shape, old_shape, old_strides, order):
+ # Return the proper strides for new_shape, or None if the mapping crosses
+ # stepping boundaries
+
# Assumes that prod(old_shape) == prod(new_shape), len(old_shape) > 1, and
# len(new_shape) > 0
steps = []
last_step = 1
oldI = 0
new_strides = []
- if old_strides[0] < old_strides[-1]:
- #Start at old_shape[0], old_stides[0]
+ if order == 'F':
for i in range(len(old_shape)):
steps.append(old_strides[i] / last_step)
last_step *= old_shape[i]
@@ -199,12 +201,10 @@
n_old_elems_to_use *= old_shape[oldI]
if n_new_elems_used == n_old_elems_to_use:
oldI += 1
- if oldI >= len(old_shape):
- continue
- cur_step = steps[oldI]
- n_old_elems_to_use *= old_shape[oldI]
- else:
- #Start at old_shape[-1], old_strides[-1]
+ if oldI < len(old_shape):
+ cur_step = steps[oldI]
+ n_old_elems_to_use *= old_shape[oldI]
+ elif order == 'C':
for i in range(len(old_shape) - 1, -1, -1):
steps.insert(0, old_strides[i] / last_step)
last_step *= old_shape[i]
@@ -223,10 +223,10 @@
n_old_elems_to_use *= old_shape[oldI]
if n_new_elems_used == n_old_elems_to_use:
oldI -= 1
- if oldI < -len(old_shape):
- continue
- cur_step = steps[oldI]
- n_old_elems_to_use *= old_shape[oldI]
+ if oldI >= -len(old_shape):
+ cur_step = steps[oldI]
+ n_old_elems_to_use *= old_shape[oldI]
+ assert len(new_strides) == len(new_shape)
return new_strides
class BaseArray(Wrappable):
@@ -631,8 +631,8 @@
concrete = self.get_concrete()
new_shape = get_shape_from_iterable(space, concrete.size, w_shape)
# Since we got to here, prod(new_shape) == self.size
- new_strides = calc_new_strides(new_shape,
- concrete.shape, concrete.strides)
+ new_strides = calc_new_strides(new_shape, concrete.shape,
+ concrete.strides, concrete.order)
if new_strides:
# We can create a view, strides somehow match up.
ndims = len(new_shape)
@@ -1221,7 +1221,8 @@
self.backstrides = backstrides
self.shape = new_shape
return
- new_strides = calc_new_strides(new_shape, self.shape, self.strides)
+ new_strides = calc_new_strides(new_shape, self.shape, self.strides,
+ self.order)
if new_strides is None:
raise OperationError(space.w_AttributeError, space.wrap(
"incompatible shape for a non-contiguous array"))
diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py
--- a/pypy/module/micronumpy/test/test_numarray.py
+++ b/pypy/module/micronumpy/test/test_numarray.py
@@ -154,13 +154,18 @@
def test_calc_new_strides(self):
from pypy.module.micronumpy.interp_numarray import calc_new_strides
- assert calc_new_strides([2, 4], [4, 2], [4, 2]) == [8, 2]
- assert calc_new_strides([2, 4, 3], [8, 3], [1, 16]) == [1, 2, 16]
- assert calc_new_strides([2, 3, 4], [8, 3], [1, 16]) is None
- assert calc_new_strides([24], [2, 4, 3], [48, 6, 1]) is None
- assert calc_new_strides([24], [2, 4, 3], [24, 6, 2]) == [2]
- assert calc_new_strides([105, 1], [3, 5, 7], [35, 7, 1]) == [1, 1]
- assert calc_new_strides([1, 105], [3, 5, 7], [35, 7, 1]) == [105, 1]
+ assert calc_new_strides([2, 4], [4, 2], [4, 2], "C") == [8, 2]
+ assert calc_new_strides([2, 4, 3], [8, 3], [1, 16], 'F') == [1, 2, 16]
+ assert calc_new_strides([2, 3, 4], [8, 3], [1, 16], 'F') is None
+ assert calc_new_strides([24], [2, 4, 3], [48, 6, 1], 'C') is None
+ assert calc_new_strides([24], [2, 4, 3], [24, 6, 2], 'C') == [2]
+ assert calc_new_strides([105, 1], [3, 5, 7], [35, 7, 1],'C') == [1, 1]
+ assert calc_new_strides([1, 105], [3, 5, 7], [35, 7, 1],'C') == [105, 1]
+ assert calc_new_strides([1, 105], [3, 5, 7], [35, 7, 1],'F') is None
+ assert calc_new_strides([1, 1, 1, 105, 1], [15, 7], [7, 1],'C') == \
+ [105, 105, 105, 1, 1]
+ assert calc_new_strides([1, 1, 105, 1, 1], [7, 15], [1, 7],'F') == \
+ [1, 1, 1, 105, 105]
class AppTestNumArray(BaseNumpyAppTest):
@@ -385,6 +390,8 @@
a.shape = ()
#numpy allows this
a.shape = (1,)
+ a = array(range(6)).reshape(2,3).T
+ raises(AttributeError, 'a.shape = 6')
def test_reshape(self):
from _numpypy import array, zeros
More information about the pypy-commit
mailing list