[pypy-commit] pypy numpy-fixes: make view actually a view rather than a copy if dtype is same-length
mattip
noreply at buildbot.pypy.org
Wed Apr 29 21:28:29 CEST 2015
Author: mattip <matti.picus at gmail.com>
Branch: numpy-fixes
Changeset: r76949:8e4a51fc2b92
Date: 2015-04-28 22:53 +0300
http://bitbucket.org/pypy/pypy/changeset/8e4a51fc2b92/
Log: make view actually a view rather than a copy if dtype is same-length
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
@@ -90,9 +90,13 @@
new_shape, self, orig_array)
return None
- def get_view(self, space, orig_array, dtype, new_shape):
- strides, backstrides = calc_strides(new_shape, dtype,
+ def get_view(self, space, orig_array, dtype, new_shape, reuse_strides=False):
+ if not reuse_strides:
+ strides, backstrides = calc_strides(new_shape, dtype,
self.order)
+ else:
+ strides = self.get_strides()
+ backstrides = self.get_backstrides()
return SliceArray(self.start, strides, backstrides, new_shape,
self, orig_array, dtype=dtype)
@@ -328,11 +332,7 @@
return ArrayBuffer(self, readonly)
def astype(self, space, dtype):
- # 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()]
+ strides, backstrides = calc_strides(self.get_shape(), dtype, self.order)
impl = ConcreteArray(self.get_shape(), dtype, self.order,
strides, backstrides)
loop.setslice(space, impl.get_shape(), impl, self)
diff --git a/pypy/module/micronumpy/ndarray.py b/pypy/module/micronumpy/ndarray.py
--- a/pypy/module/micronumpy/ndarray.py
+++ b/pypy/module/micronumpy/ndarray.py
@@ -850,7 +850,15 @@
raise OperationError(space.w_ValueError, space.wrap(
"new type not compatible with array."))
# Strides, shape does not change
- v = impl.astype(space, dtype)
+ if dtype.is_object() != impl.dtype.is_object():
+ raise oefmt(space.w_ValueError, 'expect trouble in ndarray.view,'
+ ' target dtype %r but self.dtype %r',dtype, impl.dtype)
+
+ base = impl.base()
+ if base is None:
+ base = self
+ v = impl.get_view(space, base, dtype, self.get_shape(),
+ reuse_strides=True)
return wrap_impl(space, w_type, self, v)
strides = impl.get_strides()
if dims == 1 or strides[0] <strides[-1]:
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
@@ -1817,6 +1817,8 @@
assert exc.value[0] == 'new type not compatible with array.'
s[...] = 2
v = s.view(x.__class__)
+ assert v.strides == s.strides
+ assert v.base is s.base
assert (v == 2).all()
def test_tolist_scalar(self):
@@ -2169,7 +2171,6 @@
def test_astype(self):
from numpy import array, arange
- import gc
b = array(1).astype(float)
assert b == 1
assert b.dtype == float
@@ -2186,8 +2187,6 @@
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.T.astype('i4')
diff --git a/pypy/module/micronumpy/test/test_subtype.py b/pypy/module/micronumpy/test/test_subtype.py
--- a/pypy/module/micronumpy/test/test_subtype.py
+++ b/pypy/module/micronumpy/test/test_subtype.py
@@ -72,7 +72,7 @@
def test_subtype_view(self):
from numpy import ndarray, array
- class matrix(ndarray):
+ class matrix(ndarray, object):
def __new__(subtype, data, dtype=None, copy=True):
if isinstance(data, matrix):
return data
@@ -86,6 +86,11 @@
b = a.view(s)
assert b == a
assert type(b) is type(a)
+ a = matrix(array(range(5)))
+ for s in [matrix, ndarray]:
+ b = ndarray.view(a, s)
+ assert (b == a).all()
+ assert type(b) is s
def test_subtype_like_matrix(self):
import numpy as np
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
@@ -34,15 +34,20 @@
_raw_storage_getitem_unaligned = raw_storage_getitem_unaligned
def raw_storage_setitem_unaligned(storage, offset, value):
assert offset >=0
- assert offset < storage._obj.getlength()
+ try:
+ assert offset < storage._obj.getlength()
+ except AttributeError:
+ pass
return _raw_storage_setitem_unaligned(storage, offset, value)
def raw_storage_getitem_unaligned(T, storage, offset):
assert offset >=0
- assert offset < storage._obj.getlength()
+ try:
+ assert offset < storage._obj.getlength()
+ except AttributeError:
+ pass
return _raw_storage_getitem_unaligned(T, storage, offset)
'''
-
def simple_unary_op(func):
specialize.argtype(1)(func)
@functools.wraps(func)
More information about the pypy-commit
mailing list