diff --git a/dpnp/dpnp_iface_types.py b/dpnp/dpnp_iface_types.py index 68da06583fe..bb45efa6594 100644 --- a/dpnp/dpnp_iface_types.py +++ b/dpnp/dpnp_iface_types.py @@ -34,8 +34,11 @@ This module provides public type interface file for the library """ +import dpctl.tensor as dpt import numpy +from dpnp.dpnp_array import dpnp_array + __all__ = [ "bool", "bool_", @@ -50,12 +53,14 @@ "dtype", "e", "euler_gamma", + "finfo", "float", "float_", "float16", "float32", "float64", "floating", + "iinfo", "inexact", "Inf", "inf", @@ -140,6 +145,85 @@ PZERO = numpy.PZERO +def finfo(dtype): + """ + Returns machine limits for floating-point data types. + + For full documentation refer to :obj:`numpy.finfo`. + + Parameters + ---------- + dtype : dtype, dpnp_array + Floating-point dtype or an array with floating point data type. + If complex, the information is about its component data type. + + Returns + ------- + out : finfo_object + An object have the following attributes + * bits: int + number of bits occupied by dtype. + * dtype: dtype + real-valued floating-point data type. + * eps: float + difference between 1.0 and the next smallest representable + real-valued floating-point number larger than 1.0 according + to the IEEE-754 standard. + * epsneg: float + difference between 1.0 and the next smallest representable real-valued + floating-point number smaller than 1.0 according to the IEEE-754 + standard. + * max: float + largest representable real-valued number. + * min: float + smallest representable real-valued number. + * precision: float + the approximate number of decimal digits to which this kind of + floating point type is precise. + * resolution: float + the approximate decimal resolution of this type. + * tiny: float + an alias for `smallest_normal` + * smallest_normal: float + smallest positive real-valued floating-point number with + full precision. + + """ + if isinstance(dtype, dpnp_array): + dtype = dtype.dtype + return dpt.finfo(dtype) + + +def iinfo(dtype): + """ + Returns machine limits for integer data types. + + For full documentation refer to :obj:`numpy.iinfo`. + + Parameters + ---------- + dtype : dtype, dpnp_array + Integer dtype or an array with integer dtype. + + Returns + ------- + out : iinfo_object + An object with the following attributes + * bits: int + number of bits occupied by the data type + * dtype: dtype + integer data type. + * max: int + largest representable number. + * min: int + smallest representable number. + + """ + if isinstance(dtype, dpnp_array): + dtype = dtype.dtype + return dpt.iinfo(dtype) + + def isscalar(obj): """ Returns True if the type of `obj` is a scalar type. diff --git a/dpnp/random/dpnp_algo_random.pyx b/dpnp/random/dpnp_algo_random.pyx index 85557c781a5..5fb1e4ae00d 100644 --- a/dpnp/random/dpnp_algo_random.pyx +++ b/dpnp/random/dpnp_algo_random.pyx @@ -462,7 +462,7 @@ cdef class MT19937(_Engine): if value < 0: return False - max_val = numpy.iinfo(numpy.uint32).max + max_val = dpnp.iinfo(numpy.uint32).max if isinstance(value, dpnp_array): max_val = dpnp.array(max_val, dtype=numpy.uint32) return value <= max_val @@ -499,7 +499,7 @@ cdef class MCG59(_Engine): if value < 0: return False - max_val = numpy.iinfo(numpy.uint64).max + max_val = dpnp.iinfo(numpy.uint64).max if isinstance(value, dpnp_array): max_val = dpnp.array(max_val, dtype=numpy.uint64) return value <= max_val @@ -1052,7 +1052,7 @@ cpdef utils.dpnp_descriptor dpnp_rng_negative_binomial(double a, double p, size) result_shape = utils._object_to_tuple(size) if p == 0.0: - filled_val = numpy.iinfo(dtype).min + filled_val = dpnp.iinfo(dtype).min return utils.dpnp_descriptor(dpnp.full(result_shape, filled_val, dtype=dtype)) elif p == 1.0: return utils.dpnp_descriptor(dpnp.full(result_shape, 0, dtype=dtype)) diff --git a/dpnp/random/dpnp_iface_random.py b/dpnp/random/dpnp_iface_random.py index 1d647dc225b..1f2137a0807 100644 --- a/dpnp/random/dpnp_iface_random.py +++ b/dpnp/random/dpnp_iface_random.py @@ -675,7 +675,7 @@ def multinomial(n, pvals, size=None): d = len(pvals) if n < 0: pass - elif n > numpy.iinfo(dpnp.int32).max: + elif n > dpnp.iinfo(dpnp.int32).max: pass elif pvals_sum > 1.0: pass diff --git a/dpnp/random/dpnp_random_state.py b/dpnp/random/dpnp_random_state.py index 4d6f8d22a71..c53ae620b2c 100644 --- a/dpnp/random/dpnp_random_state.py +++ b/dpnp/random/dpnp_random_state.py @@ -81,7 +81,7 @@ def __init__(self, seed=None, device=None, sycl_queue=None): is_cpu = self._sycl_device.is_cpu if seed is None: low = 0 - high = numpy.iinfo(numpy.int32).max + 1 + high = dpnp.iinfo(numpy.int32).max + 1 if is_cpu: # ask NumPy to generate an array of three random integers as default seed value @@ -237,8 +237,8 @@ def normal( dtype = self._validate_float_dtype( dtype, (dpnp.float32, dpnp.float64) ) - min_floating = numpy.finfo(dtype).min - max_floating = numpy.finfo(dtype).max + min_floating = dpnp.finfo(dtype).min + max_floating = dpnp.finfo(dtype).max if ( loc >= max_floating or loc <= min_floating @@ -371,8 +371,8 @@ def randint(self, low, high=None, size=None, dtype=int, usm_type="device"): high = low low = 0 - min_int = numpy.iinfo("int32").min - max_int = numpy.iinfo("int32").max + min_int = dpnp.iinfo("int32").min + max_int = dpnp.iinfo("int32").max if ( not self._is_finite_scalar(low) @@ -587,8 +587,8 @@ def uniform( elif not dpnp.isscalar(high): pass else: - min_double = numpy.finfo("double").min - max_double = numpy.finfo("double").max + min_double = dpnp.finfo("double").min + max_double = dpnp.finfo("double").max if ( not self._is_finite_scalar(low) diff --git a/tests/helper.py b/tests/helper.py index bb8ccd378a2..b3d816e769a 100644 --- a/tests/helper.py +++ b/tests/helper.py @@ -18,7 +18,7 @@ def assert_dtype_allclose(dpnp_arr, numpy_arr, check_type=True): is_inexact = lambda x: dpnp.issubdtype(x.dtype, dpnp.inexact) if is_inexact(dpnp_arr) or is_inexact(numpy_arr): tol = 8 * max( - numpy.finfo(dpnp_arr.dtype).resolution, + dpnp.finfo(dpnp_arr).resolution, numpy.finfo(numpy_arr.dtype).resolution, ) assert_allclose(dpnp_arr.asnumpy(), numpy_arr, atol=tol, rtol=tol) diff --git a/tests/test_random.py b/tests/test_random.py index 93026f64b0d..17383c56610 100644 --- a/tests/test_random.py +++ b/tests/test_random.py @@ -674,10 +674,10 @@ def test_extreme_value(self): ) n = 5 p = 0.0 - res = dpnp.asnumpy(dpnp.random.negative_binomial(n=n, p=p, size=10)) - check_val = numpy.iinfo(res.dtype).min - assert len(numpy.unique(res)) == 1 - assert numpy.unique(res)[0] == check_val + res = dpnp.random.negative_binomial(n=n, p=p, size=10) + check_val = dpnp.iinfo(res).min + assert len(dpnp.unique(res)) == 1 + assert dpnp.unique(res)[0] == check_val def test_invalid_args(self): n = 10 # parameter `n`, OK diff --git a/tests/test_random_state.py b/tests/test_random_state.py index f6be26202fb..4771eadc42e 100644 --- a/tests/test_random_state.py +++ b/tests/test_random_state.py @@ -91,9 +91,9 @@ def test_distr(self, dtype, usm_type): ) # TODO: discuss with opneMKL: there is a difference between CPU and GPU # generated samples since 9 digit while precision=15 for float64 - # precision = numpy.finfo(dtype=dtype).precision + # precision = dpnp.finfo(dtype=dtype).precision precision = ( - 8 if dtype == dpnp.float64 else numpy.finfo(dtype=dtype).precision + 8 if dtype == dpnp.float64 else dpnp.finfo(dtype=dtype).precision ) assert_array_almost_equal( dpnp_data.asnumpy(), expected, decimal=precision @@ -136,8 +136,8 @@ def test_scale(self, dtype, usm_type): [ numpy.inf, -numpy.inf, - numpy.nextafter(numpy.finfo(get_default_floating()).max, 0), - numpy.nextafter(numpy.finfo(get_default_floating()).min, 0), + numpy.nextafter(dpnp.finfo(get_default_floating()).max, 0), + numpy.nextafter(dpnp.finfo(get_default_floating()).min, 0), ], ids=[ "numpy.inf", @@ -170,8 +170,8 @@ def test_inf_loc_scale(self, loc): def test_extreme_bounds(self): dtype = get_default_floating() - fmin = numpy.finfo(dtype).min - fmax = numpy.finfo(dtype).max + fmin = dpnp.finfo(dtype).min + fmax = dpnp.finfo(dtype).max size = 1000 func = RandomState(34567).normal @@ -228,7 +228,7 @@ def test_fallback(self, loc, scale): ) dtype = get_default_floating() - precision = numpy.finfo(dtype=dtype).precision + precision = dpnp.finfo(dtype=dtype).precision assert_array_almost_equal(actual, expected, decimal=precision) # check if compute follows data isn't broken @@ -310,7 +310,7 @@ def test_distr(self, usm_type): dtype=dtype, ) - precision = numpy.finfo(dtype=dtype).precision + precision = dpnp.finfo(dtype=dtype).precision assert_array_almost_equal(data.asnumpy(), expected, decimal=precision) assert_cfd(data, sycl_queue, usm_type) @@ -464,8 +464,8 @@ def test_negative_interval(self): def test_bounds_checking(self): dtype = dpnp.int32 func = RandomState().randint - low = numpy.iinfo(dtype).min - high = numpy.iinfo(dtype).max + low = dpnp.iinfo(dtype).min + high = dpnp.iinfo(dtype).max # inf can't be converted to int boundary assert_raises(OverflowError, func, -numpy.inf, 0) @@ -486,8 +486,8 @@ def test_bounds_checking(self): def test_rng_zero_and_extremes(self): dtype = dpnp.int32 func = RandomState().randint - low = numpy.iinfo(dtype).min - high = numpy.iinfo(dtype).max + low = dpnp.iinfo(dtype).min + high = dpnp.iinfo(dtype).max sycl_device = dpctl.SyclQueue().sycl_device if sycl_device.has_aspect_gpu and not sycl_device.has_aspect_fp64: @@ -507,8 +507,8 @@ def test_rng_zero_and_extremes(self): def test_full_range(self): dtype = dpnp.int32 - low = numpy.iinfo(dtype).min - high = numpy.iinfo(dtype).max + low = dpnp.iinfo(dtype).min + high = dpnp.iinfo(dtype).max try: RandomState().randint(low, high) @@ -642,8 +642,8 @@ def test_distr(self, usm_type): # TODO: discuss with opneMKL: there is a difference between CPU and GPU # generated samples since 9 digit while precision=15 for float64 - # precision = numpy.finfo(dtype=numpy.float64).precision - precision = numpy.finfo(dtype=numpy.float32).precision + # precision = dpnp.finfo(dtype=numpy.float64).precision + precision = dpnp.finfo(dtype=numpy.float32).precision assert_array_almost_equal(data.asnumpy(), expected, decimal=precision) # call with the same seed has to draw the same values @@ -707,7 +707,7 @@ def test_scalar(self, func): rs = RandomState(seed) a2 = getattr(rs, func)(size=size).asnumpy() - precision = numpy.finfo(dtype=numpy.float64).precision + precision = dpnp.finfo(dtype=numpy.float64).precision assert_array_almost_equal(a1, a2, decimal=precision) @pytest.mark.usefixtures("allow_fall_back_on_numpy") @@ -782,8 +782,8 @@ def test_invalid_type(self, seed): range(-1, -11, -1), numpy.arange(4, dtype=numpy.int32), dpnp.arange(-3, 3, dtype=numpy.int32), - numpy.iinfo(numpy.uint32).max + 1, - (1, 7, numpy.iinfo(numpy.uint32).max + 1), + dpnp.iinfo(numpy.uint32).max + 1, + (1, 7, dpnp.iinfo(numpy.uint32).max + 1), ], ids=[ "-1", @@ -794,8 +794,8 @@ def test_invalid_type(self, seed): "range(-1, -11, -1)", "numpy.arange(4, dtype=numpy.int32)", "dpnp.arange(-3, 3, dtype=numpy.int32)", - "numpy.iinfo(numpy.uint32).max + 1", - "(1, 7, numpy.iinfo(numpy.uint32).max + 1)", + "dpnp.iinfo(numpy.uint32).max + 1", + "(1, 7, dpnp.iinfo(numpy.uint32).max + 1)", ], ) def test_invalid_value(self, seed): @@ -879,8 +879,8 @@ def test_distr(self, usm_type): # TODO: discuss with opneMKL: there is a difference between CPU and GPU # generated samples since 9 digit while precision=15 for float64 - # precision = numpy.finfo(dtype=numpy.float64).precision - precision = numpy.finfo(dtype=numpy.float32).precision + # precision = dpnp.finfo(dtype=numpy.float64).precision + precision = dpnp.finfo(dtype=numpy.float32).precision assert_array_almost_equal(data.asnumpy(), expected, decimal=precision) # call with the same seed has to draw the same values @@ -957,7 +957,7 @@ def test_distr(self, usm_type): dtype=dtype, ) - precision = numpy.finfo(dtype=dtype).precision + precision = dpnp.finfo(dtype=dtype).precision assert_array_almost_equal(data.asnumpy(), expected, decimal=precision) # call with omitted dimensions has to draw the first element from expected @@ -1042,7 +1042,7 @@ def test_distr(self, bounds, dtype, usm_type): ] ) assert_array_almost_equal( - actual, expected, decimal=numpy.finfo(dtype=dtype).precision + actual, expected, decimal=dpnp.finfo(dtype=dtype).precision ) else: expected = numpy.array([[3, 8], [2, 4], [1, 4]]) @@ -1057,7 +1057,7 @@ def test_distr(self, bounds, dtype, usm_type): ] ) assert_array_almost_equal( - actual, expected, decimal=numpy.finfo(dtype=dtype).precision + actual, expected, decimal=dpnp.finfo(dtype=dtype).precision ) else: expected = numpy.array([[1, 4], [5, 1], [3, 7]]) @@ -1101,13 +1101,13 @@ def test_low_high_equal(self, dtype, usm_type): assert_array_equal(actual, expected) else: assert_array_almost_equal( - actual, expected, decimal=numpy.finfo(dtype=dtype).precision + actual, expected, decimal=dpnp.finfo(dtype=dtype).precision ) @pytest.mark.usefixtures("allow_fall_back_on_numpy") def test_range_bounds(self): - fmin = numpy.finfo("double").min - fmax = numpy.finfo("double").max + fmin = dpnp.finfo("double").min + fmax = dpnp.finfo("double").max func = RandomState().uniform assert_raises(OverflowError, func, -numpy.inf, 0) @@ -1146,7 +1146,7 @@ def test_fallback(self, low, high): ) dtype = get_default_floating() - precision = numpy.finfo(dtype=dtype).precision + precision = dpnp.finfo(dtype=dtype).precision assert_array_almost_equal(actual, expected, decimal=precision) # check if compute follows data isn't broken diff --git a/tests/third_party/cupy/creation_tests/test_ranges.py b/tests/third_party/cupy/creation_tests/test_ranges.py index c165b4e94a2..be2f113a318 100644 --- a/tests/third_party/cupy/creation_tests/test_ranges.py +++ b/tests/third_party/cupy/creation_tests/test_ranges.py @@ -141,13 +141,13 @@ def test_linspace_neg_num(self): @testing.numpy_cupy_allclose() def test_linspace_float_overflow(self, xp): dtype = cupy.default_float_type() - return xp.linspace(0.0, numpy.finfo(dtype).max / 5, 10, dtype=dtype) + return xp.linspace(0.0, xp.finfo(dtype).max / 5, 10, dtype=dtype) @testing.numpy_cupy_allclose() def test_linspace_float_underflow(self, xp): # find minimum subnormal number dtype = cupy.default_float_type() - x = numpy.finfo(dtype).min + x = xp.finfo(dtype).min while x / 2 > 0: x /= 2 return xp.linspace(0.0, x, 10, dtype=dtype)