import functools import math import sys import unittest import numpy import pytest import cupy from cupy import testing def skip_int_equality_before_numpy_1_20(names=('dtype',)): """Require numpy/numpy#16841 or skip the equality check.""" def decorator(wrapped): if numpy.lib.NumpyVersion(numpy.__version__) >= '1.20.0': return wrapped @functools.wraps(wrapped) def wrapper(self, *args, **kwargs): xp = kwargs['xp'] dtypes = [kwargs[name] for name in names] ret = wrapped(self, *args, **kwargs) if any(numpy.issubdtype(dtype, numpy.integer) for dtype in dtypes): ret = xp.zeros_like(ret) return ret return wrapper return decorator class TestRanges(unittest.TestCase): @testing.for_all_dtypes(no_bool=True) @testing.numpy_cupy_array_equal() def test_arange(self, xp, dtype): return xp.arange(10, dtype=dtype) @testing.for_all_dtypes(no_bool=True) @testing.numpy_cupy_array_equal() def test_arange2(self, xp, dtype): return xp.arange(5, 10, dtype=dtype) @testing.for_all_dtypes(no_bool=True) @testing.numpy_cupy_array_equal() def test_arange3(self, xp, dtype): return xp.arange(1, 11, 2, dtype=dtype) @testing.for_all_dtypes(no_bool=True) @testing.numpy_cupy_array_equal() def test_arange4(self, xp, dtype): return xp.arange(20, 2, -3).astype(dtype) @testing.for_all_dtypes(no_bool=True) @testing.numpy_cupy_array_equal() def test_arange5(self, xp, dtype): return xp.arange(0, 100, None, dtype=dtype) @testing.for_all_dtypes() @testing.numpy_cupy_array_equal() def test_arange6(self, xp, dtype): return xp.arange(0, 2, dtype=dtype) @testing.for_all_dtypes() @testing.numpy_cupy_array_equal() def test_arange7(self, xp, dtype): return xp.arange(10, 11, dtype=dtype) @testing.for_all_dtypes() @testing.numpy_cupy_array_equal() def test_arange8(self, xp, dtype): return xp.arange(10, 8, -1).astype(dtype) @testing.with_requires('numpy>=1.24') def test_arange9(self): for xp in (numpy, cupy): with pytest.raises(TypeError): xp.arange(10, dtype=xp.bool_) @testing.numpy_cupy_array_equal() def test_arange_no_dtype_int(self, xp): return xp.arange(1, 11, 2) @testing.numpy_cupy_array_equal() def test_arange_no_dtype_float(self, xp): return xp.arange(1.0, 11.0, 2.0) @testing.numpy_cupy_array_equal() def test_arange_negative_size(self, xp): return xp.arange(3, 1) @testing.for_all_dtypes(no_bool=True) @testing.numpy_cupy_array_equal() def test_linspace(self, xp, dtype): return xp.linspace(0, 10, 5, dtype=dtype) @testing.for_all_dtypes(no_bool=True) @testing.numpy_cupy_array_equal() def test_linspace2(self, xp, dtype): return xp.linspace(10, 0, 5, dtype=dtype) @testing.for_all_dtypes(no_bool=True) @testing.numpy_cupy_array_equal() @skip_int_equality_before_numpy_1_20() def test_linspace3(self, xp, dtype): if xp.dtype(dtype).kind == 'u': pytest.skip() return xp.linspace(-10, 8, 9, dtype=dtype) @testing.for_all_dtypes(no_bool=True) @testing.numpy_cupy_array_equal() def test_linspace_zero_num(self, xp, dtype): return xp.linspace(0, 10, 0, dtype=dtype) @testing.for_all_dtypes(no_bool=True) @testing.numpy_cupy_array_equal() def test_linspace_zero_num_no_endopoint_with_retstep(self, xp, dtype): x, step = xp.linspace(0, 10, 0, dtype=dtype, endpoint=False, retstep=True) assert math.isnan(step) return x @testing.with_requires('numpy>=1.18') @testing.for_all_dtypes(no_bool=True) @testing.numpy_cupy_array_equal() def test_linspace_one_num_no_endopoint_with_retstep(self, xp, dtype): start, stop = 3, 7 x, step = xp.linspace(start, stop, 1, dtype=dtype, endpoint=False, retstep=True) assert step == stop - start return x @testing.for_all_dtypes(no_bool=True) @testing.numpy_cupy_array_equal() def test_linspace_one_num(self, xp, dtype): return xp.linspace(0, 2, 1, dtype=dtype) @testing.for_all_dtypes(no_bool=True) @testing.numpy_cupy_array_equal() def test_linspace_no_endpoint(self, xp, dtype): return xp.linspace(0, 10, 5, dtype=dtype, endpoint=False) @testing.for_all_dtypes(no_bool=True) @testing.numpy_cupy_array_equal() def test_linspace_with_retstep(self, xp, dtype): x, step = xp.linspace(0, 10, 5, dtype=dtype, retstep=True) assert step == 2.5 return x @testing.numpy_cupy_allclose() def test_linspace_no_dtype_int(self, xp): return xp.linspace(0, 10) @testing.numpy_cupy_allclose() def test_linspace_no_dtype_float(self, xp): return xp.linspace(0.0, 10.0) @testing.numpy_cupy_allclose() def test_linspace_float_args_with_int_dtype(self, xp): return xp.linspace(0.1, 9.1, 11, dtype=int) def test_linspace_neg_num(self): for xp in (numpy, cupy): with pytest.raises(ValueError): xp.linspace(0, 10, -1) @testing.numpy_cupy_allclose() def test_linspace_float_overflow(self, xp): return xp.linspace(0., sys.float_info.max / 5, 10, dtype=float) @testing.numpy_cupy_array_equal() def test_linspace_float_underflow(self, xp): # find minimum subnormal number x = sys.float_info.min while x / 2 > 0: x /= 2 return xp.linspace(0., x, 10, dtype=float) @testing.with_requires('numpy>=1.16') @testing.for_all_dtypes_combination(names=('dtype_range', 'dtype_out'), no_bool=True, no_complex=True) @testing.numpy_cupy_array_equal() def test_linspace_array_start_stop(self, xp, dtype_range, dtype_out): start = xp.array([0, 120], dtype=dtype_range) stop = xp.array([100, 0], dtype=dtype_range) return xp.linspace(start, stop, num=50, dtype=dtype_out) @testing.with_requires('numpy>=1.16') @testing.for_all_dtypes_combination(names=('dtype_range', 'dtype_out'), no_bool=True, no_complex=True) @testing.numpy_cupy_array_equal() @skip_int_equality_before_numpy_1_20(names=('dtype_range', 'dtype_out')) def test_linspace_mixed_start_stop(self, xp, dtype_range, dtype_out): start = 0.0 if xp.dtype(dtype_range).kind in 'u': stop = xp.array([100, 16], dtype=dtype_range) else: stop = xp.array([100, -100], dtype=dtype_range) return xp.linspace(start, stop, num=50, dtype=dtype_out) @testing.with_requires('numpy>=1.16') @testing.for_all_dtypes_combination(names=('dtype_range', 'dtype_out'), no_bool=True, no_complex=True) @testing.numpy_cupy_array_equal() @skip_int_equality_before_numpy_1_20(names=('dtype_range', 'dtype_out')) def test_linspace_mixed_start_stop2(self, xp, dtype_range, dtype_out): if xp.dtype(dtype_range).kind in 'u': start = xp.array([160, 120], dtype=dtype_range) else: start = xp.array([-120, 120], dtype=dtype_range) stop = 0 return xp.linspace(start, stop, num=50, dtype=dtype_out) @testing.with_requires('numpy>=1.16') @testing.for_all_dtypes_combination(names=('dtype_range', 'dtype_out'), no_bool=True, no_complex=True) @testing.numpy_cupy_array_equal() def test_linspace_array_start_stop_axis1(self, xp, dtype_range, dtype_out): start = xp.array([0, 120], dtype=dtype_range) stop = xp.array([100, 0], dtype=dtype_range) return xp.linspace(start, stop, num=50, dtype=dtype_out, axis=1) @testing.with_requires('numpy>=1.16') @testing.for_complex_dtypes() @testing.numpy_cupy_array_equal() def test_linspace_complex_start_stop(self, xp, dtype): start = xp.array([0, 120], dtype=dtype) stop = xp.array([100, 0], dtype=dtype) return xp.linspace(start, stop, num=50, dtype=dtype) @testing.with_requires('numpy>=1.16') @testing.for_all_dtypes(no_bool=True) @testing.numpy_cupy_array_equal() def test_linspace_start_stop_list(self, xp, dtype): start = [0, 0] stop = [100, 16] return xp.linspace(start, stop, num=50, dtype=dtype) @testing.for_all_dtypes(no_bool=True) @testing.numpy_cupy_allclose() def test_logspace(self, xp, dtype): return xp.logspace(0, 2, 5, dtype=dtype) @testing.for_all_dtypes(no_bool=True) @testing.numpy_cupy_allclose() def test_logspace2(self, xp, dtype): return xp.logspace(2, 0, 5, dtype=dtype) @testing.for_all_dtypes(no_bool=True) @testing.numpy_cupy_allclose() def test_logspace_zero_num(self, xp, dtype): return xp.logspace(0, 2, 0, dtype=dtype) @testing.for_all_dtypes(no_bool=True) @testing.numpy_cupy_allclose() def test_logspace_one_num(self, xp, dtype): return xp.logspace(0, 2, 1, dtype=dtype) @testing.for_all_dtypes(no_bool=True) @testing.numpy_cupy_allclose() def test_logspace_no_endpoint(self, xp, dtype): return xp.logspace(0, 2, 5, dtype=dtype, endpoint=False) @testing.numpy_cupy_allclose() def test_logspace_no_dtype_int(self, xp): return xp.logspace(0, 2) @testing.numpy_cupy_allclose() def test_logspace_no_dtype_float(self, xp): return xp.logspace(0.0, 2.0) @testing.numpy_cupy_allclose() def test_logspace_float_args_with_int_dtype(self, xp): return xp.logspace(0.1, 2.1, 11, dtype=int) def test_logspace_neg_num(self): for xp in (numpy, cupy): with pytest.raises(ValueError): xp.logspace(0, 10, -1) @testing.for_all_dtypes(no_bool=True) @testing.numpy_cupy_allclose() def test_logspace_base(self, xp, dtype): return xp.logspace(0, 2, 5, base=2.0, dtype=dtype) # See #7946 and https://github.com/numpy/numpy/issues/24957 @testing.with_requires('numpy>=1.16, !=1.25.*, !=1.26.*') @testing.for_all_dtypes_combination(names=('dtype_range', 'dtype_out'), no_bool=True, no_complex=True) @testing.numpy_cupy_allclose(rtol=1e-6, contiguous_check=False) def test_logspace_array_start_stop_axis1(self, xp, dtype_range, dtype_out): start = xp.array([0, 2], dtype=dtype_range) stop = xp.array([2, 0], dtype=dtype_range) return xp.logspace(start, stop, num=5, dtype=dtype_out, axis=1) @testing.parameterize( *testing.product({ 'indexing': ['xy', 'ij'], 'sparse': [False, True], 'copy': [False, True], }) ) class TestMeshgrid(unittest.TestCase): @testing.for_all_dtypes() def test_meshgrid0(self, dtype): out = cupy.meshgrid(indexing=self.indexing, sparse=self.sparse, copy=self.copy) assert (out == []) @testing.for_all_dtypes() @testing.numpy_cupy_array_equal() def test_meshgrid1(self, xp, dtype): x = xp.arange(2).astype(dtype) return xp.meshgrid(x, indexing=self.indexing, sparse=self.sparse, copy=self.copy) @testing.for_all_dtypes() @testing.numpy_cupy_array_equal() def test_meshgrid2(self, xp, dtype): x = xp.arange(2).astype(dtype) y = xp.arange(3).astype(dtype) return xp.meshgrid(x, y, indexing=self.indexing, sparse=self.sparse, copy=self.copy) @testing.for_all_dtypes() @testing.numpy_cupy_array_equal() def test_meshgrid3(self, xp, dtype): x = xp.arange(2).astype(dtype) y = xp.arange(3).astype(dtype) z = xp.arange(4).astype(dtype) return xp.meshgrid(x, y, z, indexing=self.indexing, sparse=self.sparse, copy=self.copy) class TestMgrid(unittest.TestCase): @testing.numpy_cupy_array_equal() def test_mgrid0(self, xp): return xp.mgrid[0:] @testing.numpy_cupy_array_equal() def test_mgrid1(self, xp): return xp.mgrid[-10:10] @testing.numpy_cupy_array_equal() def test_mgrid2(self, xp): return xp.mgrid[-10:10:10j] @testing.numpy_cupy_array_equal() def test_mgrid3(self, xp): x = xp.zeros(10)[:, None] y = xp.ones(10)[:, None] return xp.mgrid[x:y:10j] @testing.numpy_cupy_array_equal() def test_mgrid4(self, xp): # check len(keys) > 1 return xp.mgrid[-10:10:10j, -10:10:10j] @testing.numpy_cupy_array_equal() def test_mgrid5(self, xp): # check len(keys) > 1 x = xp.zeros(10)[:, None] y = xp.ones(10)[:, None] return xp.mgrid[x:y:10j, x:y:10j] class TestOgrid(unittest.TestCase): @testing.numpy_cupy_array_equal() def test_ogrid0(self, xp): return xp.ogrid[0:] @testing.numpy_cupy_array_equal() def test_ogrid1(self, xp): return xp.ogrid[-10:10] @testing.numpy_cupy_array_equal() def test_ogrid2(self, xp): return xp.ogrid[-10:10:10j] @testing.numpy_cupy_array_equal() def test_ogrid3(self, xp): x = xp.zeros(10)[:, None] y = xp.ones(10)[:, None] return xp.ogrid[x:y:10j] @testing.numpy_cupy_array_equal() def test_ogrid4(self, xp): # check len(keys) > 1 return xp.ogrid[-10:10:10j, -10:10:10j] @testing.numpy_cupy_array_equal() def test_ogrid5(self, xp): # check len(keys) > 1 x = xp.zeros(10)[:, None] y = xp.ones(10)[:, None] return xp.ogrid[x:y:10j, x:y:10j]