from __future__ import division, absolute_import, print_function import sys import itertools import pytest import numpy as np from numpy.core._multiarray_tests import solve_diophantine, internal_overlap from numpy.core import _umath_tests from numpy.lib.stride_tricks import as_strided from numpy.compat import long from numpy.testing import ( assert_, assert_raises, assert_equal, assert_array_equal ) if sys.version_info[0] >= 3: xrange = range ndims = 2 size = 10 shape = tuple([size] * ndims) MAY_SHARE_BOUNDS = 0 MAY_SHARE_EXACT = -1 def _indices_for_nelems(nelems): """Returns slices of length nelems, from start onwards, in direction sign.""" if nelems == 0: return [size // 2] # int index res = [] for step in (1, 2): for sign in (-1, 1): start = size // 2 - nelems * step * sign // 2 stop = start + nelems * step * sign res.append(slice(start, stop, step * sign)) return res def _indices_for_axis(): """Returns (src, dst) pairs of indices.""" res = [] for nelems in (0, 2, 3): ind = _indices_for_nelems(nelems) # no itertools.product available in Py2.4 res.extend([(a, b) for a in ind for b in ind]) # all assignments of size "nelems" return res def _indices(ndims): """Returns ((axis0_src, axis0_dst), (axis1_src, axis1_dst), ... ) index pairs.""" ind = _indices_for_axis() # no itertools.product available in Py2.4 res = [[]] for i in range(ndims): newres = [] for elem in ind: for others in res: newres.append([elem] + others) res = newres return res def _check_assignment(srcidx, dstidx): """Check assignment arr[dstidx] = arr[srcidx] works.""" arr = np.arange(np.product(shape)).reshape(shape) cpy = arr.copy() cpy[dstidx] = arr[srcidx] arr[dstidx] = arr[srcidx] assert_(np.all(arr == cpy), 'assigning arr[%s] = arr[%s]' % (dstidx, srcidx)) def test_overlapping_assignments(): # Test automatically generated assignments which overlap in memory. inds = _indices(ndims) for ind in inds: srcidx = tuple([a[0] for a in ind]) dstidx = tuple([a[1] for a in ind]) _check_assignment(srcidx, dstidx) @pytest.mark.slow def test_diophantine_fuzz(): # Fuzz test the diophantine solver rng = np.random.RandomState(1234) max_int = np.iinfo(np.intp).max for ndim in range(10): feasible_count = 0 infeasible_count = 0 min_count = 500//(ndim + 1) while min(feasible_count, infeasible_count) < min_count: # Ensure big and small integer problems A_max = 1 + rng.randint(0, 11, dtype=np.intp)**6 U_max = rng.randint(0, 11, dtype=np.intp)**6 A_max = min(max_int, A_max) U_max = min(max_int-1, U_max) A = tuple(int(rng.randint(1, A_max+1, dtype=np.intp)) for j in range(ndim)) U = tuple(int(rng.randint(0, U_max+2, dtype=np.intp)) for j in range(ndim)) b_ub = min(max_int-2, sum(a*ub for a, ub in zip(A, U))) b = rng.randint(-1, b_ub+2, dtype=np.intp) if ndim == 0 and feasible_count < min_count: b = 0 X = solve_diophantine(A, U, b) if X is None: # Check the simplified decision problem agrees X_simplified = solve_diophantine(A, U, b, simplify=1) assert_(X_simplified is None, (A, U, b, X_simplified)) # Check no solution exists (provided the problem is # small enough so that brute force checking doesn't # take too long) try: ranges = tuple(xrange(0, a*ub+1, a) for a, ub in zip(A, U)) except OverflowError: # xrange on 32-bit Python 2 may overflow continue size = 1 for r in ranges: size *= len(r) if size < 100000: assert_(not any(sum(w) == b for w in itertools.product(*ranges))) infeasible_count += 1 else: # Check the simplified decision problem agrees X_simplified = solve_diophantine(A, U, b, simplify=1) assert_(X_simplified is not None, (A, U, b, X_simplified)) # Check validity assert_(sum(a*x for a, x in zip(A, X)) == b) assert_(all(0 <= x <= ub for x, ub in zip(X, U))) feasible_count += 1 def test_diophantine_overflow(): # Smoke test integer overflow detection max_intp = np.iinfo(np.intp).max max_int64 = np.iinfo(np.int64).max if max_int64 <= max_intp: # Check that the algorithm works internally in 128-bit; # solving this problem requires large intermediate numbers A = (max_int64//2, max_int64//2 - 10) U = (max_int64//2, max_int64//2 - 10) b = 2*(max_int64//2) - 10 assert_equal(solve_diophantine(A, U, b), (1, 1)) def check_may_share_memory_exact(a, b): got = np.may_share_memory(a, b, max_work=MAY_SHARE_EXACT) assert_equal(np.may_share_memory(a, b), np.may_share_memory(a, b, max_work=MAY_SHARE_BOUNDS)) a.fill(0) b.fill(0) a.fill(1) exact = b.any() err_msg = "" if got != exact: err_msg = " " + "\n ".join([ "base_a - base_b = %r" % (a.__array_interface__['data'][0] - b.__array_interface__['data'][0],), "shape_a = %r" % (a.shape,), "shape_b = %r" % (b.shape,), "strides_a = %r" % (a.strides,), "strides_b = %r" % (b.strides,), "size_a = %r" % (a.size,), "size_b = %r" % (b.size,) ]) assert_equal(got, exact, err_msg=err_msg) def test_may_share_memory_manual(): # Manual test cases for may_share_memory # Base arrays xs0 = [ np.zeros([13, 21, 23, 22], dtype=np.int8), np.zeros([13, 21, 23*2, 22], dtype=np.int8)[:,:,::2,:] ] # Generate all negative stride combinations xs = [] for x in xs0: for ss in itertools.product(*(([slice(None), slice(None, None, -1)],)*4)): xp = x[ss] xs.append(xp) for x in xs: # The default is a simple extent check assert_(np.may_share_memory(x[:,0,:], x[:,1,:])) assert_(np.may_share_memory(x[:,0,:], x[:,1,:], max_work=None)) # Exact checks check_may_share_memory_exact(x[:,0,:], x[:,1,:]) check_may_share_memory_exact(x[:,::7], x[:,3::3]) try: xp = x.ravel() if xp.flags.owndata: continue xp = xp.view(np.int16) except ValueError: continue # 0-size arrays cannot overlap check_may_share_memory_exact(x.ravel()[6:6], xp.reshape(13, 21, 23, 11)[:,::7]) # Test itemsize is dealt with check_may_share_memory_exact(x[:,::7], xp.reshape(13, 21, 23, 11)) check_may_share_memory_exact(x[:,::7], xp.reshape(13, 21, 23, 11)[:,3::3]) check_may_share_memory_exact(x.ravel()[6:7], xp.reshape(13, 21, 23, 11)[:,::7]) # Check unit size x = np.zeros([1], dtype=np.int8) check_may_share_memory_exact(x, x) check_may_share_memory_exact(x, x.copy()) def iter_random_view_pairs(x, same_steps=True, equal_size=False): rng = np.random.RandomState(1234) if equal_size and same_steps: raise ValueError() def random_slice(n, step): start = rng.randint(0, n+1, dtype=np.intp) stop = rng.randint(start, n+1, dtype=np.intp) if rng.randint(0, 2, dtype=np.intp) == 0: stop, start = start, stop step *= -1 return slice(start, stop, step) def random_slice_fixed_size(n, step, size): start = rng.randint(0, n+1 - size*step) stop = start + (size-1)*step + 1 if rng.randint(0, 2) == 0: stop, start = start-1, stop-1 if stop < 0: stop = None step *= -1 return slice(start, stop, step) # First a few regular views yield x, x for j in range(1, 7, 3): yield x[j:], x[:-j] yield x[...,j:], x[...,:-j] # An array with zero stride internal overlap strides = list(x.strides) strides[0] = 0 xp = as_strided(x, shape=x.shape, strides=strides) yield x, xp yield xp, xp # An array with non-zero stride internal overlap strides = list(x.strides) if strides[0] > 1: strides[0] = 1 xp = as_strided(x, shape=x.shape, strides=strides) yield x, xp yield xp, xp # Then discontiguous views while True: steps = tuple(rng.randint(1, 11, dtype=np.intp) if rng.randint(0, 5, dtype=np.intp) == 0 else 1 for j in range(x.ndim)) s1 = tuple(random_slice(p, s) for p, s in zip(x.shape, steps)) t1 = np.arange(x.ndim) rng.shuffle(t1) if equal_size: t2 = t1 else: t2 = np.arange(x.ndim) rng.shuffle(t2) a = x[s1] if equal_size: if a.size == 0: continue steps2 = tuple(rng.randint(1, max(2, p//(1+pa))) if rng.randint(0, 5) == 0 else 1 for p, s, pa in zip(x.shape, s1, a.shape)) s2 = tuple(random_slice_fixed_size(p, s, pa) for p, s, pa in zip(x.shape, steps2, a.shape)) elif same_steps: steps2 = steps else: steps2 = tuple(rng.randint(1, 11, dtype=np.intp) if rng.randint(0, 5, dtype=np.intp) == 0 else 1 for j in range(x.ndim)) if not equal_size: s2 = tuple(random_slice(p, s) for p, s in zip(x.shape, steps2)) a = a.transpose(t1) b = x[s2].transpose(t2) yield a, b def check_may_share_memory_easy_fuzz(get_max_work, same_steps, min_count): # Check that overlap problems with common strides are solved with # little work. x = np.zeros([17,34,71,97], dtype=np.int16) feasible = 0 infeasible = 0 pair_iter = iter_random_view_pairs(x, same_steps) while min(feasible, infeasible) < min_count: a, b = next(pair_iter) bounds_overlap = np.may_share_memory(a, b) may_share_answer = np.may_share_memory(a, b) easy_answer = np.may_share_memory(a, b, max_work=get_max_work(a, b)) exact_answer = np.may_share_memory(a, b, max_work=MAY_SHARE_EXACT) if easy_answer != exact_answer: # assert_equal is slow... assert_equal(easy_answer, exact_answer) if may_share_answer != bounds_overlap: assert_equal(may_share_answer, bounds_overlap) if bounds_overlap: if exact_answer: feasible += 1 else: infeasible += 1 @pytest.mark.slow def test_may_share_memory_easy_fuzz(): # Check that overlap problems with common strides are always # solved with little work. check_may_share_memory_easy_fuzz(get_max_work=lambda a, b: 1, same_steps=True, min_count=2000) @pytest.mark.slow def test_may_share_memory_harder_fuzz(): # Overlap problems with not necessarily common strides take more # work. # # The work bound below can't be reduced much. Harder problems can # also exist but not be detected here, as the set of problems # comes from RNG. check_may_share_memory_easy_fuzz(get_max_work=lambda a, b: max(a.size, b.size)//2, same_steps=False, min_count=2000) def test_shares_memory_api(): x = np.zeros([4, 5, 6], dtype=np.int8) assert_equal(np.shares_memory(x, x), True) assert_equal(np.shares_memory(x, x.copy()), False) a = x[:,::2,::3] b = x[:,::3,::2] assert_equal(np.shares_memory(a, b), True) assert_equal(np.shares_memory(a, b, max_work=None), True) assert_raises(np.TooHardError, np.shares_memory, a, b, max_work=1) assert_raises(np.TooHardError, np.shares_memory, a, b, max_work=long(1)) def test_may_share_memory_bad_max_work(): x = np.zeros([1]) assert_raises(OverflowError, np.may_share_memory, x, x, max_work=10**100) assert_raises(OverflowError, np.shares_memory, x, x, max_work=10**100) def test_internal_overlap_diophantine(): def check(A, U, exists=None): X = solve_diophantine(A, U, 0, require_ub_nontrivial=1) if exists is None: exists = (X is not None) if X is not None: assert_(sum(a*x for a, x in zip(A, X)) == sum(a*u//2 for a, u in zip(A, U))) assert_(all(0 <= x <= u for x, u in zip(X, U))) assert_(any(x != u//2 for x, u in zip(X, U))) if exists: assert_(X is not None, repr(X)) else: assert_(X is None, repr(X)) # Smoke tests check((3, 2), (2*2, 3*2), exists=True) check((3*2, 2), (15*2, (3-1)*2), exists=False) def test_internal_overlap_slices(): # Slicing an array never generates internal overlap x = np.zeros([17,34,71,97], dtype=np.int16) rng = np.random.RandomState(1234) def random_slice(n, step): start = rng.randint(0, n+1, dtype=np.intp) stop = rng.randint(start, n+1, dtype=np.intp) if rng.randint(0, 2, dtype=np.intp) == 0: stop, start = start, stop step *= -1 return slice(start, stop, step) cases = 0 min_count = 5000 while cases < min_count: steps = tuple(rng.randint(1, 11, dtype=np.intp) if rng.randint(0, 5, dtype=np.intp) == 0 else 1 for j in range(x.ndim)) t1 = np.arange(x.ndim) rng.shuffle(t1) s1 = tuple(random_slice(p, s) for p, s in zip(x.shape, steps)) a = x[s1].transpose(t1) assert_(not internal_overlap(a)) cases += 1 def check_internal_overlap(a, manual_expected=None): got = internal_overlap(a) # Brute-force check m = set() ranges = tuple(xrange(n) for n in a.shape) for v in itertools.product(*ranges): offset = sum(s*w for s, w in zip(a.strides, v)) if offset in m: expected = True break else: m.add(offset) else: expected = False # Compare if got != expected: assert_equal(got, expected, err_msg=repr((a.strides, a.shape))) if manual_expected is not None and expected != manual_expected: assert_equal(expected, manual_expected) return got def test_internal_overlap_manual(): # Stride tricks can construct arrays with internal overlap # We don't care about memory bounds, the array is not # read/write accessed x = np.arange(1).astype(np.int8) # Check low-dimensional special cases check_internal_overlap(x, False) # 1-dim check_internal_overlap(x.reshape([]), False) # 0-dim a = as_strided(x, strides=(3, 4), shape=(4, 4)) check_internal_overlap(a, False) a = as_strided(x, strides=(3, 4), shape=(5, 4)) check_internal_overlap(a, True) a = as_strided(x, strides=(0,), shape=(0,)) check_internal_overlap(a, False) a = as_strided(x, strides=(0,), shape=(1,)) check_internal_overlap(a, False) a = as_strided(x, strides=(0,), shape=(2,)) check_internal_overlap(a, True) a = as_strided(x, strides=(0, -9993), shape=(87, 22)) check_internal_overlap(a, True) a = as_strided(x, strides=(0, -9993), shape=(1, 22)) check_internal_overlap(a, False) a = as_strided(x, strides=(0, -9993), shape=(0, 22)) check_internal_overlap(a, False) def test_internal_overlap_fuzz(): # Fuzz check; the brute-force check is fairly slow x = np.arange(1).astype(np.int8) overlap = 0 no_overlap = 0 min_count = 100 rng = np.random.RandomState(1234) while min(overlap, no_overlap) < min_count: ndim = rng.randint(1, 4, dtype=np.intp) strides = tuple(rng.randint(-1000, 1000, dtype=np.intp) for j in range(ndim)) shape = tuple(rng.randint(1, 30, dtype=np.intp) for j in range(ndim)) a = as_strided(x, strides=strides, shape=shape) result = check_internal_overlap(a) if result: overlap += 1 else: no_overlap += 1 def test_non_ndarray_inputs(): # Regression check for gh-5604 class MyArray(object): def __init__(self, data): self.data = data @property def __array_interface__(self): return self.data.__array_interface__ class MyArray2(object): def __init__(self, data): self.data = data def __array__(self): return self.data for cls in [MyArray, MyArray2]: x = np.arange(5) assert_(np.may_share_memory(cls(x[::2]), x[1::2])) assert_(not np.shares_memory(cls(x[::2]), x[1::2])) assert_(np.shares_memory(cls(x[1::3]), x[::2])) assert_(np.may_share_memory(cls(x[1::3]), x[::2])) def view_element_first_byte(x): """Construct an array viewing the first byte of each element of `x`""" from numpy.lib.stride_tricks import DummyArray interface = dict(x.__array_interface__) interface['typestr'] = '|b1' interface['descr'] = [('', '|b1')] return np.asarray(DummyArray(interface, x)) def assert_copy_equivalent(operation, args, out, **kwargs): """ Check that operation(*args, out=out) produces results equivalent to out[...] = operation(*args, out=out.copy()) """ kwargs['out'] = out kwargs2 = dict(kwargs) kwargs2['out'] = out.copy() out_orig = out.copy() out[...] = operation(*args, **kwargs2) expected = out.copy() out[...] = out_orig got = operation(*args, **kwargs).copy() if (got != expected).any(): assert_equal(got, expected) class TestUFunc(object): """ Test ufunc call memory overlap handling """ def check_unary_fuzz(self, operation, get_out_axis_size, dtype=np.int16, count=5000): shapes = [7, 13, 8, 21, 29, 32] rng = np.random.RandomState(1234) for ndim in range(1, 6): x = rng.randint(0, 2**16, size=shapes[:ndim]).astype(dtype) it = iter_random_view_pairs(x, same_steps=False, equal_size=True) min_count = count // (ndim + 1)**2 overlapping = 0 while overlapping < min_count: a, b = next(it) a_orig = a.copy() b_orig = b.copy() if get_out_axis_size is None: assert_copy_equivalent(operation, [a], out=b) if np.shares_memory(a, b): overlapping += 1 else: for axis in itertools.chain(range(ndim), [None]): a[...] = a_orig b[...] = b_orig # Determine size for reduction axis (None if scalar) outsize, scalarize = get_out_axis_size(a, b, axis) if outsize == 'skip': continue # Slice b to get an output array of the correct size sl = [slice(None)] * ndim if axis is None: if outsize is None: sl = [slice(0, 1)] + [0]*(ndim - 1) else: sl = [slice(0, outsize)] + [0]*(ndim - 1) else: if outsize is None: k = b.shape[axis]//2 if ndim == 1: sl[axis] = slice(k, k + 1) else: sl[axis] = k else: assert b.shape[axis] >= outsize sl[axis] = slice(0, outsize) b_out = b[tuple(sl)] if scalarize: b_out = b_out.reshape([]) if np.shares_memory(a, b_out): overlapping += 1 # Check result assert_copy_equivalent(operation, [a], out=b_out, axis=axis) @pytest.mark.slow def test_unary_ufunc_call_fuzz(self): self.check_unary_fuzz(np.invert, None, np.int16) def test_binary_ufunc_accumulate_fuzz(self): def get_out_axis_size(a, b, axis): if axis is None: if a.ndim == 1: return a.size, False else: return 'skip', False # accumulate doesn't support this else: return a.shape[axis], False self.check_unary_fuzz(np.add.accumulate, get_out_axis_size, dtype=np.int16, count=500) def test_binary_ufunc_reduce_fuzz(self): def get_out_axis_size(a, b, axis): return None, (axis is None or a.ndim == 1) self.check_unary_fuzz(np.add.reduce, get_out_axis_size, dtype=np.int16, count=500) def test_binary_ufunc_reduceat_fuzz(self): def get_out_axis_size(a, b, axis): if axis is None: if a.ndim == 1: return a.size, False else: return 'skip', False # reduceat doesn't support this else: return a.shape[axis], False def do_reduceat(a, out, axis): if axis is None: size = len(a) step = size//len(out) else: size = a.shape[axis] step = a.shape[axis] // out.shape[axis] idx = np.arange(0, size, step) return np.add.reduceat(a, idx, out=out, axis=axis) self.check_unary_fuzz(do_reduceat, get_out_axis_size, dtype=np.int16, count=500) def test_binary_ufunc_reduceat_manual(self): def check(ufunc, a, ind, out): c1 = ufunc.reduceat(a.copy(), ind.copy(), out=out.copy()) c2 = ufunc.reduceat(a, ind, out=out) assert_array_equal(c1, c2) # Exactly same input/output arrays a = np.arange(10000, dtype=np.int16) check(np.add, a, a[::-1].copy(), a) # Overlap with index a = np.arange(10000, dtype=np.int16) check(np.add, a, a[::-1], a) def test_unary_gufunc_fuzz(self): shapes = [7, 13, 8, 21, 29, 32] gufunc = _umath_tests.euclidean_pdist rng = np.random.RandomState(1234) for ndim in range(2, 6): x = rng.rand(*shapes[:ndim]) it = iter_random_view_pairs(x, same_steps=False, equal_size=True) min_count = 500 // (ndim + 1)**2 overlapping = 0 while overlapping < min_count: a, b = next(it) if min(a.shape[-2:]) < 2 or min(b.shape[-2:]) < 2 or a.shape[-1] < 2: continue # Ensure the shapes are so that euclidean_pdist is happy if b.shape[-1] > b.shape[-2]: b = b[...,0,:] else: b = b[...,:,0] n = a.shape[-2] p = n * (n - 1) // 2 if p <= b.shape[-1] and p > 0: b = b[...,:p] else: n = max(2, int(np.sqrt(b.shape[-1]))//2) p = n * (n - 1) // 2 a = a[...,:n,:] b = b[...,:p] # Call if np.shares_memory(a, b): overlapping += 1 with np.errstate(over='ignore', invalid='ignore'): assert_copy_equivalent(gufunc, [a], out=b) def test_ufunc_at_manual(self): def check(ufunc, a, ind, b=None): a0 = a.copy() if b is None: ufunc.at(a0, ind.copy()) c1 = a0.copy() ufunc.at(a, ind) c2 = a.copy() else: ufunc.at(a0, ind.copy(), b.copy()) c1 = a0.copy() ufunc.at(a, ind, b) c2 = a.copy() assert_array_equal(c1, c2) # Overlap with index a = np.arange(10000, dtype=np.int16) check(np.invert, a[::-1], a) # Overlap with second data array a = np.arange(100, dtype=np.int16) ind = np.arange(0, 100, 2, dtype=np.int16) check(np.add, a, ind, a[25:75]) def test_unary_ufunc_1d_manual(self): # Exercise branches in PyArray_EQUIVALENTLY_ITERABLE def check(a, b): a_orig = a.copy() b_orig = b.copy() b0 = b.copy() c1 = ufunc(a, out=b0) c2 = ufunc(a, out=b) assert_array_equal(c1, c2) # Trigger "fancy ufunc loop" code path mask = view_element_first_byte(b).view(np.bool_) a[...] = a_orig b[...] = b_orig c1 = ufunc(a, out=b.copy(), where=mask.copy()).copy() a[...] = a_orig b[...] = b_orig c2 = ufunc(a, out=b, where=mask.copy()).copy() # Also, mask overlapping with output a[...] = a_orig b[...] = b_orig c3 = ufunc(a, out=b, where=mask).copy() assert_array_equal(c1, c2) assert_array_equal(c1, c3) dtypes = [np.int8, np.int16, np.int32, np.int64, np.float32, np.float64, np.complex64, np.complex128] dtypes = [np.dtype(x) for x in dtypes] for dtype in dtypes: if np.issubdtype(dtype, np.integer): ufunc = np.invert else: ufunc = np.reciprocal n = 1000 k = 10 indices = [ np.index_exp[:n], np.index_exp[k:k+n], np.index_exp[n-1::-1], np.index_exp[k+n-1:k-1:-1], np.index_exp[:2*n:2], np.index_exp[k:k+2*n:2], np.index_exp[2*n-1::-2], np.index_exp[k+2*n-1:k-1:-2], ] for xi, yi in itertools.product(indices, indices): v = np.arange(1, 1 + n*2 + k, dtype=dtype) x = v[xi] y = v[yi] with np.errstate(all='ignore'): check(x, y) # Scalar cases check(x[:1], y) check(x[-1:], y) check(x[:1].reshape([]), y) check(x[-1:].reshape([]), y) def test_unary_ufunc_where_same(self): # Check behavior at wheremask overlap ufunc = np.invert def check(a, out, mask): c1 = ufunc(a, out=out.copy(), where=mask.copy()) c2 = ufunc(a, out=out, where=mask) assert_array_equal(c1, c2) # Check behavior with same input and output arrays x = np.arange(100).astype(np.bool_) check(x, x, x) check(x, x.copy(), x) check(x, x, x.copy()) @pytest.mark.slow def test_binary_ufunc_1d_manual(self): ufunc = np.add def check(a, b, c): c0 = c.copy() c1 = ufunc(a, b, out=c0) c2 = ufunc(a, b, out=c) assert_array_equal(c1, c2) for dtype in [np.int8, np.int16, np.int32, np.int64, np.float32, np.float64, np.complex64, np.complex128]: # Check different data dependency orders n = 1000 k = 10 indices = [] for p in [1, 2]: indices.extend([ np.index_exp[:p*n:p], np.index_exp[k:k+p*n:p], np.index_exp[p*n-1::-p], np.index_exp[k+p*n-1:k-1:-p], ]) for x, y, z in itertools.product(indices, indices, indices): v = np.arange(6*n).astype(dtype) x = v[x] y = v[y] z = v[z] check(x, y, z) # Scalar cases check(x[:1], y, z) check(x[-1:], y, z) check(x[:1].reshape([]), y, z) check(x[-1:].reshape([]), y, z) check(x, y[:1], z) check(x, y[-1:], z) check(x, y[:1].reshape([]), z) check(x, y[-1:].reshape([]), z) def test_inplace_op_simple_manual(self): rng = np.random.RandomState(1234) x = rng.rand(200, 200) # bigger than bufsize x += x.T assert_array_equal(x - x.T, 0)