Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Leverage dpctl.tensor.iinfo() and dpctl.tensor.finfo() implementation. #1582

Merged
merged 4 commits into from
Oct 11, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions dpnp/dpnp_iface_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -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_",
Expand All @@ -50,12 +53,14 @@
"dtype",
"e",
"euler_gamma",
"iinfo",
npolina4 marked this conversation as resolved.
Show resolved Hide resolved
"float",
"float_",
"float16",
"float32",
"float64",
"floating",
"finfo",
"inexact",
"Inf",
"inf",
Expand Down Expand Up @@ -140,6 +145,74 @@
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
npolina4 marked this conversation as resolved.
Show resolved Hide resolved
number of bits occupied by dtype.
* 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.
* max: float
largest representable real-valued number.
* min: float
smallest representable real-valued number.
* smallest_normal: float
smallest positive real-valued floating-point number with
full precision.
* dtype: dtype
real-valued floating-point data type.
npolina4 marked this conversation as resolved.
Show resolved Hide resolved

"""
if isinstance(dtype, dpnp_array):
dtype = dtype.dtype
npolina4 marked this conversation as resolved.
Show resolved Hide resolved
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
* max: int
largest representable number.
* min: int
smallest representable number.
* dtype: dtype
integer data type.

"""
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.
Expand Down
6 changes: 3 additions & 3 deletions dpnp/random/dpnp_algo_random.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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))
Expand Down
2 changes: 1 addition & 1 deletion dpnp/random/dpnp_iface_random.py
Original file line number Diff line number Diff line change
Expand Up @@ -674,7 +674,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
Expand Down
14 changes: 7 additions & 7 deletions dpnp/random/dpnp_random_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
60 changes: 30 additions & 30 deletions tests/test_random_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)

Expand Down Expand Up @@ -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)
Expand All @@ -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:
Expand All @@ -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)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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")
Expand Down Expand Up @@ -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",
Expand All @@ -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):
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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]])
Expand All @@ -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]])
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions tests/third_party/cupy/creation_tests/test_ranges.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Loading