Author: mattip <[email protected]>
Branch: numpy-fixes
Changeset: r76925:cfb31de4972f
Date: 2015-04-24 16:27 +0300
http://bitbucket.org/pypy/pypy/changeset/cfb31de4972f/
Log: fix d198d926afb8
diff --git a/pypy/module/micronumpy/concrete.py
b/pypy/module/micronumpy/concrete.py
--- a/pypy/module/micronumpy/concrete.py
+++ b/pypy/module/micronumpy/concrete.py
@@ -11,7 +11,7 @@
from pypy.module.micronumpy.iterators import ArrayIter
from pypy.module.micronumpy.strides import (Chunk, Chunks, NewAxisChunk,
RecordChunk, calc_strides, calc_new_strides, shape_agreement,
- calculate_broadcast_strides, calc_backstrides)
+ calculate_broadcast_strides, calc_backstrides, calc_start)
from rpython.rlib.objectmodel import keepalive_until_here
from rpython.rtyper.annlowlevel import cast_gcref_to_instance
from pypy.interpreter.baseobjspace import W_Root
@@ -328,8 +328,11 @@
return ArrayBuffer(self, readonly)
def astype(self, space, dtype):
- strides, backstrides = calc_strides(self.get_shape(), dtype,
- self.order)
+ # we want to create a new array, but must respect the strides
+ # in self. So find a factor of the itemtype.elsize, and use this
+ factor = float(dtype.elsize) / self.dtype.elsize
+ strides = [int(factor*s) for s in self.get_strides()]
+ backstrides = [int(factor*s) for s in self.get_backstrides()]
impl = ConcreteArray(self.get_shape(), dtype, self.order,
strides, backstrides)
loop.setslice(space, impl.get_shape(), impl, self)
@@ -426,8 +429,9 @@
gcstruct = _create_objectstore(storage, length, dtype.elsize)
else:
storage = dtype.itemtype.malloc(length * dtype.elsize,
zero=zero)
+ start = calc_start(shape, strides)
ConcreteArrayNotOwning.__init__(self, shape, dtype, order, strides,
backstrides,
- storage)
+ storage, start=start)
self.gcstruct = gcstruct
def __del__(self):
diff --git a/pypy/module/micronumpy/strides.py
b/pypy/module/micronumpy/strides.py
--- a/pypy/module/micronumpy/strides.py
+++ b/pypy/module/micronumpy/strides.py
@@ -429,6 +429,17 @@
n_old_elems_to_use *= old_shape[oldI]
return new_strides[:]
+def calc_start(shape, strides):
+ ''' Strides can be negative for non-contiguous data.
+ Calculate the appropriate positive starting position so
+ the indexing still works properly
+ '''
+ start = 0
+ for i in range(len(shape)):
+ if strides[i] < 0:
+ start -= strides[i] * (shape[i] - 1)
+ return start
+
@jit.unroll_safe
def is_c_contiguous(arr):
shape = arr.get_shape()
diff --git a/pypy/module/micronumpy/test/test_ndarray.py
b/pypy/module/micronumpy/test/test_ndarray.py
--- a/pypy/module/micronumpy/test/test_ndarray.py
+++ b/pypy/module/micronumpy/test/test_ndarray.py
@@ -2169,6 +2169,7 @@
def test_astype(self):
from numpy import array, arange
+ import gc
b = array(1).astype(float)
assert b == 1
assert b.dtype == float
@@ -2182,8 +2183,15 @@
assert (b == [False, True, True]).all()
assert b.dtype == 'bool'
+ a = arange(11)[::-1]
+ b = a.astype('int32')
+ assert (b == a).all()
+ del b
+ gc.collect()
+
a = arange(6, dtype='f4').reshape(2,3)
- b = a.astype('i4')
+ b = a.T.astype('i4')
+ assert (a.T.strides == b.strides)
a = array('x').astype('S3').dtype
assert a.itemsize == 3
diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py
--- a/pypy/module/micronumpy/types.py
+++ b/pypy/module/micronumpy/types.py
@@ -28,6 +28,20 @@
log2e = 1. / log2
log10 = math.log(10)
+'''
+if not we_are_translated():
+ _raw_storage_setitem_unaligned = raw_storage_setitem_unaligned
+ _raw_storage_getitem_unaligned = raw_storage_getitem_unaligned
+ def raw_storage_setitem_unaligned(storage, offset, value):
+ assert offset >=0
+ assert offset < storage._obj.getlength()
+ return _raw_storage_setitem_unaligned(storage, offset, value)
+
+ def raw_storage_getitem_unaligned(T, storage, offset):
+ assert offset >=0
+ assert offset < storage._obj.getlength()
+ return _raw_storage_getitem_unaligned(T, storage, offset)
+'''
def simple_unary_op(func):
specialize.argtype(1)(func)
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit