Skip to content

Commit

Permalink
Leverage dpctl.tensor.iinfo() and dpctl.tensor.finfo() implementation. (
Browse files Browse the repository at this point in the history
#1582)

* Leverage dpctl.tensor.iinfo() and dpctl.tensor.finfo() implementation.

* Address comment for dpnp.iinfo and dpnp.finfo functions

* Update dpnp_iface_types.py
  • Loading branch information
npolina4 authored Oct 11, 2023
1 parent 76e3f87 commit 0fe9a00
Show file tree
Hide file tree
Showing 8 changed files with 132 additions and 48 deletions.
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
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.
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

0 comments on commit 0fe9a00

Please sign in to comment.