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

Reply via email to