diff --git a/array_api_compat/common/_aliases.py b/array_api_compat/common/_aliases.py index 03910681..46cbb359 100644 --- a/array_api_compat/common/_aliases.py +++ b/array_api_compat/common/_aliases.py @@ -5,7 +5,7 @@ from __future__ import annotations import inspect -from typing import NamedTuple, Optional, Sequence, Tuple, Union +from typing import Any, NamedTuple, Optional, Sequence, Tuple, Union from ._typing import Array, Device, DType, Namespace from ._helpers import ( @@ -609,6 +609,23 @@ def sign(x: Array, /, xp: Namespace, **kwargs) -> Array: out[xp.isnan(x)] = xp.nan return out[()] + +def finfo(type_: DType | Array, /, xp: Namespace) -> Any: + # It is surprisingly difficult to recognize a dtype apart from an array. + # np.int64 is not the same as np.asarray(1).dtype! + try: + return xp.finfo(type_) + except (ValueError, TypeError): + return xp.finfo(type_.dtype) + + +def iinfo(type_: DType | Array, /, xp: Namespace) -> Any: + try: + return xp.iinfo(type_) + except (ValueError, TypeError): + return xp.iinfo(type_.dtype) + + __all__ = ['arange', 'empty', 'empty_like', 'eye', 'full', 'full_like', 'linspace', 'ones', 'ones_like', 'zeros', 'zeros_like', 'UniqueAllResult', 'UniqueCountsResult', 'UniqueInverseResult', @@ -616,6 +633,6 @@ def sign(x: Array, /, xp: Namespace, **kwargs) -> Array: 'std', 'var', 'cumulative_sum', 'cumulative_prod','clip', 'permute_dims', 'reshape', 'argsort', 'sort', 'nonzero', 'ceil', 'floor', 'trunc', 'matmul', 'matrix_transpose', 'tensordot', 'vecdot', 'isdtype', - 'unstack', 'sign'] + 'unstack', 'sign', 'finfo', 'iinfo'] _all_ignore = ['inspect', 'array_namespace', 'NamedTuple'] diff --git a/array_api_compat/cupy/_aliases.py b/array_api_compat/cupy/_aliases.py index 423fd10a..fd1460ae 100644 --- a/array_api_compat/cupy/_aliases.py +++ b/array_api_compat/cupy/_aliases.py @@ -61,6 +61,8 @@ matrix_transpose = get_xp(cp)(_aliases.matrix_transpose) tensordot = get_xp(cp)(_aliases.tensordot) sign = get_xp(cp)(_aliases.sign) +finfo = get_xp(cp)(_aliases.finfo) +iinfo = get_xp(cp)(_aliases.iinfo) _copy_default = object() diff --git a/array_api_compat/dask/array/_aliases.py b/array_api_compat/dask/array/_aliases.py index e6eff359..dca6d570 100644 --- a/array_api_compat/dask/array/_aliases.py +++ b/array_api_compat/dask/array/_aliases.py @@ -5,8 +5,6 @@ import numpy as np from numpy import ( # dtypes - iinfo, - finfo, bool_ as bool, float32, float64, @@ -131,6 +129,8 @@ def arange( matmul = get_xp(np)(_aliases.matmul) tensordot = get_xp(np)(_aliases.tensordot) sign = get_xp(np)(_aliases.sign) +finfo = get_xp(np)(_aliases.finfo) +iinfo = get_xp(np)(_aliases.iinfo) # asarray also adds the copy keyword, which is not present in numpy 1.0. @@ -343,10 +343,9 @@ def count_nonzero( '__array_namespace_info__', 'asarray', 'astype', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'bitwise_left_shift', 'bitwise_invert', - 'bitwise_right_shift', 'concat', 'pow', 'iinfo', 'finfo', 'can_cast', + 'bitwise_right_shift', 'concat', 'pow', 'can_cast', 'result_type', 'bool', 'float32', 'float64', 'int8', 'int16', 'int32', 'int64', - 'uint8', 'uint16', 'uint32', 'uint64', - 'complex64', 'complex128', 'iinfo', 'finfo', + 'uint8', 'uint16', 'uint32', 'uint64', 'complex64', 'complex128', 'can_cast', 'count_nonzero', 'result_type'] _all_ignore = ["array_namespace", "get_xp", "da", "np"] diff --git a/array_api_compat/numpy/_aliases.py b/array_api_compat/numpy/_aliases.py index 1d084b2b..ae0d006d 100644 --- a/array_api_compat/numpy/_aliases.py +++ b/array_api_compat/numpy/_aliases.py @@ -61,6 +61,8 @@ matrix_transpose = get_xp(np)(_aliases.matrix_transpose) tensordot = get_xp(np)(_aliases.tensordot) sign = get_xp(np)(_aliases.sign) +finfo = get_xp(np)(_aliases.finfo) +iinfo = get_xp(np)(_aliases.iinfo) def _supports_buffer_protocol(obj): diff --git a/array_api_compat/torch/_aliases.py b/array_api_compat/torch/_aliases.py index 0891525a..a2ed1449 100644 --- a/array_api_compat/torch/_aliases.py +++ b/array_api_compat/torch/_aliases.py @@ -250,6 +250,9 @@ def min(x: Array, /, *, axis: Optional[Union[int, Tuple[int, ...]]] = None, keep unstack = get_xp(torch)(_aliases.unstack) cumulative_sum = get_xp(torch)(_aliases.cumulative_sum) cumulative_prod = get_xp(torch)(_aliases.cumulative_prod) +finfo = get_xp(torch)(_aliases.finfo) +iinfo = get_xp(torch)(_aliases.iinfo) + # torch.sort also returns a tuple # https://github.com/pytorch/pytorch/issues/70921 @@ -851,6 +854,6 @@ def sign(x: Array, /) -> Array: 'UniqueAllResult', 'UniqueCountsResult', 'UniqueInverseResult', 'unique_all', 'unique_counts', 'unique_inverse', 'unique_values', 'matmul', 'matrix_transpose', 'vecdot', 'tensordot', 'isdtype', - 'take', 'take_along_axis', 'sign'] + 'take', 'take_along_axis', 'sign', 'finfo', 'iinfo'] _all_ignore = ['torch', 'get_xp'] diff --git a/cupy-xfails.txt b/cupy-xfails.txt index 3d20d745..a30572f8 100644 --- a/cupy-xfails.txt +++ b/cupy-xfails.txt @@ -14,9 +14,10 @@ array_api_tests/test_array_object.py::test_getitem # copy=False is not yet implemented array_api_tests/test_creation_functions.py::test_asarray_arrays -# finfo test is testing that the result is a float instead of float32 (see -# also https://github.com/data-apis/array-api/issues/405) +# attributes are np.float32 instead of float +# (see also https://github.com/data-apis/array-api/issues/405) array_api_tests/test_data_type_functions.py::test_finfo[float32] +array_api_tests/test_data_type_functions.py::test_finfo[complex64] # Some array attributes are missing, and we do not wrap the array object array_api_tests/test_has_names.py::test_has_names[array_method-__array_namespace__] diff --git a/dask-xfails.txt b/dask-xfails.txt index bd65d004..932aeada 100644 --- a/dask-xfails.txt +++ b/dask-xfails.txt @@ -12,8 +12,10 @@ array_api_tests/test_array_object.py::test_getitem_masking # zero division error, and typeerror: tuple indices must be integers or slices not tuple array_api_tests/test_creation_functions.py::test_eye -# finfo(float32).eps returns float32 but should return float +# attributes are np.float32 instead of float +# (see also https://github.com/data-apis/array-api/issues/405) array_api_tests/test_data_type_functions.py::test_finfo[float32] +array_api_tests/test_data_type_functions.py::test_finfo[complex64] # out[-1]=dask.array but should be some floating number # (I think the test is not forcing the op to be computed?) diff --git a/numpy-1-21-xfails.txt b/numpy-1-21-xfails.txt index 30cde668..66443a73 100644 --- a/numpy-1-21-xfails.txt +++ b/numpy-1-21-xfails.txt @@ -1,8 +1,10 @@ # asarray(copy=False) is not yet implemented array_api_tests/test_creation_functions.py::test_asarray_arrays -# finfo(float32).eps returns float32 but should return float +# attributes are np.float32 instead of float +# (see also https://github.com/data-apis/array-api/issues/405) array_api_tests/test_data_type_functions.py::test_finfo[float32] +array_api_tests/test_data_type_functions.py::test_finfo[complex64] # Array methods and attributes not already on np.ndarray cannot be wrapped array_api_tests/test_has_names.py::test_has_names[array_method-__array_namespace__] @@ -41,7 +43,7 @@ array_api_tests/meta/test_hypothesis_helpers.py::test_symmetric_matrices ############################ # finfo has no smallest_normal -array_api_tests/test_data_type_functions.py::test_finfo[float64] +array_api_tests/test_data_type_functions.py::test_finfo # dlpack stuff array_api_tests/test_has_names.py::test_has_names[creation-from_dlpack] diff --git a/numpy-1-26-xfails.txt b/numpy-1-26-xfails.txt index 1ce28ef4..ed95083a 100644 --- a/numpy-1-26-xfails.txt +++ b/numpy-1-26-xfails.txt @@ -1,5 +1,7 @@ -# finfo(float32).eps returns float32 but should return float +# attributes are np.float32 instead of float +# (see also https://github.com/data-apis/array-api/issues/405) array_api_tests/test_data_type_functions.py::test_finfo[float32] +array_api_tests/test_data_type_functions.py::test_finfo[complex64] # Array methods and attributes not already on np.ndarray cannot be wrapped array_api_tests/test_has_names.py::test_has_names[array_method-__array_namespace__] diff --git a/numpy-dev-xfails.txt b/numpy-dev-xfails.txt index 98659710..972d2346 100644 --- a/numpy-dev-xfails.txt +++ b/numpy-dev-xfails.txt @@ -1,5 +1,7 @@ -# finfo(float32).eps returns float32 but should return float +# attributes are np.float32 instead of float +# (see also https://github.com/data-apis/array-api/issues/405) array_api_tests/test_data_type_functions.py::test_finfo[float32] +array_api_tests/test_data_type_functions.py::test_finfo[complex64] # The test suite cannot properly get the signature for vecdot # https://github.com/numpy/numpy/pull/26237 diff --git a/numpy-xfails.txt b/numpy-xfails.txt index 0885dcaa..0f09985e 100644 --- a/numpy-xfails.txt +++ b/numpy-xfails.txt @@ -1,5 +1,7 @@ -# finfo(float32).eps returns float32 but should return float +# attributes are np.float32 instead of float +# (see also https://github.com/data-apis/array-api/issues/405) array_api_tests/test_data_type_functions.py::test_finfo[float32] +array_api_tests/test_data_type_functions.py::test_finfo[complex64] # The test suite cannot properly get the signature for vecdot # https://github.com/numpy/numpy/pull/26237 diff --git a/torch-xfails.txt b/torch-xfails.txt index f8333d90..e556fa4f 100644 --- a/torch-xfails.txt +++ b/torch-xfails.txt @@ -115,6 +115,10 @@ array_api_tests/test_operators_and_elementwise_functions.py::test_round array_api_tests/test_set_functions.py::test_unique_counts array_api_tests/test_set_functions.py::test_unique_values +# finfo/iinfo.dtype is a string instead of a dtype +array_api_tests/test_data_type_functions.py::test_finfo_dtype +array_api_tests/test_data_type_functions.py::test_iinfo_dtype + # 2023.12 support array_api_tests/test_has_names.py::test_has_names[manipulation-repeat] array_api_tests/test_manipulation_functions.py::test_repeat