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 all commits
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
84 changes: 84 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",
"finfo",
"float",
"float_",
"float16",
"float32",
"float64",
"floating",
"iinfo",
"inexact",
"Inf",
"inf",
Expand Down Expand Up @@ -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
npolina4 marked this conversation as resolved.
Show resolved Hide resolved
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
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
* 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.
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 @@ -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
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
2 changes: 1 addition & 1 deletion tests/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
8 changes: 4 additions & 4 deletions tests/test_random.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading