summaryrefslogtreecommitdiff
path: root/numpy/core
diff options
context:
space:
mode:
Diffstat (limited to 'numpy/core')
-rw-r--r--numpy/core/tests/test_multiarray.py155
1 files changed, 82 insertions, 73 deletions
diff --git a/numpy/core/tests/test_multiarray.py b/numpy/core/tests/test_multiarray.py
index 44dd17496..98981c8b6 100644
--- a/numpy/core/tests/test_multiarray.py
+++ b/numpy/core/tests/test_multiarray.py
@@ -2795,79 +2795,6 @@ class TestBinop(object):
assert_equal(a, 5)
assert_equal(b, 3)
- def test_extension_incref_elide(self):
- # test extension (e.g. cython) calling PyNumber_* slots without
- # increasing the reference counts
- #
- # def incref_elide(a):
- # d = input.copy() # refcount 1
- # return d, d + d # PyNumber_Add without increasing refcount
- from numpy.core.multiarray_tests import incref_elide
- d = np.ones(100000)
- orig, res = incref_elide(d)
- d + d
- # the return original should not be changed to an inplace operation
- assert_array_equal(orig, d)
- assert_array_equal(res, d + d)
-
- def test_extension_incref_elide_stack(self):
- # scanning if the refcount == 1 object is on the python stack to check
- # that we are called directly from python is flawed as object may still
- # be above the stack pointer and we have no access to the top of it
- #
- # def incref_elide_l(d):
- # return l[4] + l[4] # PyNumber_Add without increasing refcount
- from numpy.core.multiarray_tests import incref_elide_l
- # padding with 1 makes sure the object on the stack is not overwriten
- l = [1, 1, 1, 1, np.ones(100000)]
- res = incref_elide_l(l)
- # the return original should not be changed to an inplace operation
- assert_array_equal(l[4], np.ones(100000))
- assert_array_equal(res, l[4] + l[4])
-
- def test_temporary_with_cast(self):
- # check that we don't elide into a temporary which would need casting
- d = np.ones(200000, dtype=np.int64)
- assert_equal(((d + d) + 2**222).dtype, np.dtype('O'))
-
- r = ((d + d) / 2)
- assert_equal(r.dtype, np.dtype('f8'))
-
- r = np.true_divide((d + d), 2)
- assert_equal(r.dtype, np.dtype('f8'))
-
- r = ((d + d) / 2.)
- assert_equal(r.dtype, np.dtype('f8'))
-
- r = ((d + d) // 2)
- assert_equal(r.dtype, np.dtype(np.int64))
-
- # commutative elision into the astype result
- f = np.ones(100000, dtype=np.float32)
- assert_equal(((f + f) + f.astype(np.float64)).dtype, np.dtype('f8'))
-
- # no elision into f + f
- d = f.astype(np.float64)
- assert_equal(((f + f) + d).dtype, np.dtype('f8'))
-
- c = np.ones(100000, dtype=np.complex)
- assert_equal(abs(c * 2.0).dtype, np.dtype('f8'))
-
- def test_elide_broadcast(self):
- # test no elision on broadcast to higher dimension
- # only triggers elision code path in debug mode as triggering it in
- # normal mode needs 256kb large matching dimension, so a lot of memory
- d = np.ones((2000, 1), dtype=int)
- b = np.ones((2000), dtype=np.bool)
- r = (1 - d) + b
- assert_equal(r, 1)
- assert_equal(r.shape, (2000, 2000))
-
- def test_elide_scalar(self):
- # check inplace op does not create ndarray from scalars
- a = np.bool_()
- assert_(type(~(a & a)) is np.bool_)
-
# ndarray.__rop__ always calls ufunc
# ndarray.__iop__ always calls ufunc
# ndarray.__op__, __rop__:
@@ -3143,6 +3070,88 @@ class TestBinop(object):
assert_(isinstance(A, OutClass))
+class TestTemporaryElide(TestCase):
+ # elision is only triggered on relatively large arrays
+
+ def test_extension_incref_elide(self):
+ # test extension (e.g. cython) calling PyNumber_* slots without
+ # increasing the reference counts
+ #
+ # def incref_elide(a):
+ # d = input.copy() # refcount 1
+ # return d, d + d # PyNumber_Add without increasing refcount
+ from numpy.core.multiarray_tests import incref_elide
+ d = np.ones(100000)
+ orig, res = incref_elide(d)
+ d + d
+ # the return original should not be changed to an inplace operation
+ assert_array_equal(orig, d)
+ assert_array_equal(res, d + d)
+
+ def test_extension_incref_elide_stack(self):
+ # scanning if the refcount == 1 object is on the python stack to check
+ # that we are called directly from python is flawed as object may still
+ # be above the stack pointer and we have no access to the top of it
+ #
+ # def incref_elide_l(d):
+ # return l[4] + l[4] # PyNumber_Add without increasing refcount
+ from numpy.core.multiarray_tests import incref_elide_l
+ # padding with 1 makes sure the object on the stack is not overwriten
+ l = [1, 1, 1, 1, np.ones(100000)]
+ res = incref_elide_l(l)
+ # the return original should not be changed to an inplace operation
+ assert_array_equal(l[4], np.ones(100000))
+ assert_array_equal(res, l[4] + l[4])
+
+ def test_temporary_with_cast(self):
+ # check that we don't elide into a temporary which would need casting
+ d = np.ones(200000, dtype=np.int64)
+ assert_equal(((d + d) + 2**222).dtype, np.dtype('O'))
+
+ r = ((d + d) / 2)
+ assert_equal(r.dtype, np.dtype('f8'))
+
+ r = np.true_divide((d + d), 2)
+ assert_equal(r.dtype, np.dtype('f8'))
+
+ r = ((d + d) / 2.)
+ assert_equal(r.dtype, np.dtype('f8'))
+
+ r = ((d + d) // 2)
+ assert_equal(r.dtype, np.dtype(np.int64))
+
+ # commutative elision into the astype result
+ f = np.ones(100000, dtype=np.float32)
+ assert_equal(((f + f) + f.astype(np.float64)).dtype, np.dtype('f8'))
+
+ # no elision into lower type
+ d = f.astype(np.float64)
+ assert_equal(((f + f) + d).dtype, d.dtype)
+ l = np.ones(100000, dtype=np.longdouble)
+ assert_equal(((d + d) + l).dtype, l.dtype)
+
+ # test unary abs with different output dtype
+ for dt in (np.complex64, np.complex128, np.clongdouble):
+ c = np.ones(100000, dtype=dt)
+ r = abs(c * 2.0)
+ assert_equal(r.dtype, np.dtype('f%d' % (c.itemsize // 2)))
+
+ def test_elide_broadcast(self):
+ # test no elision on broadcast to higher dimension
+ # only triggers elision code path in debug mode as triggering it in
+ # normal mode needs 256kb large matching dimension, so a lot of memory
+ d = np.ones((2000, 1), dtype=int)
+ b = np.ones((2000), dtype=np.bool)
+ r = (1 - d) + b
+ assert_equal(r, 1)
+ assert_equal(r.shape, (2000, 2000))
+
+ def test_elide_scalar(self):
+ # check inplace op does not create ndarray from scalars
+ a = np.bool_()
+ assert_(type(~(a & a)) is np.bool_)
+
+
class TestCAPI(TestCase):
def test_IsPythonScalar(self):
from numpy.core.multiarray_tests import IsPythonScalar