From ed334f848d4c38ee3e106c272101d0251c381aae Mon Sep 17 00:00:00 2001 From: neosunhan Date: Tue, 14 Jun 2022 18:51:28 +0800 Subject: [PATCH 001/150] Create `array_api` namespace --- heat/array_api/__init__.py | 36 +++++++ heat/array_api/_array_object.py | 177 ++++++++++++++++++++++++++++++++ heat/array_api/_dtypes.py | 141 +++++++++++++++++++++++++ heat/array_api/_typing.py | 28 +++++ 4 files changed, 382 insertions(+) create mode 100644 heat/array_api/__init__.py create mode 100644 heat/array_api/_array_object.py create mode 100644 heat/array_api/_dtypes.py create mode 100644 heat/array_api/_typing.py diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py new file mode 100644 index 0000000000..be9cb06355 --- /dev/null +++ b/heat/array_api/__init__.py @@ -0,0 +1,36 @@ +""" +A Heat sub-namespace that conforms to the Python array API standard. +""" +import warnings + +warnings.warn("The heat.array_api submodule is not fully implemented.", stacklevel=2) + +__all__ = [] + +from ._dtypes import ( + int8, + int16, + int32, + int64, + uint8, + # uint16, + # uint32, + # uint64, + float32, + float64, + bool, +) + +__all__ += [ + "int8", + "int16", + "int32", + "int64", + "uint8", + # "uint16", + # "uint32", + # "uint64", + "float32", + "float64", + "bool", +] diff --git a/heat/array_api/_array_object.py b/heat/array_api/_array_object.py new file mode 100644 index 0000000000..cd92933796 --- /dev/null +++ b/heat/array_api/_array_object.py @@ -0,0 +1,177 @@ +from __future__ import annotations + +from ._dtypes import ( + _all_dtypes, + _boolean_dtypes, + _integer_dtypes, + _integer_or_boolean_dtypes, + _floating_dtypes, + _numeric_dtypes, + _result_type, + _dtype_categories, +) +from ._typing import Dtype + +import heat as ht +from heat import array_api +from heat.core.devices import Device +from heat.core.dndarray import DNDarray +from typing import Any, Tuple, Union, Optional + + +class Array: + """ + DNDarray object for the array API namespace. + This is a wrapper around `heat.DNDarray` that restricts the usage to only + those things that are required by the array API namespace. Note, + attributes on this object that start with a single underscore are not part + of the API specification and should only be used internally. This object + should not be constructed directly. Rather, use one of the creation + functions, such as asarray(). + """ + + _array: DNDarray + + @classmethod + def _new(cls, x, /): + """ + This is a private method for initializing the array API Array + object. + Functions outside of the array_api submodule should not use this + method. Use one of the creation functions instead, such as + `asarray`. + """ + obj = super().__new__(cls) + obj._array = x + return obj + + def __new__(cls, *args, **kwargs): + """ + Prevent `Array()` from working. + """ + raise TypeError( + "The array_api Array object should not be instantiated directly. Use an array creation function, such as asarray(), instead." + ) + + def _check_allowed_dtypes( + self, other: Union[bool, int, float, Array], dtype_category: str, op: str + ) -> Array: + """ + Helper function for operators to only allow specific input dtypes + Use like + other = self._check_allowed_dtypes(other, 'numeric', '__add__') + if other is NotImplemented: + return other + """ + if self.dtype not in _dtype_categories[dtype_category]: + raise TypeError(f"Only {dtype_category} dtypes are allowed in {op}") + if isinstance(other, (int, float, bool)): + other = self._promote_scalar(other) + elif isinstance(other, Array): + if other.dtype not in _dtype_categories[dtype_category]: + raise TypeError(f"Only {dtype_category} dtypes are allowed in {op}") + else: + return NotImplemented + return other + + def _promote_scalar(self, scalar): + """ + Returns a promoted version of a Python scalar appropriate for use with + operations on self. + This may raise a `TypeError` when the scalar type is incompatible with + the dtype of self. + """ + # Note: Only Python scalar types that match the array dtype are + # allowed. + if isinstance(scalar, bool): + if self.dtype not in _boolean_dtypes: + raise TypeError("Python bool scalars can only be promoted with bool arrays") + elif isinstance(scalar, int): + if self.dtype in _boolean_dtypes: + raise TypeError("Python int scalars cannot be promoted with bool arrays") + elif isinstance(scalar, float): + if self.dtype not in _floating_dtypes: + raise TypeError( + "Python float scalars can only be promoted with floating-point arrays." + ) + else: + raise TypeError("'scalar' must be a Python scalar") + + # Note: scalars are unconditionally cast to the same dtype as the + # array. + + return Array._new(ht.array(scalar, self.dtype)) + + def __abs__(self: Array, /) -> Array: + """ + Calculates the absolute value for each element of an array instance + (i.e., the element-wise result has the same magnitude as the respective + element but has positive sign). + """ + if self.dtype not in _numeric_dtypes: + raise TypeError("Only numeric dtypes are allowed in __abs__") + res = ht.abs(self._array) + return self.__class__._new(res) + + def __add__(self: Array, other: Union[int, float, Array], /) -> Array: + """ + Calculates the sum for each element of an array instance with the + respective element of the array `other`. + """ + other = self._check_allowed_dtypes(other, "numeric", "__add__") + if other is NotImplemented: + return other + res = ht.add(self._array, other._array) + return self.__class__._new(res) + + def __and__(self: Array, other: Union[int, bool, Array], /) -> Array: + """ + Evaluates `self_i & other_i` for each element of an array instance + with the respective element of the array `other`. + """ + other = self._check_allowed_dtypes(other, "integer or boolean", "__and__") + if other is NotImplemented: + return other + res = ht.bitwise_and(self._array, other._array) + return self.__class__._new(res) + + def __array_namespace__(self: Array, /, *, api_version: Optional[str] = None) -> Any: + if api_version is not None and api_version != "2021.12": + raise ValueError(f"Unrecognized array API version: {api_version}") + return array_api + + @property + def dtype(self) -> Dtype: + """ + Array API compatible wrapper for `heat.DNDarray.dtype`. + """ + return self._array.dtype + + @property + def device(self) -> Device: + """ + Array API compatible wrapper for `heat.DNDarray.device`. + """ + return self._array.device + + @property + def ndim(self) -> int: + """ + Array API compatible wrapper for `heat.DNDarray.ndim`. + See its docstring for more information. + """ + return self._array.ndim + + @property + def shape(self) -> Tuple[Optional[int], ...]: + """ + Array API compatible wrapper for `heat.DNDarray.shape`. + """ + return self._array.shape + + @property + def size(self) -> Optional[int]: + """ + Array API compatible wrapper for `heat.DNDarray.size`. + """ + return self._array.size diff --git a/heat/array_api/_dtypes.py b/heat/array_api/_dtypes.py new file mode 100644 index 0000000000..58239a46c1 --- /dev/null +++ b/heat/array_api/_dtypes.py @@ -0,0 +1,141 @@ +import heat as ht + +int8 = ht.int8 +int16 = ht.int16 +int32 = ht.int32 +int64 = ht.int64 +uint8 = ht.uint8 +# uint16 = +# uint32 = +# uint64 = +float32 = ht.float32 +float64 = ht.float64 +bool = ht.bool + +_all_dtypes = ( + int8, + int16, + int32, + int64, + uint8, + # uint16, + # uint32, + # uint64, + float32, + float64, + bool, +) +_boolean_dtypes = (bool,) +_floating_dtypes = (float32, float64) +_integer_dtypes = ( + int8, + int16, + int32, + int64, + uint8, + # uint16, + # uint32, + # uint64 +) +_integer_or_boolean_dtypes = ( + bool, + int8, + int16, + int32, + int64, + uint8, + # uint16, + # uint32, + # uint64, +) +_numeric_dtypes = ( + float32, + float64, + int8, + int16, + int32, + int64, + uint8, + # uint16, + # uint32, + # uint64, +) + +_dtype_categories = { + "all": _all_dtypes, + "numeric": _numeric_dtypes, + "integer": _integer_dtypes, + "integer or boolean": _integer_or_boolean_dtypes, + "boolean": _boolean_dtypes, + "floating-point": _floating_dtypes, +} + +_promotion_table = { + (int8, int8): int8, + (int8, int16): int16, + (int8, int32): int32, + (int8, int64): int64, + (int16, int8): int16, + (int16, int16): int16, + (int16, int32): int32, + (int16, int64): int64, + (int32, int8): int32, + (int32, int16): int32, + (int32, int32): int32, + (int32, int64): int64, + (int64, int8): int64, + (int64, int16): int64, + (int64, int32): int64, + (int64, int64): int64, + (uint8, uint8): uint8, + # (uint8, uint16): uint16, + # (uint8, uint32): uint32, + # (uint8, uint64): uint64, + # (uint16, uint8): uint16, + # (uint16, uint16): uint16, + # (uint16, uint32): uint32, + # (uint16, uint64): uint64, + # (uint32, uint8): uint32, + # (uint32, uint16): uint32, + # (uint32, uint32): uint32, + # (uint32, uint64): uint64, + # (uint64, uint8): uint64, + # (uint64, uint16): uint64, + # (uint64, uint32): uint64, + # (uint64, uint64): uint64, + (int8, uint8): int16, + # (int8, uint16): int32, + # (int8, uint32): int64, + (int16, uint8): int16, + # (int16, uint16): int32, + # (int16, uint32): int64, + (int32, uint8): int32, + # (int32, uint16): int32, + # (int32, uint32): int64, + (int64, uint8): int64, + # (int64, uint16): int64, + # (int64, uint32): int64, + (uint8, int8): int16, + # (uint16, int8): int32, + # (uint32, int8): int64, + (uint8, int16): int16, + # (uint16, int16): int32, + # (uint32, int16): int64, + (uint8, int32): int32, + # (uint16, int32): int32, + # (uint32, int32): int64, + (uint8, int64): int64, + # (uint16, int64): int64, + # (uint32, int64): int64, + (float32, float32): float32, + (float32, float64): float64, + (float64, float32): float64, + (float64, float64): float64, + (bool, bool): bool, +} + + +def _result_type(type1, type2): + if (type1, type2) in _promotion_table: + return _promotion_table[type1, type2] + raise TypeError(f"{type1} and {type2} cannot be type promoted together") diff --git a/heat/array_api/_typing.py b/heat/array_api/_typing.py new file mode 100644 index 0000000000..81886bfc1c --- /dev/null +++ b/heat/array_api/_typing.py @@ -0,0 +1,28 @@ +from typing import Union +from ._dtypes import ( + int8, + int16, + int32, + int64, + uint8, + # uint16, + # uint32, + # uint64, + float32, + float64, + bool, +) + +Dtype = Union[ + int8, + int16, + int32, + int64, + uint8, + # uint16, + # uint32, + # uint64, + float32, + float64, + bool, +] From ec0ebdccffb8024c1ced1499a36c778c6cf3a33b Mon Sep 17 00:00:00 2001 From: neosunhan Date: Tue, 14 Jun 2022 21:13:44 +0800 Subject: [PATCH 002/150] Enable `copy` parameter for `asarray` --- heat/core/factories.py | 6 +++++- heat/core/tests/test_factories.py | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/heat/core/factories.py b/heat/core/factories.py index 50a55a0613..a636c68023 100644 --- a/heat/core/factories.py +++ b/heat/core/factories.py @@ -434,6 +434,7 @@ def array( def asarray( obj: Iterable, dtype: Optional[Type[datatype]] = None, + copy: bool = False, order: str = "C", is_split: Optional[bool] = None, device: Optional[Union[str, Device]] = None, @@ -449,6 +450,9 @@ def asarray( tuples of tuples, tuples of lists and ndarrays. dtype : dtype, optional By default, the data-type is inferred from the input data. + copy : bool, optional + If ``True``, then the object is copied. Otherwise, a copy will only be made if `obj` is a nested + sequence or if a copy is needed to satisfy any of the other requirements, e.g. ``dtype``. order: str, optional Whether to use row-major (C-style) or column-major (Fortran-style) memory representation. Defaults to ā€˜Cā€™. is_split : None or int, optional @@ -482,7 +486,7 @@ def asarray( >>> ht.asarray(a, dtype=ht.float64) is a False """ - return array(obj, dtype=dtype, copy=False, order=order, is_split=is_split, device=device) + return array(obj, dtype=dtype, copy=copy, order=order, is_split=is_split, device=device) def empty( diff --git a/heat/core/tests/test_factories.py b/heat/core/tests/test_factories.py index c996c06232..91d566aef7 100644 --- a/heat/core/tests/test_factories.py +++ b/heat/core/tests/test_factories.py @@ -312,6 +312,7 @@ def test_asarray(self): # same heat array arr = ht.array([1, 2]) self.assertTrue(ht.asarray(arr) is arr) + self.assertFalse(ht.asarray(arr, copy=True) is arr) # from distributed python list arr = ht.array([1, 2, 3, 4, 5, 6], split=0) @@ -328,6 +329,7 @@ def test_asarray(self): asarr = ht.asarray(arr) self.assertTrue(np.alltrue(np.equal(asarr.numpy(), arr))) + self.assertFalse(ht.asarray(arr, copy=True).larray is arr) asarr[0] = 0 if asarr.device == ht.cpu: From 77813fc22b262a243138e61f75e5f03dcd49ed29 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Tue, 14 Jun 2022 22:15:57 +0800 Subject: [PATCH 003/150] Add `iinfo` and `finfo` --- heat/array_api/__init__.py | 12 ++++++ heat/array_api/_data_type_functions.py | 52 ++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 heat/array_api/_data_type_functions.py diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index be9cb06355..c9db1392f8 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -7,6 +7,18 @@ __all__ = [] +from ._creation_functions import asarray, zeros + +__all__ += ["asarray", "zeros"] + +from ._data_type_functions import finfo, iinfo + +__all__ += ["finfo", "iinfo"] + +from ._constants import e, inf, nan, newaxis, pi + +__all__ += ["e", "inf", "nan", "newaxis", "pi"] + from ._dtypes import ( int8, int16, diff --git a/heat/array_api/_data_type_functions.py b/heat/array_api/_data_type_functions.py new file mode 100644 index 0000000000..6e0e46f7ad --- /dev/null +++ b/heat/array_api/_data_type_functions.py @@ -0,0 +1,52 @@ +import heat as ht + +from dataclasses import dataclass +from typing import Union + +from ._typing import Array, Dtype + + +@dataclass +class finfo_object: + """ + Internal object for return type of finfo. + """ + + bits: int + eps: float + max: float + min: float + smallest_normal: float + + +@dataclass +class iinfo_object: + """ + Internal object for return type of iinfo. + """ + + bits: int + max: int + min: int + + +def finfo(type: Union[Dtype, Array], /) -> finfo_object: + """ + Array API compatible wrapper for `ht.finfo`. + """ + fi = ht.finfo(type) + return finfo_object( + fi.bits, + fi.eps, + fi.max, + fi.min, + fi.tiny, + ) + + +def iinfo(type: Union[Dtype, Array], /) -> iinfo_object: + """ + Array API compatible wrapper for :`ht.iinfo`. + """ + ii = ht.iinfo(type) + return iinfo_object(ii.bits, int(ii.max), int(ii.min)) From 38461c764db8677658aa416d7255e3250fe1178f Mon Sep 17 00:00:00 2001 From: neosunhan Date: Wed, 15 Jun 2022 09:42:18 +0800 Subject: [PATCH 004/150] Add constants --- heat/array_api/_constants.py | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 heat/array_api/_constants.py diff --git a/heat/array_api/_constants.py b/heat/array_api/_constants.py new file mode 100644 index 0000000000..1c3636a0ed --- /dev/null +++ b/heat/array_api/_constants.py @@ -0,0 +1,7 @@ +from heat.core.constants import E, INF, NAN, PI + +e = E +inf = INF +nan = NAN +newaxis = None +pi = PI From ae1defbb22a5c1649ed9ae1d465965f1c3bbebc3 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Wed, 15 Jun 2022 13:15:33 +0800 Subject: [PATCH 005/150] Modify `iinfo` and `finfo` to read minimum value from torch object This fixes a bug where negative numbers could be represented by uint8. --- heat/core/tests/test_types.py | 2 ++ heat/core/types.py | 8 ++------ 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/heat/core/tests/test_types.py b/heat/core/tests/test_types.py index 91676650f8..0ae87d9073 100644 --- a/heat/core/tests/test_types.py +++ b/heat/core/tests/test_types.py @@ -376,6 +376,8 @@ def test_iinfo(self): self.assertEqual(info32.max, 2147483647) self.assertEqual(info32.min, -2147483648) + self.assertEqual(ht.iinfo(ht.uint8).min, 0) + with self.assertRaises(TypeError): ht.iinfo(1.0) diff --git a/heat/core/types.py b/heat/core/types.py index 7af5994f67..3e4bb1ce0c 100644 --- a/heat/core/types.py +++ b/heat/core/types.py @@ -996,11 +996,9 @@ def __new__(cls, dtype: Type[datatype]): def _init(self, dtype: Type[datatype]): _torch_finfo = torch.finfo(dtype.torch_type()) - for word in ["bits", "eps", "max", "tiny"]: + for word in ["bits", "eps", "max", "min", "tiny"]: setattr(self, word, getattr(_torch_finfo, word)) - self.min = -self.max - return self @@ -1044,11 +1042,9 @@ def __new__(cls, dtype: Type[datatype]): def _init(self, dtype: Type[datatype]): _torch_iinfo = torch.iinfo(dtype.torch_type()) - for word in ["bits", "max"]: + for word in ["bits", "max", "min"]: setattr(self, word, getattr(_torch_iinfo, word)) - self.min = -(self.max + 1) - return self From 313d22d0ef0eee2e2bb249cd1258f6a208e06822 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Wed, 15 Jun 2022 13:45:00 +0800 Subject: [PATCH 006/150] Add docstrings --- heat/array_api/__init__.py | 24 +++-- heat/array_api/_array_object.py | 114 ++++++++++++++++++++-- heat/array_api/_creation_functions.py | 105 ++++++++++++++++++++ heat/array_api/_data_type_functions.py | 9 +- heat/array_api/_dtypes.py | 1 + heat/array_api/_elementwise_functions.py | 48 +++++++++ heat/array_api/_manipulation_functions.py | 11 +++ heat/array_api/_utility_functions.py | 21 ++++ 8 files changed, 314 insertions(+), 19 deletions(-) create mode 100644 heat/array_api/_creation_functions.py create mode 100644 heat/array_api/_elementwise_functions.py create mode 100644 heat/array_api/_manipulation_functions.py create mode 100644 heat/array_api/_utility_functions.py diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index c9db1392f8..daf3de79ad 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -7,17 +7,17 @@ __all__ = [] -from ._creation_functions import asarray, zeros +from ._constants import e, inf, nan, newaxis, pi -__all__ += ["asarray", "zeros"] +__all__ += ["e", "inf", "nan", "newaxis", "pi"] -from ._data_type_functions import finfo, iinfo +from ._creation_functions import asarray, full, zeros -__all__ += ["finfo", "iinfo"] +__all__ += ["asarray", "full", "zeros"] -from ._constants import e, inf, nan, newaxis, pi +from ._data_type_functions import finfo, iinfo -__all__ += ["e", "inf", "nan", "newaxis", "pi"] +__all__ += ["finfo", "iinfo"] from ._dtypes import ( int8, @@ -46,3 +46,15 @@ "float64", "bool", ] + +from ._elementwise_functions import equal, isfinite, isinf, isnan + +__all__ += ["equal", "isfinite", "isinf", "isnan"] + +from ._manipulation_functions import reshape + +__all__ += ["reshape"] + +from ._utility_functions import all + +__all__ += ["all"] diff --git a/heat/array_api/_array_object.py b/heat/array_api/_array_object.py index cd92933796..aaaaba82de 100644 --- a/heat/array_api/_array_object.py +++ b/heat/array_api/_array_object.py @@ -1,5 +1,10 @@ from __future__ import annotations +import heat as ht + +from typing import TYPE_CHECKING, Any, Tuple, Union, Optional + +from ._creation_functions import asarray from ._dtypes import ( _all_dtypes, _boolean_dtypes, @@ -10,13 +15,13 @@ _result_type, _dtype_categories, ) -from ._typing import Dtype -import heat as ht +if TYPE_CHECKING: + from ._typing import Dtype, Device + from builtins import ellipsis + from heat import array_api -from heat.core.devices import Device from heat.core.dndarray import DNDarray -from typing import Any, Tuple, Union, Optional class Array: @@ -53,6 +58,18 @@ def __new__(cls, *args, **kwargs): "The array_api Array object should not be instantiated directly. Use an array creation function, such as asarray(), instead." ) + def __str__(self: Array, /) -> str: + """ + Computes a printable representation of the Array. + """ + return self._array.__str__().replace("DNDarray", "Array") + + def __repr__(self: Array, /) -> str: + """ + Computes a printable representation of the Array. + """ + return self._array.__str__().replace("DNDarray", "Array") + def _check_allowed_dtypes( self, other: Union[bool, int, float, Array], dtype_category: str, op: str ) -> Array: @@ -72,6 +89,7 @@ def _check_allowed_dtypes( raise TypeError(f"Only {dtype_category} dtypes are allowed in {op}") else: return NotImplemented + _result_type(self.dtype, other.dtype) return other def _promote_scalar(self, scalar): @@ -136,42 +154,118 @@ def __and__(self: Array, other: Union[int, bool, Array], /) -> Array: return self.__class__._new(res) def __array_namespace__(self: Array, /, *, api_version: Optional[str] = None) -> Any: + """ + Returns an object that has all the array API functions on it. + """ if api_version is not None and api_version != "2021.12": raise ValueError(f"Unrecognized array API version: {api_version}") return array_api + def __bool__(self: Array, /) -> bool: + """ + Converts a zero-dimensional boolean array to a Python `bool` object. + """ + if self._array.ndim != 0: + raise TypeError("bool is only allowed on arrays with 0 dimensions") + if self.dtype not in _boolean_dtypes: + raise ValueError("bool is only allowed on boolean arrays") + res = self._array.__bool__() + return res + + def __float__(self: Array, /) -> float: + """ + Converts a zero-dimensional floating-point array to a Python `float` object. + """ + if self._array.ndim != 0: + raise TypeError("float is only allowed on arrays with 0 dimensions") + if self.dtype not in _floating_dtypes: + raise ValueError("float is only allowed on floating-point arrays") + res = self._array.__float__() + return res + + def __getitem__( + self: Array, + key: Union[int, slice, ellipsis, Tuple[Union[int, slice, ellipsis], ...], Array], + /, + ) -> Array: + """ + Returns `self[key]`. + """ + # Note: Only indices required by the spec are allowed. See the + # docstring of _validate_index + # self._validate_index(key) + if isinstance(key, Array): + # Indexing self._array with array_api arrays can be erroneous + key = key._array + res = self._array.__getitem__(key) + return self._new(res) + + # def __index__(self: Array, /) -> int: + # """ + # Performs the operation __index__. + # """ + # res = self.__int__() + # return res + + def __int__(self: Array, /) -> int: + """ + Converts a zero-dimensional integer array to a Python `int` object. + """ + if self._array.ndim != 0: + raise TypeError("int is only allowed on arrays with 0 dimensions") + if self.dtype not in _integer_dtypes: + raise ValueError("int is only allowed on integer arrays") + res = self._array.__int__() + return res + + def __setitem__( + self, + key: Union[int, slice, ellipsis, Tuple[Union[int, slice, ellipsis], ...], Array], + value: Union[int, float, bool, Array], + /, + ) -> None: + """ + Sets `self[key]` to `value`. + """ + # Note: Only indices required by the spec are allowed. See the + # docstring of _validate_index + # self._validate_index(key) + if isinstance(key, Array): + # Indexing self._array with array_api arrays can be erroneous + key = key._array + self._array.__setitem__(key, asarray(value)._array) + @property def dtype(self) -> Dtype: """ - Array API compatible wrapper for `heat.DNDarray.dtype`. + Data type of the array elements. """ return self._array.dtype @property def device(self) -> Device: """ - Array API compatible wrapper for `heat.DNDarray.device`. + Hardware device the array data resides on. """ return self._array.device @property def ndim(self) -> int: """ - Array API compatible wrapper for `heat.DNDarray.ndim`. - See its docstring for more information. + Number of array dimensions (axes). """ return self._array.ndim @property def shape(self) -> Tuple[Optional[int], ...]: """ - Array API compatible wrapper for `heat.DNDarray.shape`. + Array dimensions. """ return self._array.shape @property def size(self) -> Optional[int]: """ - Array API compatible wrapper for `heat.DNDarray.size`. + Number of elements in an array. """ return self._array.size diff --git a/heat/array_api/_creation_functions.py b/heat/array_api/_creation_functions.py new file mode 100644 index 0000000000..00d622153b --- /dev/null +++ b/heat/array_api/_creation_functions.py @@ -0,0 +1,105 @@ +from __future__ import annotations + +import heat as ht +from typing import TYPE_CHECKING, Union, Optional, Tuple + +from ._dtypes import _all_dtypes, default_float + +if TYPE_CHECKING: + from ._typing import Array, Dtype, Device, NestedSequence, SupportsBufferProtocol + + +def _check_valid_dtype(dtype): + # Note: Only spelling dtypes as the dtype objects is supported. + + # We use this instead of "dtype in _all_dtypes" because the dtype objects + # define equality with the sorts of things we want to disallow. + for d in (None,) + _all_dtypes: + if dtype is d: + return + raise ValueError(f"{dtype} is not supported") + + +def asarray( + obj: Union[ + Array, + bool, + int, + float, + NestedSequence[bool | int | float], + SupportsBufferProtocol, + ], + /, + *, + dtype: Optional[Dtype] = None, + device: Optional[Device] = None, + copy: Optional[bool] = None, +) -> Array: + """ + Convert the input to an array. + """ + # _array_object imports in this file are inside the functions to avoid + # circular imports + from ._array_object import Array + + # _check_valid_dtype(dtype) + # if device not in ["cpu", None]: + # raise ValueError(f"Unsupported device {device!r}") + if isinstance(obj, Array): + if dtype is not None and obj.dtype != dtype: + copy = True + # if copy: + # return Array._new(np.array(obj._array, copy=True, dtype=dtype)) + if not copy: + return obj + if dtype is None and isinstance(obj, int) and (obj > 2**64 or obj < -(2**63)): + # TODO: This won't handle large integers in lists. + raise OverflowError("Integer out of bounds for array dtypes") + res = ht.asarray(obj, dtype=dtype, copy=copy, device=device) + return Array._new(res) + + +def full( + shape: Union[int, Tuple[int, ...]], + fill_value: Union[int, float], + *, + dtype: Optional[Dtype] = None, + device: Optional[Device] = None, +) -> Array: + """ + Returns a new array having a specified `shape` and filled with `fill_value`. + """ + from ._array_object import Array + + # _check_valid_dtype(dtype) + # if device not in ["cpu", None]: + # raise ValueError(f"Unsupported device {device!r}") + if isinstance(fill_value, Array) and fill_value.ndim == 0: + fill_value = fill_value._array + if dtype is None: + dtype = default_float + res = ht.full(shape, fill_value, dtype=dtype, device=device) + # if res.dtype not in _all_dtypes: + # # This will happen if the fill value is not something that NumPy + # # coerces to one of the acceptable dtypes. + # raise TypeError("Invalid input to full") + return Array._new(res) + + +def zeros( + shape: Union[int, Tuple[int, ...]], + *, + dtype: Optional[Dtype] = None, + device: Optional[Device] = None, +) -> Array: + """ + Returns a new array having a specified `shape` and filled with zeros. + """ + from ._array_object import Array + + # _check_valid_dtype(dtype) + # if device not in ["cpu", None]: + # raise ValueError(f"Unsupported device {device!r}") + if dtype is None: + dtype = default_float + return Array._new(ht.zeros(shape, dtype=dtype, device=device)) diff --git a/heat/array_api/_data_type_functions.py b/heat/array_api/_data_type_functions.py index 6e0e46f7ad..de4be17411 100644 --- a/heat/array_api/_data_type_functions.py +++ b/heat/array_api/_data_type_functions.py @@ -1,9 +1,12 @@ +from __future__ import annotations + import heat as ht from dataclasses import dataclass from typing import Union -from ._typing import Array, Dtype +from ._array_object import Array +from ._typing import Dtype @dataclass @@ -32,7 +35,7 @@ class iinfo_object: def finfo(type: Union[Dtype, Array], /) -> finfo_object: """ - Array API compatible wrapper for `ht.finfo`. + Machine limits for floating-point data types. """ fi = ht.finfo(type) return finfo_object( @@ -46,7 +49,7 @@ def finfo(type: Union[Dtype, Array], /) -> finfo_object: def iinfo(type: Union[Dtype, Array], /) -> iinfo_object: """ - Array API compatible wrapper for :`ht.iinfo`. + Machine limits for integer data types. """ ii = ht.iinfo(type) return iinfo_object(ii.bits, int(ii.max), int(ii.min)) diff --git a/heat/array_api/_dtypes.py b/heat/array_api/_dtypes.py index 58239a46c1..cb7eebeaf1 100644 --- a/heat/array_api/_dtypes.py +++ b/heat/array_api/_dtypes.py @@ -11,6 +11,7 @@ float32 = ht.float32 float64 = ht.float64 bool = ht.bool +default_float = float32 _all_dtypes = ( int8, diff --git a/heat/array_api/_elementwise_functions.py b/heat/array_api/_elementwise_functions.py new file mode 100644 index 0000000000..3c55249ec7 --- /dev/null +++ b/heat/array_api/_elementwise_functions.py @@ -0,0 +1,48 @@ +from __future__ import annotations + +import heat as ht + +from ._array_object import Array +from ._dtypes import _numeric_dtypes, _result_type + + +def equal(x1: Array, x2: Array, /) -> Array: + """ + Computes the truth value of `x1_i == x2_i` for each element `x1_i` of + the input array `x1` with the respective element `x2_i` of the input + array `x2`. + """ + # Call result type here just to raise on disallowed type combinations + # _result_type(x1.dtype, x2.dtype) + # x1, x2 = Array._normalize_two_args(x1, x2) + return Array._new(ht.eq(x1._array, x2._array)) + + +def isfinite(x: Array, /) -> Array: + """ + Tests each element `x_i` of the input array `x` to determine if finite + (i.e., not `NaN` and not equal to positive or negative infinity). + """ + if x.dtype not in _numeric_dtypes: + raise TypeError("Only numeric dtypes are allowed in isfinite") + return Array._new(ht.isfinite(x._array)) + + +def isinf(x: Array, /) -> Array: + """ + Tests each element `x_i` of the input array `x` to determine if equal + to positive or negative infinity. + """ + if x.dtype not in _numeric_dtypes: + raise TypeError("Only numeric dtypes are allowed in isinf") + return Array._new(ht.isinf(x._array)) + + +def isnan(x: Array, /) -> Array: + """ + Tests each element `x_i` of the input array `x` to determine whether + the element is `NaN`. + """ + if x.dtype not in _numeric_dtypes: + raise TypeError("Only numeric dtypes are allowed in isnan") + return Array._new(ht.isnan(x._array)) diff --git a/heat/array_api/_manipulation_functions.py b/heat/array_api/_manipulation_functions.py new file mode 100644 index 0000000000..2bf9d450d6 --- /dev/null +++ b/heat/array_api/_manipulation_functions.py @@ -0,0 +1,11 @@ +import heat as ht +from typing import Tuple, Optional + +from ._array_object import Array + + +def reshape(x: Array, /, shape: Tuple[int, ...], *, copy: Optional[bool] = None) -> Array: + """ + Reshapes an array without changing its data. + """ + return Array._new(ht.reshape(x._array, shape)) diff --git a/heat/array_api/_utility_functions.py b/heat/array_api/_utility_functions.py new file mode 100644 index 0000000000..bc1983f5f1 --- /dev/null +++ b/heat/array_api/_utility_functions.py @@ -0,0 +1,21 @@ +import heat as ht +from typing import Optional, Tuple, Union + +from ._array_object import Array + + +def all( + x: Array, + /, + *, + axis: Optional[Union[int, Tuple[int, ...]]] = None, + keepdims: bool = False, +) -> Array: + """ + Tests whether all input array elements evaluate to `True` along a specified axis. + """ + singleton = x._array.shape == () or (1,) + res = ht.all(x._array, axis=axis, keepdim=keepdims) + if singleton: + res = ht.squeeze(res) + return Array._new(res) From 136e1b772890fa3bedd6c362c156ae157b504a68 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Thu, 16 Jun 2022 00:04:47 +0800 Subject: [PATCH 007/150] Fix bug where `keepdim` was not working for `all` --- heat/core/logical.py | 3 +++ heat/core/tests/test_logical.py | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/heat/core/logical.py b/heat/core/logical.py index 9b4dcc8f79..c26f46f138 100644 --- a/heat/core/logical.py +++ b/heat/core/logical.py @@ -91,6 +91,9 @@ def all( def local_all(t, *args, **kwargs): return torch.all(t != 0, *args, **kwargs) + if keepdim and axis is None: + axis = tuple(range(x.ndim)) + return _operations.__reduce_op( x, local_all, MPI.LAND, axis=axis, out=out, neutral=1, keepdim=keepdim ) diff --git a/heat/core/tests/test_logical.py b/heat/core/tests/test_logical.py index a995d53db3..dc318b40c2 100644 --- a/heat/core/tests/test_logical.py +++ b/heat/core/tests/test_logical.py @@ -140,6 +140,10 @@ def test_all(self): out_noaxis = ht.zeros((1, 2, 3, 5), split=1) ht.all(ones_noaxis_split_axis_neg, axis=-2, out=out_noaxis) + # test keepdim + ones_2d = ht.ones((1, 1)) + self.assertEqual(ones_2d.all(keepdim=True).shape, ones_2d.shape) + # exceptions with self.assertRaises(ValueError): ht.ones(array_len).all(axis=1) From 9c6b34490dcc87b78da8a91d971b4d7177cf433f Mon Sep 17 00:00:00 2001 From: neosunhan Date: Thu, 16 Jun 2022 10:07:38 +0800 Subject: [PATCH 008/150] Implement `all` --- heat/array_api/_creation_functions.py | 9 ++++++--- heat/array_api/_dtypes.py | 2 +- heat/array_api/_utility_functions.py | 8 ++++---- heat/core/factories.py | 8 ++++++-- 4 files changed, 17 insertions(+), 10 deletions(-) diff --git a/heat/array_api/_creation_functions.py b/heat/array_api/_creation_functions.py index 00d622153b..7524fb7c88 100644 --- a/heat/array_api/_creation_functions.py +++ b/heat/array_api/_creation_functions.py @@ -52,9 +52,12 @@ def asarray( # return Array._new(np.array(obj._array, copy=True, dtype=dtype)) if not copy: return obj - if dtype is None and isinstance(obj, int) and (obj > 2**64 or obj < -(2**63)): - # TODO: This won't handle large integers in lists. - raise OverflowError("Integer out of bounds for array dtypes") + if dtype is None: + if isinstance(obj, int) and (obj > 2**64 or obj < -(2**63)): + # TODO: This won't handle large integers in lists. + raise OverflowError("Integer out of bounds for array dtypes") + elif isinstance(obj, float): + dtype = default_float res = ht.asarray(obj, dtype=dtype, copy=copy, device=device) return Array._new(res) diff --git a/heat/array_api/_dtypes.py b/heat/array_api/_dtypes.py index cb7eebeaf1..9d7c44f57d 100644 --- a/heat/array_api/_dtypes.py +++ b/heat/array_api/_dtypes.py @@ -11,7 +11,7 @@ float32 = ht.float32 float64 = ht.float64 bool = ht.bool -default_float = float32 +default_float = float64 _all_dtypes = ( int8, diff --git a/heat/array_api/_utility_functions.py b/heat/array_api/_utility_functions.py index bc1983f5f1..0cd37e4a02 100644 --- a/heat/array_api/_utility_functions.py +++ b/heat/array_api/_utility_functions.py @@ -14,8 +14,8 @@ def all( """ Tests whether all input array elements evaluate to `True` along a specified axis. """ - singleton = x._array.shape == () or (1,) - res = ht.all(x._array, axis=axis, keepdim=keepdims) - if singleton: - res = ht.squeeze(res) + res = ht.all(x._array, axis=axis, keepdim=True) + if not keepdims or x._array.ndim == 0: + res = ht.squeeze(res, axis=axis) + return Array._new(res) diff --git a/heat/core/factories.py b/heat/core/factories.py index a636c68023..53d90794fb 100644 --- a/heat/core/factories.py +++ b/heat/core/factories.py @@ -299,8 +299,11 @@ def array( obj = obj.larray # sanitize the data type - if dtype is not None: + if dtype is None: + torch_dtype = None + else: dtype = types.canonical_heat_type(dtype) + torch_dtype = dtype.torch_type() # sanitize device if device is not None: @@ -316,6 +319,7 @@ def array( try: obj = torch.tensor( obj, + dtype=torch_dtype, device=device.torch_device if device is not None else devices.get_device().torch_device, @@ -326,6 +330,7 @@ def array( if not isinstance(obj, DNDarray): obj = torch.as_tensor( obj, + dtype=torch_dtype, device=device.torch_device if device is not None else devices.get_device().torch_device, @@ -335,7 +340,6 @@ def array( if dtype is None: dtype = types.canonical_heat_type(obj.dtype) else: - torch_dtype = dtype.torch_type() if obj.dtype != torch_dtype: obj = obj.type(torch_dtype) From ab30f5682e14648f76f92f348d71e5293777507d Mon Sep 17 00:00:00 2001 From: neosunhan Date: Thu, 16 Jun 2022 10:15:42 +0800 Subject: [PATCH 009/150] Implement `Array.__eq__` --- heat/array_api/_array_object.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/heat/array_api/_array_object.py b/heat/array_api/_array_object.py index aaaaba82de..9f37796949 100644 --- a/heat/array_api/_array_object.py +++ b/heat/array_api/_array_object.py @@ -172,6 +172,20 @@ def __bool__(self: Array, /) -> bool: res = self._array.__bool__() return res + def __eq__(self: Array, other: Union[int, float, bool, Array], /) -> Array: + """ + Computes the truth value of `self_i == other_i` for each element of an + array instance with the respective element of the array `other`. + """ + # Even though "all" dtypes are allowed, we still require them to be + # promotable with each other. + other = self._check_allowed_dtypes(other, "all", "__eq__") + if other is NotImplemented: + return other + # self, other = self._normalize_two_args(self, other) + res = self._array.__eq__(other._array) + return self.__class__._new(res) + def __float__(self: Array, /) -> float: """ Converts a zero-dimensional floating-point array to a Python `float` object. From 198a38e3251fa635d6377b6ab1b5eebed45e045a Mon Sep 17 00:00:00 2001 From: neosunhan Date: Thu, 16 Jun 2022 10:25:59 +0800 Subject: [PATCH 010/150] Implement `astype` --- heat/array_api/__init__.py | 4 ++-- heat/array_api/_data_type_functions.py | 9 +++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index daf3de79ad..c15eabf351 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -15,9 +15,9 @@ __all__ += ["asarray", "full", "zeros"] -from ._data_type_functions import finfo, iinfo +from ._data_type_functions import astype, finfo, iinfo -__all__ += ["finfo", "iinfo"] +__all__ += ["astype", "finfo", "iinfo"] from ._dtypes import ( int8, diff --git a/heat/array_api/_data_type_functions.py b/heat/array_api/_data_type_functions.py index de4be17411..61513d28fd 100644 --- a/heat/array_api/_data_type_functions.py +++ b/heat/array_api/_data_type_functions.py @@ -9,6 +9,15 @@ from ._typing import Dtype +def astype(x: Array, dtype: Dtype, /, *, copy: bool = True) -> Array: + """ + Copies an array to a specified data type irrespective of Type Promotion Rules. + """ + if not copy and dtype == x.dtype: + return x + return Array._new(x._array.astype(dtype=dtype)) + + @dataclass class finfo_object: """ From 2e8cfc3dd40fcfd543cddbcfc3860d902eaf7451 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Fri, 17 Jun 2022 12:57:56 +0800 Subject: [PATCH 011/150] Implement `Array` object --- heat/array_api/_array_object.py | 401 +++++++++++++++++++++++++- heat/array_api/_creation_functions.py | 8 +- heat/array_api/_dtypes.py | 1 + heat/array_api/_typing.py | 2 + 4 files changed, 399 insertions(+), 13 deletions(-) diff --git a/heat/array_api/_array_object.py b/heat/array_api/_array_object.py index 9f37796949..bc8ab4d5a7 100644 --- a/heat/array_api/_array_object.py +++ b/heat/array_api/_array_object.py @@ -38,13 +38,18 @@ class Array: _array: DNDarray @classmethod - def _new(cls, x, /): + def _new(cls, x: DNDarray, /): """ This is a private method for initializing the array API Array object. Functions outside of the array_api submodule should not use this method. Use one of the creation functions instead, such as `asarray`. + + Parameters + ---------- + x : DNDarray + Underlying `DNDarray` """ obj = super().__new__(cls) obj._array = x @@ -128,34 +133,52 @@ def __abs__(self: Array, /) -> Array: """ if self.dtype not in _numeric_dtypes: raise TypeError("Only numeric dtypes are allowed in __abs__") - res = ht.abs(self._array) + res = self._array.abs(dtype=self.dtype) return self.__class__._new(res) def __add__(self: Array, other: Union[int, float, Array], /) -> Array: """ Calculates the sum for each element of an array instance with the respective element of the array `other`. + + Parameters + ---------- + other : Union[int, float, Array] + Addend array. Must have a numeric data type. """ other = self._check_allowed_dtypes(other, "numeric", "__add__") if other is NotImplemented: return other - res = ht.add(self._array, other._array) + res = self._array.__add__(other._array) return self.__class__._new(res) def __and__(self: Array, other: Union[int, bool, Array], /) -> Array: """ Evaluates `self_i & other_i` for each element of an array instance with the respective element of the array `other`. + + Parameters + ---------- + other : Union[int, bool, Array] + Other array. Must have an integer or boolean data type. """ other = self._check_allowed_dtypes(other, "integer or boolean", "__and__") if other is NotImplemented: return other - res = ht.bitwise_and(self._array, other._array) + res = self._array.__and__(other._array) return self.__class__._new(res) def __array_namespace__(self: Array, /, *, api_version: Optional[str] = None) -> Any: """ Returns an object that has all the array API functions on it. + + Parameters + ---------- + api_version : Optional[str] + string representing the version of the array API specification to + be returned, in `'YYYY.MM'` form. If it is `None` (default), it + returns the namespace corresponding to latest version of the + array API specification. """ if api_version is not None and api_version != "2021.12": raise ValueError(f"Unrecognized array API version: {api_version}") @@ -176,6 +199,11 @@ def __eq__(self: Array, other: Union[int, float, bool, Array], /) -> Array: """ Computes the truth value of `self_i == other_i` for each element of an array instance with the respective element of the array `other`. + + Parameters + ---------- + other : Union[int, float, bool, Array] + Other array. """ # Even though "all" dtypes are allowed, we still require them to be # promotable with each other. @@ -197,6 +225,40 @@ def __float__(self: Array, /) -> float: res = self._array.__float__() return res + def __floordiv__(self: Array, other: Union[int, float, Array], /) -> Array: + """ + Evaluates `self_i // other_i` for each element of an array instance + with the respective element of the array `other`. + + Parameters + ---------- + other : Union[int, float, Array] + Other array. Must have a numeric data type. + """ + other = self._check_allowed_dtypes(other, "numeric", "__floordiv__") + if other is NotImplemented: + return other + # self, other = self._normalize_two_args(self, other) + res = self._array.__floordiv__(other._array) + return self.__class__._new(res) + + def __ge__(self: Array, other: Union[int, float, Array], /) -> Array: + """ + Computes the truth value of `self_i >= other_i` for each element of + an array instance with the respective element of the array `other`. + + Parameters + ---------- + other : Union[int, float, Array] + Other array. Must have a numeric data type. + """ + other = self._check_allowed_dtypes(other, "numeric", "__ge__") + if other is NotImplemented: + return other + # self, other = self._normalize_two_args(self, other) + res = self._array.__ge__(other._array) + return self.__class__._new(res) + def __getitem__( self: Array, key: Union[int, slice, ellipsis, Tuple[Union[int, slice, ellipsis], ...], Array], @@ -204,6 +266,11 @@ def __getitem__( ) -> Array: """ Returns `self[key]`. + + Parameters + ---------- + key : Union[int, slice, ellipsis, Tuple[Union[int, slice, ellipsis], ...], array] + Index key """ # Note: Only indices required by the spec are allowed. See the # docstring of _validate_index @@ -211,15 +278,38 @@ def __getitem__( if isinstance(key, Array): # Indexing self._array with array_api arrays can be erroneous key = key._array + # if 0 in self.shape: + # new_array = self._array + # if isinstance(key, tuple): + # for i, index in enumerate((x for x in key if x != ...)): + # if index is None: + # new_array = new_array.expand_dims(i) + # return self._new(new_array) res = self._array.__getitem__(key) return self._new(res) - # def __index__(self: Array, /) -> int: - # """ - # Performs the operation __index__. - # """ - # res = self.__int__() - # return res + def __gt__(self: Array, other: Union[int, float, Array], /) -> Array: + """ + Computes the truth value of `self_i > other_i` for each element + of an array instance with the respective element of the array `other`. + + Parameters + ---------- + other : Union[int, float, Array] + Other array. Must have a numeric data type. + """ + other = self._check_allowed_dtypes(other, "numeric", "__gt__") + if other is NotImplemented: + return other + # self, other = self._normalize_two_args(self, other) + res = self._array.__gt__(other._array) + return self.__class__._new(res) + + def __index__(self: Array, /) -> int: + """ + Converts a zero-dimensional integer array to a Python `int` object. + """ + return self.__int__() def __int__(self: Array, /) -> int: """ @@ -232,6 +322,208 @@ def __int__(self: Array, /) -> int: res = self._array.__int__() return res + def __invert__(self: Array, /) -> Array: + """ + Evaluates `~self_i` for each element of an array instance. + """ + if self.dtype not in _integer_or_boolean_dtypes: + raise TypeError("Only integer or boolean dtypes are allowed in __invert__") + res = self._array.__invert__() + return self.__class__._new(res) + + def __le__(self: Array, other: Union[int, float, Array], /) -> Array: + """ + Computes the truth value of `self_i <= other_i` for each element of an + array instance with the respective element of the array `other`. + + Parameters + ---------- + other : Union[int, float, Array] + Other array. Must have a numeric data type. + """ + other = self._check_allowed_dtypes(other, "numeric", "__le__") + if other is NotImplemented: + return other + # self, other = self._normalize_two_args(self, other) + res = self._array.__le__(other._array) + return self.__class__._new(res) + + def __lshift__(self: Array, other: Union[int, Array], /) -> Array: + """ + Evaluates `self_i << other_i` for each element of an array instance + with the respective element of the array `other`. + + Parameters + ---------- + other : Union[int, Array] + Other array. Must have an integer data type. Each element + must be greater than or equal to `0`. + """ + other = self._check_allowed_dtypes(other, "integer", "__lshift__") + if other is NotImplemented: + return other + # self, other = self._normalize_two_args(self, other) + res = self._array.__lshift__(other._array) + return self.__class__._new(res) + + def __lt__(self: Array, other: Union[int, float, Array], /) -> Array: + """ + Computes the truth value of `self_i < other_i` for each element + of an array instance with the respective element of the array `other`. + + Parameters + ---------- + other : Union[int, Array] + Other array. Must have a numeric data type. + """ + other = self._check_allowed_dtypes(other, "numeric", "__lt__") + if other is NotImplemented: + return other + # self, other = self._normalize_two_args(self, other) + res = self._array.__lt__(other._array) + return self.__class__._new(res) + + def __matmul__(self: Array, other: Array, /) -> Array: + """ + Computes the matrix product. + + Parameters + ---------- + other : Array + Other array. Must have a numeric data type and at least one dimension. + """ + other = self._check_allowed_dtypes(other, "numeric", "__matmul__") + if other is NotImplemented: + return other + res = self._array.__matmul__(other._array) + return self.__class__._new(res) + + def __mod__(self: Array, other: Union[int, float, Array], /) -> Array: + """ + Evaluates `self_i % other_i` for each element of an array instance + with the respective element of the array `other`. + + Parameters + ---------- + other : Union[int, float, array] + Other array. Must have a numeric data type. + """ + other = self._check_allowed_dtypes(other, "numeric", "__mod__") + if other is NotImplemented: + return other + # self, other = self._normalize_two_args(self, other) + res = self._array.__mod__(other._array) + return self.__class__._new(res) + + def __mul__(self: Array, other: Union[int, float, Array], /) -> Array: + """ + Calculates the product for each element of an array instance with + the respective element of the array `other`. + + Parameters + ---------- + other : Union[int, float, array] + Other array. Must have a numeric data type. + """ + other = self._check_allowed_dtypes(other, "numeric", "__mul__") + if other is NotImplemented: + return other + # self, other = self._normalize_two_args(self, other) + res = self._array.__mul__(other._array) + return self.__class__._new(res) + + def __ne__(self: Array, other: Union[int, float, bool, Array], /) -> Array: + """ + Computes the truth value of `self_i != other_i` for each element of + an array instance with the respective element of the array `other`. + + Parameters + ---------- + other : Union[int, float, bool, array] + Other array. + """ + other = self._check_allowed_dtypes(other, "all", "__ne__") + if other is NotImplemented: + return other + # self, other = self._normalize_two_args(self, other) + res = self._array.__ne__(other._array) + return self.__class__._new(res) + + def __neg__(self: Array, /) -> Array: + """ + Evaluates `-self_i` for each element of an array instance. + """ + if self.dtype not in _numeric_dtypes: + raise TypeError("Only numeric dtypes are allowed in __neg__") + res = self._array.__neg__() + return self.__class__._new(res) + + def __or__(self: Array, other: Union[int, bool, Array], /) -> Array: + """ + Evaluates `self_i | other_i` for each element of an array instance + with the respective element of the array `other`. + + Parameters + ---------- + other : Union[int, bool, array] + Other array. Must have an integer or boolean data type. + """ + other = self._check_allowed_dtypes(other, "integer or boolean", "__or__") + if other is NotImplemented: + return other + # self, other = self._normalize_two_args(self, other) + res = self._array.__or__(other._array) + return self.__class__._new(res) + + def __pos__(self: Array, /) -> Array: + """ + Evaluates `+self_i` for each element of an array instance. + """ + if self.dtype not in _numeric_dtypes: + raise TypeError("Only numeric dtypes are allowed in __pos__") + res = self._array.__pos__() + return self.__class__._new(res) + + def __pow__(self: Array, other: Union[int, float, Array], /) -> Array: + """ + Calculates an approximation of exponentiation by raising each element + (the base) of an array instance to the power of `other_i` (the exponent), + where `other_i` is the corresponding element of the array `other`. + + Parameters + ---------- + other : Union[int, float, array] + Other array. Must have a numeric data type. + """ + # from ._elementwise_functions import pow + + other = self._check_allowed_dtypes(other, "numeric", "__pow__") + if other is NotImplemented: + return other + # Note: NumPy's __pow__ does not follow type promotion rules for 0-d + # arrays, so we use pow() here instead. + # return pow(self, other) + res = self._array.__pow__() + return self.__class__._new(res) + + def __rshift__(self: Array, other: Union[int, Array], /) -> Array: + """ + Evaluates `self_i >> other_i` for each element of an array instance + with the respective element of the array `other`. + + Parameters + ---------- + other : Union[int, array] + Other array. Must have an integer data type. Each element must be + greater than or equal to `0`. + """ + other = self._check_allowed_dtypes(other, "integer", "__rshift__") + if other is NotImplemented: + return other + # self, other = self._normalize_two_args(self, other) + res = self._array.__rshift__(other._array) + return self.__class__._new(res) + def __setitem__( self, key: Union[int, slice, ellipsis, Tuple[Union[int, slice, ellipsis], ...], Array], @@ -247,7 +539,73 @@ def __setitem__( if isinstance(key, Array): # Indexing self._array with array_api arrays can be erroneous key = key._array - self._array.__setitem__(key, asarray(value)._array) + if isinstance(value, Array): + value = value._array + if self.ndim == 0 and key == ...: + self._array = ht.asarray(value) + else: + self._array.__setitem__(key, value) + + def __sub__(self: Array, other: Union[int, float, Array], /) -> Array: + """ + Calculates the difference for each element of an array instance + with the respective element of the array `other`. + + Parameters + ---------- + other : Union[int, float, array] + Subtrahend array. Must have a numeric data type. + """ + other = self._check_allowed_dtypes(other, "numeric", "__sub__") + if other is NotImplemented: + return other + # self, other = self._normalize_two_args(self, other) + res = self._array.__sub__(other._array) + return self.__class__._new(res) + + def __truediv__(self: Array, other: Union[int, float, Array], /) -> Array: + """ + Evaluates `self_i / other_i` for each element of an array instance + with the respective element of the array `other`. + + Parameters + ---------- + other : Union[int, float, array] + Subtrahend array. Must have a numeric data type. + """ + other = self._check_allowed_dtypes(other, "numeric", "__truediv__") + if other is NotImplemented: + return other + # self, other = self._normalize_two_args(self, other) + res = self._array.__truediv__(other._array) + return self.__class__._new(res) + + def __xor__(self: Array, other: Union[int, bool, Array], /) -> Array: + """ + Evaluates `self_i ^ other_i` for each element of an array instance + with the respective element of the array `other`. + + Parameters + ---------- + other : Union[int, bool, array] + Subtrahend array. Must have an integer or boolean data type. + """ + other = self._check_allowed_dtypes(other, "integer or boolean", "__xor__") + if other is NotImplemented: + return other + # self, other = self._normalize_two_args(self, other) + res = self._array.__xor__(other._array) + return self.__class__._new(res) + + # def to_device(self: Array, device: Device, /, stream: Optional[Union[int, Any]] = None) -> Array: + # """ + # Copy the array from the device on which it currently resides to the specified `device`. + # """ + # if stream is not None: + # raise ValueError("The stream argument to to_device() is not supported") + # if device == 'cpu': + # return self + # raise ValueError(f"Unsupported device {device!r}") @property def dtype(self) -> Dtype: @@ -263,6 +621,15 @@ def device(self) -> Device: """ return self._array.device + @property + def mT(self) -> Array: + """ + Transpose of a matrix (or a stack of matrices). + """ + if self.ndim < 2: + raise ValueError("x.mT requires x to have at least 2 dimensions.") + return self._array.transpose(axes=list(range(self.ndim))[:-2] + [-1, -2]) + @property def ndim(self) -> int: """ @@ -283,3 +650,15 @@ def size(self) -> Optional[int]: Number of elements in an array. """ return self._array.size + + @property + def T(self) -> Array: + """ + Transpose of the array. + """ + # Note: T only works on 2-dimensional arrays, as outlined in the specification: + if self.ndim != 2: + raise ValueError( + "x.T requires x to have 2 dimensions. Use x.mT to transpose stacks of matrices and permute_dims() to permute dimensions." + ) + return self.__class__._new(self._array.T) diff --git a/heat/array_api/_creation_functions.py b/heat/array_api/_creation_functions.py index 7524fb7c88..7eed441800 100644 --- a/heat/array_api/_creation_functions.py +++ b/heat/array_api/_creation_functions.py @@ -3,7 +3,7 @@ import heat as ht from typing import TYPE_CHECKING, Union, Optional, Tuple -from ._dtypes import _all_dtypes, default_float +from ._dtypes import _all_dtypes, default_int, default_float if TYPE_CHECKING: from ._typing import Array, Dtype, Device, NestedSequence, SupportsBufferProtocol @@ -52,6 +52,7 @@ def asarray( # return Array._new(np.array(obj._array, copy=True, dtype=dtype)) if not copy: return obj + obj = obj._array if dtype is None: if isinstance(obj, int) and (obj > 2**64 or obj < -(2**63)): # TODO: This won't handle large integers in lists. @@ -80,7 +81,10 @@ def full( if isinstance(fill_value, Array) and fill_value.ndim == 0: fill_value = fill_value._array if dtype is None: - dtype = default_float + if isinstance(fill_value, int): + dtype = default_int + elif isinstance(fill_value, float): + dtype = default_float res = ht.full(shape, fill_value, dtype=dtype, device=device) # if res.dtype not in _all_dtypes: # # This will happen if the fill value is not something that NumPy diff --git a/heat/array_api/_dtypes.py b/heat/array_api/_dtypes.py index 9d7c44f57d..187a6f3ad8 100644 --- a/heat/array_api/_dtypes.py +++ b/heat/array_api/_dtypes.py @@ -11,6 +11,7 @@ float32 = ht.float32 float64 = ht.float64 bool = ht.bool +default_int = int64 default_float = float64 _all_dtypes = ( diff --git a/heat/array_api/_typing.py b/heat/array_api/_typing.py index 81886bfc1c..115e3f6c84 100644 --- a/heat/array_api/_typing.py +++ b/heat/array_api/_typing.py @@ -13,6 +13,8 @@ bool, ) +from heat.core.devices import Device + Dtype = Union[ int8, int16, From fed2952fa6acf2da0d1f325a112b32d398bba1a2 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Fri, 17 Jun 2022 17:11:14 +0800 Subject: [PATCH 012/150] Implement `add` --- heat/array_api/__init__.py | 4 ++ heat/array_api/_array_object.py | 2 +- heat/array_api/_statistical_functions.py | 50 ++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 heat/array_api/_statistical_functions.py diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index c15eabf351..8049c74dbd 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -55,6 +55,10 @@ __all__ += ["reshape"] +from ._statistical_functions import sum + +__all__ += ["sum"] + from ._utility_functions import all __all__ += ["all"] diff --git a/heat/array_api/_array_object.py b/heat/array_api/_array_object.py index bc8ab4d5a7..66459b7ecc 100644 --- a/heat/array_api/_array_object.py +++ b/heat/array_api/_array_object.py @@ -541,7 +541,7 @@ def __setitem__( key = key._array if isinstance(value, Array): value = value._array - if self.ndim == 0 and key == ...: + if self.ndim == 0 and isinstance(key, type(...)): self._array = ht.asarray(value) else: self._array.__setitem__(key, value) diff --git a/heat/array_api/_statistical_functions.py b/heat/array_api/_statistical_functions.py new file mode 100644 index 0000000000..104a362bde --- /dev/null +++ b/heat/array_api/_statistical_functions.py @@ -0,0 +1,50 @@ +from __future__ import annotations + +from ._dtypes import _numeric_dtypes +from ._array_object import Array + +from typing import TYPE_CHECKING, Optional, Tuple, Union + +if TYPE_CHECKING: + from ._typing import Dtype + +import heat as ht + + +def sum( + x: Array, + /, + *, + axis: Optional[Union[int, Tuple[int, ...]]] = None, + dtype: Optional[Dtype] = None, + keepdims: bool = False, +) -> Array: + """ + Calculates the sum of the input array `x`. + + Parameters + ---------- + x : Array + Input array. Must have a numeric data type. + axis : Optional[Union[int, Tuple[int, ...]]] + Axis or axes along which sums are computed. By default, the sum is + computed over the entire array. If a tuple of integers, sums are computed + over multiple axes. Default: `None`. + dtype : Optional[Dtype] + Data type of the returned array. + keepdims : bool + If `True`, the reduced axes (dimensions) are included in the result as + singleton dimensions. Otherwise, if `False`, the reduced axes + (dimensions) are be included in the result. + """ + if x.dtype not in _numeric_dtypes: + raise TypeError("Only numeric dtypes are allowed in sum") + # Note: sum() and prod() always upcast integers to (u)int64 and float32 to + # float64 for dtype=None. `np.sum` does that too for integers, but not for + # float32, so we need to special-case it here + # if dtype is None and x.dtype == float32: + # dtype = float64 + res = ht.sum(x._array, axis=axis, keepdim=True) + if not keepdims or x._array.ndim == 0: + res = ht.squeeze(res, axis=axis) + return Array._new(res) From accbd151e9eb4f03be894ad980999ae99e77d917 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Fri, 17 Jun 2022 18:20:10 +0800 Subject: [PATCH 013/150] Standardize import order --- heat/array_api/__init__.py | 47 ++++++++++++++++++++--- heat/array_api/_array_object.py | 12 +++--- heat/array_api/_constants.py | 10 ++--- heat/array_api/_creation_functions.py | 10 ++--- heat/array_api/_data_type_functions.py | 10 +++-- heat/array_api/_elementwise_functions.py | 6 +-- heat/array_api/_manipulation_functions.py | 7 +++- heat/array_api/_utility_functions.py | 7 +++- 8 files changed, 75 insertions(+), 34 deletions(-) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index 8049c74dbd..25267a5aea 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -11,11 +11,34 @@ __all__ += ["e", "inf", "nan", "newaxis", "pi"] -from ._creation_functions import asarray, full, zeros +from ._creation_functions import ( + asarray, + full, + zeros, +) + +__all__ += [ + "asarray", + "full", + "zeros", +] + +from ._data_type_functions import ( + astype, + finfo, + iinfo, +) + +from heat.core.devices import cpu -__all__ += ["asarray", "full", "zeros"] +__all__ += ["cpu"] -from ._data_type_functions import astype, finfo, iinfo +import heat.core.devices + +if hasattr(heat.core.devices, "gpu"): + from heat.core.devices import gpu + + __all__ += ["gpu"] __all__ += ["astype", "finfo", "iinfo"] @@ -47,11 +70,23 @@ "bool", ] -from ._elementwise_functions import equal, isfinite, isinf, isnan +from ._elementwise_functions import ( + equal, + isfinite, + isinf, + isnan, +) -__all__ += ["equal", "isfinite", "isinf", "isnan"] +__all__ += [ + "equal", + "isfinite", + "isinf", + "isnan", +] -from ._manipulation_functions import reshape +from ._manipulation_functions import ( + reshape, +) __all__ += ["reshape"] diff --git a/heat/array_api/_array_object.py b/heat/array_api/_array_object.py index 66459b7ecc..87b4abe906 100644 --- a/heat/array_api/_array_object.py +++ b/heat/array_api/_array_object.py @@ -1,8 +1,6 @@ from __future__ import annotations -import heat as ht - -from typing import TYPE_CHECKING, Any, Tuple, Union, Optional +from typing import TYPE_CHECKING, Any, Optional, Tuple, Union from ._creation_functions import asarray from ._dtypes import ( @@ -17,11 +15,11 @@ ) if TYPE_CHECKING: - from ._typing import Dtype, Device + from ._typing import Device, Dtype from builtins import ellipsis +import heat as ht from heat import array_api -from heat.core.dndarray import DNDarray class Array: @@ -35,10 +33,10 @@ class Array: functions, such as asarray(). """ - _array: DNDarray + _array: ht.DNDarray @classmethod - def _new(cls, x: DNDarray, /): + def _new(cls, x, /): """ This is a private method for initializing the array API Array object. diff --git a/heat/array_api/_constants.py b/heat/array_api/_constants.py index 1c3636a0ed..1f01405e9c 100644 --- a/heat/array_api/_constants.py +++ b/heat/array_api/_constants.py @@ -1,7 +1,7 @@ -from heat.core.constants import E, INF, NAN, PI +import heat as ht -e = E -inf = INF -nan = NAN +e = ht.e +inf = ht.inf +nan = ht.nan newaxis = None -pi = PI +pi = ht.pi diff --git a/heat/array_api/_creation_functions.py b/heat/array_api/_creation_functions.py index 7eed441800..c43caed433 100644 --- a/heat/array_api/_creation_functions.py +++ b/heat/array_api/_creation_functions.py @@ -1,12 +1,12 @@ from __future__ import annotations -import heat as ht -from typing import TYPE_CHECKING, Union, Optional, Tuple - -from ._dtypes import _all_dtypes, default_int, default_float +from typing import TYPE_CHECKING, Optional, Tuple, Union if TYPE_CHECKING: - from ._typing import Array, Dtype, Device, NestedSequence, SupportsBufferProtocol + from ._typing import Array, Device, Dtype, NestedSequence, SupportsBufferProtocol +from ._dtypes import _all_dtypes, default_float, default_int + +import heat as ht def _check_valid_dtype(dtype): diff --git a/heat/array_api/_data_type_functions.py b/heat/array_api/_data_type_functions.py index 61513d28fd..9eb6309e2d 100644 --- a/heat/array_api/_data_type_functions.py +++ b/heat/array_api/_data_type_functions.py @@ -1,12 +1,14 @@ from __future__ import annotations -import heat as ht +from ._array_object import Array from dataclasses import dataclass -from typing import Union +from typing import TYPE_CHECKING, Union -from ._array_object import Array -from ._typing import Dtype +if TYPE_CHECKING: + from ._typing import Dtype + +import heat as ht def astype(x: Array, dtype: Dtype, /, *, copy: bool = True) -> Array: diff --git a/heat/array_api/_elementwise_functions.py b/heat/array_api/_elementwise_functions.py index 3c55249ec7..3e3d851826 100644 --- a/heat/array_api/_elementwise_functions.py +++ b/heat/array_api/_elementwise_functions.py @@ -1,9 +1,9 @@ from __future__ import annotations -import heat as ht - -from ._array_object import Array from ._dtypes import _numeric_dtypes, _result_type +from ._array_object import Array + +import heat as ht def equal(x1: Array, x2: Array, /) -> Array: diff --git a/heat/array_api/_manipulation_functions.py b/heat/array_api/_manipulation_functions.py index 2bf9d450d6..2c915630f1 100644 --- a/heat/array_api/_manipulation_functions.py +++ b/heat/array_api/_manipulation_functions.py @@ -1,8 +1,11 @@ -import heat as ht -from typing import Tuple, Optional +from __future__ import annotations from ._array_object import Array +from typing import Optional, Tuple + +import heat as ht + def reshape(x: Array, /, shape: Tuple[int, ...], *, copy: Optional[bool] = None) -> Array: """ diff --git a/heat/array_api/_utility_functions.py b/heat/array_api/_utility_functions.py index 0cd37e4a02..3ce0c486b1 100644 --- a/heat/array_api/_utility_functions.py +++ b/heat/array_api/_utility_functions.py @@ -1,8 +1,11 @@ -import heat as ht -from typing import Optional, Tuple, Union +from __future__ import annotations from ._array_object import Array +from typing import Optional, Tuple, Union + +import heat as ht + def all( x: Array, From de16eac748f9b489c02ae6abeac63d680a1f3982 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Fri, 17 Jun 2022 20:51:49 +0800 Subject: [PATCH 014/150] Document function parameters --- heat/array_api/_array_object.py | 106 +++++++++++----------- heat/array_api/_constants.py | 5 + heat/array_api/_creation_functions.py | 69 ++++++++------ heat/array_api/_data_type_functions.py | 24 ++++- heat/array_api/_dtypes.py | 15 +++ heat/array_api/_elementwise_functions.py | 41 ++++++--- heat/array_api/_manipulation_functions.py | 18 +++- heat/array_api/_statistical_functions.py | 17 +++- heat/array_api/_utility_functions.py | 15 ++- 9 files changed, 210 insertions(+), 100 deletions(-) diff --git a/heat/array_api/_array_object.py b/heat/array_api/_array_object.py index 87b4abe906..b5a62f5beb 100644 --- a/heat/array_api/_array_object.py +++ b/heat/array_api/_array_object.py @@ -25,12 +25,12 @@ class Array: """ DNDarray object for the array API namespace. - This is a wrapper around `heat.DNDarray` that restricts the usage to only + This is a wrapper around ``heat.DNDarray`` that restricts the usage to only those things that are required by the array API namespace. Note, attributes on this object that start with a single underscore are not part of the API specification and should only be used internally. This object should not be constructed directly. Rather, use one of the creation - functions, such as asarray(). + functions, such as ``asarray``. """ _array: ht.DNDarray @@ -42,12 +42,12 @@ def _new(cls, x, /): object. Functions outside of the array_api submodule should not use this method. Use one of the creation functions instead, such as - `asarray`. + ``asarray``. Parameters ---------- x : DNDarray - Underlying `DNDarray` + Underlying ``DNDarray`` """ obj = super().__new__(cls) obj._array = x @@ -55,7 +55,7 @@ def _new(cls, x, /): def __new__(cls, *args, **kwargs): """ - Prevent `Array()` from working. + Prevent ``Array()`` from working. """ raise TypeError( "The array_api Array object should not be instantiated directly. Use an array creation function, such as asarray(), instead." @@ -99,7 +99,7 @@ def _promote_scalar(self, scalar): """ Returns a promoted version of a Python scalar appropriate for use with operations on self. - This may raise a `TypeError` when the scalar type is incompatible with + This may raise a ``TypeError`` when the scalar type is incompatible with the dtype of self. """ # Note: Only Python scalar types that match the array dtype are @@ -116,7 +116,7 @@ def _promote_scalar(self, scalar): "Python float scalars can only be promoted with floating-point arrays." ) else: - raise TypeError("'scalar' must be a Python scalar") + raise TypeError(f"{scalar} must be a Python scalar") # Note: scalars are unconditionally cast to the same dtype as the # array. @@ -137,7 +137,7 @@ def __abs__(self: Array, /) -> Array: def __add__(self: Array, other: Union[int, float, Array], /) -> Array: """ Calculates the sum for each element of an array instance with the - respective element of the array `other`. + respective element of the array ``other``. Parameters ---------- @@ -152,8 +152,8 @@ def __add__(self: Array, other: Union[int, float, Array], /) -> Array: def __and__(self: Array, other: Union[int, bool, Array], /) -> Array: """ - Evaluates `self_i & other_i` for each element of an array instance - with the respective element of the array `other`. + Evaluates ``self_i & other_i`` for each element of an array instance + with the respective element of the array ``other``. Parameters ---------- @@ -174,7 +174,7 @@ def __array_namespace__(self: Array, /, *, api_version: Optional[str] = None) -> ---------- api_version : Optional[str] string representing the version of the array API specification to - be returned, in `'YYYY.MM'` form. If it is `None` (default), it + be returned, in ``'YYYY.MM'`` form. If it is ``None`` (default), it returns the namespace corresponding to latest version of the array API specification. """ @@ -184,7 +184,7 @@ def __array_namespace__(self: Array, /, *, api_version: Optional[str] = None) -> def __bool__(self: Array, /) -> bool: """ - Converts a zero-dimensional boolean array to a Python `bool` object. + Converts a zero-dimensional boolean array to a Python ``bool`` object. """ if self._array.ndim != 0: raise TypeError("bool is only allowed on arrays with 0 dimensions") @@ -195,8 +195,8 @@ def __bool__(self: Array, /) -> bool: def __eq__(self: Array, other: Union[int, float, bool, Array], /) -> Array: """ - Computes the truth value of `self_i == other_i` for each element of an - array instance with the respective element of the array `other`. + Computes the truth value of ``self_i == other_i`` for each element of an + array instance with the respective element of the array ``other``. Parameters ---------- @@ -214,7 +214,7 @@ def __eq__(self: Array, other: Union[int, float, bool, Array], /) -> Array: def __float__(self: Array, /) -> float: """ - Converts a zero-dimensional floating-point array to a Python `float` object. + Converts a zero-dimensional floating-point array to a Python ``float`` object. """ if self._array.ndim != 0: raise TypeError("float is only allowed on arrays with 0 dimensions") @@ -225,8 +225,8 @@ def __float__(self: Array, /) -> float: def __floordiv__(self: Array, other: Union[int, float, Array], /) -> Array: """ - Evaluates `self_i // other_i` for each element of an array instance - with the respective element of the array `other`. + Evaluates ``self_i // other_i`` for each element of an array instance + with the respective element of the array ``other``. Parameters ---------- @@ -242,8 +242,8 @@ def __floordiv__(self: Array, other: Union[int, float, Array], /) -> Array: def __ge__(self: Array, other: Union[int, float, Array], /) -> Array: """ - Computes the truth value of `self_i >= other_i` for each element of - an array instance with the respective element of the array `other`. + Computes the truth value of ``self_i >= other_i`` for each element of + an array instance with the respective element of the array ``other``. Parameters ---------- @@ -263,7 +263,7 @@ def __getitem__( /, ) -> Array: """ - Returns `self[key]`. + Returns ``self[key]``. Parameters ---------- @@ -288,8 +288,8 @@ def __getitem__( def __gt__(self: Array, other: Union[int, float, Array], /) -> Array: """ - Computes the truth value of `self_i > other_i` for each element - of an array instance with the respective element of the array `other`. + Computes the truth value of ``self_i > other_i`` for each element + of an array instance with the respective element of the array ``other``. Parameters ---------- @@ -305,13 +305,13 @@ def __gt__(self: Array, other: Union[int, float, Array], /) -> Array: def __index__(self: Array, /) -> int: """ - Converts a zero-dimensional integer array to a Python `int` object. + Converts a zero-dimensional integer array to a Python ``int`` object. """ return self.__int__() def __int__(self: Array, /) -> int: """ - Converts a zero-dimensional integer array to a Python `int` object. + Converts a zero-dimensional integer array to a Python ``int`` object. """ if self._array.ndim != 0: raise TypeError("int is only allowed on arrays with 0 dimensions") @@ -322,7 +322,7 @@ def __int__(self: Array, /) -> int: def __invert__(self: Array, /) -> Array: """ - Evaluates `~self_i` for each element of an array instance. + Evaluates ``~self_i`` for each element of an array instance. """ if self.dtype not in _integer_or_boolean_dtypes: raise TypeError("Only integer or boolean dtypes are allowed in __invert__") @@ -331,8 +331,8 @@ def __invert__(self: Array, /) -> Array: def __le__(self: Array, other: Union[int, float, Array], /) -> Array: """ - Computes the truth value of `self_i <= other_i` for each element of an - array instance with the respective element of the array `other`. + Computes the truth value of ``self_i <= other_i`` for each element of an + array instance with the respective element of the array ``other``. Parameters ---------- @@ -348,14 +348,14 @@ def __le__(self: Array, other: Union[int, float, Array], /) -> Array: def __lshift__(self: Array, other: Union[int, Array], /) -> Array: """ - Evaluates `self_i << other_i` for each element of an array instance - with the respective element of the array `other`. + Evaluates ``self_i << other_i`` for each element of an array instance + with the respective element of the array ``other``. Parameters ---------- other : Union[int, Array] Other array. Must have an integer data type. Each element - must be greater than or equal to `0`. + must be greater than or equal to ``0``. """ other = self._check_allowed_dtypes(other, "integer", "__lshift__") if other is NotImplemented: @@ -366,8 +366,8 @@ def __lshift__(self: Array, other: Union[int, Array], /) -> Array: def __lt__(self: Array, other: Union[int, float, Array], /) -> Array: """ - Computes the truth value of `self_i < other_i` for each element - of an array instance with the respective element of the array `other`. + Computes the truth value of ``self_i < other_i`` for each element + of an array instance with the respective element of the array ``other``. Parameters ---------- @@ -398,8 +398,8 @@ def __matmul__(self: Array, other: Array, /) -> Array: def __mod__(self: Array, other: Union[int, float, Array], /) -> Array: """ - Evaluates `self_i % other_i` for each element of an array instance - with the respective element of the array `other`. + Evaluates ``self_i % other_i`` for each element of an array instance + with the respective element of the array ``other``. Parameters ---------- @@ -416,7 +416,7 @@ def __mod__(self: Array, other: Union[int, float, Array], /) -> Array: def __mul__(self: Array, other: Union[int, float, Array], /) -> Array: """ Calculates the product for each element of an array instance with - the respective element of the array `other`. + the respective element of the array ``other``. Parameters ---------- @@ -432,8 +432,8 @@ def __mul__(self: Array, other: Union[int, float, Array], /) -> Array: def __ne__(self: Array, other: Union[int, float, bool, Array], /) -> Array: """ - Computes the truth value of `self_i != other_i` for each element of - an array instance with the respective element of the array `other`. + Computes the truth value of ``self_i != other_i`` for each element of + an array instance with the respective element of the array ``other``. Parameters ---------- @@ -449,7 +449,7 @@ def __ne__(self: Array, other: Union[int, float, bool, Array], /) -> Array: def __neg__(self: Array, /) -> Array: """ - Evaluates `-self_i` for each element of an array instance. + Evaluates ``-self_i`` for each element of an array instance. """ if self.dtype not in _numeric_dtypes: raise TypeError("Only numeric dtypes are allowed in __neg__") @@ -458,8 +458,8 @@ def __neg__(self: Array, /) -> Array: def __or__(self: Array, other: Union[int, bool, Array], /) -> Array: """ - Evaluates `self_i | other_i` for each element of an array instance - with the respective element of the array `other`. + Evaluates ``self_i | other_i`` for each element of an array instance + with the respective element of the array ``other``. Parameters ---------- @@ -475,7 +475,7 @@ def __or__(self: Array, other: Union[int, bool, Array], /) -> Array: def __pos__(self: Array, /) -> Array: """ - Evaluates `+self_i` for each element of an array instance. + Evaluates ``+self_i`` for each element of an array instance. """ if self.dtype not in _numeric_dtypes: raise TypeError("Only numeric dtypes are allowed in __pos__") @@ -485,8 +485,8 @@ def __pos__(self: Array, /) -> Array: def __pow__(self: Array, other: Union[int, float, Array], /) -> Array: """ Calculates an approximation of exponentiation by raising each element - (the base) of an array instance to the power of `other_i` (the exponent), - where `other_i` is the corresponding element of the array `other`. + (the base) of an array instance to the power of ``other_i`` (the exponent), + where ``other_i`` is the corresponding element of the array ``other``. Parameters ---------- @@ -506,14 +506,14 @@ def __pow__(self: Array, other: Union[int, float, Array], /) -> Array: def __rshift__(self: Array, other: Union[int, Array], /) -> Array: """ - Evaluates `self_i >> other_i` for each element of an array instance - with the respective element of the array `other`. + Evaluates ``self_i >> other_i`` for each element of an array instance + with the respective element of the array ``other``. Parameters ---------- other : Union[int, array] Other array. Must have an integer data type. Each element must be - greater than or equal to `0`. + greater than or equal to ``0``. """ other = self._check_allowed_dtypes(other, "integer", "__rshift__") if other is NotImplemented: @@ -529,7 +529,7 @@ def __setitem__( /, ) -> None: """ - Sets `self[key]` to `value`. + Sets ``self[key]`` to ``value``. """ # Note: Only indices required by the spec are allowed. See the # docstring of _validate_index @@ -547,7 +547,7 @@ def __setitem__( def __sub__(self: Array, other: Union[int, float, Array], /) -> Array: """ Calculates the difference for each element of an array instance - with the respective element of the array `other`. + with the respective element of the array ``other``. Parameters ---------- @@ -563,8 +563,8 @@ def __sub__(self: Array, other: Union[int, float, Array], /) -> Array: def __truediv__(self: Array, other: Union[int, float, Array], /) -> Array: """ - Evaluates `self_i / other_i` for each element of an array instance - with the respective element of the array `other`. + Evaluates ``self_i / other_i`` for each element of an array instance + with the respective element of the array ``other``. Parameters ---------- @@ -580,8 +580,8 @@ def __truediv__(self: Array, other: Union[int, float, Array], /) -> Array: def __xor__(self: Array, other: Union[int, bool, Array], /) -> Array: """ - Evaluates `self_i ^ other_i` for each element of an array instance - with the respective element of the array `other`. + Evaluates ``self_i ^ other_i`` for each element of an array instance + with the respective element of the array ``other``. Parameters ---------- @@ -597,7 +597,7 @@ def __xor__(self: Array, other: Union[int, bool, Array], /) -> Array: # def to_device(self: Array, device: Device, /, stream: Optional[Union[int, Any]] = None) -> Array: # """ - # Copy the array from the device on which it currently resides to the specified `device`. + # Copy the array from the device on which it currently resides to the specified ``device``. # """ # if stream is not None: # raise ValueError("The stream argument to to_device() is not supported") diff --git a/heat/array_api/_constants.py b/heat/array_api/_constants.py index 1f01405e9c..574b37615f 100644 --- a/heat/array_api/_constants.py +++ b/heat/array_api/_constants.py @@ -1,7 +1,12 @@ import heat as ht e = ht.e +"""IEEE 754 floating-point representation of Euler's constant.""" inf = ht.inf +"""IEEE 754 floating-point representation of (positive) infinity.""" nan = ht.nan +"""IEEE 754 floating-point representation of Not a Number (``NaN``).""" newaxis = None +"""An alias for ``None`` which is useful for indexing arrays.""" pi = ht.pi +"""IEEE 754 floating-point representation of the mathematical constant :math:`\\pi`.""" diff --git a/heat/array_api/_creation_functions.py b/heat/array_api/_creation_functions.py index c43caed433..d30491306c 100644 --- a/heat/array_api/_creation_functions.py +++ b/heat/array_api/_creation_functions.py @@ -9,17 +9,6 @@ import heat as ht -def _check_valid_dtype(dtype): - # Note: Only spelling dtypes as the dtype objects is supported. - - # We use this instead of "dtype in _all_dtypes" because the dtype objects - # define equality with the sorts of things we want to disallow. - for d in (None,) + _all_dtypes: - if dtype is d: - return - raise ValueError(f"{dtype} is not supported") - - def asarray( obj: Union[ Array, @@ -37,19 +26,30 @@ def asarray( ) -> Array: """ Convert the input to an array. + + Parameters + ---------- + obj : Union[array, bool, int, float, NestedSequence[bool | int | float], SupportsBufferProtocol] + Object to be converted to an array. May be a Python scalar, + a (possibly nested) sequence of Python scalars, or an object + supporting the Python buffer protocol. Default: ``None``. + dtype : Optional[Dtype] + Output array data type. If ``dtype`` is ``None``, the output array data + type is inferred from the data type(s) in ``obj``. + device : Optional[Device] + Device on which to place the created array. If ``device`` is ``None`` and + ``x`` is an array, the output array device is inferred from ``x``. + Default: ``None``. + copy : Optional[bool] + Boolean indicating whether or not to copy the input. """ # _array_object imports in this file are inside the functions to avoid # circular imports from ._array_object import Array - # _check_valid_dtype(dtype) - # if device not in ["cpu", None]: - # raise ValueError(f"Unsupported device {device!r}") if isinstance(obj, Array): if dtype is not None and obj.dtype != dtype: copy = True - # if copy: - # return Array._new(np.array(obj._array, copy=True, dtype=dtype)) if not copy: return obj obj = obj._array @@ -71,13 +71,22 @@ def full( device: Optional[Device] = None, ) -> Array: """ - Returns a new array having a specified `shape` and filled with `fill_value`. + Returns a new array having a specified ``shape`` and filled with ``fill_value``. + + Parameters + ---------- + shape : Union[int, Tuple[int, ...]] + Output array shape. + fill_value : Union[int, float] + Fill value. + dtype : Optional[Dtype] + Output array data type. If ``dtype`` is ``None``, the output array data + type is inferred from ``fill_value``. Default: ``None``. + device : Optional[Device] + Device on which to place the created array. """ from ._array_object import Array - # _check_valid_dtype(dtype) - # if device not in ["cpu", None]: - # raise ValueError(f"Unsupported device {device!r}") if isinstance(fill_value, Array) and fill_value.ndim == 0: fill_value = fill_value._array if dtype is None: @@ -86,10 +95,6 @@ def full( elif isinstance(fill_value, float): dtype = default_float res = ht.full(shape, fill_value, dtype=dtype, device=device) - # if res.dtype not in _all_dtypes: - # # This will happen if the fill value is not something that NumPy - # # coerces to one of the acceptable dtypes. - # raise TypeError("Invalid input to full") return Array._new(res) @@ -100,13 +105,21 @@ def zeros( device: Optional[Device] = None, ) -> Array: """ - Returns a new array having a specified `shape` and filled with zeros. + Returns a new array having a specified ``shape`` and filled with zeros. + + Parameters + ---------- + shape : Union[int, Tuple[int, ...]] + Output array shape. + dtype : Optional[Dtype] + Output array data type. If ``dtype`` is ``None``, the output array data + type is the default floating-point data type (``float64``). + Default: ``None``. + device : Optional[Device] + Device on which to place the created array. """ from ._array_object import Array - # _check_valid_dtype(dtype) - # if device not in ["cpu", None]: - # raise ValueError(f"Unsupported device {device!r}") if dtype is None: dtype = default_float return Array._new(ht.zeros(shape, dtype=dtype, device=device)) diff --git a/heat/array_api/_data_type_functions.py b/heat/array_api/_data_type_functions.py index 9eb6309e2d..e10fabc8cd 100644 --- a/heat/array_api/_data_type_functions.py +++ b/heat/array_api/_data_type_functions.py @@ -14,10 +14,22 @@ def astype(x: Array, dtype: Dtype, /, *, copy: bool = True) -> Array: """ Copies an array to a specified data type irrespective of Type Promotion Rules. + + Parameters + ---------- + x : Array + Array to cast. + dtype : Dtype + Desired data type. + copy : bool + If ``True``, a newly allocated array is returned. If ``False`` and the + specified ``dtype`` matches the data type of the input array, the + input array is returned; otherwise, a newly allocated is returned. + Default: ``True``. """ if not copy and dtype == x.dtype: return x - return Array._new(x._array.astype(dtype=dtype)) + return Array._new(x._array.astype(dtype, copy=True)) @dataclass @@ -47,6 +59,11 @@ class iinfo_object: def finfo(type: Union[Dtype, Array], /) -> finfo_object: """ Machine limits for floating-point data types. + + Parameters + ---------- + type : Union[Dtype, Array] + The kind of floating-point data-type about which to get information. """ fi = ht.finfo(type) return finfo_object( @@ -61,6 +78,11 @@ def finfo(type: Union[Dtype, Array], /) -> finfo_object: def iinfo(type: Union[Dtype, Array], /) -> iinfo_object: """ Machine limits for integer data types. + + Parameters + ---------- + type : Union[Dtype, Array] + The kind of integer data-type about which to get information. """ ii = ht.iinfo(type) return iinfo_object(ii.bits, int(ii.max), int(ii.min)) diff --git a/heat/array_api/_dtypes.py b/heat/array_api/_dtypes.py index 187a6f3ad8..ec76aba79b 100644 --- a/heat/array_api/_dtypes.py +++ b/heat/array_api/_dtypes.py @@ -1,18 +1,33 @@ import heat as ht int8 = ht.int8 +"""An 8-bit signed integer whose values exist on the interval ``[-128, +127]``.""" int16 = ht.int16 +"""A 16-bit signed integer whose values exist on the interval ``[-32,767, +32,767]``.""" int32 = ht.int32 +"""A 32-bit signed integer whose values exist on the interval ``[-2,147,483,647, +2,147,483,647]``.""" int64 = ht.int64 +"""A 64-bit signed integer whose values exist on the interval ``[-9,223,372,036,854,775,807, +9,223,372,036,854,775,807]``.""" uint8 = ht.uint8 +"""An 8-bit unsigned integer whose values exist on the interval ``[0, +255]``.""" +# Waiting on Pytorch to introduce support for these 3 data types +# See https://github.com/pytorch/pytorch/issues/58734 # uint16 = +# """A 16-bit unsigned integer whose values exist on the interval ``[0, +65,535]``.""" # uint32 = +# """A 32-bit unsigned integer whose values exist on the interval ``[0, +4,294,967,295]``.""" # uint64 = +# """A 64-bit unsigned integer whose values exist on the interval ``[0, +18,446,744,073,709,551,615]``.""" float32 = ht.float32 +"""IEEE 754 single-precision (32-bit) binary floating-point number (see IEEE 754-2019).""" float64 = ht.float64 +"""IEEE 754 double-precision (64-bit) binary floating-point number (see IEEE 754-2019).""" bool = ht.bool +"""Boolean (``True`` or ``False``).""" default_int = int64 +"""Default integer data type is ``int64``""" default_float = float64 +"""Default floating-point data type is ``float64``""" _all_dtypes = ( int8, diff --git a/heat/array_api/_elementwise_functions.py b/heat/array_api/_elementwise_functions.py index 3e3d851826..041b45fec2 100644 --- a/heat/array_api/_elementwise_functions.py +++ b/heat/array_api/_elementwise_functions.py @@ -8,20 +8,29 @@ def equal(x1: Array, x2: Array, /) -> Array: """ - Computes the truth value of `x1_i == x2_i` for each element `x1_i` of - the input array `x1` with the respective element `x2_i` of the input - array `x2`. + Computes the truth value of ``x1_i == x2_i`` for each element ``x1_i`` of + the input array ``x1`` with the respective element ``x2_i`` of the input + array ``x2``. + + Parameters + ---------- + x1 : Array + First input array. + x2 : Array + Second input array. Must be compatible with ``x1``. """ - # Call result type here just to raise on disallowed type combinations - # _result_type(x1.dtype, x2.dtype) - # x1, x2 = Array._normalize_two_args(x1, x2) return Array._new(ht.eq(x1._array, x2._array)) def isfinite(x: Array, /) -> Array: """ - Tests each element `x_i` of the input array `x` to determine if finite - (i.e., not `NaN` and not equal to positive or negative infinity). + Tests each element ``x_i`` of the input array ``x`` to determine if finite + (i.e., not ``NaN`` and not equal to positive or negative infinity). + + Parameters + ---------- + x : Array + Input array. Must have a numeric data type. """ if x.dtype not in _numeric_dtypes: raise TypeError("Only numeric dtypes are allowed in isfinite") @@ -30,8 +39,13 @@ def isfinite(x: Array, /) -> Array: def isinf(x: Array, /) -> Array: """ - Tests each element `x_i` of the input array `x` to determine if equal + Tests each element ``x_i`` of the input array ``x`` to determine if equal to positive or negative infinity. + + Parameters + ---------- + x : Array + Input array. Must have a numeric data type. """ if x.dtype not in _numeric_dtypes: raise TypeError("Only numeric dtypes are allowed in isinf") @@ -40,8 +54,13 @@ def isinf(x: Array, /) -> Array: def isnan(x: Array, /) -> Array: """ - Tests each element `x_i` of the input array `x` to determine whether - the element is `NaN`. + Tests each element ``x_i`` of the input array ``x`` to determine whether + the element is ``NaN``. + + Parameters + ---------- + x : Array + Input array. Must have a numeric data type. """ if x.dtype not in _numeric_dtypes: raise TypeError("Only numeric dtypes are allowed in isnan") diff --git a/heat/array_api/_manipulation_functions.py b/heat/array_api/_manipulation_functions.py index 2c915630f1..d49ad2eaaf 100644 --- a/heat/array_api/_manipulation_functions.py +++ b/heat/array_api/_manipulation_functions.py @@ -10,5 +10,21 @@ def reshape(x: Array, /, shape: Tuple[int, ...], *, copy: Optional[bool] = None) -> Array: """ Reshapes an array without changing its data. + + Parameters + ---------- + x : Array + Input array to reshape. + shape : Tuple[int, ...] + A new shape compatible with the original shape. One shape dimension + is allowed to be ``-1``. When a shape dimension is ``-1``, the + corresponding output array shape dimension is inferred from the length + of the array and the remaining dimensions. + copy : Optional[bool] + Boolean indicating whether or not to copy the input array. """ - return Array._new(ht.reshape(x._array, shape)) + res = ht.reshape(x._array, shape) + if not copy: + x._array = res + return x + return Array._new(res) diff --git a/heat/array_api/_statistical_functions.py b/heat/array_api/_statistical_functions.py index 104a362bde..998fe8f4ff 100644 --- a/heat/array_api/_statistical_functions.py +++ b/heat/array_api/_statistical_functions.py @@ -1,6 +1,6 @@ from __future__ import annotations -from ._dtypes import _numeric_dtypes +from ._dtypes import _numeric_dtypes, _floating_dtypes, _integer_dtypes, default_float, default_int from ._array_object import Array from typing import TYPE_CHECKING, Optional, Tuple, Union @@ -20,7 +20,7 @@ def sum( keepdims: bool = False, ) -> Array: """ - Calculates the sum of the input array `x`. + Calculates the sum of the input array ``x``. Parameters ---------- @@ -29,12 +29,12 @@ def sum( axis : Optional[Union[int, Tuple[int, ...]]] Axis or axes along which sums are computed. By default, the sum is computed over the entire array. If a tuple of integers, sums are computed - over multiple axes. Default: `None`. + over multiple axes. Default: ``None``. dtype : Optional[Dtype] Data type of the returned array. keepdims : bool - If `True`, the reduced axes (dimensions) are included in the result as - singleton dimensions. Otherwise, if `False`, the reduced axes + If ``True``, the reduced axes (dimensions) are included in the result as + singleton dimensions. Otherwise, if ``False``, the reduced axes (dimensions) are be included in the result. """ if x.dtype not in _numeric_dtypes: @@ -47,4 +47,11 @@ def sum( res = ht.sum(x._array, axis=axis, keepdim=True) if not keepdims or x._array.ndim == 0: res = ht.squeeze(res, axis=axis) + if dtype is None: + if x.dtype in _floating_dtypes: + dtype = default_float + elif x.dtype in _integer_dtypes: + dtype = default_int + if dtype is not None: + res.astype(dtype, copy=False) return Array._new(res) diff --git a/heat/array_api/_utility_functions.py b/heat/array_api/_utility_functions.py index 3ce0c486b1..6400ebece6 100644 --- a/heat/array_api/_utility_functions.py +++ b/heat/array_api/_utility_functions.py @@ -15,7 +15,20 @@ def all( keepdims: bool = False, ) -> Array: """ - Tests whether all input array elements evaluate to `True` along a specified axis. + Tests whether all input array elements evaluate to ``True`` along a + specified axis. + + Parameters + ---------- + x : Array + Input array. + axis : Optional[Union[int, Tuple[int, ...]]] + Axis or axes along which to perform a logical AND reduction. By + default, a logical AND reduction is performed over the entire array. + keepdims : bool + If ``True``, the reduced axes (dimensions) are included in the result + as singleton dimensions. Otherwise, if ``False``, the reduced axes + (dimensions) are be included in the result. Default: ``False``. """ res = ht.all(x._array, axis=axis, keepdim=True) if not keepdims or x._array.ndim == 0: From f0a169bfd43a081133d8d8fa5124833376a8f9b7 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Fri, 17 Jun 2022 21:33:27 +0800 Subject: [PATCH 015/150] Fix bug causing precision loss in `abs` In cases involving large numbers where the `dtype` parameter was unchanged, precision loss occurred due to intermediate casting to float32 (in `__local_op`) before casting back to the original `dtype`. Fixed by not doing the intermediate casting. --- heat/core/rounding.py | 8 ++++++-- heat/core/tests/test_rounding.py | 5 +++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/heat/core/rounding.py b/heat/core/rounding.py index b6c68343c4..31dafefa17 100644 --- a/heat/core/rounding.py +++ b/heat/core/rounding.py @@ -52,7 +52,7 @@ def abs( if dtype is not None and not issubclass(dtype, dtype): raise TypeError("dtype must be a heat data type") - absolute_values = _operations.__local_op(torch.abs, x, out) + absolute_values = _operations.__local_op(torch.abs, x, out, no_cast=True) if dtype is not None: absolute_values.larray = absolute_values.larray.type(dtype.torch_type()) absolute_values._DNDarray__dtype = dtype @@ -181,7 +181,11 @@ def fabs(x: DNDarray, out: Optional[DNDarray] = None) -> DNDarray: If not provided or ``None``, a freshly-allocated array is returned. """ - return abs(x, out, dtype=None) + if isinstance(x, DNDarray): + dtype = types.promote_types(x.dtype, types.float32) + else: + dtype = None + return abs(x, out, dtype=dtype) DNDarray.fabs: Callable[[DNDarray, Optional[DNDarray]], DNDarray] = lambda self, out=None: fabs( diff --git a/heat/core/tests/test_rounding.py b/heat/core/tests/test_rounding.py index 379c0e0ca4..9a151e0c39 100644 --- a/heat/core/tests/test_rounding.py +++ b/heat/core/tests/test_rounding.py @@ -1,3 +1,4 @@ +from tabnanny import check import numpy as np import torch @@ -57,6 +58,10 @@ def test_abs(self): self.assertEqual(absolute_values.sum(axis=0), 100) self.assertEqual(absolute_values.dtype, ht.float32) self.assertEqual(absolute_values.larray.dtype, torch.float32) + check_precision = ht.asarray(9007199254740993, dtype=ht.int64) + precision_absolute_values = ht.abs(check_precision, dtype=ht.int64) + self.assertEqual(precision_absolute_values.sum(), check_precision.sum()) + self.assertEqual(precision_absolute_values.dtype, check_precision.dtype) # for fabs self.assertEqual(int8_absolute_values_fabs.dtype, ht.float32) self.assertEqual(int16_absolute_values_fabs.dtype, ht.float32) From 1e0c29b1ea7718a008bad0365721ff92147e7145 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Fri, 17 Jun 2022 21:42:11 +0800 Subject: [PATCH 016/150] Implement `abs` --- heat/array_api/__init__.py | 2 ++ heat/array_api/_elementwise_functions.py | 11 +++++++++++ 2 files changed, 13 insertions(+) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index 25267a5aea..74c28c09f4 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -71,6 +71,7 @@ ] from ._elementwise_functions import ( + abs, equal, isfinite, isinf, @@ -78,6 +79,7 @@ ) __all__ += [ + "abs", "equal", "isfinite", "isinf", diff --git a/heat/array_api/_elementwise_functions.py b/heat/array_api/_elementwise_functions.py index 041b45fec2..8b51fb8160 100644 --- a/heat/array_api/_elementwise_functions.py +++ b/heat/array_api/_elementwise_functions.py @@ -6,6 +6,17 @@ import heat as ht +def abs(x: Array, /) -> Array: + """ + Calculates the absolute value for each element ``x_i`` of the input array ``x`` + (i.e., the element-wise result has the same magnitude as the respective + element in ``x`` but has positive sign). + """ + if x.dtype not in _numeric_dtypes: + raise TypeError("Only numeric dtypes are allowed in abs") + return Array._new(ht.abs(x._array, dtype=x.dtype)) + + def equal(x1: Array, x2: Array, /) -> Array: """ Computes the truth value of ``x1_i == x2_i`` for each element ``x1_i`` of From 9bcbb016f6d3b333ce7ae6f73c3eda12735ff989 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Fri, 17 Jun 2022 21:53:29 +0800 Subject: [PATCH 017/150] Implement `add` --- heat/array_api/__init__.py | 2 ++ heat/array_api/_array_object.py | 33 ++++++++++++++++++++++++ heat/array_api/_elementwise_functions.py | 13 ++++++++++ 3 files changed, 48 insertions(+) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index 74c28c09f4..2441e20c60 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -72,6 +72,7 @@ from ._elementwise_functions import ( abs, + add, equal, isfinite, isinf, @@ -80,6 +81,7 @@ __all__ += [ "abs", + "add", "equal", "isfinite", "isinf", diff --git a/heat/array_api/_array_object.py b/heat/array_api/_array_object.py index b5a62f5beb..558ca26454 100644 --- a/heat/array_api/_array_object.py +++ b/heat/array_api/_array_object.py @@ -123,6 +123,38 @@ def _promote_scalar(self, scalar): return Array._new(ht.array(scalar, self.dtype)) + @staticmethod + def _normalize_two_args(x1, x2) -> Tuple[Array, Array]: + """ + Normalize inputs to two arg functions to fix type promotion rules + NumPy deviates from the spec type promotion rules in cases where one + argument is 0-dimensional and the other is not. For example: + >>> import numpy as np + >>> a = np.array([1.0], dtype=np.float32) + >>> b = np.array(1.0, dtype=np.float64) + >>> np.add(a, b) # The spec says this should be float64 + array([2.], dtype=float32) + To fix this, we add a dimension to the 0-dimension array before passing it + through. This works because a dimension would be added anyway from + broadcasting, so the resulting shape is the same, but this prevents NumPy + from not promoting the dtype. + """ + # Another option would be to use signature=(x1.dtype, x2.dtype, None), + # but that only works for ufuncs, so we would have to call the ufuncs + # directly in the operator methods. One should also note that this + # sort of trick wouldn't work for functions like searchsorted, which + # don't do normal broadcasting, but there aren't any functions like + # that in the array API namespace. + if x1.ndim == 0 and x2.ndim != 0: + # The _array[None] workaround was chosen because it is relatively + # performant. broadcast_to(x1._array, x2.shape) is much slower. We + # could also manually type promote x2, but that is more complicated + # and about the same performance as this. + x1 = Array._new(x1._array[None]) + elif x2.ndim == 0 and x1.ndim != 0: + x2 = Array._new(x2._array[None]) + return (x1, x2) + def __abs__(self: Array, /) -> Array: """ Calculates the absolute value for each element of an array instance @@ -147,6 +179,7 @@ def __add__(self: Array, other: Union[int, float, Array], /) -> Array: other = self._check_allowed_dtypes(other, "numeric", "__add__") if other is NotImplemented: return other + self, other = self._normalize_two_args(self, other) res = self._array.__add__(other._array) return self.__class__._new(res) diff --git a/heat/array_api/_elementwise_functions.py b/heat/array_api/_elementwise_functions.py index 8b51fb8160..d346409c23 100644 --- a/heat/array_api/_elementwise_functions.py +++ b/heat/array_api/_elementwise_functions.py @@ -17,6 +17,19 @@ def abs(x: Array, /) -> Array: return Array._new(ht.abs(x._array, dtype=x.dtype)) +def add(x1: Array, x2: Array, /) -> Array: + """ + Calculates the sum for each element ``x1_i`` of the input array ``x1`` with + the respective element ``x2_i`` of the input array ``x2``. + """ + if x1.dtype not in _numeric_dtypes or x2.dtype not in _numeric_dtypes: + raise TypeError("Only numeric dtypes are allowed in add") + # Call result type here just to raise on disallowed type combinations + _result_type(x1.dtype, x2.dtype) + x1, x2 = Array._normalize_two_args(x1, x2) + return Array._new(ht.add(x1._array, x2._array)) + + def equal(x1: Array, x2: Array, /) -> Array: """ Computes the truth value of ``x1_i == x2_i`` for each element ``x1_i`` of From ff53a9579ca844aa12d9cb8f87ea8ed6c8c2bb52 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Fri, 17 Jun 2022 22:00:36 +0800 Subject: [PATCH 018/150] Implement `bitwise_and` --- heat/array_api/__init__.py | 2 ++ heat/array_api/_array_object.py | 1 + heat/array_api/_elementwise_functions.py | 41 +++++++++++++++++++++++- 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index 2441e20c60..4cd4c26e81 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -73,6 +73,7 @@ from ._elementwise_functions import ( abs, add, + bitwise_and, equal, isfinite, isinf, @@ -82,6 +83,7 @@ __all__ += [ "abs", "add", + "bitwise_and", "equal", "isfinite", "isinf", diff --git a/heat/array_api/_array_object.py b/heat/array_api/_array_object.py index 558ca26454..7e908b7371 100644 --- a/heat/array_api/_array_object.py +++ b/heat/array_api/_array_object.py @@ -196,6 +196,7 @@ def __and__(self: Array, other: Union[int, bool, Array], /) -> Array: other = self._check_allowed_dtypes(other, "integer or boolean", "__and__") if other is NotImplemented: return other + self, other = self._normalize_two_args(self, other) res = self._array.__and__(other._array) return self.__class__._new(res) diff --git a/heat/array_api/_elementwise_functions.py b/heat/array_api/_elementwise_functions.py index d346409c23..923c60f8a9 100644 --- a/heat/array_api/_elementwise_functions.py +++ b/heat/array_api/_elementwise_functions.py @@ -1,6 +1,10 @@ from __future__ import annotations -from ._dtypes import _numeric_dtypes, _result_type +from ._dtypes import ( + _numeric_dtypes, + _integer_or_boolean_dtypes, + _result_type, +) from ._array_object import Array import heat as ht @@ -11,6 +15,11 @@ def abs(x: Array, /) -> Array: Calculates the absolute value for each element ``x_i`` of the input array ``x`` (i.e., the element-wise result has the same magnitude as the respective element in ``x`` but has positive sign). + + Parameters + ---------- + x : Array + Input array. Must have a numeric data type. """ if x.dtype not in _numeric_dtypes: raise TypeError("Only numeric dtypes are allowed in abs") @@ -21,6 +30,14 @@ def add(x1: Array, x2: Array, /) -> Array: """ Calculates the sum for each element ``x1_i`` of the input array ``x1`` with the respective element ``x2_i`` of the input array ``x2``. + + Parameters + ---------- + x1 : Array + First input array. Must have a numeric data type. + x2 : Array + Second input array. Must be compatible with ``x1`` and have a numeric + data type. """ if x1.dtype not in _numeric_dtypes or x2.dtype not in _numeric_dtypes: raise TypeError("Only numeric dtypes are allowed in add") @@ -30,6 +47,28 @@ def add(x1: Array, x2: Array, /) -> Array: return Array._new(ht.add(x1._array, x2._array)) +def bitwise_and(x1: Array, x2: Array, /) -> Array: + """ + Computes the bitwise AND of the underlying binary representation of each + element ``x1_i`` of the input array ``x1`` with the respective element + ``x2_i`` of the input array ``x2``. + + Parameters + ---------- + x1 : Array + First input array. Must have an integer or boolean data type. + x2 : Array + Second input array. Must be compatible with ``x1`` and have an integer + or boolean data type. + """ + if x1.dtype not in _integer_or_boolean_dtypes or x2.dtype not in _integer_or_boolean_dtypes: + raise TypeError("Only integer or boolean dtypes are allowed in bitwise_and") + # Call result type here just to raise on disallowed type combinations + _result_type(x1.dtype, x2.dtype) + x1, x2 = Array._normalize_two_args(x1, x2) + return Array._new(ht.bitwise_and(x1._array, x2._array)) + + def equal(x1: Array, x2: Array, /) -> Array: """ Computes the truth value of ``x1_i == x2_i`` for each element ``x1_i`` of From afe0b956777829519ce7c5b89158ccfe29e27fba Mon Sep 17 00:00:00 2001 From: neosunhan Date: Fri, 17 Jun 2022 22:28:43 +0800 Subject: [PATCH 019/150] Implement `bitwise_left_shift`, `less`, `any` Fixed bug in `ht.any` where `keepdim` argument was not working when `axis=None` (same fix as 136e1b7) --- heat/array_api/__init__.py | 8 +++- heat/array_api/_array_object.py | 4 +- heat/array_api/_elementwise_functions.py | 48 ++++++++++++++++++++++++ heat/array_api/_utility_functions.py | 30 +++++++++++++++ heat/core/logical.py | 3 ++ heat/core/tests/test_logical.py | 4 ++ 6 files changed, 93 insertions(+), 4 deletions(-) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index 4cd4c26e81..81a0b05be4 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -74,20 +74,24 @@ abs, add, bitwise_and, + bitwise_left_shift, equal, isfinite, isinf, isnan, + less, ) __all__ += [ "abs", "add", "bitwise_and", + "bitwise_left_shift", "equal", "isfinite", "isinf", "isnan", + "less", ] from ._manipulation_functions import ( @@ -100,6 +104,6 @@ __all__ += ["sum"] -from ._utility_functions import all +from ._utility_functions import all, any -__all__ += ["all"] +__all__ += ["all", "any"] diff --git a/heat/array_api/_array_object.py b/heat/array_api/_array_object.py index 7e908b7371..a1fe92ae8d 100644 --- a/heat/array_api/_array_object.py +++ b/heat/array_api/_array_object.py @@ -394,7 +394,7 @@ def __lshift__(self: Array, other: Union[int, Array], /) -> Array: other = self._check_allowed_dtypes(other, "integer", "__lshift__") if other is NotImplemented: return other - # self, other = self._normalize_two_args(self, other) + self, other = self._normalize_two_args(self, other) res = self._array.__lshift__(other._array) return self.__class__._new(res) @@ -411,7 +411,7 @@ def __lt__(self: Array, other: Union[int, float, Array], /) -> Array: other = self._check_allowed_dtypes(other, "numeric", "__lt__") if other is NotImplemented: return other - # self, other = self._normalize_two_args(self, other) + self, other = self._normalize_two_args(self, other) res = self._array.__lt__(other._array) return self.__class__._new(res) diff --git a/heat/array_api/_elementwise_functions.py b/heat/array_api/_elementwise_functions.py index 923c60f8a9..795c5f6a6d 100644 --- a/heat/array_api/_elementwise_functions.py +++ b/heat/array_api/_elementwise_functions.py @@ -2,6 +2,7 @@ from ._dtypes import ( _numeric_dtypes, + _integer_dtypes, _integer_or_boolean_dtypes, _result_type, ) @@ -69,6 +70,31 @@ def bitwise_and(x1: Array, x2: Array, /) -> Array: return Array._new(ht.bitwise_and(x1._array, x2._array)) +def bitwise_left_shift(x1: Array, x2: Array, /) -> Array: + """ + Shifts the bits of each element ``x1_i`` of the input array ``x1`` to the + left by appending ``x2_i`` (i.e., the respective element in the input array + ``x2``) zeros to the right of ``x1_i``. + + Parameters + ---------- + x1 : Array + First input array. Must have an integer data type. + x2 : Array + Second input array. Must be compatible with ``x1`` and have an integer + data type. Each element must be greater than or equal to ``0``. + """ + if x1.dtype not in _integer_dtypes or x2.dtype not in _integer_dtypes: + raise TypeError("Only integer dtypes are allowed in bitwise_left_shift") + # Call result type here just to raise on disallowed type combinations + _result_type(x1.dtype, x2.dtype) + x1, x2 = Array._normalize_two_args(x1, x2) + # Note: bitwise_left_shift is only defined for x2 nonnegative. + if ht.any(x2._array < 0): + raise ValueError("bitwise_left_shift(x1, x2) is only defined for x2 >= 0") + return Array._new(ht.left_shift(x1._array, x2._array)) + + def equal(x1: Array, x2: Array, /) -> Array: """ Computes the truth value of ``x1_i == x2_i`` for each element ``x1_i`` of @@ -128,3 +154,25 @@ def isnan(x: Array, /) -> Array: if x.dtype not in _numeric_dtypes: raise TypeError("Only numeric dtypes are allowed in isnan") return Array._new(ht.isnan(x._array)) + + +def less(x1: Array, x2: Array, /) -> Array: + """ + Computes the truth value of ``x1_i < x2_i`` for each element ``x1_i`` of + the input array ``x1`` with the respective element ``x2_i`` of the input + array ``x2``. + + Parameters + ---------- + x1 : Array + First input array. Must have a numeric data type. + x2 : Array + Second input array. Must be compatible with ``x1`` and have a numeric + data type. + """ + if x1.dtype not in _numeric_dtypes or x2.dtype not in _numeric_dtypes: + raise TypeError("Only numeric dtypes are allowed in less") + # Call result type here just to raise on disallowed type combinations + _result_type(x1.dtype, x2.dtype) + x1, x2 = Array._normalize_two_args(x1, x2) + return Array._new(ht.less(x1._array, x2._array)) diff --git a/heat/array_api/_utility_functions.py b/heat/array_api/_utility_functions.py index 6400ebece6..ba6fcd71ae 100644 --- a/heat/array_api/_utility_functions.py +++ b/heat/array_api/_utility_functions.py @@ -35,3 +35,33 @@ def all( res = ht.squeeze(res, axis=axis) return Array._new(res) + + +def any( + x: Array, + /, + *, + axis: Optional[Union[int, Tuple[int, ...]]] = None, + keepdims: bool = False, +) -> Array: + """ + Tests whether any input array element evaluates to ``True`` along a specified + axis. + + Parameters + ---------- + x : Array + Input array. + axis : Optional[Union[int, Tuple[int, ...]]] + Axis or axes along which to perform a logical OR reduction. By + default, a logical OR reduction is performed over the entire array. + keepdims : bool + If ``True``, the reduced axes (dimensions) are included in the result + as singleton dimensions. Otherwise, if ``False``, the reduced axes + (dimensions) are be included in the result. Default: ``False``. + """ + res = ht.any(x._array, axis=axis, keepdim=True) + if not keepdims or x._array.ndim == 0: + res = ht.squeeze(res, axis=axis) + + return Array._new(res) diff --git a/heat/core/logical.py b/heat/core/logical.py index c26f46f138..a6be081ea7 100644 --- a/heat/core/logical.py +++ b/heat/core/logical.py @@ -199,6 +199,9 @@ def any( def local_any(t, *args, **kwargs): return torch.any(t != 0, *args, **kwargs) + if keepdim and axis is None: + axis = tuple(range(x.ndim)) + return _operations.__reduce_op( x, local_any, MPI.LOR, axis=axis, out=out, neutral=0, keepdim=keepdim ) diff --git a/heat/core/tests/test_logical.py b/heat/core/tests/test_logical.py index dc318b40c2..852de71d19 100644 --- a/heat/core/tests/test_logical.py +++ b/heat/core/tests/test_logical.py @@ -216,6 +216,10 @@ def test_any(self): self.assertEqual(any_tensor.dtype, ht.bool) self.assertTrue(ht.equal(any_tensor, res)) + # test keepdim + ones_2d = ht.ones((1, 1)) + self.assertEqual(ones_2d.any(keepdim=True).shape, ones_2d.shape) + def test_isclose(self): size = ht.communication.MPI_WORLD.size a = ht.float32([[2, 2], [2, 2]]) From 2ef6e3ab08a21a7e2d3396296c34259a4e3da7a7 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Fri, 17 Jun 2022 22:38:04 +0800 Subject: [PATCH 020/150] Implement `bitwise_invert` --- heat/array_api/__init__.py | 2 ++ heat/array_api/_elementwise_functions.py | 14 ++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index 81a0b05be4..ebdcbda6af 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -75,6 +75,7 @@ add, bitwise_and, bitwise_left_shift, + bitwise_invert, equal, isfinite, isinf, @@ -87,6 +88,7 @@ "add", "bitwise_and", "bitwise_left_shift", + "bitwise_invert", "equal", "isfinite", "isinf", diff --git a/heat/array_api/_elementwise_functions.py b/heat/array_api/_elementwise_functions.py index 795c5f6a6d..2c8f485871 100644 --- a/heat/array_api/_elementwise_functions.py +++ b/heat/array_api/_elementwise_functions.py @@ -95,6 +95,20 @@ def bitwise_left_shift(x1: Array, x2: Array, /) -> Array: return Array._new(ht.left_shift(x1._array, x2._array)) +def bitwise_invert(x: Array, /) -> Array: + """ + Inverts (flips) each bit for each element ``x_i`` of the input array ``x``. + + Parameters + ---------- + x : Array + Input array. Must have an integer or boolean data type. + """ + if x.dtype not in _integer_or_boolean_dtypes: + raise TypeError("Only integer or boolean dtypes are allowed in bitwise_invert") + return Array._new(ht.invert(x._array)) + + def equal(x1: Array, x2: Array, /) -> Array: """ Computes the truth value of ``x1_i == x2_i`` for each element ``x1_i`` of From 574f469e8fca59c764b28ce59ee05ece7d6ccf40 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Fri, 17 Jun 2022 22:41:15 +0800 Subject: [PATCH 021/150] Implement `bitwise_or` --- heat/array_api/__init__.py | 2 ++ heat/array_api/_array_object.py | 2 +- heat/array_api/_elementwise_functions.py | 14 ++++++++++++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index ebdcbda6af..ffdcb817e7 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -76,6 +76,7 @@ bitwise_and, bitwise_left_shift, bitwise_invert, + bitwise_or, equal, isfinite, isinf, @@ -89,6 +90,7 @@ "bitwise_and", "bitwise_left_shift", "bitwise_invert", + "bitwise_or", "equal", "isfinite", "isinf", diff --git a/heat/array_api/_array_object.py b/heat/array_api/_array_object.py index a1fe92ae8d..e3ca1c9f51 100644 --- a/heat/array_api/_array_object.py +++ b/heat/array_api/_array_object.py @@ -503,7 +503,7 @@ def __or__(self: Array, other: Union[int, bool, Array], /) -> Array: other = self._check_allowed_dtypes(other, "integer or boolean", "__or__") if other is NotImplemented: return other - # self, other = self._normalize_two_args(self, other) + self, other = self._normalize_two_args(self, other) res = self._array.__or__(other._array) return self.__class__._new(res) diff --git a/heat/array_api/_elementwise_functions.py b/heat/array_api/_elementwise_functions.py index 2c8f485871..d476a9be01 100644 --- a/heat/array_api/_elementwise_functions.py +++ b/heat/array_api/_elementwise_functions.py @@ -109,6 +109,20 @@ def bitwise_invert(x: Array, /) -> Array: return Array._new(ht.invert(x._array)) +def bitwise_or(x1: Array, x2: Array, /) -> Array: + """ + Computes the bitwise OR of the underlying binary representation of each + element ``x1_i`` of the input array ``x1`` with the respective element + ``x2_i`` of the input array ``x2``. + """ + if x1.dtype not in _integer_or_boolean_dtypes or x2.dtype not in _integer_or_boolean_dtypes: + raise TypeError("Only integer or boolean dtypes are allowed in bitwise_or") + # Call result type here just to raise on disallowed type combinations + _result_type(x1.dtype, x2.dtype) + x1, x2 = Array._normalize_two_args(x1, x2) + return Array._new(ht.bitwise_or(x1._array, x2._array)) + + def equal(x1: Array, x2: Array, /) -> Array: """ Computes the truth value of ``x1_i == x2_i`` for each element ``x1_i`` of From b684c86190eb2e08d10a7ed759e3d63af9045794 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Sat, 18 Jun 2022 14:42:00 +0800 Subject: [PATCH 022/150] Fix documentation for `_normalize_two_args` --- heat/array_api/__init__.py | 2 ++ heat/array_api/_array_object.py | 22 ++++++---------- heat/array_api/_elementwise_functions.py | 32 ++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 14 deletions(-) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index ffdcb817e7..0c114a2907 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -77,6 +77,7 @@ bitwise_left_shift, bitwise_invert, bitwise_or, + bitwise_right_shift, equal, isfinite, isinf, @@ -91,6 +92,7 @@ "bitwise_left_shift", "bitwise_invert", "bitwise_or", + "bitwise_right_shift", "equal", "isfinite", "isinf", diff --git a/heat/array_api/_array_object.py b/heat/array_api/_array_object.py index e3ca1c9f51..4cf68a8bb1 100644 --- a/heat/array_api/_array_object.py +++ b/heat/array_api/_array_object.py @@ -127,24 +127,18 @@ def _promote_scalar(self, scalar): def _normalize_two_args(x1, x2) -> Tuple[Array, Array]: """ Normalize inputs to two arg functions to fix type promotion rules - NumPy deviates from the spec type promotion rules in cases where one + Heat deviates from the spec type promotion rules in cases where one argument is 0-dimensional and the other is not. For example: - >>> import numpy as np - >>> a = np.array([1.0], dtype=np.float32) - >>> b = np.array(1.0, dtype=np.float64) - >>> np.add(a, b) # The spec says this should be float64 - array([2.], dtype=float32) + >>> import heat as ht + >>> a = ht.array([1.0], dtype=ht.float32) + >>> b = ht.array(1.0, dtype=ht.float64) + >>> ht.add(a, b) # The spec says this should be float64 + DNDarray([2.], dtype=ht.float32, device=cpu:0, split=None) To fix this, we add a dimension to the 0-dimension array before passing it through. This works because a dimension would be added anyway from - broadcasting, so the resulting shape is the same, but this prevents NumPy + broadcasting, so the resulting shape is the same, but this prevents Heat from not promoting the dtype. """ - # Another option would be to use signature=(x1.dtype, x2.dtype, None), - # but that only works for ufuncs, so we would have to call the ufuncs - # directly in the operator methods. One should also note that this - # sort of trick wouldn't work for functions like searchsorted, which - # don't do normal broadcasting, but there aren't any functions like - # that in the array API namespace. if x1.ndim == 0 and x2.ndim != 0: # The _array[None] workaround was chosen because it is relatively # performant. broadcast_to(x1._array, x2.shape) is much slower. We @@ -552,7 +546,7 @@ def __rshift__(self: Array, other: Union[int, Array], /) -> Array: other = self._check_allowed_dtypes(other, "integer", "__rshift__") if other is NotImplemented: return other - # self, other = self._normalize_two_args(self, other) + self, other = self._normalize_two_args(self, other) res = self._array.__rshift__(other._array) return self.__class__._new(res) diff --git a/heat/array_api/_elementwise_functions.py b/heat/array_api/_elementwise_functions.py index d476a9be01..6f53205b1e 100644 --- a/heat/array_api/_elementwise_functions.py +++ b/heat/array_api/_elementwise_functions.py @@ -114,6 +114,14 @@ def bitwise_or(x1: Array, x2: Array, /) -> Array: Computes the bitwise OR of the underlying binary representation of each element ``x1_i`` of the input array ``x1`` with the respective element ``x2_i`` of the input array ``x2``. + + Parameters + ---------- + x1 : Array + First input array. Must have an integer or boolean data type. + x2 : Array + Second input array. Must be compatible with ``x1`` and have an integer + or boolean data type. """ if x1.dtype not in _integer_or_boolean_dtypes or x2.dtype not in _integer_or_boolean_dtypes: raise TypeError("Only integer or boolean dtypes are allowed in bitwise_or") @@ -123,6 +131,30 @@ def bitwise_or(x1: Array, x2: Array, /) -> Array: return Array._new(ht.bitwise_or(x1._array, x2._array)) +def bitwise_right_shift(x1: Array, x2: Array, /) -> Array: + """ + Shifts the bits of each element ``x1_i`` of the input array ``x1`` to the + right according to the respective element ``x2_i`` of the input array ``x2``. + + Parameters + ---------- + x1 : Array + First input array. Must have an integer data type. + x2 : Array + Second input array. Must be compatible with ``x1`` and have an integer + data type. Each element must be greater than or equal to ``0``. + """ + if x1.dtype not in _integer_dtypes or x2.dtype not in _integer_dtypes: + raise TypeError("Only integer dtypes are allowed in bitwise_right_shift") + # Call result type here just to raise on disallowed type combinations + _result_type(x1.dtype, x2.dtype) + x1, x2 = Array._normalize_two_args(x1, x2) + # Note: bitwise_right_shift is only defined for x2 nonnegative. + if ht.any(x2._array < 0): + raise ValueError("bitwise_right_shift(x1, x2) is only defined for x2 >= 0") + return Array._new(ht.right_shift(x1._array, x2._array)) + + def equal(x1: Array, x2: Array, /) -> Array: """ Computes the truth value of ``x1_i == x2_i`` for each element ``x1_i`` of From 6c50d7b5edce7cd5c11a49e01cca662a00a00385 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Sat, 18 Jun 2022 15:02:20 +0800 Subject: [PATCH 023/150] Fix bug in `linalg.matrix_norm` f0a169b introduced a change in ht.abs where the dtype is not promoted to float by default. This caused the tests to fail. --- heat/core/linalg/basics.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/heat/core/linalg/basics.py b/heat/core/linalg/basics.py index bc5d3e9e65..d7f9c1e10a 100644 --- a/heat/core/linalg/basics.py +++ b/heat/core/linalg/basics.py @@ -1174,11 +1174,13 @@ def matrix_norm( row_axis, col_axis = axis + dtype = types.promote_types(x.dtype, types.float32) + if ord == 1: if col_axis > row_axis and not keepdims: col_axis -= 1 return statistics.max( - arithmetics.sum(rounding.abs(x), axis=row_axis, keepdim=keepdims), + arithmetics.sum(rounding.abs(x, dtype=dtype), axis=row_axis, keepdim=keepdims), axis=col_axis, keepdim=keepdims, ) @@ -1186,7 +1188,7 @@ def matrix_norm( if col_axis > row_axis and not keepdims: col_axis -= 1 return statistics.min( - arithmetics.sum(rounding.abs(x), axis=row_axis, keepdim=keepdims), + arithmetics.sum(rounding.abs(x, dtype=dtype), axis=row_axis, keepdim=keepdims), axis=col_axis, keepdim=keepdims, ) @@ -1198,7 +1200,7 @@ def matrix_norm( if row_axis > col_axis and not keepdims: row_axis -= 1 return statistics.max( - arithmetics.sum(rounding.abs(x), axis=col_axis, keepdim=keepdims), + arithmetics.sum(rounding.abs(x, dtype=dtype), axis=col_axis, keepdim=keepdims), axis=row_axis, keepdim=keepdims, ) @@ -1206,7 +1208,7 @@ def matrix_norm( if row_axis > col_axis and not keepdims: row_axis -= 1 return statistics.min( - arithmetics.sum(rounding.abs(x), axis=col_axis, keepdim=keepdims), + arithmetics.sum(rounding.abs(x, dtype=dtype), axis=col_axis, keepdim=keepdims), axis=row_axis, keepdim=keepdims, ) From 9fb9bdd0a221e13bcbc29748b23420d0c78a4b60 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Sat, 18 Jun 2022 15:18:21 +0800 Subject: [PATCH 024/150] Implement `bitwise_xor` --- heat/array_api/__init__.py | 2 ++ heat/array_api/_array_object.py | 2 +- heat/array_api/_elementwise_functions.py | 22 ++++++++++++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index 0c114a2907..fd76fa67aa 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -78,6 +78,7 @@ bitwise_invert, bitwise_or, bitwise_right_shift, + bitwise_xor, equal, isfinite, isinf, @@ -93,6 +94,7 @@ "bitwise_invert", "bitwise_or", "bitwise_right_shift", + "bitwise_xor", "equal", "isfinite", "isinf", diff --git a/heat/array_api/_array_object.py b/heat/array_api/_array_object.py index 4cf68a8bb1..eaff0dad37 100644 --- a/heat/array_api/_array_object.py +++ b/heat/array_api/_array_object.py @@ -619,7 +619,7 @@ def __xor__(self: Array, other: Union[int, bool, Array], /) -> Array: other = self._check_allowed_dtypes(other, "integer or boolean", "__xor__") if other is NotImplemented: return other - # self, other = self._normalize_two_args(self, other) + self, other = self._normalize_two_args(self, other) res = self._array.__xor__(other._array) return self.__class__._new(res) diff --git a/heat/array_api/_elementwise_functions.py b/heat/array_api/_elementwise_functions.py index 6f53205b1e..10a1e6a489 100644 --- a/heat/array_api/_elementwise_functions.py +++ b/heat/array_api/_elementwise_functions.py @@ -155,6 +155,28 @@ def bitwise_right_shift(x1: Array, x2: Array, /) -> Array: return Array._new(ht.right_shift(x1._array, x2._array)) +def bitwise_xor(x1: Array, x2: Array, /) -> Array: + """ + Computes the bitwise XOR of the underlying binary representation of each element + ``x1_i`` of the input array ``x1`` with the respective element ``x2_i`` of the + input array ``x2``. + + Parameters + ---------- + x1 : Array + First input array. Must have an integer or boolean data type. + x2 : Array + Second input array. Must be compatible with ``x1`` and have an integer + or boolean data type. + """ + if x1.dtype not in _integer_or_boolean_dtypes or x2.dtype not in _integer_or_boolean_dtypes: + raise TypeError("Only integer or boolean dtypes are allowed in bitwise_xor") + # Call result type here just to raise on disallowed type combinations + _result_type(x1.dtype, x2.dtype) + x1, x2 = Array._normalize_two_args(x1, x2) + return Array._new(ht.bitwise_xor(x1._array, x2._array)) + + def equal(x1: Array, x2: Array, /) -> Array: """ Computes the truth value of ``x1_i == x2_i`` for each element ``x1_i`` of From ad655ee75a3883b7391ce4967df931d0876c6edf Mon Sep 17 00:00:00 2001 From: neosunhan Date: Sat, 18 Jun 2022 15:22:03 +0800 Subject: [PATCH 025/150] Implement `equal` --- heat/array_api/_array_object.py | 2 +- heat/array_api/_elementwise_functions.py | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/heat/array_api/_array_object.py b/heat/array_api/_array_object.py index eaff0dad37..63a18ebcd5 100644 --- a/heat/array_api/_array_object.py +++ b/heat/array_api/_array_object.py @@ -236,7 +236,7 @@ def __eq__(self: Array, other: Union[int, float, bool, Array], /) -> Array: other = self._check_allowed_dtypes(other, "all", "__eq__") if other is NotImplemented: return other - # self, other = self._normalize_two_args(self, other) + self, other = self._normalize_two_args(self, other) res = self._array.__eq__(other._array) return self.__class__._new(res) diff --git a/heat/array_api/_elementwise_functions.py b/heat/array_api/_elementwise_functions.py index 10a1e6a489..1463f24bba 100644 --- a/heat/array_api/_elementwise_functions.py +++ b/heat/array_api/_elementwise_functions.py @@ -190,6 +190,9 @@ def equal(x1: Array, x2: Array, /) -> Array: x2 : Array Second input array. Must be compatible with ``x1``. """ + # Call result type here just to raise on disallowed type combinations + _result_type(x1.dtype, x2.dtype) + x1, x2 = Array._normalize_two_args(x1, x2) return Array._new(ht.eq(x1._array, x2._array)) From 41143f7e5a54ef8b21167f598d9bdf5ca7217139 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Sat, 18 Jun 2022 15:26:35 +0800 Subject: [PATCH 026/150] Implement `floor_divide` --- heat/array_api/__init__.py | 2 ++ heat/array_api/_array_object.py | 2 +- heat/array_api/_elementwise_functions.py | 23 +++++++++++++++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index fd76fa67aa..9ec664e29c 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -80,6 +80,7 @@ bitwise_right_shift, bitwise_xor, equal, + floor_divide, isfinite, isinf, isnan, @@ -96,6 +97,7 @@ "bitwise_right_shift", "bitwise_xor", "equal", + "floor_divide", "isfinite", "isinf", "isnan", diff --git a/heat/array_api/_array_object.py b/heat/array_api/_array_object.py index 63a18ebcd5..1cb812986f 100644 --- a/heat/array_api/_array_object.py +++ b/heat/array_api/_array_object.py @@ -264,7 +264,7 @@ def __floordiv__(self: Array, other: Union[int, float, Array], /) -> Array: other = self._check_allowed_dtypes(other, "numeric", "__floordiv__") if other is NotImplemented: return other - # self, other = self._normalize_two_args(self, other) + self, other = self._normalize_two_args(self, other) res = self._array.__floordiv__(other._array) return self.__class__._new(res) diff --git a/heat/array_api/_elementwise_functions.py b/heat/array_api/_elementwise_functions.py index 1463f24bba..9df4049d75 100644 --- a/heat/array_api/_elementwise_functions.py +++ b/heat/array_api/_elementwise_functions.py @@ -196,6 +196,29 @@ def equal(x1: Array, x2: Array, /) -> Array: return Array._new(ht.eq(x1._array, x2._array)) +def floor_divide(x1: Array, x2: Array, /) -> Array: + """ + Rounds the result of dividing each element ``x1_i`` of the input array ``x1`` + by the respective element ``x2_i`` of the input array ``x2`` to the greatest + (i.e., closest to ``+infinity``) integer-value number that is not greater than + the division result. + + Parameters + ---------- + x1 : Array + First input array. Must have a numeric data type. + x2 : Array + Second input array. Must be compatible with ``x1`` and have a numeric + data type. + """ + if x1.dtype not in _numeric_dtypes or x2.dtype not in _numeric_dtypes: + raise TypeError("Only numeric dtypes are allowed in floor_divide") + # Call result type here just to raise on disallowed type combinations + _result_type(x1.dtype, x2.dtype) + x1, x2 = Array._normalize_two_args(x1, x2) + return Array._new(ht.floor_divide(x1._array, x2._array)) + + def isfinite(x: Array, /) -> Array: """ Tests each element ``x_i`` of the input array ``x`` to determine if finite From aeb97e49d81e9b738736cc67be1af39a4a27b5c6 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Sat, 18 Jun 2022 15:28:52 +0800 Subject: [PATCH 027/150] Implement `greater_equal` --- heat/array_api/__init__.py | 2 ++ heat/array_api/_array_object.py | 2 +- heat/array_api/_elementwise_functions.py | 22 ++++++++++++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index 9ec664e29c..b0864f47e0 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -81,6 +81,7 @@ bitwise_xor, equal, floor_divide, + greater_equal, isfinite, isinf, isnan, @@ -98,6 +99,7 @@ "bitwise_xor", "equal", "floor_divide", + "greater_equal", "isfinite", "isinf", "isnan", diff --git a/heat/array_api/_array_object.py b/heat/array_api/_array_object.py index 1cb812986f..b52bcf9635 100644 --- a/heat/array_api/_array_object.py +++ b/heat/array_api/_array_object.py @@ -281,7 +281,7 @@ def __ge__(self: Array, other: Union[int, float, Array], /) -> Array: other = self._check_allowed_dtypes(other, "numeric", "__ge__") if other is NotImplemented: return other - # self, other = self._normalize_two_args(self, other) + self, other = self._normalize_two_args(self, other) res = self._array.__ge__(other._array) return self.__class__._new(res) diff --git a/heat/array_api/_elementwise_functions.py b/heat/array_api/_elementwise_functions.py index 9df4049d75..ac623a7387 100644 --- a/heat/array_api/_elementwise_functions.py +++ b/heat/array_api/_elementwise_functions.py @@ -219,6 +219,28 @@ def floor_divide(x1: Array, x2: Array, /) -> Array: return Array._new(ht.floor_divide(x1._array, x2._array)) +def greater_equal(x1: Array, x2: Array, /) -> Array: + """ + Computes the truth value of ``x1_i >= x2_i`` for each element ``x1_i`` of + the input array ``x1`` with the respective element ``x2_i`` of the input + array ``x2``. + + Parameters + ---------- + x1 : Array + First input array. Must have a numeric data type. + x2 : Array + Second input array. Must be compatible with ``x1`` and have a numeric + data type. + """ + if x1.dtype not in _numeric_dtypes or x2.dtype not in _numeric_dtypes: + raise TypeError("Only numeric dtypes are allowed in greater_equal") + # Call result type here just to raise on disallowed type combinations + _result_type(x1.dtype, x2.dtype) + x1, x2 = Array._normalize_two_args(x1, x2) + return Array._new(ht.greater_equal(x1._array, x2._array)) + + def isfinite(x: Array, /) -> Array: """ Tests each element ``x_i`` of the input array ``x`` to determine if finite From 58308db903a488fecf53c3a502d7061f5d6b3b25 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Sat, 18 Jun 2022 15:30:32 +0800 Subject: [PATCH 028/150] Implement `greater` --- heat/array_api/__init__.py | 2 ++ heat/array_api/_array_object.py | 2 +- heat/array_api/_elementwise_functions.py | 22 ++++++++++++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index b0864f47e0..51efb13ee6 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -81,6 +81,7 @@ bitwise_xor, equal, floor_divide, + greater, greater_equal, isfinite, isinf, @@ -99,6 +100,7 @@ "bitwise_xor", "equal", "floor_divide", + "greater", "greater_equal", "isfinite", "isinf", diff --git a/heat/array_api/_array_object.py b/heat/array_api/_array_object.py index b52bcf9635..2ec7dbdc40 100644 --- a/heat/array_api/_array_object.py +++ b/heat/array_api/_array_object.py @@ -327,7 +327,7 @@ def __gt__(self: Array, other: Union[int, float, Array], /) -> Array: other = self._check_allowed_dtypes(other, "numeric", "__gt__") if other is NotImplemented: return other - # self, other = self._normalize_two_args(self, other) + self, other = self._normalize_two_args(self, other) res = self._array.__gt__(other._array) return self.__class__._new(res) diff --git a/heat/array_api/_elementwise_functions.py b/heat/array_api/_elementwise_functions.py index ac623a7387..016a526d1e 100644 --- a/heat/array_api/_elementwise_functions.py +++ b/heat/array_api/_elementwise_functions.py @@ -219,6 +219,28 @@ def floor_divide(x1: Array, x2: Array, /) -> Array: return Array._new(ht.floor_divide(x1._array, x2._array)) +def greater(x1: Array, x2: Array, /) -> Array: + """ + Computes the truth value of ``x1_i > x2_i`` for each element ``x1_i`` of + the input array ``x1`` with the respective element ``x2_i`` of the input + array ``x2``. + + Parameters + ---------- + x1 : Array + First input array. Must have a numeric data type. + x2 : Array + Second input array. Must be compatible with ``x1`` and have a numeric + data type. + """ + if x1.dtype not in _numeric_dtypes or x2.dtype not in _numeric_dtypes: + raise TypeError("Only numeric dtypes are allowed in greater") + # Call result type here just to raise on disallowed type combinations + _result_type(x1.dtype, x2.dtype) + x1, x2 = Array._normalize_two_args(x1, x2) + return Array._new(ht.greater(x1._array, x2._array)) + + def greater_equal(x1: Array, x2: Array, /) -> Array: """ Computes the truth value of ``x1_i >= x2_i`` for each element ``x1_i`` of From 544ab0e3e567d1e3d4da1dc5bb00b621e3b265d9 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Sat, 18 Jun 2022 15:33:12 +0800 Subject: [PATCH 029/150] Implement `less_equal` --- heat/array_api/__init__.py | 2 ++ heat/array_api/_array_object.py | 2 +- heat/array_api/_elementwise_functions.py | 22 ++++++++++++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index 51efb13ee6..6194ad0b7c 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -87,6 +87,7 @@ isinf, isnan, less, + less_equal, ) __all__ += [ @@ -106,6 +107,7 @@ "isinf", "isnan", "less", + "less_equal", ] from ._manipulation_functions import ( diff --git a/heat/array_api/_array_object.py b/heat/array_api/_array_object.py index 2ec7dbdc40..71ba4b2508 100644 --- a/heat/array_api/_array_object.py +++ b/heat/array_api/_array_object.py @@ -370,7 +370,7 @@ def __le__(self: Array, other: Union[int, float, Array], /) -> Array: other = self._check_allowed_dtypes(other, "numeric", "__le__") if other is NotImplemented: return other - # self, other = self._normalize_two_args(self, other) + self, other = self._normalize_two_args(self, other) res = self._array.__le__(other._array) return self.__class__._new(res) diff --git a/heat/array_api/_elementwise_functions.py b/heat/array_api/_elementwise_functions.py index 016a526d1e..890d07c4e3 100644 --- a/heat/array_api/_elementwise_functions.py +++ b/heat/array_api/_elementwise_functions.py @@ -328,3 +328,25 @@ def less(x1: Array, x2: Array, /) -> Array: _result_type(x1.dtype, x2.dtype) x1, x2 = Array._normalize_two_args(x1, x2) return Array._new(ht.less(x1._array, x2._array)) + + +def less_equal(x1: Array, x2: Array, /) -> Array: + """ + Computes the truth value of ``x1_i <= x2_i`` for each element ``x1_i`` + of the input array ``x1`` with the respective element ``x2_i`` of the + input array ``x2``. + + Parameters + ---------- + x1 : Array + First input array. Must have a numeric data type. + x2 : Array + Second input array. Must be compatible with ``x1`` and have a numeric + data type. + """ + if x1.dtype not in _numeric_dtypes or x2.dtype not in _numeric_dtypes: + raise TypeError("Only numeric dtypes are allowed in less_equal") + # Call result type here just to raise on disallowed type combinations + _result_type(x1.dtype, x2.dtype) + x1, x2 = Array._normalize_two_args(x1, x2) + return Array._new(ht.less_equal(x1._array, x2._array)) From 7ff5119a039d630120f733e762d63793cdbc0778 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Sat, 18 Jun 2022 15:44:23 +0800 Subject: [PATCH 030/150] Implement `remainder` --- heat/array_api/__init__.py | 10 ++++++++++ heat/array_api/_array_object.py | 2 +- heat/array_api/_elementwise_functions.py | 21 ++++++++++++++++++++ heat/array_api/linalg.py | 25 ++++++++++++++++++++++++ 4 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 heat/array_api/linalg.py diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index 6194ad0b7c..44c71f9223 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -88,6 +88,7 @@ isnan, less, less_equal, + remainder, ) __all__ += [ @@ -108,8 +109,17 @@ "isnan", "less", "less_equal", + "remainder", ] +from . import linalg + +__all__ += ["linalg"] + +from .linalg import matmul + +__all__ += ["matmul"] + from ._manipulation_functions import ( reshape, ) diff --git a/heat/array_api/_array_object.py b/heat/array_api/_array_object.py index 71ba4b2508..5e4a7f5920 100644 --- a/heat/array_api/_array_object.py +++ b/heat/array_api/_array_object.py @@ -437,7 +437,7 @@ def __mod__(self: Array, other: Union[int, float, Array], /) -> Array: other = self._check_allowed_dtypes(other, "numeric", "__mod__") if other is NotImplemented: return other - # self, other = self._normalize_two_args(self, other) + self, other = self._normalize_two_args(self, other) res = self._array.__mod__(other._array) return self.__class__._new(res) diff --git a/heat/array_api/_elementwise_functions.py b/heat/array_api/_elementwise_functions.py index 890d07c4e3..0f25c63a6e 100644 --- a/heat/array_api/_elementwise_functions.py +++ b/heat/array_api/_elementwise_functions.py @@ -350,3 +350,24 @@ def less_equal(x1: Array, x2: Array, /) -> Array: _result_type(x1.dtype, x2.dtype) x1, x2 = Array._normalize_two_args(x1, x2) return Array._new(ht.less_equal(x1._array, x2._array)) + + +def remainder(x1: Array, x2: Array, /) -> Array: + """ + Returns the remainder of division for each element ``x1_i`` of the input + array ``x1`` and the respective element ``x2_i`` of the input array ``x2``. + + Parameters + ---------- + x1 : Array + Dividend input array. Must have a numeric data type. + x2 : Array + Divisor input array. Must be compatible with ``x1`` and have a numeric + data type. + """ + if x1.dtype not in _numeric_dtypes or x2.dtype not in _numeric_dtypes: + raise TypeError("Only numeric dtypes are allowed in remainder") + # Call result type here just to raise on disallowed type combinations + _result_type(x1.dtype, x2.dtype) + x1, x2 = Array._normalize_two_args(x1, x2) + return Array._new(ht.remainder(x1._array, x2._array)) diff --git a/heat/array_api/linalg.py b/heat/array_api/linalg.py new file mode 100644 index 0000000000..e453c11f1c --- /dev/null +++ b/heat/array_api/linalg.py @@ -0,0 +1,25 @@ +""" +Linear Algebra Extension for the Array API standard. +""" +from __future__ import annotations + +from ._dtypes import _numeric_dtypes +from ._array_object import Array + +import heat as ht + + +def matmul(x1: Array, x2: Array, /) -> Array: + """ + Computes the matrix product. + + Parameters + ---------- + x1 : Array + First input array. Must have a numeric data type and at least one dimension. + x2 : Array + Second input array. Must have a numeric data type and at least one dimension. + """ + if x1.dtype not in _numeric_dtypes or x2.dtype not in _numeric_dtypes: + raise TypeError("Only numeric dtypes are allowed in matmul") + return Array._new(ht.matmul(x1._array, x2._array)) From fd627860412e5bba3508307e5c38807ffd3a8cf7 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Sat, 18 Jun 2022 15:46:53 +0800 Subject: [PATCH 031/150] Implement `multiply` --- heat/array_api/__init__.py | 2 ++ heat/array_api/_array_object.py | 2 +- heat/array_api/_elementwise_functions.py | 21 +++++++++++++++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index 44c71f9223..515dbd858a 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -88,6 +88,7 @@ isnan, less, less_equal, + multiply, remainder, ) @@ -109,6 +110,7 @@ "isnan", "less", "less_equal", + "multiply", "remainder", ] diff --git a/heat/array_api/_array_object.py b/heat/array_api/_array_object.py index 5e4a7f5920..5341d1e29c 100644 --- a/heat/array_api/_array_object.py +++ b/heat/array_api/_array_object.py @@ -454,7 +454,7 @@ def __mul__(self: Array, other: Union[int, float, Array], /) -> Array: other = self._check_allowed_dtypes(other, "numeric", "__mul__") if other is NotImplemented: return other - # self, other = self._normalize_two_args(self, other) + self, other = self._normalize_two_args(self, other) res = self._array.__mul__(other._array) return self.__class__._new(res) diff --git a/heat/array_api/_elementwise_functions.py b/heat/array_api/_elementwise_functions.py index 0f25c63a6e..5ae27b4271 100644 --- a/heat/array_api/_elementwise_functions.py +++ b/heat/array_api/_elementwise_functions.py @@ -352,6 +352,27 @@ def less_equal(x1: Array, x2: Array, /) -> Array: return Array._new(ht.less_equal(x1._array, x2._array)) +def multiply(x1: Array, x2: Array, /) -> Array: + """ + Calculates the product for each element ``x1_i`` of the input array ``x1`` + with the respective element ``x2_i`` of the input array ``x2``. + + Parameters + ---------- + x1 : Array + First input array. Must have a numeric data type. + x2 : Array + Second input array. Must be compatible with ``x1`` and have a numeric + data type. + """ + if x1.dtype not in _numeric_dtypes or x2.dtype not in _numeric_dtypes: + raise TypeError("Only numeric dtypes are allowed in multiply") + # Call result type here just to raise on disallowed type combinations + _result_type(x1.dtype, x2.dtype) + x1, x2 = Array._normalize_two_args(x1, x2) + return Array._new(ht.multiply(x1._array, x2._array)) + + def remainder(x1: Array, x2: Array, /) -> Array: """ Returns the remainder of division for each element ``x1_i`` of the input From 48b66cff80e1c402c781e2e05d1b5a7aeb334090 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Sat, 18 Jun 2022 15:49:22 +0800 Subject: [PATCH 032/150] Implement `not_equal` --- heat/array_api/__init__.py | 2 ++ heat/array_api/_array_object.py | 2 +- heat/array_api/_elementwise_functions.py | 19 +++++++++++++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index 515dbd858a..e5f5e8957b 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -89,6 +89,7 @@ less, less_equal, multiply, + not_equal, remainder, ) @@ -111,6 +112,7 @@ "less", "less_equal", "multiply", + "not_equal", "remainder", ] diff --git a/heat/array_api/_array_object.py b/heat/array_api/_array_object.py index 5341d1e29c..55d795db01 100644 --- a/heat/array_api/_array_object.py +++ b/heat/array_api/_array_object.py @@ -471,7 +471,7 @@ def __ne__(self: Array, other: Union[int, float, bool, Array], /) -> Array: other = self._check_allowed_dtypes(other, "all", "__ne__") if other is NotImplemented: return other - # self, other = self._normalize_two_args(self, other) + self, other = self._normalize_two_args(self, other) res = self._array.__ne__(other._array) return self.__class__._new(res) diff --git a/heat/array_api/_elementwise_functions.py b/heat/array_api/_elementwise_functions.py index 5ae27b4271..0c5ee2920f 100644 --- a/heat/array_api/_elementwise_functions.py +++ b/heat/array_api/_elementwise_functions.py @@ -373,6 +373,25 @@ def multiply(x1: Array, x2: Array, /) -> Array: return Array._new(ht.multiply(x1._array, x2._array)) +def not_equal(x1: Array, x2: Array, /) -> Array: + """ + Computes the truth value of ``x1_i != x2_i`` for each element ``x1_i`` + of the input array ``x1`` with the respective element ``x2_i`` of the + input array ``x2``. + + Parameters + ---------- + x1 : Array + First input array. + x2 : Array + Second input array. Must be compatible with ``x1``. + """ + # Call result type here just to raise on disallowed type combinations + _result_type(x1.dtype, x2.dtype) + x1, x2 = Array._normalize_two_args(x1, x2) + return Array._new(ht.not_equal(x1._array, x2._array)) + + def remainder(x1: Array, x2: Array, /) -> Array: """ Returns the remainder of division for each element ``x1_i`` of the input From 1c586cc472c86e83eb295772dcd77502ec9eeec0 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Sat, 18 Jun 2022 15:51:17 +0800 Subject: [PATCH 033/150] Implement `negative` --- heat/array_api/__init__.py | 2 ++ heat/array_api/_elementwise_functions.py | 15 +++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index e5f5e8957b..8595ae3604 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -89,6 +89,7 @@ less, less_equal, multiply, + negative, not_equal, remainder, ) @@ -112,6 +113,7 @@ "less", "less_equal", "multiply", + "negative", "not_equal", "remainder", ] diff --git a/heat/array_api/_elementwise_functions.py b/heat/array_api/_elementwise_functions.py index 0c5ee2920f..0c80ae9e51 100644 --- a/heat/array_api/_elementwise_functions.py +++ b/heat/array_api/_elementwise_functions.py @@ -373,6 +373,21 @@ def multiply(x1: Array, x2: Array, /) -> Array: return Array._new(ht.multiply(x1._array, x2._array)) +def negative(x: Array, /) -> Array: + """ + Computes the numerical negative of each element ``x_i`` + (i.e., ``y_i = -x_i``) of the input array ``x``. + + Parameters + ---------- + x : Array + Input array. Must have a numeric data type. + """ + if x.dtype not in _numeric_dtypes: + raise TypeError("Only numeric dtypes are allowed in negative") + return Array._new(ht.negative(x._array)) + + def not_equal(x1: Array, x2: Array, /) -> Array: """ Computes the truth value of ``x1_i != x2_i`` for each element ``x1_i`` From ba8a78cb06fc01ffcbdfd9fe49751b23685c15d6 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Sat, 18 Jun 2022 15:52:48 +0800 Subject: [PATCH 034/150] Implement `positive` --- heat/array_api/__init__.py | 2 ++ heat/array_api/_elementwise_functions.py | 15 +++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index 8595ae3604..2869350177 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -91,6 +91,7 @@ multiply, negative, not_equal, + positive, remainder, ) @@ -115,6 +116,7 @@ "multiply", "negative", "not_equal", + "positive", "remainder", ] diff --git a/heat/array_api/_elementwise_functions.py b/heat/array_api/_elementwise_functions.py index 0c80ae9e51..c0bf57636e 100644 --- a/heat/array_api/_elementwise_functions.py +++ b/heat/array_api/_elementwise_functions.py @@ -407,6 +407,21 @@ def not_equal(x1: Array, x2: Array, /) -> Array: return Array._new(ht.not_equal(x1._array, x2._array)) +def positive(x: Array, /) -> Array: + """ + Computes the numerical positive of each element ``x_i`` + (i.e., ``y_i = +x_i``) of the input array ``x``. + + Parameters + ---------- + x : Array + Input array. Must have a numeric data type. + """ + if x.dtype not in _numeric_dtypes: + raise TypeError("Only numeric dtypes are allowed in positive") + return Array._new(ht.positive(x._array)) + + def remainder(x1: Array, x2: Array, /) -> Array: """ Returns the remainder of division for each element ``x1_i`` of the input From bce5b0ac466ccadfe8c6d8d16a1b193d45a9bce9 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Sat, 18 Jun 2022 15:59:00 +0800 Subject: [PATCH 035/150] Implement `pow` --- heat/array_api/__init__.py | 2 ++ heat/array_api/_array_object.py | 8 ++------ heat/array_api/_elementwise_functions.py | 25 ++++++++++++++++++++++++ 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index 2869350177..fac79d23c5 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -92,6 +92,7 @@ negative, not_equal, positive, + pow, remainder, ) @@ -117,6 +118,7 @@ "negative", "not_equal", "positive", + "pow", "remainder", ] diff --git a/heat/array_api/_array_object.py b/heat/array_api/_array_object.py index 55d795db01..9448218d43 100644 --- a/heat/array_api/_array_object.py +++ b/heat/array_api/_array_object.py @@ -521,15 +521,11 @@ def __pow__(self: Array, other: Union[int, float, Array], /) -> Array: other : Union[int, float, array] Other array. Must have a numeric data type. """ - # from ._elementwise_functions import pow - other = self._check_allowed_dtypes(other, "numeric", "__pow__") if other is NotImplemented: return other - # Note: NumPy's __pow__ does not follow type promotion rules for 0-d - # arrays, so we use pow() here instead. - # return pow(self, other) - res = self._array.__pow__() + self, other = self._normalize_two_args(self, other) + res = self._array.__pow__(other._array) return self.__class__._new(res) def __rshift__(self: Array, other: Union[int, Array], /) -> Array: diff --git a/heat/array_api/_elementwise_functions.py b/heat/array_api/_elementwise_functions.py index c0bf57636e..a9e53e4995 100644 --- a/heat/array_api/_elementwise_functions.py +++ b/heat/array_api/_elementwise_functions.py @@ -422,6 +422,31 @@ def positive(x: Array, /) -> Array: return Array._new(ht.positive(x._array)) +def pow(x1: Array, x2: Array, /) -> Array: + """ + Calculates an approximation of exponentiation by raising each element + ``x1_i`` (the base) of the input array ``x1`` to the power of + ``x2_i`` (the exponent), where ``x2_i`` is the corresponding element of + the input array ``x2``. + + Parameters + ---------- + x1 : Array + First input array whose elements correspond to the exponentiation base. + Must have a numeric data type. + x2 : Array + Second input array whose elements correspond to the exponentiation exponent. + Must be compatible with ``x1`` and have a numeric + data type. + """ + if x1.dtype not in _numeric_dtypes or x2.dtype not in _numeric_dtypes: + raise TypeError("Only numeric dtypes are allowed in pow") + # Call result type here just to raise on disallowed type combinations + _result_type(x1.dtype, x2.dtype) + x1, x2 = Array._normalize_two_args(x1, x2) + return Array._new(ht.pow(x1._array, x2._array)) + + def remainder(x1: Array, x2: Array, /) -> Array: """ Returns the remainder of division for each element ``x1_i`` of the input From e6236b74de150a78626d10b6da5b4462019dfceb Mon Sep 17 00:00:00 2001 From: neosunhan Date: Sat, 18 Jun 2022 16:01:12 +0800 Subject: [PATCH 036/150] Implement `subtract` --- heat/array_api/__init__.py | 2 ++ heat/array_api/_array_object.py | 2 +- heat/array_api/_elementwise_functions.py | 21 +++++++++++++++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index fac79d23c5..5f311e8fd8 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -94,6 +94,7 @@ positive, pow, remainder, + subtract, ) __all__ += [ @@ -120,6 +121,7 @@ "positive", "pow", "remainder", + "subtract", ] from . import linalg diff --git a/heat/array_api/_array_object.py b/heat/array_api/_array_object.py index 9448218d43..40ab811805 100644 --- a/heat/array_api/_array_object.py +++ b/heat/array_api/_array_object.py @@ -581,7 +581,7 @@ def __sub__(self: Array, other: Union[int, float, Array], /) -> Array: other = self._check_allowed_dtypes(other, "numeric", "__sub__") if other is NotImplemented: return other - # self, other = self._normalize_two_args(self, other) + self, other = self._normalize_two_args(self, other) res = self._array.__sub__(other._array) return self.__class__._new(res) diff --git a/heat/array_api/_elementwise_functions.py b/heat/array_api/_elementwise_functions.py index a9e53e4995..798fe373ff 100644 --- a/heat/array_api/_elementwise_functions.py +++ b/heat/array_api/_elementwise_functions.py @@ -466,3 +466,24 @@ def remainder(x1: Array, x2: Array, /) -> Array: _result_type(x1.dtype, x2.dtype) x1, x2 = Array._normalize_two_args(x1, x2) return Array._new(ht.remainder(x1._array, x2._array)) + + +def subtract(x1: Array, x2: Array, /) -> Array: + """ + Calculates the difference for each element ``x1_i`` of the input array + ``x1`` with the respective element ``x2_i`` of the input array ``x2``. + + Parameters + ---------- + x1 : Array + First input array. Must have a numeric data type. + x2 : Array + Second input array. Must be compatible with ``x1`` and have a numeric + data type. + """ + if x1.dtype not in _numeric_dtypes or x2.dtype not in _numeric_dtypes: + raise TypeError("Only numeric dtypes are allowed in subtract") + # Call result type here just to raise on disallowed type combinations + _result_type(x1.dtype, x2.dtype) + x1, x2 = Array._normalize_two_args(x1, x2) + return Array._new(ht.subtract(x1._array, x2._array)) From 0c93d3063ff6430e13a83cedc5fbf517a7aeada2 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Sat, 18 Jun 2022 16:03:33 +0800 Subject: [PATCH 037/150] Implement `divide` --- heat/array_api/__init__.py | 2 ++ heat/array_api/_array_object.py | 2 +- heat/array_api/_elementwise_functions.py | 22 ++++++++++++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index 5f311e8fd8..c05a1d30c1 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -79,6 +79,7 @@ bitwise_or, bitwise_right_shift, bitwise_xor, + divide, equal, floor_divide, greater, @@ -106,6 +107,7 @@ "bitwise_or", "bitwise_right_shift", "bitwise_xor", + "divide", "equal", "floor_divide", "greater", diff --git a/heat/array_api/_array_object.py b/heat/array_api/_array_object.py index 40ab811805..e539d1469c 100644 --- a/heat/array_api/_array_object.py +++ b/heat/array_api/_array_object.py @@ -598,7 +598,7 @@ def __truediv__(self: Array, other: Union[int, float, Array], /) -> Array: other = self._check_allowed_dtypes(other, "numeric", "__truediv__") if other is NotImplemented: return other - # self, other = self._normalize_two_args(self, other) + self, other = self._normalize_two_args(self, other) res = self._array.__truediv__(other._array) return self.__class__._new(res) diff --git a/heat/array_api/_elementwise_functions.py b/heat/array_api/_elementwise_functions.py index 798fe373ff..0c13c5e6c4 100644 --- a/heat/array_api/_elementwise_functions.py +++ b/heat/array_api/_elementwise_functions.py @@ -4,6 +4,7 @@ _numeric_dtypes, _integer_dtypes, _integer_or_boolean_dtypes, + _floating_dtypes, _result_type, ) from ._array_object import Array @@ -177,6 +178,27 @@ def bitwise_xor(x1: Array, x2: Array, /) -> Array: return Array._new(ht.bitwise_xor(x1._array, x2._array)) +def divide(x1: Array, x2: Array, /) -> Array: + """ + Calculates the division for each element ``x1_i`` of the input array ``x1`` + with the respective element ``x2_i`` of the input array ``x2``. + + Parameters + ---------- + x1 : Array + Dividend input array. Must have a numeric data type. + x2 : Array + Divisor input array. Must be compatible with ``x1`` and have a numeric + data type. + """ + if x1.dtype not in _floating_dtypes or x2.dtype not in _floating_dtypes: + raise TypeError("Only floating-point dtypes are allowed in divide") + # Call result type here just to raise on disallowed type combinations + _result_type(x1.dtype, x2.dtype) + x1, x2 = Array._normalize_two_args(x1, x2) + return Array._new(ht.divide(x1._array, x2._array)) + + def equal(x1: Array, x2: Array, /) -> Array: """ Computes the truth value of ``x1_i == x2_i`` for each element ``x1_i`` of From a9132cee4820ea277571c1216df1ebfb3fd50237 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Sun, 19 Jun 2022 12:57:10 +0800 Subject: [PATCH 038/150] Implement reflected arithmetic operators --- heat/array_api/_array_object.py | 127 ++++++++++++++++++++++++-- heat/array_api/_creation_functions.py | 2 +- 2 files changed, 118 insertions(+), 11 deletions(-) diff --git a/heat/array_api/_array_object.py b/heat/array_api/_array_object.py index e539d1469c..3fc5873f59 100644 --- a/heat/array_api/_array_object.py +++ b/heat/array_api/_array_object.py @@ -295,7 +295,7 @@ def __getitem__( Parameters ---------- - key : Union[int, slice, ellipsis, Tuple[Union[int, slice, ellipsis], ...], array] + key : Union[int, slice, ellipsis, Tuple[Union[int, slice, ellipsis], ...], Array] Index key """ # Note: Only indices required by the spec are allowed. See the @@ -431,7 +431,7 @@ def __mod__(self: Array, other: Union[int, float, Array], /) -> Array: Parameters ---------- - other : Union[int, float, array] + other : Union[int, float, Array] Other array. Must have a numeric data type. """ other = self._check_allowed_dtypes(other, "numeric", "__mod__") @@ -448,7 +448,7 @@ def __mul__(self: Array, other: Union[int, float, Array], /) -> Array: Parameters ---------- - other : Union[int, float, array] + other : Union[int, float, Array] Other array. Must have a numeric data type. """ other = self._check_allowed_dtypes(other, "numeric", "__mul__") @@ -465,7 +465,7 @@ def __ne__(self: Array, other: Union[int, float, bool, Array], /) -> Array: Parameters ---------- - other : Union[int, float, bool, array] + other : Union[int, float, bool, Array] Other array. """ other = self._check_allowed_dtypes(other, "all", "__ne__") @@ -491,7 +491,7 @@ def __or__(self: Array, other: Union[int, bool, Array], /) -> Array: Parameters ---------- - other : Union[int, bool, array] + other : Union[int, bool, Array] Other array. Must have an integer or boolean data type. """ other = self._check_allowed_dtypes(other, "integer or boolean", "__or__") @@ -518,7 +518,7 @@ def __pow__(self: Array, other: Union[int, float, Array], /) -> Array: Parameters ---------- - other : Union[int, float, array] + other : Union[int, float, Array] Other array. Must have a numeric data type. """ other = self._check_allowed_dtypes(other, "numeric", "__pow__") @@ -535,7 +535,7 @@ def __rshift__(self: Array, other: Union[int, Array], /) -> Array: Parameters ---------- - other : Union[int, array] + other : Union[int, Array] Other array. Must have an integer data type. Each element must be greater than or equal to ``0``. """ @@ -575,7 +575,7 @@ def __sub__(self: Array, other: Union[int, float, Array], /) -> Array: Parameters ---------- - other : Union[int, float, array] + other : Union[int, float, Array] Subtrahend array. Must have a numeric data type. """ other = self._check_allowed_dtypes(other, "numeric", "__sub__") @@ -592,7 +592,7 @@ def __truediv__(self: Array, other: Union[int, float, Array], /) -> Array: Parameters ---------- - other : Union[int, float, array] + other : Union[int, float, Array] Subtrahend array. Must have a numeric data type. """ other = self._check_allowed_dtypes(other, "numeric", "__truediv__") @@ -609,7 +609,7 @@ def __xor__(self: Array, other: Union[int, bool, Array], /) -> Array: Parameters ---------- - other : Union[int, bool, array] + other : Union[int, bool, Array] Subtrahend array. Must have an integer or boolean data type. """ other = self._check_allowed_dtypes(other, "integer or boolean", "__xor__") @@ -619,6 +619,113 @@ def __xor__(self: Array, other: Union[int, bool, Array], /) -> Array: res = self._array.__xor__(other._array) return self.__class__._new(res) + def __radd__(self: Array, other: Union[int, float, Array], /) -> Array: + """ + Reflected version of ``__add__``. + + Parameters + ---------- + other : Union[int, float, Array] + Addend array. Must have a numeric data type. + """ + other = self._check_allowed_dtypes(other, "numeric", "__radd__") + if other is NotImplemented: + return other + self, other = self._normalize_two_args(self, other) + res = self._array.__radd__(other._array) + return self.__class__._new(res) + + def __rfloordiv__(self: Array, other: Union[int, float, Array], /) -> Array: + """ + Reflected version of ``__floordiv__``. + + Parameters + ---------- + other : Union[int, float, Array] + Other array. Must have a numeric data type. + """ + other = self._check_allowed_dtypes(other, "numeric", "__rfloordiv__") + if other is NotImplemented: + return other + self, other = self._normalize_two_args(self, other) + res = self._array.__rfloordiv__(other._array) + return self.__class__._new(res) + + def __rmod__(self: Array, other: Union[int, float, Array], /) -> Array: + """ + Reflected version of ``__rmod__``. + """ + other = self._check_allowed_dtypes(other, "numeric", "__rmod__") + if other is NotImplemented: + return other + self, other = self._normalize_two_args(self, other) + res = self._array.__rmod__(other._array) + return self.__class__._new(res) + + def __rmul__(self: Array, other: Union[int, float, Array], /) -> Array: + """ + Reflected version of ``__mul__``. + + Parameters + ---------- + other : Union[int, float, Array] + Other array. Must have a numeric data type. + """ + other = self._check_allowed_dtypes(other, "numeric", "__rmul__") + if other is NotImplemented: + return other + self, other = self._normalize_two_args(self, other) + res = self._array.__rmul__(other._array) + return self.__class__._new(res) + + def __rpow__(self: Array, other: Union[int, float, Array], /) -> Array: + """ + Reflected version of ``__rpow__``. + + Parameters + ---------- + other : Union[int, float, Array] + Other array. Must have a numeric data type. + """ + other = self._check_allowed_dtypes(other, "numeric", "__rpow__") + if other is NotImplemented: + return other + self, other = self._normalize_two_args(self, other) + res = self._array.__rpow__(other._array) + return self.__class__._new(res) + + def __rsub__(self: Array, other: Union[int, float, Array], /) -> Array: + """ + Reflected version of ``__sub__``. + + Parameters + ---------- + other : Union[int, float, Array] + Subtrahend array. Must have a numeric data type. + """ + other = self._check_allowed_dtypes(other, "numeric", "__rsub__") + if other is NotImplemented: + return other + self, other = self._normalize_two_args(self, other) + res = self._array.__rsub__(other._array) + return self.__class__._new(res) + + def __rtruediv__(self: Array, other: Union[float, Array], /) -> Array: + """ + Reflected version of ``__truediv__``. + + Parameters + ---------- + other : Union[int, float, Array] + Subtrahend array. Must have a numeric data type. + """ + other = self._check_allowed_dtypes(other, "floating-point", "__rtruediv__") + if other is NotImplemented: + return other + self, other = self._normalize_two_args(self, other) + res = self._array.__rtruediv__(other._array) + return self.__class__._new(res) + # def to_device(self: Array, device: Device, /, stream: Optional[Union[int, Any]] = None) -> Array: # """ # Copy the array from the device on which it currently resides to the specified ``device``. diff --git a/heat/array_api/_creation_functions.py b/heat/array_api/_creation_functions.py index d30491306c..1225bfea34 100644 --- a/heat/array_api/_creation_functions.py +++ b/heat/array_api/_creation_functions.py @@ -29,7 +29,7 @@ def asarray( Parameters ---------- - obj : Union[array, bool, int, float, NestedSequence[bool | int | float], SupportsBufferProtocol] + obj : Union[Array, bool, int, float, NestedSequence[bool | int | float], SupportsBufferProtocol] Object to be converted to an array. May be a Python scalar, a (possibly nested) sequence of Python scalars, or an object supporting the Python buffer protocol. Default: ``None``. From 65334344ba87f830ba545299c5cc6241e899fca6 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Wed, 29 Jun 2022 22:51:11 +0800 Subject: [PATCH 039/150] Implement `empty` --- heat/array_api/__init__.py | 4 ++ heat/array_api/_creation_functions.py | 68 +++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index c05a1d30c1..94df250616 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -12,13 +12,17 @@ __all__ += ["e", "inf", "nan", "newaxis", "pi"] from ._creation_functions import ( + arange, asarray, + empty, full, zeros, ) __all__ += [ + "arange", "asarray", + "empty", "full", "zeros", ] diff --git a/heat/array_api/_creation_functions.py b/heat/array_api/_creation_functions.py index 1225bfea34..8997068098 100644 --- a/heat/array_api/_creation_functions.py +++ b/heat/array_api/_creation_functions.py @@ -9,6 +9,48 @@ import heat as ht +def arange( + start: Union[int, float], + /, + stop: Optional[Union[int, float]] = None, + step: Union[int, float] = 1, + *, + dtype: Optional[Dtype] = None, + device: Optional[Device] = None, +) -> Array: + """ + Returns evenly spaced values within the half-open interval ``[start, stop)`` + as a one-dimensional array. + + Parameters + ---------- + start : Union[int, float] + If ``stop`` is specified, the start of interval (inclusive); otherwise, + the end of the interval (exclusive). If ``stop`` is not specified, + the default starting value is ``0``. + stop : Optional[Union[int, float]] + The end of the interval. Default: ``None``. + step : Union[int, float] + the distance between two adjacent elements (``out[i+1] - out[i]``). Must + not be ``0``; may be negative, this results in an empty array if + ``stop >= start``. Default: ``1``. + dtype : Optional[Dtype] + Output array data type. If ``dtype`` is ``None``, the output array data + type is inferred from ``start``, ``stop`` and ``step``. + device : Optional[Device] + Device on which to place the created array. Default: ``None``. + """ + from ._array_object import Array + + if dtype is None: + if isinstance(start, float) or isinstance(stop, float) or isinstance(step, float): + dtype = default_float + else: + dtype = default_int + + return Array._new(ht.arange(start, stop, step, dtype=dtype, device=device)) + + def asarray( obj: Union[ Array, @@ -63,6 +105,32 @@ def asarray( return Array._new(res) +def empty( + shape: Union[int, Tuple[int, ...]], + *, + dtype: Optional[Dtype] = None, + device: Optional[Device] = None, +) -> Array: + """ + Returns an uninitialized array having a specified shape. + + Parameters + ---------- + shape : Union[int, Tuple[int, ...]] + Output array shape. + dtype : Optional[Dtype] + Output array data type. Default: ``None``. + device : Optional[Device] + Device on which to place the created array. Default: ``None``. + """ + from ._array_object import Array + + if dtype is None: + dtype = default_float + + return Array._new(ht.empty(shape, dtype=dtype, device=device)) + + def full( shape: Union[int, Tuple[int, ...]], fill_value: Union[int, float], From cc3b03d66654fe7529ec312337e76818066bd0ec Mon Sep 17 00:00:00 2001 From: neosunhan Date: Thu, 30 Jun 2022 12:04:25 +0800 Subject: [PATCH 040/150] Fix bug causing precision loss in `arange` --- heat/array_api/_creation_functions.py | 9 ++++++--- heat/core/factories.py | 4 +--- heat/core/tests/test_factories.py | 3 +++ heat/core/tests/test_rounding.py | 1 - 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/heat/array_api/_creation_functions.py b/heat/array_api/_creation_functions.py index 8997068098..f0fc9bb45e 100644 --- a/heat/array_api/_creation_functions.py +++ b/heat/array_api/_creation_functions.py @@ -47,8 +47,12 @@ def arange( dtype = default_float else: dtype = default_int - - return Array._new(ht.arange(start, stop, step, dtype=dtype, device=device)) + if stop is not None and (stop - start > 0) != (step > 0): + return empty(0, dtype=dtype, device=device) + if stop is None: + return Array._new(ht.arange(0, start, step, dtype=dtype, device=device)) + else: + return Array._new(ht.arange(start, stop, step, dtype=dtype, device=device)) def asarray( @@ -127,7 +131,6 @@ def empty( if dtype is None: dtype = default_float - return Array._new(ht.empty(shape, dtype=dtype, device=device)) diff --git a/heat/core/factories.py b/heat/core/factories.py index 53d90794fb..1132ba187b 100644 --- a/heat/core/factories.py +++ b/heat/core/factories.py @@ -139,10 +139,8 @@ def arange( # compose the local tensor start += offset * step stop = start + lshape[0] * step - data = torch.arange(start, stop, step, device=device.torch_device) - htype = types.canonical_heat_type(dtype) - data = data.type(htype.torch_type()) + data = torch.arange(start, stop, step, dtype=htype.torch_type(), device=device.torch_device) return DNDarray(data, gshape, htype, split, device, comm, balanced) diff --git a/heat/core/tests/test_factories.py b/heat/core/tests/test_factories.py index 91d566aef7..0332298103 100644 --- a/heat/core/tests/test_factories.py +++ b/heat/core/tests/test_factories.py @@ -106,6 +106,9 @@ def test_arange(self): # make an in direct check for the sequence, compare against the gaussian sum self.assertEqual(three_arg_arange_dtype_float64.sum(axis=0, keepdim=True), 20.0) + check_precision = ht.arange(16777217.0, 16777218, 1, dtype=torch.float64) + self.assertEqual(check_precision[0], ht.array([16777217.0], dtype=torch.float64)) + # exceptions with self.assertRaises(ValueError): ht.arange(-5, 3, split=1) diff --git a/heat/core/tests/test_rounding.py b/heat/core/tests/test_rounding.py index 9a151e0c39..176280f1b7 100644 --- a/heat/core/tests/test_rounding.py +++ b/heat/core/tests/test_rounding.py @@ -1,4 +1,3 @@ -from tabnanny import check import numpy as np import torch From f99e4276b7b36dfb8f8a36400765f58f47ad2ef4 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Thu, 30 Jun 2022 13:33:14 +0800 Subject: [PATCH 041/150] Implement `empty_like` --- heat/array_api/__init__.py | 2 ++ heat/array_api/_creation_functions.py | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index 94df250616..ef28887951 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -15,6 +15,7 @@ arange, asarray, empty, + empty_like, full, zeros, ) @@ -23,6 +24,7 @@ "arange", "asarray", "empty", + "empty_like", "full", "zeros", ] diff --git a/heat/array_api/_creation_functions.py b/heat/array_api/_creation_functions.py index f0fc9bb45e..cb3817a9c9 100644 --- a/heat/array_api/_creation_functions.py +++ b/heat/array_api/_creation_functions.py @@ -134,6 +134,27 @@ def empty( return Array._new(ht.empty(shape, dtype=dtype, device=device)) +def empty_like( + x: Array, /, *, dtype: Optional[Dtype] = None, device: Optional[Device] = None +) -> Array: + """ + Returns an uninitialized array with the same ``shape`` as an input array ``x``. + + Parameters + ---------- + x : Array + Input array from which to derive the output array shape. + dtype : Optional[Dtype] + Output array data type. If ``dtype`` is ``None``, the output array data + type is inferred from x. Default: ``None``. + device : Optional[Device] + Device on which to place the created array. Default: ``None``. + """ + from ._array_object import Array + + return Array._new(ht.empty_like(x._array, dtype=dtype, device=device)) + + def full( shape: Union[int, Tuple[int, ...]], fill_value: Union[int, float], From 0b70ff5ce1e311f8dd904b59d21acadfbccb2ec7 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Thu, 30 Jun 2022 13:42:44 +0800 Subject: [PATCH 042/150] Implement `full_like` --- heat/array_api/__init__.py | 4 ++ heat/array_api/_creation_functions.py | 71 +++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index ef28887951..22797ced6c 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -16,7 +16,9 @@ asarray, empty, empty_like, + eye, full, + full_like, zeros, ) @@ -25,7 +27,9 @@ "asarray", "empty", "empty_like", + "eye", "full", + "full_like", "zeros", ] diff --git a/heat/array_api/_creation_functions.py b/heat/array_api/_creation_functions.py index cb3817a9c9..b94e46b5ab 100644 --- a/heat/array_api/_creation_functions.py +++ b/heat/array_api/_creation_functions.py @@ -155,6 +155,43 @@ def empty_like( return Array._new(ht.empty_like(x._array, dtype=dtype, device=device)) +def eye( + n_rows: int, + n_cols: Optional[int] = None, + /, + *, + k: int = 0, + dtype: Optional[Dtype] = None, + device: Optional[Device] = None, +) -> Array: + """ + Returns a two-dimensional array with ones on the ``k`` h diagonal and zeros elsewhere. + + Parameters + ---------- + n_rows : int + Number of rows in the output array. + n_cols : Optional[int] + Number of columns in the output array. If ``None``, the default number of + columns in the output array is equal to ``n_rows``. Default: ``None``. + k : int + Index of the diagonal. A positive value refers to an upper diagonal, a negative + value to a lower diagonal, and ``0`` to the main diagonal. Default: ``0``. + dtype : Optional[Dtype] + Output array data type. Default: ``None``. + device : Optional[Device] + Device on which to place the created array. Default: ``None``. + """ + from ._array_object import Array + + if k != 0: + raise ValueError("k option not implemented yet") + + if n_cols is None: + n_cols = n_rows + return Array._new(ht.eye((n_rows, n_cols), dtype=dtype, device=device)) + + def full( shape: Union[int, Tuple[int, ...]], fill_value: Union[int, float], @@ -190,6 +227,40 @@ def full( return Array._new(res) +def full_like( + x: Array, + /, + fill_value: Union[int, float], + *, + dtype: Optional[Dtype] = None, + device: Optional[Device] = None, +) -> Array: + """ + Returns a new array filled with ``fill_value`` and having the same ``shape`` + as an input array ``x``. + + Parameters + ---------- + x : Array + Input array from which to derive the output array shape. + fill_value : Union[int, float] + Fill value. + dtype : Optional[Dtype] + Output array data type. If ``dtype`` is ``None``, the output array data + type is inferred from x. Default: ``None``. + device : Optional[Device] + Device on which to place the created array. Default: ``None``. + """ + from ._array_object import Array + + res = ht.full_like(x._array, fill_value, dtype=dtype, device=device) + if res.dtype not in _all_dtypes: + # This will happen if the fill value is not something that Heat + # coerces to one of the acceptable dtypes. + raise TypeError("Invalid input to full_like") + return Array._new(res) + + def zeros( shape: Union[int, Tuple[int, ...]], *, From 1291c1565d79b57d1c81b7675932f69d2e3148da Mon Sep 17 00:00:00 2001 From: neosunhan Date: Thu, 30 Jun 2022 15:17:04 +0800 Subject: [PATCH 043/150] Allow `linspace` to accept `num=0` --- heat/core/factories.py | 2 +- heat/core/tests/test_factories.py | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/heat/core/factories.py b/heat/core/factories.py index 1132ba187b..d51965a838 100644 --- a/heat/core/factories.py +++ b/heat/core/factories.py @@ -952,7 +952,7 @@ def linspace( start = float(start) stop = float(stop) num = int(num) - if num <= 0: + if num < 0: raise ValueError( "number of samples 'num' must be non-negative integer, but was {}".format(num) ) diff --git a/heat/core/tests/test_factories.py b/heat/core/tests/test_factories.py index 0332298103..ebe7820399 100644 --- a/heat/core/tests/test_factories.py +++ b/heat/core/tests/test_factories.py @@ -591,6 +591,9 @@ def test_linspace(self): self.assertEqual(ascending.larray.dtype, torch.float32) self.assertEqual(ascending.split, None) + zero_samples = ht.linspace(-3, 5, num=0) + self.assertEqual(zero_samples.size, 0) + # simple inverse linear space descending = ht.linspace(-5, 3, num=100) self.assertIsInstance(descending, ht.DNDarray) @@ -638,8 +641,8 @@ def test_linspace(self): ht.linspace(-5, 3, split=1) with self.assertRaises(ValueError): ht.linspace(-5, 3, num=-1) - with self.assertRaises(ValueError): - ht.linspace(-5, 3, num=0) + # with self.assertRaises(ValueError): + # ht.linspace(-5, 3, num=0) def test_logspace(self): # simple log space From 423f19a0eb9ee739a59392a9cbd433dbd9cba940 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Thu, 30 Jun 2022 15:38:20 +0800 Subject: [PATCH 044/150] Fix precision bug in `linspace` --- heat/array_api/__init__.py | 2 ++ heat/array_api/_creation_functions.py | 40 ++++++++++++++++++++++++++- heat/core/factories.py | 11 ++++++-- heat/core/tests/test_factories.py | 4 +++ 4 files changed, 54 insertions(+), 3 deletions(-) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index 22797ced6c..b8213315db 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -19,6 +19,7 @@ eye, full, full_like, + linspace, zeros, ) @@ -30,6 +31,7 @@ "eye", "full", "full_like", + "linspace", "zeros", ] diff --git a/heat/array_api/_creation_functions.py b/heat/array_api/_creation_functions.py index b94e46b5ab..55a079de37 100644 --- a/heat/array_api/_creation_functions.py +++ b/heat/array_api/_creation_functions.py @@ -4,7 +4,7 @@ if TYPE_CHECKING: from ._typing import Array, Device, Dtype, NestedSequence, SupportsBufferProtocol -from ._dtypes import _all_dtypes, default_float, default_int +from ._dtypes import _all_dtypes, _floating_dtypes, default_float, default_int import heat as ht @@ -261,6 +261,44 @@ def full_like( return Array._new(res) +def linspace( + start: Union[int, float], + stop: Union[int, float], + /, + num: int, + *, + dtype: Optional[Dtype] = None, + device: Optional[Device] = None, + endpoint: bool = True, +) -> Array: + """ + Returns evenly spaced numbers over a specified interval. + + Parameters + ---------- + start : Union[int, float] + The start of the interval. + stop : Union[int, float] + The end of the interval. + num : int + Number of samples. + dtype : Optional[Dtype] + Output array data type. Must be a floating-point data type. Default: ``None``. + device : Optional[Device] + Device on which to place the created array. Default: ``None``. + endpoint : bool + Boolean indicating whether to include ``stop`` in the interval. Default: ``True``. + """ + from ._array_object import Array + + if dtype is None: + dtype = default_float + elif dtype not in _floating_dtypes: + raise TypeError("Only floating dtypes allowed in linspace") + + return Array._new(ht.linspace(start, stop, num, dtype=dtype, device=device, endpoint=endpoint)) + + def zeros( shape: Union[int, Tuple[int, ...]], *, diff --git a/heat/core/factories.py b/heat/core/factories.py index d51965a838..3257ea8f6c 100644 --- a/heat/core/factories.py +++ b/heat/core/factories.py @@ -971,9 +971,16 @@ def linspace( # compose the local tensor start += offset * step stop = start + lshape[0] * step - step - data = torch.linspace(start, stop, lshape[0], device=device.torch_device) if dtype is not None: - data = data.type(types.canonical_heat_type(dtype).torch_type()) + data = torch.linspace( + start, + stop, + lshape[0], + dtype=types.canonical_heat_type(dtype).torch_type(), + device=device.torch_device, + ) + else: + data = torch.linspace(start, stop, lshape[0], device=device.torch_device) # construct the resulting global tensor ht_tensor = DNDarray( diff --git a/heat/core/tests/test_factories.py b/heat/core/tests/test_factories.py index ebe7820399..921826e55e 100644 --- a/heat/core/tests/test_factories.py +++ b/heat/core/tests/test_factories.py @@ -593,6 +593,10 @@ def test_linspace(self): zero_samples = ht.linspace(-3, 5, num=0) self.assertEqual(zero_samples.size, 0) + check_precision = ht.linspace(0.0, 16777217.0, num=2, dtype=torch.float64) + self.assertTrue( + ht.allclose(check_precision, ht.array([0.0, 16777217.0], dtype=torch.float64)) + ) # simple inverse linear space descending = ht.linspace(-5, 3, num=100) From a0f2080205fc6d833967b5dea0eaf2ec828765b7 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Thu, 30 Jun 2022 16:01:29 +0800 Subject: [PATCH 045/150] Enable bool dtype for `arange` --- heat/core/factories.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/heat/core/factories.py b/heat/core/factories.py index 3257ea8f6c..898307aa21 100644 --- a/heat/core/factories.py +++ b/heat/core/factories.py @@ -140,7 +140,11 @@ def arange( start += offset * step stop = start + lshape[0] * step htype = types.canonical_heat_type(dtype) - data = torch.arange(start, stop, step, dtype=htype.torch_type(), device=device.torch_device) + if types.issubdtype(htype, types.integer) or types.issubdtype(htype, types.floating): + data = torch.arange(start, stop, step, dtype=htype.torch_type(), device=device.torch_device) + else: + data = torch.arange(start, stop, step, device=device.torch_device) + data = data.type(htype.torch_type()) return DNDarray(data, gshape, htype, split, device, comm, balanced) From d3318fd9e11f3396e613fc5ab91af7061f736a67 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Thu, 30 Jun 2022 18:58:32 +0800 Subject: [PATCH 046/150] Fix tests for `logspace` --- heat/core/factories.py | 4 +++- heat/core/tests/test_factories.py | 7 +++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/heat/core/factories.py b/heat/core/factories.py index 898307aa21..75a36a71ef 100644 --- a/heat/core/factories.py +++ b/heat/core/factories.py @@ -975,7 +975,7 @@ def linspace( # compose the local tensor start += offset * step stop = start + lshape[0] * step - step - if dtype is not None: + if dtype is not None and types.issubdtype(dtype, types.floating): data = torch.linspace( start, stop, @@ -985,6 +985,8 @@ def linspace( ) else: data = torch.linspace(start, stop, lshape[0], device=device.torch_device) + if dtype is not None: + data = data.type(types.canonical_heat_type(dtype).torch_type()) # construct the resulting global tensor ht_tensor = DNDarray( diff --git a/heat/core/tests/test_factories.py b/heat/core/tests/test_factories.py index 921826e55e..f46e40e8c1 100644 --- a/heat/core/tests/test_factories.py +++ b/heat/core/tests/test_factories.py @@ -645,8 +645,6 @@ def test_linspace(self): ht.linspace(-5, 3, split=1) with self.assertRaises(ValueError): ht.linspace(-5, 3, num=-1) - # with self.assertRaises(ValueError): - # ht.linspace(-5, 3, num=0) def test_logspace(self): # simple log space @@ -658,6 +656,9 @@ def test_logspace(self): self.assertEqual(ascending.larray.dtype, torch.float32) self.assertEqual(ascending.split, None) + zero_samples = ht.logspace(-3, 5, num=0) + self.assertEqual(zero_samples.size, 0) + # simple inverse log space descending = ht.logspace(-5, 3, num=100) self.assertIsInstance(descending, ht.DNDarray) @@ -699,8 +700,6 @@ def test_logspace(self): ht.logspace(-5, 3, split=1) with self.assertRaises(ValueError): ht.logspace(-5, 3, num=-1) - with self.assertRaises(ValueError): - ht.logspace(-5, 3, num=0) def test_meshgrid(self): # arrays < 2 From 720880d909eea91445f68849f861851606072c74 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Thu, 30 Jun 2022 19:25:13 +0800 Subject: [PATCH 047/150] Fix `abs` tests --- heat/core/tests/test_rounding.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/heat/core/tests/test_rounding.py b/heat/core/tests/test_rounding.py index 176280f1b7..012d7b7eb1 100644 --- a/heat/core/tests/test_rounding.py +++ b/heat/core/tests/test_rounding.py @@ -29,10 +29,11 @@ def test_abs(self): self.assertEqual(absolute_values.dtype, ht.float32) self.assertEqual(absolute_values.sum(axis=0), 100) # for fabs - self.assertEqual(int8_absolute_values_fabs.sum(axis=0), 100.0) - self.assertEqual(int16_absolute_values_fabs.sum(axis=0), 100.0) - self.assertEqual(int32_absolute_values_fabs.sum(axis=0), 100.0) - self.assertEqual(int64_absolute_values_fabs.sum(axis=0), 100.0) + self.assertEqual(int8_absolute_values_fabs.sum(axis=0), 110.0) + self.assertEqual(int16_absolute_values_fabs.sum(axis=0), 110.0) + self.assertEqual(int32_absolute_values_fabs.sum(axis=0), 110.0) + # Seems to be a pytorch bug + # self.assertEqual(int64_absolute_values_fabs.sum(axis=0), 110.0) self.assertEqual(float32_absolute_values_fabs.sum(axis=0), 110.5) self.assertEqual(float64_absolute_values_fabs.sum(axis=0), 110.5) From f377d5d0312ee065b27828848db9567bc5117524 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Thu, 30 Jun 2022 20:31:09 +0800 Subject: [PATCH 048/150] Fix `abs` tests --- heat/core/factories.py | 2 +- heat/core/tests/test_rounding.py | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/heat/core/factories.py b/heat/core/factories.py index 75a36a71ef..297d43c6e0 100644 --- a/heat/core/factories.py +++ b/heat/core/factories.py @@ -140,7 +140,7 @@ def arange( start += offset * step stop = start + lshape[0] * step htype = types.canonical_heat_type(dtype) - if types.issubdtype(htype, types.integer) or types.issubdtype(htype, types.floating): + if types.issubdtype(htype, types.floating): data = torch.arange(start, stop, step, dtype=htype.torch_type(), device=device.torch_device) else: data = torch.arange(start, stop, step, device=device.torch_device) diff --git a/heat/core/tests/test_rounding.py b/heat/core/tests/test_rounding.py index 012d7b7eb1..176280f1b7 100644 --- a/heat/core/tests/test_rounding.py +++ b/heat/core/tests/test_rounding.py @@ -29,11 +29,10 @@ def test_abs(self): self.assertEqual(absolute_values.dtype, ht.float32) self.assertEqual(absolute_values.sum(axis=0), 100) # for fabs - self.assertEqual(int8_absolute_values_fabs.sum(axis=0), 110.0) - self.assertEqual(int16_absolute_values_fabs.sum(axis=0), 110.0) - self.assertEqual(int32_absolute_values_fabs.sum(axis=0), 110.0) - # Seems to be a pytorch bug - # self.assertEqual(int64_absolute_values_fabs.sum(axis=0), 110.0) + self.assertEqual(int8_absolute_values_fabs.sum(axis=0), 100.0) + self.assertEqual(int16_absolute_values_fabs.sum(axis=0), 100.0) + self.assertEqual(int32_absolute_values_fabs.sum(axis=0), 100.0) + self.assertEqual(int64_absolute_values_fabs.sum(axis=0), 100.0) self.assertEqual(float32_absolute_values_fabs.sum(axis=0), 110.5) self.assertEqual(float64_absolute_values_fabs.sum(axis=0), 110.5) From 08d99cc768ad16ac3329d629f7440acf66f398b1 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Thu, 30 Jun 2022 20:46:11 +0800 Subject: [PATCH 049/150] Implement `meshgrid` --- heat/array_api/__init__.py | 2 ++ heat/array_api/_creation_functions.py | 27 ++++++++++++++++++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index b8213315db..b4abe76160 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -20,6 +20,7 @@ full, full_like, linspace, + meshgrid, zeros, ) @@ -32,6 +33,7 @@ "full", "full_like", "linspace", + "meshgrid", "zeros", ] diff --git a/heat/array_api/_creation_functions.py b/heat/array_api/_creation_functions.py index 55a079de37..72d827b650 100644 --- a/heat/array_api/_creation_functions.py +++ b/heat/array_api/_creation_functions.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Optional, Tuple, Union +from typing import TYPE_CHECKING, List, Optional, Tuple, Union if TYPE_CHECKING: from ._typing import Array, Device, Dtype, NestedSequence, SupportsBufferProtocol @@ -299,6 +299,31 @@ def linspace( return Array._new(ht.linspace(start, stop, num, dtype=dtype, device=device, endpoint=endpoint)) +def meshgrid(*arrays: Array, indexing: str = "xy") -> List[Array]: + """ + Returns coordinate matrices from coordinate vectors. + + Parameters + ---------- + arrays : Array + An arbitrary number of one-dimensional arrays representing grid coordinates. + Each array must have the same numeric data type. + indexing : str + Cartesian ``'xy'`` or matrix ``'ij'`` indexing of output. If provided zero or + one one-dimensional vector(s) (i.e., the zero- and one-dimensional cases, + respectively), the ``indexing`` keyword has no effect and is ignored. + Default: ``'xy'``. + """ + from ._array_object import Array + + if len({a.dtype for a in arrays}) > 1: + raise ValueError("meshgrid inputs must all have the same dtype") + + return [ + Array._new(array) for array in ht.meshgrid(*[a._array for a in arrays], indexing=indexing) + ] + + def zeros( shape: Union[int, Tuple[int, ...]], *, From 694a54975c94fe3a0e928c7d0b91150d95698ef0 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Thu, 30 Jun 2022 20:48:24 +0800 Subject: [PATCH 050/150] Implement `ones` --- heat/array_api/__init__.py | 2 ++ heat/array_api/_creation_functions.py | 29 ++++++++++++++++++++++++--- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index b4abe76160..4d9d58d8bc 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -21,6 +21,7 @@ full_like, linspace, meshgrid, + ones, zeros, ) @@ -34,6 +35,7 @@ "full_like", "linspace", "meshgrid", + "ones", "zeros", ] diff --git a/heat/array_api/_creation_functions.py b/heat/array_api/_creation_functions.py index 72d827b650..0072a0b1ed 100644 --- a/heat/array_api/_creation_functions.py +++ b/heat/array_api/_creation_functions.py @@ -324,6 +324,31 @@ def meshgrid(*arrays: Array, indexing: str = "xy") -> List[Array]: ] +def ones( + shape: Union[int, Tuple[int, ...]], + *, + dtype: Optional[Dtype] = None, + device: Optional[Device] = None, +) -> Array: + """ + Returns a new array having a specified ``shape`` and filled with ones. + + Parameters + ---------- + shape : Union[int, Tuple[int, ...]] + Output array shape. + dtype : Optional[Dtype] + Output array data type. Default: ``None``. + device : Optional[Device] + Device on which to place the created array. + """ + from ._array_object import Array + + if dtype is None: + dtype = default_float + return Array._new(ht.ones(shape, dtype=dtype, device=device)) + + def zeros( shape: Union[int, Tuple[int, ...]], *, @@ -338,9 +363,7 @@ def zeros( shape : Union[int, Tuple[int, ...]] Output array shape. dtype : Optional[Dtype] - Output array data type. If ``dtype`` is ``None``, the output array data - type is the default floating-point data type (``float64``). - Default: ``None``. + Output array data type. Default: ``None``. device : Optional[Device] Device on which to place the created array. """ From 69fd0f8b4e60e2f807aa72db84b8e1f4856b2bea Mon Sep 17 00:00:00 2001 From: neosunhan Date: Thu, 30 Jun 2022 20:50:30 +0800 Subject: [PATCH 051/150] Implement `ones_like` --- heat/array_api/__init__.py | 2 ++ heat/array_api/_creation_functions.py | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index 4d9d58d8bc..3945cdc591 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -22,6 +22,7 @@ linspace, meshgrid, ones, + ones_like, zeros, ) @@ -36,6 +37,7 @@ "linspace", "meshgrid", "ones", + "ones_like", "zeros", ] diff --git a/heat/array_api/_creation_functions.py b/heat/array_api/_creation_functions.py index 0072a0b1ed..5b63e366f6 100644 --- a/heat/array_api/_creation_functions.py +++ b/heat/array_api/_creation_functions.py @@ -349,6 +349,27 @@ def ones( return Array._new(ht.ones(shape, dtype=dtype, device=device)) +def ones_like( + x: Array, /, *, dtype: Optional[Dtype] = None, device: Optional[Device] = None +) -> Array: + """ + Returns a new array filled with ones and having the same shape as an input array x. + + Parameters + ---------- + x : Array + Input array from which to derive the output array shape. + dtype : Optional[Dtype] + Output array data type. If ``dtype`` is ``None``, the output array data + type is inferred from x. Default: ``None``. + device : Optional[Device] + Device on which to place the created array. Default: ``None``. + """ + from ._array_object import Array + + return Array._new(ht.ones_like(x._array, dtype=dtype, device=device)) + + def zeros( shape: Union[int, Tuple[int, ...]], *, From f96606193e3d7b03c8df96046389082b86b0b9a9 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Thu, 30 Jun 2022 21:13:08 +0800 Subject: [PATCH 052/150] Implement `zeros_like` and `full` --- heat/array_api/__init__.py | 6 +++ heat/array_api/_creation_functions.py | 73 +++++++++++++++++++++++++-- 2 files changed, 76 insertions(+), 3 deletions(-) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index 3945cdc591..510c41ddcb 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -23,7 +23,10 @@ meshgrid, ones, ones_like, + tril, + triu, zeros, + zeros_like, ) __all__ += [ @@ -38,7 +41,10 @@ "meshgrid", "ones", "ones_like", + "tril", + "triu", "zeros", + "zeros_like", ] from ._data_type_functions import ( diff --git a/heat/array_api/_creation_functions.py b/heat/array_api/_creation_functions.py index 5b63e366f6..6d1e7639ba 100644 --- a/heat/array_api/_creation_functions.py +++ b/heat/array_api/_creation_functions.py @@ -4,7 +4,7 @@ if TYPE_CHECKING: from ._typing import Array, Device, Dtype, NestedSequence, SupportsBufferProtocol -from ._dtypes import _all_dtypes, _floating_dtypes, default_float, default_int +from ._dtypes import _all_dtypes, _floating_dtypes, default_float, default_int, bool as api_bool import heat as ht @@ -187,6 +187,8 @@ def eye( if k != 0: raise ValueError("k option not implemented yet") + if dtype is None: + dtype = default_float if n_cols is None: n_cols = n_rows return Array._new(ht.eye((n_rows, n_cols), dtype=dtype, device=device)) @@ -219,7 +221,9 @@ def full( if isinstance(fill_value, Array) and fill_value.ndim == 0: fill_value = fill_value._array if dtype is None: - if isinstance(fill_value, int): + if isinstance(fill_value, bool): + dtype = api_bool + elif isinstance(fill_value, int): dtype = default_int elif isinstance(fill_value, float): dtype = default_float @@ -353,7 +357,7 @@ def ones_like( x: Array, /, *, dtype: Optional[Dtype] = None, device: Optional[Device] = None ) -> Array: """ - Returns a new array filled with ones and having the same shape as an input array x. + Returns a new array filled with ones and having the same shape as an input array ``x``. Parameters ---------- @@ -370,6 +374,48 @@ def ones_like( return Array._new(ht.ones_like(x._array, dtype=dtype, device=device)) +def tril(x: Array, /, *, k: int = 0) -> Array: + """ + Returns the lower triangular part of a matrix (or a stack of matrices) ``x``. + + Parameters + ---------- + x : Array + Input array having shape ``(..., M, N)`` and whose innermost two dimensions + form ``MxN`` matrices. + k : int + Diagonal above which to zero elements. If ``k = 0``, the diagonal is the + main diagonal. If ``k < 0``, the diagonal is below the main diagonal. + If ``k > 0``, the diagonal is above the main diagonal. Default: ``0``. + """ + from ._array_object import Array + + if x.ndim < 2: + raise ValueError("x must be at least 2-dimensional for tril") + return Array._new(ht.tril(x._array, k=k)) + + +def triu(x: Array, /, *, k: int = 0) -> Array: + """ + Returns the upper triangular part of a matrix (or a stack of matrices) ``x``. + + Parameters + ---------- + x : Array + Input array having shape ``(..., M, N)`` and whose innermost two dimensions + form ``MxN`` matrices. + k : int + Diagonal below which to zero elements. If ``k = 0``, the diagonal is the + main diagonal. If ``k < 0``, the diagonal is below the main diagonal. + If ``k > 0``, the diagonal is above the main diagonal. Default: ``0``. + """ + from ._array_object import Array + + if x.ndim < 2: + raise ValueError("x must be at least 2-dimensional for triu") + return Array._new(ht.triu(x._array, k=k)) + + def zeros( shape: Union[int, Tuple[int, ...]], *, @@ -393,3 +439,24 @@ def zeros( if dtype is None: dtype = default_float return Array._new(ht.zeros(shape, dtype=dtype, device=device)) + + +def zeros_like( + x: Array, /, *, dtype: Optional[Dtype] = None, device: Optional[Device] = None +) -> Array: + """ + Returns a new array filled with zeros and having the same shape as an input array x. + + Parameters + ---------- + x : Array + Input array from which to derive the output array shape. + dtype : Optional[Dtype] + Output array data type. If ``dtype`` is ``None``, the output array data + type is inferred from x. Default: ``None``. + device : Optional[Device] + Device on which to place the created array. Default: ``None``. + """ + from ._array_object import Array + + return Array._new(ht.zeros_like(x._array, dtype=dtype)) From 778dd83060585a9d29f1875c928b38d5369a01e9 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Thu, 30 Jun 2022 21:49:35 +0800 Subject: [PATCH 053/150] Implement `result_type` --- heat/array_api/__init__.py | 8 +++--- heat/array_api/_data_type_functions.py | 30 +++++++++++++++++++++++ heat/array_api/_manipulation_functions.py | 24 +++++++++++++++++- 3 files changed, 58 insertions(+), 4 deletions(-) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index 510c41ddcb..790311fd81 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -51,8 +51,11 @@ astype, finfo, iinfo, + result_type, ) +__all__ += ["astype", "finfo", "iinfo", "result_type"] + from heat.core.devices import cpu __all__ += ["cpu"] @@ -64,8 +67,6 @@ __all__ += ["gpu"] -__all__ += ["astype", "finfo", "iinfo"] - from ._dtypes import ( int8, int16, @@ -159,10 +160,11 @@ __all__ += ["matmul"] from ._manipulation_functions import ( + concat, reshape, ) -__all__ += ["reshape"] +__all__ += ["concat", "reshape"] from ._statistical_functions import sum diff --git a/heat/array_api/_data_type_functions.py b/heat/array_api/_data_type_functions.py index e10fabc8cd..f86903cd63 100644 --- a/heat/array_api/_data_type_functions.py +++ b/heat/array_api/_data_type_functions.py @@ -1,6 +1,7 @@ from __future__ import annotations from ._array_object import Array +from ._dtypes import _all_dtypes, _result_type from dataclasses import dataclass from typing import TYPE_CHECKING, Union @@ -86,3 +87,32 @@ def iinfo(type: Union[Dtype, Array], /) -> iinfo_object: """ ii = ht.iinfo(type) return iinfo_object(ii.bits, int(ii.max), int(ii.min)) + + +def result_type(*arrays_and_dtypes: Union[Array, Dtype]) -> Dtype: + """ + Returns the dtype that results from applying the type promotion rules + to the arguments. + + Parameters + ---------- + arrays_and_dtypes : Union[Array, Dtype] + An arbitrary number of input arrays and/or dtypes. + """ + A = [] + for a in arrays_and_dtypes: + if isinstance(a, Array): + a = a.dtype + elif isinstance(a, ht.DNDarray) or a not in _all_dtypes: + raise TypeError("result_type() inputs must be array_api arrays or dtypes") + A.append(a) + + if len(A) == 0: + raise ValueError("at least one array or dtype is required") + elif len(A) == 1: + return A[0] + else: + t = A[0] + for t2 in A[1:]: + t = _result_type(t, t2) + return t diff --git a/heat/array_api/_manipulation_functions.py b/heat/array_api/_manipulation_functions.py index d49ad2eaaf..b63f9e55c2 100644 --- a/heat/array_api/_manipulation_functions.py +++ b/heat/array_api/_manipulation_functions.py @@ -1,12 +1,34 @@ from __future__ import annotations from ._array_object import Array +from ._data_type_functions import result_type -from typing import Optional, Tuple +from typing import Optional, Tuple, Union, List import heat as ht +def concat(arrays: Union[Tuple[Array, ...], List[Array]], /, *, axis: Optional[int] = 0) -> Array: + """ + Joins a sequence of arrays along an existing axis. + + Parameters + ---------- + arrays : Union[Tuple[Array, ...], List[Array]] + Input arrays to join. The arrays must have the same shape, + except in the dimension specified by ``axis``. + axis : Optional[int] + Axis along which the arrays will be joined. If ``axis`` is ``None``, + arrays are flattened before concatenation. Default: ``0``. + """ + # dtype = result_type(*arrays) + arrays = tuple(a._array for a in arrays) + if axis is None: + arrays = tuple(ht.flatten(a) for a in arrays) + axis = 0 + return Array._new(ht.concatenate(arrays, axis=axis)) + + def reshape(x: Array, /, shape: Tuple[int, ...], *, copy: Optional[bool] = None) -> Array: """ Reshapes an array without changing its data. From 4857e61dd73b2718780641b5e841820ed85f08ce Mon Sep 17 00:00:00 2001 From: neosunhan Date: Thu, 30 Jun 2022 22:11:56 +0800 Subject: [PATCH 054/150] Implement `expand_dims` --- heat/array_api/__init__.py | 3 ++- heat/array_api/_manipulation_functions.py | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index 790311fd81..4d582e2461 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -161,10 +161,11 @@ from ._manipulation_functions import ( concat, + expand_dims, reshape, ) -__all__ += ["concat", "reshape"] +__all__ += ["concat", "expand_dims", "reshape"] from ._statistical_functions import sum diff --git a/heat/array_api/_manipulation_functions.py b/heat/array_api/_manipulation_functions.py index b63f9e55c2..8058d920e1 100644 --- a/heat/array_api/_manipulation_functions.py +++ b/heat/array_api/_manipulation_functions.py @@ -29,6 +29,23 @@ def concat(arrays: Union[Tuple[Array, ...], List[Array]], /, *, axis: Optional[i return Array._new(ht.concatenate(arrays, axis=axis)) +def expand_dims(x: Array, /, *, axis: int = 0) -> Array: + """ + Expands the shape of an array by inserting a new axis (dimension) of + size one at the position specified by ``axis``. + + Parameters + ---------- + x : Array + Input array. + axis : int + Axis position (zero-based). + """ + if axis < -x.ndim - 1 or axis > x.ndim: + raise IndexError("Invalid axis") + return Array._new(ht.expand_dims(x._array, axis)) + + def reshape(x: Array, /, shape: Tuple[int, ...], *, copy: Optional[bool] = None) -> Array: """ Reshapes an array without changing its data. From fb8ebf8b8eec5de1df9a8682c04246d8cbbe196e Mon Sep 17 00:00:00 2001 From: neosunhan Date: Thu, 30 Jun 2022 22:15:22 +0800 Subject: [PATCH 055/150] Implement `flip` --- heat/array_api/__init__.py | 3 ++- heat/array_api/_manipulation_functions.py | 19 ++++++++++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index 4d582e2461..3bd48bfdd0 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -162,10 +162,11 @@ from ._manipulation_functions import ( concat, expand_dims, + flip, reshape, ) -__all__ += ["concat", "expand_dims", "reshape"] +__all__ += ["concat", "expand_dims", "flip", "reshape"] from ._statistical_functions import sum diff --git a/heat/array_api/_manipulation_functions.py b/heat/array_api/_manipulation_functions.py index 8058d920e1..a9e40bd586 100644 --- a/heat/array_api/_manipulation_functions.py +++ b/heat/array_api/_manipulation_functions.py @@ -39,13 +39,30 @@ def expand_dims(x: Array, /, *, axis: int = 0) -> Array: x : Array Input array. axis : int - Axis position (zero-based). + Axis position (zero-based). If ``x`` has rank (i.e, number of dimensions) ``N``, + a valid ``axis`` must reside on the closed-interval ``[-N-1, N]``. """ if axis < -x.ndim - 1 or axis > x.ndim: raise IndexError("Invalid axis") return Array._new(ht.expand_dims(x._array, axis)) +def flip(x: Array, /, *, axis: Optional[Union[int, Tuple[int, ...]]] = None) -> Array: + """ + Reverses the order of elements in an array along the given ``axis``. The + shape of the array is preserved. + + Parameters + ---------- + x : Array + Input array. + axis : int + Axis (or axes) along which to flip. If ``axis`` is ``None``, the function + flips all input array axes. + """ + return Array._new(ht.flip(x._array, axis=axis)) + + def reshape(x: Array, /, shape: Tuple[int, ...], *, copy: Optional[bool] = None) -> Array: """ Reshapes an array without changing its data. From 3043a4f201d544bdbc00f2121a18a256cd316736 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Thu, 30 Jun 2022 22:18:48 +0800 Subject: [PATCH 056/150] Implement `permute_dims` --- heat/array_api/__init__.py | 3 ++- heat/array_api/_manipulation_functions.py | 17 ++++++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index 3bd48bfdd0..20e50269fa 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -163,10 +163,11 @@ concat, expand_dims, flip, + permute_dims, reshape, ) -__all__ += ["concat", "expand_dims", "flip", "reshape"] +__all__ += ["concat", "expand_dims", "flip", "permute_dims", "reshape"] from ._statistical_functions import sum diff --git a/heat/array_api/_manipulation_functions.py b/heat/array_api/_manipulation_functions.py index a9e40bd586..c867a05fab 100644 --- a/heat/array_api/_manipulation_functions.py +++ b/heat/array_api/_manipulation_functions.py @@ -56,13 +56,28 @@ def flip(x: Array, /, *, axis: Optional[Union[int, Tuple[int, ...]]] = None) -> ---------- x : Array Input array. - axis : int + axis : Optional[Union[int, Tuple[int, ...]]] Axis (or axes) along which to flip. If ``axis`` is ``None``, the function flips all input array axes. """ return Array._new(ht.flip(x._array, axis=axis)) +def permute_dims(x: Array, /, axes: Tuple[int, ...]) -> Array: + """ + Permutes the axes (dimensions) of an array ``x``. + + Parameters + ---------- + x : Array + Input array. + axes : Tuple[int, ...] + Tuple containing a permutation of ``(0, 1, ..., N-1)`` where ``N`` is the + number of axes (dimensions) of ``x``. + """ + return Array._new(ht.transpose(x._array, list(axes))) + + def reshape(x: Array, /, shape: Tuple[int, ...], *, copy: Optional[bool] = None) -> Array: """ Reshapes an array without changing its data. From 2d2df2edeb847aec1b5bedc25aca17dd591079c2 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Thu, 30 Jun 2022 22:23:28 +0800 Subject: [PATCH 057/150] Implement `roll` --- heat/array_api/__init__.py | 3 ++- heat/array_api/_manipulation_functions.py | 31 +++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index 20e50269fa..63aceebb29 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -165,9 +165,10 @@ flip, permute_dims, reshape, + roll, ) -__all__ += ["concat", "expand_dims", "flip", "permute_dims", "reshape"] +__all__ += ["concat", "expand_dims", "flip", "permute_dims", "reshape", "roll"] from ._statistical_functions import sum diff --git a/heat/array_api/_manipulation_functions.py b/heat/array_api/_manipulation_functions.py index c867a05fab..a8b48d96fe 100644 --- a/heat/array_api/_manipulation_functions.py +++ b/heat/array_api/_manipulation_functions.py @@ -99,3 +99,34 @@ def reshape(x: Array, /, shape: Tuple[int, ...], *, copy: Optional[bool] = None) x._array = res return x return Array._new(res) + + +def roll( + x: Array, + /, + shift: Union[int, Tuple[int, ...]], + *, + axis: Optional[Union[int, Tuple[int, ...]]] = None, +) -> Array: + """ + Rolls array elements along a specified axis. Array elements that roll + beyond the last position are re-introduced at the first position. + Array elements that roll beyond the first position are re-introduced + at the last position. + + Parameters + ---------- + x : Array + Input array. + shift : Union[int, Tuple[int, ...]] + Number of places by which the elements are shifted. If ``shift`` is a + tuple, then ``axis`` must be a tuple of the same size, and each of the + given axes is shifted by the corresponding element in ``shift``. + If ``shift`` is an ``int`` and ``axis`` a tuple, then the same ``shift`` + is used for all specified axes. + axis : Optional[Union[int, Tuple[int, ...]]] + Axis (or axes) along which elements to shift. If ``axis`` is ``None``, + the array is flattened, shifted, and then restored to its original shape. + Default: ``None``. + """ + return Array._new(ht.roll(x._array, shift, axis=axis)) From 76a2ba06487ad87de47b57056e557a6ad5176ba8 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Thu, 30 Jun 2022 22:26:48 +0800 Subject: [PATCH 058/150] Implement `squeeze` --- heat/array_api/__init__.py | 4 ++- heat/array_api/_manipulation_functions.py | 35 +++++++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index 63aceebb29..dd60083064 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -166,9 +166,11 @@ permute_dims, reshape, roll, + squeeze, + stack, ) -__all__ += ["concat", "expand_dims", "flip", "permute_dims", "reshape", "roll"] +__all__ += ["concat", "expand_dims", "flip", "permute_dims", "reshape", "roll", "squeeze", "stack"] from ._statistical_functions import sum diff --git a/heat/array_api/_manipulation_functions.py b/heat/array_api/_manipulation_functions.py index a8b48d96fe..86295bf3d5 100644 --- a/heat/array_api/_manipulation_functions.py +++ b/heat/array_api/_manipulation_functions.py @@ -130,3 +130,38 @@ def roll( Default: ``None``. """ return Array._new(ht.roll(x._array, shift, axis=axis)) + + +def squeeze(x: Array, /, axis: Union[int, Tuple[int, ...]]) -> Array: + """ + Removes singleton dimensions (axes) from ``x``. + + Parameters + ---------- + x : Array + Input array. + axis : Union[int, Tuple[int, ...]] + Axis (or axes) to squeeze. + + Raises + ------ + ``ValueError``, if an axis is selected with shape entry greater than one. + """ + return Array._new(ht.squeeze(x._array, axis=axis)) + + +def stack(arrays: Union[Tuple[Array, ...], List[Array]], /, *, axis: int = 0) -> Array: + """ + Joins a sequence of arrays along a new axis. + + Parameters + ---------- + arrays : Union[Tuple[array, ...], List[array]] + Input arrays to join. Each array must have the same shape. + axis : int + Axis along which the arrays will be joined. + """ + # Call result type here just to raise on disallowed type combinations + result_type(*arrays) + arrays = tuple(a._array for a in arrays) + return Array._new(ht.stack(arrays, axis=axis)) From a67a9a05e2491c754061866b33bdcb61aea3a508 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Wed, 6 Jul 2022 10:01:40 +0800 Subject: [PATCH 059/150] Implement `can_cast` --- heat/array_api/__init__.py | 3 +- heat/array_api/_data_type_functions.py | 51 +++++++++++++++++++++++++- 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index dd60083064..f3226f6146 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -51,10 +51,11 @@ astype, finfo, iinfo, + can_cast, result_type, ) -__all__ += ["astype", "finfo", "iinfo", "result_type"] +__all__ += ["astype", "finfo", "iinfo", "can_cast", "result_type"] from heat.core.devices import cpu diff --git a/heat/array_api/_data_type_functions.py b/heat/array_api/_data_type_functions.py index f86903cd63..15e3212185 100644 --- a/heat/array_api/_data_type_functions.py +++ b/heat/array_api/_data_type_functions.py @@ -4,12 +4,13 @@ from ._dtypes import _all_dtypes, _result_type from dataclasses import dataclass -from typing import TYPE_CHECKING, Union +from typing import TYPE_CHECKING, Union, List if TYPE_CHECKING: from ._typing import Dtype import heat as ht +from heat.core.stride_tricks import broadcast_shape def astype(x: Array, dtype: Dtype, /, *, copy: bool = True) -> Array: @@ -33,6 +34,54 @@ def astype(x: Array, dtype: Dtype, /, *, copy: bool = True) -> Array: return Array._new(x._array.astype(dtype, copy=True)) +def broadcast_arrays(*arrays: Array) -> List[Array]: + """ + Broadcasts one or more arrays against one another. + + Parameters + ---------- + arrays : Array + An arbitrary number of to-be broadcasted arrays. + """ + from ._array_object import Array + + if len(arrays) <= 1: + return arrays + output_shape = arrays[0].shape + for a in arrays[1:]: + output_shape = broadcast_shape(output_shape, a.shape) + return [Array._new(array) for array in ht.broadcast_arrays(*[a._array for a in arrays])] + + +def can_cast(from_: Union[Dtype, Array], to: Dtype, /) -> bool: + """ + Determines if one data type can be cast to another data type according to + Type Promotion Rules. + + + Parameters + ---------- + from : Union[Dtype, Array] + Input data type or array from which to cast. + to : Dtype + Desired data type. + """ + if isinstance(from_, Array): + from_ = from_.dtype + elif from_ not in _all_dtypes: + raise TypeError(f"{from_=}, but should be an array_api array or dtype") + if to not in _all_dtypes: + raise TypeError(f"{to=}, but should be a dtype") + try: + # We promote `from_` and `to` together. We then check if the promoted + # dtype is `to`, which indicates if `from_` can (up)cast to `to`. + dtype = _result_type(from_, to) + return to == dtype + except TypeError: + # _result_type() raises if the dtypes don't promote together + return False + + @dataclass class finfo_object: """ From 1cbe90e64b070d8d6f9d5a38dcc7ef2676e4a011 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Wed, 6 Jul 2022 10:08:43 +0800 Subject: [PATCH 060/150] Implement `acos` --- heat/array_api/__init__.py | 6 ++++-- heat/array_api/_elementwise_functions.py | 16 ++++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index f3226f6146..9831ae1d18 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -49,13 +49,13 @@ from ._data_type_functions import ( astype, + can_cast, finfo, iinfo, - can_cast, result_type, ) -__all__ += ["astype", "finfo", "iinfo", "can_cast", "result_type"] +__all__ += ["astype", "can_cast", "finfo", "iinfo", "result_type"] from heat.core.devices import cpu @@ -98,6 +98,7 @@ from ._elementwise_functions import ( abs, + acos, add, bitwise_and, bitwise_left_shift, @@ -126,6 +127,7 @@ __all__ += [ "abs", + "acos", "add", "bitwise_and", "bitwise_left_shift", diff --git a/heat/array_api/_elementwise_functions.py b/heat/array_api/_elementwise_functions.py index 0c13c5e6c4..94bcc2f3a5 100644 --- a/heat/array_api/_elementwise_functions.py +++ b/heat/array_api/_elementwise_functions.py @@ -28,6 +28,22 @@ def abs(x: Array, /) -> Array: return Array._new(ht.abs(x._array, dtype=x.dtype)) +def acos(x: Array, /) -> Array: + """ + Calculates an approximation of the principal value of the inverse cosine, + having domain ``[-1, +1]`` and codomain ``[+0, +Ļ€]``, for each element ``x_i`` + of the input array ``x``. Each element-wise result is expressed in radians. + + Parameters + ---------- + x : Array + Input array. Must have a floating-point data type. + """ + if x.dtype not in _floating_dtypes: + raise TypeError("Only floating-point dtypes are allowed in acos") + return Array._new(ht.acos(x._array)) + + def add(x1: Array, x2: Array, /) -> Array: """ Calculates the sum for each element ``x1_i`` of the input array ``x1`` with From da0a42c77d9dd2cb7545700cf30de30d4c1717f4 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Wed, 6 Jul 2022 10:11:45 +0800 Subject: [PATCH 061/150] Implement `acosh` --- heat/array_api/__init__.py | 2 ++ heat/array_api/_elementwise_functions.py | 17 +++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index 9831ae1d18..9fc14d4681 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -99,6 +99,7 @@ from ._elementwise_functions import ( abs, acos, + acosh, add, bitwise_and, bitwise_left_shift, @@ -128,6 +129,7 @@ __all__ += [ "abs", "acos", + "acosh", "add", "bitwise_and", "bitwise_left_shift", diff --git a/heat/array_api/_elementwise_functions.py b/heat/array_api/_elementwise_functions.py index 94bcc2f3a5..ad87a59565 100644 --- a/heat/array_api/_elementwise_functions.py +++ b/heat/array_api/_elementwise_functions.py @@ -44,6 +44,23 @@ def acos(x: Array, /) -> Array: return Array._new(ht.acos(x._array)) +def acosh(x: Array, /) -> Array: + """ + Calculates an approximation to the inverse hyperbolic cosine, having domain + ``[+1, +infinity]`` and codomain ``[+0, +infinity]``, for each element ``x_i`` + of the input array ``x``. + + Parameters + ---------- + x : Array + Input array whose elements each represent the area of a hyperbolic sector. + Must have a floating-point data type. + """ + if x.dtype not in _floating_dtypes: + raise TypeError("Only floating-point dtypes are allowed in acosh") + return Array._new(ht.acosh(x._array)) + + def add(x1: Array, x2: Array, /) -> Array: """ Calculates the sum for each element ``x1_i`` of the input array ``x1`` with From c37effdb4b872a528f2e8e639c2dfbc0c00ce652 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Wed, 6 Jul 2022 10:15:14 +0800 Subject: [PATCH 062/150] Implement `asin` and `asinh` --- heat/array_api/__init__.py | 4 +++ heat/array_api/_elementwise_functions.py | 33 ++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index 9fc14d4681..e6ae766b6b 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -101,6 +101,8 @@ acos, acosh, add, + asin, + asinh, bitwise_and, bitwise_left_shift, bitwise_invert, @@ -131,6 +133,8 @@ "acos", "acosh", "add", + "asin", + "asinh", "bitwise_and", "bitwise_left_shift", "bitwise_invert", diff --git a/heat/array_api/_elementwise_functions.py b/heat/array_api/_elementwise_functions.py index ad87a59565..27d6910c13 100644 --- a/heat/array_api/_elementwise_functions.py +++ b/heat/array_api/_elementwise_functions.py @@ -82,6 +82,39 @@ def add(x1: Array, x2: Array, /) -> Array: return Array._new(ht.add(x1._array, x2._array)) +def asin(x: Array, /) -> Array: + """ + Calculates an approximation of the principal value of the inverse sine, having + domain ``[-1, +1]`` and codomain ``[-Ļ€/2, +Ļ€/2]`` for each element ``x_i`` of + the input array ``x``. Each element-wise result is expressed in radians. + + Parameters + ---------- + x : Array + Input array. Must have a floating-point data type. + """ + if x.dtype not in _floating_dtypes: + raise TypeError("Only floating-point dtypes are allowed in asin") + return Array._new(ht.asin(x._array)) + + +def asinh(x: Array, /) -> Array: + """ + Calculates an approximation to the inverse hyperbolic sine, having domain + ``[-infinity, +infinity]`` and codomain ``[-infinity, +infinity]``, for each + element ``x_i`` in the input array ``x``. + + Parameters + ---------- + x : Array + Input array whose elements each represent the area of a hyperbolic sector. + Must have a floating-point data type. + """ + if x.dtype not in _floating_dtypes: + raise TypeError("Only floating-point dtypes are allowed in asinh") + return Array._new(ht.asinh(x._array)) + + def bitwise_and(x1: Array, x2: Array, /) -> Array: """ Computes the bitwise AND of the underlying binary representation of each From a3a36442c58868f5e6695eae6228cf71eb5533d4 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Wed, 6 Jul 2022 10:23:38 +0800 Subject: [PATCH 063/150] Implement `atan`, `atan2`, `atanh` --- heat/array_api/__init__.py | 6 +++ heat/array_api/_elementwise_functions.py | 66 ++++++++++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index e6ae766b6b..8f654d3587 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -103,6 +103,9 @@ add, asin, asinh, + atan, + atan2, + atanh, bitwise_and, bitwise_left_shift, bitwise_invert, @@ -135,6 +138,9 @@ "add", "asin", "asinh", + "atan", + "atan2", + "atanh", "bitwise_and", "bitwise_left_shift", "bitwise_invert", diff --git a/heat/array_api/_elementwise_functions.py b/heat/array_api/_elementwise_functions.py index 27d6910c13..9a461ba9ff 100644 --- a/heat/array_api/_elementwise_functions.py +++ b/heat/array_api/_elementwise_functions.py @@ -115,6 +115,72 @@ def asinh(x: Array, /) -> Array: return Array._new(ht.asinh(x._array)) +def atan(x: Array, /) -> Array: + """ + Calculates an implementation-dependent approximation of the principal value of + the inverse tangent, having domain ``[-infinity, +infinity]`` and codomain + ``[-Ļ€/2, +Ļ€/2]``, for each element ``x_i`` of the input array ``x``. + Each element-wise result is expressed in radians. + + Parameters + ---------- + x : Array + Input array. Must have a floating-point data type. + """ + if x.dtype not in _floating_dtypes: + raise TypeError("Only floating-point dtypes are allowed in atan") + return Array._new(ht.atan(x._array)) + + +def atan2(x1: Array, x2: Array, /) -> Array: + """ + Calculates an approximation of the inverse tangent of the quotient ``x1/x2``, + having domain ``[-infinity, +infinity] x [-infinity, +infinity]`` (where the + ``x`` notation denotes the set of ordered pairs of elements ``(x1_i, x2_i)``) + and codomain ``[-Ļ€, +Ļ€]``, for each pair of elements ``(x1_i, x2_i)`` of the + input arrays ``x1`` and ``x2``, respectively. Each element-wise result is + expressed in radians. + + The mathematical signs of ``x1_i`` and ``x2_i`` determine the quadrant of each + element-wise result. The quadrant (i.e., branch) is chosen such that each + element-wise result is the signed angle in radians between the ray ending at the + origin and passing through the point ``(1,0)`` and the ray ending at the origin + and passing through the point ``(x2_i, x1_i)``. + + Parameters + ---------- + x1 : Array + Input array corresponding to the y-coordinates. Must have a floating-point + data type. + x2 : Array + Input array corresponding to the x-coordinates. Must be compatible with ``x1`` + and have a floating-point data type. + """ + if x1.dtype not in _floating_dtypes or x2.dtype not in _floating_dtypes: + raise TypeError("Only floating-point dtypes are allowed in atan2") + # Call result type here just to raise on disallowed type combinations + _result_type(x1.dtype, x2.dtype) + x1, x2 = Array._normalize_two_args(x1, x2) + return Array._new(ht.atan2(x1._array, x2._array)) + + +def atanh(x: Array, /) -> Array: + """ + Calculates an approximation to the inverse hyperbolic tangent, having domain + ``[-1, +1]`` and codomain ``[-infinity, +infinity]``, for each element ``x_i`` + of the input array ``x``. + + Parameters + ---------- + x : Array + Input array whose elements each represent the area of a hyperbolic sector. + Must have a floating-point data type. + """ + if x.dtype not in _floating_dtypes: + raise TypeError("Only floating-point dtypes are allowed in atanh") + return Array._new(ht.atanh(x._array)) + + def bitwise_and(x1: Array, x2: Array, /) -> Array: """ Computes the bitwise AND of the underlying binary representation of each From 058873a30295f05b6c8536006ead5788cc054cdc Mon Sep 17 00:00:00 2001 From: neosunhan Date: Wed, 6 Jul 2022 10:26:52 +0800 Subject: [PATCH 064/150] Implement `ceil` --- heat/array_api/__init__.py | 2 ++ heat/array_api/_elementwise_functions.py | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index 8f654d3587..f07079504d 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -112,6 +112,7 @@ bitwise_or, bitwise_right_shift, bitwise_xor, + ceil, divide, equal, floor_divide, @@ -147,6 +148,7 @@ "bitwise_or", "bitwise_right_shift", "bitwise_xor", + "ceil", "divide", "equal", "floor_divide", diff --git a/heat/array_api/_elementwise_functions.py b/heat/array_api/_elementwise_functions.py index 9a461ba9ff..0e35fa3457 100644 --- a/heat/array_api/_elementwise_functions.py +++ b/heat/array_api/_elementwise_functions.py @@ -310,6 +310,24 @@ def bitwise_xor(x1: Array, x2: Array, /) -> Array: return Array._new(ht.bitwise_xor(x1._array, x2._array)) +def ceil(x: Array, /) -> Array: + """ + Rounds each element ``x_i`` of the input array ``x`` to the smallest (i.e., closest + to ``-infinity``) integer-valued number that is not less than ``x_i``. + + Parameters + ---------- + x : Array + Input array. Must have a numeric data type. + """ + if x.dtype not in _numeric_dtypes: + raise TypeError("Only numeric dtypes are allowed in ceil") + if x.dtype in _integer_dtypes: + # Note: The return dtype of ceil is the same as the input + return x + return Array._new(ht.ceil(x._array)) + + def divide(x1: Array, x2: Array, /) -> Array: """ Calculates the division for each element ``x1_i`` of the input array ``x1`` From 50b4054a57e0aee4fbd00061e3ef6f6a061199b2 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Wed, 6 Jul 2022 10:30:41 +0800 Subject: [PATCH 065/150] Implement `cos` and `cosh` --- heat/array_api/__init__.py | 4 +++ heat/array_api/_elementwise_functions.py | 34 ++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index f07079504d..c0e5a372a1 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -113,6 +113,8 @@ bitwise_right_shift, bitwise_xor, ceil, + cos, + cosh, divide, equal, floor_divide, @@ -149,6 +151,8 @@ "bitwise_right_shift", "bitwise_xor", "ceil", + "cos", + "cosh", "divide", "equal", "floor_divide", diff --git a/heat/array_api/_elementwise_functions.py b/heat/array_api/_elementwise_functions.py index 0e35fa3457..23146116c1 100644 --- a/heat/array_api/_elementwise_functions.py +++ b/heat/array_api/_elementwise_functions.py @@ -328,6 +328,40 @@ def ceil(x: Array, /) -> Array: return Array._new(ht.ceil(x._array)) +def cos(x: Array, /) -> Array: + """ + Calculates an approximation to the cosine, having domain ``(-infinity, +infinity)`` + and codomain ``[-1, +1]``, for each element ``x_i`` of the input array ``x``. + Each element ``x_i`` is assumed to be expressed in radians. + + Parameters + ---------- + x : Array + Input array whose elements are each expressed in radians. Must have a + floating-point data type. + """ + if x.dtype not in _floating_dtypes: + raise TypeError("Only floating-point dtypes are allowed in cos") + return Array._new(ht.cos(x._array)) + + +def cosh(x: Array, /) -> Array: + """ + Calculates an approximation to the hyperbolic cosine, having domain + ``[-infinity, +infinity]`` and codomain ``[-infinity, +infinity]``, for each + element ``x_i`` in the input array ``x``. + + Parameters + ---------- + x : Array + Input array whose elements each represent a hyperbolic angle. Must have + a floating-point data type. + """ + if x.dtype not in _floating_dtypes: + raise TypeError("Only floating-point dtypes are allowed in cosh") + return Array._new(ht.cosh(x._array)) + + def divide(x1: Array, x2: Array, /) -> Array: """ Calculates the division for each element ``x1_i`` of the input array ``x1`` From b26ccd9120efeb45e5c0c2a3582c8254b6ca0a7d Mon Sep 17 00:00:00 2001 From: neosunhan Date: Wed, 6 Jul 2022 10:34:34 +0800 Subject: [PATCH 066/150] Implement `exp` and `expm1` --- heat/array_api/__init__.py | 4 +++ heat/array_api/_elementwise_functions.py | 33 ++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index c0e5a372a1..5c1291cc8d 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -117,6 +117,8 @@ cosh, divide, equal, + exp, + expm1, floor_divide, greater, greater_equal, @@ -155,6 +157,8 @@ "cosh", "divide", "equal", + "exp", + "expm1", "floor_divide", "greater", "greater_equal", diff --git a/heat/array_api/_elementwise_functions.py b/heat/array_api/_elementwise_functions.py index 23146116c1..2685671be4 100644 --- a/heat/array_api/_elementwise_functions.py +++ b/heat/array_api/_elementwise_functions.py @@ -402,6 +402,39 @@ def equal(x1: Array, x2: Array, /) -> Array: return Array._new(ht.eq(x1._array, x2._array)) +def exp(x: Array, /) -> Array: + """ + Calculates an approximation to the exponential function, having domain + ``[-infinity, +infinity]`` and codomain ``[+0, +infinity]``, for each element + ``x_i`` of the input array ``x`` (``e`` raised to the power of ``x_i``, where + ``e`` is the base of the natural logarithm). + + Parameters + ---------- + x : Array + Input array. Must have a floating-point data type. + """ + if x.dtype not in _floating_dtypes: + raise TypeError("Only floating-point dtypes are allowed in exp") + return Array._new(ht.exp(x._array)) + + +def expm1(x: Array, /) -> Array: + """ + Calculates an approximation to ``exp(x)-1``, having domain + ``[-infinity, +infinity]`` and codomain ``[-1, +infinity]``, for each element + ``x_i`` of the input array ``x``. + + Parameters + ---------- + x : Array + Input array. Must have a floating-point data type. + """ + if x.dtype not in _floating_dtypes: + raise TypeError("Only floating-point dtypes are allowed in expm1") + return Array._new(ht.expm1(x._array)) + + def floor_divide(x1: Array, x2: Array, /) -> Array: """ Rounds the result of dividing each element ``x1_i`` of the input array ``x1`` From 666855a3cbbc3eba0edcae913e35215429815d09 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Wed, 6 Jul 2022 10:36:20 +0800 Subject: [PATCH 067/150] Implement `floor` --- heat/array_api/__init__.py | 2 ++ heat/array_api/_elementwise_functions.py | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index 5c1291cc8d..675243cf29 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -119,6 +119,7 @@ equal, exp, expm1, + floor, floor_divide, greater, greater_equal, @@ -159,6 +160,7 @@ "equal", "exp", "expm1", + "floor", "floor_divide", "greater", "greater_equal", diff --git a/heat/array_api/_elementwise_functions.py b/heat/array_api/_elementwise_functions.py index 2685671be4..bc59375ed9 100644 --- a/heat/array_api/_elementwise_functions.py +++ b/heat/array_api/_elementwise_functions.py @@ -435,6 +435,25 @@ def expm1(x: Array, /) -> Array: return Array._new(ht.expm1(x._array)) +def floor(x: Array, /) -> Array: + """ + Rounds each element ``x_i`` of the input array ``x`` to the greatest + (i.e., closest to ``+infinity``) integer-valued number that is not greater + than ``x_i``. + + Parameters + ---------- + x : Array + Input array. Must have a numeric data type. + """ + if x.dtype not in _numeric_dtypes: + raise TypeError("Only numeric dtypes are allowed in floor") + if x.dtype in _integer_dtypes: + # Note: The return dtype of floor is the same as the input + return x + return Array._new(ht.floor(x._array)) + + def floor_divide(x1: Array, x2: Array, /) -> Array: """ Rounds the result of dividing each element ``x1_i`` of the input array ``x1`` From 4ce40dc285fe4be47e94e93d6f966da0e5b95098 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Wed, 6 Jul 2022 10:44:28 +0800 Subject: [PATCH 068/150] Implement `log`, `log1p`, `log2`, `log10`, `logaddexp` --- heat/array_api/__init__.py | 10 +++ heat/array_api/_elementwise_functions.py | 86 ++++++++++++++++++++++++ 2 files changed, 96 insertions(+) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index 675243cf29..6f80a613d8 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -128,6 +128,11 @@ isnan, less, less_equal, + log, + log1p, + log2, + log10, + logaddexp, multiply, negative, not_equal, @@ -169,6 +174,11 @@ "isnan", "less", "less_equal", + "log", + "log1p", + "log2", + "log10", + "logaddexp", "multiply", "negative", "not_equal", diff --git a/heat/array_api/_elementwise_functions.py b/heat/array_api/_elementwise_functions.py index bc59375ed9..0190a758fe 100644 --- a/heat/array_api/_elementwise_functions.py +++ b/heat/array_api/_elementwise_functions.py @@ -610,6 +610,92 @@ def less_equal(x1: Array, x2: Array, /) -> Array: return Array._new(ht.less_equal(x1._array, x2._array)) +def log(x: Array, /) -> Array: + """ + Calculates an approximation to the natural (base ``e``) logarithm, having domain + ``[0, +infinity]`` and codomain ``[-infinity, +infinity]``, for each element + ``x_i`` of the input array ``x``. + + Parameters + ---------- + x : Array + Input array. Must have a floating-point data type. + """ + if x.dtype not in _floating_dtypes: + raise TypeError("Only floating-point dtypes are allowed in log") + return Array._new(ht.log(x._array)) + + +def log1p(x: Array, /) -> Array: + """ + Calculates an approximation to ``log(1+x)``, where ``log`` refers to the natural + (base ``e``) logarithm, having domain ``[-1, +infinity]`` and codomain + ``[-infinity, +infinity]``, for each element ``x_i`` of the input array ``x``. + + Parameters + ---------- + x : Array + Input array. Must have a floating-point data type. + """ + if x.dtype not in _floating_dtypes: + raise TypeError("Only floating-point dtypes are allowed in log1p") + return Array._new(ht.log1p(x._array)) + + +def log2(x: Array, /) -> Array: + """ + Calculates an approximation to the base ``2`` logarithm, having domain + ``[0, +infinity]`` and codomain ``[-infinity, +infinity]``, for each element + ``x_i`` of the input array ``x``. + + Parameters + ---------- + x : Array + Input array. Must have a floating-point data type. + """ + if x.dtype not in _floating_dtypes: + raise TypeError("Only floating-point dtypes are allowed in log2") + return Array._new(ht.log2(x._array)) + + +def log10(x: Array, /) -> Array: + """ + Calculates an approximation to the base ``10`` logarithm, having domain + ``[0, +infinity]`` and codomain ``[-infinity, +infinity]``, for each element + ``x_i`` of the input array ``x``. + + Parameters + ---------- + x : Array + Input array. Must have a floating-point data type. + """ + if x.dtype not in _floating_dtypes: + raise TypeError("Only floating-point dtypes are allowed in log10") + return Array._new(ht.log10(x._array)) + + +def logaddexp(x1: Array, x2: Array) -> Array: + """ + Calculates the logarithm of the sum of exponentiations ``log(exp(x1) + exp(x2))`` + for each element ``x1_i`` of the input array ``x1`` with the respective element + ``x2_i`` of the input array ``x2``. + + Parameters + ---------- + x1 : Array + First input array. Must have a floating-point data type. + x2 : Array + Second input array. Must be compatible with ``x1`` and have a floating-point + data type. + """ + if x1.dtype not in _floating_dtypes or x2.dtype not in _floating_dtypes: + raise TypeError("Only floating-point dtypes are allowed in logaddexp") + # Call result type here just to raise on disallowed type combinations + _result_type(x1.dtype, x2.dtype) + x1, x2 = Array._normalize_two_args(x1, x2) + return Array._new(ht.logaddexp(x1._array, x2._array)) + + def multiply(x1: Array, x2: Array, /) -> Array: """ Calculates the product for each element ``x1_i`` of the input array ``x1`` From 19294ddaed12fe6c44e87e488f9e20b4e05b6f28 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Wed, 6 Jul 2022 10:49:55 +0800 Subject: [PATCH 069/150] Implement `logical_and`, `logical_not`, `logical_or`, `logical_xor` --- heat/array_api/__init__.py | 8 +++ heat/array_api/_elementwise_functions.py | 78 ++++++++++++++++++++++++ 2 files changed, 86 insertions(+) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index 6f80a613d8..c5f0442e12 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -133,6 +133,10 @@ log2, log10, logaddexp, + logical_and, + logical_not, + logical_or, + logical_xor, multiply, negative, not_equal, @@ -179,6 +183,10 @@ "log2", "log10", "logaddexp", + "logical_and", + "logical_not", + "logical_or", + "logical_xor", "multiply", "negative", "not_equal", diff --git a/heat/array_api/_elementwise_functions.py b/heat/array_api/_elementwise_functions.py index 0190a758fe..4c38e245e3 100644 --- a/heat/array_api/_elementwise_functions.py +++ b/heat/array_api/_elementwise_functions.py @@ -2,6 +2,7 @@ from ._dtypes import ( _numeric_dtypes, + _boolean_dtypes, _integer_dtypes, _integer_or_boolean_dtypes, _floating_dtypes, @@ -696,6 +697,83 @@ def logaddexp(x1: Array, x2: Array) -> Array: return Array._new(ht.logaddexp(x1._array, x2._array)) +def logical_and(x1: Array, x2: Array, /) -> Array: + """ + Computes the logical AND for each element ``x1_i`` of the input array ``x1`` + with the respective element ``x2_i`` of the input array ``x2``. + + Parameters + ---------- + x1 : Array + First input array. Must have a boolean data type. + x2 : Array + Second input array. Must be compatible with ``x1`` and have a boolean + data type. + """ + if x1.dtype not in _boolean_dtypes or x2.dtype not in _boolean_dtypes: + raise TypeError("Only boolean dtypes are allowed in logical_and") + # Call result type here just to raise on disallowed type combinations + _result_type(x1.dtype, x2.dtype) + x1, x2 = Array._normalize_two_args(x1, x2) + return Array._new(ht.logical_and(x1._array, x2._array)) + + +def logical_not(x: Array, /) -> Array: + """ + Computes the logical NOT for each element ``x_i`` of the input array ``x``. + + Parameters + ---------- + x : Array + Input array. Must have a boolean data type. + """ + if x.dtype not in _boolean_dtypes: + raise TypeError("Only boolean dtypes are allowed in logical_not") + return Array._new(ht.logical_not(x._array)) + + +def logical_or(x1: Array, x2: Array, /) -> Array: + """ + Computes the logical OR for each element ``x1_i`` of the input array ``x1`` + with the respective element ``x2_i`` of the input array ``x2``. + + Parameters + ---------- + x1 : Array + First input array. Must have a boolean data type. + x2 : Array + Second input array. Must be compatible with ``x1`` and have a boolean + data type. + """ + if x1.dtype not in _boolean_dtypes or x2.dtype not in _boolean_dtypes: + raise TypeError("Only boolean dtypes are allowed in logical_or") + # Call result type here just to raise on disallowed type combinations + _result_type(x1.dtype, x2.dtype) + x1, x2 = Array._normalize_two_args(x1, x2) + return Array._new(ht.logical_or(x1._array, x2._array)) + + +def logical_xor(x1: Array, x2: Array, /) -> Array: + """ + Computes the logical XOR for each element ``x1_i`` of the input array ``x1`` + with the respective element ``x2_i`` of the input array ``x2``. + + Parameters + ---------- + x1 : Array + First input array. Must have a boolean data type. + x2 : Array + Second input array. Must be compatible with ``x1`` and have a boolean + data type. + """ + if x1.dtype not in _boolean_dtypes or x2.dtype not in _boolean_dtypes: + raise TypeError("Only boolean dtypes are allowed in logical_xor") + # Call result type here just to raise on disallowed type combinations + _result_type(x1.dtype, x2.dtype) + x1, x2 = Array._normalize_two_args(x1, x2) + return Array._new(ht.logical_xor(x1._array, x2._array)) + + def multiply(x1: Array, x2: Array, /) -> Array: """ Calculates the product for each element ``x1_i`` of the input array ``x1`` From a487a4a79ef54faa737fdfffb299e259b1e5c8b7 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Wed, 6 Jul 2022 11:12:32 +0800 Subject: [PATCH 070/150] Implement `round` --- heat/array_api/__init__.py | 2 ++ heat/array_api/_elementwise_functions.py | 17 +++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index c5f0442e12..16ee4eaf57 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -143,6 +143,7 @@ positive, pow, remainder, + round, subtract, ) @@ -193,6 +194,7 @@ "positive", "pow", "remainder", + "round", "subtract", ] diff --git a/heat/array_api/_elementwise_functions.py b/heat/array_api/_elementwise_functions.py index 4c38e245e3..d6c9e09829 100644 --- a/heat/array_api/_elementwise_functions.py +++ b/heat/array_api/_elementwise_functions.py @@ -890,6 +890,23 @@ def remainder(x1: Array, x2: Array, /) -> Array: return Array._new(ht.remainder(x1._array, x2._array)) +def round(x: Array, /) -> Array: + """ + Rounds each element ``x_i`` of the input array ``x`` to the nearest + integer-valued number. + + Parameters + ---------- + x : Array + Input array. Must have a numeric data type. + """ + if x.dtype not in _numeric_dtypes: + raise TypeError("Only numeric dtypes are allowed in round") + elif x.dtype in _integer_dtypes: + return x + return Array._new(ht.round(x._array)) + + def subtract(x1: Array, x2: Array, /) -> Array: """ Calculates the difference for each element ``x1_i`` of the input array From fd767ced66f424bb7c1f016a8f6ee239010355cd Mon Sep 17 00:00:00 2001 From: neosunhan Date: Wed, 6 Jul 2022 11:17:29 +0800 Subject: [PATCH 071/150] Implement `sign` --- heat/array_api/__init__.py | 2 ++ heat/array_api/_elementwise_functions.py | 16 ++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index 16ee4eaf57..13b8ab3a34 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -144,6 +144,7 @@ pow, remainder, round, + sign, subtract, ) @@ -195,6 +196,7 @@ "pow", "remainder", "round", + "sign", "subtract", ] diff --git a/heat/array_api/_elementwise_functions.py b/heat/array_api/_elementwise_functions.py index d6c9e09829..fc1d328c5b 100644 --- a/heat/array_api/_elementwise_functions.py +++ b/heat/array_api/_elementwise_functions.py @@ -9,6 +9,7 @@ _result_type, ) from ._array_object import Array +from ._data_type_functions import astype import heat as ht @@ -907,6 +908,21 @@ def round(x: Array, /) -> Array: return Array._new(ht.round(x._array)) +def sign(x: Array, /) -> Array: + """ + Returns an indication of the sign of a number for each element ``x_i`` of + the input array ``x``. + + Parameters + ---------- + x : Array + Input array. Must have a numeric data type. + """ + if x.dtype not in _numeric_dtypes: + raise TypeError("Only numeric dtypes are allowed in sign") + return astype(Array._new(ht.sign(x._array)), x.dtype) + + def subtract(x1: Array, x2: Array, /) -> Array: """ Calculates the difference for each element ``x1_i`` of the input array From 2c7dd1a580585f70982b7b18d636ecac269b0282 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Wed, 6 Jul 2022 11:21:28 +0800 Subject: [PATCH 072/150] Implement `sin` and `sinh` --- heat/array_api/__init__.py | 4 +++ heat/array_api/_elementwise_functions.py | 34 ++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index 13b8ab3a34..7f402a6968 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -145,6 +145,8 @@ remainder, round, sign, + sin, + sinh, subtract, ) @@ -197,6 +199,8 @@ "remainder", "round", "sign", + "sin", + "sinh", "subtract", ] diff --git a/heat/array_api/_elementwise_functions.py b/heat/array_api/_elementwise_functions.py index fc1d328c5b..f3fd6eae52 100644 --- a/heat/array_api/_elementwise_functions.py +++ b/heat/array_api/_elementwise_functions.py @@ -923,6 +923,40 @@ def sign(x: Array, /) -> Array: return astype(Array._new(ht.sign(x._array)), x.dtype) +def sin(x: Array, /) -> Array: + """ + Calculates an approximation to the sine, having domain ``(-infinity, +infinity)`` + and codomain ``[-1, +1]``, for each element ``x_i`` of the input array ``x``. + Each element ``x_i`` is assumed to be expressed in radians. + + Parameters + ---------- + x : Array + Input array whose elements are each expressed in radians. Must have a + floating-point data type. + """ + if x.dtype not in _floating_dtypes: + raise TypeError("Only floating-point dtypes are allowed in sin") + return Array._new(ht.sin(x._array)) + + +def sinh(x: Array, /) -> Array: + """ + Calculates an approximation to the hyperbolic sine, having domain + ``[-infinity, +infinity]`` and codomain ``[-infinity, +infinity]``, for + each element ``x_i`` of the input array ``x``. + + Parameters + ---------- + x : Array + Input array whose elements each represent a hyperbolic angle. Must have + a floating-point data type. + """ + if x.dtype not in _floating_dtypes: + raise TypeError("Only floating-point dtypes are allowed in sinh") + return Array._new(ht.sinh(x._array)) + + def subtract(x1: Array, x2: Array, /) -> Array: """ Calculates the difference for each element ``x1_i`` of the input array From 05582b675a7112d2b4063ed976792b0598582b2d Mon Sep 17 00:00:00 2001 From: neosunhan Date: Wed, 6 Jul 2022 11:29:23 +0800 Subject: [PATCH 073/150] Implement `square` and `sqrt` --- heat/array_api/__init__.py | 4 ++++ heat/array_api/_elementwise_functions.py | 29 ++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index 7f402a6968..a0900dce4a 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -147,6 +147,8 @@ sign, sin, sinh, + square, + sqrt, subtract, ) @@ -201,6 +203,8 @@ "sign", "sin", "sinh", + "square", + "sqrt", "subtract", ] diff --git a/heat/array_api/_elementwise_functions.py b/heat/array_api/_elementwise_functions.py index f3fd6eae52..3884a14f0e 100644 --- a/heat/array_api/_elementwise_functions.py +++ b/heat/array_api/_elementwise_functions.py @@ -957,6 +957,35 @@ def sinh(x: Array, /) -> Array: return Array._new(ht.sinh(x._array)) +def square(x: Array, /) -> Array: + """ + Squares ``(x_i * x_i)`` each element ``x_i`` of the input array ``x``. + + Parameters + ---------- + x : Array + Input array. Must have a numeric data type. + """ + if x.dtype not in _numeric_dtypes: + raise TypeError("Only numeric dtypes are allowed in square") + return astype(Array._new(ht.square(x._array)), x.dtype) + + +def sqrt(x: Array, /) -> Array: + """ + Calculates the square root, having domain ``[0, +infinity]`` and codomain + ``[0, +infinity]``, for each element ``x_i`` of the input array ``x``. + + Parameters + ---------- + x : Array + Input array. Must have a floating-point data type. + """ + if x.dtype not in _floating_dtypes: + raise TypeError("Only floating-point dtypes are allowed in sqrt") + return Array._new(ht.sqrt(x._array)) + + def subtract(x1: Array, x2: Array, /) -> Array: """ Calculates the difference for each element ``x1_i`` of the input array From 0936cf9829c9c62d3a8269fc68eb0940fca5427b Mon Sep 17 00:00:00 2001 From: neosunhan Date: Wed, 6 Jul 2022 11:32:16 +0800 Subject: [PATCH 074/150] Implement `tan` and `tanh` --- heat/array_api/__init__.py | 4 +++ heat/array_api/_elementwise_functions.py | 34 ++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index a0900dce4a..c7e37101fe 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -150,6 +150,8 @@ square, sqrt, subtract, + tan, + tanh, ) __all__ += [ @@ -206,6 +208,8 @@ "square", "sqrt", "subtract", + "tan", + "tanh", ] from . import linalg diff --git a/heat/array_api/_elementwise_functions.py b/heat/array_api/_elementwise_functions.py index 3884a14f0e..e556a9c790 100644 --- a/heat/array_api/_elementwise_functions.py +++ b/heat/array_api/_elementwise_functions.py @@ -1005,3 +1005,37 @@ def subtract(x1: Array, x2: Array, /) -> Array: _result_type(x1.dtype, x2.dtype) x1, x2 = Array._normalize_two_args(x1, x2) return Array._new(ht.subtract(x1._array, x2._array)) + + +def tan(x: Array, /) -> Array: + """ + Calculates an approximation to the tangent, having domain ``(-infinity, +infinity)`` + and codomain ``(-infinity, +infinity)``, for each element ``x_i`` of the + input array ``x``. Each element ``x_i`` is assumed to be expressed in radians. + + Parameters + ---------- + x : Array + Input array whose elements are each expressed in radians. Must have a + floating-point data type. + """ + if x.dtype not in _floating_dtypes: + raise TypeError("Only floating-point dtypes are allowed in tan") + return Array._new(ht.tan(x._array)) + + +def tanh(x: Array, /) -> Array: + """ + Calculates an approximation to the hyperbolic tangent, having domain + ``[-infinity, +infinity]`` and codomain ``[-1, +1]``, for each element ``x_i`` + of the input array ``x``. + + Parameters + ---------- + x : Array + Input array whose elements each represent a hyperbolic angle. Must have + a floating-point data type. + """ + if x.dtype not in _floating_dtypes: + raise TypeError("Only floating-point dtypes are allowed in tanh") + return Array._new(ht.tanh(x._array)) From 3ee71123cbd0996d39192362a6807d0c20f80ea5 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Wed, 6 Jul 2022 11:33:36 +0800 Subject: [PATCH 075/150] Implement `trunc` --- heat/array_api/__init__.py | 2 ++ heat/array_api/_elementwise_functions.py | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index c7e37101fe..48962bbec7 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -152,6 +152,7 @@ subtract, tan, tanh, + trunc, ) __all__ += [ @@ -210,6 +211,7 @@ "subtract", "tan", "tanh", + "trunc", ] from . import linalg diff --git a/heat/array_api/_elementwise_functions.py b/heat/array_api/_elementwise_functions.py index e556a9c790..6e7274b40b 100644 --- a/heat/array_api/_elementwise_functions.py +++ b/heat/array_api/_elementwise_functions.py @@ -1039,3 +1039,21 @@ def tanh(x: Array, /) -> Array: if x.dtype not in _floating_dtypes: raise TypeError("Only floating-point dtypes are allowed in tanh") return Array._new(ht.tanh(x._array)) + + +def trunc(x: Array, /) -> Array: + """ + Rounds each element ``x_i`` of the input array ``x`` to the integer-valued + number that is closest to but no greater than ``x_i``. + + Parameters + ---------- + x : Array + Input array. Must have a numeric data type. + """ + if x.dtype not in _numeric_dtypes: + raise TypeError("Only numeric dtypes are allowed in trunc") + if x.dtype in _integer_dtypes: + # Note: The return dtype of trunc is the same as the input + return x + return Array._new(ht.trunc(x._array)) From 4febd5896424915c786a69c28d792ad2f67df319 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Wed, 6 Jul 2022 15:35:23 +0800 Subject: [PATCH 076/150] Implement `argmax` and `argmin` --- heat/array_api/__init__.py | 4 ++ heat/array_api/_searching_functions.py | 80 ++++++++++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 heat/array_api/_searching_functions.py diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index 48962bbec7..a79acf20e8 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -235,6 +235,10 @@ __all__ += ["concat", "expand_dims", "flip", "permute_dims", "reshape", "roll", "squeeze", "stack"] +from ._searching_functions import argmax, argmin + +__all__ += ["argmax", "argmin"] + from ._statistical_functions import sum __all__ += ["sum"] diff --git a/heat/array_api/_searching_functions.py b/heat/array_api/_searching_functions.py new file mode 100644 index 0000000000..bee55613ff --- /dev/null +++ b/heat/array_api/_searching_functions.py @@ -0,0 +1,80 @@ +from __future__ import annotations + +from ._array_object import Array +from ._dtypes import _result_type, _numeric_dtypes + +from typing import Optional, Tuple + +import heat as ht + + +def argmax(x: Array, /, *, axis: Optional[int] = None, keepdims: bool = False) -> Array: + """ + Returns the indices of the maximum values along a specified axis. When the + maximum value occurs multiple times, only the indices corresponding to the + first occurrence are returned. + + Parameters + ---------- + x : Array + Input array. Must have a numeric data type. + axis : Optional[int] + Axis along which to search. If ``None``, the function returns the index of + the maximum value of the flattened array. Default: ``None``. + keepdims : bool + If ``True``, the reduced axes (dimensions) are included in the result as + singleton dimensions. Otherwise, if ``False``, the reduced axes (dimensions) + are not be included in the result. Default: ``False``. + """ + if x.dtype not in _numeric_dtypes: + raise TypeError("Only numeric dtypes are allowed in argmax") + if axis is None: + if keepdims: + output_shape = tuple(1 for _ in range(x.ndim)) + else: + output_shape = () + else: + if axis < 0: + axis += x.ndim + if keepdims: + output_shape = tuple(dim if i != axis else 1 for i, dim in enumerate(x.shape)) + else: + output_shape = tuple(dim for i, dim in enumerate(x.shape) if i != axis) + res = ht.argmax(x._array, axis=axis, keepdim=True).reshape(output_shape) + return Array._new(res) + + +def argmin(x: Array, /, *, axis: Optional[int] = None, keepdims: bool = False) -> Array: + """ + Returns the indices of the minimum values along a specified axis. When the + minimum value occurs multiple times, only the indices corresponding to the + first occurrence are returned. + + Parameters + ---------- + x : Array + Input array. Must have a numeric data type. + axis : Optional[int] + Axis along which to search. If ``None``, the function returns the index of + the minimum value of the flattened array. Default: ``None``. + keepdims : bool + If ``True``, the reduced axes (dimensions) are included in the result as + singleton dimensions. Otherwise, if ``False``, the reduced axes (dimensions) + are not be included in the result. Default: ``False``. + """ + if x.dtype not in _numeric_dtypes: + raise TypeError("Only numeric dtypes are allowed in argmin") + if axis is None: + if keepdims: + output_shape = tuple(1 for _ in range(x.ndim)) + else: + output_shape = () + else: + if axis < 0: + axis += x.ndim + if keepdims: + output_shape = tuple(dim if i != axis else 1 for i, dim in enumerate(x.shape)) + else: + output_shape = tuple(dim for i, dim in enumerate(x.shape) if i != axis) + res = ht.argmin(x._array, axis=axis, keepdim=True).reshape(output_shape) + return Array._new(res) From d6949f47f3f0ad09dbda71611281bdb8608f88a2 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Wed, 6 Jul 2022 16:19:01 +0800 Subject: [PATCH 077/150] Implement `vecdot` --- heat/array_api/__init__.py | 8 ++--- heat/array_api/_searching_functions.py | 33 +++++++++++++++++++ heat/array_api/linalg.py | 45 +++++++++++++++++++++++++- 3 files changed, 81 insertions(+), 5 deletions(-) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index a79acf20e8..8a68671716 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -218,9 +218,9 @@ __all__ += ["linalg"] -from .linalg import matmul +from .linalg import matmul, matrix_transpose, vecdot -__all__ += ["matmul"] +__all__ += ["matmul", "matrix_transpose", "vecdot"] from ._manipulation_functions import ( concat, @@ -235,9 +235,9 @@ __all__ += ["concat", "expand_dims", "flip", "permute_dims", "reshape", "roll", "squeeze", "stack"] -from ._searching_functions import argmax, argmin +from ._searching_functions import argmax, argmin, where -__all__ += ["argmax", "argmin"] +__all__ += ["argmax", "argmin", "where"] from ._statistical_functions import sum diff --git a/heat/array_api/_searching_functions.py b/heat/array_api/_searching_functions.py index bee55613ff..9c4f57aa49 100644 --- a/heat/array_api/_searching_functions.py +++ b/heat/array_api/_searching_functions.py @@ -78,3 +78,36 @@ def argmin(x: Array, /, *, axis: Optional[int] = None, keepdims: bool = False) - output_shape = tuple(dim for i, dim in enumerate(x.shape) if i != axis) res = ht.argmin(x._array, axis=axis, keepdim=True).reshape(output_shape) return Array._new(res) + + +def nonzero(x: Array, /) -> Tuple[Array, ...]: + """ + Returns the indices of the array elements which are non-zero. + + Parameters + ---------- + x : Array + Input array. Must have a positive rank. + """ + # Fixed in PR #937, waiting for merge + return ht.nonzero(x._array) + + +def where(condition: Array, x1: Array, x2: Array, /) -> Array: + """ + Returns elements chosen from ``x1`` or ``x2`` depending on ``condition``. + + Parameters + ---------- + condition : Array + When ``True``, yield ``x1_i``; otherwise, yield ``x2_i``. Must be + compatible with ``x1`` and ``x2``. + x1 : Array + First input array. Must be compatible with ``condition`` and ``x2``. + x2 : Array + Second input array. Must be compatible with ``condition`` and ``x1``. + """ + # Call result type here just to raise on disallowed type combinations + _result_type(x1.dtype, x2.dtype) + x1, x2 = Array._normalize_two_args(x1, x2) + return Array._new(ht.where(condition._array, x1._array, x2._array)) diff --git a/heat/array_api/linalg.py b/heat/array_api/linalg.py index e453c11f1c..94a8e59d07 100644 --- a/heat/array_api/linalg.py +++ b/heat/array_api/linalg.py @@ -3,7 +3,7 @@ """ from __future__ import annotations -from ._dtypes import _numeric_dtypes +from ._dtypes import _numeric_dtypes, _result_type from ._array_object import Array import heat as ht @@ -23,3 +23,46 @@ def matmul(x1: Array, x2: Array, /) -> Array: if x1.dtype not in _numeric_dtypes or x2.dtype not in _numeric_dtypes: raise TypeError("Only numeric dtypes are allowed in matmul") return Array._new(ht.matmul(x1._array, x2._array)) + + +def matrix_transpose(x: Array, /) -> Array: + """ + Transposes a matrix (or a stack of matrices) ``x``. + + Parameters + ---------- + x : Array + Input array having shape ``(..., M, N)`` and whose innermost two + dimensions form ``MxN`` matrices. + """ + if x.ndim < 2: + raise ValueError("x must be at least 2-dimensional for matrix_transpose") + return Array._new(ht.swapaxes(x._array, -1, -2)) + # axes = list(range(x.ndim)) + # axes[-1], axes[-2] = axes[-2], axes[-1] + # return Array._new(ht.transpose(x._array, axes)) + + +def vecdot(x1: Array, x2: Array, /, *, axis: int = -1) -> Array: + """ + Computes the (vector) dot product of two arrays. + + Parameters + ---------- + x1 : Array + First input array. Must have a numeric data type. + x2 : Array + Second input array. Must be compatible with ``x1`` and have a numeric data type. + axis : int + Axis over which to compute the dot product. Must be an integer on the interval + ``[-N, N)``, where ``N`` is the rank (number of dimensions) of the shape + determined according to Broadcasting. If specified as a negative integer, the + function determines the axis along which to compute the dot product by counting + backward from the last dimension (where ``-1`` refers to the last dimension). + By default, the function computes the dot product over the last axis. + Default: ``-1``. + """ + if x1.dtype not in _numeric_dtypes or x2.dtype not in _numeric_dtypes: + raise TypeError("Only numeric dtypes are allowed in vecdot") + res = ht.vecdot(x1._array, x2._array, axis=axis) + return Array._new(res.astype(_result_type(x1.dtype, x2.dtype))) From 970c1fe8b5913254d61ecd9f9f0a7ea3d8b0e23e Mon Sep 17 00:00:00 2001 From: neosunhan Date: Wed, 6 Jul 2022 16:46:33 +0800 Subject: [PATCH 078/150] Implement `unique_values` --- heat/array_api/__init__.py | 4 +++ heat/array_api/_data_type_functions.py | 4 +-- heat/array_api/_set_functions.py | 46 ++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 heat/array_api/_set_functions.py diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index 8a68671716..2b58c31800 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -239,6 +239,10 @@ __all__ += ["argmax", "argmin", "where"] +from ._set_functions import unique_inverse, unique_values + +__all__ += ["unique_inverse", "unique_values"] + from ._statistical_functions import sum __all__ += ["sum"] diff --git a/heat/array_api/_data_type_functions.py b/heat/array_api/_data_type_functions.py index 15e3212185..58bf68a4c8 100644 --- a/heat/array_api/_data_type_functions.py +++ b/heat/array_api/_data_type_functions.py @@ -85,7 +85,7 @@ def can_cast(from_: Union[Dtype, Array], to: Dtype, /) -> bool: @dataclass class finfo_object: """ - Internal object for return type of finfo. + Internal object for return type of ``finfo``. """ bits: int @@ -98,7 +98,7 @@ class finfo_object: @dataclass class iinfo_object: """ - Internal object for return type of iinfo. + Internal object for return type of ``iinfo``. """ bits: int diff --git a/heat/array_api/_set_functions.py b/heat/array_api/_set_functions.py new file mode 100644 index 0000000000..1d975a4a13 --- /dev/null +++ b/heat/array_api/_set_functions.py @@ -0,0 +1,46 @@ +from __future__ import annotations + +from ._array_object import Array + +from typing import NamedTuple +from ._typing import int64 + +import heat as ht + + +class UniqueInverseResult(NamedTuple): + """ + Internal object for return type of ``unique_inverse``. + """ + + values: Array + inverse_indices: Array + + +def unique_inverse(x: Array, /) -> UniqueInverseResult: + """ + Returns the unique elements of an input array ``x`` and the indices from the + set of unique elements that reconstruct ``x``. + + Parameters + ---------- + x : Array + Input array. If ``x`` has more than one dimension, the function flattens ``x`` + and returns the unique elements of the flattened array. + """ + values, inverse_indices = ht.unique(x._array, return_inverse=True) + inverse_indices = inverse_indices.astype(int64) + return UniqueInverseResult(Array._new(values), Array._new(inverse_indices)) + + +def unique_values(x: Array, /) -> Array: + """ + Returns the unique elements of an input array ``x``. + + Parameters + ---------- + x : Array + Input array. If ``x`` has more than one dimension, the function flattens ``x`` + and returns the unique elements of the flattened array. + """ + return Array._new(ht.unique(x._array)) From cca8c2abf67285b7d1576872b3afe500f3ea6cda Mon Sep 17 00:00:00 2001 From: neosunhan Date: Wed, 6 Jul 2022 17:21:04 +0800 Subject: [PATCH 079/150] Implement `max` and `min` --- heat/array_api/__init__.py | 8 ++- heat/array_api/_sorting_functions.py | 32 +++++++++ heat/array_api/_statistical_functions.py | 86 +++++++++++++++++++++++- 3 files changed, 123 insertions(+), 3 deletions(-) create mode 100644 heat/array_api/_sorting_functions.py diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index 2b58c31800..ffbeec8144 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -243,9 +243,13 @@ __all__ += ["unique_inverse", "unique_values"] -from ._statistical_functions import sum +from ._sorting_functions import sort -__all__ += ["sum"] +__all__ += ["sort"] + +from ._statistical_functions import max, min, sum + +__all__ += ["max", "min", "sum"] from ._utility_functions import all, any diff --git a/heat/array_api/_sorting_functions.py b/heat/array_api/_sorting_functions.py new file mode 100644 index 0000000000..62dd7c9a82 --- /dev/null +++ b/heat/array_api/_sorting_functions.py @@ -0,0 +1,32 @@ +from __future__ import annotations + +from ._array_object import Array + +import heat as ht + + +def sort(x: Array, /, *, axis: int = -1, descending: bool = False, stable: bool = True) -> Array: + """ + Returns a sorted copy of an input array x. + + Parameters + ---------- + x : Array + Input array. + axis : int + Axis along which to sort. If set to ``-1``, the function must sort along the + last axis. Default: ``-1``. + descending : bool + Sort order. If ``True``, the array must be sorted in descending order (by + value). If ``False``, the array must be sorted in ascending order (by value). + Default: ``False``. + stable : bool + Sort stability. If ``True``, the returned array maintains the relative order + of ``x`` values which compare as equal. If ``False``, the returned array may + or may not maintain the relative order of ``x`` values which compare as equal. + Default: ``True``. + """ + if stable: + raise ValueError("Stable sorting not yet implemented") + res = ht.sort(x._array, axis=axis, descending=descending) + return Array._new(res[0]) diff --git a/heat/array_api/_statistical_functions.py b/heat/array_api/_statistical_functions.py index 998fe8f4ff..a2d8733872 100644 --- a/heat/array_api/_statistical_functions.py +++ b/heat/array_api/_statistical_functions.py @@ -11,6 +11,90 @@ import heat as ht +def max( + x: Array, + /, + *, + axis: Optional[Union[int, Tuple[int, ...]]] = None, + keepdims: bool = False, +) -> Array: + """ + Calculates the maximum value of the input array ``x``. + + Parameters + ---------- + x : Array + Input array. Must have a numeric data type. + axis : Optional[Union[int, Tuple[int, ...]]] + Axis or axes along which maximum values are computed. By default, the maximum + value is computed over the entire array. If a tuple of integers, maximum + values are computed over multiple axes. Default: ``None``. + keepdims : bool + If ``True``, the reduced axes (dimensions) are included in the result as + singleton dimensions. Otherwise, if ``False``, the reduced axes + (dimensions) are be included in the result. Default: ``False``. + """ + if x.dtype not in _numeric_dtypes: + raise TypeError("Only numeric dtypes are allowed in max") + res = ht.max(x._array, axis=axis, keepdim=True) + if axis is None: + if keepdims: + output_shape = tuple(1 for _ in range(x.ndim)) + else: + output_shape = () + else: + if isinstance(axis, int): + axis = (axis,) + axis = [a if a >= 0 else a + x.ndim for a in axis] + if keepdims: + output_shape = tuple(1 if i in axis else dim for i, dim in enumerate(x.shape)) + else: + output_shape = tuple(dim for i, dim in enumerate(x.shape) if i not in axis) + return Array._new(res.reshape(output_shape)) + + +def min( + x: Array, + /, + *, + axis: Optional[Union[int, Tuple[int, ...]]] = None, + keepdims: bool = False, +) -> Array: + """ + Calculates the minimum value of the input array ``x``. + + Parameters + ---------- + x : Array + Input array. Must have a numeric data type. + axis : Optional[Union[int, Tuple[int, ...]]] + Axis or axes along which minimum values are computed. By default, the minimum + value is computed over the entire array. If a tuple of integers, minimum + values are computed over multiple axes. Default: ``None``. + keepdims : bool + If ``True``, the reduced axes (dimensions) are included in the result as + singleton dimensions. Otherwise, if ``False``, the reduced axes + (dimensions) are be included in the result. Default: ``False``. + """ + if x.dtype not in _numeric_dtypes: + raise TypeError("Only numeric dtypes are allowed in min") + res = ht.min(x._array, axis=axis, keepdim=True) + if axis is None: + if keepdims: + output_shape = tuple(1 for _ in range(x.ndim)) + else: + output_shape = () + else: + if isinstance(axis, int): + axis = (axis,) + axis = [a if a >= 0 else a + x.ndim for a in axis] + if keepdims: + output_shape = tuple(1 if i in axis else dim for i, dim in enumerate(x.shape)) + else: + output_shape = tuple(dim for i, dim in enumerate(x.shape) if i not in axis) + return Array._new(res.reshape(output_shape)) + + def sum( x: Array, /, @@ -35,7 +119,7 @@ def sum( keepdims : bool If ``True``, the reduced axes (dimensions) are included in the result as singleton dimensions. Otherwise, if ``False``, the reduced axes - (dimensions) are be included in the result. + (dimensions) are be included in the result. Default: ``False``. """ if x.dtype not in _numeric_dtypes: raise TypeError("Only numeric dtypes are allowed in sum") From 724633673dbb183657ccd67a5349057e9e7a5593 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Wed, 6 Jul 2022 17:28:25 +0800 Subject: [PATCH 080/150] Implement `mean` --- heat/array_api/__init__.py | 4 +-- heat/array_api/_statistical_functions.py | 44 ++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index ffbeec8144..c95a7ff42d 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -247,9 +247,9 @@ __all__ += ["sort"] -from ._statistical_functions import max, min, sum +from ._statistical_functions import max, mean, min, sum -__all__ += ["max", "min", "sum"] +__all__ += ["max", "mean", "min", "sum"] from ._utility_functions import all, any diff --git a/heat/array_api/_statistical_functions.py b/heat/array_api/_statistical_functions.py index a2d8733872..57ce76a6f0 100644 --- a/heat/array_api/_statistical_functions.py +++ b/heat/array_api/_statistical_functions.py @@ -53,6 +53,50 @@ def max( return Array._new(res.reshape(output_shape)) +def mean( + x: Array, + /, + *, + axis: Optional[Union[int, Tuple[int, ...]]] = None, + keepdims: bool = False, +) -> Array: + """ + Calculates the arithmetic mean of the input array ``x``. + + Parameters + ---------- + x : Array + Input array. Must have a floating-point data type. + axis : Optional[Union[int, Tuple[int, ...]]] + Axis or axes along which arithmetic means are computed. By default, the mean + is computed over the entire array. If a tuple of integers, arithmetic means + are computed over multiple axes. Default: ``None``. + keepdims : bool + If ``True``, the reduced axes (dimensions) are included in the result as + singleton dimensions. Otherwise, if ``False``, the reduced axes + (dimensions) are be included in the result. Default: ``False``. + """ + if x.dtype not in _floating_dtypes: + raise TypeError("Only floating-point dtypes are allowed in mean") + if axis == (): + return x + res = ht.mean(x._array, axis=axis) + if axis is None: + if keepdims: + output_shape = tuple(1 for _ in range(x.ndim)) + else: + output_shape = () + else: + if isinstance(axis, int): + axis = (axis,) + axis = [a if a >= 0 else a + x.ndim for a in axis] + if keepdims: + output_shape = tuple(1 if i in axis else dim for i, dim in enumerate(x.shape)) + else: + output_shape = tuple(dim for i, dim in enumerate(x.shape) if i not in axis) + return Array._new(res.astype(x.dtype).reshape(output_shape)) + + def min( x: Array, /, From 7cf980c1ccf02ea765af7c400b035e570e7a492f Mon Sep 17 00:00:00 2001 From: neosunhan Date: Wed, 6 Jul 2022 17:43:17 +0800 Subject: [PATCH 081/150] Implement `std` --- heat/array_api/__init__.py | 4 +- heat/array_api/_statistical_functions.py | 92 ++++++++++++++++++++++++ 2 files changed, 94 insertions(+), 2 deletions(-) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index c95a7ff42d..30c039e355 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -247,9 +247,9 @@ __all__ += ["sort"] -from ._statistical_functions import max, mean, min, sum +from ._statistical_functions import max, mean, min, prod, std, sum -__all__ += ["max", "mean", "min", "sum"] +__all__ += ["max", "mean", "min", "prod", "std", "sum"] from ._utility_functions import all, any diff --git a/heat/array_api/_statistical_functions.py b/heat/array_api/_statistical_functions.py index 57ce76a6f0..1e7fa9e7c0 100644 --- a/heat/array_api/_statistical_functions.py +++ b/heat/array_api/_statistical_functions.py @@ -139,6 +139,98 @@ def min( return Array._new(res.reshape(output_shape)) +def prod( + x: Array, + /, + *, + axis: Optional[Union[int, Tuple[int, ...]]] = None, + dtype: Optional[Dtype] = None, + keepdims: bool = False, +) -> Array: + """ + Calculates the product of input array ``x`` elements. + + Parameters + ---------- + x : Array + Input array. Must have a numeric data type. + axis : Optional[Union[int, Tuple[int, ...]]] + Axis or axes along which products are computed. By default, the product is + computed over the entire array. If a tuple of integers, products are computed + over multiple axes. Default: ``None``. + dtype : Optional[Dtype] + Data type of the returned array. + keepdims : bool + If ``True``, the reduced axes (dimensions) are included in the result as + singleton dimensions. Otherwise, if ``False``, the reduced axes + (dimensions) are be included in the result. Default: ``False``. + """ + if x.dtype not in _numeric_dtypes: + raise TypeError("Only numeric dtypes are allowed in prod") + # Note: sum() and prod() always upcast float32 to float64 for dtype=None + # We need to do so here before computing the product to avoid overflow + # if dtype is None and x.dtype == float32: + # dtype = float64 + res = ht.prod(x._array, axis=axis, keepdim=True) + if not keepdims or x._array.ndim == 0: + res = ht.squeeze(res, axis=axis) + if dtype is None: + if x.dtype in _floating_dtypes: + dtype = default_float + elif x.dtype in _integer_dtypes: + dtype = default_int + if dtype is not None: + res.astype(dtype, copy=False) + return Array._new(res) + + +def std( + x: Array, + /, + *, + axis: Optional[Union[int, Tuple[int, ...]]] = None, + correction: Union[int, float] = 0.0, + keepdims: bool = False, +) -> Array: + """ + Calculates the standard deviation of the input array ``x``. + + Parameters + ---------- + x : Array + Input array. Must have a floating-point data type. + axis : Optional[Union[int, Tuple[int, ...]]] + Axis or axes along which standard deviations are computed. By default, the + standard deviation is computed over the entire array. If a tuple of integers, + standard deviations are computed over multiple axes. Default: ``None``. + correction : Union[int, float] + Degrees of freedom adjustment. + keepdims : bool + If ``True``, the reduced axes (dimensions) are included in the result as + singleton dimensions. Otherwise, if ``False``, the reduced axes + (dimensions) are be included in the result. Default: ``False``. + """ + if x.dtype not in _floating_dtypes: + raise TypeError("Only floating-point dtypes are allowed in std") + res = ht.std(x._array, axis=axis, ddof=int(correction)) + if not isinstance(res, ht.DNDarray): + res = ht.array(res, dtype=x.dtype) + if axis is None: + if keepdims: + output_shape = tuple(1 for _ in range(x.ndim)) + else: + output_shape = () + else: + if isinstance(axis, int): + axis = (axis,) + axis = [a if a >= 0 else a + x.ndim for a in axis] + if keepdims: + output_shape = tuple(1 if i in axis else dim for i, dim in enumerate(x.shape)) + else: + output_shape = tuple(dim for i, dim in enumerate(x.shape) if i not in axis) + return Array._new(res.reshape(output_shape)) + + def sum( x: Array, /, From 438fe1b1c293ad5c076de2e126cdc7619ffb9b89 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Wed, 6 Jul 2022 17:50:06 +0800 Subject: [PATCH 082/150] Fix documentation --- heat/array_api/__init__.py | 4 +- heat/array_api/_statistical_functions.py | 47 ++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index 30c039e355..c8f5189553 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -247,9 +247,9 @@ __all__ += ["sort"] -from ._statistical_functions import max, mean, min, prod, std, sum +from ._statistical_functions import max, mean, min, prod, std, sum, var -__all__ += ["max", "mean", "min", "prod", "std", "sum"] +__all__ += ["max", "mean", "min", "prod", "std", "sum", "var"] from ._utility_functions import all, any diff --git a/heat/array_api/_statistical_functions.py b/heat/array_api/_statistical_functions.py index 1e7fa9e7c0..e2fd2d3040 100644 --- a/heat/array_api/_statistical_functions.py +++ b/heat/array_api/_statistical_functions.py @@ -275,3 +275,50 @@ def sum( if dtype is not None: res.astype(dtype, copy=False) return Array._new(res) + + +def var( + x: Array, + /, + *, + axis: Optional[Union[int, Tuple[int, ...]]] = None, + correction: Union[int, float] = 0.0, + keepdims: bool = False, +) -> Array: + """ + Calculates the variance of the input array ``x``. + + Parameters + ---------- + x : Array + Input array. Must have a floating-point data type. + axis : Optional[Union[int, Tuple[int, ...]]] + Axis or axes along which variances are computed. By default, the + variance is computed over the entire array. If a tuple of integers, + variances are computed over multiple axes. Default: ``None``. + correction : Union[int, float] + Degrees of freedom adjustment. + keepdims : bool + If ``True``, the reduced axes (dimensions) are included in the result as + singleton dimensions. Otherwise, if ``False``, the reduced axes + (dimensions) are be included in the result. Default: ``False``. + """ + if x.dtype not in _floating_dtypes: + raise TypeError("Only floating-point dtypes are allowed in var") + if axis == (): + return x + res = ht.var(x._array, axis=axis, ddof=int(correction)) + if axis is None: + if keepdims: + output_shape = tuple(1 for _ in range(x.ndim)) + else: + output_shape = () + else: + if isinstance(axis, int): + axis = (axis,) + axis = [a if a >= 0 else a + x.ndim for a in axis] + if keepdims: + output_shape = tuple(1 if i in axis else dim for i, dim in enumerate(x.shape)) + else: + output_shape = tuple(dim for i, dim in enumerate(x.shape) if i not in axis) + return Array._new(res.astype(x.dtype).reshape(output_shape)) From f10b2cb35f516b47d2d6502a3f3345909455d46e Mon Sep 17 00:00:00 2001 From: neosunhan Date: Sun, 4 Sep 2022 19:22:10 +0800 Subject: [PATCH 083/150] Add dlpack functions --- heat/array_api/__init__.py | 21 ++- heat/array_api/_array_object.py | 207 +++++++++++++++++++++---- heat/array_api/_creation_functions.py | 18 ++- heat/array_api/_data_type_functions.py | 28 +++- heat/array_api/_searching_functions.py | 4 +- heat/array_api/_typing.py | 7 +- heat/array_api/linalg.py | 38 ++++- 7 files changed, 279 insertions(+), 44 deletions(-) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index c8f5189553..ac1adf709a 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -17,6 +17,7 @@ empty, empty_like, eye, + from_dlpack, full, full_like, linspace, @@ -49,13 +50,23 @@ from ._data_type_functions import ( astype, + broadcast_arrays, + broadcast_to, can_cast, finfo, iinfo, result_type, ) -__all__ += ["astype", "can_cast", "finfo", "iinfo", "result_type"] +__all__ += [ + "astype", + "broadcast_arrays", + "broadcast_to", + "can_cast", + "finfo", + "iinfo", + "result_type", +] from heat.core.devices import cpu @@ -218,9 +229,9 @@ __all__ += ["linalg"] -from .linalg import matmul, matrix_transpose, vecdot +from .linalg import matmul, matrix_transpose, tensordot, vecdot -__all__ += ["matmul", "matrix_transpose", "vecdot"] +__all__ += ["matmul", "matrix_transpose", "tensordot", "vecdot"] from ._manipulation_functions import ( concat, @@ -235,9 +246,9 @@ __all__ += ["concat", "expand_dims", "flip", "permute_dims", "reshape", "roll", "squeeze", "stack"] -from ._searching_functions import argmax, argmin, where +from ._searching_functions import argmax, argmin, nonzero, where -__all__ += ["argmax", "argmin", "where"] +__all__ += ["argmax", "argmin", "nonzero", "where"] from ._set_functions import unique_inverse, unique_values diff --git a/heat/array_api/_array_object.py b/heat/array_api/_array_object.py index 3fc5873f59..86a8a9b7a8 100644 --- a/heat/array_api/_array_object.py +++ b/heat/array_api/_array_object.py @@ -1,10 +1,10 @@ from __future__ import annotations +import operator +import enum from typing import TYPE_CHECKING, Any, Optional, Tuple, Union -from ._creation_functions import asarray from ._dtypes import ( - _all_dtypes, _boolean_dtypes, _integer_dtypes, _integer_or_boolean_dtypes, @@ -15,7 +15,12 @@ ) if TYPE_CHECKING: - from ._typing import Device, Dtype + from ._typing import cpu, Device, Dtype, PyCapsule + + try: + from ._typing import gpu + except ImportError: + pass from builtins import ellipsis import heat as ht @@ -73,6 +78,12 @@ def __repr__(self: Array, /) -> str: """ return self._array.__str__().replace("DNDarray", "Array") + def __len__(self) -> int: + """ + The length of the Array. + """ + return self._array.__len__() + def _check_allowed_dtypes( self, other: Union[bool, int, float, Array], dtype_category: str, op: str ) -> Array: @@ -149,6 +160,127 @@ def _normalize_two_args(x1, x2) -> Tuple[Array, Array]: x2 = Array._new(x2._array[None]) return (x1, x2) + def _validate_index(self, key): + """ + Validate an index according to the array API. + The array API specification only requires a subset of indices that are + supported by Heat. This function will reject any index that is + allowed by Heat but not required by the array API specification. + This function raises IndexError if the index ``key`` is invalid. + """ + _key = key if isinstance(key, tuple) else (key,) + for i in _key: + if isinstance(i, bool) or not ( + isinstance(i, int) # i.e. ints + or isinstance(i, slice) + or i == Ellipsis + or i is None + or isinstance(i, Array) + or isinstance(i, ht.DNDarray) + ): + raise IndexError( + f"Single-axes index {i} has {type(i)=}, but only " + "integers, slices (:), ellipsis (...), newaxis (None), " + "zero-dimensional integer arrays and boolean arrays " + "are specified in the Array API." + ) + + nonexpanding_key = [] + single_axes = [] + n_ellipsis = 0 + key_has_mask = False + for i in _key: + if i is not None: + nonexpanding_key.append(i) + if isinstance(i, Array) or isinstance(i, ht.DNDarray): + if i.dtype in _boolean_dtypes: + key_has_mask = True + single_axes.append(i) + else: + # i must not be an array here, to avoid elementwise equals + if i == Ellipsis: + n_ellipsis += 1 + else: + single_axes.append(i) + + n_single_axes = len(single_axes) + if n_ellipsis > 1: + return # handled by DNDarray + elif n_ellipsis == 0: + # Note boolean masks must be the sole index, which we check for + # later on. + if not key_has_mask and n_single_axes < self.ndim: + raise IndexError( + f"{self.ndim=}, but the multi-axes index only specifies " + f"{n_single_axes} dimensions. If this was intentional, " + "add a trailing ellipsis (...) which expands into as many " + "slices (:) as necessary." + ) + + if n_ellipsis == 0: + indexed_shape = self.shape + else: + ellipsis_start = None + for pos, i in enumerate(nonexpanding_key): + if not (isinstance(i, Array) or isinstance(i, ht.DNDarray)): + if i == Ellipsis: + ellipsis_start = pos + break + assert ellipsis_start is not None # sanity check + ellipsis_end = self.ndim - (n_single_axes - ellipsis_start) + indexed_shape = self.shape[:ellipsis_start] + self.shape[ellipsis_end:] + for i, side in zip(single_axes, indexed_shape): + if isinstance(i, slice): + if side == 0: + f_range = "0 (or None)" + else: + f_range = f"between -{side} and {side - 1} (or None)" + if i.start is not None: + try: + start = operator.index(i.start) + except TypeError: + raise IndexError("Invalid start value in slice") + else: + if not (-side <= start <= side): + raise IndexError( + f"Slice {i} contains {start=}, but should be " + f"{f_range} for an axis of size {side} " + "(out-of-bounds starts are not specified in " + "the Array API)" + ) + if i.stop is not None: + try: + stop = operator.index(i.stop) + except TypeError: + raise IndexError("Invalid stop value in slice") + else: + if not (-side <= stop <= side): + raise IndexError( + f"Slice {i} contains {stop=}, but should be " + f"{f_range} for an axis of size {side} " + "(out-of-bounds stops are not specified in " + "the Array API)" + ) + elif isinstance(i, Array): + if i.dtype in _boolean_dtypes and len(_key) != 1: + assert isinstance(key, tuple) # sanity check + raise IndexError( + f"Single-axes index {i} is a boolean array and " + f"{len(key)=}, but masking is only specified in the " + "Array API when the array is the sole index." + ) + elif i.dtype in _integer_dtypes and i.ndim != 0: + raise IndexError( + f"Single-axes index {i} is a non-zero-dimensional " + "integer array, but advanced integer indexing is not " + "specified in the Array API." + ) + elif isinstance(i, tuple): + raise IndexError( + f"Single-axes index {i} is a tuple, but nested tuple " + "indices are not specified in the Array API." + ) + def __abs__(self: Array, /) -> Array: """ Calculates the absolute value for each element of an array instance @@ -221,6 +353,26 @@ def __bool__(self: Array, /) -> bool: res = self._array.__bool__() return res + def __dlpack__(self: Array, /, *, stream: Optional[Union[int, Any]] = None) -> PyCapsule: + """ + Exports the array for consumption by ``from_dlpack()`` as a DLPack capsule. + + Parameters + ---------- + stream : Optional[Union[int, Any]] + For CUDA and ROCm, a Python integer representing a pointer to a stream, + on devices that support streams. + """ + return self._array.__array.__dlpack__(stream=stream) + + def __dlpack_device__(self: Array, /) -> Tuple[enum.Enum, int]: + """ + Returns device type and device ID in DLPack format. Meant for use + within ``from_dlpack()``. + """ + # Note: device support is required for this + return self._array.__array.__dlpack_device__() + def __eq__(self: Array, other: Union[int, float, bool, Array], /) -> Array: """ Computes the truth value of ``self_i == other_i`` for each element of an @@ -300,17 +452,10 @@ def __getitem__( """ # Note: Only indices required by the spec are allowed. See the # docstring of _validate_index - # self._validate_index(key) + self._validate_index(key) if isinstance(key, Array): # Indexing self._array with array_api arrays can be erroneous key = key._array - # if 0 in self.shape: - # new_array = self._array - # if isinstance(key, tuple): - # for i, index in enumerate((x for x in key if x != ...)): - # if index is None: - # new_array = new_array.expand_dims(i) - # return self._new(new_array) res = self._array.__getitem__(key) return self._new(res) @@ -557,16 +702,13 @@ def __setitem__( """ # Note: Only indices required by the spec are allowed. See the # docstring of _validate_index - # self._validate_index(key) + self._validate_index(key) if isinstance(key, Array): # Indexing self._array with array_api arrays can be erroneous key = key._array if isinstance(value, Array): value = value._array - if self.ndim == 0 and isinstance(key, type(...)): - self._array = ht.asarray(value) - else: - self._array.__setitem__(key, value) + self._array.__setitem__(key, value) def __sub__(self: Array, other: Union[int, float, Array], /) -> Array: """ @@ -726,15 +868,26 @@ def __rtruediv__(self: Array, other: Union[float, Array], /) -> Array: res = self._array.__rtruediv__(other._array) return self.__class__._new(res) - # def to_device(self: Array, device: Device, /, stream: Optional[Union[int, Any]] = None) -> Array: - # """ - # Copy the array from the device on which it currently resides to the specified ``device``. - # """ - # if stream is not None: - # raise ValueError("The stream argument to to_device() is not supported") - # if device == 'cpu': - # return self - # raise ValueError(f"Unsupported device {device!r}") + def to_device( + self: Array, device: Device, /, stream: Optional[Union[int, Any]] = None + ) -> Array: + """ + Copy the array from the device on which it currently resides to the specified ``device``. + + Parameters + ---------- + device : Device + A ``Device`` object. + stream : Optional[Union[int, Any]] + Stream object to use during copy. + """ + if stream is not None: + raise ValueError("The stream argument to to_device() is not supported") + if device == cpu: + return self._array.cpu() + elif device == gpu: + return self._array.gpu() + raise ValueError(f"Unsupported device {device!r}") @property def dtype(self) -> Dtype: @@ -755,9 +908,11 @@ def mT(self) -> Array: """ Transpose of a matrix (or a stack of matrices). """ + from .linalg import matrix_transpose + if self.ndim < 2: raise ValueError("x.mT requires x to have at least 2 dimensions.") - return self._array.transpose(axes=list(range(self.ndim))[:-2] + [-1, -2]) + return matrix_transpose(self) @property def ndim(self) -> int: diff --git a/heat/array_api/_creation_functions.py b/heat/array_api/_creation_functions.py index 6d1e7639ba..dd082ecc93 100644 --- a/heat/array_api/_creation_functions.py +++ b/heat/array_api/_creation_functions.py @@ -7,6 +7,7 @@ from ._dtypes import _all_dtypes, _floating_dtypes, default_float, default_int, bool as api_bool import heat as ht +import torch def arange( @@ -105,7 +106,7 @@ def asarray( raise OverflowError("Integer out of bounds for array dtypes") elif isinstance(obj, float): dtype = default_float - res = ht.asarray(obj, dtype=dtype, copy=copy, device=device) + res = ht.asarray(obj, dtype=dtype, device=device) return Array._new(res) @@ -194,6 +195,21 @@ def eye( return Array._new(ht.eye((n_rows, n_cols), dtype=dtype, device=device)) +def from_dlpack(x: object, /) -> Array: + """ + Returns a new array containing the data from another (array) object with a + ``__dlpack__`` method. + + Parameters + ---------- + x : object + Input (array) object. + """ + from ._array_object import Array + + return Array._new(torch.from_dlpack(x)) + + def full( shape: Union[int, Tuple[int, ...]], fill_value: Union[int, float], diff --git a/heat/array_api/_data_type_functions.py b/heat/array_api/_data_type_functions.py index 58bf68a4c8..7c4d016695 100644 --- a/heat/array_api/_data_type_functions.py +++ b/heat/array_api/_data_type_functions.py @@ -4,7 +4,7 @@ from ._dtypes import _all_dtypes, _result_type from dataclasses import dataclass -from typing import TYPE_CHECKING, Union, List +from typing import TYPE_CHECKING, Union, List, Tuple if TYPE_CHECKING: from ._typing import Dtype @@ -45,14 +45,30 @@ def broadcast_arrays(*arrays: Array) -> List[Array]: """ from ._array_object import Array - if len(arrays) <= 1: - return arrays - output_shape = arrays[0].shape - for a in arrays[1:]: - output_shape = broadcast_shape(output_shape, a.shape) + # if len(arrays) <= 1: + # return arrays + # output_shape = arrays[0].shape + # for a in arrays[1:]: + # output_shape = broadcast_shape(output_shape, a.shape) return [Array._new(array) for array in ht.broadcast_arrays(*[a._array for a in arrays])] +def broadcast_to(x: Array, /, shape: Tuple[int, ...]) -> Array: + """ + Broadcasts an array to a specified shape. + + Parameters + ---------- + x : Array + Array to broadcast. + shape : Tuple[int, ...] + Array shape. Must be compatible with x. + """ + from ._array_object import Array + + return Array._new(ht.broadcast_to(x._array, shape)) + + def can_cast(from_: Union[Dtype, Array], to: Dtype, /) -> bool: """ Determines if one data type can be cast to another data type according to diff --git a/heat/array_api/_searching_functions.py b/heat/array_api/_searching_functions.py index 9c4f57aa49..b11980c39c 100644 --- a/heat/array_api/_searching_functions.py +++ b/heat/array_api/_searching_functions.py @@ -89,8 +89,8 @@ def nonzero(x: Array, /) -> Tuple[Array, ...]: x : Array Input array. Must have a positive rank. """ - # Fixed in PR #937, waiting for merge - return ht.nonzero(x._array) + # Fixed in PR #914, waiting for merge + return tuple(Array._new(i) for i in ht.nonzero(x._array)) def where(condition: Array, x1: Array, x2: Array, /) -> Array: diff --git a/heat/array_api/_typing.py b/heat/array_api/_typing.py index 115e3f6c84..efbb37fc64 100644 --- a/heat/array_api/_typing.py +++ b/heat/array_api/_typing.py @@ -13,7 +13,12 @@ bool, ) -from heat.core.devices import Device +from heat.core.devices import Device, cpu + +try: + from heat.core.devices import gpu +except ImportError: + pass Dtype = Union[ int8, diff --git a/heat/array_api/linalg.py b/heat/array_api/linalg.py index 94a8e59d07..50049ad091 100644 --- a/heat/array_api/linalg.py +++ b/heat/array_api/linalg.py @@ -6,6 +6,11 @@ from ._dtypes import _numeric_dtypes, _result_type from ._array_object import Array +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from ._typing import Sequence, Tuple, Union + import heat as ht @@ -38,9 +43,36 @@ def matrix_transpose(x: Array, /) -> Array: if x.ndim < 2: raise ValueError("x must be at least 2-dimensional for matrix_transpose") return Array._new(ht.swapaxes(x._array, -1, -2)) - # axes = list(range(x.ndim)) - # axes[-1], axes[-2] = axes[-2], axes[-1] - # return Array._new(ht.transpose(x._array, axes)) + + +def tensordot( + x1: Array, x2: Array, /, *, axes: Union[int, Tuple[Sequence[int], Sequence[int]]] = 2 +) -> Array: + """ + Return a tensor contraction of ``x1`` and ``x2`` over specific axes. + + Parameters + ---------- + x1 : Array + First input array. Must have a numeric data type. + x2 : Array + Second input array. Must have a numeric data type. Corresponding contracted axes of ``x1`` + and ``x2`` must be equal. + axes : Union[int, Tuple[Sequence[int], Sequence[int]]] + Number of axes (dimensions) to contract or explicit sequences of axes (dimensions) for + ``x1`` and ``x2``, respectively. If ``axes`` is an ``int`` equal to ``N``, then contraction is + performed over the last ``N`` axes of ``x1`` and the first ``N`` axes of ``x2`` in order. + The size of each corresponding axis (dimension) must match. Must be nonnegative. + If ``axes`` is a tuple of two sequences ``(x1_axes, x2_axes)``, the first sequence must apply + to ``x1`` and the second sequence to ``x2``. Both sequences must have the same length. + Each axis (dimension) ``x1_axes[i]`` for ``x1`` must have the same size as the respective axis + (dimension) ``x2_axes[i]`` for ``x2``. Each sequence must consist of unique (nonnegative) + integers that specify valid axes for each respective array. + """ + if x1.dtype not in _numeric_dtypes or x2.dtype not in _numeric_dtypes: + raise TypeError("Only numeric dtypes are allowed in tensordot") + + return Array._new(ht.tensordot(x1._array, x2._array, axes=axes)) def vecdot(x1: Array, x2: Array, /, *, axis: int = -1) -> Array: From 6473b707548326dc7f1cb422d1eace8750fd12e3 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Sun, 4 Sep 2022 19:50:10 +0800 Subject: [PATCH 084/150] Extract changes made in core module Shift changes made in core module to separate branches for individual PRs. --- heat/core/factories.py | 37 ++++++++----------------------- heat/core/linalg/basics.py | 10 ++++----- heat/core/logical.py | 6 ----- heat/core/rounding.py | 8 ++----- heat/core/tests/test_factories.py | 5 ----- heat/core/tests/test_logical.py | 8 ------- heat/core/tests/test_rounding.py | 4 ---- heat/core/tests/test_types.py | 2 -- 8 files changed, 15 insertions(+), 65 deletions(-) diff --git a/heat/core/factories.py b/heat/core/factories.py index 297d43c6e0..695545c879 100644 --- a/heat/core/factories.py +++ b/heat/core/factories.py @@ -139,12 +139,10 @@ def arange( # compose the local tensor start += offset * step stop = start + lshape[0] * step + data = torch.arange(start, stop, step, device=device.torch_device) + htype = types.canonical_heat_type(dtype) - if types.issubdtype(htype, types.floating): - data = torch.arange(start, stop, step, dtype=htype.torch_type(), device=device.torch_device) - else: - data = torch.arange(start, stop, step, device=device.torch_device) - data = data.type(htype.torch_type()) + data = data.type(htype.torch_type()) return DNDarray(data, gshape, htype, split, device, comm, balanced) @@ -301,11 +299,8 @@ def array( obj = obj.larray # sanitize the data type - if dtype is None: - torch_dtype = None - else: + if dtype is not None: dtype = types.canonical_heat_type(dtype) - torch_dtype = dtype.torch_type() # sanitize device if device is not None: @@ -321,7 +316,6 @@ def array( try: obj = torch.tensor( obj, - dtype=torch_dtype, device=device.torch_device if device is not None else devices.get_device().torch_device, @@ -332,7 +326,6 @@ def array( if not isinstance(obj, DNDarray): obj = torch.as_tensor( obj, - dtype=torch_dtype, device=device.torch_device if device is not None else devices.get_device().torch_device, @@ -342,6 +335,7 @@ def array( if dtype is None: dtype = types.canonical_heat_type(obj.dtype) else: + torch_dtype = dtype.torch_type() if obj.dtype != torch_dtype: obj = obj.type(torch_dtype) @@ -440,7 +434,6 @@ def array( def asarray( obj: Iterable, dtype: Optional[Type[datatype]] = None, - copy: bool = False, order: str = "C", is_split: Optional[bool] = None, device: Optional[Union[str, Device]] = None, @@ -456,9 +449,6 @@ def asarray( tuples of tuples, tuples of lists and ndarrays. dtype : dtype, optional By default, the data-type is inferred from the input data. - copy : bool, optional - If ``True``, then the object is copied. Otherwise, a copy will only be made if `obj` is a nested - sequence or if a copy is needed to satisfy any of the other requirements, e.g. ``dtype``. order: str, optional Whether to use row-major (C-style) or column-major (Fortran-style) memory representation. Defaults to ā€˜Cā€™. is_split : None or int, optional @@ -492,7 +482,7 @@ def asarray( >>> ht.asarray(a, dtype=ht.float64) is a False """ - return array(obj, dtype=dtype, copy=copy, order=order, is_split=is_split, device=device) + return array(obj, dtype=dtype, copy=False, order=order, is_split=is_split, device=device) def empty( @@ -975,18 +965,9 @@ def linspace( # compose the local tensor start += offset * step stop = start + lshape[0] * step - step - if dtype is not None and types.issubdtype(dtype, types.floating): - data = torch.linspace( - start, - stop, - lshape[0], - dtype=types.canonical_heat_type(dtype).torch_type(), - device=device.torch_device, - ) - else: - data = torch.linspace(start, stop, lshape[0], device=device.torch_device) - if dtype is not None: - data = data.type(types.canonical_heat_type(dtype).torch_type()) + data = torch.linspace(start, stop, lshape[0], device=device.torch_device) + if dtype is not None: + data = data.type(types.canonical_heat_type(dtype).torch_type()) # construct the resulting global tensor ht_tensor = DNDarray( diff --git a/heat/core/linalg/basics.py b/heat/core/linalg/basics.py index d7f9c1e10a..bc5d3e9e65 100644 --- a/heat/core/linalg/basics.py +++ b/heat/core/linalg/basics.py @@ -1174,13 +1174,11 @@ def matrix_norm( row_axis, col_axis = axis - dtype = types.promote_types(x.dtype, types.float32) - if ord == 1: if col_axis > row_axis and not keepdims: col_axis -= 1 return statistics.max( - arithmetics.sum(rounding.abs(x, dtype=dtype), axis=row_axis, keepdim=keepdims), + arithmetics.sum(rounding.abs(x), axis=row_axis, keepdim=keepdims), axis=col_axis, keepdim=keepdims, ) @@ -1188,7 +1186,7 @@ def matrix_norm( if col_axis > row_axis and not keepdims: col_axis -= 1 return statistics.min( - arithmetics.sum(rounding.abs(x, dtype=dtype), axis=row_axis, keepdim=keepdims), + arithmetics.sum(rounding.abs(x), axis=row_axis, keepdim=keepdims), axis=col_axis, keepdim=keepdims, ) @@ -1200,7 +1198,7 @@ def matrix_norm( if row_axis > col_axis and not keepdims: row_axis -= 1 return statistics.max( - arithmetics.sum(rounding.abs(x, dtype=dtype), axis=col_axis, keepdim=keepdims), + arithmetics.sum(rounding.abs(x), axis=col_axis, keepdim=keepdims), axis=row_axis, keepdim=keepdims, ) @@ -1208,7 +1206,7 @@ def matrix_norm( if row_axis > col_axis and not keepdims: row_axis -= 1 return statistics.min( - arithmetics.sum(rounding.abs(x, dtype=dtype), axis=col_axis, keepdim=keepdims), + arithmetics.sum(rounding.abs(x), axis=col_axis, keepdim=keepdims), axis=row_axis, keepdim=keepdims, ) diff --git a/heat/core/logical.py b/heat/core/logical.py index a6be081ea7..9b4dcc8f79 100644 --- a/heat/core/logical.py +++ b/heat/core/logical.py @@ -91,9 +91,6 @@ def all( def local_all(t, *args, **kwargs): return torch.all(t != 0, *args, **kwargs) - if keepdim and axis is None: - axis = tuple(range(x.ndim)) - return _operations.__reduce_op( x, local_all, MPI.LAND, axis=axis, out=out, neutral=1, keepdim=keepdim ) @@ -199,9 +196,6 @@ def any( def local_any(t, *args, **kwargs): return torch.any(t != 0, *args, **kwargs) - if keepdim and axis is None: - axis = tuple(range(x.ndim)) - return _operations.__reduce_op( x, local_any, MPI.LOR, axis=axis, out=out, neutral=0, keepdim=keepdim ) diff --git a/heat/core/rounding.py b/heat/core/rounding.py index 31dafefa17..3028ecdec7 100644 --- a/heat/core/rounding.py +++ b/heat/core/rounding.py @@ -52,7 +52,7 @@ def abs( if dtype is not None and not issubclass(dtype, dtype): raise TypeError("dtype must be a heat data type") - absolute_values = _operations.__local_op(torch.abs, x, out, no_cast=True) + absolute_values = _operations.__local_op(torch.abs, x) if dtype is not None: absolute_values.larray = absolute_values.larray.type(dtype.torch_type()) absolute_values._DNDarray__dtype = dtype @@ -181,11 +181,7 @@ def fabs(x: DNDarray, out: Optional[DNDarray] = None) -> DNDarray: If not provided or ``None``, a freshly-allocated array is returned. """ - if isinstance(x, DNDarray): - dtype = types.promote_types(x.dtype, types.float32) - else: - dtype = None - return abs(x, out, dtype=dtype) + return abs(x, out, dtype=None) DNDarray.fabs: Callable[[DNDarray, Optional[DNDarray]], DNDarray] = lambda self, out=None: fabs( diff --git a/heat/core/tests/test_factories.py b/heat/core/tests/test_factories.py index 091e484e28..dd973f988e 100644 --- a/heat/core/tests/test_factories.py +++ b/heat/core/tests/test_factories.py @@ -106,9 +106,6 @@ def test_arange(self): # make an in direct check for the sequence, compare against the gaussian sum self.assertEqual(three_arg_arange_dtype_float64.sum(axis=0, keepdim=True), 20.0) - check_precision = ht.arange(16777217.0, 16777218, 1, dtype=torch.float64) - self.assertEqual(check_precision[0], ht.array([16777217.0], dtype=torch.float64)) - # exceptions with self.assertRaises(ValueError): ht.arange(-5, 3, split=1) @@ -315,7 +312,6 @@ def test_asarray(self): # same heat array arr = ht.array([1, 2]) self.assertTrue(ht.asarray(arr) is arr) - self.assertFalse(ht.asarray(arr, copy=True) is arr) # from distributed python list arr = ht.array([1, 2, 3, 4, 5, 6], split=0) @@ -332,7 +328,6 @@ def test_asarray(self): asarr = ht.asarray(arr) self.assertTrue(np.alltrue(np.equal(asarr.numpy(), arr))) - self.assertFalse(ht.asarray(arr, copy=True).larray is arr) asarr[0] = 0 if asarr.device == ht.cpu: diff --git a/heat/core/tests/test_logical.py b/heat/core/tests/test_logical.py index 852de71d19..a995d53db3 100644 --- a/heat/core/tests/test_logical.py +++ b/heat/core/tests/test_logical.py @@ -140,10 +140,6 @@ def test_all(self): out_noaxis = ht.zeros((1, 2, 3, 5), split=1) ht.all(ones_noaxis_split_axis_neg, axis=-2, out=out_noaxis) - # test keepdim - ones_2d = ht.ones((1, 1)) - self.assertEqual(ones_2d.all(keepdim=True).shape, ones_2d.shape) - # exceptions with self.assertRaises(ValueError): ht.ones(array_len).all(axis=1) @@ -216,10 +212,6 @@ def test_any(self): self.assertEqual(any_tensor.dtype, ht.bool) self.assertTrue(ht.equal(any_tensor, res)) - # test keepdim - ones_2d = ht.ones((1, 1)) - self.assertEqual(ones_2d.any(keepdim=True).shape, ones_2d.shape) - def test_isclose(self): size = ht.communication.MPI_WORLD.size a = ht.float32([[2, 2], [2, 2]]) diff --git a/heat/core/tests/test_rounding.py b/heat/core/tests/test_rounding.py index 176280f1b7..379c0e0ca4 100644 --- a/heat/core/tests/test_rounding.py +++ b/heat/core/tests/test_rounding.py @@ -57,10 +57,6 @@ def test_abs(self): self.assertEqual(absolute_values.sum(axis=0), 100) self.assertEqual(absolute_values.dtype, ht.float32) self.assertEqual(absolute_values.larray.dtype, torch.float32) - check_precision = ht.asarray(9007199254740993, dtype=ht.int64) - precision_absolute_values = ht.abs(check_precision, dtype=ht.int64) - self.assertEqual(precision_absolute_values.sum(), check_precision.sum()) - self.assertEqual(precision_absolute_values.dtype, check_precision.dtype) # for fabs self.assertEqual(int8_absolute_values_fabs.dtype, ht.float32) self.assertEqual(int16_absolute_values_fabs.dtype, ht.float32) diff --git a/heat/core/tests/test_types.py b/heat/core/tests/test_types.py index 3d901ba1ad..6aa765a070 100644 --- a/heat/core/tests/test_types.py +++ b/heat/core/tests/test_types.py @@ -377,8 +377,6 @@ def test_iinfo(self): self.assertEqual(info32.min, -2147483648) self.assertEqual(ht.iinfo(ht.uint8).min, 0) - self.assertEqual(ht.iinfo(ht.uint8).min, 0) - with self.assertRaises(TypeError): ht.iinfo(1.0) From d5fbfda37840c33fa0472dcdc2881714bf3d9a12 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Sun, 4 Sep 2022 19:53:03 +0800 Subject: [PATCH 085/150] Restore original `abs` --- heat/core/rounding.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/heat/core/rounding.py b/heat/core/rounding.py index 3028ecdec7..b6c68343c4 100644 --- a/heat/core/rounding.py +++ b/heat/core/rounding.py @@ -52,7 +52,7 @@ def abs( if dtype is not None and not issubclass(dtype, dtype): raise TypeError("dtype must be a heat data type") - absolute_values = _operations.__local_op(torch.abs, x) + absolute_values = _operations.__local_op(torch.abs, x, out) if dtype is not None: absolute_values.larray = absolute_values.larray.type(dtype.torch_type()) absolute_values._DNDarray__dtype = dtype From f81048a94582e184ef4d9f6399afe2e7aa9e3cef Mon Sep 17 00:00:00 2001 From: neosunhan Date: Sun, 4 Sep 2022 20:38:21 +0800 Subject: [PATCH 086/150] Fix documentation --- heat/array_api/_array_object.py | 16 +--- heat/array_api/_creation_functions.py | 1 - heat/array_api/_data_type_functions.py | 5 -- heat/array_api/_dtypes.py | 4 +- heat/array_api/_elementwise_functions.py | 5 -- heat/array_api/_manipulation_functions.py | 2 +- heat/array_api/_searching_functions.py | 30 +------ heat/array_api/_statistical_functions.py | 98 +++-------------------- heat/array_api/_utility_functions.py | 8 +- heat/array_api/linalg.py | 1 - 10 files changed, 19 insertions(+), 151 deletions(-) diff --git a/heat/array_api/_array_object.py b/heat/array_api/_array_object.py index 86a8a9b7a8..1198d239b9 100644 --- a/heat/array_api/_array_object.py +++ b/heat/array_api/_array_object.py @@ -129,9 +129,6 @@ def _promote_scalar(self, scalar): else: raise TypeError(f"{scalar} must be a Python scalar") - # Note: scalars are unconditionally cast to the same dtype as the - # array. - return Array._new(ht.array(scalar, self.dtype)) @staticmethod @@ -151,10 +148,6 @@ def _normalize_two_args(x1, x2) -> Tuple[Array, Array]: from not promoting the dtype. """ if x1.ndim == 0 and x2.ndim != 0: - # The _array[None] workaround was chosen because it is relatively - # performant. broadcast_to(x1._array, x2.shape) is much slower. We - # could also manually type promote x2, but that is more complicated - # and about the same performance as this. x1 = Array._new(x1._array[None]) elif x2.ndim == 0 and x1.ndim != 0: x2 = Array._new(x2._array[None]) @@ -370,7 +363,6 @@ def __dlpack_device__(self: Array, /) -> Tuple[enum.Enum, int]: Returns device type and device ID in DLPack format. Meant for use within ``from_dlpack()``. """ - # Note: device support is required for this return self._array.__array.__dlpack_device__() def __eq__(self: Array, other: Union[int, float, bool, Array], /) -> Array: @@ -450,11 +442,9 @@ def __getitem__( key : Union[int, slice, ellipsis, Tuple[Union[int, slice, ellipsis], ...], Array] Index key """ - # Note: Only indices required by the spec are allowed. See the - # docstring of _validate_index + # Note: Only indices required by the spec are allowed. self._validate_index(key) if isinstance(key, Array): - # Indexing self._array with array_api arrays can be erroneous key = key._array res = self._array.__getitem__(key) return self._new(res) @@ -700,11 +690,9 @@ def __setitem__( """ Sets ``self[key]`` to ``value``. """ - # Note: Only indices required by the spec are allowed. See the - # docstring of _validate_index + # Note: Only indices required by the spec are allowed. self._validate_index(key) if isinstance(key, Array): - # Indexing self._array with array_api arrays can be erroneous key = key._array if isinstance(value, Array): value = value._array diff --git a/heat/array_api/_creation_functions.py b/heat/array_api/_creation_functions.py index dd082ecc93..7849741c6d 100644 --- a/heat/array_api/_creation_functions.py +++ b/heat/array_api/_creation_functions.py @@ -102,7 +102,6 @@ def asarray( obj = obj._array if dtype is None: if isinstance(obj, int) and (obj > 2**64 or obj < -(2**63)): - # TODO: This won't handle large integers in lists. raise OverflowError("Integer out of bounds for array dtypes") elif isinstance(obj, float): dtype = default_float diff --git a/heat/array_api/_data_type_functions.py b/heat/array_api/_data_type_functions.py index 7c4d016695..e5f5695e59 100644 --- a/heat/array_api/_data_type_functions.py +++ b/heat/array_api/_data_type_functions.py @@ -45,11 +45,6 @@ def broadcast_arrays(*arrays: Array) -> List[Array]: """ from ._array_object import Array - # if len(arrays) <= 1: - # return arrays - # output_shape = arrays[0].shape - # for a in arrays[1:]: - # output_shape = broadcast_shape(output_shape, a.shape) return [Array._new(array) for array in ht.broadcast_arrays(*[a._array for a in arrays])] diff --git a/heat/array_api/_dtypes.py b/heat/array_api/_dtypes.py index ec76aba79b..0747809cc2 100644 --- a/heat/array_api/_dtypes.py +++ b/heat/array_api/_dtypes.py @@ -10,8 +10,8 @@ """A 64-bit signed integer whose values exist on the interval ``[-9,223,372,036,854,775,807, +9,223,372,036,854,775,807]``.""" uint8 = ht.uint8 """An 8-bit unsigned integer whose values exist on the interval ``[0, +255]``.""" -# Waiting on Pytorch to introduce support for these 3 data types -# See https://github.com/pytorch/pytorch/issues/58734 +# For the status of Pytorch support for these 3 data types, +# see https://github.com/pytorch/pytorch/issues/58734 # uint16 = # """A 16-bit unsigned integer whose values exist on the interval ``[0, +65,535]``.""" # uint32 = diff --git a/heat/array_api/_elementwise_functions.py b/heat/array_api/_elementwise_functions.py index 6e7274b40b..da6f9e3af9 100644 --- a/heat/array_api/_elementwise_functions.py +++ b/heat/array_api/_elementwise_functions.py @@ -224,7 +224,6 @@ def bitwise_left_shift(x1: Array, x2: Array, /) -> Array: # Call result type here just to raise on disallowed type combinations _result_type(x1.dtype, x2.dtype) x1, x2 = Array._normalize_two_args(x1, x2) - # Note: bitwise_left_shift is only defined for x2 nonnegative. if ht.any(x2._array < 0): raise ValueError("bitwise_left_shift(x1, x2) is only defined for x2 >= 0") return Array._new(ht.left_shift(x1._array, x2._array)) @@ -260,7 +259,6 @@ def bitwise_or(x1: Array, x2: Array, /) -> Array: """ if x1.dtype not in _integer_or_boolean_dtypes or x2.dtype not in _integer_or_boolean_dtypes: raise TypeError("Only integer or boolean dtypes are allowed in bitwise_or") - # Call result type here just to raise on disallowed type combinations _result_type(x1.dtype, x2.dtype) x1, x2 = Array._normalize_two_args(x1, x2) return Array._new(ht.bitwise_or(x1._array, x2._array)) @@ -325,7 +323,6 @@ def ceil(x: Array, /) -> Array: if x.dtype not in _numeric_dtypes: raise TypeError("Only numeric dtypes are allowed in ceil") if x.dtype in _integer_dtypes: - # Note: The return dtype of ceil is the same as the input return x return Array._new(ht.ceil(x._array)) @@ -451,7 +448,6 @@ def floor(x: Array, /) -> Array: if x.dtype not in _numeric_dtypes: raise TypeError("Only numeric dtypes are allowed in floor") if x.dtype in _integer_dtypes: - # Note: The return dtype of floor is the same as the input return x return Array._new(ht.floor(x._array)) @@ -1054,6 +1050,5 @@ def trunc(x: Array, /) -> Array: if x.dtype not in _numeric_dtypes: raise TypeError("Only numeric dtypes are allowed in trunc") if x.dtype in _integer_dtypes: - # Note: The return dtype of trunc is the same as the input return x return Array._new(ht.trunc(x._array)) diff --git a/heat/array_api/_manipulation_functions.py b/heat/array_api/_manipulation_functions.py index 86295bf3d5..aaa7b89e9e 100644 --- a/heat/array_api/_manipulation_functions.py +++ b/heat/array_api/_manipulation_functions.py @@ -21,7 +21,7 @@ def concat(arrays: Union[Tuple[Array, ...], List[Array]], /, *, axis: Optional[i Axis along which the arrays will be joined. If ``axis`` is ``None``, arrays are flattened before concatenation. Default: ``0``. """ - # dtype = result_type(*arrays) + result_type(*arrays) arrays = tuple(a._array for a in arrays) if axis is None: arrays = tuple(ht.flatten(a) for a in arrays) diff --git a/heat/array_api/_searching_functions.py b/heat/array_api/_searching_functions.py index b11980c39c..d9631745e5 100644 --- a/heat/array_api/_searching_functions.py +++ b/heat/array_api/_searching_functions.py @@ -28,19 +28,7 @@ def argmax(x: Array, /, *, axis: Optional[int] = None, keepdims: bool = False) - """ if x.dtype not in _numeric_dtypes: raise TypeError("Only numeric dtypes are allowed in argmax") - if axis is None: - if keepdims: - output_shape = tuple(1 for _ in range(x.ndim)) - else: - output_shape = () - else: - if axis < 0: - axis += x.ndim - if keepdims: - output_shape = tuple(dim if i != axis else 1 for i, dim in enumerate(x.shape)) - else: - output_shape = tuple(dim for i, dim in enumerate(x.shape) if i != axis) - res = ht.argmax(x._array, axis=axis, keepdim=True).reshape(output_shape) + res = ht.argmax(x._array, axis=axis, keepdim=keepdims) return Array._new(res) @@ -64,19 +52,7 @@ def argmin(x: Array, /, *, axis: Optional[int] = None, keepdims: bool = False) - """ if x.dtype not in _numeric_dtypes: raise TypeError("Only numeric dtypes are allowed in argmin") - if axis is None: - if keepdims: - output_shape = tuple(1 for _ in range(x.ndim)) - else: - output_shape = () - else: - if axis < 0: - axis += x.ndim - if keepdims: - output_shape = tuple(dim if i != axis else 1 for i, dim in enumerate(x.shape)) - else: - output_shape = tuple(dim for i, dim in enumerate(x.shape) if i != axis) - res = ht.argmin(x._array, axis=axis, keepdim=True).reshape(output_shape) + res = ht.argmin(x._array, axis=axis, keepdim=keepdims) return Array._new(res) @@ -89,7 +65,7 @@ def nonzero(x: Array, /) -> Tuple[Array, ...]: x : Array Input array. Must have a positive rank. """ - # Fixed in PR #914, waiting for merge + # See PR #914 for overhaul return tuple(Array._new(i) for i in ht.nonzero(x._array)) diff --git a/heat/array_api/_statistical_functions.py b/heat/array_api/_statistical_functions.py index e2fd2d3040..11df80890f 100644 --- a/heat/array_api/_statistical_functions.py +++ b/heat/array_api/_statistical_functions.py @@ -36,21 +36,8 @@ def max( """ if x.dtype not in _numeric_dtypes: raise TypeError("Only numeric dtypes are allowed in max") - res = ht.max(x._array, axis=axis, keepdim=True) - if axis is None: - if keepdims: - output_shape = tuple(1 for _ in range(x.ndim)) - else: - output_shape = () - else: - if isinstance(axis, int): - axis = (axis,) - axis = [a if a >= 0 else a + x.ndim for a in axis] - if keepdims: - output_shape = tuple(1 if i in axis else dim for i, dim in enumerate(x.shape)) - else: - output_shape = tuple(dim for i, dim in enumerate(x.shape) if i not in axis) - return Array._new(res.reshape(output_shape)) + res = ht.max(x._array, axis=axis, keepdim=keepdims) + return Array._new(res) def mean( @@ -81,20 +68,7 @@ def mean( if axis == (): return x res = ht.mean(x._array, axis=axis) - if axis is None: - if keepdims: - output_shape = tuple(1 for _ in range(x.ndim)) - else: - output_shape = () - else: - if isinstance(axis, int): - axis = (axis,) - axis = [a if a >= 0 else a + x.ndim for a in axis] - if keepdims: - output_shape = tuple(1 if i in axis else dim for i, dim in enumerate(x.shape)) - else: - output_shape = tuple(dim for i, dim in enumerate(x.shape) if i not in axis) - return Array._new(res.astype(x.dtype).reshape(output_shape)) + return Array._new(res.astype(x.dtype)) def min( @@ -122,21 +96,8 @@ def min( """ if x.dtype not in _numeric_dtypes: raise TypeError("Only numeric dtypes are allowed in min") - res = ht.min(x._array, axis=axis, keepdim=True) - if axis is None: - if keepdims: - output_shape = tuple(1 for _ in range(x.ndim)) - else: - output_shape = () - else: - if isinstance(axis, int): - axis = (axis,) - axis = [a if a >= 0 else a + x.ndim for a in axis] - if keepdims: - output_shape = tuple(1 if i in axis else dim for i, dim in enumerate(x.shape)) - else: - output_shape = tuple(dim for i, dim in enumerate(x.shape) if i not in axis) - return Array._new(res.reshape(output_shape)) + res = ht.min(x._array, axis=axis, keepdim=keepdims) + return Array._new(res) def prod( @@ -167,13 +128,7 @@ def prod( """ if x.dtype not in _numeric_dtypes: raise TypeError("Only numeric dtypes are allowed in prod") - # Note: sum() and prod() always upcast float32 to float64 for dtype=None - # We need to do so here before computing the product to avoid overflow - # if dtype is None and x.dtype == float32: - # dtype = float64 - res = ht.prod(x._array, axis=axis, keepdim=True) - if not keepdims or x._array.ndim == 0: - res = ht.squeeze(res, axis=axis) + res = ht.prod(x._array, axis=axis, keepdim=keepdims) if dtype is None: if x.dtype in _floating_dtypes: dtype = default_float @@ -213,22 +168,7 @@ def std( if x.dtype not in _floating_dtypes: raise TypeError("Only floating-point dtypes are allowed in std") res = ht.std(x._array, axis=axis, ddof=int(correction)) - if not isinstance(res, ht.DNDarray): - res = ht.array(res, dtype=x.dtype) - if axis is None: - if keepdims: - output_shape = tuple(1 for _ in range(x.ndim)) - else: - output_shape = () - else: - if isinstance(axis, int): - axis = (axis,) - axis = [a if a >= 0 else a + x.ndim for a in axis] - if keepdims: - output_shape = tuple(1 if i in axis else dim for i, dim in enumerate(x.shape)) - else: - output_shape = tuple(dim for i, dim in enumerate(x.shape) if i not in axis) - return Array._new(res.reshape(output_shape)) + return Array._new(res) def sum( @@ -259,14 +199,7 @@ def sum( """ if x.dtype not in _numeric_dtypes: raise TypeError("Only numeric dtypes are allowed in sum") - # Note: sum() and prod() always upcast integers to (u)int64 and float32 to - # float64 for dtype=None. `np.sum` does that too for integers, but not for - # float32, so we need to special-case it here - # if dtype is None and x.dtype == float32: - # dtype = float64 - res = ht.sum(x._array, axis=axis, keepdim=True) - if not keepdims or x._array.ndim == 0: - res = ht.squeeze(res, axis=axis) + res = ht.sum(x._array, axis=axis, keepdim=keepdims) if dtype is None: if x.dtype in _floating_dtypes: dtype = default_float @@ -308,17 +241,4 @@ def var( if axis == (): return x res = ht.var(x._array, axis=axis, ddof=int(correction)) - if axis is None: - if keepdims: - output_shape = tuple(1 for _ in range(x.ndim)) - else: - output_shape = () - else: - if isinstance(axis, int): - axis = (axis,) - axis = [a if a >= 0 else a + x.ndim for a in axis] - if keepdims: - output_shape = tuple(1 if i in axis else dim for i, dim in enumerate(x.shape)) - else: - output_shape = tuple(dim for i, dim in enumerate(x.shape) if i not in axis) - return Array._new(res.astype(x.dtype).reshape(output_shape)) + return Array._new(res.astype(x.dtype)) diff --git a/heat/array_api/_utility_functions.py b/heat/array_api/_utility_functions.py index ba6fcd71ae..ced0b3fda6 100644 --- a/heat/array_api/_utility_functions.py +++ b/heat/array_api/_utility_functions.py @@ -30,9 +30,7 @@ def all( as singleton dimensions. Otherwise, if ``False``, the reduced axes (dimensions) are be included in the result. Default: ``False``. """ - res = ht.all(x._array, axis=axis, keepdim=True) - if not keepdims or x._array.ndim == 0: - res = ht.squeeze(res, axis=axis) + res = ht.all(x._array, axis=axis, keepdim=keepdims) return Array._new(res) @@ -60,8 +58,6 @@ def any( as singleton dimensions. Otherwise, if ``False``, the reduced axes (dimensions) are be included in the result. Default: ``False``. """ - res = ht.any(x._array, axis=axis, keepdim=True) - if not keepdims or x._array.ndim == 0: - res = ht.squeeze(res, axis=axis) + res = ht.any(x._array, axis=axis, keepdim=keepdims) return Array._new(res) diff --git a/heat/array_api/linalg.py b/heat/array_api/linalg.py index 50049ad091..d388552942 100644 --- a/heat/array_api/linalg.py +++ b/heat/array_api/linalg.py @@ -71,7 +71,6 @@ def tensordot( """ if x1.dtype not in _numeric_dtypes or x2.dtype not in _numeric_dtypes: raise TypeError("Only numeric dtypes are allowed in tensordot") - return Array._new(ht.tensordot(x1._array, x2._array, axes=axes)) From 824fa9be4f9b85b935817575eca2f02ffacb32ce Mon Sep 17 00:00:00 2001 From: neosunhan Date: Mon, 5 Sep 2022 13:58:40 +0800 Subject: [PATCH 087/150] Add `from_dlpack` --- heat/array_api/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index ac1adf709a..3806ee6a39 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -36,6 +36,7 @@ "empty", "empty_like", "eye", + "from_dlpack", "full", "full_like", "linspace", From ca588a0e308817faafa108d3ff4c63811e65e2b7 Mon Sep 17 00:00:00 2001 From: neosunhan Date: Fri, 30 Sep 2022 20:55:13 +0800 Subject: [PATCH 088/150] Add ci tests --- .github/workflows/array-api.yml | 164 ++++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 .github/workflows/array-api.yml diff --git a/.github/workflows/array-api.yml b/.github/workflows/array-api.yml new file mode 100644 index 0000000000..405f754a30 --- /dev/null +++ b/.github/workflows/array-api.yml @@ -0,0 +1,164 @@ +name: Test Array API + +on: + pull_request_review: + types: [submitted] + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: [3.8, 3.9] + + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Use Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + architecture: x64 + - name: Install + run: | + python -m pip install --upgrade pip + python -m pip install . + - name: Checkout array-api-tests + uses: actions/checkout@v3 + with: + repository: data-api/array-api-tests + ref: 2022.05.18 + path: array-api-tests + submodules: 'true' + - name: Install dependencies + run: | + python -m pip install -r array-api-tests/requirements.txt + - name: Run the test suite + env: + ARRAY_API_TESTS_MODULE: heat.array_api + run: | + # Skip testing functions with known issues + cat << EOF >> skips.txt + + # PR #938 Indexing overhaul + array-api-tests/array_api_tests/test_array_object.py::test_getitem + array-api-tests/array_api_tests/test_array_object.py::test_setitem + array-api-tests/array_api_tests/test_array_object.py::test_getitem_masking + array-api-tests/array_api_tests/test_array_object.py::test_setitem_masking + array-api-tests/array_api_tests/test_linalg.py::test_matrix_matmul + array-api-tests/array_api_tests/test_manipulation_functions.py::test_concat + array-api-tests/array_api_tests/test_manipulation_functions.py::test_stack + array-api-tests/array_api_tests/test_searching_functions.py::test_argmax + array-api-tests/array_api_tests/test_searching_functions.py::test_argmin + array-api-tests/array_api_tests/test_searching_functions.py::test_nonzero + array-api-tests/array_api_tests/test_searching_functions.py::test_where + array-api-tests/array_api_tests/test_special_cases.py::test_nan_propagation[max] + array-api-tests/array_api_tests/test_special_cases.py::test_nan_propagation[min] + array-api-tests/array_api_tests/test_special_cases.py::test_nan_propagation[prod] + array-api-tests/array_api_tests/test_special_cases.py::test_nan_propagation[sum] + array-api-tests/array_api_tests/test_special_cases.py::test_binary[add(isfinite(x1_i) and x1_i != 0 and x2_i == -x1_i) -> +0] + array-api-tests/array_api_tests/test_special_cases.py::test_iop[__iadd__(isfinite(x1_i) and x1_i != 0 and x2_i == -x1_i) -> +0] + array-api-tests/array_api_tests/test_statistical_functions.py::test_max + array-api-tests/array_api_tests/test_statistical_functions.py::test_mean + array-api-tests/array_api_tests/test_statistical_functions.py::test_min + array-api-tests/array_api_tests/test_statistical_functions.py::test_prod + array-api-tests/array_api_tests/test_statistical_functions.py::test_var + array-api-tests/array_api_tests/test_utility_functions.py::test_all + array-api-tests/array_api_tests/test_utility_functions.py::test_any + + # Pytorch dtypes https://github.com/pytorch/pytorch/issues/58734 + array-api-tests/array_api_tests/test_array_object.py::test_scalar_casting[__int__(uint16)] + array-api-tests/array_api_tests/test_array_object.py::test_scalar_casting[__int__(uint32)] + array-api-tests/array_api_tests/test_array_object.py::test_scalar_casting[__int__(uint64)] + array-api-tests/array_api_tests/test_array_object.py::test_scalar_casting[__index__(uint16)] + array-api-tests/array_api_tests/test_array_object.py::test_scalar_casting[__index__(uint32] + array-api-tests/array_api_tests/test_array_object.py::test_scalar_casting[__inndes__(uint64)] + array-api-tests/array_api_tests/test_data_type_functions.py::test_iinfo[uint16] + array-api-tests/array_api_tests/test_data_type_functions.py::test_iinfo[uint32] + array-api-tests/array_api_tests/test_data_type_functions.py::test_iinfo[uint64] + array-api-tests/array_api_tests/test_statistical_functions.py::test_sum + array-api-tests/array_api_tests/test_type_promotion.py + + # PR #1000 any/all keepdim + array-api-tests/array_api_tests/test_linalg.py::test_matrix_transpose + array-api-tests/array_api_tests/test_operators_and_elementwise_functions.py::test_abs + array-api-tests/array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_left_shift + array-api-tests/array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_right_shift + array-api-tests/array_api_tests/test_operators_and_elementwise_functions.py::test_floor_divide + array-api-tests/array_api_tests/test_operators_and_elementwise_functions.py::test_positive + array-api-tests/array_api_tests/test_operators_and_elementwise_functions.py::test_pow + array-api-tests/array_api_tests/test_operators_and_elementwise_functions.py::test_remainder + + # PR #993 Precision loss + array-api-tests/array_api_tests/test_creation_functions.py::test_arange + array-api-tests/array_api_tests/test_creation_functions.py::test_linspace + + # PR #1018 __reduce_op bug + array-api-tests/array_api_tests/test_creation_functions.py::test_asarray_arrays + array-api-tests/array_api_tests/test_creation_functions.py::test_full + array-api-tests/array_api_tests/test_creation_functions.py::test_full_like + array-api-tests/array_api_tests/test_creation_functions.py::test_ones + array-api-tests/array_api_tests/test_creation_functions.py::test_ones_like + array-api-tests/array_api_tests/test_creation_functions.py::test_zeros + array-api-tests/array_api_tests/test_creation_functions.py::test_zeros_like + array-api-tests/array_api_tests/test_operators_and_elementwise_functions.py::test_negative + array-api-tests/array_api_tests/test_special_cases.py::test_empty_arrays[prod] + array-api-tests/array_api_tests/test_special_cases.py::test_nan_propagation[sum] + + # k not implemented + array-api-tests/array_api_tests/test_creation_functions.py::test_eye + + # PR #1020 broadcasting + array-api-tests/array_api_tests/test_data_type_functions.py::test_broadcast_arrays + array-api-tests/array_api_tests/test_data_type_functions.py::test_broadcast_to + + # PR #749 unique + array-api-tests/array_api_tests/test_set_functions.py::test_unique_all + array-api-tests/array_api_tests/test_set_functions.py::test_unique_counts + array-api-tests/array_api_tests/test_set_functions.py::test_unique_inverse + array-api-tests/array_api_tests/test_set_functions.py::test_unique_values + array-api-tests/array_api_tests/test_signatures.py::test_func_signature[unique_all] + array-api-tests/array_api_tests/test_signatures.py::test_func_signature[unique_counts] + array-api-tests/array_api_tests/test_sorting_functions.py::test_sort + + # PR #996 argsort + array-api-tests/array_api_tests/test_signatures.py::test_func_signature[argsort] + array-api-tests/array_api_tests/test_sorting_functions.py::test_argsort + + # tensordot + array-api-tests/array_api_tests/test_linalg.py::test_tensordot + + # Special cases + array-api-tests/array_api_tests/test_operators_and_elementwise_functions.py::test_square + array-api-tests/array_api_tests/test_special_cases.py::test_binary[floor_divide(x1_i is +infinity and isfinite(x2_i) and x2_i > 0) -> +infinity] + array-api-tests/array_api_tests/test_special_cases.py::test_binary[floor_divide(x1_i is +infinity and isfinite(x2_i) and x2_i < 0) -> -infinity] + array-api-tests/array_api_tests/test_special_cases.py::test_binary[floor_divide(x1_i is -infinity and isfinite(x2_i) and x2_i > 0) -> -infinity] + array-api-tests/array_api_tests/test_special_cases.py::test_binary[floor_divide(x1_i is -infinity and isfinite(x2_i) and x2_i < 0) -> +infinity] + array-api-tests/array_api_tests/test_special_cases.py::test_binary[floor_divide(isfinite(x1_i) and x1_i > 0 and x2_i is -infinity) -> -0] + array-api-tests/array_api_tests/test_special_cases.py::test_binary[floor_divide(isfinite(x1_i) and x1_i < 0 and x2_i is +infinity) -> -0] + array-api-tests/array_api_tests/test_special_cases.py::test_binary[__floordiv__(x1_i is +infinity and isfinite(x2_i) and x2_i > 0) -> +infinity] + array-api-tests/array_api_tests/test_special_cases.py::test_binary[__floordiv__(x1_i is +infinity and isfinite(x2_i) and x2_i < 0) -> -infinity] + array-api-tests/array_api_tests/test_special_cases.py::test_binary[__floordiv__(x1_i is -infinity and isfinite(x2_i) and x2_i > 0) -> -infinity] + array-api-tests/array_api_tests/test_special_cases.py::test_binary[__floordiv__(x1_i is -infinity and isfinite(x2_i) and x2_i < 0) -> +infinity] + array-api-tests/array_api_tests/test_special_cases.py::test_binary[__floordiv__(isfinite(x1_i) and x1_i > 0 and x2_i is -infinity) -> -0] + array-api-tests/array_api_tests/test_special_cases.py::test_binary[__floordiv__(isfinite(x1_i) and x1_i < 0 and x2_i is +infinity) -> -0] + array-api-tests/array_api_tests/test_special_cases.py::test_binary[remainder(x1_i is -0 and x2_i > 0) -> +0] + array-api-tests/array_api_tests/test_special_cases.py::test_binary[remainder(x1_i is +0 and x2_i < 0) -> -0] + array-api-tests/array_api_tests/test_special_cases.py::test_binary[__mod__(x1_i is -0 and x2_i > 0) -> +0] + array-api-tests/array_api_tests/test_special_cases.py::test_binary[__mod__(x1_i is +0 and x2_i < 0) -> -0] + array-api-tests/array_api_tests/test_special_cases.py::test_iop[__ifloordiv__(x1_i is +infinity and isfinite(x2_i) and x2_i > 0) -> +infinity] + array-api-tests/array_api_tests/test_special_cases.py::test_iop[__ifloordiv__(x1_i is +infinity and isfinite(x2_i) and x2_i < 0) -> -infinity] + array-api-tests/array_api_tests/test_special_cases.py::test_iop[__ifloordiv__(x1_i is -infinity and isfinite(x2_i) and x2_i > 0) -> -infinity] + array-api-tests/array_api_tests/test_special_cases.py::test_iop[__ifloordiv__(x1_i is -infinity and isfinite(x2_i) and x2_i < 0) -> +infinity] + array-api-tests/array_api_tests/test_special_cases.py::test_iop[__ifloordiv__(isfinite(x1_i) and x1_i > 0 and x2_i is -infinity) -> -0] + array-api-tests/array_api_tests/test_special_cases.py::test_iop[__ifloordiv__(isfinite(x1_i) and x1_i < 0 and x2_i is +infinity) -> -0] + array-api-tests/array_api_tests/test_special_cases.py::test_iop[__imod__(x1_i is -0 and x2_i > 0) -> +0] + array-api-tests/array_api_tests/test_special_cases.py::test_iop[__imod__(x1_i is +0 and x2_i < 0) -> -0] + # std special cases + array-api-tests/array_api_tests/test_statistical_functions.py::test_std + array-api-tests/array_api_tests/test_special_cases.py::test_empty_arrays[std] + array-api-tests/array_api_tests/test_special_cases.py::test_nan_propagation[std] + + EOF + + pytest array-api-tests/array_api_tests -v -rxXfE --ci --disable-extension linalg From b25be5f4949cbae959ddd7c0c030943bd8b66f93 Mon Sep 17 00:00:00 2001 From: Claudia Comito <39374113+ClaudiaComito@users.noreply.github.com> Date: Wed, 17 May 2023 10:20:42 +0200 Subject: [PATCH 089/150] [skip ci] install MPI, update API reference, introduce manual trigger --- .github/workflows/array-api.yml | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/.github/workflows/array-api.yml b/.github/workflows/array-api.yml index 405f754a30..123768e0b6 100644 --- a/.github/workflows/array-api.yml +++ b/.github/workflows/array-api.yml @@ -1,8 +1,9 @@ name: Test Array API on: - pull_request_review: - types: [submitted] + workflow_dispatch: + # pull_request_review: + # types: [submitted] jobs: build: @@ -10,10 +11,15 @@ jobs: strategy: matrix: python-version: [3.8, 3.9] + mpi: [ 'openmpi' ] steps: - name: Checkout uses: actions/checkout@v3 + - name: Setup MPI + uses: mpi4py/setup-mpi@v1 + with: + mpi: ${{ matrix.mpi }} - name: Use Python ${{ matrix.python-version }} uses: actions/setup-python@v2 with: @@ -27,7 +33,7 @@ jobs: uses: actions/checkout@v3 with: repository: data-api/array-api-tests - ref: 2022.05.18 + ref: 2022.09.30 path: array-api-tests submodules: 'true' - name: Install dependencies From c954cab8d96c2a9df787fab1e934e0dee7dee56f Mon Sep 17 00:00:00 2001 From: Claudia Comito <39374113+ClaudiaComito@users.noreply.github.com> Date: Wed, 17 May 2023 10:28:14 +0200 Subject: [PATCH 090/150] [skip ci] trigger on PR label --- .github/workflows/array-api.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/array-api.yml b/.github/workflows/array-api.yml index 123768e0b6..52bf87c98d 100644 --- a/.github/workflows/array-api.yml +++ b/.github/workflows/array-api.yml @@ -1,12 +1,14 @@ name: Test Array API on: - workflow_dispatch: + pull_request: + types: [opened, synchronize, reopened, labeled] # pull_request_review: # types: [submitted] jobs: build: + if: contains(github.event.pull_request.labels.*.name, 'test array API') runs-on: ubuntu-latest strategy: matrix: From 74234ac1b2330202711a7b567e19f19942e6fa9c Mon Sep 17 00:00:00 2001 From: Claudia Comito <39374113+ClaudiaComito@users.noreply.github.com> Date: Wed, 17 May 2023 10:38:39 +0200 Subject: [PATCH 091/150] adding back original trigger --- .github/workflows/array-api.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/array-api.yml b/.github/workflows/array-api.yml index 52bf87c98d..e24132115f 100644 --- a/.github/workflows/array-api.yml +++ b/.github/workflows/array-api.yml @@ -3,8 +3,8 @@ name: Test Array API on: pull_request: types: [opened, synchronize, reopened, labeled] - # pull_request_review: - # types: [submitted] + pull_request_review: + types: [submitted] jobs: build: From a9f80b43893e74feece84656ac9335d4263563f4 Mon Sep 17 00:00:00 2001 From: Claudia Comito <39374113+ClaudiaComito@users.noreply.github.com> Date: Wed, 17 May 2023 10:42:07 +0200 Subject: [PATCH 092/150] back to original trigger --- .github/workflows/array-api.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/array-api.yml b/.github/workflows/array-api.yml index e24132115f..02d0040bd7 100644 --- a/.github/workflows/array-api.yml +++ b/.github/workflows/array-api.yml @@ -1,14 +1,14 @@ name: Test Array API on: - pull_request: - types: [opened, synchronize, reopened, labeled] + # pull_request: + # types: [opened, synchronize, reopened, labeled] pull_request_review: types: [submitted] jobs: build: - if: contains(github.event.pull_request.labels.*.name, 'test array API') +# if: contains(github.event.pull_request.labels.*.name, 'test array API') runs-on: ubuntu-latest strategy: matrix: From bfe3f12ea7df9f6e60898572e464cc5d64dee426 Mon Sep 17 00:00:00 2001 From: Claudia Comito <39374113+ClaudiaComito@users.noreply.github.com> Date: Wed, 17 May 2023 11:20:03 +0200 Subject: [PATCH 093/150] [skip ci] fix workflow indentation --- .github/workflows/array-api.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/array-api.yml b/.github/workflows/array-api.yml index 02d0040bd7..7a96a7e724 100644 --- a/.github/workflows/array-api.yml +++ b/.github/workflows/array-api.yml @@ -13,7 +13,7 @@ jobs: strategy: matrix: python-version: [3.8, 3.9] - mpi: [ 'openmpi' ] + mpi: [ 'openmpi' ] steps: - name: Checkout From 6d4706bfbee8107f453be758f0b6ceaaad9f3915 Mon Sep 17 00:00:00 2001 From: Claudia Comito <39374113+ClaudiaComito@users.noreply.github.com> Date: Wed, 17 May 2023 11:26:47 +0200 Subject: [PATCH 094/150] fix URL of test repository --- .github/workflows/array-api.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/array-api.yml b/.github/workflows/array-api.yml index 7a96a7e724..58259ac6ac 100644 --- a/.github/workflows/array-api.yml +++ b/.github/workflows/array-api.yml @@ -34,7 +34,7 @@ jobs: - name: Checkout array-api-tests uses: actions/checkout@v3 with: - repository: data-api/array-api-tests + repository: data-apis/array-api-tests ref: 2022.09.30 path: array-api-tests submodules: 'true' From 509c19e2ed1b4ef47387d94bb28eca869c10e4df Mon Sep 17 00:00:00 2001 From: Claudia Comito <39374113+ClaudiaComito@users.noreply.github.com> Date: Tue, 5 Sep 2023 09:57:45 +0200 Subject: [PATCH 095/150] Test Python 3.9 and 3.10 --- .github/workflows/array-api.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/array-api.yml b/.github/workflows/array-api.yml index 58259ac6ac..91cfa9f032 100644 --- a/.github/workflows/array-api.yml +++ b/.github/workflows/array-api.yml @@ -12,7 +12,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: [3.8, 3.9] + python-version: [3.9, '3.10'] mpi: [ 'openmpi' ] steps: From 2fd9ad2748da723054c9da5409870f7a2fcfbe91 Mon Sep 17 00:00:00 2001 From: Michael Tarnawa Date: Mon, 11 Sep 2023 09:00:42 +0200 Subject: [PATCH 096/150] Update array-api.yml --- .github/workflows/array-api.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/array-api.yml b/.github/workflows/array-api.yml index 91cfa9f032..35a07abc6e 100644 --- a/.github/workflows/array-api.yml +++ b/.github/workflows/array-api.yml @@ -169,4 +169,4 @@ jobs: EOF - pytest array-api-tests/array_api_tests -v -rxXfE --ci --disable-extension linalg + pytest array-api-tests/array_api_tests -v -rxXfE --ci --disable-extension linalg --skips-file skips.txt From 57feb55a41983ada34e2098ede2c60d3c36aad02 Mon Sep 17 00:00:00 2001 From: Michael Tarnawa Date: Fri, 16 Feb 2024 16:08:58 +0100 Subject: [PATCH 097/150] change skipfile path --- .github/workflows/array-api.yml | 122 -------------------------------- skips.txt | 118 ++++++++++++++++++++++++++++++ 2 files changed, 118 insertions(+), 122 deletions(-) create mode 100644 skips.txt diff --git a/.github/workflows/array-api.yml b/.github/workflows/array-api.yml index 35a07abc6e..70fea71a56 100644 --- a/.github/workflows/array-api.yml +++ b/.github/workflows/array-api.yml @@ -46,127 +46,5 @@ jobs: ARRAY_API_TESTS_MODULE: heat.array_api run: | # Skip testing functions with known issues - cat << EOF >> skips.txt - - # PR #938 Indexing overhaul - array-api-tests/array_api_tests/test_array_object.py::test_getitem - array-api-tests/array_api_tests/test_array_object.py::test_setitem - array-api-tests/array_api_tests/test_array_object.py::test_getitem_masking - array-api-tests/array_api_tests/test_array_object.py::test_setitem_masking - array-api-tests/array_api_tests/test_linalg.py::test_matrix_matmul - array-api-tests/array_api_tests/test_manipulation_functions.py::test_concat - array-api-tests/array_api_tests/test_manipulation_functions.py::test_stack - array-api-tests/array_api_tests/test_searching_functions.py::test_argmax - array-api-tests/array_api_tests/test_searching_functions.py::test_argmin - array-api-tests/array_api_tests/test_searching_functions.py::test_nonzero - array-api-tests/array_api_tests/test_searching_functions.py::test_where - array-api-tests/array_api_tests/test_special_cases.py::test_nan_propagation[max] - array-api-tests/array_api_tests/test_special_cases.py::test_nan_propagation[min] - array-api-tests/array_api_tests/test_special_cases.py::test_nan_propagation[prod] - array-api-tests/array_api_tests/test_special_cases.py::test_nan_propagation[sum] - array-api-tests/array_api_tests/test_special_cases.py::test_binary[add(isfinite(x1_i) and x1_i != 0 and x2_i == -x1_i) -> +0] - array-api-tests/array_api_tests/test_special_cases.py::test_iop[__iadd__(isfinite(x1_i) and x1_i != 0 and x2_i == -x1_i) -> +0] - array-api-tests/array_api_tests/test_statistical_functions.py::test_max - array-api-tests/array_api_tests/test_statistical_functions.py::test_mean - array-api-tests/array_api_tests/test_statistical_functions.py::test_min - array-api-tests/array_api_tests/test_statistical_functions.py::test_prod - array-api-tests/array_api_tests/test_statistical_functions.py::test_var - array-api-tests/array_api_tests/test_utility_functions.py::test_all - array-api-tests/array_api_tests/test_utility_functions.py::test_any - - # Pytorch dtypes https://github.com/pytorch/pytorch/issues/58734 - array-api-tests/array_api_tests/test_array_object.py::test_scalar_casting[__int__(uint16)] - array-api-tests/array_api_tests/test_array_object.py::test_scalar_casting[__int__(uint32)] - array-api-tests/array_api_tests/test_array_object.py::test_scalar_casting[__int__(uint64)] - array-api-tests/array_api_tests/test_array_object.py::test_scalar_casting[__index__(uint16)] - array-api-tests/array_api_tests/test_array_object.py::test_scalar_casting[__index__(uint32] - array-api-tests/array_api_tests/test_array_object.py::test_scalar_casting[__inndes__(uint64)] - array-api-tests/array_api_tests/test_data_type_functions.py::test_iinfo[uint16] - array-api-tests/array_api_tests/test_data_type_functions.py::test_iinfo[uint32] - array-api-tests/array_api_tests/test_data_type_functions.py::test_iinfo[uint64] - array-api-tests/array_api_tests/test_statistical_functions.py::test_sum - array-api-tests/array_api_tests/test_type_promotion.py - - # PR #1000 any/all keepdim - array-api-tests/array_api_tests/test_linalg.py::test_matrix_transpose - array-api-tests/array_api_tests/test_operators_and_elementwise_functions.py::test_abs - array-api-tests/array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_left_shift - array-api-tests/array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_right_shift - array-api-tests/array_api_tests/test_operators_and_elementwise_functions.py::test_floor_divide - array-api-tests/array_api_tests/test_operators_and_elementwise_functions.py::test_positive - array-api-tests/array_api_tests/test_operators_and_elementwise_functions.py::test_pow - array-api-tests/array_api_tests/test_operators_and_elementwise_functions.py::test_remainder - - # PR #993 Precision loss - array-api-tests/array_api_tests/test_creation_functions.py::test_arange - array-api-tests/array_api_tests/test_creation_functions.py::test_linspace - - # PR #1018 __reduce_op bug - array-api-tests/array_api_tests/test_creation_functions.py::test_asarray_arrays - array-api-tests/array_api_tests/test_creation_functions.py::test_full - array-api-tests/array_api_tests/test_creation_functions.py::test_full_like - array-api-tests/array_api_tests/test_creation_functions.py::test_ones - array-api-tests/array_api_tests/test_creation_functions.py::test_ones_like - array-api-tests/array_api_tests/test_creation_functions.py::test_zeros - array-api-tests/array_api_tests/test_creation_functions.py::test_zeros_like - array-api-tests/array_api_tests/test_operators_and_elementwise_functions.py::test_negative - array-api-tests/array_api_tests/test_special_cases.py::test_empty_arrays[prod] - array-api-tests/array_api_tests/test_special_cases.py::test_nan_propagation[sum] - - # k not implemented - array-api-tests/array_api_tests/test_creation_functions.py::test_eye - - # PR #1020 broadcasting - array-api-tests/array_api_tests/test_data_type_functions.py::test_broadcast_arrays - array-api-tests/array_api_tests/test_data_type_functions.py::test_broadcast_to - - # PR #749 unique - array-api-tests/array_api_tests/test_set_functions.py::test_unique_all - array-api-tests/array_api_tests/test_set_functions.py::test_unique_counts - array-api-tests/array_api_tests/test_set_functions.py::test_unique_inverse - array-api-tests/array_api_tests/test_set_functions.py::test_unique_values - array-api-tests/array_api_tests/test_signatures.py::test_func_signature[unique_all] - array-api-tests/array_api_tests/test_signatures.py::test_func_signature[unique_counts] - array-api-tests/array_api_tests/test_sorting_functions.py::test_sort - - # PR #996 argsort - array-api-tests/array_api_tests/test_signatures.py::test_func_signature[argsort] - array-api-tests/array_api_tests/test_sorting_functions.py::test_argsort - - # tensordot - array-api-tests/array_api_tests/test_linalg.py::test_tensordot - - # Special cases - array-api-tests/array_api_tests/test_operators_and_elementwise_functions.py::test_square - array-api-tests/array_api_tests/test_special_cases.py::test_binary[floor_divide(x1_i is +infinity and isfinite(x2_i) and x2_i > 0) -> +infinity] - array-api-tests/array_api_tests/test_special_cases.py::test_binary[floor_divide(x1_i is +infinity and isfinite(x2_i) and x2_i < 0) -> -infinity] - array-api-tests/array_api_tests/test_special_cases.py::test_binary[floor_divide(x1_i is -infinity and isfinite(x2_i) and x2_i > 0) -> -infinity] - array-api-tests/array_api_tests/test_special_cases.py::test_binary[floor_divide(x1_i is -infinity and isfinite(x2_i) and x2_i < 0) -> +infinity] - array-api-tests/array_api_tests/test_special_cases.py::test_binary[floor_divide(isfinite(x1_i) and x1_i > 0 and x2_i is -infinity) -> -0] - array-api-tests/array_api_tests/test_special_cases.py::test_binary[floor_divide(isfinite(x1_i) and x1_i < 0 and x2_i is +infinity) -> -0] - array-api-tests/array_api_tests/test_special_cases.py::test_binary[__floordiv__(x1_i is +infinity and isfinite(x2_i) and x2_i > 0) -> +infinity] - array-api-tests/array_api_tests/test_special_cases.py::test_binary[__floordiv__(x1_i is +infinity and isfinite(x2_i) and x2_i < 0) -> -infinity] - array-api-tests/array_api_tests/test_special_cases.py::test_binary[__floordiv__(x1_i is -infinity and isfinite(x2_i) and x2_i > 0) -> -infinity] - array-api-tests/array_api_tests/test_special_cases.py::test_binary[__floordiv__(x1_i is -infinity and isfinite(x2_i) and x2_i < 0) -> +infinity] - array-api-tests/array_api_tests/test_special_cases.py::test_binary[__floordiv__(isfinite(x1_i) and x1_i > 0 and x2_i is -infinity) -> -0] - array-api-tests/array_api_tests/test_special_cases.py::test_binary[__floordiv__(isfinite(x1_i) and x1_i < 0 and x2_i is +infinity) -> -0] - array-api-tests/array_api_tests/test_special_cases.py::test_binary[remainder(x1_i is -0 and x2_i > 0) -> +0] - array-api-tests/array_api_tests/test_special_cases.py::test_binary[remainder(x1_i is +0 and x2_i < 0) -> -0] - array-api-tests/array_api_tests/test_special_cases.py::test_binary[__mod__(x1_i is -0 and x2_i > 0) -> +0] - array-api-tests/array_api_tests/test_special_cases.py::test_binary[__mod__(x1_i is +0 and x2_i < 0) -> -0] - array-api-tests/array_api_tests/test_special_cases.py::test_iop[__ifloordiv__(x1_i is +infinity and isfinite(x2_i) and x2_i > 0) -> +infinity] - array-api-tests/array_api_tests/test_special_cases.py::test_iop[__ifloordiv__(x1_i is +infinity and isfinite(x2_i) and x2_i < 0) -> -infinity] - array-api-tests/array_api_tests/test_special_cases.py::test_iop[__ifloordiv__(x1_i is -infinity and isfinite(x2_i) and x2_i > 0) -> -infinity] - array-api-tests/array_api_tests/test_special_cases.py::test_iop[__ifloordiv__(x1_i is -infinity and isfinite(x2_i) and x2_i < 0) -> +infinity] - array-api-tests/array_api_tests/test_special_cases.py::test_iop[__ifloordiv__(isfinite(x1_i) and x1_i > 0 and x2_i is -infinity) -> -0] - array-api-tests/array_api_tests/test_special_cases.py::test_iop[__ifloordiv__(isfinite(x1_i) and x1_i < 0 and x2_i is +infinity) -> -0] - array-api-tests/array_api_tests/test_special_cases.py::test_iop[__imod__(x1_i is -0 and x2_i > 0) -> +0] - array-api-tests/array_api_tests/test_special_cases.py::test_iop[__imod__(x1_i is +0 and x2_i < 0) -> -0] - # std special cases - array-api-tests/array_api_tests/test_statistical_functions.py::test_std - array-api-tests/array_api_tests/test_special_cases.py::test_empty_arrays[std] - array-api-tests/array_api_tests/test_special_cases.py::test_nan_propagation[std] - - EOF pytest array-api-tests/array_api_tests -v -rxXfE --ci --disable-extension linalg --skips-file skips.txt diff --git a/skips.txt b/skips.txt new file mode 100644 index 0000000000..26745433d6 --- /dev/null +++ b/skips.txt @@ -0,0 +1,118 @@ +# PR #938 Indexing overhaul + array-api-tests/array_api_tests/test_array_object.py::test_getitem + array-api-tests/array_api_tests/test_array_object.py::test_setitem + array-api-tests/array_api_tests/test_array_object.py::test_getitem_masking + array-api-tests/array_api_tests/test_array_object.py::test_setitem_masking + array-api-tests/array_api_tests/test_linalg.py::test_matrix_matmul + array-api-tests/array_api_tests/test_manipulation_functions.py::test_concat + array-api-tests/array_api_tests/test_manipulation_functions.py::test_stack + array-api-tests/array_api_tests/test_searching_functions.py::test_argmax + array-api-tests/array_api_tests/test_searching_functions.py::test_argmin + array-api-tests/array_api_tests/test_searching_functions.py::test_nonzero + array-api-tests/array_api_tests/test_searching_functions.py::test_where + array-api-tests/array_api_tests/test_special_cases.py::test_nan_propagation[max] + array-api-tests/array_api_tests/test_special_cases.py::test_nan_propagation[min] + array-api-tests/array_api_tests/test_special_cases.py::test_nan_propagation[prod] + array-api-tests/array_api_tests/test_special_cases.py::test_nan_propagation[sum] + array-api-tests/array_api_tests/test_special_cases.py::test_binary[add(isfinite(x1_i) and x1_i != 0 and x2_i == -x1_i) -> +0] + array-api-tests/array_api_tests/test_special_cases.py::test_iop[__iadd__(isfinite(x1_i) and x1_i != 0 and x2_i == -x1_i) -> +0] + array-api-tests/array_api_tests/test_statistical_functions.py::test_max + array-api-tests/array_api_tests/test_statistical_functions.py::test_mean + array-api-tests/array_api_tests/test_statistical_functions.py::test_min + array-api-tests/array_api_tests/test_statistical_functions.py::test_prod + array-api-tests/array_api_tests/test_statistical_functions.py::test_var + array-api-tests/array_api_tests/test_utility_functions.py::test_all + array-api-tests/array_api_tests/test_utility_functions.py::test_any + + # Pytorch dtypes https://github.com/pytorch/pytorch/issues/58734 + array-api-tests/array_api_tests/test_array_object.py::test_scalar_casting[__int__(uint16)] + array-api-tests/array_api_tests/test_array_object.py::test_scalar_casting[__int__(uint32)] + array-api-tests/array_api_tests/test_array_object.py::test_scalar_casting[__int__(uint64)] + array-api-tests/array_api_tests/test_array_object.py::test_scalar_casting[__index__(uint16)] + array-api-tests/array_api_tests/test_array_object.py::test_scalar_casting[__index__(uint32] + array-api-tests/array_api_tests/test_array_object.py::test_scalar_casting[__inndes__(uint64)] + array-api-tests/array_api_tests/test_data_type_functions.py::test_iinfo[uint16] + array-api-tests/array_api_tests/test_data_type_functions.py::test_iinfo[uint32] + array-api-tests/array_api_tests/test_data_type_functions.py::test_iinfo[uint64] + array-api-tests/array_api_tests/test_statistical_functions.py::test_sum + array-api-tests/array_api_tests/test_type_promotion.py + + # PR #1000 any/all keepdim + array-api-tests/array_api_tests/test_linalg.py::test_matrix_transpose + array-api-tests/array_api_tests/test_operators_and_elementwise_functions.py::test_abs + array-api-tests/array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_left_shift + array-api-tests/array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_right_shift + array-api-tests/array_api_tests/test_operators_and_elementwise_functions.py::test_floor_divide + array-api-tests/array_api_tests/test_operators_and_elementwise_functions.py::test_positive + array-api-tests/array_api_tests/test_operators_and_elementwise_functions.py::test_pow + array-api-tests/array_api_tests/test_operators_and_elementwise_functions.py::test_remainder + + # PR #993 Precision loss + array-api-tests/array_api_tests/test_creation_functions.py::test_arange + array-api-tests/array_api_tests/test_creation_functions.py::test_linspace + + # PR #1018 __reduce_op bug + array-api-tests/array_api_tests/test_creation_functions.py::test_asarray_arrays + array-api-tests/array_api_tests/test_creation_functions.py::test_full + array-api-tests/array_api_tests/test_creation_functions.py::test_full_like + array-api-tests/array_api_tests/test_creation_functions.py::test_ones + array-api-tests/array_api_tests/test_creation_functions.py::test_ones_like + array-api-tests/array_api_tests/test_creation_functions.py::test_zeros + array-api-tests/array_api_tests/test_creation_functions.py::test_zeros_like + array-api-tests/array_api_tests/test_operators_and_elementwise_functions.py::test_negative + array-api-tests/array_api_tests/test_special_cases.py::test_empty_arrays[prod] + array-api-tests/array_api_tests/test_special_cases.py::test_nan_propagation[sum] + + # k not implemented + array-api-tests/array_api_tests/test_creation_functions.py::test_eye + + # PR #1020 broadcasting + array-api-tests/array_api_tests/test_data_type_functions.py::test_broadcast_arrays + array-api-tests/array_api_tests/test_data_type_functions.py::test_broadcast_to + + # PR #749 unique + array-api-tests/array_api_tests/test_set_functions.py::test_unique_all + array-api-tests/array_api_tests/test_set_functions.py::test_unique_counts + array-api-tests/array_api_tests/test_set_functions.py::test_unique_inverse + array-api-tests/array_api_tests/test_set_functions.py::test_unique_values + array-api-tests/array_api_tests/test_signatures.py::test_func_signature[unique_all] + array-api-tests/array_api_tests/test_signatures.py::test_func_signature[unique_counts] + array-api-tests/array_api_tests/test_sorting_functions.py::test_sort + + # PR #996 argsort + array-api-tests/array_api_tests/test_signatures.py::test_func_signature[argsort] + array-api-tests/array_api_tests/test_sorting_functions.py::test_argsort + + # tensordot + array-api-tests/array_api_tests/test_linalg.py::test_tensordot + + # Special cases + array-api-tests/array_api_tests/test_operators_and_elementwise_functions.py::test_square + array-api-tests/array_api_tests/test_special_cases.py::test_binary[floor_divide(x1_i is +infinity and isfinite(x2_i) and x2_i > 0) -> +infinity] + array-api-tests/array_api_tests/test_special_cases.py::test_binary[floor_divide(x1_i is +infinity and isfinite(x2_i) and x2_i < 0) -> -infinity] + array-api-tests/array_api_tests/test_special_cases.py::test_binary[floor_divide(x1_i is -infinity and isfinite(x2_i) and x2_i > 0) -> -infinity] + array-api-tests/array_api_tests/test_special_cases.py::test_binary[floor_divide(x1_i is -infinity and isfinite(x2_i) and x2_i < 0) -> +infinity] + array-api-tests/array_api_tests/test_special_cases.py::test_binary[floor_divide(isfinite(x1_i) and x1_i > 0 and x2_i is -infinity) -> -0] + array-api-tests/array_api_tests/test_special_cases.py::test_binary[floor_divide(isfinite(x1_i) and x1_i < 0 and x2_i is +infinity) -> -0] + array-api-tests/array_api_tests/test_special_cases.py::test_binary[__floordiv__(x1_i is +infinity and isfinite(x2_i) and x2_i > 0) -> +infinity] + array-api-tests/array_api_tests/test_special_cases.py::test_binary[__floordiv__(x1_i is +infinity and isfinite(x2_i) and x2_i < 0) -> -infinity] + array-api-tests/array_api_tests/test_special_cases.py::test_binary[__floordiv__(x1_i is -infinity and isfinite(x2_i) and x2_i > 0) -> -infinity] + array-api-tests/array_api_tests/test_special_cases.py::test_binary[__floordiv__(x1_i is -infinity and isfinite(x2_i) and x2_i < 0) -> +infinity] + array-api-tests/array_api_tests/test_special_cases.py::test_binary[__floordiv__(isfinite(x1_i) and x1_i > 0 and x2_i is -infinity) -> -0] + array-api-tests/array_api_tests/test_special_cases.py::test_binary[__floordiv__(isfinite(x1_i) and x1_i < 0 and x2_i is +infinity) -> -0] + array-api-tests/array_api_tests/test_special_cases.py::test_binary[remainder(x1_i is -0 and x2_i > 0) -> +0] + array-api-tests/array_api_tests/test_special_cases.py::test_binary[remainder(x1_i is +0 and x2_i < 0) -> -0] + array-api-tests/array_api_tests/test_special_cases.py::test_binary[__mod__(x1_i is -0 and x2_i > 0) -> +0] + array-api-tests/array_api_tests/test_special_cases.py::test_binary[__mod__(x1_i is +0 and x2_i < 0) -> -0] + array-api-tests/array_api_tests/test_special_cases.py::test_iop[__ifloordiv__(x1_i is +infinity and isfinite(x2_i) and x2_i > 0) -> +infinity] + array-api-tests/array_api_tests/test_special_cases.py::test_iop[__ifloordiv__(x1_i is +infinity and isfinite(x2_i) and x2_i < 0) -> -infinity] + array-api-tests/array_api_tests/test_special_cases.py::test_iop[__ifloordiv__(x1_i is -infinity and isfinite(x2_i) and x2_i > 0) -> -infinity] + array-api-tests/array_api_tests/test_special_cases.py::test_iop[__ifloordiv__(x1_i is -infinity and isfinite(x2_i) and x2_i < 0) -> +infinity] + array-api-tests/array_api_tests/test_special_cases.py::test_iop[__ifloordiv__(isfinite(x1_i) and x1_i > 0 and x2_i is -infinity) -> -0] + array-api-tests/array_api_tests/test_special_cases.py::test_iop[__ifloordiv__(isfinite(x1_i) and x1_i < 0 and x2_i is +infinity) -> -0] + array-api-tests/array_api_tests/test_special_cases.py::test_iop[__imod__(x1_i is -0 and x2_i > 0) -> +0] + array-api-tests/array_api_tests/test_special_cases.py::test_iop[__imod__(x1_i is +0 and x2_i < 0) -> -0] + # std special cases + array-api-tests/array_api_tests/test_statistical_functions.py::test_std + array-api-tests/array_api_tests/test_special_cases.py::test_empty_arrays[std] + array-api-tests/array_api_tests/test_special_cases.py::test_nan_propagation[std] \ No newline at end of file From 8d5946e1f8e2d2a6a3b497c1ba0c635eb8a29698 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 16 Feb 2024 15:09:28 +0000 Subject: [PATCH 098/150] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- heat/array_api/__init__.py | 1 + heat/array_api/linalg.py | 1 + skips.txt | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index 3806ee6a39..4250ed5c49 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -1,6 +1,7 @@ """ A Heat sub-namespace that conforms to the Python array API standard. """ + import warnings warnings.warn("The heat.array_api submodule is not fully implemented.", stacklevel=2) diff --git a/heat/array_api/linalg.py b/heat/array_api/linalg.py index d388552942..8f74bad03d 100644 --- a/heat/array_api/linalg.py +++ b/heat/array_api/linalg.py @@ -1,6 +1,7 @@ """ Linear Algebra Extension for the Array API standard. """ + from __future__ import annotations from ._dtypes import _numeric_dtypes, _result_type diff --git a/skips.txt b/skips.txt index 26745433d6..337aa8178f 100644 --- a/skips.txt +++ b/skips.txt @@ -115,4 +115,4 @@ # std special cases array-api-tests/array_api_tests/test_statistical_functions.py::test_std array-api-tests/array_api_tests/test_special_cases.py::test_empty_arrays[std] - array-api-tests/array_api_tests/test_special_cases.py::test_nan_propagation[std] \ No newline at end of file + array-api-tests/array_api_tests/test_special_cases.py::test_nan_propagation[std] From 7a56c52f630ed754d5a405c99eddc85082bb6e6e Mon Sep 17 00:00:00 2001 From: Michael Tarnawa Date: Mon, 19 Feb 2024 09:21:07 +0100 Subject: [PATCH 099/150] Update array-api.yml Retry test suite --- .github/workflows/array-api.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/array-api.yml b/.github/workflows/array-api.yml index 70fea71a56..9cd7b483d7 100644 --- a/.github/workflows/array-api.yml +++ b/.github/workflows/array-api.yml @@ -1,10 +1,11 @@ name: Test Array API on: + push # pull_request: # types: [opened, synchronize, reopened, labeled] - pull_request_review: - types: [submitted] + #pull_request_review: + # types: [submitted] jobs: build: From 19f5a7505fab8a8d9b0aab9725660a4879a06a67 Mon Sep 17 00:00:00 2001 From: Michael Tarnawa Date: Mon, 19 Feb 2024 13:38:26 +0100 Subject: [PATCH 100/150] Update array-api.yml --- .github/workflows/array-api.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/array-api.yml b/.github/workflows/array-api.yml index 9cd7b483d7..0f53aca87c 100644 --- a/.github/workflows/array-api.yml +++ b/.github/workflows/array-api.yml @@ -19,6 +19,8 @@ jobs: steps: - name: Checkout uses: actions/checkout@v3 + with: + path: heat - name: Setup MPI uses: mpi4py/setup-mpi@v1 with: @@ -36,7 +38,6 @@ jobs: uses: actions/checkout@v3 with: repository: data-apis/array-api-tests - ref: 2022.09.30 path: array-api-tests submodules: 'true' - name: Install dependencies @@ -46,6 +47,7 @@ jobs: env: ARRAY_API_TESTS_MODULE: heat.array_api run: | + export PYTHONPATH="${GITHUB_WORKSPACE}/heat" # Skip testing functions with known issues - - pytest array-api-tests/array_api_tests -v -rxXfE --ci --disable-extension linalg --skips-file skips.txt + cd ${GITHUB_WORKSPACE}/array-api-tests + pytest array-api-tests/ -v -rxXfE --ci --skips-file ${GITHUB_WORKSPACE}/heat/skips.txt From f729a4e51c58bf9c36f3a051cdd33bf2b9081ae3 Mon Sep 17 00:00:00 2001 From: Michael Tarnawa Date: Mon, 19 Feb 2024 13:56:50 +0100 Subject: [PATCH 101/150] Update array-api.yml --- .github/workflows/array-api.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/array-api.yml b/.github/workflows/array-api.yml index 0f53aca87c..19b1032261 100644 --- a/.github/workflows/array-api.yml +++ b/.github/workflows/array-api.yml @@ -33,7 +33,7 @@ jobs: - name: Install run: | python -m pip install --upgrade pip - python -m pip install . + python -m pip install heat/ - name: Checkout array-api-tests uses: actions/checkout@v3 with: From e8c9917df87f70667bc654fa88cfcb8ec47e81d6 Mon Sep 17 00:00:00 2001 From: Michael Tarnawa Date: Mon, 19 Feb 2024 14:20:35 +0100 Subject: [PATCH 102/150] Update array-api.yml --- .github/workflows/array-api.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/array-api.yml b/.github/workflows/array-api.yml index 19b1032261..5beddf7203 100644 --- a/.github/workflows/array-api.yml +++ b/.github/workflows/array-api.yml @@ -33,7 +33,7 @@ jobs: - name: Install run: | python -m pip install --upgrade pip - python -m pip install heat/ + python -m pip install ${GITHUB_WORKSPACE}/heat/ - name: Checkout array-api-tests uses: actions/checkout@v3 with: @@ -42,7 +42,7 @@ jobs: submodules: 'true' - name: Install dependencies run: | - python -m pip install -r array-api-tests/requirements.txt + python -m pip install -r ${GITHUB_WORKSPACE}/array-api-tests/requirements.txt - name: Run the test suite env: ARRAY_API_TESTS_MODULE: heat.array_api @@ -50,4 +50,4 @@ jobs: export PYTHONPATH="${GITHUB_WORKSPACE}/heat" # Skip testing functions with known issues cd ${GITHUB_WORKSPACE}/array-api-tests - pytest array-api-tests/ -v -rxXfE --ci --skips-file ${GITHUB_WORKSPACE}/heat/skips.txt + pytest -v -rxXfE --ci --skips-file ${GITHUB_WORKSPACE}/heat/skips.txt array-api-tests/ From 407adfb7ff9ed60c0af934c88836c69be3a36adc Mon Sep 17 00:00:00 2001 From: Michael Tarnawa Date: Mon, 19 Feb 2024 14:59:16 +0100 Subject: [PATCH 103/150] Update array-api.yml --- .github/workflows/array-api.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/array-api.yml b/.github/workflows/array-api.yml index 5beddf7203..128d80a1e6 100644 --- a/.github/workflows/array-api.yml +++ b/.github/workflows/array-api.yml @@ -50,4 +50,4 @@ jobs: export PYTHONPATH="${GITHUB_WORKSPACE}/heat" # Skip testing functions with known issues cd ${GITHUB_WORKSPACE}/array-api-tests - pytest -v -rxXfE --ci --skips-file ${GITHUB_WORKSPACE}/heat/skips.txt array-api-tests/ + pytest -v -rxXfE --ci --xfails-file ${GITHUB_WORKSPACE}/heat/skips.txt --disable-extension linalg array-api-tests/ From c2a91fe1a21ed2b6a5e359701526f8b9f6616a70 Mon Sep 17 00:00:00 2001 From: Michael Tarnawa Date: Mon, 19 Feb 2024 15:33:00 +0100 Subject: [PATCH 104/150] Update array-api.yml --- .github/workflows/array-api.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/array-api.yml b/.github/workflows/array-api.yml index 128d80a1e6..494088afe6 100644 --- a/.github/workflows/array-api.yml +++ b/.github/workflows/array-api.yml @@ -33,7 +33,7 @@ jobs: - name: Install run: | python -m pip install --upgrade pip - python -m pip install ${GITHUB_WORKSPACE}/heat/ + python -m pip install ${{ GITHUB_WORKSPACE }}/heat/ - name: Checkout array-api-tests uses: actions/checkout@v3 with: @@ -42,12 +42,12 @@ jobs: submodules: 'true' - name: Install dependencies run: | - python -m pip install -r ${GITHUB_WORKSPACE}/array-api-tests/requirements.txt + python -m pip install -r ${{ GITHUB_WORKSPACE }}/array-api-tests/requirements.txt - name: Run the test suite env: ARRAY_API_TESTS_MODULE: heat.array_api run: | - export PYTHONPATH="${GITHUB_WORKSPACE}/heat" + export PYTHONPATH="${{ GITHUB_WORKSPACE }}/heat" # Skip testing functions with known issues cd ${GITHUB_WORKSPACE}/array-api-tests - pytest -v -rxXfE --ci --xfails-file ${GITHUB_WORKSPACE}/heat/skips.txt --disable-extension linalg array-api-tests/ + pytest -v -rxXfE --ci --xfails-file ${{ GITHUB_WORKSPACE }}/heat/skips.txt --disable-extension linalg array-api-tests/ From b0e15c89dddf950e621ff8a2912b72e601a4f28c Mon Sep 17 00:00:00 2001 From: Michael Tarnawa Date: Tue, 20 Feb 2024 08:07:41 +0100 Subject: [PATCH 105/150] Update array-api.yml --- .github/workflows/array-api.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/array-api.yml b/.github/workflows/array-api.yml index 494088afe6..869c78b082 100644 --- a/.github/workflows/array-api.yml +++ b/.github/workflows/array-api.yml @@ -33,7 +33,7 @@ jobs: - name: Install run: | python -m pip install --upgrade pip - python -m pip install ${{ GITHUB_WORKSPACE }}/heat/ + python -m pip install ${{ github.workspace }}/heat/ - name: Checkout array-api-tests uses: actions/checkout@v3 with: @@ -42,12 +42,12 @@ jobs: submodules: 'true' - name: Install dependencies run: | - python -m pip install -r ${{ GITHUB_WORKSPACE }}/array-api-tests/requirements.txt + python -m pip install -r ${{ github.workspace }}/array-api-tests/requirements.txt - name: Run the test suite env: ARRAY_API_TESTS_MODULE: heat.array_api run: | - export PYTHONPATH="${{ GITHUB_WORKSPACE }}/heat" + export PYTHONPATH="${{ github.workspace }}/heat" # Skip testing functions with known issues cd ${GITHUB_WORKSPACE}/array-api-tests - pytest -v -rxXfE --ci --xfails-file ${{ GITHUB_WORKSPACE }}/heat/skips.txt --disable-extension linalg array-api-tests/ + pytest -v -rxXfE --ci --xfails-file ${{ github.workspace }}/heat/skips.txt --disable-extension linalg array-api-tests/ From 63442abac225fb9e003650a3d81655608e658f8e Mon Sep 17 00:00:00 2001 From: Michael Tarnawa Date: Tue, 20 Feb 2024 08:11:35 +0100 Subject: [PATCH 106/150] Update array-api.yml --- .github/workflows/array-api.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/array-api.yml b/.github/workflows/array-api.yml index 869c78b082..e2732927b9 100644 --- a/.github/workflows/array-api.yml +++ b/.github/workflows/array-api.yml @@ -50,4 +50,4 @@ jobs: export PYTHONPATH="${{ github.workspace }}/heat" # Skip testing functions with known issues cd ${GITHUB_WORKSPACE}/array-api-tests - pytest -v -rxXfE --ci --xfails-file ${{ github.workspace }}/heat/skips.txt --disable-extension linalg array-api-tests/ + pytest -v -rxXfE array-api-tests/ --ci --xfails-file ${{ github.workspace }}/heat/skips.txt --disable-extension linalg From 735314f5a2df3d2ae4cb7e29bcb7bb3ab165e148 Mon Sep 17 00:00:00 2001 From: Michael Tarnawa Date: Tue, 20 Feb 2024 08:19:26 +0100 Subject: [PATCH 107/150] Update array-api.yml --- .github/workflows/array-api.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/array-api.yml b/.github/workflows/array-api.yml index e2732927b9..9d81195c52 100644 --- a/.github/workflows/array-api.yml +++ b/.github/workflows/array-api.yml @@ -49,5 +49,5 @@ jobs: run: | export PYTHONPATH="${{ github.workspace }}/heat" # Skip testing functions with known issues - cd ${GITHUB_WORKSPACE}/array-api-tests + cd ${{ github.workspace }}/array-api-tests pytest -v -rxXfE array-api-tests/ --ci --xfails-file ${{ github.workspace }}/heat/skips.txt --disable-extension linalg From d12e877d779f368312ab7ea488b6f9bdda870508 Mon Sep 17 00:00:00 2001 From: Michael Tarnawa Date: Tue, 20 Feb 2024 08:26:04 +0100 Subject: [PATCH 108/150] Update array-api.yml --- .github/workflows/array-api.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/array-api.yml b/.github/workflows/array-api.yml index 9d81195c52..c9e231657b 100644 --- a/.github/workflows/array-api.yml +++ b/.github/workflows/array-api.yml @@ -50,4 +50,4 @@ jobs: export PYTHONPATH="${{ github.workspace }}/heat" # Skip testing functions with known issues cd ${{ github.workspace }}/array-api-tests - pytest -v -rxXfE array-api-tests/ --ci --xfails-file ${{ github.workspace }}/heat/skips.txt --disable-extension linalg + pytest -v -rxXfE --ci --xfails-file ${{ github.workspace }}/heat/skips.txt --disable-extension linalg array_api_tests/ From d5a0fee6123fa35e3f2f04e26b56afe97e1c5054 Mon Sep 17 00:00:00 2001 From: Michael Tarnawa Date: Tue, 20 Feb 2024 08:35:13 +0100 Subject: [PATCH 109/150] Update array-api.yml --- .github/workflows/array-api.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/array-api.yml b/.github/workflows/array-api.yml index c9e231657b..2a738f044e 100644 --- a/.github/workflows/array-api.yml +++ b/.github/workflows/array-api.yml @@ -50,4 +50,4 @@ jobs: export PYTHONPATH="${{ github.workspace }}/heat" # Skip testing functions with known issues cd ${{ github.workspace }}/array-api-tests - pytest -v -rxXfE --ci --xfails-file ${{ github.workspace }}/heat/skips.txt --disable-extension linalg array_api_tests/ + pytest -v -rxXfE --ci array_api_tests/ --skips-file ${{ github.workspace }}/heat/skips.txt --disable-extension linalg From a96e91adf8747424cdc1b1aab9e42049210de767 Mon Sep 17 00:00:00 2001 From: Michael Tarnawa Date: Tue, 20 Feb 2024 10:07:22 +0100 Subject: [PATCH 110/150] update skips file --- skips.txt | 216 +++++++++++++++++++++++++++--------------------------- 1 file changed, 109 insertions(+), 107 deletions(-) diff --git a/skips.txt b/skips.txt index 337aa8178f..04dc4bf2ed 100644 --- a/skips.txt +++ b/skips.txt @@ -1,118 +1,120 @@ +array_api_tests/test_fft.py + # PR #938 Indexing overhaul - array-api-tests/array_api_tests/test_array_object.py::test_getitem - array-api-tests/array_api_tests/test_array_object.py::test_setitem - array-api-tests/array_api_tests/test_array_object.py::test_getitem_masking - array-api-tests/array_api_tests/test_array_object.py::test_setitem_masking - array-api-tests/array_api_tests/test_linalg.py::test_matrix_matmul - array-api-tests/array_api_tests/test_manipulation_functions.py::test_concat - array-api-tests/array_api_tests/test_manipulation_functions.py::test_stack - array-api-tests/array_api_tests/test_searching_functions.py::test_argmax - array-api-tests/array_api_tests/test_searching_functions.py::test_argmin - array-api-tests/array_api_tests/test_searching_functions.py::test_nonzero - array-api-tests/array_api_tests/test_searching_functions.py::test_where - array-api-tests/array_api_tests/test_special_cases.py::test_nan_propagation[max] - array-api-tests/array_api_tests/test_special_cases.py::test_nan_propagation[min] - array-api-tests/array_api_tests/test_special_cases.py::test_nan_propagation[prod] - array-api-tests/array_api_tests/test_special_cases.py::test_nan_propagation[sum] - array-api-tests/array_api_tests/test_special_cases.py::test_binary[add(isfinite(x1_i) and x1_i != 0 and x2_i == -x1_i) -> +0] - array-api-tests/array_api_tests/test_special_cases.py::test_iop[__iadd__(isfinite(x1_i) and x1_i != 0 and x2_i == -x1_i) -> +0] - array-api-tests/array_api_tests/test_statistical_functions.py::test_max - array-api-tests/array_api_tests/test_statistical_functions.py::test_mean - array-api-tests/array_api_tests/test_statistical_functions.py::test_min - array-api-tests/array_api_tests/test_statistical_functions.py::test_prod - array-api-tests/array_api_tests/test_statistical_functions.py::test_var - array-api-tests/array_api_tests/test_utility_functions.py::test_all - array-api-tests/array_api_tests/test_utility_functions.py::test_any +array_api_tests/test_array_object.py::test_getitem +array_api_tests/test_array_object.py::test_setitem +array_api_tests/test_array_object.py::test_getitem_masking +array_api_tests/test_array_object.py::test_setitem_masking +array_api_tests/test_linalg.py::test_matrix_matmul +array_api_tests/test_manipulation_functions.py::test_concat +array_api_tests/test_manipulation_functions.py::test_stack +array_api_tests/test_searching_functions.py::test_argmax +array_api_tests/test_searching_functions.py::test_argmin +array_api_tests/test_searching_functions.py::test_nonzero +array_api_tests/test_searching_functions.py::test_where +array_api_tests/test_special_cases.py::test_nan_propagation[max] +array_api_tests/test_special_cases.py::test_nan_propagation[min] +array_api_tests/test_special_cases.py::test_nan_propagation[prod] +array_api_tests/test_special_cases.py::test_nan_propagation[sum] +array_api_tests/test_special_cases.py::test_binary[add(isfinite(x1_i) and x1_i != 0 and x2_i == -x1_i) -> +0] +array_api_tests/test_special_cases.py::test_iop[__iadd__(isfinite(x1_i) and x1_i != 0 and x2_i == -x1_i) -> +0] +array_api_tests/test_statistical_functions.py::test_max +array_api_tests/test_statistical_functions.py::test_mean +array_api_tests/test_statistical_functions.py::test_min +array_api_tests/test_statistical_functions.py::test_prod +array_api_tests/test_statistical_functions.py::test_var +array_api_tests/test_utility_functions.py::test_all +array_api_tests/test_utility_functions.py::test_any - # Pytorch dtypes https://github.com/pytorch/pytorch/issues/58734 - array-api-tests/array_api_tests/test_array_object.py::test_scalar_casting[__int__(uint16)] - array-api-tests/array_api_tests/test_array_object.py::test_scalar_casting[__int__(uint32)] - array-api-tests/array_api_tests/test_array_object.py::test_scalar_casting[__int__(uint64)] - array-api-tests/array_api_tests/test_array_object.py::test_scalar_casting[__index__(uint16)] - array-api-tests/array_api_tests/test_array_object.py::test_scalar_casting[__index__(uint32] - array-api-tests/array_api_tests/test_array_object.py::test_scalar_casting[__inndes__(uint64)] - array-api-tests/array_api_tests/test_data_type_functions.py::test_iinfo[uint16] - array-api-tests/array_api_tests/test_data_type_functions.py::test_iinfo[uint32] - array-api-tests/array_api_tests/test_data_type_functions.py::test_iinfo[uint64] - array-api-tests/array_api_tests/test_statistical_functions.py::test_sum - array-api-tests/array_api_tests/test_type_promotion.py +# Pytorch dtypes https://github.com/pytorch/pytorch/issues/58734 +array_api_tests/test_array_object.py::test_scalar_casting[__int__(uint16)] +array_api_tests/test_array_object.py::test_scalar_casting[__int__(uint32)] +array_api_tests/test_array_object.py::test_scalar_casting[__int__(uint64)] +array_api_tests/test_array_object.py::test_scalar_casting[__index__(uint16)] +array_api_tests/test_array_object.py::test_scalar_casting[__index__(uint32] +array_api_tests/test_array_object.py::test_scalar_casting[__inndes__(uint64)] +array_api_tests/test_data_type_functions.py::test_iinfo[uint16] +array_api_tests/test_data_type_functions.py::test_iinfo[uint32] +array_api_tests/test_data_type_functions.py::test_iinfo[uint64] +array_api_tests/test_statistical_functions.py::test_sum +array_api_tests/test_type_promotion.py - # PR #1000 any/all keepdim - array-api-tests/array_api_tests/test_linalg.py::test_matrix_transpose - array-api-tests/array_api_tests/test_operators_and_elementwise_functions.py::test_abs - array-api-tests/array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_left_shift - array-api-tests/array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_right_shift - array-api-tests/array_api_tests/test_operators_and_elementwise_functions.py::test_floor_divide - array-api-tests/array_api_tests/test_operators_and_elementwise_functions.py::test_positive - array-api-tests/array_api_tests/test_operators_and_elementwise_functions.py::test_pow - array-api-tests/array_api_tests/test_operators_and_elementwise_functions.py::test_remainder +# PR #1000 any/all keepdim +array_api_tests/test_linalg.py::test_matrix_transpose +array_api_tests/test_operators_and_elementwise_functions.py::test_abs +array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_left_shift +array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_right_shift +array_api_tests/test_operators_and_elementwise_functions.py::test_floor_divide +array_api_tests/test_operators_and_elementwise_functions.py::test_positive +array_api_tests/test_operators_and_elementwise_functions.py::test_pow +array_api_tests/test_operators_and_elementwise_functions.py::test_remainder - # PR #993 Precision loss - array-api-tests/array_api_tests/test_creation_functions.py::test_arange - array-api-tests/array_api_tests/test_creation_functions.py::test_linspace +# PR #993 Precision loss +array_api_tests/test_creation_functions.py::test_arange +array_api_tests/test_creation_functions.py::test_linspace - # PR #1018 __reduce_op bug - array-api-tests/array_api_tests/test_creation_functions.py::test_asarray_arrays - array-api-tests/array_api_tests/test_creation_functions.py::test_full - array-api-tests/array_api_tests/test_creation_functions.py::test_full_like - array-api-tests/array_api_tests/test_creation_functions.py::test_ones - array-api-tests/array_api_tests/test_creation_functions.py::test_ones_like - array-api-tests/array_api_tests/test_creation_functions.py::test_zeros - array-api-tests/array_api_tests/test_creation_functions.py::test_zeros_like - array-api-tests/array_api_tests/test_operators_and_elementwise_functions.py::test_negative - array-api-tests/array_api_tests/test_special_cases.py::test_empty_arrays[prod] - array-api-tests/array_api_tests/test_special_cases.py::test_nan_propagation[sum] +# PR #1018 __reduce_op bug +array_api_tests/test_creation_functions.py::test_asarray_arrays +array_api_tests/test_creation_functions.py::test_full +array_api_tests/test_creation_functions.py::test_full_like +array_api_tests/test_creation_functions.py::test_ones +array_api_tests/test_creation_functions.py::test_ones_like +array_api_tests/test_creation_functions.py::test_zeros +array_api_tests/test_creation_functions.py::test_zeros_like +array_api_tests/test_operators_and_elementwise_functions.py::test_negative +array_api_tests/test_special_cases.py::test_empty_arrays[prod] +array_api_tests/test_special_cases.py::test_nan_propagation[sum] - # k not implemented - array-api-tests/array_api_tests/test_creation_functions.py::test_eye +# k not implemented +array_api_tests/test_creation_functions.py::test_eye - # PR #1020 broadcasting - array-api-tests/array_api_tests/test_data_type_functions.py::test_broadcast_arrays - array-api-tests/array_api_tests/test_data_type_functions.py::test_broadcast_to +# PR #1020 broadcasting +array_api_tests/test_data_type_functions.py::test_broadcast_arrays +array_api_tests/test_data_type_functions.py::test_broadcast_to - # PR #749 unique - array-api-tests/array_api_tests/test_set_functions.py::test_unique_all - array-api-tests/array_api_tests/test_set_functions.py::test_unique_counts - array-api-tests/array_api_tests/test_set_functions.py::test_unique_inverse - array-api-tests/array_api_tests/test_set_functions.py::test_unique_values - array-api-tests/array_api_tests/test_signatures.py::test_func_signature[unique_all] - array-api-tests/array_api_tests/test_signatures.py::test_func_signature[unique_counts] - array-api-tests/array_api_tests/test_sorting_functions.py::test_sort +# PR #749 unique +array_api_tests/test_set_functions.py::test_unique_all +array_api_tests/test_set_functions.py::test_unique_counts +array_api_tests/test_set_functions.py::test_unique_inverse +array_api_tests/test_set_functions.py::test_unique_values +array_api_tests/test_signatures.py::test_func_signature[unique_all] +array_api_tests/test_signatures.py::test_func_signature[unique_counts] +array_api_tests/test_sorting_functions.py::test_sort - # PR #996 argsort - array-api-tests/array_api_tests/test_signatures.py::test_func_signature[argsort] - array-api-tests/array_api_tests/test_sorting_functions.py::test_argsort +# PR #996 argsort +array_api_tests/test_signatures.py::test_func_signature[argsort] +array_api_tests/test_sorting_functions.py::test_argsort - # tensordot - array-api-tests/array_api_tests/test_linalg.py::test_tensordot +# tensordot +array_api_tests/test_linalg.py::test_tensordot - # Special cases - array-api-tests/array_api_tests/test_operators_and_elementwise_functions.py::test_square - array-api-tests/array_api_tests/test_special_cases.py::test_binary[floor_divide(x1_i is +infinity and isfinite(x2_i) and x2_i > 0) -> +infinity] - array-api-tests/array_api_tests/test_special_cases.py::test_binary[floor_divide(x1_i is +infinity and isfinite(x2_i) and x2_i < 0) -> -infinity] - array-api-tests/array_api_tests/test_special_cases.py::test_binary[floor_divide(x1_i is -infinity and isfinite(x2_i) and x2_i > 0) -> -infinity] - array-api-tests/array_api_tests/test_special_cases.py::test_binary[floor_divide(x1_i is -infinity and isfinite(x2_i) and x2_i < 0) -> +infinity] - array-api-tests/array_api_tests/test_special_cases.py::test_binary[floor_divide(isfinite(x1_i) and x1_i > 0 and x2_i is -infinity) -> -0] - array-api-tests/array_api_tests/test_special_cases.py::test_binary[floor_divide(isfinite(x1_i) and x1_i < 0 and x2_i is +infinity) -> -0] - array-api-tests/array_api_tests/test_special_cases.py::test_binary[__floordiv__(x1_i is +infinity and isfinite(x2_i) and x2_i > 0) -> +infinity] - array-api-tests/array_api_tests/test_special_cases.py::test_binary[__floordiv__(x1_i is +infinity and isfinite(x2_i) and x2_i < 0) -> -infinity] - array-api-tests/array_api_tests/test_special_cases.py::test_binary[__floordiv__(x1_i is -infinity and isfinite(x2_i) and x2_i > 0) -> -infinity] - array-api-tests/array_api_tests/test_special_cases.py::test_binary[__floordiv__(x1_i is -infinity and isfinite(x2_i) and x2_i < 0) -> +infinity] - array-api-tests/array_api_tests/test_special_cases.py::test_binary[__floordiv__(isfinite(x1_i) and x1_i > 0 and x2_i is -infinity) -> -0] - array-api-tests/array_api_tests/test_special_cases.py::test_binary[__floordiv__(isfinite(x1_i) and x1_i < 0 and x2_i is +infinity) -> -0] - array-api-tests/array_api_tests/test_special_cases.py::test_binary[remainder(x1_i is -0 and x2_i > 0) -> +0] - array-api-tests/array_api_tests/test_special_cases.py::test_binary[remainder(x1_i is +0 and x2_i < 0) -> -0] - array-api-tests/array_api_tests/test_special_cases.py::test_binary[__mod__(x1_i is -0 and x2_i > 0) -> +0] - array-api-tests/array_api_tests/test_special_cases.py::test_binary[__mod__(x1_i is +0 and x2_i < 0) -> -0] - array-api-tests/array_api_tests/test_special_cases.py::test_iop[__ifloordiv__(x1_i is +infinity and isfinite(x2_i) and x2_i > 0) -> +infinity] - array-api-tests/array_api_tests/test_special_cases.py::test_iop[__ifloordiv__(x1_i is +infinity and isfinite(x2_i) and x2_i < 0) -> -infinity] - array-api-tests/array_api_tests/test_special_cases.py::test_iop[__ifloordiv__(x1_i is -infinity and isfinite(x2_i) and x2_i > 0) -> -infinity] - array-api-tests/array_api_tests/test_special_cases.py::test_iop[__ifloordiv__(x1_i is -infinity and isfinite(x2_i) and x2_i < 0) -> +infinity] - array-api-tests/array_api_tests/test_special_cases.py::test_iop[__ifloordiv__(isfinite(x1_i) and x1_i > 0 and x2_i is -infinity) -> -0] - array-api-tests/array_api_tests/test_special_cases.py::test_iop[__ifloordiv__(isfinite(x1_i) and x1_i < 0 and x2_i is +infinity) -> -0] - array-api-tests/array_api_tests/test_special_cases.py::test_iop[__imod__(x1_i is -0 and x2_i > 0) -> +0] - array-api-tests/array_api_tests/test_special_cases.py::test_iop[__imod__(x1_i is +0 and x2_i < 0) -> -0] - # std special cases - array-api-tests/array_api_tests/test_statistical_functions.py::test_std - array-api-tests/array_api_tests/test_special_cases.py::test_empty_arrays[std] - array-api-tests/array_api_tests/test_special_cases.py::test_nan_propagation[std] +# Special cases +array_api_tests/test_operators_and_elementwise_functions.py::test_square +array_api_tests/test_special_cases.py::test_binary[floor_divide(x1_i is +infinity and isfinite(x2_i) and x2_i > 0) -> +infinity] +array_api_tests/test_special_cases.py::test_binary[floor_divide(x1_i is +infinity and isfinite(x2_i) and x2_i < 0) -> -infinity] +array_api_tests/test_special_cases.py::test_binary[floor_divide(x1_i is -infinity and isfinite(x2_i) and x2_i > 0) -> -infinity] +array_api_tests/test_special_cases.py::test_binary[floor_divide(x1_i is -infinity and isfinite(x2_i) and x2_i < 0) -> +infinity] +array_api_tests/test_special_cases.py::test_binary[floor_divide(isfinite(x1_i) and x1_i > 0 and x2_i is -infinity) -> -0] +array_api_tests/test_special_cases.py::test_binary[floor_divide(isfinite(x1_i) and x1_i < 0 and x2_i is +infinity) -> -0] +array_api_tests/test_special_cases.py::test_binary[__floordiv__(x1_i is +infinity and isfinite(x2_i) and x2_i > 0) -> +infinity] +array_api_tests/test_special_cases.py::test_binary[__floordiv__(x1_i is +infinity and isfinite(x2_i) and x2_i < 0) -> -infinity] +array_api_tests/test_special_cases.py::test_binary[__floordiv__(x1_i is -infinity and isfinite(x2_i) and x2_i > 0) -> -infinity] +array_api_tests/test_special_cases.py::test_binary[__floordiv__(x1_i is -infinity and isfinite(x2_i) and x2_i < 0) -> +infinity] +array_api_tests/test_special_cases.py::test_binary[__floordiv__(isfinite(x1_i) and x1_i > 0 and x2_i is -infinity) -> -0] +array_api_tests/test_special_cases.py::test_binary[__floordiv__(isfinite(x1_i) and x1_i < 0 and x2_i is +infinity) -> -0] +array_api_tests/test_special_cases.py::test_binary[remainder(x1_i is -0 and x2_i > 0) -> +0] +array_api_tests/test_special_cases.py::test_binary[remainder(x1_i is +0 and x2_i < 0) -> -0] +array_api_tests/test_special_cases.py::test_binary[__mod__(x1_i is -0 and x2_i > 0) -> +0] +array_api_tests/test_special_cases.py::test_binary[__mod__(x1_i is +0 and x2_i < 0) -> -0] +array_api_tests/test_special_cases.py::test_iop[__ifloordiv__(x1_i is +infinity and isfinite(x2_i) and x2_i > 0) -> +infinity] +array_api_tests/test_special_cases.py::test_iop[__ifloordiv__(x1_i is +infinity and isfinite(x2_i) and x2_i < 0) -> -infinity] +array_api_tests/test_special_cases.py::test_iop[__ifloordiv__(x1_i is -infinity and isfinite(x2_i) and x2_i > 0) -> -infinity] +array_api_tests/test_special_cases.py::test_iop[__ifloordiv__(x1_i is -infinity and isfinite(x2_i) and x2_i < 0) -> +infinity] +array_api_tests/test_special_cases.py::test_iop[__ifloordiv__(isfinite(x1_i) and x1_i > 0 and x2_i is -infinity) -> -0] +array_api_tests/test_special_cases.py::test_iop[__ifloordiv__(isfinite(x1_i) and x1_i < 0 and x2_i is +infinity) -> -0] +array_api_tests/test_special_cases.py::test_iop[__imod__(x1_i is -0 and x2_i > 0) -> +0] +array_api_tests/test_special_cases.py::test_iop[__imod__(x1_i is +0 and x2_i < 0) -> -0] +# std special cases +array_api_tests/test_statistical_functions.py::test_std +array_api_tests/test_special_cases.py::test_empty_arrays[std] +array_api_tests/test_special_cases.py::test_nan_propagation[std] From 4b2c7df382137302cbf924f364f7ce54ad25bd9b Mon Sep 17 00:00:00 2001 From: Michael Tarnawa Date: Tue, 20 Feb 2024 10:34:22 +0100 Subject: [PATCH 111/150] Update array-api.yml --- .github/workflows/array-api.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/array-api.yml b/.github/workflows/array-api.yml index 2a738f044e..f6049d5a85 100644 --- a/.github/workflows/array-api.yml +++ b/.github/workflows/array-api.yml @@ -50,4 +50,4 @@ jobs: export PYTHONPATH="${{ github.workspace }}/heat" # Skip testing functions with known issues cd ${{ github.workspace }}/array-api-tests - pytest -v -rxXfE --ci array_api_tests/ --skips-file ${{ github.workspace }}/heat/skips.txt --disable-extension linalg + pytest array_api_tests/ -v -rxXfE --ci --skips-file ${{ github.workspace }}/heat/skips.txt --disable-extension linalg From 83bb9a4e82aed9cdc955a808147a33220be7fad4 Mon Sep 17 00:00:00 2001 From: Michael Tarnawa Date: Tue, 20 Feb 2024 10:48:52 +0100 Subject: [PATCH 112/150] Update array-api.yml --- .github/workflows/array-api.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/array-api.yml b/.github/workflows/array-api.yml index f6049d5a85..32f15f9087 100644 --- a/.github/workflows/array-api.yml +++ b/.github/workflows/array-api.yml @@ -46,6 +46,7 @@ jobs: - name: Run the test suite env: ARRAY_API_TESTS_MODULE: heat.array_api + ARRAY_API_TESTS_VERSION: "2021.12" run: | export PYTHONPATH="${{ github.workspace }}/heat" # Skip testing functions with known issues From 92eace9fb13359212ea69dd4ff57e434cae9f8f2 Mon Sep 17 00:00:00 2001 From: Michael Tarnawa Date: Tue, 20 Feb 2024 11:02:02 +0100 Subject: [PATCH 113/150] skips --- .github/workflows/array-api.yml | 1 - skips.txt | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/array-api.yml b/.github/workflows/array-api.yml index 32f15f9087..f6049d5a85 100644 --- a/.github/workflows/array-api.yml +++ b/.github/workflows/array-api.yml @@ -46,7 +46,6 @@ jobs: - name: Run the test suite env: ARRAY_API_TESTS_MODULE: heat.array_api - ARRAY_API_TESTS_VERSION: "2021.12" run: | export PYTHONPATH="${{ github.workspace }}/heat" # Skip testing functions with known issues diff --git a/skips.txt b/skips.txt index 04dc4bf2ed..991502e1ab 100644 --- a/skips.txt +++ b/skips.txt @@ -1,4 +1,4 @@ -array_api_tests/test_fft.py +array-api-tests/array_api_tests/test_fft.py # PR #938 Indexing overhaul array_api_tests/test_array_object.py::test_getitem From 59c64c620681d5eda015834973ab307d9522eae3 Mon Sep 17 00:00:00 2001 From: Michael Tarnawa Date: Tue, 20 Feb 2024 11:10:19 +0100 Subject: [PATCH 114/150] update skips.txt --- skips.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/skips.txt b/skips.txt index 991502e1ab..2808937016 100644 --- a/skips.txt +++ b/skips.txt @@ -1,4 +1,4 @@ -array-api-tests/array_api_tests/test_fft.py +array_api_tests/test_fft.py # PR #938 Indexing overhaul array_api_tests/test_array_object.py::test_getitem @@ -31,7 +31,7 @@ array_api_tests/test_array_object.py::test_scalar_casting[__int__(uint16)] array_api_tests/test_array_object.py::test_scalar_casting[__int__(uint32)] array_api_tests/test_array_object.py::test_scalar_casting[__int__(uint64)] array_api_tests/test_array_object.py::test_scalar_casting[__index__(uint16)] -array_api_tests/test_array_object.py::test_scalar_casting[__index__(uint32] +array_api_tests/test_array_object.py::test_scalar_casting[__index__(uint32)] array_api_tests/test_array_object.py::test_scalar_casting[__inndes__(uint64)] array_api_tests/test_data_type_functions.py::test_iinfo[uint16] array_api_tests/test_data_type_functions.py::test_iinfo[uint32] From 3b598266bee6453333dbaf1fbb142666d7c26832 Mon Sep 17 00:00:00 2001 From: Michael Tarnawa Date: Thu, 7 Mar 2024 14:29:03 +0100 Subject: [PATCH 115/150] Update skips.txt --- skips.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/skips.txt b/skips.txt index 2808937016..0ec5e70cf4 100644 --- a/skips.txt +++ b/skips.txt @@ -5,7 +5,7 @@ array_api_tests/test_array_object.py::test_getitem array_api_tests/test_array_object.py::test_setitem array_api_tests/test_array_object.py::test_getitem_masking array_api_tests/test_array_object.py::test_setitem_masking -array_api_tests/test_linalg.py::test_matrix_matmul +# array_api_tests/test_linalg.py::test_matrix_matmul array_api_tests/test_manipulation_functions.py::test_concat array_api_tests/test_manipulation_functions.py::test_stack array_api_tests/test_searching_functions.py::test_argmax @@ -40,7 +40,7 @@ array_api_tests/test_statistical_functions.py::test_sum array_api_tests/test_type_promotion.py # PR #1000 any/all keepdim -array_api_tests/test_linalg.py::test_matrix_transpose +# array_api_tests/test_linalg.py::test_matrix_transpose array_api_tests/test_operators_and_elementwise_functions.py::test_abs array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_left_shift array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_right_shift @@ -86,7 +86,7 @@ array_api_tests/test_signatures.py::test_func_signature[argsort] array_api_tests/test_sorting_functions.py::test_argsort # tensordot -array_api_tests/test_linalg.py::test_tensordot +# array_api_tests/test_linalg.py::test_tensordot # Special cases array_api_tests/test_operators_and_elementwise_functions.py::test_square From 6c62126767c77211d54892f367d02e6922671ffe Mon Sep 17 00:00:00 2001 From: Michael Tarnawa Date: Thu, 7 Mar 2024 15:21:42 +0100 Subject: [PATCH 116/150] Update skips.txt --- skips.txt | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/skips.txt b/skips.txt index 0ec5e70cf4..f600f1eea1 100644 --- a/skips.txt +++ b/skips.txt @@ -1,4 +1,14 @@ -array_api_tests/test_fft.py +# fft +array_api_tests/test_fft.py::test_fft +array_api_tests/test_fft.py::test_ifft +array_api_tests/test_fft.py::test_fftn +array_api_tests/test_fft.py::test_ifftn +array_api_tests/test_fft.py::test_rfft +array_api_tests/test_fft.py::test_irfft +array_api_tests/test_fft.py::test_rfftn +array_api_tests/test_fft.py::test_irfftn +array_api_tests/test_fft.py::test_hfft +array_api_tests/test_fft.py::test_ihfft # PR #938 Indexing overhaul array_api_tests/test_array_object.py::test_getitem From 714321115dce7db906af1e11874516c9c4479142 Mon Sep 17 00:00:00 2001 From: Michael Tarnawa Date: Fri, 8 Mar 2024 09:28:27 +0100 Subject: [PATCH 117/150] Update array-api.yml --- .github/workflows/array-api.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/array-api.yml b/.github/workflows/array-api.yml index f6049d5a85..f7ae057c8d 100644 --- a/.github/workflows/array-api.yml +++ b/.github/workflows/array-api.yml @@ -33,7 +33,7 @@ jobs: - name: Install run: | python -m pip install --upgrade pip - python -m pip install ${{ github.workspace }}/heat/ + python -m pip install ${GITHUB_WORKSPACE}/heat/ - name: Checkout array-api-tests uses: actions/checkout@v3 with: @@ -42,12 +42,12 @@ jobs: submodules: 'true' - name: Install dependencies run: | - python -m pip install -r ${{ github.workspace }}/array-api-tests/requirements.txt + python -m pip install -r ${GITHUB_WORKSPACE}/array-api-tests/requirements.txt - name: Run the test suite env: ARRAY_API_TESTS_MODULE: heat.array_api run: | - export PYTHONPATH="${{ github.workspace }}/heat" + export PYTHONPATH="${GITHUB_WORKSPACE}/heat" # Skip testing functions with known issues - cd ${{ github.workspace }}/array-api-tests - pytest array_api_tests/ -v -rxXfE --ci --skips-file ${{ github.workspace }}/heat/skips.txt --disable-extension linalg + cd ${GITHUB_WORKSPACE}/array-api-tests + pytest array_api_tests/ -v -rxXfE --ci --skips-file ${GITHUB_WORKSPACE}/heat/skips.txt --disable-extension linalg fft From 1522115a84477fd082c0ebccc07e6bfb7a9a27b4 Mon Sep 17 00:00:00 2001 From: Michael Tarnawa Date: Fri, 8 Mar 2024 09:58:15 +0100 Subject: [PATCH 118/150] Update array-api.yml --- .github/workflows/array-api.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/array-api.yml b/.github/workflows/array-api.yml index f7ae057c8d..1665859e02 100644 --- a/.github/workflows/array-api.yml +++ b/.github/workflows/array-api.yml @@ -40,6 +40,7 @@ jobs: repository: data-apis/array-api-tests path: array-api-tests submodules: 'true' + ref: '2022.09.30' - name: Install dependencies run: | python -m pip install -r ${GITHUB_WORKSPACE}/array-api-tests/requirements.txt From 463a205f0dcf85bfde8cef39df53854c080aa9a7 Mon Sep 17 00:00:00 2001 From: Michael Tarnawa Date: Fri, 8 Mar 2024 10:06:23 +0100 Subject: [PATCH 119/150] Update array-api.yml --- .github/workflows/array-api.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/array-api.yml b/.github/workflows/array-api.yml index 1665859e02..355d6e4de9 100644 --- a/.github/workflows/array-api.yml +++ b/.github/workflows/array-api.yml @@ -51,4 +51,4 @@ jobs: export PYTHONPATH="${GITHUB_WORKSPACE}/heat" # Skip testing functions with known issues cd ${GITHUB_WORKSPACE}/array-api-tests - pytest array_api_tests/ -v -rxXfE --ci --skips-file ${GITHUB_WORKSPACE}/heat/skips.txt --disable-extension linalg fft + pytest array_api_tests/ -v -rxXfE --ci --xfails-file ${GITHUB_WORKSPACE}/heat/skips.txt --disable-extension linalg fft From ff8fad116b8496fda6ee8bc7d927a146e427c44c Mon Sep 17 00:00:00 2001 From: Michael Tarnawa Date: Fri, 8 Mar 2024 10:20:44 +0100 Subject: [PATCH 120/150] Update array-api.yml --- .github/workflows/array-api.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/array-api.yml b/.github/workflows/array-api.yml index 355d6e4de9..b118672770 100644 --- a/.github/workflows/array-api.yml +++ b/.github/workflows/array-api.yml @@ -40,15 +40,16 @@ jobs: repository: data-apis/array-api-tests path: array-api-tests submodules: 'true' - ref: '2022.09.30' +# ref: '2022.09.30' - name: Install dependencies run: | python -m pip install -r ${GITHUB_WORKSPACE}/array-api-tests/requirements.txt - name: Run the test suite env: ARRAY_API_TESTS_MODULE: heat.array_api + ARRAY_API_TESTS_VERSION: "2021.12" run: | export PYTHONPATH="${GITHUB_WORKSPACE}/heat" # Skip testing functions with known issues cd ${GITHUB_WORKSPACE}/array-api-tests - pytest array_api_tests/ -v -rxXfE --ci --xfails-file ${GITHUB_WORKSPACE}/heat/skips.txt --disable-extension linalg fft + pytest array_api_tests/ -v -rxXfE --ci --skips-file ${GITHUB_WORKSPACE}/heat/skips.txt --disable-extension linalg fft From 3910263c5bc29c8b12a773ebc8b22a7251c903d2 Mon Sep 17 00:00:00 2001 From: Michael Tarnawa Date: Fri, 8 Mar 2024 10:25:40 +0100 Subject: [PATCH 121/150] Update array-api.yml --- .github/workflows/array-api.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/array-api.yml b/.github/workflows/array-api.yml index b118672770..bbc5bd555c 100644 --- a/.github/workflows/array-api.yml +++ b/.github/workflows/array-api.yml @@ -47,7 +47,7 @@ jobs: - name: Run the test suite env: ARRAY_API_TESTS_MODULE: heat.array_api - ARRAY_API_TESTS_VERSION: "2021.12" + ARRAY_API_TESTS_VERSION: "2022.12" run: | export PYTHONPATH="${GITHUB_WORKSPACE}/heat" # Skip testing functions with known issues From 70aa22bce04d69718cc5dc52aa920f8995dd0949 Mon Sep 17 00:00:00 2001 From: Michael Tarnawa Date: Fri, 8 Mar 2024 11:54:28 +0100 Subject: [PATCH 122/150] Update array-api.yml --- .github/workflows/array-api.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/array-api.yml b/.github/workflows/array-api.yml index bbc5bd555c..8137fcac16 100644 --- a/.github/workflows/array-api.yml +++ b/.github/workflows/array-api.yml @@ -52,4 +52,4 @@ jobs: export PYTHONPATH="${GITHUB_WORKSPACE}/heat" # Skip testing functions with known issues cd ${GITHUB_WORKSPACE}/array-api-tests - pytest array_api_tests/ -v -rxXfE --ci --skips-file ${GITHUB_WORKSPACE}/heat/skips.txt --disable-extension linalg fft + pytest -v -rxXfE --ci --skips-file ${GITHUB_WORKSPACE}/heat/skips.txt --disable-extension linalg fft array_api_tests/ From c79f4beea3e0fbed19df4520a5134842a3c2f4fc Mon Sep 17 00:00:00 2001 From: Michael Tarnawa Date: Fri, 8 Mar 2024 11:58:23 +0100 Subject: [PATCH 123/150] Update array-api.yml --- .github/workflows/array-api.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/array-api.yml b/.github/workflows/array-api.yml index 8137fcac16..bbc5bd555c 100644 --- a/.github/workflows/array-api.yml +++ b/.github/workflows/array-api.yml @@ -52,4 +52,4 @@ jobs: export PYTHONPATH="${GITHUB_WORKSPACE}/heat" # Skip testing functions with known issues cd ${GITHUB_WORKSPACE}/array-api-tests - pytest -v -rxXfE --ci --skips-file ${GITHUB_WORKSPACE}/heat/skips.txt --disable-extension linalg fft array_api_tests/ + pytest array_api_tests/ -v -rxXfE --ci --skips-file ${GITHUB_WORKSPACE}/heat/skips.txt --disable-extension linalg fft From c17464d302ea886bdd9e2291bfa6ac6e2751f47c Mon Sep 17 00:00:00 2001 From: Michael Tarnawa Date: Fri, 8 Mar 2024 14:03:59 +0100 Subject: [PATCH 124/150] Update __init__.py --- heat/array_api/__init__.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index 4250ed5c49..e1eef32c20 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -6,7 +6,9 @@ warnings.warn("The heat.array_api submodule is not fully implemented.", stacklevel=2) -__all__ = [] +__array_api_version__ = "2022.12" + +__all__ = ["__array_api_version__"] from ._constants import e, inf, nan, newaxis, pi From 4fedbfe54fd9fa9c4a62dc3a2e3ce76293517b13 Mon Sep 17 00:00:00 2001 From: Michael Tarnawa Date: Mon, 11 Mar 2024 13:52:20 +0100 Subject: [PATCH 125/150] skip failing tests --- .github/workflows/array-api.yml | 6 +- heat/array_api/test/skips.txt | 578 ++++++++++++++++++++++++++++++++ skips.txt | 130 ------- 3 files changed, 580 insertions(+), 134 deletions(-) create mode 100644 heat/array_api/test/skips.txt delete mode 100644 skips.txt diff --git a/.github/workflows/array-api.yml b/.github/workflows/array-api.yml index bbc5bd555c..a53603d32d 100644 --- a/.github/workflows/array-api.yml +++ b/.github/workflows/array-api.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: [3.9, '3.10'] + python-version: ['3.9', '3.10', '3.11'] mpi: [ 'openmpi' ] steps: @@ -40,16 +40,14 @@ jobs: repository: data-apis/array-api-tests path: array-api-tests submodules: 'true' -# ref: '2022.09.30' - name: Install dependencies run: | python -m pip install -r ${GITHUB_WORKSPACE}/array-api-tests/requirements.txt - name: Run the test suite env: ARRAY_API_TESTS_MODULE: heat.array_api - ARRAY_API_TESTS_VERSION: "2022.12" run: | export PYTHONPATH="${GITHUB_WORKSPACE}/heat" # Skip testing functions with known issues cd ${GITHUB_WORKSPACE}/array-api-tests - pytest array_api_tests/ -v -rxXfE --ci --skips-file ${GITHUB_WORKSPACE}/heat/skips.txt --disable-extension linalg fft + pytest array_api_tests/ -v -rxXfE --ci --skips-file ${GITHUB_WORKSPACE}/heat/array_api/test/skips.txt diff --git a/heat/array_api/test/skips.txt b/heat/array_api/test/skips.txt new file mode 100644 index 0000000000..f5db3e8dd9 --- /dev/null +++ b/heat/array_api/test/skips.txt @@ -0,0 +1,578 @@ +# fft +array_api_tests/test_fft.py::test_fft +array_api_tests/test_fft.py::test_ifft +array_api_tests/test_fft.py::test_fftn +array_api_tests/test_fft.py::test_ifftn +array_api_tests/test_fft.py::test_rfft +array_api_tests/test_fft.py::test_irfft +array_api_tests/test_fft.py::test_rfftn +array_api_tests/test_fft.py::test_irfftn +array_api_tests/test_fft.py::test_hfft +array_api_tests/test_fft.py::test_ihfft + +# PR #938 Indexing overhaul +array_api_tests/test_array_object.py::test_getitem +array_api_tests/test_array_object.py::test_setitem +array_api_tests/test_array_object.py::test_getitem_masking +array_api_tests/test_array_object.py::test_setitem_masking +# array_api_tests/test_linalg.py::test_matrix_matmul +array_api_tests/test_manipulation_functions.py::test_concat +array_api_tests/test_manipulation_functions.py::test_stack +array_api_tests/test_searching_functions.py::test_argmax +array_api_tests/test_searching_functions.py::test_argmin +array_api_tests/test_searching_functions.py::test_nonzero +array_api_tests/test_searching_functions.py::test_where +array_api_tests/test_special_cases.py::test_nan_propagation[max] +array_api_tests/test_special_cases.py::test_nan_propagation[min] +array_api_tests/test_special_cases.py::test_nan_propagation[prod] +array_api_tests/test_special_cases.py::test_nan_propagation[sum] +array_api_tests/test_special_cases.py::test_binary[add(isfinite(x1_i) and x1_i != 0 and x2_i == -x1_i) -> +0] +array_api_tests/test_special_cases.py::test_iop[__iadd__(isfinite(x1_i) and x1_i != 0 and x2_i == -x1_i) -> +0] +array_api_tests/test_statistical_functions.py::test_max +array_api_tests/test_statistical_functions.py::test_mean +array_api_tests/test_statistical_functions.py::test_min +array_api_tests/test_statistical_functions.py::test_prod +array_api_tests/test_statistical_functions.py::test_var +array_api_tests/test_utility_functions.py::test_all +array_api_tests/test_utility_functions.py::test_any + +# Pytorch dtypes https://github.com/pytorch/pytorch/issues/58734 +array_api_tests/test_array_object.py::test_scalar_casting[__int__(uint16)] +array_api_tests/test_array_object.py::test_scalar_casting[__int__(uint32)] +array_api_tests/test_array_object.py::test_scalar_casting[__int__(uint64)] +array_api_tests/test_array_object.py::test_scalar_casting[__index__(uint16)] +array_api_tests/test_array_object.py::test_scalar_casting[__index__(uint32)] +array_api_tests/test_array_object.py::test_scalar_casting[__index__(uint64)] +array_api_tests/test_data_type_functions.py::test_iinfo[uint16] +array_api_tests/test_data_type_functions.py::test_iinfo[uint32] +array_api_tests/test_data_type_functions.py::test_iinfo[uint64] +array_api_tests/test_statistical_functions.py::test_sum +array_api_tests/test_type_promotion.py + +# PR #1000 any/all keepdim +# array_api_tests/test_linalg.py::test_matrix_transpose +array_api_tests/test_operators_and_elementwise_functions.py::test_abs +array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_left_shift +array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_right_shift +array_api_tests/test_operators_and_elementwise_functions.py::test_floor_divide +array_api_tests/test_operators_and_elementwise_functions.py::test_positive +array_api_tests/test_operators_and_elementwise_functions.py::test_pow +array_api_tests/test_operators_and_elementwise_functions.py::test_remainder + +# PR #993 Precision loss +array_api_tests/test_creation_functions.py::test_arange +array_api_tests/test_creation_functions.py::test_linspace + +# PR #1018 __reduce_op bug +array_api_tests/test_creation_functions.py::test_asarray_arrays +array_api_tests/test_creation_functions.py::test_full +array_api_tests/test_creation_functions.py::test_full_like +array_api_tests/test_creation_functions.py::test_ones +array_api_tests/test_creation_functions.py::test_ones_like +array_api_tests/test_creation_functions.py::test_zeros +array_api_tests/test_creation_functions.py::test_zeros_like +array_api_tests/test_operators_and_elementwise_functions.py::test_negative +array_api_tests/test_special_cases.py::test_empty_arrays[prod] +array_api_tests/test_special_cases.py::test_nan_propagation[sum] + +# k not implemented +array_api_tests/test_creation_functions.py::test_eye + +# PR #1020 broadcasting +array_api_tests/test_data_type_functions.py::test_broadcast_arrays +array_api_tests/test_data_type_functions.py::test_broadcast_to + +# PR #749 unique +array_api_tests/test_set_functions.py::test_unique_all +array_api_tests/test_set_functions.py::test_unique_counts +array_api_tests/test_set_functions.py::test_unique_inverse +array_api_tests/test_set_functions.py::test_unique_values +array_api_tests/test_signatures.py::test_func_signature[unique_all] +array_api_tests/test_signatures.py::test_func_signature[unique_counts] +array_api_tests/test_sorting_functions.py::test_sort + +# PR #996 argsort +array_api_tests/test_signatures.py::test_func_signature[argsort] +array_api_tests/test_sorting_functions.py::test_argsort + +# tensordot +# array_api_tests/test_linalg.py::test_tensordot + +# Special cases +array_api_tests/test_operators_and_elementwise_functions.py::test_square +array_api_tests/test_special_cases.py::test_binary[floor_divide(x1_i is +infinity and isfinite(x2_i) and x2_i > 0) -> +infinity] +array_api_tests/test_special_cases.py::test_binary[floor_divide(x1_i is +infinity and isfinite(x2_i) and x2_i < 0) -> -infinity] +array_api_tests/test_special_cases.py::test_binary[floor_divide(x1_i is -infinity and isfinite(x2_i) and x2_i > 0) -> -infinity] +array_api_tests/test_special_cases.py::test_binary[floor_divide(x1_i is -infinity and isfinite(x2_i) and x2_i < 0) -> +infinity] +array_api_tests/test_special_cases.py::test_binary[floor_divide(isfinite(x1_i) and x1_i > 0 and x2_i is -infinity) -> -0] +array_api_tests/test_special_cases.py::test_binary[floor_divide(isfinite(x1_i) and x1_i < 0 and x2_i is +infinity) -> -0] +array_api_tests/test_special_cases.py::test_binary[__floordiv__(x1_i is +infinity and isfinite(x2_i) and x2_i > 0) -> +infinity] +array_api_tests/test_special_cases.py::test_binary[__floordiv__(x1_i is +infinity and isfinite(x2_i) and x2_i < 0) -> -infinity] +array_api_tests/test_special_cases.py::test_binary[__floordiv__(x1_i is -infinity and isfinite(x2_i) and x2_i > 0) -> -infinity] +array_api_tests/test_special_cases.py::test_binary[__floordiv__(x1_i is -infinity and isfinite(x2_i) and x2_i < 0) -> +infinity] +array_api_tests/test_special_cases.py::test_binary[__floordiv__(isfinite(x1_i) and x1_i > 0 and x2_i is -infinity) -> -0] +array_api_tests/test_special_cases.py::test_binary[__floordiv__(isfinite(x1_i) and x1_i < 0 and x2_i is +infinity) -> -0] +array_api_tests/test_special_cases.py::test_binary[remainder(x1_i is -0 and x2_i > 0) -> +0] +array_api_tests/test_special_cases.py::test_binary[remainder(x1_i is +0 and x2_i < 0) -> -0] +array_api_tests/test_special_cases.py::test_binary[__mod__(x1_i is -0 and x2_i > 0) -> +0] +array_api_tests/test_special_cases.py::test_binary[__mod__(x1_i is +0 and x2_i < 0) -> -0] +array_api_tests/test_special_cases.py::test_iop[__ifloordiv__(x1_i is +infinity and isfinite(x2_i) and x2_i > 0) -> +infinity] +array_api_tests/test_special_cases.py::test_iop[__ifloordiv__(x1_i is +infinity and isfinite(x2_i) and x2_i < 0) -> -infinity] +array_api_tests/test_special_cases.py::test_iop[__ifloordiv__(x1_i is -infinity and isfinite(x2_i) and x2_i > 0) -> -infinity] +array_api_tests/test_special_cases.py::test_iop[__ifloordiv__(x1_i is -infinity and isfinite(x2_i) and x2_i < 0) -> +infinity] +array_api_tests/test_special_cases.py::test_iop[__ifloordiv__(isfinite(x1_i) and x1_i > 0 and x2_i is -infinity) -> -0] +array_api_tests/test_special_cases.py::test_iop[__ifloordiv__(isfinite(x1_i) and x1_i < 0 and x2_i is +infinity) -> -0] +array_api_tests/test_special_cases.py::test_iop[__imod__(x1_i is -0 and x2_i > 0) -> +0] +array_api_tests/test_special_cases.py::test_iop[__imod__(x1_i is +0 and x2_i < 0) -> -0] +# std special cases +array_api_tests/test_statistical_functions.py::test_std +array_api_tests/test_special_cases.py::test_empty_arrays[std] +array_api_tests/test_special_cases.py::test_nan_propagation[std] + +# skip FAILED tests +array_api_tests/test_array_object.py::test_scalar_casting[__float__(float64)] +array_api_tests/test_creation_functions.py::test_asarray_scalars +array_api_tests/test_creation_functions.py::test_empty +array_api_tests/test_creation_functions.py::test_empty_like +array_api_tests/test_creation_functions.py::test_meshgrid +array_api_tests/test_data_type_functions.py::test_astype +array_api_tests/test_data_type_functions.py::test_can_cast +array_api_tests/test_data_type_functions.py::test_finfo[float32] +array_api_tests/test_data_type_functions.py::test_finfo[float64] +array_api_tests/test_data_type_functions.py::test_iinfo[uint8] +array_api_tests/test_data_type_functions.py::test_iinfo[int8] +array_api_tests/test_data_type_functions.py::test_iinfo[int16] +array_api_tests/test_data_type_functions.py::test_iinfo[int32] +array_api_tests/test_data_type_functions.py::test_iinfo[int64] +array_api_tests/test_data_type_functions.py::test_isdtype +array_api_tests/test_has_names.py::test_has_names[linalg-cholesky] +array_api_tests/test_has_names.py::test_has_names[linalg-cross] +array_api_tests/test_has_names.py::test_has_names[linalg-cholesky] +array_api_tests/test_has_names.py::test_has_names[linalg-cross] +array_api_tests/test_has_names.py::test_has_names[linalg-det] +array_api_tests/test_has_names.py::test_has_names[linalg-diagonal] +array_api_tests/test_has_names.py::test_has_names[linalg-eigh] +array_api_tests/test_has_names.py::test_has_names[linalg-eigvalsh] +array_api_tests/test_has_names.py::test_has_names[linalg-inv] +array_api_tests/test_has_names.py::test_has_names[linalg-matrix_norm] +array_api_tests/test_has_names.py::test_has_names[linalg-matrix_power] +array_api_tests/test_has_names.py::test_has_names[linalg-matrix_rank] +array_api_tests/test_has_names.py::test_has_names[linalg-outer] +array_api_tests/test_has_names.py::test_has_names[linalg-pinv] +array_api_tests/test_has_names.py::test_has_names[linalg-qr] +array_api_tests/test_has_names.py::test_has_names[linalg-slogdet] +array_api_tests/test_has_names.py::test_has_names[linalg-solve] +array_api_tests/test_has_names.py::test_has_names[linalg-svd] +array_api_tests/test_has_names.py::test_has_names[linalg-svdvals] +array_api_tests/test_has_names.py::test_has_names[linalg-trace] +array_api_tests/test_has_names.py::test_has_names[linalg-vector_norm] +array_api_tests/test_has_names.py::test_has_names[data_type-isdtype] +array_api_tests/test_has_names.py::test_has_names[indexing-take] +array_api_tests/test_has_names.py::test_has_names[sorting-argsort] +array_api_tests/test_has_names.py::test_has_names[set-unique_all] +array_api_tests/test_has_names.py::test_has_names[set-unique_counts] +array_api_tests/test_has_names.py::test_has_names[elementwise-conj] +array_api_tests/test_has_names.py::test_has_names[elementwise-imag] +array_api_tests/test_has_names.py::test_has_names[elementwise-real] +array_api_tests/test_has_names.py::test_has_names[array_method-__complex__] +array_api_tests/test_indexing_functions.py::test_take +array_api_tests/test_linalg.py::test_matmul +array_api_tests/test_linalg.py::test_matrix_transpose +array_api_tests/test_linalg.py::test_tensordot +array_api_tests/test_linalg.py::test_vecdot +array_api_tests/test_manipulation_functions.py::test_expand_dims +array_api_tests/test_manipulation_functions.py::test_squeeze +array_api_tests/test_manipulation_functions.py::test_flip +array_api_tests/test_manipulation_functions.py::test_permute_dims +array_api_tests/test_manipulation_functions.py::test_roll +array_api_tests/test_operators_and_elementwise_functions.py::test_acos +array_api_tests/test_operators_and_elementwise_functions.py::test_acosh +array_api_tests/test_operators_and_elementwise_functions.py::test_add[add(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_add[__add__(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_add[__add__(x, s)] +array_api_tests/test_operators_and_elementwise_functions.py::test_add[__iadd__(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_asin +array_api_tests/test_operators_and_elementwise_functions.py::test_asinh +array_api_tests/test_operators_and_elementwise_functions.py::test_atan +array_api_tests/test_operators_and_elementwise_functions.py::test_atan2 +array_api_tests/test_operators_and_elementwise_functions.py::test_atanh +array_api_tests/test_operators_and_elementwise_functions.py::test_ceil +array_api_tests/test_operators_and_elementwise_functions.py::test_conj +array_api_tests/test_operators_and_elementwise_functions.py::test_cos +array_api_tests/test_operators_and_elementwise_functions.py::test_cosh +array_api_tests/test_operators_and_elementwise_functions.py::test_divide[divide(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_divide[__truediv__(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_divide[__truediv__(x, s)] +array_api_tests/test_operators_and_elementwise_functions.py::test_divide[__itruediv__(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_divide[__itruediv__(x, s)] +array_api_tests/test_operators_and_elementwise_functions.py::test_equal[equal(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_equal[__eq__(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_equal[__eq__(x, s)] +array_api_tests/test_operators_and_elementwise_functions.py::test_exp +array_api_tests/test_operators_and_elementwise_functions.py::test_expm1 +array_api_tests/test_operators_and_elementwise_functions.py::test_floor +array_api_tests/test_operators_and_elementwise_functions.py::test_greater[greater(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_greater[__gt__(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_greater_equal[greater_equal(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_greater_equal[__ge__(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_greater_equal[__ge__(x, s)] +array_api_tests/test_operators_and_elementwise_functions.py::test_imag +array_api_tests/test_operators_and_elementwise_functions.py::test_isfinite +array_api_tests/test_operators_and_elementwise_functions.py::test_isinf +array_api_tests/test_operators_and_elementwise_functions.py::test_isnan +array_api_tests/test_operators_and_elementwise_functions.py::test_less[less(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_less[__lt__(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_less[__lt__(x, s)] +array_api_tests/test_operators_and_elementwise_functions.py::test_less_equal[less_equal(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_less_equal[__le__(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_less_equal[__le__(x, s)] +array_api_tests/test_operators_and_elementwise_functions.py::test_log +array_api_tests/test_operators_and_elementwise_functions.py::test_log1p +array_api_tests/test_operators_and_elementwise_functions.py::test_log2 +array_api_tests/test_operators_and_elementwise_functions.py::test_log10 +array_api_tests/test_operators_and_elementwise_functions.py::test_logaddexp +array_api_tests/test_operators_and_elementwise_functions.py::test_multiply[multiply(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_multiply[__mul__(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_multiply[__mul__(x, s)] +array_api_tests/test_operators_and_elementwise_functions.py::test_multiply[__imul__(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_not_equal[not_equal(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_not_equal[__ne__(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_not_equal[__ne__(x, s)] +array_api_tests/test_operators_and_elementwise_functions.py::test_real +array_api_tests/test_operators_and_elementwise_functions.py::test_round +array_api_tests/test_operators_and_elementwise_functions.py::test_sign +array_api_tests/test_operators_and_elementwise_functions.py::test_sin +array_api_tests/test_operators_and_elementwise_functions.py::test_sinh +array_api_tests/test_operators_and_elementwise_functions.py::test_sqrt +array_api_tests/test_operators_and_elementwise_functions.py::test_subtract[subtract(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_subtract[__sub__(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_subtract[__sub__(x, s)] +array_api_tests/test_operators_and_elementwise_functions.py::test_subtract[__isub__(x, s)] +array_api_tests/test_operators_and_elementwise_functions.py::test_tan +array_api_tests/test_operators_and_elementwise_functions.py::test_tanh +array_api_tests/test_operators_and_elementwise_functions.py::test_trunc +array_api_tests/test_signatures.py::test_func_signature[isdtype] +array_api_tests/test_signatures.py::test_func_signature[take] +array_api_tests/test_signatures.py::test_func_signature[conj] +array_api_tests/test_signatures.py::test_func_signature[imag] +array_api_tests/test_signatures.py::test_func_signature[real] +array_api_tests/test_signatures.py::test_array_method_signature[__complex__] +array_api_tests/test_special_cases.py::test_unary[abs(x_i is NaN) -> NaN] +array_api_tests/test_special_cases.py::test_unary[abs(x_i is -0) -> +0] +array_api_tests/test_special_cases.py::test_unary[abs(x_i is -infinity) -> +infinity] +array_api_tests/test_special_cases.py::test_unary[__abs__(x_i is NaN) -> NaN] +array_api_tests/test_special_cases.py::test_unary[__abs__(x_i is -0) -> +0] +array_api_tests/test_special_cases.py::test_unary[__abs__(x_i is -infinity) -> +infinity] +array_api_tests/test_special_cases.py::test_unary[acos(x_i is NaN) -> NaN] +array_api_tests/test_special_cases.py::test_unary[acos(x_i > 1) -> NaN] +array_api_tests/test_special_cases.py::test_unary[acos(x_i < -1) -> NaN] +array_api_tests/test_special_cases.py::test_unary[acos(x_i is 1) -> +0] +array_api_tests/test_special_cases.py::test_unary[acosh(x_i is NaN) -> NaN] +array_api_tests/test_special_cases.py::test_unary[acosh(x_i < 1) -> NaN] +array_api_tests/test_special_cases.py::test_unary[acosh(x_i is 1) -> +0] +array_api_tests/test_special_cases.py::test_unary[acosh(x_i is +infinity) -> +infinity] +array_api_tests/test_special_cases.py::test_unary[asin(x_i is NaN) -> NaN] +array_api_tests/test_special_cases.py::test_unary[asin(x_i > 1) -> NaN] +array_api_tests/test_special_cases.py::test_unary[asin(x_i < -1) -> NaN] +array_api_tests/test_special_cases.py::test_unary[asin(x_i is +0) -> +0] +array_api_tests/test_special_cases.py::test_unary[asin(x_i is -0) -> -0] +array_api_tests/test_special_cases.py::test_unary[asinh(x_i is NaN) -> NaN] +array_api_tests/test_special_cases.py::test_unary[asinh(x_i is +0) -> +0] +array_api_tests/test_special_cases.py::test_unary[asinh(x_i is -0) -> -0] +array_api_tests/test_special_cases.py::test_unary[asinh(x_i is +infinity) -> +infinity] +array_api_tests/test_special_cases.py::test_unary[asinh(x_i is -infinity) -> -infinity] +array_api_tests/test_special_cases.py::test_unary[atan(x_i is NaN) -> NaN] +array_api_tests/test_special_cases.py::test_unary[atan(x_i is +0) -> +0] +array_api_tests/test_special_cases.py::test_unary[atan(x_i is -0) -> -0] +array_api_tests/test_special_cases.py::test_unary[atan(x_i is +infinity) -> roughly +pi/2] +array_api_tests/test_special_cases.py::test_unary[atan(x_i is -infinity) -> roughly -pi/2] +array_api_tests/test_special_cases.py::test_unary[atanh(x_i is NaN) -> NaN] +array_api_tests/test_special_cases.py::test_unary[atanh(x_i < -1) -> NaN] +array_api_tests/test_special_cases.py::test_unary[atanh(x_i > 1) -> NaN] +array_api_tests/test_special_cases.py::test_unary[atanh(x_i is -1) -> -infinity] +array_api_tests/test_special_cases.py::test_unary[atanh(x_i is +1) -> +infinity] +array_api_tests/test_special_cases.py::test_unary[atanh(x_i is +0) -> +0] +array_api_tests/test_special_cases.py::test_unary[atanh(x_i is -0) -> -0] +array_api_tests/test_special_cases.py::test_unary[ceil(x_i.is_integer()) -> x_i] +array_api_tests/test_special_cases.py::test_unary[cos(x_i is NaN) -> NaN] +array_api_tests/test_special_cases.py::test_unary[cos(x_i is +0) -> 1] +array_api_tests/test_special_cases.py::test_unary[cos(x_i is -0) -> 1] +array_api_tests/test_special_cases.py::test_unary[cos(x_i is +infinity) -> NaN] +array_api_tests/test_special_cases.py::test_unary[cos(x_i is -infinity) -> NaN] +array_api_tests/test_special_cases.py::test_unary[cosh(x_i is NaN) -> NaN] +array_api_tests/test_special_cases.py::test_unary[cosh(x_i is +0) -> 1] +array_api_tests/test_special_cases.py::test_unary[cosh(x_i is -0) -> 1] +array_api_tests/test_special_cases.py::test_unary[cosh(x_i is +infinity) -> +infinity] +array_api_tests/test_special_cases.py::test_unary[cosh(x_i is -infinity) -> +infinity] +array_api_tests/test_special_cases.py::test_unary[exp(x_i is NaN) -> NaN] +array_api_tests/test_special_cases.py::test_unary[exp(x_i is +0) -> 1] +array_api_tests/test_special_cases.py::test_unary[exp(x_i is -0) -> 1] +array_api_tests/test_special_cases.py::test_unary[exp(x_i is +infinity) -> +infinity] +array_api_tests/test_special_cases.py::test_unary[exp(x_i is -infinity) -> +0] +array_api_tests/test_special_cases.py::test_unary[expm1(x_i is NaN) -> NaN] +array_api_tests/test_special_cases.py::test_unary[expm1(x_i is +0) -> +0] +array_api_tests/test_special_cases.py::test_unary[expm1(x_i is -0) -> -0] +array_api_tests/test_special_cases.py::test_unary[expm1(x_i is +infinity) -> +infinity] +array_api_tests/test_special_cases.py::test_unary[expm1(x_i is -infinity) -> -1] +array_api_tests/test_special_cases.py::test_unary[floor(x_i.is_integer()) -> x_i] +array_api_tests/test_special_cases.py::test_unary[isfinite((x_i is +infinity or x_i == -infinity)) -> False] +array_api_tests/test_special_cases.py::test_unary[isfinite(x_i is NaN) -> False] +array_api_tests/test_special_cases.py::test_unary[isfinite(isfinite(x_i)) -> True] +array_api_tests/test_special_cases.py::test_unary[isinf((x_i is +infinity or x_i == -infinity)) -> True] +array_api_tests/test_special_cases.py::test_unary[isnan(x_i is NaN) -> True] +array_api_tests/test_special_cases.py::test_unary[log(x_i is NaN) -> NaN] +array_api_tests/test_special_cases.py::test_unary[log(x_i < 0) -> NaN] +array_api_tests/test_special_cases.py::test_unary[log((x_i is +0 or x_i == -0)) -> -infinity] +array_api_tests/test_special_cases.py::test_unary[log(x_i is 1) -> +0] +array_api_tests/test_special_cases.py::test_unary[log(x_i is +infinity) -> +infinity] +array_api_tests/test_special_cases.py::test_unary[log1p(x_i is NaN) -> NaN] +array_api_tests/test_special_cases.py::test_unary[log1p(x_i < -1) -> NaN] +array_api_tests/test_special_cases.py::test_unary[log1p(x_i is -1) -> -infinity] +array_api_tests/test_special_cases.py::test_unary[log1p(x_i is -0) -> -0] +array_api_tests/test_special_cases.py::test_unary[log1p(x_i is +0) -> +0] +array_api_tests/test_special_cases.py::test_unary[log1p(x_i is +infinity) -> +infinity] +array_api_tests/test_special_cases.py::test_unary[log2(x_i is NaN) -> NaN] +array_api_tests/test_special_cases.py::test_unary[log2(x_i < 0) -> NaN] +array_api_tests/test_special_cases.py::test_unary[log2((x_i is +0 or x_i == -0)) -> -infinity] +array_api_tests/test_special_cases.py::test_unary[log2(x_i is 1) -> +0] +array_api_tests/test_special_cases.py::test_unary[log2(x_i is +infinity) -> +infinity] +array_api_tests/test_special_cases.py::test_unary[log10(x_i is NaN) -> NaN] +array_api_tests/test_special_cases.py::test_unary[log10(x_i < 0) -> NaN] +array_api_tests/test_special_cases.py::test_unary[log10((x_i is +0 or x_i == -0)) -> -infinity] +array_api_tests/test_special_cases.py::test_unary[log10(x_i is 1) -> +0] +array_api_tests/test_special_cases.py::test_unary[log10(x_i is +infinity) -> +infinity] +array_api_tests/test_special_cases.py::test_unary[round(x_i.is_integer()) -> x_i] +array_api_tests/test_special_cases.py::test_unary[round(x_i is +infinity) -> +infinity] +array_api_tests/test_special_cases.py::test_unary[round(x_i is -infinity) -> -infinity] +array_api_tests/test_special_cases.py::test_unary[round(x_i is +0) -> +0] +array_api_tests/test_special_cases.py::test_unary[round(x_i is -0) -> -0] +array_api_tests/test_special_cases.py::test_unary[round(x_i is NaN) -> NaN] +array_api_tests/test_special_cases.py::test_unary[round(modf(i)[0] == 0.5) -> Decimal(i).to_integral_exact(ROUND_HALF_EVEN)] +array_api_tests/test_special_cases.py::test_unary[sign(x_i < 0) -> -1] +array_api_tests/test_special_cases.py::test_unary[sign((x_i is -0 or x_i == +0)) -> 0] +array_api_tests/test_special_cases.py::test_unary[sign(x_i > 0) -> +1] +array_api_tests/test_special_cases.py::test_unary[sign(x_i is NaN) -> NaN] +array_api_tests/test_special_cases.py::test_unary[sin(x_i is NaN) -> NaN] +array_api_tests/test_special_cases.py::test_unary[sin(x_i is +0) -> +0] +array_api_tests/test_special_cases.py::test_unary[sin(x_i is -0) -> -0] +array_api_tests/test_special_cases.py::test_unary[sin((x_i is +infinity or x_i == -infinity)) -> NaN] +array_api_tests/test_special_cases.py::test_unary[sinh(x_i is NaN) -> NaN] +array_api_tests/test_special_cases.py::test_unary[sinh(x_i is +0) -> +0] +array_api_tests/test_special_cases.py::test_unary[sinh(x_i is -0) -> -0] +array_api_tests/test_special_cases.py::test_unary[sinh(x_i is +infinity) -> +infinity] +array_api_tests/test_special_cases.py::test_unary[sinh(x_i is -infinity) -> -infinity] +array_api_tests/test_special_cases.py::test_unary[sqrt(x_i is NaN) -> NaN] +array_api_tests/test_special_cases.py::test_unary[sqrt(x_i < 0) -> NaN] +array_api_tests/test_special_cases.py::test_unary[sqrt(x_i is +0) -> +0] +array_api_tests/test_special_cases.py::test_unary[sqrt(x_i is -0) -> -0] +array_api_tests/test_special_cases.py::test_unary[sqrt(x_i is +infinity) -> +infinity] +array_api_tests/test_special_cases.py::test_unary[tan(x_i is NaN) -> NaN] +array_api_tests/test_special_cases.py::test_unary[tan(x_i is +0) -> +0] +array_api_tests/test_special_cases.py::test_unary[tan(x_i is -0) -> -0] +array_api_tests/test_special_cases.py::test_unary[tan((x_i is +infinity or x_i == -infinity)) -> NaN] +array_api_tests/test_special_cases.py::test_unary[tanh(x_i is NaN) -> NaN] +array_api_tests/test_special_cases.py::test_unary[tanh(x_i is +0) -> +0] +array_api_tests/test_special_cases.py::test_unary[tanh(x_i is -0) -> -0] +array_api_tests/test_special_cases.py::test_unary[tanh(x_i is +infinity) -> +1] +array_api_tests/test_special_cases.py::test_unary[tanh(x_i is -infinity) -> -1] +array_api_tests/test_special_cases.py::test_unary[trunc(x_i.is_integer()) -> x_i] +array_api_tests/test_special_cases.py::test_binary[add(x1_i is NaN or x2_i is NaN) -> NaN] +array_api_tests/test_special_cases.py::test_binary[add(x1_i is +infinity and x2_i is -infinity) -> NaN] +array_api_tests/test_special_cases.py::test_binary[add(x1_i is -infinity and x2_i is +infinity) -> NaN] +array_api_tests/test_special_cases.py::test_binary[add(x1_i is +infinity and x2_i is +infinity) -> +infinity] +array_api_tests/test_special_cases.py::test_binary[add(x1_i is -infinity and x2_i is -infinity) -> -infinity] +array_api_tests/test_special_cases.py::test_binary[add(x1_i is +infinity and isfinite(x2_i)) -> +infinity] +array_api_tests/test_special_cases.py::test_binary[add(x1_i is -infinity and isfinite(x2_i)) -> -infinity] +array_api_tests/test_special_cases.py::test_binary[add(isfinite(x1_i) and x2_i is +infinity) -> +infinity] +array_api_tests/test_special_cases.py::test_binary[add(isfinite(x1_i) and x2_i is -infinity) -> -infinity] +array_api_tests/test_special_cases.py::test_binary[add(x1_i is -0 and x2_i is -0) -> -0] +array_api_tests/test_special_cases.py::test_binary[add(x1_i is -0 and x2_i is +0) -> +0] +array_api_tests/test_special_cases.py::test_binary[add(x1_i is +0 and x2_i is -0) -> +0] +array_api_tests/test_special_cases.py::test_binary[add(x1_i is +0 and x2_i is +0) -> +0] +array_api_tests/test_special_cases.py::test_binary[add((x1_i is +0 or x1_i == -0) and isfinite(x2_i) and x2_i != 0) -> x2_i] +array_api_tests/test_special_cases.py::test_binary[add(isfinite(x1_i) and x1_i != 0 and (x2_i is +0 or x2_i == -0)) -> x1_i] +array_api_tests/test_special_cases.py::test_binary[__add__(x1_i is NaN or x2_i is NaN) -> NaN] +array_api_tests/test_special_cases.py::test_binary[__add__(x1_i is +infinity and x2_i is -infinity) -> NaN] +array_api_tests/test_special_cases.py::test_binary[__add__(x1_i is -infinity and x2_i is +infinity) -> NaN] +array_api_tests/test_special_cases.py::test_binary[__add__(x1_i is +infinity and x2_i is +infinity) -> +infinity] +array_api_tests/test_special_cases.py::test_binary[__add__(x1_i is -infinity and x2_i is -infinity) -> -infinity] +array_api_tests/test_special_cases.py::test_binary[__add__(x1_i is +infinity and isfinite(x2_i)) -> +infinity] +array_api_tests/test_special_cases.py::test_binary[__add__(x1_i is -infinity and isfinite(x2_i)) -> -infinity] +array_api_tests/test_special_cases.py::test_binary[__add__(isfinite(x1_i) and x2_i is +infinity) -> +infinity] +array_api_tests/test_special_cases.py::test_binary[__add__(isfinite(x1_i) and x2_i is -infinity) -> -infinity] +array_api_tests/test_special_cases.py::test_binary[__add__(x1_i is -0 and x2_i is -0) -> -0] +array_api_tests/test_special_cases.py::test_binary[__add__(x1_i is -0 and x2_i is +0) -> +0] +array_api_tests/test_special_cases.py::test_binary[__add__(x1_i is +0 and x2_i is -0) -> +0] +array_api_tests/test_special_cases.py::test_binary[__add__(x1_i is +0 and x2_i is +0) -> +0] +array_api_tests/test_special_cases.py::test_binary[__add__((x1_i is +0 or x1_i == -0) and isfinite(x2_i) and x2_i != 0) -> x2_i] +array_api_tests/test_special_cases.py::test_binary[__add__(isfinite(x1_i) and x1_i != 0 and (x2_i is +0 or x2_i == -0)) -> x1_i] +array_api_tests/test_special_cases.py::test_binary[__add__(isfinite(x1_i) and x1_i != 0 and x2_i == -x1_i) -> +0] +array_api_tests/test_special_cases.py::test_binary[divide(x1_i is NaN or x2_i is NaN) -> NaN] +array_api_tests/test_special_cases.py::test_binary[divide((x1_i is +infinity or x1_i == -infinity) and (x2_i is +infinity or x2_i == -infinity)) -> NaN] +array_api_tests/test_special_cases.py::test_binary[divide((x1_i is +0 or x1_i == -0) and (x2_i is +0 or x2_i == -0)) -> NaN] +array_api_tests/test_special_cases.py::test_binary[divide(x1_i is +0 and x2_i > 0) -> +0] +array_api_tests/test_special_cases.py::test_binary[divide(x1_i is -0 and x2_i > 0) -> -0] +array_api_tests/test_special_cases.py::test_binary[divide(x1_i is +0 and x2_i < 0) -> -0] +array_api_tests/test_special_cases.py::test_binary[divide(x1_i is -0 and x2_i < 0) -> +0] +array_api_tests/test_special_cases.py::test_binary[divide(x1_i > 0 and x2_i is +0) -> +infinity] +array_api_tests/test_special_cases.py::test_binary[divide(x1_i > 0 and x2_i is -0) -> -infinity] +array_api_tests/test_special_cases.py::test_binary[divide(x1_i < 0 and x2_i is +0) -> -infinity] +array_api_tests/test_special_cases.py::test_binary[divide(x1_i < 0 and x2_i is -0) -> +infinity] +array_api_tests/test_special_cases.py::test_binary[divide(x1_i is +infinity and isfinite(x2_i) and x2_i > 0) -> +infinity] +array_api_tests/test_special_cases.py::test_binary[divide(x1_i is +infinity and isfinite(x2_i) and x2_i < 0) -> -infinity] +array_api_tests/test_special_cases.py::test_binary[divide(x1_i is -infinity and isfinite(x2_i) and x2_i > 0) -> -infinity] +array_api_tests/test_special_cases.py::test_binary[divide(x1_i is -infinity and isfinite(x2_i) and x2_i < 0) -> +infinity] +array_api_tests/test_special_cases.py::test_binary[divide(isfinite(x1_i) and x1_i > 0 and x2_i is +infinity) -> +0] +array_api_tests/test_special_cases.py::test_binary[divide(isfinite(x1_i) and x1_i > 0 and x2_i is -infinity) -> -0] +array_api_tests/test_special_cases.py::test_binary[divide(isfinite(x1_i) and x1_i < 0 and x2_i is +infinity) -> -0] +array_api_tests/test_special_cases.py::test_binary[divide(isfinite(x1_i) and x1_i < 0 and x2_i is -infinity) -> +0] +array_api_tests/test_special_cases.py::test_binary[divide(copysign(1, x1_i) == copysign(1, x2_i) and isfinite(x1_i) and x1_i != 0 and isfinite(x2_i) and x2_i != 0) -> positive sign] +array_api_tests/test_special_cases.py::test_binary[divide(copysign(1, x1_i) != copysign(1, x2_i) and isfinite(x1_i) and x1_i != 0 and isfinite(x2_i) and x2_i != 0) -> negative sign] +array_api_tests/test_special_cases.py::test_binary[__truediv__(x1_i is NaN or x2_i is NaN) -> NaN] +array_api_tests/test_special_cases.py::test_binary[__truediv__((x1_i is +infinity or x1_i == -infinity) and (x2_i is +infinity or x2_i == -infinity)) -> NaN] +array_api_tests/test_special_cases.py::test_binary[__truediv__((x1_i is +0 or x1_i == -0) and (x2_i is +0 or x2_i == -0)) -> NaN] +array_api_tests/test_special_cases.py::test_binary[__truediv__(x1_i is +0 and x2_i > 0) -> +0] +array_api_tests/test_special_cases.py::test_binary[__truediv__(x1_i is -0 and x2_i > 0) -> -0] +array_api_tests/test_special_cases.py::test_binary[__truediv__(x1_i is +0 and x2_i < 0) -> -0] +array_api_tests/test_special_cases.py::test_binary[__truediv__(x1_i is -0 and x2_i < 0) -> +0] +array_api_tests/test_special_cases.py::test_binary[__truediv__(x1_i > 0 and x2_i is +0) -> +infinity] +array_api_tests/test_special_cases.py::test_binary[__truediv__(x1_i > 0 and x2_i is -0) -> -infinity] +array_api_tests/test_special_cases.py::test_binary[__truediv__(x1_i < 0 and x2_i is +0) -> -infinity] +array_api_tests/test_special_cases.py::test_binary[__truediv__(x1_i < 0 and x2_i is -0) -> +infinity] +array_api_tests/test_special_cases.py::test_binary[__truediv__(x1_i is +infinity and isfinite(x2_i) and x2_i > 0) -> +infinity] +array_api_tests/test_special_cases.py::test_binary[__truediv__(x1_i is +infinity and isfinite(x2_i) and x2_i < 0) -> -infinity] +array_api_tests/test_special_cases.py::test_binary[__truediv__(x1_i is -infinity and isfinite(x2_i) and x2_i > 0) -> -infinity] +array_api_tests/test_special_cases.py::test_binary[__truediv__(x1_i is -infinity and isfinite(x2_i) and x2_i < 0) -> +infinity] +array_api_tests/test_special_cases.py::test_binary[__truediv__(isfinite(x1_i) and x1_i > 0 and x2_i is +infinity) -> +0] +array_api_tests/test_special_cases.py::test_binary[__truediv__(isfinite(x1_i) and x1_i > 0 and x2_i is -infinity) -> -0] +array_api_tests/test_special_cases.py::test_binary[__truediv__(isfinite(x1_i) and x1_i < 0 and x2_i is +infinity) -> -0] +array_api_tests/test_special_cases.py::test_binary[__truediv__(isfinite(x1_i) and x1_i < 0 and x2_i is -infinity) -> +0] +array_api_tests/test_special_cases.py::test_binary[__truediv__(copysign(1, x1_i) == copysign(1, x2_i) and isfinite(x1_i) and x1_i != 0 and isfinite(x2_i) and x2_i != 0) -> positive sign] +array_api_tests/test_special_cases.py::test_binary[__truediv__(copysign(1, x1_i) != copysign(1, x2_i) and isfinite(x1_i) and x1_i != 0 and isfinite(x2_i) and x2_i != 0) -> negative sign] +array_api_tests/test_special_cases.py::test_binary[multiply(x1_i is NaN or x2_i is NaN) -> NaN] +array_api_tests/test_special_cases.py::test_binary[multiply((x1_i is +infinity or x1_i == -infinity) and (x2_i is +0 or x2_i == -0)) -> NaN] +array_api_tests/test_special_cases.py::test_binary[multiply((x1_i is +0 or x1_i == -0) and (x2_i is +infinity or x2_i == -infinity)) -> NaN] +array_api_tests/test_special_cases.py::test_binary[multiply(copysign(1, x1_i) == copysign(1, x2_i)) -> positive sign] +array_api_tests/test_special_cases.py::test_binary[multiply(copysign(1, x1_i) != copysign(1, x2_i)) -> negative sign] +array_api_tests/test_special_cases.py::test_binary[__mul__(x1_i is NaN or x2_i is NaN) -> NaN] +array_api_tests/test_special_cases.py::test_binary[__mul__((x1_i is +infinity or x1_i == -infinity) and (x2_i is +0 or x2_i == -0)) -> NaN] +array_api_tests/test_special_cases.py::test_binary[__mul__((x1_i is +0 or x1_i == -0) and (x2_i is +infinity or x2_i == -infinity)) -> NaN] +array_api_tests/test_special_cases.py::test_binary[__mul__(copysign(1, x1_i) == copysign(1, x2_i)) -> positive sign] +array_api_tests/test_special_cases.py::test_binary[__mul__(copysign(1, x1_i) != copysign(1, x2_i)) -> negative sign] +array_api_tests/test_special_cases.py::test_binary[pow(not x1_i == 1 and x2_i is NaN) -> NaN] +array_api_tests/test_special_cases.py::test_binary[pow(x2_i is +0) -> 1] +array_api_tests/test_special_cases.py::test_binary[pow(x2_i is -0) -> 1] +array_api_tests/test_special_cases.py::test_binary[pow(x1_i is NaN and not x2_i == 0) -> NaN] +array_api_tests/test_special_cases.py::test_binary[pow(abs(x1_i) > 1 and x2_i is +infinity) -> +infinity] +array_api_tests/test_special_cases.py::test_binary[pow(abs(x1_i) > 1 and x2_i is -infinity) -> +0] +array_api_tests/test_special_cases.py::test_binary[pow(abs(x1_i) is 1 and x2_i is +infinity) -> 1] +array_api_tests/test_special_cases.py::test_binary[pow(abs(x1_i) is 1 and x2_i is -infinity) -> 1] +array_api_tests/test_special_cases.py::test_binary[pow(x1_i is 1 and not x2_i is NaN) -> 1] +array_api_tests/test_special_cases.py::test_binary[pow(abs(x1_i) < 1 and x2_i is +infinity) -> +0] +array_api_tests/test_special_cases.py::test_binary[pow(abs(x1_i) < 1 and x2_i is -infinity) -> +infinity] +array_api_tests/test_special_cases.py::test_binary[pow(x1_i is +infinity and x2_i > 0) -> +infinity] +array_api_tests/test_special_cases.py::test_binary[pow(x1_i is +infinity and x2_i < 0) -> +0] +array_api_tests/test_special_cases.py::test_binary[pow(x1_i is -infinity and x2_i > 0 and x2_i.is_integer() and x2_i % 2 == 1) -> -infinity] +array_api_tests/test_special_cases.py::test_binary[pow(x1_i is -infinity and x2_i > 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +infinity] +array_api_tests/test_special_cases.py::test_binary[pow(x1_i is -infinity and x2_i < 0 and x2_i.is_integer() and x2_i % 2 == 1) -> -0] +array_api_tests/test_special_cases.py::test_binary[pow(x1_i is -infinity and x2_i < 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +0] +array_api_tests/test_special_cases.py::test_binary[pow(x1_i is +0 and x2_i > 0) -> +0] +array_api_tests/test_special_cases.py::test_binary[pow(x1_i is +0 and x2_i < 0) -> +infinity] +array_api_tests/test_special_cases.py::test_binary[pow(x1_i is -0 and x2_i > 0 and x2_i.is_integer() and x2_i % 2 == 1) -> -0] +array_api_tests/test_special_cases.py::test_binary[pow(x1_i is -0 and x2_i > 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +0] +array_api_tests/test_special_cases.py::test_binary[pow(x1_i is -0 and x2_i < 0 and x2_i.is_integer() and x2_i % 2 == 1) -> -infinity] +array_api_tests/test_special_cases.py::test_binary[pow(x1_i is -0 and x2_i < 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +infinity] +array_api_tests/test_special_cases.py::test_binary[pow(x1_i < 0 and isfinite(x1_i) and isfinite(x2_i) and not x2_i.is_integer()) -> NaN] +array_api_tests/test_special_cases.py::test_binary[__pow__(not x1_i == 1 and x2_i is NaN) -> NaN] +array_api_tests/test_special_cases.py::test_binary[__pow__(x2_i is +0) -> 1] +array_api_tests/test_special_cases.py::test_binary[__pow__(x2_i is -0) -> 1] +array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is NaN and not x2_i == 0) -> NaN] +array_api_tests/test_special_cases.py::test_binary[__pow__(abs(x1_i) > 1 and x2_i is +infinity) -> +infinity] +array_api_tests/test_special_cases.py::test_binary[__pow__(abs(x1_i) > 1 and x2_i is -infinity) -> +0] +array_api_tests/test_special_cases.py::test_binary[__pow__(abs(x1_i) is 1 and x2_i is +infinity) -> 1] +array_api_tests/test_special_cases.py::test_binary[__pow__(abs(x1_i) is 1 and x2_i is -infinity) -> 1] +array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is 1 and not x2_i is NaN) -> 1] +array_api_tests/test_special_cases.py::test_binary[__pow__(abs(x1_i) < 1 and x2_i is +infinity) -> +0] +array_api_tests/test_special_cases.py::test_binary[__pow__(abs(x1_i) < 1 and x2_i is -infinity) -> +infinity] +array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is +infinity and x2_i > 0) -> +infinity] +array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is +infinity and x2_i < 0) -> +0] +array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is -infinity and x2_i > 0 and x2_i.is_integer() and x2_i % 2 == 1) -> -infinity] +array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is -infinity and x2_i > 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +infinity] +array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is -infinity and x2_i < 0 and x2_i.is_integer() and x2_i % 2 == 1) -> -0] +array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is -infinity and x2_i < 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +0] +array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is +0 and x2_i > 0) -> +0] +array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is +0 and x2_i < 0) -> +infinity] +array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is -0 and x2_i > 0 and x2_i.is_integer() and x2_i % 2 == 1) -> -0] +array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is -0 and x2_i > 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +0] +array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is -0 and x2_i < 0 and x2_i.is_integer() and x2_i % 2 == 1) -> -infinity] +array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is -0 and x2_i < 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +infinity] +array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i < 0 and isfinite(x1_i) and isfinite(x2_i) and not x2_i.is_integer()) -> NaN] +array_api_tests/test_special_cases.py::test_iop[__iadd__(x1_i is NaN or x2_i is NaN) -> NaN] +array_api_tests/test_special_cases.py::test_iop[__iadd__(x1_i is +infinity and x2_i is -infinity) -> NaN] +array_api_tests/test_special_cases.py::test_iop[__iadd__(x1_i is -infinity and x2_i is +infinity) -> NaN] +array_api_tests/test_special_cases.py::test_iop[__iadd__(x1_i is +infinity and x2_i is +infinity) -> +infinity] +array_api_tests/test_special_cases.py::test_iop[__iadd__(x1_i is -infinity and x2_i is -infinity) -> -infinity] +array_api_tests/test_special_cases.py::test_iop[__iadd__(x1_i is +infinity and isfinite(x2_i)) -> +infinity] +array_api_tests/test_special_cases.py::test_iop[__iadd__(x1_i is -infinity and isfinite(x2_i)) -> -infinity] +array_api_tests/test_special_cases.py::test_iop[__iadd__(isfinite(x1_i) and x2_i is +infinity) -> +infinity] +array_api_tests/test_special_cases.py::test_iop[__iadd__(isfinite(x1_i) and x2_i is -infinity) -> -infinity] +array_api_tests/test_special_cases.py::test_iop[__iadd__(x1_i is -0 and x2_i is -0) -> -0] +array_api_tests/test_special_cases.py::test_iop[__iadd__(x1_i is -0 and x2_i is +0) -> +0] +array_api_tests/test_special_cases.py::test_iop[__iadd__(x1_i is +0 and x2_i is -0) -> +0] +array_api_tests/test_special_cases.py::test_iop[__iadd__(x1_i is +0 and x2_i is +0) -> +0] +array_api_tests/test_special_cases.py::test_iop[__iadd__((x1_i is +0 or x1_i == -0) and isfinite(x2_i) and x2_i != 0) -> x2_i] +array_api_tests/test_special_cases.py::test_iop[__iadd__(isfinite(x1_i) and x1_i != 0 and (x2_i is +0 or x2_i == -0)) -> x1_i] +array_api_tests/test_special_cases.py::test_iop[__iadd__(isfinite(x1_i) and x1_i != 0 and x2_i == -x1_i) -> +0] +array_api_tests/test_special_cases.py::test_iop[__itruediv__(x1_i is NaN or x2_i is NaN) -> NaN] +array_api_tests/test_special_cases.py::test_iop[__itruediv__((x1_i is +infinity or x1_i == -infinity) and (x2_i is +infinity or x2_i == -infinity)) -> NaN] +array_api_tests/test_special_cases.py::test_iop[__itruediv__((x1_i is +0 or x1_i == -0) and (x2_i is +0 or x2_i == -0)) -> NaN] +array_api_tests/test_special_cases.py::test_iop[__itruediv__(x1_i is +0 and x2_i > 0) -> +0] +array_api_tests/test_special_cases.py::test_iop[__itruediv__(x1_i is -0 and x2_i > 0) -> -0] +array_api_tests/test_special_cases.py::test_iop[__itruediv__(x1_i is +0 and x2_i < 0) -> -0] +array_api_tests/test_special_cases.py::test_iop[__itruediv__(x1_i is -0 and x2_i < 0) -> +0] +array_api_tests/test_special_cases.py::test_iop[__itruediv__(x1_i > 0 and x2_i is +0) -> +infinity] +array_api_tests/test_special_cases.py::test_iop[__itruediv__(x1_i > 0 and x2_i is -0) -> -infinity] +array_api_tests/test_special_cases.py::test_iop[__itruediv__(x1_i < 0 and x2_i is +0) -> -infinity] +array_api_tests/test_special_cases.py::test_iop[__itruediv__(x1_i < 0 and x2_i is -0) -> +infinity] +array_api_tests/test_special_cases.py::test_iop[__itruediv__(x1_i is +infinity and isfinite(x2_i) and x2_i > 0) -> +infinity] +array_api_tests/test_special_cases.py::test_iop[__itruediv__(x1_i is +infinity and isfinite(x2_i) and x2_i < 0) -> -infinity] +array_api_tests/test_special_cases.py::test_iop[__itruediv__(x1_i is -infinity and isfinite(x2_i) and x2_i > 0) -> -infinity] +array_api_tests/test_special_cases.py::test_iop[__itruediv__(x1_i is -infinity and isfinite(x2_i) and x2_i < 0) -> +infinity] +array_api_tests/test_special_cases.py::test_iop[__itruediv__(isfinite(x1_i) and x1_i > 0 and x2_i is +infinity) -> +0] +array_api_tests/test_special_cases.py::test_iop[__itruediv__(isfinite(x1_i) and x1_i > 0 and x2_i is -infinity) -> -0] +array_api_tests/test_special_cases.py::test_iop[__itruediv__(isfinite(x1_i) and x1_i < 0 and x2_i is +infinity) -> -0] +array_api_tests/test_special_cases.py::test_iop[__itruediv__(isfinite(x1_i) and x1_i < 0 and x2_i is -infinity) -> +0] +array_api_tests/test_special_cases.py::test_iop[__itruediv__(copysign(1, x1_i) == copysign(1, x2_i) and isfinite(x1_i) and x1_i != 0 and isfinite(x2_i) and x2_i != 0) -> positive sign] +array_api_tests/test_special_cases.py::test_iop[__itruediv__(copysign(1, x1_i) != copysign(1, x2_i) and isfinite(x1_i) and x1_i != 0 and isfinite(x2_i) and x2_i != 0) -> negative sign] +array_api_tests/test_special_cases.py::test_iop[__imul__(x1_i is NaN or x2_i is NaN) -> NaN] +array_api_tests/test_special_cases.py::test_iop[__imul__((x1_i is +infinity or x1_i == -infinity) and (x2_i is +0 or x2_i == -0)) -> NaN] +array_api_tests/test_special_cases.py::test_iop[__imul__((x1_i is +0 or x1_i == -0) and (x2_i is +infinity or x2_i == -infinity)) -> NaN] +array_api_tests/test_special_cases.py::test_iop[__imul__(copysign(1, x1_i) == copysign(1, x2_i)) -> positive sign] +array_api_tests/test_special_cases.py::test_iop[__imul__(copysign(1, x1_i) != copysign(1, x2_i)) -> negative sign] +array_api_tests/test_special_cases.py::test_iop[__ipow__(not x1_i == 1 and x2_i is NaN) -> NaN] +array_api_tests/test_special_cases.py::test_iop[__ipow__(x2_i is +0) -> 1] +array_api_tests/test_special_cases.py::test_iop[__ipow__(x2_i is -0) -> 1] +array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i is NaN and not x2_i == 0) -> NaN] +array_api_tests/test_special_cases.py::test_iop[__ipow__(abs(x1_i) > 1 and x2_i is +infinity) -> +infinity] +array_api_tests/test_special_cases.py::test_iop[__ipow__(abs(x1_i) > 1 and x2_i is -infinity) -> +0] +array_api_tests/test_special_cases.py::test_iop[__ipow__(abs(x1_i) is 1 and x2_i is +infinity) -> 1] +array_api_tests/test_special_cases.py::test_iop[__ipow__(abs(x1_i) is 1 and x2_i is -infinity) -> 1] +array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i is 1 and not x2_i is NaN) -> 1] +array_api_tests/test_special_cases.py::test_iop[__ipow__(abs(x1_i) < 1 and x2_i is +infinity) -> +0] +array_api_tests/test_special_cases.py::test_iop[__ipow__(abs(x1_i) < 1 and x2_i is -infinity) -> +infinity] +array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i is +infinity and x2_i > 0) -> +infinity] +array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i is +infinity and x2_i < 0) -> +0] +array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i is -infinity and x2_i > 0 and x2_i.is_integer() and x2_i % 2 == 1) -> -infinity] +array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i is -infinity and x2_i > 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +infinity] +array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i is -infinity and x2_i < 0 and x2_i.is_integer() and x2_i % 2 == 1) -> -0] +array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i is -infinity and x2_i < 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +0] +array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i is +0 and x2_i > 0) -> +0] +array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i is +0 and x2_i < 0) -> +infinity] +array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i is -0 and x2_i > 0 and x2_i.is_integer() and x2_i % 2 == 1) -> -0] +array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i is -0 and x2_i > 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +0] +array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i is -0 and x2_i < 0 and x2_i.is_integer() and x2_i % 2 == 1) -> -infinity] +array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i is -0 and x2_i < 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +infinity] +array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i < 0 and isfinite(x1_i) and isfinite(x2_i) and not x2_i.is_integer()) -> NaN] +array_api_tests/test_special_cases.py::test_empty_arrays[sum] +array_api_tests/test_special_cases.py::test_nan_propagation[mean] +array_api_tests/test_special_cases.py::test_nan_propagation[var] \ No newline at end of file diff --git a/skips.txt b/skips.txt deleted file mode 100644 index f600f1eea1..0000000000 --- a/skips.txt +++ /dev/null @@ -1,130 +0,0 @@ -# fft -array_api_tests/test_fft.py::test_fft -array_api_tests/test_fft.py::test_ifft -array_api_tests/test_fft.py::test_fftn -array_api_tests/test_fft.py::test_ifftn -array_api_tests/test_fft.py::test_rfft -array_api_tests/test_fft.py::test_irfft -array_api_tests/test_fft.py::test_rfftn -array_api_tests/test_fft.py::test_irfftn -array_api_tests/test_fft.py::test_hfft -array_api_tests/test_fft.py::test_ihfft - -# PR #938 Indexing overhaul -array_api_tests/test_array_object.py::test_getitem -array_api_tests/test_array_object.py::test_setitem -array_api_tests/test_array_object.py::test_getitem_masking -array_api_tests/test_array_object.py::test_setitem_masking -# array_api_tests/test_linalg.py::test_matrix_matmul -array_api_tests/test_manipulation_functions.py::test_concat -array_api_tests/test_manipulation_functions.py::test_stack -array_api_tests/test_searching_functions.py::test_argmax -array_api_tests/test_searching_functions.py::test_argmin -array_api_tests/test_searching_functions.py::test_nonzero -array_api_tests/test_searching_functions.py::test_where -array_api_tests/test_special_cases.py::test_nan_propagation[max] -array_api_tests/test_special_cases.py::test_nan_propagation[min] -array_api_tests/test_special_cases.py::test_nan_propagation[prod] -array_api_tests/test_special_cases.py::test_nan_propagation[sum] -array_api_tests/test_special_cases.py::test_binary[add(isfinite(x1_i) and x1_i != 0 and x2_i == -x1_i) -> +0] -array_api_tests/test_special_cases.py::test_iop[__iadd__(isfinite(x1_i) and x1_i != 0 and x2_i == -x1_i) -> +0] -array_api_tests/test_statistical_functions.py::test_max -array_api_tests/test_statistical_functions.py::test_mean -array_api_tests/test_statistical_functions.py::test_min -array_api_tests/test_statistical_functions.py::test_prod -array_api_tests/test_statistical_functions.py::test_var -array_api_tests/test_utility_functions.py::test_all -array_api_tests/test_utility_functions.py::test_any - -# Pytorch dtypes https://github.com/pytorch/pytorch/issues/58734 -array_api_tests/test_array_object.py::test_scalar_casting[__int__(uint16)] -array_api_tests/test_array_object.py::test_scalar_casting[__int__(uint32)] -array_api_tests/test_array_object.py::test_scalar_casting[__int__(uint64)] -array_api_tests/test_array_object.py::test_scalar_casting[__index__(uint16)] -array_api_tests/test_array_object.py::test_scalar_casting[__index__(uint32)] -array_api_tests/test_array_object.py::test_scalar_casting[__inndes__(uint64)] -array_api_tests/test_data_type_functions.py::test_iinfo[uint16] -array_api_tests/test_data_type_functions.py::test_iinfo[uint32] -array_api_tests/test_data_type_functions.py::test_iinfo[uint64] -array_api_tests/test_statistical_functions.py::test_sum -array_api_tests/test_type_promotion.py - -# PR #1000 any/all keepdim -# array_api_tests/test_linalg.py::test_matrix_transpose -array_api_tests/test_operators_and_elementwise_functions.py::test_abs -array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_left_shift -array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_right_shift -array_api_tests/test_operators_and_elementwise_functions.py::test_floor_divide -array_api_tests/test_operators_and_elementwise_functions.py::test_positive -array_api_tests/test_operators_and_elementwise_functions.py::test_pow -array_api_tests/test_operators_and_elementwise_functions.py::test_remainder - -# PR #993 Precision loss -array_api_tests/test_creation_functions.py::test_arange -array_api_tests/test_creation_functions.py::test_linspace - -# PR #1018 __reduce_op bug -array_api_tests/test_creation_functions.py::test_asarray_arrays -array_api_tests/test_creation_functions.py::test_full -array_api_tests/test_creation_functions.py::test_full_like -array_api_tests/test_creation_functions.py::test_ones -array_api_tests/test_creation_functions.py::test_ones_like -array_api_tests/test_creation_functions.py::test_zeros -array_api_tests/test_creation_functions.py::test_zeros_like -array_api_tests/test_operators_and_elementwise_functions.py::test_negative -array_api_tests/test_special_cases.py::test_empty_arrays[prod] -array_api_tests/test_special_cases.py::test_nan_propagation[sum] - -# k not implemented -array_api_tests/test_creation_functions.py::test_eye - -# PR #1020 broadcasting -array_api_tests/test_data_type_functions.py::test_broadcast_arrays -array_api_tests/test_data_type_functions.py::test_broadcast_to - -# PR #749 unique -array_api_tests/test_set_functions.py::test_unique_all -array_api_tests/test_set_functions.py::test_unique_counts -array_api_tests/test_set_functions.py::test_unique_inverse -array_api_tests/test_set_functions.py::test_unique_values -array_api_tests/test_signatures.py::test_func_signature[unique_all] -array_api_tests/test_signatures.py::test_func_signature[unique_counts] -array_api_tests/test_sorting_functions.py::test_sort - -# PR #996 argsort -array_api_tests/test_signatures.py::test_func_signature[argsort] -array_api_tests/test_sorting_functions.py::test_argsort - -# tensordot -# array_api_tests/test_linalg.py::test_tensordot - -# Special cases -array_api_tests/test_operators_and_elementwise_functions.py::test_square -array_api_tests/test_special_cases.py::test_binary[floor_divide(x1_i is +infinity and isfinite(x2_i) and x2_i > 0) -> +infinity] -array_api_tests/test_special_cases.py::test_binary[floor_divide(x1_i is +infinity and isfinite(x2_i) and x2_i < 0) -> -infinity] -array_api_tests/test_special_cases.py::test_binary[floor_divide(x1_i is -infinity and isfinite(x2_i) and x2_i > 0) -> -infinity] -array_api_tests/test_special_cases.py::test_binary[floor_divide(x1_i is -infinity and isfinite(x2_i) and x2_i < 0) -> +infinity] -array_api_tests/test_special_cases.py::test_binary[floor_divide(isfinite(x1_i) and x1_i > 0 and x2_i is -infinity) -> -0] -array_api_tests/test_special_cases.py::test_binary[floor_divide(isfinite(x1_i) and x1_i < 0 and x2_i is +infinity) -> -0] -array_api_tests/test_special_cases.py::test_binary[__floordiv__(x1_i is +infinity and isfinite(x2_i) and x2_i > 0) -> +infinity] -array_api_tests/test_special_cases.py::test_binary[__floordiv__(x1_i is +infinity and isfinite(x2_i) and x2_i < 0) -> -infinity] -array_api_tests/test_special_cases.py::test_binary[__floordiv__(x1_i is -infinity and isfinite(x2_i) and x2_i > 0) -> -infinity] -array_api_tests/test_special_cases.py::test_binary[__floordiv__(x1_i is -infinity and isfinite(x2_i) and x2_i < 0) -> +infinity] -array_api_tests/test_special_cases.py::test_binary[__floordiv__(isfinite(x1_i) and x1_i > 0 and x2_i is -infinity) -> -0] -array_api_tests/test_special_cases.py::test_binary[__floordiv__(isfinite(x1_i) and x1_i < 0 and x2_i is +infinity) -> -0] -array_api_tests/test_special_cases.py::test_binary[remainder(x1_i is -0 and x2_i > 0) -> +0] -array_api_tests/test_special_cases.py::test_binary[remainder(x1_i is +0 and x2_i < 0) -> -0] -array_api_tests/test_special_cases.py::test_binary[__mod__(x1_i is -0 and x2_i > 0) -> +0] -array_api_tests/test_special_cases.py::test_binary[__mod__(x1_i is +0 and x2_i < 0) -> -0] -array_api_tests/test_special_cases.py::test_iop[__ifloordiv__(x1_i is +infinity and isfinite(x2_i) and x2_i > 0) -> +infinity] -array_api_tests/test_special_cases.py::test_iop[__ifloordiv__(x1_i is +infinity and isfinite(x2_i) and x2_i < 0) -> -infinity] -array_api_tests/test_special_cases.py::test_iop[__ifloordiv__(x1_i is -infinity and isfinite(x2_i) and x2_i > 0) -> -infinity] -array_api_tests/test_special_cases.py::test_iop[__ifloordiv__(x1_i is -infinity and isfinite(x2_i) and x2_i < 0) -> +infinity] -array_api_tests/test_special_cases.py::test_iop[__ifloordiv__(isfinite(x1_i) and x1_i > 0 and x2_i is -infinity) -> -0] -array_api_tests/test_special_cases.py::test_iop[__ifloordiv__(isfinite(x1_i) and x1_i < 0 and x2_i is +infinity) -> -0] -array_api_tests/test_special_cases.py::test_iop[__imod__(x1_i is -0 and x2_i > 0) -> +0] -array_api_tests/test_special_cases.py::test_iop[__imod__(x1_i is +0 and x2_i < 0) -> -0] -# std special cases -array_api_tests/test_statistical_functions.py::test_std -array_api_tests/test_special_cases.py::test_empty_arrays[std] -array_api_tests/test_special_cases.py::test_nan_propagation[std] From 5db33f9c7c6c79c46908b4970524fedbf01a77ad Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 11 Mar 2024 12:52:58 +0000 Subject: [PATCH 126/150] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- heat/array_api/test/skips.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/heat/array_api/test/skips.txt b/heat/array_api/test/skips.txt index f5db3e8dd9..fc79551649 100644 --- a/heat/array_api/test/skips.txt +++ b/heat/array_api/test/skips.txt @@ -575,4 +575,4 @@ array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i is -0 and x2_i < 0 array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i < 0 and isfinite(x1_i) and isfinite(x2_i) and not x2_i.is_integer()) -> NaN] array_api_tests/test_special_cases.py::test_empty_arrays[sum] array_api_tests/test_special_cases.py::test_nan_propagation[mean] -array_api_tests/test_special_cases.py::test_nan_propagation[var] \ No newline at end of file +array_api_tests/test_special_cases.py::test_nan_propagation[var] From 981aba6b686966bb8dbca72e579b7c157b68fbe8 Mon Sep 17 00:00:00 2001 From: Michael Tarnawa Date: Mon, 11 Mar 2024 14:01:07 +0100 Subject: [PATCH 127/150] Update array-api.yml --- .github/workflows/array-api.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/array-api.yml b/.github/workflows/array-api.yml index a53603d32d..988feca174 100644 --- a/.github/workflows/array-api.yml +++ b/.github/workflows/array-api.yml @@ -50,4 +50,4 @@ jobs: export PYTHONPATH="${GITHUB_WORKSPACE}/heat" # Skip testing functions with known issues cd ${GITHUB_WORKSPACE}/array-api-tests - pytest array_api_tests/ -v -rxXfE --ci --skips-file ${GITHUB_WORKSPACE}/heat/array_api/test/skips.txt + pytest array_api_tests/ -v -rxXfE --ci --skips-file ${GITHUB_WORKSPACE}/heat/heat/array_api/test/skips.txt From 140fd4cbf1ef8fdc17ef814d3afa9b0f79d36bfd Mon Sep 17 00:00:00 2001 From: Michael Tarnawa Date: Mon, 11 Mar 2024 14:31:10 +0100 Subject: [PATCH 128/150] Update array-api.yml --- .github/workflows/array-api.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/array-api.yml b/.github/workflows/array-api.yml index 988feca174..ffef87ecd7 100644 --- a/.github/workflows/array-api.yml +++ b/.github/workflows/array-api.yml @@ -50,4 +50,4 @@ jobs: export PYTHONPATH="${GITHUB_WORKSPACE}/heat" # Skip testing functions with known issues cd ${GITHUB_WORKSPACE}/array-api-tests - pytest array_api_tests/ -v -rxXfE --ci --skips-file ${GITHUB_WORKSPACE}/heat/heat/array_api/test/skips.txt + pytest array_api_tests/ -v -rxXfE --ci --skips-file ${GITHUB_WORKSPACE}/heat/heat/array_api/test/skips.txt --disable-extension linalg From b18cf98d341b25ba3801b586ba0199f6e21ce826 Mon Sep 17 00:00:00 2001 From: Michael Tarnawa Date: Mon, 11 Mar 2024 14:43:09 +0100 Subject: [PATCH 129/150] update skips --- heat/array_api/test/skips.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/heat/array_api/test/skips.txt b/heat/array_api/test/skips.txt index fc79551649..caddf909c8 100644 --- a/heat/array_api/test/skips.txt +++ b/heat/array_api/test/skips.txt @@ -191,6 +191,7 @@ array_api_tests/test_operators_and_elementwise_functions.py::test_add[add(x1, x2 array_api_tests/test_operators_and_elementwise_functions.py::test_add[__add__(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_add[__add__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_add[__iadd__(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_add[__iadd__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_asin array_api_tests/test_operators_and_elementwise_functions.py::test_asinh array_api_tests/test_operators_and_elementwise_functions.py::test_atan @@ -213,6 +214,7 @@ array_api_tests/test_operators_and_elementwise_functions.py::test_expm1 array_api_tests/test_operators_and_elementwise_functions.py::test_floor array_api_tests/test_operators_and_elementwise_functions.py::test_greater[greater(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_greater[__gt__(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_greater[__gt__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_greater_equal[greater_equal(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_greater_equal[__ge__(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_greater_equal[__ge__(x, s)] @@ -235,6 +237,7 @@ array_api_tests/test_operators_and_elementwise_functions.py::test_multiply[multi array_api_tests/test_operators_and_elementwise_functions.py::test_multiply[__mul__(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_multiply[__mul__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_multiply[__imul__(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_multiply[__imul__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_not_equal[not_equal(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_not_equal[__ne__(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_not_equal[__ne__(x, s)] @@ -247,6 +250,7 @@ array_api_tests/test_operators_and_elementwise_functions.py::test_sqrt array_api_tests/test_operators_and_elementwise_functions.py::test_subtract[subtract(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_subtract[__sub__(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_subtract[__sub__(x, s)] +array_api_tests/test_operators_and_elementwise_functions.py::test_subtract[__isub__(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_subtract[__isub__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_tan array_api_tests/test_operators_and_elementwise_functions.py::test_tanh From acbfa0535ab0e31bddfd7618c1d1871e9323ef31 Mon Sep 17 00:00:00 2001 From: Michael Tarnawa Date: Mon, 11 Mar 2024 15:10:52 +0100 Subject: [PATCH 130/150] update skips --- heat/array_api/test/skips.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/heat/array_api/test/skips.txt b/heat/array_api/test/skips.txt index caddf909c8..ca18ab444d 100644 --- a/heat/array_api/test/skips.txt +++ b/heat/array_api/test/skips.txt @@ -197,6 +197,7 @@ array_api_tests/test_operators_and_elementwise_functions.py::test_asinh array_api_tests/test_operators_and_elementwise_functions.py::test_atan array_api_tests/test_operators_and_elementwise_functions.py::test_atan2 array_api_tests/test_operators_and_elementwise_functions.py::test_atanh +array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_or[bitwise_or(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_ceil array_api_tests/test_operators_and_elementwise_functions.py::test_conj array_api_tests/test_operators_and_elementwise_functions.py::test_cos From 188303a93bb4ae0afd87ccc15850b1d6ec3a3905 Mon Sep 17 00:00:00 2001 From: Michael Tarnawa Date: Mon, 11 Mar 2024 15:29:43 +0100 Subject: [PATCH 131/150] update skips.txt --- heat/array_api/test/skips.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/heat/array_api/test/skips.txt b/heat/array_api/test/skips.txt index ca18ab444d..34a4d74877 100644 --- a/heat/array_api/test/skips.txt +++ b/heat/array_api/test/skips.txt @@ -198,6 +198,7 @@ array_api_tests/test_operators_and_elementwise_functions.py::test_atan array_api_tests/test_operators_and_elementwise_functions.py::test_atan2 array_api_tests/test_operators_and_elementwise_functions.py::test_atanh array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_or[bitwise_or(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_or[__or__(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_ceil array_api_tests/test_operators_and_elementwise_functions.py::test_conj array_api_tests/test_operators_and_elementwise_functions.py::test_cos From 7fff72b792f1be12657a0145067b85fa2e344aa2 Mon Sep 17 00:00:00 2001 From: Michael Tarnawa Date: Tue, 12 Mar 2024 08:47:23 +0100 Subject: [PATCH 132/150] Update skips.txt --- heat/array_api/test/skips.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/heat/array_api/test/skips.txt b/heat/array_api/test/skips.txt index 34a4d74877..ba70eaa97a 100644 --- a/heat/array_api/test/skips.txt +++ b/heat/array_api/test/skips.txt @@ -199,6 +199,7 @@ array_api_tests/test_operators_and_elementwise_functions.py::test_atan2 array_api_tests/test_operators_and_elementwise_functions.py::test_atanh array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_or[bitwise_or(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_or[__or__(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_xor[bitwise_xor(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_ceil array_api_tests/test_operators_and_elementwise_functions.py::test_conj array_api_tests/test_operators_and_elementwise_functions.py::test_cos From 3b86d54b44098411e6355a9e7365ebc1e77dc6ee Mon Sep 17 00:00:00 2001 From: Michael Tarnawa Date: Wed, 27 Mar 2024 11:16:27 +0100 Subject: [PATCH 133/150] Update array-api.yml --- .github/workflows/array-api.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/array-api.yml b/.github/workflows/array-api.yml index ffef87ecd7..ff000d35f4 100644 --- a/.github/workflows/array-api.yml +++ b/.github/workflows/array-api.yml @@ -50,4 +50,4 @@ jobs: export PYTHONPATH="${GITHUB_WORKSPACE}/heat" # Skip testing functions with known issues cd ${GITHUB_WORKSPACE}/array-api-tests - pytest array_api_tests/ -v -rxXfE --ci --skips-file ${GITHUB_WORKSPACE}/heat/heat/array_api/test/skips.txt --disable-extension linalg + pytest array_api_tests/ -v -rxXfE --ci --xfails-file ${GITHUB_WORKSPACE}/heat/heat/array_api/test/skips.txt --disable-extension linalg From 6b13c3dc45e7f4c4d1ac3d43605b991667aa0362 Mon Sep 17 00:00:00 2001 From: Michael Tarnawa Date: Wed, 10 Jul 2024 08:43:57 +0200 Subject: [PATCH 134/150] add complex types --- heat/array_api/__init__.py | 10 +++++-- heat/array_api/_dtypes.py | 55 ++++++++++++++++++++++++++++++++--- heat/array_api/test/skips.txt | 1 + 3 files changed, 59 insertions(+), 7 deletions(-) diff --git a/heat/array_api/__init__.py b/heat/array_api/__init__.py index e1eef32c20..a02e69e3d7 100644 --- a/heat/array_api/__init__.py +++ b/heat/array_api/__init__.py @@ -6,7 +6,7 @@ warnings.warn("The heat.array_api submodule is not fully implemented.", stacklevel=2) -__array_api_version__ = "2022.12" +__array_api_version__ = "2023.12" __all__ = ["__array_api_version__"] @@ -84,6 +84,7 @@ __all__ += ["gpu"] from ._dtypes import ( + bool, int8, int16, int32, @@ -94,10 +95,12 @@ # uint64, float32, float64, - bool, + complex64, + complex128, ) __all__ += [ + "bool", "int8", "int16", "int32", @@ -108,7 +111,8 @@ # "uint64", "float32", "float64", - "bool", + "complex64", + "complex128", ] from ._elementwise_functions import ( diff --git a/heat/array_api/_dtypes.py b/heat/array_api/_dtypes.py index 0747809cc2..359bafa921 100644 --- a/heat/array_api/_dtypes.py +++ b/heat/array_api/_dtypes.py @@ -1,5 +1,7 @@ import heat as ht +bool = ht.bool +"""Boolean (``True`` or ``False``).""" int8 = ht.int8 """An 8-bit signed integer whose values exist on the interval ``[-128, +127]``.""" int16 = ht.int16 @@ -22,14 +24,18 @@ """IEEE 754 single-precision (32-bit) binary floating-point number (see IEEE 754-2019).""" float64 = ht.float64 """IEEE 754 double-precision (64-bit) binary floating-point number (see IEEE 754-2019).""" -bool = ht.bool -"""Boolean (``True`` or ``False``).""" +complex64 = ht.complex64 +"""Single-precision (64-bit) complex floating-point number whose real and imaginary components must be IEEE 754 single-precision (32-bit) binary floating-point numbers (see IEEE 754-2019).""" +complex128 = ht.complex128 +"""Double-precision (128-bit) complex floating-point number whose real and imaginary components must be IEEE 754 double-precision (64-bit) binary floating-point numbers (see IEEE 754-2019).""" + default_int = int64 """Default integer data type is ``int64``""" default_float = float64 """Default floating-point data type is ``float64``""" _all_dtypes = ( + bool, int8, int16, int32, @@ -40,10 +46,13 @@ # uint64, float32, float64, - bool, + complex64, + complex128, ) _boolean_dtypes = (bool,) -_floating_dtypes = (float32, float64) +_real_floating_dtypes = (float32, float64) +_floating_dtypes = (float32, float64, complex64, complex128) +_complex_floating_dtypes = (complex64, complex128) _integer_dtypes = ( int8, int16, @@ -54,6 +63,13 @@ # uint32, # uint64 ) +_signed_integer_dtypes = (int8, int16, int32, int64) +_unsigned_integer_dtypes = ( + uint8, + # uint16, + # utnt32, + # uint64 +) _integer_or_boolean_dtypes = ( bool, int8, @@ -65,9 +81,23 @@ # uint32, # uint64, ) +_real_numeric_dtypes = ( + float32, + float64, + int8, + int16, + int32, + int64, + uint8, + # uint16, + # uint32, + # uint64, +) _numeric_dtypes = ( float32, float64, + complex64, + complex128, int8, int16, int32, @@ -80,10 +110,13 @@ _dtype_categories = { "all": _all_dtypes, + "real numeric": _real_numeric_dtypes, "numeric": _numeric_dtypes, "integer": _integer_dtypes, "integer or boolean": _integer_or_boolean_dtypes, "boolean": _boolean_dtypes, + "real floating-point": _floating_dtypes, + "complex floating-point": _complex_floating_dtypes, "floating-point": _floating_dtypes, } @@ -148,6 +181,20 @@ (float32, float64): float64, (float64, float32): float64, (float64, float64): float64, + (complex64, complex64): complex64, + (complex128, complex128): complex128, + (complex64, complex64): complex64, + (complex64, complex128): complex128, + (complex128, complex64): complex128, + (complex128, complex128): complex128, + (float32, complex64): complex64, + (float32, complex128): complex128, + (float64, complex64): complex128, + (float64, complex128): complex128, + (complex64, float32): complex64, + (complex64, float64): complex128, + (complex128, float32): complex128, + (complex128, float64): complex128, (bool, bool): bool, } diff --git a/heat/array_api/test/skips.txt b/heat/array_api/test/skips.txt index ba70eaa97a..1af9f3f003 100644 --- a/heat/array_api/test/skips.txt +++ b/heat/array_api/test/skips.txt @@ -583,3 +583,4 @@ array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i < 0 and isfinite(x array_api_tests/test_special_cases.py::test_empty_arrays[sum] array_api_tests/test_special_cases.py::test_nan_propagation[mean] array_api_tests/test_special_cases.py::test_nan_propagation[var] +array_api_tests/test_searching_functions.py::test_nonzero_zerodim_error From 6fe8134af166328643195bbf5a23ccb896048786 Mon Sep 17 00:00:00 2001 From: Michael Tarnawa Date: Thu, 11 Jul 2024 11:03:37 +0200 Subject: [PATCH 135/150] update skips.txt/xfails.txt --- heat/array_api/test/skips.txt | 542 +++++++++------------------------ heat/array_api/test/xfails.txt | 318 +++++++++++++++++++ 2 files changed, 455 insertions(+), 405 deletions(-) create mode 100644 heat/array_api/test/xfails.txt diff --git a/heat/array_api/test/skips.txt b/heat/array_api/test/skips.txt index 1af9f3f003..d3a81ea0e0 100644 --- a/heat/array_api/test/skips.txt +++ b/heat/array_api/test/skips.txt @@ -1,145 +1,26 @@ -# fft -array_api_tests/test_fft.py::test_fft -array_api_tests/test_fft.py::test_ifft -array_api_tests/test_fft.py::test_fftn -array_api_tests/test_fft.py::test_ifftn -array_api_tests/test_fft.py::test_rfft -array_api_tests/test_fft.py::test_irfft -array_api_tests/test_fft.py::test_rfftn -array_api_tests/test_fft.py::test_irfftn -array_api_tests/test_fft.py::test_hfft -array_api_tests/test_fft.py::test_ihfft - -# PR #938 Indexing overhaul array_api_tests/test_array_object.py::test_getitem array_api_tests/test_array_object.py::test_setitem array_api_tests/test_array_object.py::test_getitem_masking array_api_tests/test_array_object.py::test_setitem_masking -# array_api_tests/test_linalg.py::test_matrix_matmul -array_api_tests/test_manipulation_functions.py::test_concat -array_api_tests/test_manipulation_functions.py::test_stack -array_api_tests/test_searching_functions.py::test_argmax -array_api_tests/test_searching_functions.py::test_argmin -array_api_tests/test_searching_functions.py::test_nonzero -array_api_tests/test_searching_functions.py::test_where -array_api_tests/test_special_cases.py::test_nan_propagation[max] -array_api_tests/test_special_cases.py::test_nan_propagation[min] -array_api_tests/test_special_cases.py::test_nan_propagation[prod] -array_api_tests/test_special_cases.py::test_nan_propagation[sum] -array_api_tests/test_special_cases.py::test_binary[add(isfinite(x1_i) and x1_i != 0 and x2_i == -x1_i) -> +0] -array_api_tests/test_special_cases.py::test_iop[__iadd__(isfinite(x1_i) and x1_i != 0 and x2_i == -x1_i) -> +0] -array_api_tests/test_statistical_functions.py::test_max -array_api_tests/test_statistical_functions.py::test_mean -array_api_tests/test_statistical_functions.py::test_min -array_api_tests/test_statistical_functions.py::test_prod -array_api_tests/test_statistical_functions.py::test_var -array_api_tests/test_utility_functions.py::test_all -array_api_tests/test_utility_functions.py::test_any - -# Pytorch dtypes https://github.com/pytorch/pytorch/issues/58734 -array_api_tests/test_array_object.py::test_scalar_casting[__int__(uint16)] -array_api_tests/test_array_object.py::test_scalar_casting[__int__(uint32)] -array_api_tests/test_array_object.py::test_scalar_casting[__int__(uint64)] -array_api_tests/test_array_object.py::test_scalar_casting[__index__(uint16)] -array_api_tests/test_array_object.py::test_scalar_casting[__index__(uint32)] -array_api_tests/test_array_object.py::test_scalar_casting[__index__(uint64)] -array_api_tests/test_data_type_functions.py::test_iinfo[uint16] -array_api_tests/test_data_type_functions.py::test_iinfo[uint32] -array_api_tests/test_data_type_functions.py::test_iinfo[uint64] -array_api_tests/test_statistical_functions.py::test_sum -array_api_tests/test_type_promotion.py - -# PR #1000 any/all keepdim -# array_api_tests/test_linalg.py::test_matrix_transpose -array_api_tests/test_operators_and_elementwise_functions.py::test_abs -array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_left_shift -array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_right_shift -array_api_tests/test_operators_and_elementwise_functions.py::test_floor_divide -array_api_tests/test_operators_and_elementwise_functions.py::test_positive -array_api_tests/test_operators_and_elementwise_functions.py::test_pow -array_api_tests/test_operators_and_elementwise_functions.py::test_remainder - -# PR #993 Precision loss +array_api_tests/test_array_object.py::test_scalar_casting[__float__(float64)] array_api_tests/test_creation_functions.py::test_arange -array_api_tests/test_creation_functions.py::test_linspace - -# PR #1018 __reduce_op bug array_api_tests/test_creation_functions.py::test_asarray_arrays +array_api_tests/test_creation_functions.py::test_empty_like +array_api_tests/test_creation_functions.py::test_eye array_api_tests/test_creation_functions.py::test_full array_api_tests/test_creation_functions.py::test_full_like +array_api_tests/test_creation_functions.py::test_linspace +array_api_tests/test_creation_functions.py::test_meshgrid array_api_tests/test_creation_functions.py::test_ones array_api_tests/test_creation_functions.py::test_ones_like array_api_tests/test_creation_functions.py::test_zeros array_api_tests/test_creation_functions.py::test_zeros_like -array_api_tests/test_operators_and_elementwise_functions.py::test_negative -array_api_tests/test_special_cases.py::test_empty_arrays[prod] -array_api_tests/test_special_cases.py::test_nan_propagation[sum] - -# k not implemented -array_api_tests/test_creation_functions.py::test_eye - -# PR #1020 broadcasting +array_api_tests/test_data_type_functions.py::test_astype array_api_tests/test_data_type_functions.py::test_broadcast_arrays array_api_tests/test_data_type_functions.py::test_broadcast_to - -# PR #749 unique -array_api_tests/test_set_functions.py::test_unique_all -array_api_tests/test_set_functions.py::test_unique_counts -array_api_tests/test_set_functions.py::test_unique_inverse -array_api_tests/test_set_functions.py::test_unique_values -array_api_tests/test_signatures.py::test_func_signature[unique_all] -array_api_tests/test_signatures.py::test_func_signature[unique_counts] -array_api_tests/test_sorting_functions.py::test_sort - -# PR #996 argsort -array_api_tests/test_signatures.py::test_func_signature[argsort] -array_api_tests/test_sorting_functions.py::test_argsort - -# tensordot -# array_api_tests/test_linalg.py::test_tensordot - -# Special cases -array_api_tests/test_operators_and_elementwise_functions.py::test_square -array_api_tests/test_special_cases.py::test_binary[floor_divide(x1_i is +infinity and isfinite(x2_i) and x2_i > 0) -> +infinity] -array_api_tests/test_special_cases.py::test_binary[floor_divide(x1_i is +infinity and isfinite(x2_i) and x2_i < 0) -> -infinity] -array_api_tests/test_special_cases.py::test_binary[floor_divide(x1_i is -infinity and isfinite(x2_i) and x2_i > 0) -> -infinity] -array_api_tests/test_special_cases.py::test_binary[floor_divide(x1_i is -infinity and isfinite(x2_i) and x2_i < 0) -> +infinity] -array_api_tests/test_special_cases.py::test_binary[floor_divide(isfinite(x1_i) and x1_i > 0 and x2_i is -infinity) -> -0] -array_api_tests/test_special_cases.py::test_binary[floor_divide(isfinite(x1_i) and x1_i < 0 and x2_i is +infinity) -> -0] -array_api_tests/test_special_cases.py::test_binary[__floordiv__(x1_i is +infinity and isfinite(x2_i) and x2_i > 0) -> +infinity] -array_api_tests/test_special_cases.py::test_binary[__floordiv__(x1_i is +infinity and isfinite(x2_i) and x2_i < 0) -> -infinity] -array_api_tests/test_special_cases.py::test_binary[__floordiv__(x1_i is -infinity and isfinite(x2_i) and x2_i > 0) -> -infinity] -array_api_tests/test_special_cases.py::test_binary[__floordiv__(x1_i is -infinity and isfinite(x2_i) and x2_i < 0) -> +infinity] -array_api_tests/test_special_cases.py::test_binary[__floordiv__(isfinite(x1_i) and x1_i > 0 and x2_i is -infinity) -> -0] -array_api_tests/test_special_cases.py::test_binary[__floordiv__(isfinite(x1_i) and x1_i < 0 and x2_i is +infinity) -> -0] -array_api_tests/test_special_cases.py::test_binary[remainder(x1_i is -0 and x2_i > 0) -> +0] -array_api_tests/test_special_cases.py::test_binary[remainder(x1_i is +0 and x2_i < 0) -> -0] -array_api_tests/test_special_cases.py::test_binary[__mod__(x1_i is -0 and x2_i > 0) -> +0] -array_api_tests/test_special_cases.py::test_binary[__mod__(x1_i is +0 and x2_i < 0) -> -0] -array_api_tests/test_special_cases.py::test_iop[__ifloordiv__(x1_i is +infinity and isfinite(x2_i) and x2_i > 0) -> +infinity] -array_api_tests/test_special_cases.py::test_iop[__ifloordiv__(x1_i is +infinity and isfinite(x2_i) and x2_i < 0) -> -infinity] -array_api_tests/test_special_cases.py::test_iop[__ifloordiv__(x1_i is -infinity and isfinite(x2_i) and x2_i > 0) -> -infinity] -array_api_tests/test_special_cases.py::test_iop[__ifloordiv__(x1_i is -infinity and isfinite(x2_i) and x2_i < 0) -> +infinity] -array_api_tests/test_special_cases.py::test_iop[__ifloordiv__(isfinite(x1_i) and x1_i > 0 and x2_i is -infinity) -> -0] -array_api_tests/test_special_cases.py::test_iop[__ifloordiv__(isfinite(x1_i) and x1_i < 0 and x2_i is +infinity) -> -0] -array_api_tests/test_special_cases.py::test_iop[__imod__(x1_i is -0 and x2_i > 0) -> +0] -array_api_tests/test_special_cases.py::test_iop[__imod__(x1_i is +0 and x2_i < 0) -> -0] -# std special cases -array_api_tests/test_statistical_functions.py::test_std -array_api_tests/test_special_cases.py::test_empty_arrays[std] -array_api_tests/test_special_cases.py::test_nan_propagation[std] - -# skip FAILED tests -array_api_tests/test_array_object.py::test_scalar_casting[__float__(float64)] -array_api_tests/test_creation_functions.py::test_asarray_scalars -array_api_tests/test_creation_functions.py::test_empty -array_api_tests/test_creation_functions.py::test_empty_like -array_api_tests/test_creation_functions.py::test_meshgrid -array_api_tests/test_data_type_functions.py::test_astype array_api_tests/test_data_type_functions.py::test_can_cast array_api_tests/test_data_type_functions.py::test_finfo[float32] array_api_tests/test_data_type_functions.py::test_finfo[float64] -array_api_tests/test_data_type_functions.py::test_iinfo[uint8] array_api_tests/test_data_type_functions.py::test_iinfo[int8] array_api_tests/test_data_type_functions.py::test_iinfo[int16] array_api_tests/test_data_type_functions.py::test_iinfo[int32] @@ -147,8 +28,6 @@ array_api_tests/test_data_type_functions.py::test_iinfo[int64] array_api_tests/test_data_type_functions.py::test_isdtype array_api_tests/test_has_names.py::test_has_names[linalg-cholesky] array_api_tests/test_has_names.py::test_has_names[linalg-cross] -array_api_tests/test_has_names.py::test_has_names[linalg-cholesky] -array_api_tests/test_has_names.py::test_has_names[linalg-cross] array_api_tests/test_has_names.py::test_has_names[linalg-det] array_api_tests/test_has_names.py::test_has_names[linalg-diagonal] array_api_tests/test_has_names.py::test_has_names[linalg-eigh] @@ -166,42 +45,78 @@ array_api_tests/test_has_names.py::test_has_names[linalg-svd] array_api_tests/test_has_names.py::test_has_names[linalg-svdvals] array_api_tests/test_has_names.py::test_has_names[linalg-trace] array_api_tests/test_has_names.py::test_has_names[linalg-vector_norm] -array_api_tests/test_has_names.py::test_has_names[data_type-isdtype] +array_api_tests/test_has_names.py::test_has_names[fft-fft] +array_api_tests/test_has_names.py::test_has_names[fft-ifft] +array_api_tests/test_has_names.py::test_has_names[fft-fftn] +array_api_tests/test_has_names.py::test_has_names[fft-ifftn] +array_api_tests/test_has_names.py::test_has_names[fft-rfft] +array_api_tests/test_has_names.py::test_has_names[fft-irfft] +array_api_tests/test_has_names.py::test_has_names[fft-rfftn] +array_api_tests/test_has_names.py::test_has_names[fft-irfftn] +array_api_tests/test_has_names.py::test_has_names[fft-hfft] +array_api_tests/test_has_names.py::test_has_names[fft-ihfft] +array_api_tests/test_has_names.py::test_has_names[fft-fftfreq] +array_api_tests/test_has_names.py::test_has_names[fft-rfftfreq] +array_api_tests/test_has_names.py::test_has_names[fft-fftshift] +array_api_tests/test_has_names.py::test_has_names[fft-ifftshift] array_api_tests/test_has_names.py::test_has_names[indexing-take] -array_api_tests/test_has_names.py::test_has_names[sorting-argsort] array_api_tests/test_has_names.py::test_has_names[set-unique_all] array_api_tests/test_has_names.py::test_has_names[set-unique_counts] +array_api_tests/test_has_names.py::test_has_names[manipulation-moveaxis] +array_api_tests/test_has_names.py::test_has_names[manipulation-repeat] +array_api_tests/test_has_names.py::test_has_names[manipulation-tile] +array_api_tests/test_has_names.py::test_has_names[manipulation-unstack] +array_api_tests/test_has_names.py::test_has_names[searching-searchsorted] +array_api_tests/test_has_names.py::test_has_names[elementwise-clip] array_api_tests/test_has_names.py::test_has_names[elementwise-conj] +array_api_tests/test_has_names.py::test_has_names[elementwise-copysign] +array_api_tests/test_has_names.py::test_has_names[elementwise-hypot] array_api_tests/test_has_names.py::test_has_names[elementwise-imag] +array_api_tests/test_has_names.py::test_has_names[elementwise-maximum] +array_api_tests/test_has_names.py::test_has_names[elementwise-minimum] array_api_tests/test_has_names.py::test_has_names[elementwise-real] +array_api_tests/test_has_names.py::test_has_names[elementwise-signbit] +array_api_tests/test_has_names.py::test_has_names[statistical-cumulative_sum] +array_api_tests/test_has_names.py::test_has_names[sorting-argsort] +array_api_tests/test_has_names.py::test_has_names[data_type-isdtype] +array_api_tests/test_has_names.py::test_has_names[info-__array_namespace_info__] array_api_tests/test_has_names.py::test_has_names[array_method-__complex__] array_api_tests/test_indexing_functions.py::test_take -array_api_tests/test_linalg.py::test_matmul +array_api_tests/test_inspection_functions.py::test_array_namespace_info +array_api_tests/test_inspection_functions.py::test_array_namespace_info_dtypes array_api_tests/test_linalg.py::test_matrix_transpose array_api_tests/test_linalg.py::test_tensordot array_api_tests/test_linalg.py::test_vecdot +array_api_tests/test_manipulation_functions.py::test_concat array_api_tests/test_manipulation_functions.py::test_expand_dims +array_api_tests/test_manipulation_functions.py::test_moveaxis array_api_tests/test_manipulation_functions.py::test_squeeze array_api_tests/test_manipulation_functions.py::test_flip -array_api_tests/test_manipulation_functions.py::test_permute_dims -array_api_tests/test_manipulation_functions.py::test_roll +array_api_tests/test_manipulation_functions.py::test_repeat +array_api_tests/test_manipulation_functions.py::test_stack +array_api_tests/test_manipulation_functions.py::test_tile +array_api_tests/test_manipulation_functions.py::test_unstack +array_api_tests/test_operators_and_elementwise_functions.py::test_abs[abs] +array_api_tests/test_operators_and_elementwise_functions.py::test_abs[__abs__] array_api_tests/test_operators_and_elementwise_functions.py::test_acos array_api_tests/test_operators_and_elementwise_functions.py::test_acosh array_api_tests/test_operators_and_elementwise_functions.py::test_add[add(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_add[__add__(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_add[__add__(x, s)] -array_api_tests/test_operators_and_elementwise_functions.py::test_add[__iadd__(x1, x2)] -array_api_tests/test_operators_and_elementwise_functions.py::test_add[__iadd__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_asin array_api_tests/test_operators_and_elementwise_functions.py::test_asinh array_api_tests/test_operators_and_elementwise_functions.py::test_atan array_api_tests/test_operators_and_elementwise_functions.py::test_atan2 array_api_tests/test_operators_and_elementwise_functions.py::test_atanh -array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_or[bitwise_or(x1, x2)] -array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_or[__or__(x1, x2)] -array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_xor[bitwise_xor(x1, x2)] -array_api_tests/test_operators_and_elementwise_functions.py::test_ceil +array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_left_shift[bitwise_left_shift(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_left_shift[__lshift__(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_left_shift[__ilshift__(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_right_shift[bitwise_right_shift(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_right_shift[__rshift__(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_right_shift[__irshift__(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_clip array_api_tests/test_operators_and_elementwise_functions.py::test_conj +array_api_tests/test_operators_and_elementwise_functions.py::test_copysign array_api_tests/test_operators_and_elementwise_functions.py::test_cos array_api_tests/test_operators_and_elementwise_functions.py::test_cosh array_api_tests/test_operators_and_elementwise_functions.py::test_divide[divide(x1, x2)] @@ -211,212 +126,118 @@ array_api_tests/test_operators_and_elementwise_functions.py::test_divide[__itrue array_api_tests/test_operators_and_elementwise_functions.py::test_divide[__itruediv__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_equal[equal(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_equal[__eq__(x1, x2)] -array_api_tests/test_operators_and_elementwise_functions.py::test_equal[__eq__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_exp array_api_tests/test_operators_and_elementwise_functions.py::test_expm1 -array_api_tests/test_operators_and_elementwise_functions.py::test_floor -array_api_tests/test_operators_and_elementwise_functions.py::test_greater[greater(x1, x2)] -array_api_tests/test_operators_and_elementwise_functions.py::test_greater[__gt__(x1, x2)] -array_api_tests/test_operators_and_elementwise_functions.py::test_greater[__gt__(x, s)] -array_api_tests/test_operators_and_elementwise_functions.py::test_greater_equal[greater_equal(x1, x2)] -array_api_tests/test_operators_and_elementwise_functions.py::test_greater_equal[__ge__(x1, x2)] -array_api_tests/test_operators_and_elementwise_functions.py::test_greater_equal[__ge__(x, s)] +array_api_tests/test_operators_and_elementwise_functions.py::test_floor_divide[floor_divide(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_floor_divide[__floordiv__(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_floor_divide[__floordiv__(x, s)] +array_api_tests/test_operators_and_elementwise_functions.py::test_floor_divide[__ifloordiv__(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_floor_divide[__ifloordiv__(x, s)] +array_api_tests/test_operators_and_elementwise_functions.py::test_hypot array_api_tests/test_operators_and_elementwise_functions.py::test_imag -array_api_tests/test_operators_and_elementwise_functions.py::test_isfinite array_api_tests/test_operators_and_elementwise_functions.py::test_isinf -array_api_tests/test_operators_and_elementwise_functions.py::test_isnan array_api_tests/test_operators_and_elementwise_functions.py::test_less[less(x1, x2)] -array_api_tests/test_operators_and_elementwise_functions.py::test_less[__lt__(x1, x2)] -array_api_tests/test_operators_and_elementwise_functions.py::test_less[__lt__(x, s)] -array_api_tests/test_operators_and_elementwise_functions.py::test_less_equal[less_equal(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_less_equal[__le__(x1, x2)] -array_api_tests/test_operators_and_elementwise_functions.py::test_less_equal[__le__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_log array_api_tests/test_operators_and_elementwise_functions.py::test_log1p array_api_tests/test_operators_and_elementwise_functions.py::test_log2 array_api_tests/test_operators_and_elementwise_functions.py::test_log10 array_api_tests/test_operators_and_elementwise_functions.py::test_logaddexp +array_api_tests/test_operators_and_elementwise_functions.py::test_maximum +array_api_tests/test_operators_and_elementwise_functions.py::test_minimum array_api_tests/test_operators_and_elementwise_functions.py::test_multiply[multiply(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_multiply[__mul__(x1, x2)] -array_api_tests/test_operators_and_elementwise_functions.py::test_multiply[__mul__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_multiply[__imul__(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_multiply[__imul__(x, s)] +array_api_tests/test_operators_and_elementwise_functions.py::test_negative[negative] +array_api_tests/test_operators_and_elementwise_functions.py::test_negative[__neg__] array_api_tests/test_operators_and_elementwise_functions.py::test_not_equal[not_equal(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_not_equal[__ne__(x1, x2)] -array_api_tests/test_operators_and_elementwise_functions.py::test_not_equal[__ne__(x, s)] +array_api_tests/test_operators_and_elementwise_functions.py::test_positive[positive] +array_api_tests/test_operators_and_elementwise_functions.py::test_positive[__pos__] +array_api_tests/test_operators_and_elementwise_functions.py::test_pow[pow(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_pow[__pow__(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_pow[__pow__(x, s)] +array_api_tests/test_operators_and_elementwise_functions.py::test_pow[__ipow__(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_pow[__ipow__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_real array_api_tests/test_operators_and_elementwise_functions.py::test_round +array_api_tests/test_operators_and_elementwise_functions.py::test_signbit array_api_tests/test_operators_and_elementwise_functions.py::test_sign array_api_tests/test_operators_and_elementwise_functions.py::test_sin array_api_tests/test_operators_and_elementwise_functions.py::test_sinh +array_api_tests/test_operators_and_elementwise_functions.py::test_square array_api_tests/test_operators_and_elementwise_functions.py::test_sqrt array_api_tests/test_operators_and_elementwise_functions.py::test_subtract[subtract(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_subtract[__sub__(x1, x2)] -array_api_tests/test_operators_and_elementwise_functions.py::test_subtract[__sub__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_subtract[__isub__(x1, x2)] -array_api_tests/test_operators_and_elementwise_functions.py::test_subtract[__isub__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_tan array_api_tests/test_operators_and_elementwise_functions.py::test_tanh -array_api_tests/test_operators_and_elementwise_functions.py::test_trunc -array_api_tests/test_signatures.py::test_func_signature[isdtype] +array_api_tests/test_searching_functions.py::test_argmax +array_api_tests/test_searching_functions.py::test_argmin +array_api_tests/test_searching_functions.py::test_nonzero_zerodim_error +array_api_tests/test_searching_functions.py::test_nonzero +array_api_tests/test_searching_functions.py::test_searchsorted +array_api_tests/test_set_functions.py::test_unique_all +array_api_tests/test_set_functions.py::test_unique_counts +array_api_tests/test_set_functions.py::test_unique_inverse +array_api_tests/test_set_functions.py::test_unique_values +array_api_tests/test_signatures.py::test_func_signature[from_dlpack] array_api_tests/test_signatures.py::test_func_signature[take] +array_api_tests/test_signatures.py::test_func_signature[unique_all] +array_api_tests/test_signatures.py::test_func_signature[unique_counts] +array_api_tests/test_signatures.py::test_func_signature[moveaxis] +array_api_tests/test_signatures.py::test_func_signature[repeat] +array_api_tests/test_signatures.py::test_func_signature[tile] +array_api_tests/test_signatures.py::test_func_signature[unstack] +array_api_tests/test_signatures.py::test_func_signature[searchsorted] +array_api_tests/test_signatures.py::test_func_signature[clip] array_api_tests/test_signatures.py::test_func_signature[conj] +array_api_tests/test_signatures.py::test_func_signature[copysign] +array_api_tests/test_signatures.py::test_func_signature[hypot] array_api_tests/test_signatures.py::test_func_signature[imag] +array_api_tests/test_signatures.py::test_func_signature[maximum] +array_api_tests/test_signatures.py::test_func_signature[minimum] array_api_tests/test_signatures.py::test_func_signature[real] +array_api_tests/test_signatures.py::test_func_signature[signbit] +array_api_tests/test_signatures.py::test_func_signature[cumulative_sum] +array_api_tests/test_signatures.py::test_func_signature[argsort] +array_api_tests/test_signatures.py::test_func_signature[astype] +array_api_tests/test_signatures.py::test_func_signature[isdtype] +array_api_tests/test_signatures.py::test_func_signature[__array_namespace_info__] array_api_tests/test_signatures.py::test_array_method_signature[__complex__] -array_api_tests/test_special_cases.py::test_unary[abs(x_i is NaN) -> NaN] -array_api_tests/test_special_cases.py::test_unary[abs(x_i is -0) -> +0] -array_api_tests/test_special_cases.py::test_unary[abs(x_i is -infinity) -> +infinity] -array_api_tests/test_special_cases.py::test_unary[__abs__(x_i is NaN) -> NaN] -array_api_tests/test_special_cases.py::test_unary[__abs__(x_i is -0) -> +0] -array_api_tests/test_special_cases.py::test_unary[__abs__(x_i is -infinity) -> +infinity] -array_api_tests/test_special_cases.py::test_unary[acos(x_i is NaN) -> NaN] -array_api_tests/test_special_cases.py::test_unary[acos(x_i > 1) -> NaN] -array_api_tests/test_special_cases.py::test_unary[acos(x_i < -1) -> NaN] -array_api_tests/test_special_cases.py::test_unary[acos(x_i is 1) -> +0] -array_api_tests/test_special_cases.py::test_unary[acosh(x_i is NaN) -> NaN] -array_api_tests/test_special_cases.py::test_unary[acosh(x_i < 1) -> NaN] -array_api_tests/test_special_cases.py::test_unary[acosh(x_i is 1) -> +0] -array_api_tests/test_special_cases.py::test_unary[acosh(x_i is +infinity) -> +infinity] -array_api_tests/test_special_cases.py::test_unary[asin(x_i is NaN) -> NaN] -array_api_tests/test_special_cases.py::test_unary[asin(x_i > 1) -> NaN] -array_api_tests/test_special_cases.py::test_unary[asin(x_i < -1) -> NaN] -array_api_tests/test_special_cases.py::test_unary[asin(x_i is +0) -> +0] -array_api_tests/test_special_cases.py::test_unary[asin(x_i is -0) -> -0] -array_api_tests/test_special_cases.py::test_unary[asinh(x_i is NaN) -> NaN] -array_api_tests/test_special_cases.py::test_unary[asinh(x_i is +0) -> +0] -array_api_tests/test_special_cases.py::test_unary[asinh(x_i is -0) -> -0] -array_api_tests/test_special_cases.py::test_unary[asinh(x_i is +infinity) -> +infinity] -array_api_tests/test_special_cases.py::test_unary[asinh(x_i is -infinity) -> -infinity] -array_api_tests/test_special_cases.py::test_unary[atan(x_i is NaN) -> NaN] -array_api_tests/test_special_cases.py::test_unary[atan(x_i is +0) -> +0] -array_api_tests/test_special_cases.py::test_unary[atan(x_i is -0) -> -0] -array_api_tests/test_special_cases.py::test_unary[atan(x_i is +infinity) -> roughly +pi/2] -array_api_tests/test_special_cases.py::test_unary[atan(x_i is -infinity) -> roughly -pi/2] -array_api_tests/test_special_cases.py::test_unary[atanh(x_i is NaN) -> NaN] -array_api_tests/test_special_cases.py::test_unary[atanh(x_i < -1) -> NaN] -array_api_tests/test_special_cases.py::test_unary[atanh(x_i > 1) -> NaN] -array_api_tests/test_special_cases.py::test_unary[atanh(x_i is -1) -> -infinity] -array_api_tests/test_special_cases.py::test_unary[atanh(x_i is +1) -> +infinity] -array_api_tests/test_special_cases.py::test_unary[atanh(x_i is +0) -> +0] -array_api_tests/test_special_cases.py::test_unary[atanh(x_i is -0) -> -0] -array_api_tests/test_special_cases.py::test_unary[ceil(x_i.is_integer()) -> x_i] -array_api_tests/test_special_cases.py::test_unary[cos(x_i is NaN) -> NaN] -array_api_tests/test_special_cases.py::test_unary[cos(x_i is +0) -> 1] -array_api_tests/test_special_cases.py::test_unary[cos(x_i is -0) -> 1] -array_api_tests/test_special_cases.py::test_unary[cos(x_i is +infinity) -> NaN] -array_api_tests/test_special_cases.py::test_unary[cos(x_i is -infinity) -> NaN] -array_api_tests/test_special_cases.py::test_unary[cosh(x_i is NaN) -> NaN] -array_api_tests/test_special_cases.py::test_unary[cosh(x_i is +0) -> 1] -array_api_tests/test_special_cases.py::test_unary[cosh(x_i is -0) -> 1] -array_api_tests/test_special_cases.py::test_unary[cosh(x_i is +infinity) -> +infinity] -array_api_tests/test_special_cases.py::test_unary[cosh(x_i is -infinity) -> +infinity] -array_api_tests/test_special_cases.py::test_unary[exp(x_i is NaN) -> NaN] -array_api_tests/test_special_cases.py::test_unary[exp(x_i is +0) -> 1] -array_api_tests/test_special_cases.py::test_unary[exp(x_i is -0) -> 1] -array_api_tests/test_special_cases.py::test_unary[exp(x_i is +infinity) -> +infinity] -array_api_tests/test_special_cases.py::test_unary[exp(x_i is -infinity) -> +0] -array_api_tests/test_special_cases.py::test_unary[expm1(x_i is NaN) -> NaN] -array_api_tests/test_special_cases.py::test_unary[expm1(x_i is +0) -> +0] -array_api_tests/test_special_cases.py::test_unary[expm1(x_i is -0) -> -0] -array_api_tests/test_special_cases.py::test_unary[expm1(x_i is +infinity) -> +infinity] -array_api_tests/test_special_cases.py::test_unary[expm1(x_i is -infinity) -> -1] +array_api_tests/test_signatures.py::test_array_method_signature[__dlpack__] +array_api_tests/test_signatures.py::test_info_func_signature[capabilities] +array_api_tests/test_signatures.py::test_info_func_signature[default_device] +array_api_tests/test_signatures.py::test_info_func_signature[default_dtypes] +array_api_tests/test_signatures.py::test_info_func_signature[devices] +array_api_tests/test_signatures.py::test_info_func_signature[dtypes] +array_api_tests/test_sorting_functions.py::test_argsort +array_api_tests/test_sorting_functions.py::test_sort array_api_tests/test_special_cases.py::test_unary[floor(x_i.is_integer()) -> x_i] array_api_tests/test_special_cases.py::test_unary[isfinite((x_i is +infinity or x_i == -infinity)) -> False] array_api_tests/test_special_cases.py::test_unary[isfinite(x_i is NaN) -> False] array_api_tests/test_special_cases.py::test_unary[isfinite(isfinite(x_i)) -> True] array_api_tests/test_special_cases.py::test_unary[isinf((x_i is +infinity or x_i == -infinity)) -> True] array_api_tests/test_special_cases.py::test_unary[isnan(x_i is NaN) -> True] -array_api_tests/test_special_cases.py::test_unary[log(x_i is NaN) -> NaN] -array_api_tests/test_special_cases.py::test_unary[log(x_i < 0) -> NaN] -array_api_tests/test_special_cases.py::test_unary[log((x_i is +0 or x_i == -0)) -> -infinity] -array_api_tests/test_special_cases.py::test_unary[log(x_i is 1) -> +0] -array_api_tests/test_special_cases.py::test_unary[log(x_i is +infinity) -> +infinity] -array_api_tests/test_special_cases.py::test_unary[log1p(x_i is NaN) -> NaN] -array_api_tests/test_special_cases.py::test_unary[log1p(x_i < -1) -> NaN] -array_api_tests/test_special_cases.py::test_unary[log1p(x_i is -1) -> -infinity] -array_api_tests/test_special_cases.py::test_unary[log1p(x_i is -0) -> -0] -array_api_tests/test_special_cases.py::test_unary[log1p(x_i is +0) -> +0] -array_api_tests/test_special_cases.py::test_unary[log1p(x_i is +infinity) -> +infinity] -array_api_tests/test_special_cases.py::test_unary[log2(x_i is NaN) -> NaN] -array_api_tests/test_special_cases.py::test_unary[log2(x_i < 0) -> NaN] -array_api_tests/test_special_cases.py::test_unary[log2((x_i is +0 or x_i == -0)) -> -infinity] -array_api_tests/test_special_cases.py::test_unary[log2(x_i is 1) -> +0] -array_api_tests/test_special_cases.py::test_unary[log2(x_i is +infinity) -> +infinity] -array_api_tests/test_special_cases.py::test_unary[log10(x_i is NaN) -> NaN] -array_api_tests/test_special_cases.py::test_unary[log10(x_i < 0) -> NaN] -array_api_tests/test_special_cases.py::test_unary[log10((x_i is +0 or x_i == -0)) -> -infinity] -array_api_tests/test_special_cases.py::test_unary[log10(x_i is 1) -> +0] -array_api_tests/test_special_cases.py::test_unary[log10(x_i is +infinity) -> +infinity] array_api_tests/test_special_cases.py::test_unary[round(x_i.is_integer()) -> x_i] -array_api_tests/test_special_cases.py::test_unary[round(x_i is +infinity) -> +infinity] -array_api_tests/test_special_cases.py::test_unary[round(x_i is -infinity) -> -infinity] -array_api_tests/test_special_cases.py::test_unary[round(x_i is +0) -> +0] -array_api_tests/test_special_cases.py::test_unary[round(x_i is -0) -> -0] -array_api_tests/test_special_cases.py::test_unary[round(x_i is NaN) -> NaN] array_api_tests/test_special_cases.py::test_unary[round(modf(i)[0] == 0.5) -> Decimal(i).to_integral_exact(ROUND_HALF_EVEN)] -array_api_tests/test_special_cases.py::test_unary[sign(x_i < 0) -> -1] -array_api_tests/test_special_cases.py::test_unary[sign((x_i is -0 or x_i == +0)) -> 0] -array_api_tests/test_special_cases.py::test_unary[sign(x_i > 0) -> +1] array_api_tests/test_special_cases.py::test_unary[sign(x_i is NaN) -> NaN] -array_api_tests/test_special_cases.py::test_unary[sin(x_i is NaN) -> NaN] -array_api_tests/test_special_cases.py::test_unary[sin(x_i is +0) -> +0] -array_api_tests/test_special_cases.py::test_unary[sin(x_i is -0) -> -0] -array_api_tests/test_special_cases.py::test_unary[sin((x_i is +infinity or x_i == -infinity)) -> NaN] -array_api_tests/test_special_cases.py::test_unary[sinh(x_i is NaN) -> NaN] -array_api_tests/test_special_cases.py::test_unary[sinh(x_i is +0) -> +0] -array_api_tests/test_special_cases.py::test_unary[sinh(x_i is -0) -> -0] -array_api_tests/test_special_cases.py::test_unary[sinh(x_i is +infinity) -> +infinity] -array_api_tests/test_special_cases.py::test_unary[sinh(x_i is -infinity) -> -infinity] -array_api_tests/test_special_cases.py::test_unary[sqrt(x_i is NaN) -> NaN] -array_api_tests/test_special_cases.py::test_unary[sqrt(x_i < 0) -> NaN] -array_api_tests/test_special_cases.py::test_unary[sqrt(x_i is +0) -> +0] -array_api_tests/test_special_cases.py::test_unary[sqrt(x_i is -0) -> -0] -array_api_tests/test_special_cases.py::test_unary[sqrt(x_i is +infinity) -> +infinity] -array_api_tests/test_special_cases.py::test_unary[tan(x_i is NaN) -> NaN] -array_api_tests/test_special_cases.py::test_unary[tan(x_i is +0) -> +0] -array_api_tests/test_special_cases.py::test_unary[tan(x_i is -0) -> -0] -array_api_tests/test_special_cases.py::test_unary[tan((x_i is +infinity or x_i == -infinity)) -> NaN] -array_api_tests/test_special_cases.py::test_unary[tanh(x_i is NaN) -> NaN] -array_api_tests/test_special_cases.py::test_unary[tanh(x_i is +0) -> +0] -array_api_tests/test_special_cases.py::test_unary[tanh(x_i is -0) -> -0] -array_api_tests/test_special_cases.py::test_unary[tanh(x_i is +infinity) -> +1] -array_api_tests/test_special_cases.py::test_unary[tanh(x_i is -infinity) -> -1] -array_api_tests/test_special_cases.py::test_unary[trunc(x_i.is_integer()) -> x_i] -array_api_tests/test_special_cases.py::test_binary[add(x1_i is NaN or x2_i is NaN) -> NaN] -array_api_tests/test_special_cases.py::test_binary[add(x1_i is +infinity and x2_i is -infinity) -> NaN] -array_api_tests/test_special_cases.py::test_binary[add(x1_i is -infinity and x2_i is +infinity) -> NaN] -array_api_tests/test_special_cases.py::test_binary[add(x1_i is +infinity and x2_i is +infinity) -> +infinity] -array_api_tests/test_special_cases.py::test_binary[add(x1_i is -infinity and x2_i is -infinity) -> -infinity] -array_api_tests/test_special_cases.py::test_binary[add(x1_i is +infinity and isfinite(x2_i)) -> +infinity] -array_api_tests/test_special_cases.py::test_binary[add(x1_i is -infinity and isfinite(x2_i)) -> -infinity] -array_api_tests/test_special_cases.py::test_binary[add(isfinite(x1_i) and x2_i is +infinity) -> +infinity] -array_api_tests/test_special_cases.py::test_binary[add(isfinite(x1_i) and x2_i is -infinity) -> -infinity] -array_api_tests/test_special_cases.py::test_binary[add(x1_i is -0 and x2_i is -0) -> -0] -array_api_tests/test_special_cases.py::test_binary[add(x1_i is -0 and x2_i is +0) -> +0] -array_api_tests/test_special_cases.py::test_binary[add(x1_i is +0 and x2_i is -0) -> +0] -array_api_tests/test_special_cases.py::test_binary[add(x1_i is +0 and x2_i is +0) -> +0] +array_api_tests/test_special_cases.py::test_unary[signbit(x_i is +0) -> False] +array_api_tests/test_special_cases.py::test_unary[signbit(x_i is -0) -> True] +array_api_tests/test_special_cases.py::test_unary[signbit(x_i is +infinity) -> False] +array_api_tests/test_special_cases.py::test_unary[signbit(x_i is -infinity) -> True] +array_api_tests/test_special_cases.py::test_unary[signbit(isfinite(x_i) and x_i > 0) -> False] +array_api_tests/test_special_cases.py::test_unary[signbit(isfinite(x_i) and x_i < 0) -> True] +array_api_tests/test_special_cases.py::test_unary[signbit(x_i is +NaN) -> False] +array_api_tests/test_special_cases.py::test_unary[signbit(x_i is -NaN) -> True] array_api_tests/test_special_cases.py::test_binary[add((x1_i is +0 or x1_i == -0) and isfinite(x2_i) and x2_i != 0) -> x2_i] array_api_tests/test_special_cases.py::test_binary[add(isfinite(x1_i) and x1_i != 0 and (x2_i is +0 or x2_i == -0)) -> x1_i] -array_api_tests/test_special_cases.py::test_binary[__add__(x1_i is NaN or x2_i is NaN) -> NaN] -array_api_tests/test_special_cases.py::test_binary[__add__(x1_i is +infinity and x2_i is -infinity) -> NaN] -array_api_tests/test_special_cases.py::test_binary[__add__(x1_i is -infinity and x2_i is +infinity) -> NaN] -array_api_tests/test_special_cases.py::test_binary[__add__(x1_i is +infinity and x2_i is +infinity) -> +infinity] -array_api_tests/test_special_cases.py::test_binary[__add__(x1_i is -infinity and x2_i is -infinity) -> -infinity] -array_api_tests/test_special_cases.py::test_binary[__add__(x1_i is +infinity and isfinite(x2_i)) -> +infinity] -array_api_tests/test_special_cases.py::test_binary[__add__(x1_i is -infinity and isfinite(x2_i)) -> -infinity] -array_api_tests/test_special_cases.py::test_binary[__add__(isfinite(x1_i) and x2_i is +infinity) -> +infinity] -array_api_tests/test_special_cases.py::test_binary[__add__(isfinite(x1_i) and x2_i is -infinity) -> -infinity] -array_api_tests/test_special_cases.py::test_binary[__add__(x1_i is -0 and x2_i is -0) -> -0] -array_api_tests/test_special_cases.py::test_binary[__add__(x1_i is -0 and x2_i is +0) -> +0] -array_api_tests/test_special_cases.py::test_binary[__add__(x1_i is +0 and x2_i is -0) -> +0] -array_api_tests/test_special_cases.py::test_binary[__add__(x1_i is +0 and x2_i is +0) -> +0] array_api_tests/test_special_cases.py::test_binary[__add__((x1_i is +0 or x1_i == -0) and isfinite(x2_i) and x2_i != 0) -> x2_i] -array_api_tests/test_special_cases.py::test_binary[__add__(isfinite(x1_i) and x1_i != 0 and (x2_i is +0 or x2_i == -0)) -> x1_i] -array_api_tests/test_special_cases.py::test_binary[__add__(isfinite(x1_i) and x1_i != 0 and x2_i == -x1_i) -> +0] -array_api_tests/test_special_cases.py::test_binary[divide(x1_i is NaN or x2_i is NaN) -> NaN] -array_api_tests/test_special_cases.py::test_binary[divide((x1_i is +infinity or x1_i == -infinity) and (x2_i is +infinity or x2_i == -infinity)) -> NaN] -array_api_tests/test_special_cases.py::test_binary[divide((x1_i is +0 or x1_i == -0) and (x2_i is +0 or x2_i == -0)) -> NaN] +array_api_tests/test_special_cases.py::test_binary[copysign(x1_i is NaN and x2_i < 0) -> NaN] +array_api_tests/test_special_cases.py::test_binary[copysign(x1_i is NaN and x2_i is -0) -> NaN] +array_api_tests/test_special_cases.py::test_binary[copysign(x1_i is NaN and x2_i is +0) -> NaN] +array_api_tests/test_special_cases.py::test_binary[copysign(x1_i is NaN and x2_i > 0) -> NaN] array_api_tests/test_special_cases.py::test_binary[divide(x1_i is +0 and x2_i > 0) -> +0] array_api_tests/test_special_cases.py::test_binary[divide(x1_i is -0 and x2_i > 0) -> -0] array_api_tests/test_special_cases.py::test_binary[divide(x1_i is +0 and x2_i < 0) -> -0] @@ -425,19 +246,6 @@ array_api_tests/test_special_cases.py::test_binary[divide(x1_i > 0 and x2_i is + array_api_tests/test_special_cases.py::test_binary[divide(x1_i > 0 and x2_i is -0) -> -infinity] array_api_tests/test_special_cases.py::test_binary[divide(x1_i < 0 and x2_i is +0) -> -infinity] array_api_tests/test_special_cases.py::test_binary[divide(x1_i < 0 and x2_i is -0) -> +infinity] -array_api_tests/test_special_cases.py::test_binary[divide(x1_i is +infinity and isfinite(x2_i) and x2_i > 0) -> +infinity] -array_api_tests/test_special_cases.py::test_binary[divide(x1_i is +infinity and isfinite(x2_i) and x2_i < 0) -> -infinity] -array_api_tests/test_special_cases.py::test_binary[divide(x1_i is -infinity and isfinite(x2_i) and x2_i > 0) -> -infinity] -array_api_tests/test_special_cases.py::test_binary[divide(x1_i is -infinity and isfinite(x2_i) and x2_i < 0) -> +infinity] -array_api_tests/test_special_cases.py::test_binary[divide(isfinite(x1_i) and x1_i > 0 and x2_i is +infinity) -> +0] -array_api_tests/test_special_cases.py::test_binary[divide(isfinite(x1_i) and x1_i > 0 and x2_i is -infinity) -> -0] -array_api_tests/test_special_cases.py::test_binary[divide(isfinite(x1_i) and x1_i < 0 and x2_i is +infinity) -> -0] -array_api_tests/test_special_cases.py::test_binary[divide(isfinite(x1_i) and x1_i < 0 and x2_i is -infinity) -> +0] -array_api_tests/test_special_cases.py::test_binary[divide(copysign(1, x1_i) == copysign(1, x2_i) and isfinite(x1_i) and x1_i != 0 and isfinite(x2_i) and x2_i != 0) -> positive sign] -array_api_tests/test_special_cases.py::test_binary[divide(copysign(1, x1_i) != copysign(1, x2_i) and isfinite(x1_i) and x1_i != 0 and isfinite(x2_i) and x2_i != 0) -> negative sign] -array_api_tests/test_special_cases.py::test_binary[__truediv__(x1_i is NaN or x2_i is NaN) -> NaN] -array_api_tests/test_special_cases.py::test_binary[__truediv__((x1_i is +infinity or x1_i == -infinity) and (x2_i is +infinity or x2_i == -infinity)) -> NaN] -array_api_tests/test_special_cases.py::test_binary[__truediv__((x1_i is +0 or x1_i == -0) and (x2_i is +0 or x2_i == -0)) -> NaN] array_api_tests/test_special_cases.py::test_binary[__truediv__(x1_i is +0 and x2_i > 0) -> +0] array_api_tests/test_special_cases.py::test_binary[__truediv__(x1_i is -0 and x2_i > 0) -> -0] array_api_tests/test_special_cases.py::test_binary[__truediv__(x1_i is +0 and x2_i < 0) -> -0] @@ -446,93 +254,31 @@ array_api_tests/test_special_cases.py::test_binary[__truediv__(x1_i > 0 and x2_i array_api_tests/test_special_cases.py::test_binary[__truediv__(x1_i > 0 and x2_i is -0) -> -infinity] array_api_tests/test_special_cases.py::test_binary[__truediv__(x1_i < 0 and x2_i is +0) -> -infinity] array_api_tests/test_special_cases.py::test_binary[__truediv__(x1_i < 0 and x2_i is -0) -> +infinity] -array_api_tests/test_special_cases.py::test_binary[__truediv__(x1_i is +infinity and isfinite(x2_i) and x2_i > 0) -> +infinity] -array_api_tests/test_special_cases.py::test_binary[__truediv__(x1_i is +infinity and isfinite(x2_i) and x2_i < 0) -> -infinity] -array_api_tests/test_special_cases.py::test_binary[__truediv__(x1_i is -infinity and isfinite(x2_i) and x2_i > 0) -> -infinity] -array_api_tests/test_special_cases.py::test_binary[__truediv__(x1_i is -infinity and isfinite(x2_i) and x2_i < 0) -> +infinity] -array_api_tests/test_special_cases.py::test_binary[__truediv__(isfinite(x1_i) and x1_i > 0 and x2_i is +infinity) -> +0] -array_api_tests/test_special_cases.py::test_binary[__truediv__(isfinite(x1_i) and x1_i > 0 and x2_i is -infinity) -> -0] -array_api_tests/test_special_cases.py::test_binary[__truediv__(isfinite(x1_i) and x1_i < 0 and x2_i is +infinity) -> -0] -array_api_tests/test_special_cases.py::test_binary[__truediv__(isfinite(x1_i) and x1_i < 0 and x2_i is -infinity) -> +0] -array_api_tests/test_special_cases.py::test_binary[__truediv__(copysign(1, x1_i) == copysign(1, x2_i) and isfinite(x1_i) and x1_i != 0 and isfinite(x2_i) and x2_i != 0) -> positive sign] -array_api_tests/test_special_cases.py::test_binary[__truediv__(copysign(1, x1_i) != copysign(1, x2_i) and isfinite(x1_i) and x1_i != 0 and isfinite(x2_i) and x2_i != 0) -> negative sign] -array_api_tests/test_special_cases.py::test_binary[multiply(x1_i is NaN or x2_i is NaN) -> NaN] -array_api_tests/test_special_cases.py::test_binary[multiply((x1_i is +infinity or x1_i == -infinity) and (x2_i is +0 or x2_i == -0)) -> NaN] -array_api_tests/test_special_cases.py::test_binary[multiply((x1_i is +0 or x1_i == -0) and (x2_i is +infinity or x2_i == -infinity)) -> NaN] -array_api_tests/test_special_cases.py::test_binary[multiply(copysign(1, x1_i) == copysign(1, x2_i)) -> positive sign] -array_api_tests/test_special_cases.py::test_binary[multiply(copysign(1, x1_i) != copysign(1, x2_i)) -> negative sign] -array_api_tests/test_special_cases.py::test_binary[__mul__(x1_i is NaN or x2_i is NaN) -> NaN] -array_api_tests/test_special_cases.py::test_binary[__mul__((x1_i is +infinity or x1_i == -infinity) and (x2_i is +0 or x2_i == -0)) -> NaN] -array_api_tests/test_special_cases.py::test_binary[__mul__((x1_i is +0 or x1_i == -0) and (x2_i is +infinity or x2_i == -infinity)) -> NaN] -array_api_tests/test_special_cases.py::test_binary[__mul__(copysign(1, x1_i) == copysign(1, x2_i)) -> positive sign] -array_api_tests/test_special_cases.py::test_binary[__mul__(copysign(1, x1_i) != copysign(1, x2_i)) -> negative sign] -array_api_tests/test_special_cases.py::test_binary[pow(not x1_i == 1 and x2_i is NaN) -> NaN] -array_api_tests/test_special_cases.py::test_binary[pow(x2_i is +0) -> 1] -array_api_tests/test_special_cases.py::test_binary[pow(x2_i is -0) -> 1] -array_api_tests/test_special_cases.py::test_binary[pow(x1_i is NaN and not x2_i == 0) -> NaN] +array_api_tests/test_special_cases.py::test_binary[maximum(x1_i is NaN or x2_i is NaN) -> NaN] +array_api_tests/test_special_cases.py::test_binary[minimum(x1_i is NaN or x2_i is NaN) -> NaN] array_api_tests/test_special_cases.py::test_binary[pow(abs(x1_i) > 1 and x2_i is +infinity) -> +infinity] array_api_tests/test_special_cases.py::test_binary[pow(abs(x1_i) > 1 and x2_i is -infinity) -> +0] -array_api_tests/test_special_cases.py::test_binary[pow(abs(x1_i) is 1 and x2_i is +infinity) -> 1] -array_api_tests/test_special_cases.py::test_binary[pow(abs(x1_i) is 1 and x2_i is -infinity) -> 1] -array_api_tests/test_special_cases.py::test_binary[pow(x1_i is 1 and not x2_i is NaN) -> 1] -array_api_tests/test_special_cases.py::test_binary[pow(abs(x1_i) < 1 and x2_i is +infinity) -> +0] -array_api_tests/test_special_cases.py::test_binary[pow(abs(x1_i) < 1 and x2_i is -infinity) -> +infinity] array_api_tests/test_special_cases.py::test_binary[pow(x1_i is +infinity and x2_i > 0) -> +infinity] array_api_tests/test_special_cases.py::test_binary[pow(x1_i is +infinity and x2_i < 0) -> +0] -array_api_tests/test_special_cases.py::test_binary[pow(x1_i is -infinity and x2_i > 0 and x2_i.is_integer() and x2_i % 2 == 1) -> -infinity] array_api_tests/test_special_cases.py::test_binary[pow(x1_i is -infinity and x2_i > 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +infinity] -array_api_tests/test_special_cases.py::test_binary[pow(x1_i is -infinity and x2_i < 0 and x2_i.is_integer() and x2_i % 2 == 1) -> -0] array_api_tests/test_special_cases.py::test_binary[pow(x1_i is -infinity and x2_i < 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +0] array_api_tests/test_special_cases.py::test_binary[pow(x1_i is +0 and x2_i > 0) -> +0] array_api_tests/test_special_cases.py::test_binary[pow(x1_i is +0 and x2_i < 0) -> +infinity] -array_api_tests/test_special_cases.py::test_binary[pow(x1_i is -0 and x2_i > 0 and x2_i.is_integer() and x2_i % 2 == 1) -> -0] array_api_tests/test_special_cases.py::test_binary[pow(x1_i is -0 and x2_i > 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +0] -array_api_tests/test_special_cases.py::test_binary[pow(x1_i is -0 and x2_i < 0 and x2_i.is_integer() and x2_i % 2 == 1) -> -infinity] array_api_tests/test_special_cases.py::test_binary[pow(x1_i is -0 and x2_i < 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +infinity] array_api_tests/test_special_cases.py::test_binary[pow(x1_i < 0 and isfinite(x1_i) and isfinite(x2_i) and not x2_i.is_integer()) -> NaN] -array_api_tests/test_special_cases.py::test_binary[__pow__(not x1_i == 1 and x2_i is NaN) -> NaN] -array_api_tests/test_special_cases.py::test_binary[__pow__(x2_i is +0) -> 1] -array_api_tests/test_special_cases.py::test_binary[__pow__(x2_i is -0) -> 1] -array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is NaN and not x2_i == 0) -> NaN] array_api_tests/test_special_cases.py::test_binary[__pow__(abs(x1_i) > 1 and x2_i is +infinity) -> +infinity] array_api_tests/test_special_cases.py::test_binary[__pow__(abs(x1_i) > 1 and x2_i is -infinity) -> +0] -array_api_tests/test_special_cases.py::test_binary[__pow__(abs(x1_i) is 1 and x2_i is +infinity) -> 1] -array_api_tests/test_special_cases.py::test_binary[__pow__(abs(x1_i) is 1 and x2_i is -infinity) -> 1] -array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is 1 and not x2_i is NaN) -> 1] -array_api_tests/test_special_cases.py::test_binary[__pow__(abs(x1_i) < 1 and x2_i is +infinity) -> +0] -array_api_tests/test_special_cases.py::test_binary[__pow__(abs(x1_i) < 1 and x2_i is -infinity) -> +infinity] array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is +infinity and x2_i > 0) -> +infinity] array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is +infinity and x2_i < 0) -> +0] -array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is -infinity and x2_i > 0 and x2_i.is_integer() and x2_i % 2 == 1) -> -infinity] array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is -infinity and x2_i > 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +infinity] -array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is -infinity and x2_i < 0 and x2_i.is_integer() and x2_i % 2 == 1) -> -0] array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is -infinity and x2_i < 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +0] array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is +0 and x2_i > 0) -> +0] array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is +0 and x2_i < 0) -> +infinity] -array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is -0 and x2_i > 0 and x2_i.is_integer() and x2_i % 2 == 1) -> -0] array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is -0 and x2_i > 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +0] -array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is -0 and x2_i < 0 and x2_i.is_integer() and x2_i % 2 == 1) -> -infinity] array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is -0 and x2_i < 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +infinity] array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i < 0 and isfinite(x1_i) and isfinite(x2_i) and not x2_i.is_integer()) -> NaN] -array_api_tests/test_special_cases.py::test_iop[__iadd__(x1_i is NaN or x2_i is NaN) -> NaN] -array_api_tests/test_special_cases.py::test_iop[__iadd__(x1_i is +infinity and x2_i is -infinity) -> NaN] -array_api_tests/test_special_cases.py::test_iop[__iadd__(x1_i is -infinity and x2_i is +infinity) -> NaN] -array_api_tests/test_special_cases.py::test_iop[__iadd__(x1_i is +infinity and x2_i is +infinity) -> +infinity] -array_api_tests/test_special_cases.py::test_iop[__iadd__(x1_i is -infinity and x2_i is -infinity) -> -infinity] -array_api_tests/test_special_cases.py::test_iop[__iadd__(x1_i is +infinity and isfinite(x2_i)) -> +infinity] -array_api_tests/test_special_cases.py::test_iop[__iadd__(x1_i is -infinity and isfinite(x2_i)) -> -infinity] -array_api_tests/test_special_cases.py::test_iop[__iadd__(isfinite(x1_i) and x2_i is +infinity) -> +infinity] -array_api_tests/test_special_cases.py::test_iop[__iadd__(isfinite(x1_i) and x2_i is -infinity) -> -infinity] -array_api_tests/test_special_cases.py::test_iop[__iadd__(x1_i is -0 and x2_i is -0) -> -0] -array_api_tests/test_special_cases.py::test_iop[__iadd__(x1_i is -0 and x2_i is +0) -> +0] -array_api_tests/test_special_cases.py::test_iop[__iadd__(x1_i is +0 and x2_i is -0) -> +0] -array_api_tests/test_special_cases.py::test_iop[__iadd__(x1_i is +0 and x2_i is +0) -> +0] -array_api_tests/test_special_cases.py::test_iop[__iadd__((x1_i is +0 or x1_i == -0) and isfinite(x2_i) and x2_i != 0) -> x2_i] -array_api_tests/test_special_cases.py::test_iop[__iadd__(isfinite(x1_i) and x1_i != 0 and (x2_i is +0 or x2_i == -0)) -> x1_i] array_api_tests/test_special_cases.py::test_iop[__iadd__(isfinite(x1_i) and x1_i != 0 and x2_i == -x1_i) -> +0] -array_api_tests/test_special_cases.py::test_iop[__itruediv__(x1_i is NaN or x2_i is NaN) -> NaN] -array_api_tests/test_special_cases.py::test_iop[__itruediv__((x1_i is +infinity or x1_i == -infinity) and (x2_i is +infinity or x2_i == -infinity)) -> NaN] -array_api_tests/test_special_cases.py::test_iop[__itruediv__((x1_i is +0 or x1_i == -0) and (x2_i is +0 or x2_i == -0)) -> NaN] array_api_tests/test_special_cases.py::test_iop[__itruediv__(x1_i is +0 and x2_i > 0) -> +0] array_api_tests/test_special_cases.py::test_iop[__itruediv__(x1_i is -0 and x2_i > 0) -> -0] array_api_tests/test_special_cases.py::test_iop[__itruediv__(x1_i is +0 and x2_i < 0) -> -0] @@ -541,46 +287,32 @@ array_api_tests/test_special_cases.py::test_iop[__itruediv__(x1_i > 0 and x2_i i array_api_tests/test_special_cases.py::test_iop[__itruediv__(x1_i > 0 and x2_i is -0) -> -infinity] array_api_tests/test_special_cases.py::test_iop[__itruediv__(x1_i < 0 and x2_i is +0) -> -infinity] array_api_tests/test_special_cases.py::test_iop[__itruediv__(x1_i < 0 and x2_i is -0) -> +infinity] -array_api_tests/test_special_cases.py::test_iop[__itruediv__(x1_i is +infinity and isfinite(x2_i) and x2_i > 0) -> +infinity] -array_api_tests/test_special_cases.py::test_iop[__itruediv__(x1_i is +infinity and isfinite(x2_i) and x2_i < 0) -> -infinity] -array_api_tests/test_special_cases.py::test_iop[__itruediv__(x1_i is -infinity and isfinite(x2_i) and x2_i > 0) -> -infinity] -array_api_tests/test_special_cases.py::test_iop[__itruediv__(x1_i is -infinity and isfinite(x2_i) and x2_i < 0) -> +infinity] -array_api_tests/test_special_cases.py::test_iop[__itruediv__(isfinite(x1_i) and x1_i > 0 and x2_i is +infinity) -> +0] -array_api_tests/test_special_cases.py::test_iop[__itruediv__(isfinite(x1_i) and x1_i > 0 and x2_i is -infinity) -> -0] -array_api_tests/test_special_cases.py::test_iop[__itruediv__(isfinite(x1_i) and x1_i < 0 and x2_i is +infinity) -> -0] -array_api_tests/test_special_cases.py::test_iop[__itruediv__(isfinite(x1_i) and x1_i < 0 and x2_i is -infinity) -> +0] -array_api_tests/test_special_cases.py::test_iop[__itruediv__(copysign(1, x1_i) == copysign(1, x2_i) and isfinite(x1_i) and x1_i != 0 and isfinite(x2_i) and x2_i != 0) -> positive sign] -array_api_tests/test_special_cases.py::test_iop[__itruediv__(copysign(1, x1_i) != copysign(1, x2_i) and isfinite(x1_i) and x1_i != 0 and isfinite(x2_i) and x2_i != 0) -> negative sign] -array_api_tests/test_special_cases.py::test_iop[__imul__(x1_i is NaN or x2_i is NaN) -> NaN] -array_api_tests/test_special_cases.py::test_iop[__imul__((x1_i is +infinity or x1_i == -infinity) and (x2_i is +0 or x2_i == -0)) -> NaN] -array_api_tests/test_special_cases.py::test_iop[__imul__((x1_i is +0 or x1_i == -0) and (x2_i is +infinity or x2_i == -infinity)) -> NaN] -array_api_tests/test_special_cases.py::test_iop[__imul__(copysign(1, x1_i) == copysign(1, x2_i)) -> positive sign] -array_api_tests/test_special_cases.py::test_iop[__imul__(copysign(1, x1_i) != copysign(1, x2_i)) -> negative sign] -array_api_tests/test_special_cases.py::test_iop[__ipow__(not x1_i == 1 and x2_i is NaN) -> NaN] -array_api_tests/test_special_cases.py::test_iop[__ipow__(x2_i is +0) -> 1] -array_api_tests/test_special_cases.py::test_iop[__ipow__(x2_i is -0) -> 1] -array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i is NaN and not x2_i == 0) -> NaN] array_api_tests/test_special_cases.py::test_iop[__ipow__(abs(x1_i) > 1 and x2_i is +infinity) -> +infinity] array_api_tests/test_special_cases.py::test_iop[__ipow__(abs(x1_i) > 1 and x2_i is -infinity) -> +0] -array_api_tests/test_special_cases.py::test_iop[__ipow__(abs(x1_i) is 1 and x2_i is +infinity) -> 1] -array_api_tests/test_special_cases.py::test_iop[__ipow__(abs(x1_i) is 1 and x2_i is -infinity) -> 1] -array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i is 1 and not x2_i is NaN) -> 1] -array_api_tests/test_special_cases.py::test_iop[__ipow__(abs(x1_i) < 1 and x2_i is +infinity) -> +0] -array_api_tests/test_special_cases.py::test_iop[__ipow__(abs(x1_i) < 1 and x2_i is -infinity) -> +infinity] array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i is +infinity and x2_i > 0) -> +infinity] array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i is +infinity and x2_i < 0) -> +0] -array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i is -infinity and x2_i > 0 and x2_i.is_integer() and x2_i % 2 == 1) -> -infinity] array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i is -infinity and x2_i > 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +infinity] -array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i is -infinity and x2_i < 0 and x2_i.is_integer() and x2_i % 2 == 1) -> -0] array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i is -infinity and x2_i < 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +0] array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i is +0 and x2_i > 0) -> +0] array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i is +0 and x2_i < 0) -> +infinity] -array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i is -0 and x2_i > 0 and x2_i.is_integer() and x2_i % 2 == 1) -> -0] array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i is -0 and x2_i > 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +0] -array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i is -0 and x2_i < 0 and x2_i.is_integer() and x2_i % 2 == 1) -> -infinity] array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i is -0 and x2_i < 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +infinity] array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i < 0 and isfinite(x1_i) and isfinite(x2_i) and not x2_i.is_integer()) -> NaN] +array_api_tests/test_special_cases.py::test_empty_arrays[prod] +array_api_tests/test_special_cases.py::test_empty_arrays[std] array_api_tests/test_special_cases.py::test_empty_arrays[sum] +array_api_tests/test_special_cases.py::test_nan_propagation[max] array_api_tests/test_special_cases.py::test_nan_propagation[mean] +array_api_tests/test_special_cases.py::test_nan_propagation[min] +array_api_tests/test_special_cases.py::test_nan_propagation[prod] +array_api_tests/test_special_cases.py::test_nan_propagation[std] +array_api_tests/test_special_cases.py::test_nan_propagation[sum] array_api_tests/test_special_cases.py::test_nan_propagation[var] -array_api_tests/test_searching_functions.py::test_nonzero_zerodim_error +array_api_tests/test_statistical_functions.py::test_cumulative_sum +array_api_tests/test_statistical_functions.py::test_max +array_api_tests/test_statistical_functions.py::test_mean +array_api_tests/test_statistical_functions.py::test_min +array_api_tests/test_statistical_functions.py::test_prod +array_api_tests/test_statistical_functions.py::test_sum +array_api_tests/test_utility_functions.py::test_all +array_api_tests/test_utility_functions.py::test_any diff --git a/heat/array_api/test/xfails.txt b/heat/array_api/test/xfails.txt new file mode 100644 index 0000000000..d3a81ea0e0 --- /dev/null +++ b/heat/array_api/test/xfails.txt @@ -0,0 +1,318 @@ +array_api_tests/test_array_object.py::test_getitem +array_api_tests/test_array_object.py::test_setitem +array_api_tests/test_array_object.py::test_getitem_masking +array_api_tests/test_array_object.py::test_setitem_masking +array_api_tests/test_array_object.py::test_scalar_casting[__float__(float64)] +array_api_tests/test_creation_functions.py::test_arange +array_api_tests/test_creation_functions.py::test_asarray_arrays +array_api_tests/test_creation_functions.py::test_empty_like +array_api_tests/test_creation_functions.py::test_eye +array_api_tests/test_creation_functions.py::test_full +array_api_tests/test_creation_functions.py::test_full_like +array_api_tests/test_creation_functions.py::test_linspace +array_api_tests/test_creation_functions.py::test_meshgrid +array_api_tests/test_creation_functions.py::test_ones +array_api_tests/test_creation_functions.py::test_ones_like +array_api_tests/test_creation_functions.py::test_zeros +array_api_tests/test_creation_functions.py::test_zeros_like +array_api_tests/test_data_type_functions.py::test_astype +array_api_tests/test_data_type_functions.py::test_broadcast_arrays +array_api_tests/test_data_type_functions.py::test_broadcast_to +array_api_tests/test_data_type_functions.py::test_can_cast +array_api_tests/test_data_type_functions.py::test_finfo[float32] +array_api_tests/test_data_type_functions.py::test_finfo[float64] +array_api_tests/test_data_type_functions.py::test_iinfo[int8] +array_api_tests/test_data_type_functions.py::test_iinfo[int16] +array_api_tests/test_data_type_functions.py::test_iinfo[int32] +array_api_tests/test_data_type_functions.py::test_iinfo[int64] +array_api_tests/test_data_type_functions.py::test_isdtype +array_api_tests/test_has_names.py::test_has_names[linalg-cholesky] +array_api_tests/test_has_names.py::test_has_names[linalg-cross] +array_api_tests/test_has_names.py::test_has_names[linalg-det] +array_api_tests/test_has_names.py::test_has_names[linalg-diagonal] +array_api_tests/test_has_names.py::test_has_names[linalg-eigh] +array_api_tests/test_has_names.py::test_has_names[linalg-eigvalsh] +array_api_tests/test_has_names.py::test_has_names[linalg-inv] +array_api_tests/test_has_names.py::test_has_names[linalg-matrix_norm] +array_api_tests/test_has_names.py::test_has_names[linalg-matrix_power] +array_api_tests/test_has_names.py::test_has_names[linalg-matrix_rank] +array_api_tests/test_has_names.py::test_has_names[linalg-outer] +array_api_tests/test_has_names.py::test_has_names[linalg-pinv] +array_api_tests/test_has_names.py::test_has_names[linalg-qr] +array_api_tests/test_has_names.py::test_has_names[linalg-slogdet] +array_api_tests/test_has_names.py::test_has_names[linalg-solve] +array_api_tests/test_has_names.py::test_has_names[linalg-svd] +array_api_tests/test_has_names.py::test_has_names[linalg-svdvals] +array_api_tests/test_has_names.py::test_has_names[linalg-trace] +array_api_tests/test_has_names.py::test_has_names[linalg-vector_norm] +array_api_tests/test_has_names.py::test_has_names[fft-fft] +array_api_tests/test_has_names.py::test_has_names[fft-ifft] +array_api_tests/test_has_names.py::test_has_names[fft-fftn] +array_api_tests/test_has_names.py::test_has_names[fft-ifftn] +array_api_tests/test_has_names.py::test_has_names[fft-rfft] +array_api_tests/test_has_names.py::test_has_names[fft-irfft] +array_api_tests/test_has_names.py::test_has_names[fft-rfftn] +array_api_tests/test_has_names.py::test_has_names[fft-irfftn] +array_api_tests/test_has_names.py::test_has_names[fft-hfft] +array_api_tests/test_has_names.py::test_has_names[fft-ihfft] +array_api_tests/test_has_names.py::test_has_names[fft-fftfreq] +array_api_tests/test_has_names.py::test_has_names[fft-rfftfreq] +array_api_tests/test_has_names.py::test_has_names[fft-fftshift] +array_api_tests/test_has_names.py::test_has_names[fft-ifftshift] +array_api_tests/test_has_names.py::test_has_names[indexing-take] +array_api_tests/test_has_names.py::test_has_names[set-unique_all] +array_api_tests/test_has_names.py::test_has_names[set-unique_counts] +array_api_tests/test_has_names.py::test_has_names[manipulation-moveaxis] +array_api_tests/test_has_names.py::test_has_names[manipulation-repeat] +array_api_tests/test_has_names.py::test_has_names[manipulation-tile] +array_api_tests/test_has_names.py::test_has_names[manipulation-unstack] +array_api_tests/test_has_names.py::test_has_names[searching-searchsorted] +array_api_tests/test_has_names.py::test_has_names[elementwise-clip] +array_api_tests/test_has_names.py::test_has_names[elementwise-conj] +array_api_tests/test_has_names.py::test_has_names[elementwise-copysign] +array_api_tests/test_has_names.py::test_has_names[elementwise-hypot] +array_api_tests/test_has_names.py::test_has_names[elementwise-imag] +array_api_tests/test_has_names.py::test_has_names[elementwise-maximum] +array_api_tests/test_has_names.py::test_has_names[elementwise-minimum] +array_api_tests/test_has_names.py::test_has_names[elementwise-real] +array_api_tests/test_has_names.py::test_has_names[elementwise-signbit] +array_api_tests/test_has_names.py::test_has_names[statistical-cumulative_sum] +array_api_tests/test_has_names.py::test_has_names[sorting-argsort] +array_api_tests/test_has_names.py::test_has_names[data_type-isdtype] +array_api_tests/test_has_names.py::test_has_names[info-__array_namespace_info__] +array_api_tests/test_has_names.py::test_has_names[array_method-__complex__] +array_api_tests/test_indexing_functions.py::test_take +array_api_tests/test_inspection_functions.py::test_array_namespace_info +array_api_tests/test_inspection_functions.py::test_array_namespace_info_dtypes +array_api_tests/test_linalg.py::test_matrix_transpose +array_api_tests/test_linalg.py::test_tensordot +array_api_tests/test_linalg.py::test_vecdot +array_api_tests/test_manipulation_functions.py::test_concat +array_api_tests/test_manipulation_functions.py::test_expand_dims +array_api_tests/test_manipulation_functions.py::test_moveaxis +array_api_tests/test_manipulation_functions.py::test_squeeze +array_api_tests/test_manipulation_functions.py::test_flip +array_api_tests/test_manipulation_functions.py::test_repeat +array_api_tests/test_manipulation_functions.py::test_stack +array_api_tests/test_manipulation_functions.py::test_tile +array_api_tests/test_manipulation_functions.py::test_unstack +array_api_tests/test_operators_and_elementwise_functions.py::test_abs[abs] +array_api_tests/test_operators_and_elementwise_functions.py::test_abs[__abs__] +array_api_tests/test_operators_and_elementwise_functions.py::test_acos +array_api_tests/test_operators_and_elementwise_functions.py::test_acosh +array_api_tests/test_operators_and_elementwise_functions.py::test_add[add(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_add[__add__(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_add[__add__(x, s)] +array_api_tests/test_operators_and_elementwise_functions.py::test_asin +array_api_tests/test_operators_and_elementwise_functions.py::test_asinh +array_api_tests/test_operators_and_elementwise_functions.py::test_atan +array_api_tests/test_operators_and_elementwise_functions.py::test_atan2 +array_api_tests/test_operators_and_elementwise_functions.py::test_atanh +array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_left_shift[bitwise_left_shift(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_left_shift[__lshift__(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_left_shift[__ilshift__(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_right_shift[bitwise_right_shift(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_right_shift[__rshift__(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_right_shift[__irshift__(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_clip +array_api_tests/test_operators_and_elementwise_functions.py::test_conj +array_api_tests/test_operators_and_elementwise_functions.py::test_copysign +array_api_tests/test_operators_and_elementwise_functions.py::test_cos +array_api_tests/test_operators_and_elementwise_functions.py::test_cosh +array_api_tests/test_operators_and_elementwise_functions.py::test_divide[divide(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_divide[__truediv__(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_divide[__truediv__(x, s)] +array_api_tests/test_operators_and_elementwise_functions.py::test_divide[__itruediv__(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_divide[__itruediv__(x, s)] +array_api_tests/test_operators_and_elementwise_functions.py::test_equal[equal(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_equal[__eq__(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_exp +array_api_tests/test_operators_and_elementwise_functions.py::test_expm1 +array_api_tests/test_operators_and_elementwise_functions.py::test_floor_divide[floor_divide(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_floor_divide[__floordiv__(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_floor_divide[__floordiv__(x, s)] +array_api_tests/test_operators_and_elementwise_functions.py::test_floor_divide[__ifloordiv__(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_floor_divide[__ifloordiv__(x, s)] +array_api_tests/test_operators_and_elementwise_functions.py::test_hypot +array_api_tests/test_operators_and_elementwise_functions.py::test_imag +array_api_tests/test_operators_and_elementwise_functions.py::test_isinf +array_api_tests/test_operators_and_elementwise_functions.py::test_less[less(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_less_equal[__le__(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_log +array_api_tests/test_operators_and_elementwise_functions.py::test_log1p +array_api_tests/test_operators_and_elementwise_functions.py::test_log2 +array_api_tests/test_operators_and_elementwise_functions.py::test_log10 +array_api_tests/test_operators_and_elementwise_functions.py::test_logaddexp +array_api_tests/test_operators_and_elementwise_functions.py::test_maximum +array_api_tests/test_operators_and_elementwise_functions.py::test_minimum +array_api_tests/test_operators_and_elementwise_functions.py::test_multiply[multiply(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_multiply[__mul__(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_multiply[__imul__(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_multiply[__imul__(x, s)] +array_api_tests/test_operators_and_elementwise_functions.py::test_negative[negative] +array_api_tests/test_operators_and_elementwise_functions.py::test_negative[__neg__] +array_api_tests/test_operators_and_elementwise_functions.py::test_not_equal[not_equal(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_not_equal[__ne__(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_positive[positive] +array_api_tests/test_operators_and_elementwise_functions.py::test_positive[__pos__] +array_api_tests/test_operators_and_elementwise_functions.py::test_pow[pow(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_pow[__pow__(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_pow[__pow__(x, s)] +array_api_tests/test_operators_and_elementwise_functions.py::test_pow[__ipow__(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_pow[__ipow__(x, s)] +array_api_tests/test_operators_and_elementwise_functions.py::test_real +array_api_tests/test_operators_and_elementwise_functions.py::test_round +array_api_tests/test_operators_and_elementwise_functions.py::test_signbit +array_api_tests/test_operators_and_elementwise_functions.py::test_sign +array_api_tests/test_operators_and_elementwise_functions.py::test_sin +array_api_tests/test_operators_and_elementwise_functions.py::test_sinh +array_api_tests/test_operators_and_elementwise_functions.py::test_square +array_api_tests/test_operators_and_elementwise_functions.py::test_sqrt +array_api_tests/test_operators_and_elementwise_functions.py::test_subtract[subtract(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_subtract[__sub__(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_subtract[__isub__(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_tan +array_api_tests/test_operators_and_elementwise_functions.py::test_tanh +array_api_tests/test_searching_functions.py::test_argmax +array_api_tests/test_searching_functions.py::test_argmin +array_api_tests/test_searching_functions.py::test_nonzero_zerodim_error +array_api_tests/test_searching_functions.py::test_nonzero +array_api_tests/test_searching_functions.py::test_searchsorted +array_api_tests/test_set_functions.py::test_unique_all +array_api_tests/test_set_functions.py::test_unique_counts +array_api_tests/test_set_functions.py::test_unique_inverse +array_api_tests/test_set_functions.py::test_unique_values +array_api_tests/test_signatures.py::test_func_signature[from_dlpack] +array_api_tests/test_signatures.py::test_func_signature[take] +array_api_tests/test_signatures.py::test_func_signature[unique_all] +array_api_tests/test_signatures.py::test_func_signature[unique_counts] +array_api_tests/test_signatures.py::test_func_signature[moveaxis] +array_api_tests/test_signatures.py::test_func_signature[repeat] +array_api_tests/test_signatures.py::test_func_signature[tile] +array_api_tests/test_signatures.py::test_func_signature[unstack] +array_api_tests/test_signatures.py::test_func_signature[searchsorted] +array_api_tests/test_signatures.py::test_func_signature[clip] +array_api_tests/test_signatures.py::test_func_signature[conj] +array_api_tests/test_signatures.py::test_func_signature[copysign] +array_api_tests/test_signatures.py::test_func_signature[hypot] +array_api_tests/test_signatures.py::test_func_signature[imag] +array_api_tests/test_signatures.py::test_func_signature[maximum] +array_api_tests/test_signatures.py::test_func_signature[minimum] +array_api_tests/test_signatures.py::test_func_signature[real] +array_api_tests/test_signatures.py::test_func_signature[signbit] +array_api_tests/test_signatures.py::test_func_signature[cumulative_sum] +array_api_tests/test_signatures.py::test_func_signature[argsort] +array_api_tests/test_signatures.py::test_func_signature[astype] +array_api_tests/test_signatures.py::test_func_signature[isdtype] +array_api_tests/test_signatures.py::test_func_signature[__array_namespace_info__] +array_api_tests/test_signatures.py::test_array_method_signature[__complex__] +array_api_tests/test_signatures.py::test_array_method_signature[__dlpack__] +array_api_tests/test_signatures.py::test_info_func_signature[capabilities] +array_api_tests/test_signatures.py::test_info_func_signature[default_device] +array_api_tests/test_signatures.py::test_info_func_signature[default_dtypes] +array_api_tests/test_signatures.py::test_info_func_signature[devices] +array_api_tests/test_signatures.py::test_info_func_signature[dtypes] +array_api_tests/test_sorting_functions.py::test_argsort +array_api_tests/test_sorting_functions.py::test_sort +array_api_tests/test_special_cases.py::test_unary[floor(x_i.is_integer()) -> x_i] +array_api_tests/test_special_cases.py::test_unary[isfinite((x_i is +infinity or x_i == -infinity)) -> False] +array_api_tests/test_special_cases.py::test_unary[isfinite(x_i is NaN) -> False] +array_api_tests/test_special_cases.py::test_unary[isfinite(isfinite(x_i)) -> True] +array_api_tests/test_special_cases.py::test_unary[isinf((x_i is +infinity or x_i == -infinity)) -> True] +array_api_tests/test_special_cases.py::test_unary[isnan(x_i is NaN) -> True] +array_api_tests/test_special_cases.py::test_unary[round(x_i.is_integer()) -> x_i] +array_api_tests/test_special_cases.py::test_unary[round(modf(i)[0] == 0.5) -> Decimal(i).to_integral_exact(ROUND_HALF_EVEN)] +array_api_tests/test_special_cases.py::test_unary[sign(x_i is NaN) -> NaN] +array_api_tests/test_special_cases.py::test_unary[signbit(x_i is +0) -> False] +array_api_tests/test_special_cases.py::test_unary[signbit(x_i is -0) -> True] +array_api_tests/test_special_cases.py::test_unary[signbit(x_i is +infinity) -> False] +array_api_tests/test_special_cases.py::test_unary[signbit(x_i is -infinity) -> True] +array_api_tests/test_special_cases.py::test_unary[signbit(isfinite(x_i) and x_i > 0) -> False] +array_api_tests/test_special_cases.py::test_unary[signbit(isfinite(x_i) and x_i < 0) -> True] +array_api_tests/test_special_cases.py::test_unary[signbit(x_i is +NaN) -> False] +array_api_tests/test_special_cases.py::test_unary[signbit(x_i is -NaN) -> True] +array_api_tests/test_special_cases.py::test_binary[add((x1_i is +0 or x1_i == -0) and isfinite(x2_i) and x2_i != 0) -> x2_i] +array_api_tests/test_special_cases.py::test_binary[add(isfinite(x1_i) and x1_i != 0 and (x2_i is +0 or x2_i == -0)) -> x1_i] +array_api_tests/test_special_cases.py::test_binary[__add__((x1_i is +0 or x1_i == -0) and isfinite(x2_i) and x2_i != 0) -> x2_i] +array_api_tests/test_special_cases.py::test_binary[copysign(x1_i is NaN and x2_i < 0) -> NaN] +array_api_tests/test_special_cases.py::test_binary[copysign(x1_i is NaN and x2_i is -0) -> NaN] +array_api_tests/test_special_cases.py::test_binary[copysign(x1_i is NaN and x2_i is +0) -> NaN] +array_api_tests/test_special_cases.py::test_binary[copysign(x1_i is NaN and x2_i > 0) -> NaN] +array_api_tests/test_special_cases.py::test_binary[divide(x1_i is +0 and x2_i > 0) -> +0] +array_api_tests/test_special_cases.py::test_binary[divide(x1_i is -0 and x2_i > 0) -> -0] +array_api_tests/test_special_cases.py::test_binary[divide(x1_i is +0 and x2_i < 0) -> -0] +array_api_tests/test_special_cases.py::test_binary[divide(x1_i is -0 and x2_i < 0) -> +0] +array_api_tests/test_special_cases.py::test_binary[divide(x1_i > 0 and x2_i is +0) -> +infinity] +array_api_tests/test_special_cases.py::test_binary[divide(x1_i > 0 and x2_i is -0) -> -infinity] +array_api_tests/test_special_cases.py::test_binary[divide(x1_i < 0 and x2_i is +0) -> -infinity] +array_api_tests/test_special_cases.py::test_binary[divide(x1_i < 0 and x2_i is -0) -> +infinity] +array_api_tests/test_special_cases.py::test_binary[__truediv__(x1_i is +0 and x2_i > 0) -> +0] +array_api_tests/test_special_cases.py::test_binary[__truediv__(x1_i is -0 and x2_i > 0) -> -0] +array_api_tests/test_special_cases.py::test_binary[__truediv__(x1_i is +0 and x2_i < 0) -> -0] +array_api_tests/test_special_cases.py::test_binary[__truediv__(x1_i is -0 and x2_i < 0) -> +0] +array_api_tests/test_special_cases.py::test_binary[__truediv__(x1_i > 0 and x2_i is +0) -> +infinity] +array_api_tests/test_special_cases.py::test_binary[__truediv__(x1_i > 0 and x2_i is -0) -> -infinity] +array_api_tests/test_special_cases.py::test_binary[__truediv__(x1_i < 0 and x2_i is +0) -> -infinity] +array_api_tests/test_special_cases.py::test_binary[__truediv__(x1_i < 0 and x2_i is -0) -> +infinity] +array_api_tests/test_special_cases.py::test_binary[maximum(x1_i is NaN or x2_i is NaN) -> NaN] +array_api_tests/test_special_cases.py::test_binary[minimum(x1_i is NaN or x2_i is NaN) -> NaN] +array_api_tests/test_special_cases.py::test_binary[pow(abs(x1_i) > 1 and x2_i is +infinity) -> +infinity] +array_api_tests/test_special_cases.py::test_binary[pow(abs(x1_i) > 1 and x2_i is -infinity) -> +0] +array_api_tests/test_special_cases.py::test_binary[pow(x1_i is +infinity and x2_i > 0) -> +infinity] +array_api_tests/test_special_cases.py::test_binary[pow(x1_i is +infinity and x2_i < 0) -> +0] +array_api_tests/test_special_cases.py::test_binary[pow(x1_i is -infinity and x2_i > 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +infinity] +array_api_tests/test_special_cases.py::test_binary[pow(x1_i is -infinity and x2_i < 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +0] +array_api_tests/test_special_cases.py::test_binary[pow(x1_i is +0 and x2_i > 0) -> +0] +array_api_tests/test_special_cases.py::test_binary[pow(x1_i is +0 and x2_i < 0) -> +infinity] +array_api_tests/test_special_cases.py::test_binary[pow(x1_i is -0 and x2_i > 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +0] +array_api_tests/test_special_cases.py::test_binary[pow(x1_i is -0 and x2_i < 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +infinity] +array_api_tests/test_special_cases.py::test_binary[pow(x1_i < 0 and isfinite(x1_i) and isfinite(x2_i) and not x2_i.is_integer()) -> NaN] +array_api_tests/test_special_cases.py::test_binary[__pow__(abs(x1_i) > 1 and x2_i is +infinity) -> +infinity] +array_api_tests/test_special_cases.py::test_binary[__pow__(abs(x1_i) > 1 and x2_i is -infinity) -> +0] +array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is +infinity and x2_i > 0) -> +infinity] +array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is +infinity and x2_i < 0) -> +0] +array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is -infinity and x2_i > 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +infinity] +array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is -infinity and x2_i < 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +0] +array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is +0 and x2_i > 0) -> +0] +array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is +0 and x2_i < 0) -> +infinity] +array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is -0 and x2_i > 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +0] +array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is -0 and x2_i < 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +infinity] +array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i < 0 and isfinite(x1_i) and isfinite(x2_i) and not x2_i.is_integer()) -> NaN] +array_api_tests/test_special_cases.py::test_iop[__iadd__(isfinite(x1_i) and x1_i != 0 and x2_i == -x1_i) -> +0] +array_api_tests/test_special_cases.py::test_iop[__itruediv__(x1_i is +0 and x2_i > 0) -> +0] +array_api_tests/test_special_cases.py::test_iop[__itruediv__(x1_i is -0 and x2_i > 0) -> -0] +array_api_tests/test_special_cases.py::test_iop[__itruediv__(x1_i is +0 and x2_i < 0) -> -0] +array_api_tests/test_special_cases.py::test_iop[__itruediv__(x1_i is -0 and x2_i < 0) -> +0] +array_api_tests/test_special_cases.py::test_iop[__itruediv__(x1_i > 0 and x2_i is +0) -> +infinity] +array_api_tests/test_special_cases.py::test_iop[__itruediv__(x1_i > 0 and x2_i is -0) -> -infinity] +array_api_tests/test_special_cases.py::test_iop[__itruediv__(x1_i < 0 and x2_i is +0) -> -infinity] +array_api_tests/test_special_cases.py::test_iop[__itruediv__(x1_i < 0 and x2_i is -0) -> +infinity] +array_api_tests/test_special_cases.py::test_iop[__ipow__(abs(x1_i) > 1 and x2_i is +infinity) -> +infinity] +array_api_tests/test_special_cases.py::test_iop[__ipow__(abs(x1_i) > 1 and x2_i is -infinity) -> +0] +array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i is +infinity and x2_i > 0) -> +infinity] +array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i is +infinity and x2_i < 0) -> +0] +array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i is -infinity and x2_i > 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +infinity] +array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i is -infinity and x2_i < 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +0] +array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i is +0 and x2_i > 0) -> +0] +array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i is +0 and x2_i < 0) -> +infinity] +array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i is -0 and x2_i > 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +0] +array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i is -0 and x2_i < 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +infinity] +array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i < 0 and isfinite(x1_i) and isfinite(x2_i) and not x2_i.is_integer()) -> NaN] +array_api_tests/test_special_cases.py::test_empty_arrays[prod] +array_api_tests/test_special_cases.py::test_empty_arrays[std] +array_api_tests/test_special_cases.py::test_empty_arrays[sum] +array_api_tests/test_special_cases.py::test_nan_propagation[max] +array_api_tests/test_special_cases.py::test_nan_propagation[mean] +array_api_tests/test_special_cases.py::test_nan_propagation[min] +array_api_tests/test_special_cases.py::test_nan_propagation[prod] +array_api_tests/test_special_cases.py::test_nan_propagation[std] +array_api_tests/test_special_cases.py::test_nan_propagation[sum] +array_api_tests/test_special_cases.py::test_nan_propagation[var] +array_api_tests/test_statistical_functions.py::test_cumulative_sum +array_api_tests/test_statistical_functions.py::test_max +array_api_tests/test_statistical_functions.py::test_mean +array_api_tests/test_statistical_functions.py::test_min +array_api_tests/test_statistical_functions.py::test_prod +array_api_tests/test_statistical_functions.py::test_sum +array_api_tests/test_utility_functions.py::test_all +array_api_tests/test_utility_functions.py::test_any From 74e2c9170abdba40750cfda9ea4645026547ec9b Mon Sep 17 00:00:00 2001 From: Michael Tarnawa Date: Thu, 11 Jul 2024 12:59:20 +0200 Subject: [PATCH 136/150] update skips --- heat/array_api/test/skips.txt | 34 ++++++++++++++++++---------------- heat/array_api/test/xfails.txt | 34 ++++++++++++++++++---------------- 2 files changed, 36 insertions(+), 32 deletions(-) diff --git a/heat/array_api/test/skips.txt b/heat/array_api/test/skips.txt index d3a81ea0e0..7ad24f82d2 100644 --- a/heat/array_api/test/skips.txt +++ b/heat/array_api/test/skips.txt @@ -84,14 +84,13 @@ array_api_tests/test_has_names.py::test_has_names[array_method-__complex__] array_api_tests/test_indexing_functions.py::test_take array_api_tests/test_inspection_functions.py::test_array_namespace_info array_api_tests/test_inspection_functions.py::test_array_namespace_info_dtypes +array_api_tests/test_linalg.py::test_matmul array_api_tests/test_linalg.py::test_matrix_transpose array_api_tests/test_linalg.py::test_tensordot array_api_tests/test_linalg.py::test_vecdot array_api_tests/test_manipulation_functions.py::test_concat array_api_tests/test_manipulation_functions.py::test_expand_dims array_api_tests/test_manipulation_functions.py::test_moveaxis -array_api_tests/test_manipulation_functions.py::test_squeeze -array_api_tests/test_manipulation_functions.py::test_flip array_api_tests/test_manipulation_functions.py::test_repeat array_api_tests/test_manipulation_functions.py::test_stack array_api_tests/test_manipulation_functions.py::test_tile @@ -100,9 +99,8 @@ array_api_tests/test_operators_and_elementwise_functions.py::test_abs[abs] array_api_tests/test_operators_and_elementwise_functions.py::test_abs[__abs__] array_api_tests/test_operators_and_elementwise_functions.py::test_acos array_api_tests/test_operators_and_elementwise_functions.py::test_acosh -array_api_tests/test_operators_and_elementwise_functions.py::test_add[add(x1, x2)] -array_api_tests/test_operators_and_elementwise_functions.py::test_add[__add__(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_add[__add__(x, s)] +array_api_tests/test_operators_and_elementwise_functions.py::test_add[__iadd__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_asin array_api_tests/test_operators_and_elementwise_functions.py::test_asinh array_api_tests/test_operators_and_elementwise_functions.py::test_atan @@ -128,16 +126,22 @@ array_api_tests/test_operators_and_elementwise_functions.py::test_equal[equal(x1 array_api_tests/test_operators_and_elementwise_functions.py::test_equal[__eq__(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_exp array_api_tests/test_operators_and_elementwise_functions.py::test_expm1 +array_api_tests/test_operators_and_elementwise_functions.py::test_floor array_api_tests/test_operators_and_elementwise_functions.py::test_floor_divide[floor_divide(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_floor_divide[__floordiv__(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_floor_divide[__floordiv__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_floor_divide[__ifloordiv__(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_floor_divide[__ifloordiv__(x, s)] +array_api_tests/test_operators_and_elementwise_functions.py::test_greater[greater(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_greater[__gt__(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_greater[__gt__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_hypot array_api_tests/test_operators_and_elementwise_functions.py::test_imag -array_api_tests/test_operators_and_elementwise_functions.py::test_isinf -array_api_tests/test_operators_and_elementwise_functions.py::test_less[less(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_isfinite +array_api_tests/test_operators_and_elementwise_functions.py::test_isnan +array_api_tests/test_operators_and_elementwise_functions.py::test_less_equal[less_equal(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_less_equal[__le__(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_less_equal[__le__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_log array_api_tests/test_operators_and_elementwise_functions.py::test_log1p array_api_tests/test_operators_and_elementwise_functions.py::test_log2 @@ -145,38 +149,35 @@ array_api_tests/test_operators_and_elementwise_functions.py::test_log10 array_api_tests/test_operators_and_elementwise_functions.py::test_logaddexp array_api_tests/test_operators_and_elementwise_functions.py::test_maximum array_api_tests/test_operators_and_elementwise_functions.py::test_minimum -array_api_tests/test_operators_and_elementwise_functions.py::test_multiply[multiply(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_multiply[__mul__(x1, x2)] -array_api_tests/test_operators_and_elementwise_functions.py::test_multiply[__imul__(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_multiply[__imul__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_negative[negative] array_api_tests/test_operators_and_elementwise_functions.py::test_negative[__neg__] -array_api_tests/test_operators_and_elementwise_functions.py::test_not_equal[not_equal(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_not_equal[__ne__(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_not_equal[__ne__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_positive[positive] array_api_tests/test_operators_and_elementwise_functions.py::test_positive[__pos__] array_api_tests/test_operators_and_elementwise_functions.py::test_pow[pow(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_pow[__pow__(x1, x2)] -array_api_tests/test_operators_and_elementwise_functions.py::test_pow[__pow__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_pow[__ipow__(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_pow[__ipow__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_real array_api_tests/test_operators_and_elementwise_functions.py::test_round array_api_tests/test_operators_and_elementwise_functions.py::test_signbit -array_api_tests/test_operators_and_elementwise_functions.py::test_sign array_api_tests/test_operators_and_elementwise_functions.py::test_sin array_api_tests/test_operators_and_elementwise_functions.py::test_sinh array_api_tests/test_operators_and_elementwise_functions.py::test_square array_api_tests/test_operators_and_elementwise_functions.py::test_sqrt -array_api_tests/test_operators_and_elementwise_functions.py::test_subtract[subtract(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_subtract[__sub__(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_subtract[__isub__(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_tan array_api_tests/test_operators_and_elementwise_functions.py::test_tanh +array_api_tests/test_operators_and_elementwise_functions.py::test_trunc array_api_tests/test_searching_functions.py::test_argmax array_api_tests/test_searching_functions.py::test_argmin array_api_tests/test_searching_functions.py::test_nonzero_zerodim_error array_api_tests/test_searching_functions.py::test_nonzero +array_api_tests/test_searching_functions.py::test_where array_api_tests/test_searching_functions.py::test_searchsorted array_api_tests/test_set_functions.py::test_unique_all array_api_tests/test_set_functions.py::test_unique_counts @@ -214,14 +215,14 @@ array_api_tests/test_signatures.py::test_info_func_signature[devices] array_api_tests/test_signatures.py::test_info_func_signature[dtypes] array_api_tests/test_sorting_functions.py::test_argsort array_api_tests/test_sorting_functions.py::test_sort -array_api_tests/test_special_cases.py::test_unary[floor(x_i.is_integer()) -> x_i] array_api_tests/test_special_cases.py::test_unary[isfinite((x_i is +infinity or x_i == -infinity)) -> False] array_api_tests/test_special_cases.py::test_unary[isfinite(x_i is NaN) -> False] array_api_tests/test_special_cases.py::test_unary[isfinite(isfinite(x_i)) -> True] array_api_tests/test_special_cases.py::test_unary[isinf((x_i is +infinity or x_i == -infinity)) -> True] array_api_tests/test_special_cases.py::test_unary[isnan(x_i is NaN) -> True] -array_api_tests/test_special_cases.py::test_unary[round(x_i.is_integer()) -> x_i] +array_api_tests/test_special_cases.py::test_unary[log2(x_i < 0) -> NaN] array_api_tests/test_special_cases.py::test_unary[round(modf(i)[0] == 0.5) -> Decimal(i).to_integral_exact(ROUND_HALF_EVEN)] +array_api_tests/test_special_cases.py::test_unary[sign(x_i < 0) -> -1] array_api_tests/test_special_cases.py::test_unary[sign(x_i is NaN) -> NaN] array_api_tests/test_special_cases.py::test_unary[signbit(x_i is +0) -> False] array_api_tests/test_special_cases.py::test_unary[signbit(x_i is -0) -> True] @@ -231,9 +232,11 @@ array_api_tests/test_special_cases.py::test_unary[signbit(isfinite(x_i) and x_i array_api_tests/test_special_cases.py::test_unary[signbit(isfinite(x_i) and x_i < 0) -> True] array_api_tests/test_special_cases.py::test_unary[signbit(x_i is +NaN) -> False] array_api_tests/test_special_cases.py::test_unary[signbit(x_i is -NaN) -> True] +array_api_tests/test_special_cases.py::test_unary[sqrt(x_i < 0) -> NaN] array_api_tests/test_special_cases.py::test_binary[add((x1_i is +0 or x1_i == -0) and isfinite(x2_i) and x2_i != 0) -> x2_i] array_api_tests/test_special_cases.py::test_binary[add(isfinite(x1_i) and x1_i != 0 and (x2_i is +0 or x2_i == -0)) -> x1_i] array_api_tests/test_special_cases.py::test_binary[__add__((x1_i is +0 or x1_i == -0) and isfinite(x2_i) and x2_i != 0) -> x2_i] +array_api_tests/test_special_cases.py::test_binary[__add__(isfinite(x1_i) and x1_i != 0 and x2_i == -x1_i) -> +0] array_api_tests/test_special_cases.py::test_binary[copysign(x1_i is NaN and x2_i < 0) -> NaN] array_api_tests/test_special_cases.py::test_binary[copysign(x1_i is NaN and x2_i is -0) -> NaN] array_api_tests/test_special_cases.py::test_binary[copysign(x1_i is NaN and x2_i is +0) -> NaN] @@ -277,8 +280,7 @@ array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is +0 and x2_i > array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is +0 and x2_i < 0) -> +infinity] array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is -0 and x2_i > 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +0] array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is -0 and x2_i < 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +infinity] -array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i < 0 and isfinite(x1_i) and isfinite(x2_i) and not x2_i.is_integer()) -> NaN] -array_api_tests/test_special_cases.py::test_iop[__iadd__(isfinite(x1_i) and x1_i != 0 and x2_i == -x1_i) -> +0] +array_api_tests/test_special_cases.py::test_iop[__iadd__(isfinite(x1_i) and x1_i != 0 and (x2_i is +0 or x2_i == -0)) -> x1_i] array_api_tests/test_special_cases.py::test_iop[__itruediv__(x1_i is +0 and x2_i > 0) -> +0] array_api_tests/test_special_cases.py::test_iop[__itruediv__(x1_i is -0 and x2_i > 0) -> -0] array_api_tests/test_special_cases.py::test_iop[__itruediv__(x1_i is +0 and x2_i < 0) -> -0] diff --git a/heat/array_api/test/xfails.txt b/heat/array_api/test/xfails.txt index d3a81ea0e0..7ad24f82d2 100644 --- a/heat/array_api/test/xfails.txt +++ b/heat/array_api/test/xfails.txt @@ -84,14 +84,13 @@ array_api_tests/test_has_names.py::test_has_names[array_method-__complex__] array_api_tests/test_indexing_functions.py::test_take array_api_tests/test_inspection_functions.py::test_array_namespace_info array_api_tests/test_inspection_functions.py::test_array_namespace_info_dtypes +array_api_tests/test_linalg.py::test_matmul array_api_tests/test_linalg.py::test_matrix_transpose array_api_tests/test_linalg.py::test_tensordot array_api_tests/test_linalg.py::test_vecdot array_api_tests/test_manipulation_functions.py::test_concat array_api_tests/test_manipulation_functions.py::test_expand_dims array_api_tests/test_manipulation_functions.py::test_moveaxis -array_api_tests/test_manipulation_functions.py::test_squeeze -array_api_tests/test_manipulation_functions.py::test_flip array_api_tests/test_manipulation_functions.py::test_repeat array_api_tests/test_manipulation_functions.py::test_stack array_api_tests/test_manipulation_functions.py::test_tile @@ -100,9 +99,8 @@ array_api_tests/test_operators_and_elementwise_functions.py::test_abs[abs] array_api_tests/test_operators_and_elementwise_functions.py::test_abs[__abs__] array_api_tests/test_operators_and_elementwise_functions.py::test_acos array_api_tests/test_operators_and_elementwise_functions.py::test_acosh -array_api_tests/test_operators_and_elementwise_functions.py::test_add[add(x1, x2)] -array_api_tests/test_operators_and_elementwise_functions.py::test_add[__add__(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_add[__add__(x, s)] +array_api_tests/test_operators_and_elementwise_functions.py::test_add[__iadd__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_asin array_api_tests/test_operators_and_elementwise_functions.py::test_asinh array_api_tests/test_operators_and_elementwise_functions.py::test_atan @@ -128,16 +126,22 @@ array_api_tests/test_operators_and_elementwise_functions.py::test_equal[equal(x1 array_api_tests/test_operators_and_elementwise_functions.py::test_equal[__eq__(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_exp array_api_tests/test_operators_and_elementwise_functions.py::test_expm1 +array_api_tests/test_operators_and_elementwise_functions.py::test_floor array_api_tests/test_operators_and_elementwise_functions.py::test_floor_divide[floor_divide(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_floor_divide[__floordiv__(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_floor_divide[__floordiv__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_floor_divide[__ifloordiv__(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_floor_divide[__ifloordiv__(x, s)] +array_api_tests/test_operators_and_elementwise_functions.py::test_greater[greater(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_greater[__gt__(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_greater[__gt__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_hypot array_api_tests/test_operators_and_elementwise_functions.py::test_imag -array_api_tests/test_operators_and_elementwise_functions.py::test_isinf -array_api_tests/test_operators_and_elementwise_functions.py::test_less[less(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_isfinite +array_api_tests/test_operators_and_elementwise_functions.py::test_isnan +array_api_tests/test_operators_and_elementwise_functions.py::test_less_equal[less_equal(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_less_equal[__le__(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_less_equal[__le__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_log array_api_tests/test_operators_and_elementwise_functions.py::test_log1p array_api_tests/test_operators_and_elementwise_functions.py::test_log2 @@ -145,38 +149,35 @@ array_api_tests/test_operators_and_elementwise_functions.py::test_log10 array_api_tests/test_operators_and_elementwise_functions.py::test_logaddexp array_api_tests/test_operators_and_elementwise_functions.py::test_maximum array_api_tests/test_operators_and_elementwise_functions.py::test_minimum -array_api_tests/test_operators_and_elementwise_functions.py::test_multiply[multiply(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_multiply[__mul__(x1, x2)] -array_api_tests/test_operators_and_elementwise_functions.py::test_multiply[__imul__(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_multiply[__imul__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_negative[negative] array_api_tests/test_operators_and_elementwise_functions.py::test_negative[__neg__] -array_api_tests/test_operators_and_elementwise_functions.py::test_not_equal[not_equal(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_not_equal[__ne__(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_not_equal[__ne__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_positive[positive] array_api_tests/test_operators_and_elementwise_functions.py::test_positive[__pos__] array_api_tests/test_operators_and_elementwise_functions.py::test_pow[pow(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_pow[__pow__(x1, x2)] -array_api_tests/test_operators_and_elementwise_functions.py::test_pow[__pow__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_pow[__ipow__(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_pow[__ipow__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_real array_api_tests/test_operators_and_elementwise_functions.py::test_round array_api_tests/test_operators_and_elementwise_functions.py::test_signbit -array_api_tests/test_operators_and_elementwise_functions.py::test_sign array_api_tests/test_operators_and_elementwise_functions.py::test_sin array_api_tests/test_operators_and_elementwise_functions.py::test_sinh array_api_tests/test_operators_and_elementwise_functions.py::test_square array_api_tests/test_operators_and_elementwise_functions.py::test_sqrt -array_api_tests/test_operators_and_elementwise_functions.py::test_subtract[subtract(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_subtract[__sub__(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_subtract[__isub__(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_tan array_api_tests/test_operators_and_elementwise_functions.py::test_tanh +array_api_tests/test_operators_and_elementwise_functions.py::test_trunc array_api_tests/test_searching_functions.py::test_argmax array_api_tests/test_searching_functions.py::test_argmin array_api_tests/test_searching_functions.py::test_nonzero_zerodim_error array_api_tests/test_searching_functions.py::test_nonzero +array_api_tests/test_searching_functions.py::test_where array_api_tests/test_searching_functions.py::test_searchsorted array_api_tests/test_set_functions.py::test_unique_all array_api_tests/test_set_functions.py::test_unique_counts @@ -214,14 +215,14 @@ array_api_tests/test_signatures.py::test_info_func_signature[devices] array_api_tests/test_signatures.py::test_info_func_signature[dtypes] array_api_tests/test_sorting_functions.py::test_argsort array_api_tests/test_sorting_functions.py::test_sort -array_api_tests/test_special_cases.py::test_unary[floor(x_i.is_integer()) -> x_i] array_api_tests/test_special_cases.py::test_unary[isfinite((x_i is +infinity or x_i == -infinity)) -> False] array_api_tests/test_special_cases.py::test_unary[isfinite(x_i is NaN) -> False] array_api_tests/test_special_cases.py::test_unary[isfinite(isfinite(x_i)) -> True] array_api_tests/test_special_cases.py::test_unary[isinf((x_i is +infinity or x_i == -infinity)) -> True] array_api_tests/test_special_cases.py::test_unary[isnan(x_i is NaN) -> True] -array_api_tests/test_special_cases.py::test_unary[round(x_i.is_integer()) -> x_i] +array_api_tests/test_special_cases.py::test_unary[log2(x_i < 0) -> NaN] array_api_tests/test_special_cases.py::test_unary[round(modf(i)[0] == 0.5) -> Decimal(i).to_integral_exact(ROUND_HALF_EVEN)] +array_api_tests/test_special_cases.py::test_unary[sign(x_i < 0) -> -1] array_api_tests/test_special_cases.py::test_unary[sign(x_i is NaN) -> NaN] array_api_tests/test_special_cases.py::test_unary[signbit(x_i is +0) -> False] array_api_tests/test_special_cases.py::test_unary[signbit(x_i is -0) -> True] @@ -231,9 +232,11 @@ array_api_tests/test_special_cases.py::test_unary[signbit(isfinite(x_i) and x_i array_api_tests/test_special_cases.py::test_unary[signbit(isfinite(x_i) and x_i < 0) -> True] array_api_tests/test_special_cases.py::test_unary[signbit(x_i is +NaN) -> False] array_api_tests/test_special_cases.py::test_unary[signbit(x_i is -NaN) -> True] +array_api_tests/test_special_cases.py::test_unary[sqrt(x_i < 0) -> NaN] array_api_tests/test_special_cases.py::test_binary[add((x1_i is +0 or x1_i == -0) and isfinite(x2_i) and x2_i != 0) -> x2_i] array_api_tests/test_special_cases.py::test_binary[add(isfinite(x1_i) and x1_i != 0 and (x2_i is +0 or x2_i == -0)) -> x1_i] array_api_tests/test_special_cases.py::test_binary[__add__((x1_i is +0 or x1_i == -0) and isfinite(x2_i) and x2_i != 0) -> x2_i] +array_api_tests/test_special_cases.py::test_binary[__add__(isfinite(x1_i) and x1_i != 0 and x2_i == -x1_i) -> +0] array_api_tests/test_special_cases.py::test_binary[copysign(x1_i is NaN and x2_i < 0) -> NaN] array_api_tests/test_special_cases.py::test_binary[copysign(x1_i is NaN and x2_i is -0) -> NaN] array_api_tests/test_special_cases.py::test_binary[copysign(x1_i is NaN and x2_i is +0) -> NaN] @@ -277,8 +280,7 @@ array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is +0 and x2_i > array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is +0 and x2_i < 0) -> +infinity] array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is -0 and x2_i > 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +0] array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is -0 and x2_i < 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +infinity] -array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i < 0 and isfinite(x1_i) and isfinite(x2_i) and not x2_i.is_integer()) -> NaN] -array_api_tests/test_special_cases.py::test_iop[__iadd__(isfinite(x1_i) and x1_i != 0 and x2_i == -x1_i) -> +0] +array_api_tests/test_special_cases.py::test_iop[__iadd__(isfinite(x1_i) and x1_i != 0 and (x2_i is +0 or x2_i == -0)) -> x1_i] array_api_tests/test_special_cases.py::test_iop[__itruediv__(x1_i is +0 and x2_i > 0) -> +0] array_api_tests/test_special_cases.py::test_iop[__itruediv__(x1_i is -0 and x2_i > 0) -> -0] array_api_tests/test_special_cases.py::test_iop[__itruediv__(x1_i is +0 and x2_i < 0) -> -0] From 2548bdbf78653a52be34a629355b9bff74577362 Mon Sep 17 00:00:00 2001 From: Michael Tarnawa Date: Thu, 11 Jul 2024 14:51:26 +0200 Subject: [PATCH 137/150] update skips/xfails --- heat/array_api/test/skips.txt | 31 ------------------------------- heat/array_api/test/xfails.txt | 31 ------------------------------- 2 files changed, 62 deletions(-) diff --git a/heat/array_api/test/skips.txt b/heat/array_api/test/skips.txt index 7ad24f82d2..06aeeee9cf 100644 --- a/heat/array_api/test/skips.txt +++ b/heat/array_api/test/skips.txt @@ -18,7 +18,6 @@ array_api_tests/test_creation_functions.py::test_zeros_like array_api_tests/test_data_type_functions.py::test_astype array_api_tests/test_data_type_functions.py::test_broadcast_arrays array_api_tests/test_data_type_functions.py::test_broadcast_to -array_api_tests/test_data_type_functions.py::test_can_cast array_api_tests/test_data_type_functions.py::test_finfo[float32] array_api_tests/test_data_type_functions.py::test_finfo[float64] array_api_tests/test_data_type_functions.py::test_iinfo[int8] @@ -84,11 +83,9 @@ array_api_tests/test_has_names.py::test_has_names[array_method-__complex__] array_api_tests/test_indexing_functions.py::test_take array_api_tests/test_inspection_functions.py::test_array_namespace_info array_api_tests/test_inspection_functions.py::test_array_namespace_info_dtypes -array_api_tests/test_linalg.py::test_matmul array_api_tests/test_linalg.py::test_matrix_transpose array_api_tests/test_linalg.py::test_tensordot array_api_tests/test_linalg.py::test_vecdot -array_api_tests/test_manipulation_functions.py::test_concat array_api_tests/test_manipulation_functions.py::test_expand_dims array_api_tests/test_manipulation_functions.py::test_moveaxis array_api_tests/test_manipulation_functions.py::test_repeat @@ -99,8 +96,6 @@ array_api_tests/test_operators_and_elementwise_functions.py::test_abs[abs] array_api_tests/test_operators_and_elementwise_functions.py::test_abs[__abs__] array_api_tests/test_operators_and_elementwise_functions.py::test_acos array_api_tests/test_operators_and_elementwise_functions.py::test_acosh -array_api_tests/test_operators_and_elementwise_functions.py::test_add[__add__(x, s)] -array_api_tests/test_operators_and_elementwise_functions.py::test_add[__iadd__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_asin array_api_tests/test_operators_and_elementwise_functions.py::test_asinh array_api_tests/test_operators_and_elementwise_functions.py::test_atan @@ -122,26 +117,17 @@ array_api_tests/test_operators_and_elementwise_functions.py::test_divide[__trued array_api_tests/test_operators_and_elementwise_functions.py::test_divide[__truediv__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_divide[__itruediv__(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_divide[__itruediv__(x, s)] -array_api_tests/test_operators_and_elementwise_functions.py::test_equal[equal(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_equal[__eq__(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_exp array_api_tests/test_operators_and_elementwise_functions.py::test_expm1 -array_api_tests/test_operators_and_elementwise_functions.py::test_floor array_api_tests/test_operators_and_elementwise_functions.py::test_floor_divide[floor_divide(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_floor_divide[__floordiv__(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_floor_divide[__floordiv__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_floor_divide[__ifloordiv__(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_floor_divide[__ifloordiv__(x, s)] -array_api_tests/test_operators_and_elementwise_functions.py::test_greater[greater(x1, x2)] -array_api_tests/test_operators_and_elementwise_functions.py::test_greater[__gt__(x1, x2)] -array_api_tests/test_operators_and_elementwise_functions.py::test_greater[__gt__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_hypot array_api_tests/test_operators_and_elementwise_functions.py::test_imag array_api_tests/test_operators_and_elementwise_functions.py::test_isfinite -array_api_tests/test_operators_and_elementwise_functions.py::test_isnan -array_api_tests/test_operators_and_elementwise_functions.py::test_less_equal[less_equal(x1, x2)] -array_api_tests/test_operators_and_elementwise_functions.py::test_less_equal[__le__(x1, x2)] -array_api_tests/test_operators_and_elementwise_functions.py::test_less_equal[__le__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_log array_api_tests/test_operators_and_elementwise_functions.py::test_log1p array_api_tests/test_operators_and_elementwise_functions.py::test_log2 @@ -149,27 +135,21 @@ array_api_tests/test_operators_and_elementwise_functions.py::test_log10 array_api_tests/test_operators_and_elementwise_functions.py::test_logaddexp array_api_tests/test_operators_and_elementwise_functions.py::test_maximum array_api_tests/test_operators_and_elementwise_functions.py::test_minimum -array_api_tests/test_operators_and_elementwise_functions.py::test_multiply[__mul__(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_multiply[__imul__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_negative[negative] array_api_tests/test_operators_and_elementwise_functions.py::test_negative[__neg__] array_api_tests/test_operators_and_elementwise_functions.py::test_not_equal[__ne__(x1, x2)] -array_api_tests/test_operators_and_elementwise_functions.py::test_not_equal[__ne__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_positive[positive] array_api_tests/test_operators_and_elementwise_functions.py::test_positive[__pos__] array_api_tests/test_operators_and_elementwise_functions.py::test_pow[pow(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_pow[__pow__(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_pow[__ipow__(x1, x2)] -array_api_tests/test_operators_and_elementwise_functions.py::test_pow[__ipow__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_real array_api_tests/test_operators_and_elementwise_functions.py::test_round array_api_tests/test_operators_and_elementwise_functions.py::test_signbit array_api_tests/test_operators_and_elementwise_functions.py::test_sin array_api_tests/test_operators_and_elementwise_functions.py::test_sinh -array_api_tests/test_operators_and_elementwise_functions.py::test_square array_api_tests/test_operators_and_elementwise_functions.py::test_sqrt -array_api_tests/test_operators_and_elementwise_functions.py::test_subtract[__sub__(x1, x2)] -array_api_tests/test_operators_and_elementwise_functions.py::test_subtract[__isub__(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_tan array_api_tests/test_operators_and_elementwise_functions.py::test_tanh array_api_tests/test_operators_and_elementwise_functions.py::test_trunc @@ -177,12 +157,10 @@ array_api_tests/test_searching_functions.py::test_argmax array_api_tests/test_searching_functions.py::test_argmin array_api_tests/test_searching_functions.py::test_nonzero_zerodim_error array_api_tests/test_searching_functions.py::test_nonzero -array_api_tests/test_searching_functions.py::test_where array_api_tests/test_searching_functions.py::test_searchsorted array_api_tests/test_set_functions.py::test_unique_all array_api_tests/test_set_functions.py::test_unique_counts array_api_tests/test_set_functions.py::test_unique_inverse -array_api_tests/test_set_functions.py::test_unique_values array_api_tests/test_signatures.py::test_func_signature[from_dlpack] array_api_tests/test_signatures.py::test_func_signature[take] array_api_tests/test_signatures.py::test_func_signature[unique_all] @@ -220,9 +198,6 @@ array_api_tests/test_special_cases.py::test_unary[isfinite(x_i is NaN) -> False] array_api_tests/test_special_cases.py::test_unary[isfinite(isfinite(x_i)) -> True] array_api_tests/test_special_cases.py::test_unary[isinf((x_i is +infinity or x_i == -infinity)) -> True] array_api_tests/test_special_cases.py::test_unary[isnan(x_i is NaN) -> True] -array_api_tests/test_special_cases.py::test_unary[log2(x_i < 0) -> NaN] -array_api_tests/test_special_cases.py::test_unary[round(modf(i)[0] == 0.5) -> Decimal(i).to_integral_exact(ROUND_HALF_EVEN)] -array_api_tests/test_special_cases.py::test_unary[sign(x_i < 0) -> -1] array_api_tests/test_special_cases.py::test_unary[sign(x_i is NaN) -> NaN] array_api_tests/test_special_cases.py::test_unary[signbit(x_i is +0) -> False] array_api_tests/test_special_cases.py::test_unary[signbit(x_i is -0) -> True] @@ -232,11 +207,7 @@ array_api_tests/test_special_cases.py::test_unary[signbit(isfinite(x_i) and x_i array_api_tests/test_special_cases.py::test_unary[signbit(isfinite(x_i) and x_i < 0) -> True] array_api_tests/test_special_cases.py::test_unary[signbit(x_i is +NaN) -> False] array_api_tests/test_special_cases.py::test_unary[signbit(x_i is -NaN) -> True] -array_api_tests/test_special_cases.py::test_unary[sqrt(x_i < 0) -> NaN] -array_api_tests/test_special_cases.py::test_binary[add((x1_i is +0 or x1_i == -0) and isfinite(x2_i) and x2_i != 0) -> x2_i] array_api_tests/test_special_cases.py::test_binary[add(isfinite(x1_i) and x1_i != 0 and (x2_i is +0 or x2_i == -0)) -> x1_i] -array_api_tests/test_special_cases.py::test_binary[__add__((x1_i is +0 or x1_i == -0) and isfinite(x2_i) and x2_i != 0) -> x2_i] -array_api_tests/test_special_cases.py::test_binary[__add__(isfinite(x1_i) and x1_i != 0 and x2_i == -x1_i) -> +0] array_api_tests/test_special_cases.py::test_binary[copysign(x1_i is NaN and x2_i < 0) -> NaN] array_api_tests/test_special_cases.py::test_binary[copysign(x1_i is NaN and x2_i is -0) -> NaN] array_api_tests/test_special_cases.py::test_binary[copysign(x1_i is NaN and x2_i is +0) -> NaN] @@ -280,7 +251,6 @@ array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is +0 and x2_i > array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is +0 and x2_i < 0) -> +infinity] array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is -0 and x2_i > 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +0] array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is -0 and x2_i < 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +infinity] -array_api_tests/test_special_cases.py::test_iop[__iadd__(isfinite(x1_i) and x1_i != 0 and (x2_i is +0 or x2_i == -0)) -> x1_i] array_api_tests/test_special_cases.py::test_iop[__itruediv__(x1_i is +0 and x2_i > 0) -> +0] array_api_tests/test_special_cases.py::test_iop[__itruediv__(x1_i is -0 and x2_i > 0) -> -0] array_api_tests/test_special_cases.py::test_iop[__itruediv__(x1_i is +0 and x2_i < 0) -> -0] @@ -299,7 +269,6 @@ array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i is +0 and x2_i > 0 array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i is +0 and x2_i < 0) -> +infinity] array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i is -0 and x2_i > 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +0] array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i is -0 and x2_i < 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +infinity] -array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i < 0 and isfinite(x1_i) and isfinite(x2_i) and not x2_i.is_integer()) -> NaN] array_api_tests/test_special_cases.py::test_empty_arrays[prod] array_api_tests/test_special_cases.py::test_empty_arrays[std] array_api_tests/test_special_cases.py::test_empty_arrays[sum] diff --git a/heat/array_api/test/xfails.txt b/heat/array_api/test/xfails.txt index 7ad24f82d2..06aeeee9cf 100644 --- a/heat/array_api/test/xfails.txt +++ b/heat/array_api/test/xfails.txt @@ -18,7 +18,6 @@ array_api_tests/test_creation_functions.py::test_zeros_like array_api_tests/test_data_type_functions.py::test_astype array_api_tests/test_data_type_functions.py::test_broadcast_arrays array_api_tests/test_data_type_functions.py::test_broadcast_to -array_api_tests/test_data_type_functions.py::test_can_cast array_api_tests/test_data_type_functions.py::test_finfo[float32] array_api_tests/test_data_type_functions.py::test_finfo[float64] array_api_tests/test_data_type_functions.py::test_iinfo[int8] @@ -84,11 +83,9 @@ array_api_tests/test_has_names.py::test_has_names[array_method-__complex__] array_api_tests/test_indexing_functions.py::test_take array_api_tests/test_inspection_functions.py::test_array_namespace_info array_api_tests/test_inspection_functions.py::test_array_namespace_info_dtypes -array_api_tests/test_linalg.py::test_matmul array_api_tests/test_linalg.py::test_matrix_transpose array_api_tests/test_linalg.py::test_tensordot array_api_tests/test_linalg.py::test_vecdot -array_api_tests/test_manipulation_functions.py::test_concat array_api_tests/test_manipulation_functions.py::test_expand_dims array_api_tests/test_manipulation_functions.py::test_moveaxis array_api_tests/test_manipulation_functions.py::test_repeat @@ -99,8 +96,6 @@ array_api_tests/test_operators_and_elementwise_functions.py::test_abs[abs] array_api_tests/test_operators_and_elementwise_functions.py::test_abs[__abs__] array_api_tests/test_operators_and_elementwise_functions.py::test_acos array_api_tests/test_operators_and_elementwise_functions.py::test_acosh -array_api_tests/test_operators_and_elementwise_functions.py::test_add[__add__(x, s)] -array_api_tests/test_operators_and_elementwise_functions.py::test_add[__iadd__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_asin array_api_tests/test_operators_and_elementwise_functions.py::test_asinh array_api_tests/test_operators_and_elementwise_functions.py::test_atan @@ -122,26 +117,17 @@ array_api_tests/test_operators_and_elementwise_functions.py::test_divide[__trued array_api_tests/test_operators_and_elementwise_functions.py::test_divide[__truediv__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_divide[__itruediv__(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_divide[__itruediv__(x, s)] -array_api_tests/test_operators_and_elementwise_functions.py::test_equal[equal(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_equal[__eq__(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_exp array_api_tests/test_operators_and_elementwise_functions.py::test_expm1 -array_api_tests/test_operators_and_elementwise_functions.py::test_floor array_api_tests/test_operators_and_elementwise_functions.py::test_floor_divide[floor_divide(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_floor_divide[__floordiv__(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_floor_divide[__floordiv__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_floor_divide[__ifloordiv__(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_floor_divide[__ifloordiv__(x, s)] -array_api_tests/test_operators_and_elementwise_functions.py::test_greater[greater(x1, x2)] -array_api_tests/test_operators_and_elementwise_functions.py::test_greater[__gt__(x1, x2)] -array_api_tests/test_operators_and_elementwise_functions.py::test_greater[__gt__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_hypot array_api_tests/test_operators_and_elementwise_functions.py::test_imag array_api_tests/test_operators_and_elementwise_functions.py::test_isfinite -array_api_tests/test_operators_and_elementwise_functions.py::test_isnan -array_api_tests/test_operators_and_elementwise_functions.py::test_less_equal[less_equal(x1, x2)] -array_api_tests/test_operators_and_elementwise_functions.py::test_less_equal[__le__(x1, x2)] -array_api_tests/test_operators_and_elementwise_functions.py::test_less_equal[__le__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_log array_api_tests/test_operators_and_elementwise_functions.py::test_log1p array_api_tests/test_operators_and_elementwise_functions.py::test_log2 @@ -149,27 +135,21 @@ array_api_tests/test_operators_and_elementwise_functions.py::test_log10 array_api_tests/test_operators_and_elementwise_functions.py::test_logaddexp array_api_tests/test_operators_and_elementwise_functions.py::test_maximum array_api_tests/test_operators_and_elementwise_functions.py::test_minimum -array_api_tests/test_operators_and_elementwise_functions.py::test_multiply[__mul__(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_multiply[__imul__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_negative[negative] array_api_tests/test_operators_and_elementwise_functions.py::test_negative[__neg__] array_api_tests/test_operators_and_elementwise_functions.py::test_not_equal[__ne__(x1, x2)] -array_api_tests/test_operators_and_elementwise_functions.py::test_not_equal[__ne__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_positive[positive] array_api_tests/test_operators_and_elementwise_functions.py::test_positive[__pos__] array_api_tests/test_operators_and_elementwise_functions.py::test_pow[pow(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_pow[__pow__(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_pow[__ipow__(x1, x2)] -array_api_tests/test_operators_and_elementwise_functions.py::test_pow[__ipow__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_real array_api_tests/test_operators_and_elementwise_functions.py::test_round array_api_tests/test_operators_and_elementwise_functions.py::test_signbit array_api_tests/test_operators_and_elementwise_functions.py::test_sin array_api_tests/test_operators_and_elementwise_functions.py::test_sinh -array_api_tests/test_operators_and_elementwise_functions.py::test_square array_api_tests/test_operators_and_elementwise_functions.py::test_sqrt -array_api_tests/test_operators_and_elementwise_functions.py::test_subtract[__sub__(x1, x2)] -array_api_tests/test_operators_and_elementwise_functions.py::test_subtract[__isub__(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_tan array_api_tests/test_operators_and_elementwise_functions.py::test_tanh array_api_tests/test_operators_and_elementwise_functions.py::test_trunc @@ -177,12 +157,10 @@ array_api_tests/test_searching_functions.py::test_argmax array_api_tests/test_searching_functions.py::test_argmin array_api_tests/test_searching_functions.py::test_nonzero_zerodim_error array_api_tests/test_searching_functions.py::test_nonzero -array_api_tests/test_searching_functions.py::test_where array_api_tests/test_searching_functions.py::test_searchsorted array_api_tests/test_set_functions.py::test_unique_all array_api_tests/test_set_functions.py::test_unique_counts array_api_tests/test_set_functions.py::test_unique_inverse -array_api_tests/test_set_functions.py::test_unique_values array_api_tests/test_signatures.py::test_func_signature[from_dlpack] array_api_tests/test_signatures.py::test_func_signature[take] array_api_tests/test_signatures.py::test_func_signature[unique_all] @@ -220,9 +198,6 @@ array_api_tests/test_special_cases.py::test_unary[isfinite(x_i is NaN) -> False] array_api_tests/test_special_cases.py::test_unary[isfinite(isfinite(x_i)) -> True] array_api_tests/test_special_cases.py::test_unary[isinf((x_i is +infinity or x_i == -infinity)) -> True] array_api_tests/test_special_cases.py::test_unary[isnan(x_i is NaN) -> True] -array_api_tests/test_special_cases.py::test_unary[log2(x_i < 0) -> NaN] -array_api_tests/test_special_cases.py::test_unary[round(modf(i)[0] == 0.5) -> Decimal(i).to_integral_exact(ROUND_HALF_EVEN)] -array_api_tests/test_special_cases.py::test_unary[sign(x_i < 0) -> -1] array_api_tests/test_special_cases.py::test_unary[sign(x_i is NaN) -> NaN] array_api_tests/test_special_cases.py::test_unary[signbit(x_i is +0) -> False] array_api_tests/test_special_cases.py::test_unary[signbit(x_i is -0) -> True] @@ -232,11 +207,7 @@ array_api_tests/test_special_cases.py::test_unary[signbit(isfinite(x_i) and x_i array_api_tests/test_special_cases.py::test_unary[signbit(isfinite(x_i) and x_i < 0) -> True] array_api_tests/test_special_cases.py::test_unary[signbit(x_i is +NaN) -> False] array_api_tests/test_special_cases.py::test_unary[signbit(x_i is -NaN) -> True] -array_api_tests/test_special_cases.py::test_unary[sqrt(x_i < 0) -> NaN] -array_api_tests/test_special_cases.py::test_binary[add((x1_i is +0 or x1_i == -0) and isfinite(x2_i) and x2_i != 0) -> x2_i] array_api_tests/test_special_cases.py::test_binary[add(isfinite(x1_i) and x1_i != 0 and (x2_i is +0 or x2_i == -0)) -> x1_i] -array_api_tests/test_special_cases.py::test_binary[__add__((x1_i is +0 or x1_i == -0) and isfinite(x2_i) and x2_i != 0) -> x2_i] -array_api_tests/test_special_cases.py::test_binary[__add__(isfinite(x1_i) and x1_i != 0 and x2_i == -x1_i) -> +0] array_api_tests/test_special_cases.py::test_binary[copysign(x1_i is NaN and x2_i < 0) -> NaN] array_api_tests/test_special_cases.py::test_binary[copysign(x1_i is NaN and x2_i is -0) -> NaN] array_api_tests/test_special_cases.py::test_binary[copysign(x1_i is NaN and x2_i is +0) -> NaN] @@ -280,7 +251,6 @@ array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is +0 and x2_i > array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is +0 and x2_i < 0) -> +infinity] array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is -0 and x2_i > 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +0] array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is -0 and x2_i < 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +infinity] -array_api_tests/test_special_cases.py::test_iop[__iadd__(isfinite(x1_i) and x1_i != 0 and (x2_i is +0 or x2_i == -0)) -> x1_i] array_api_tests/test_special_cases.py::test_iop[__itruediv__(x1_i is +0 and x2_i > 0) -> +0] array_api_tests/test_special_cases.py::test_iop[__itruediv__(x1_i is -0 and x2_i > 0) -> -0] array_api_tests/test_special_cases.py::test_iop[__itruediv__(x1_i is +0 and x2_i < 0) -> -0] @@ -299,7 +269,6 @@ array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i is +0 and x2_i > 0 array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i is +0 and x2_i < 0) -> +infinity] array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i is -0 and x2_i > 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +0] array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i is -0 and x2_i < 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +infinity] -array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i < 0 and isfinite(x1_i) and isfinite(x2_i) and not x2_i.is_integer()) -> NaN] array_api_tests/test_special_cases.py::test_empty_arrays[prod] array_api_tests/test_special_cases.py::test_empty_arrays[std] array_api_tests/test_special_cases.py::test_empty_arrays[sum] From d95e4f024ac59ae5ef1aeb6fd276ae18286d3818 Mon Sep 17 00:00:00 2001 From: Michael Tarnawa Date: Thu, 11 Jul 2024 15:40:59 +0200 Subject: [PATCH 138/150] update skips/xfails --- heat/array_api/test/skips.txt | 8 -------- heat/array_api/test/xfails.txt | 8 -------- 2 files changed, 16 deletions(-) diff --git a/heat/array_api/test/skips.txt b/heat/array_api/test/skips.txt index 06aeeee9cf..0004c7dda0 100644 --- a/heat/array_api/test/skips.txt +++ b/heat/array_api/test/skips.txt @@ -86,7 +86,6 @@ array_api_tests/test_inspection_functions.py::test_array_namespace_info_dtypes array_api_tests/test_linalg.py::test_matrix_transpose array_api_tests/test_linalg.py::test_tensordot array_api_tests/test_linalg.py::test_vecdot -array_api_tests/test_manipulation_functions.py::test_expand_dims array_api_tests/test_manipulation_functions.py::test_moveaxis array_api_tests/test_manipulation_functions.py::test_repeat array_api_tests/test_manipulation_functions.py::test_stack @@ -99,7 +98,6 @@ array_api_tests/test_operators_and_elementwise_functions.py::test_acosh array_api_tests/test_operators_and_elementwise_functions.py::test_asin array_api_tests/test_operators_and_elementwise_functions.py::test_asinh array_api_tests/test_operators_and_elementwise_functions.py::test_atan -array_api_tests/test_operators_and_elementwise_functions.py::test_atan2 array_api_tests/test_operators_and_elementwise_functions.py::test_atanh array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_left_shift[bitwise_left_shift(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_left_shift[__lshift__(x1, x2)] @@ -130,15 +128,12 @@ array_api_tests/test_operators_and_elementwise_functions.py::test_imag array_api_tests/test_operators_and_elementwise_functions.py::test_isfinite array_api_tests/test_operators_and_elementwise_functions.py::test_log array_api_tests/test_operators_and_elementwise_functions.py::test_log1p -array_api_tests/test_operators_and_elementwise_functions.py::test_log2 array_api_tests/test_operators_and_elementwise_functions.py::test_log10 array_api_tests/test_operators_and_elementwise_functions.py::test_logaddexp array_api_tests/test_operators_and_elementwise_functions.py::test_maximum array_api_tests/test_operators_and_elementwise_functions.py::test_minimum -array_api_tests/test_operators_and_elementwise_functions.py::test_multiply[__imul__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_negative[negative] array_api_tests/test_operators_and_elementwise_functions.py::test_negative[__neg__] -array_api_tests/test_operators_and_elementwise_functions.py::test_not_equal[__ne__(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_positive[positive] array_api_tests/test_operators_and_elementwise_functions.py::test_positive[__pos__] array_api_tests/test_operators_and_elementwise_functions.py::test_pow[pow(x1, x2)] @@ -152,7 +147,6 @@ array_api_tests/test_operators_and_elementwise_functions.py::test_sinh array_api_tests/test_operators_and_elementwise_functions.py::test_sqrt array_api_tests/test_operators_and_elementwise_functions.py::test_tan array_api_tests/test_operators_and_elementwise_functions.py::test_tanh -array_api_tests/test_operators_and_elementwise_functions.py::test_trunc array_api_tests/test_searching_functions.py::test_argmax array_api_tests/test_searching_functions.py::test_argmin array_api_tests/test_searching_functions.py::test_nonzero_zerodim_error @@ -207,7 +201,6 @@ array_api_tests/test_special_cases.py::test_unary[signbit(isfinite(x_i) and x_i array_api_tests/test_special_cases.py::test_unary[signbit(isfinite(x_i) and x_i < 0) -> True] array_api_tests/test_special_cases.py::test_unary[signbit(x_i is +NaN) -> False] array_api_tests/test_special_cases.py::test_unary[signbit(x_i is -NaN) -> True] -array_api_tests/test_special_cases.py::test_binary[add(isfinite(x1_i) and x1_i != 0 and (x2_i is +0 or x2_i == -0)) -> x1_i] array_api_tests/test_special_cases.py::test_binary[copysign(x1_i is NaN and x2_i < 0) -> NaN] array_api_tests/test_special_cases.py::test_binary[copysign(x1_i is NaN and x2_i is -0) -> NaN] array_api_tests/test_special_cases.py::test_binary[copysign(x1_i is NaN and x2_i is +0) -> NaN] @@ -240,7 +233,6 @@ array_api_tests/test_special_cases.py::test_binary[pow(x1_i is +0 and x2_i > 0) array_api_tests/test_special_cases.py::test_binary[pow(x1_i is +0 and x2_i < 0) -> +infinity] array_api_tests/test_special_cases.py::test_binary[pow(x1_i is -0 and x2_i > 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +0] array_api_tests/test_special_cases.py::test_binary[pow(x1_i is -0 and x2_i < 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +infinity] -array_api_tests/test_special_cases.py::test_binary[pow(x1_i < 0 and isfinite(x1_i) and isfinite(x2_i) and not x2_i.is_integer()) -> NaN] array_api_tests/test_special_cases.py::test_binary[__pow__(abs(x1_i) > 1 and x2_i is +infinity) -> +infinity] array_api_tests/test_special_cases.py::test_binary[__pow__(abs(x1_i) > 1 and x2_i is -infinity) -> +0] array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is +infinity and x2_i > 0) -> +infinity] diff --git a/heat/array_api/test/xfails.txt b/heat/array_api/test/xfails.txt index 06aeeee9cf..0004c7dda0 100644 --- a/heat/array_api/test/xfails.txt +++ b/heat/array_api/test/xfails.txt @@ -86,7 +86,6 @@ array_api_tests/test_inspection_functions.py::test_array_namespace_info_dtypes array_api_tests/test_linalg.py::test_matrix_transpose array_api_tests/test_linalg.py::test_tensordot array_api_tests/test_linalg.py::test_vecdot -array_api_tests/test_manipulation_functions.py::test_expand_dims array_api_tests/test_manipulation_functions.py::test_moveaxis array_api_tests/test_manipulation_functions.py::test_repeat array_api_tests/test_manipulation_functions.py::test_stack @@ -99,7 +98,6 @@ array_api_tests/test_operators_and_elementwise_functions.py::test_acosh array_api_tests/test_operators_and_elementwise_functions.py::test_asin array_api_tests/test_operators_and_elementwise_functions.py::test_asinh array_api_tests/test_operators_and_elementwise_functions.py::test_atan -array_api_tests/test_operators_and_elementwise_functions.py::test_atan2 array_api_tests/test_operators_and_elementwise_functions.py::test_atanh array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_left_shift[bitwise_left_shift(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_left_shift[__lshift__(x1, x2)] @@ -130,15 +128,12 @@ array_api_tests/test_operators_and_elementwise_functions.py::test_imag array_api_tests/test_operators_and_elementwise_functions.py::test_isfinite array_api_tests/test_operators_and_elementwise_functions.py::test_log array_api_tests/test_operators_and_elementwise_functions.py::test_log1p -array_api_tests/test_operators_and_elementwise_functions.py::test_log2 array_api_tests/test_operators_and_elementwise_functions.py::test_log10 array_api_tests/test_operators_and_elementwise_functions.py::test_logaddexp array_api_tests/test_operators_and_elementwise_functions.py::test_maximum array_api_tests/test_operators_and_elementwise_functions.py::test_minimum -array_api_tests/test_operators_and_elementwise_functions.py::test_multiply[__imul__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_negative[negative] array_api_tests/test_operators_and_elementwise_functions.py::test_negative[__neg__] -array_api_tests/test_operators_and_elementwise_functions.py::test_not_equal[__ne__(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_positive[positive] array_api_tests/test_operators_and_elementwise_functions.py::test_positive[__pos__] array_api_tests/test_operators_and_elementwise_functions.py::test_pow[pow(x1, x2)] @@ -152,7 +147,6 @@ array_api_tests/test_operators_and_elementwise_functions.py::test_sinh array_api_tests/test_operators_and_elementwise_functions.py::test_sqrt array_api_tests/test_operators_and_elementwise_functions.py::test_tan array_api_tests/test_operators_and_elementwise_functions.py::test_tanh -array_api_tests/test_operators_and_elementwise_functions.py::test_trunc array_api_tests/test_searching_functions.py::test_argmax array_api_tests/test_searching_functions.py::test_argmin array_api_tests/test_searching_functions.py::test_nonzero_zerodim_error @@ -207,7 +201,6 @@ array_api_tests/test_special_cases.py::test_unary[signbit(isfinite(x_i) and x_i array_api_tests/test_special_cases.py::test_unary[signbit(isfinite(x_i) and x_i < 0) -> True] array_api_tests/test_special_cases.py::test_unary[signbit(x_i is +NaN) -> False] array_api_tests/test_special_cases.py::test_unary[signbit(x_i is -NaN) -> True] -array_api_tests/test_special_cases.py::test_binary[add(isfinite(x1_i) and x1_i != 0 and (x2_i is +0 or x2_i == -0)) -> x1_i] array_api_tests/test_special_cases.py::test_binary[copysign(x1_i is NaN and x2_i < 0) -> NaN] array_api_tests/test_special_cases.py::test_binary[copysign(x1_i is NaN and x2_i is -0) -> NaN] array_api_tests/test_special_cases.py::test_binary[copysign(x1_i is NaN and x2_i is +0) -> NaN] @@ -240,7 +233,6 @@ array_api_tests/test_special_cases.py::test_binary[pow(x1_i is +0 and x2_i > 0) array_api_tests/test_special_cases.py::test_binary[pow(x1_i is +0 and x2_i < 0) -> +infinity] array_api_tests/test_special_cases.py::test_binary[pow(x1_i is -0 and x2_i > 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +0] array_api_tests/test_special_cases.py::test_binary[pow(x1_i is -0 and x2_i < 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +infinity] -array_api_tests/test_special_cases.py::test_binary[pow(x1_i < 0 and isfinite(x1_i) and isfinite(x2_i) and not x2_i.is_integer()) -> NaN] array_api_tests/test_special_cases.py::test_binary[__pow__(abs(x1_i) > 1 and x2_i is +infinity) -> +infinity] array_api_tests/test_special_cases.py::test_binary[__pow__(abs(x1_i) > 1 and x2_i is -infinity) -> +0] array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is +infinity and x2_i > 0) -> +infinity] From ccdf750f2b7076edcf39106d29c582979af84e2f Mon Sep 17 00:00:00 2001 From: Michael Tarnawa Date: Fri, 12 Jul 2024 11:30:19 +0200 Subject: [PATCH 139/150] put functions in limbo into skips --- .github/workflows/array-api.yml | 2 +- heat/array_api/test/skips.txt | 351 +++++++------------------------- heat/array_api/test/xfails.txt | 1 + 3 files changed, 72 insertions(+), 282 deletions(-) diff --git a/.github/workflows/array-api.yml b/.github/workflows/array-api.yml index ff000d35f4..883c013074 100644 --- a/.github/workflows/array-api.yml +++ b/.github/workflows/array-api.yml @@ -50,4 +50,4 @@ jobs: export PYTHONPATH="${GITHUB_WORKSPACE}/heat" # Skip testing functions with known issues cd ${GITHUB_WORKSPACE}/array-api-tests - pytest array_api_tests/ -v -rxXfE --ci --xfails-file ${GITHUB_WORKSPACE}/heat/heat/array_api/test/skips.txt --disable-extension linalg + pytest array_api_tests/ -v -rxXfE --ci --xfails-file ${GITHUB_WORKSPACE}/heat/heat/array_api/test/xfails.txt --skips-file ${GITHUB_WORKSPACE}/heat/heat/array_api/test/skips.txt --disable-extension linalg diff --git a/heat/array_api/test/skips.txt b/heat/array_api/test/skips.txt index 0004c7dda0..8fc36d0c26 100644 --- a/heat/array_api/test/skips.txt +++ b/heat/array_api/test/skips.txt @@ -1,281 +1,70 @@ -array_api_tests/test_array_object.py::test_getitem -array_api_tests/test_array_object.py::test_setitem -array_api_tests/test_array_object.py::test_getitem_masking -array_api_tests/test_array_object.py::test_setitem_masking -array_api_tests/test_array_object.py::test_scalar_casting[__float__(float64)] -array_api_tests/test_creation_functions.py::test_arange -array_api_tests/test_creation_functions.py::test_asarray_arrays -array_api_tests/test_creation_functions.py::test_empty_like -array_api_tests/test_creation_functions.py::test_eye -array_api_tests/test_creation_functions.py::test_full -array_api_tests/test_creation_functions.py::test_full_like -array_api_tests/test_creation_functions.py::test_linspace -array_api_tests/test_creation_functions.py::test_meshgrid -array_api_tests/test_creation_functions.py::test_ones -array_api_tests/test_creation_functions.py::test_ones_like -array_api_tests/test_creation_functions.py::test_zeros -array_api_tests/test_creation_functions.py::test_zeros_like -array_api_tests/test_data_type_functions.py::test_astype -array_api_tests/test_data_type_functions.py::test_broadcast_arrays -array_api_tests/test_data_type_functions.py::test_broadcast_to -array_api_tests/test_data_type_functions.py::test_finfo[float32] -array_api_tests/test_data_type_functions.py::test_finfo[float64] -array_api_tests/test_data_type_functions.py::test_iinfo[int8] -array_api_tests/test_data_type_functions.py::test_iinfo[int16] -array_api_tests/test_data_type_functions.py::test_iinfo[int32] -array_api_tests/test_data_type_functions.py::test_iinfo[int64] -array_api_tests/test_data_type_functions.py::test_isdtype -array_api_tests/test_has_names.py::test_has_names[linalg-cholesky] -array_api_tests/test_has_names.py::test_has_names[linalg-cross] -array_api_tests/test_has_names.py::test_has_names[linalg-det] -array_api_tests/test_has_names.py::test_has_names[linalg-diagonal] -array_api_tests/test_has_names.py::test_has_names[linalg-eigh] -array_api_tests/test_has_names.py::test_has_names[linalg-eigvalsh] -array_api_tests/test_has_names.py::test_has_names[linalg-inv] -array_api_tests/test_has_names.py::test_has_names[linalg-matrix_norm] -array_api_tests/test_has_names.py::test_has_names[linalg-matrix_power] -array_api_tests/test_has_names.py::test_has_names[linalg-matrix_rank] -array_api_tests/test_has_names.py::test_has_names[linalg-outer] -array_api_tests/test_has_names.py::test_has_names[linalg-pinv] -array_api_tests/test_has_names.py::test_has_names[linalg-qr] -array_api_tests/test_has_names.py::test_has_names[linalg-slogdet] -array_api_tests/test_has_names.py::test_has_names[linalg-solve] -array_api_tests/test_has_names.py::test_has_names[linalg-svd] -array_api_tests/test_has_names.py::test_has_names[linalg-svdvals] -array_api_tests/test_has_names.py::test_has_names[linalg-trace] -array_api_tests/test_has_names.py::test_has_names[linalg-vector_norm] -array_api_tests/test_has_names.py::test_has_names[fft-fft] -array_api_tests/test_has_names.py::test_has_names[fft-ifft] -array_api_tests/test_has_names.py::test_has_names[fft-fftn] -array_api_tests/test_has_names.py::test_has_names[fft-ifftn] -array_api_tests/test_has_names.py::test_has_names[fft-rfft] -array_api_tests/test_has_names.py::test_has_names[fft-irfft] -array_api_tests/test_has_names.py::test_has_names[fft-rfftn] -array_api_tests/test_has_names.py::test_has_names[fft-irfftn] -array_api_tests/test_has_names.py::test_has_names[fft-hfft] -array_api_tests/test_has_names.py::test_has_names[fft-ihfft] -array_api_tests/test_has_names.py::test_has_names[fft-fftfreq] -array_api_tests/test_has_names.py::test_has_names[fft-rfftfreq] -array_api_tests/test_has_names.py::test_has_names[fft-fftshift] -array_api_tests/test_has_names.py::test_has_names[fft-ifftshift] -array_api_tests/test_has_names.py::test_has_names[indexing-take] -array_api_tests/test_has_names.py::test_has_names[set-unique_all] -array_api_tests/test_has_names.py::test_has_names[set-unique_counts] -array_api_tests/test_has_names.py::test_has_names[manipulation-moveaxis] -array_api_tests/test_has_names.py::test_has_names[manipulation-repeat] -array_api_tests/test_has_names.py::test_has_names[manipulation-tile] -array_api_tests/test_has_names.py::test_has_names[manipulation-unstack] -array_api_tests/test_has_names.py::test_has_names[searching-searchsorted] -array_api_tests/test_has_names.py::test_has_names[elementwise-clip] -array_api_tests/test_has_names.py::test_has_names[elementwise-conj] -array_api_tests/test_has_names.py::test_has_names[elementwise-copysign] -array_api_tests/test_has_names.py::test_has_names[elementwise-hypot] -array_api_tests/test_has_names.py::test_has_names[elementwise-imag] -array_api_tests/test_has_names.py::test_has_names[elementwise-maximum] -array_api_tests/test_has_names.py::test_has_names[elementwise-minimum] -array_api_tests/test_has_names.py::test_has_names[elementwise-real] -array_api_tests/test_has_names.py::test_has_names[elementwise-signbit] -array_api_tests/test_has_names.py::test_has_names[statistical-cumulative_sum] -array_api_tests/test_has_names.py::test_has_names[sorting-argsort] -array_api_tests/test_has_names.py::test_has_names[data_type-isdtype] -array_api_tests/test_has_names.py::test_has_names[info-__array_namespace_info__] -array_api_tests/test_has_names.py::test_has_names[array_method-__complex__] -array_api_tests/test_indexing_functions.py::test_take -array_api_tests/test_inspection_functions.py::test_array_namespace_info -array_api_tests/test_inspection_functions.py::test_array_namespace_info_dtypes -array_api_tests/test_linalg.py::test_matrix_transpose -array_api_tests/test_linalg.py::test_tensordot -array_api_tests/test_linalg.py::test_vecdot -array_api_tests/test_manipulation_functions.py::test_moveaxis -array_api_tests/test_manipulation_functions.py::test_repeat -array_api_tests/test_manipulation_functions.py::test_stack -array_api_tests/test_manipulation_functions.py::test_tile -array_api_tests/test_manipulation_functions.py::test_unstack -array_api_tests/test_operators_and_elementwise_functions.py::test_abs[abs] -array_api_tests/test_operators_and_elementwise_functions.py::test_abs[__abs__] -array_api_tests/test_operators_and_elementwise_functions.py::test_acos -array_api_tests/test_operators_and_elementwise_functions.py::test_acosh -array_api_tests/test_operators_and_elementwise_functions.py::test_asin -array_api_tests/test_operators_and_elementwise_functions.py::test_asinh -array_api_tests/test_operators_and_elementwise_functions.py::test_atan -array_api_tests/test_operators_and_elementwise_functions.py::test_atanh -array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_left_shift[bitwise_left_shift(x1, x2)] -array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_left_shift[__lshift__(x1, x2)] -array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_left_shift[__ilshift__(x1, x2)] -array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_right_shift[bitwise_right_shift(x1, x2)] -array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_right_shift[__rshift__(x1, x2)] -array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_right_shift[__irshift__(x1, x2)] -array_api_tests/test_operators_and_elementwise_functions.py::test_clip -array_api_tests/test_operators_and_elementwise_functions.py::test_conj -array_api_tests/test_operators_and_elementwise_functions.py::test_copysign -array_api_tests/test_operators_and_elementwise_functions.py::test_cos -array_api_tests/test_operators_and_elementwise_functions.py::test_cosh -array_api_tests/test_operators_and_elementwise_functions.py::test_divide[divide(x1, x2)] -array_api_tests/test_operators_and_elementwise_functions.py::test_divide[__truediv__(x1, x2)] -array_api_tests/test_operators_and_elementwise_functions.py::test_divide[__truediv__(x, s)] -array_api_tests/test_operators_and_elementwise_functions.py::test_divide[__itruediv__(x1, x2)] -array_api_tests/test_operators_and_elementwise_functions.py::test_divide[__itruediv__(x, s)] -array_api_tests/test_operators_and_elementwise_functions.py::test_equal[__eq__(x1, x2)] -array_api_tests/test_operators_and_elementwise_functions.py::test_exp -array_api_tests/test_operators_and_elementwise_functions.py::test_expm1 -array_api_tests/test_operators_and_elementwise_functions.py::test_floor_divide[floor_divide(x1, x2)] -array_api_tests/test_operators_and_elementwise_functions.py::test_floor_divide[__floordiv__(x1, x2)] -array_api_tests/test_operators_and_elementwise_functions.py::test_floor_divide[__floordiv__(x, s)] -array_api_tests/test_operators_and_elementwise_functions.py::test_floor_divide[__ifloordiv__(x1, x2)] -array_api_tests/test_operators_and_elementwise_functions.py::test_floor_divide[__ifloordiv__(x, s)] -array_api_tests/test_operators_and_elementwise_functions.py::test_hypot -array_api_tests/test_operators_and_elementwise_functions.py::test_imag -array_api_tests/test_operators_and_elementwise_functions.py::test_isfinite -array_api_tests/test_operators_and_elementwise_functions.py::test_log -array_api_tests/test_operators_and_elementwise_functions.py::test_log1p -array_api_tests/test_operators_and_elementwise_functions.py::test_log10 -array_api_tests/test_operators_and_elementwise_functions.py::test_logaddexp -array_api_tests/test_operators_and_elementwise_functions.py::test_maximum -array_api_tests/test_operators_and_elementwise_functions.py::test_minimum -array_api_tests/test_operators_and_elementwise_functions.py::test_negative[negative] -array_api_tests/test_operators_and_elementwise_functions.py::test_negative[__neg__] -array_api_tests/test_operators_and_elementwise_functions.py::test_positive[positive] -array_api_tests/test_operators_and_elementwise_functions.py::test_positive[__pos__] -array_api_tests/test_operators_and_elementwise_functions.py::test_pow[pow(x1, x2)] -array_api_tests/test_operators_and_elementwise_functions.py::test_pow[__pow__(x1, x2)] -array_api_tests/test_operators_and_elementwise_functions.py::test_pow[__ipow__(x1, x2)] -array_api_tests/test_operators_and_elementwise_functions.py::test_real -array_api_tests/test_operators_and_elementwise_functions.py::test_round -array_api_tests/test_operators_and_elementwise_functions.py::test_signbit -array_api_tests/test_operators_and_elementwise_functions.py::test_sin -array_api_tests/test_operators_and_elementwise_functions.py::test_sinh -array_api_tests/test_operators_and_elementwise_functions.py::test_sqrt -array_api_tests/test_operators_and_elementwise_functions.py::test_tan -array_api_tests/test_operators_and_elementwise_functions.py::test_tanh -array_api_tests/test_searching_functions.py::test_argmax -array_api_tests/test_searching_functions.py::test_argmin -array_api_tests/test_searching_functions.py::test_nonzero_zerodim_error -array_api_tests/test_searching_functions.py::test_nonzero -array_api_tests/test_searching_functions.py::test_searchsorted -array_api_tests/test_set_functions.py::test_unique_all -array_api_tests/test_set_functions.py::test_unique_counts -array_api_tests/test_set_functions.py::test_unique_inverse -array_api_tests/test_signatures.py::test_func_signature[from_dlpack] -array_api_tests/test_signatures.py::test_func_signature[take] -array_api_tests/test_signatures.py::test_func_signature[unique_all] -array_api_tests/test_signatures.py::test_func_signature[unique_counts] -array_api_tests/test_signatures.py::test_func_signature[moveaxis] -array_api_tests/test_signatures.py::test_func_signature[repeat] -array_api_tests/test_signatures.py::test_func_signature[tile] -array_api_tests/test_signatures.py::test_func_signature[unstack] -array_api_tests/test_signatures.py::test_func_signature[searchsorted] -array_api_tests/test_signatures.py::test_func_signature[clip] -array_api_tests/test_signatures.py::test_func_signature[conj] -array_api_tests/test_signatures.py::test_func_signature[copysign] -array_api_tests/test_signatures.py::test_func_signature[hypot] -array_api_tests/test_signatures.py::test_func_signature[imag] -array_api_tests/test_signatures.py::test_func_signature[maximum] -array_api_tests/test_signatures.py::test_func_signature[minimum] -array_api_tests/test_signatures.py::test_func_signature[real] -array_api_tests/test_signatures.py::test_func_signature[signbit] -array_api_tests/test_signatures.py::test_func_signature[cumulative_sum] -array_api_tests/test_signatures.py::test_func_signature[argsort] -array_api_tests/test_signatures.py::test_func_signature[astype] -array_api_tests/test_signatures.py::test_func_signature[isdtype] -array_api_tests/test_signatures.py::test_func_signature[__array_namespace_info__] -array_api_tests/test_signatures.py::test_array_method_signature[__complex__] -array_api_tests/test_signatures.py::test_array_method_signature[__dlpack__] -array_api_tests/test_signatures.py::test_info_func_signature[capabilities] -array_api_tests/test_signatures.py::test_info_func_signature[default_device] -array_api_tests/test_signatures.py::test_info_func_signature[default_dtypes] -array_api_tests/test_signatures.py::test_info_func_signature[devices] -array_api_tests/test_signatures.py::test_info_func_signature[dtypes] -array_api_tests/test_sorting_functions.py::test_argsort -array_api_tests/test_sorting_functions.py::test_sort -array_api_tests/test_special_cases.py::test_unary[isfinite((x_i is +infinity or x_i == -infinity)) -> False] -array_api_tests/test_special_cases.py::test_unary[isfinite(x_i is NaN) -> False] -array_api_tests/test_special_cases.py::test_unary[isfinite(isfinite(x_i)) -> True] -array_api_tests/test_special_cases.py::test_unary[isinf((x_i is +infinity or x_i == -infinity)) -> True] -array_api_tests/test_special_cases.py::test_unary[isnan(x_i is NaN) -> True] -array_api_tests/test_special_cases.py::test_unary[sign(x_i is NaN) -> NaN] -array_api_tests/test_special_cases.py::test_unary[signbit(x_i is +0) -> False] -array_api_tests/test_special_cases.py::test_unary[signbit(x_i is -0) -> True] -array_api_tests/test_special_cases.py::test_unary[signbit(x_i is +infinity) -> False] -array_api_tests/test_special_cases.py::test_unary[signbit(x_i is -infinity) -> True] -array_api_tests/test_special_cases.py::test_unary[signbit(isfinite(x_i) and x_i > 0) -> False] -array_api_tests/test_special_cases.py::test_unary[signbit(isfinite(x_i) and x_i < 0) -> True] -array_api_tests/test_special_cases.py::test_unary[signbit(x_i is +NaN) -> False] -array_api_tests/test_special_cases.py::test_unary[signbit(x_i is -NaN) -> True] -array_api_tests/test_special_cases.py::test_binary[copysign(x1_i is NaN and x2_i < 0) -> NaN] -array_api_tests/test_special_cases.py::test_binary[copysign(x1_i is NaN and x2_i is -0) -> NaN] -array_api_tests/test_special_cases.py::test_binary[copysign(x1_i is NaN and x2_i is +0) -> NaN] -array_api_tests/test_special_cases.py::test_binary[copysign(x1_i is NaN and x2_i > 0) -> NaN] -array_api_tests/test_special_cases.py::test_binary[divide(x1_i is +0 and x2_i > 0) -> +0] -array_api_tests/test_special_cases.py::test_binary[divide(x1_i is -0 and x2_i > 0) -> -0] -array_api_tests/test_special_cases.py::test_binary[divide(x1_i is +0 and x2_i < 0) -> -0] -array_api_tests/test_special_cases.py::test_binary[divide(x1_i is -0 and x2_i < 0) -> +0] -array_api_tests/test_special_cases.py::test_binary[divide(x1_i > 0 and x2_i is +0) -> +infinity] -array_api_tests/test_special_cases.py::test_binary[divide(x1_i > 0 and x2_i is -0) -> -infinity] -array_api_tests/test_special_cases.py::test_binary[divide(x1_i < 0 and x2_i is +0) -> -infinity] -array_api_tests/test_special_cases.py::test_binary[divide(x1_i < 0 and x2_i is -0) -> +infinity] -array_api_tests/test_special_cases.py::test_binary[__truediv__(x1_i is +0 and x2_i > 0) -> +0] -array_api_tests/test_special_cases.py::test_binary[__truediv__(x1_i is -0 and x2_i > 0) -> -0] -array_api_tests/test_special_cases.py::test_binary[__truediv__(x1_i is +0 and x2_i < 0) -> -0] -array_api_tests/test_special_cases.py::test_binary[__truediv__(x1_i is -0 and x2_i < 0) -> +0] -array_api_tests/test_special_cases.py::test_binary[__truediv__(x1_i > 0 and x2_i is +0) -> +infinity] -array_api_tests/test_special_cases.py::test_binary[__truediv__(x1_i > 0 and x2_i is -0) -> -infinity] -array_api_tests/test_special_cases.py::test_binary[__truediv__(x1_i < 0 and x2_i is +0) -> -infinity] -array_api_tests/test_special_cases.py::test_binary[__truediv__(x1_i < 0 and x2_i is -0) -> +infinity] -array_api_tests/test_special_cases.py::test_binary[maximum(x1_i is NaN or x2_i is NaN) -> NaN] -array_api_tests/test_special_cases.py::test_binary[minimum(x1_i is NaN or x2_i is NaN) -> NaN] -array_api_tests/test_special_cases.py::test_binary[pow(abs(x1_i) > 1 and x2_i is +infinity) -> +infinity] -array_api_tests/test_special_cases.py::test_binary[pow(abs(x1_i) > 1 and x2_i is -infinity) -> +0] -array_api_tests/test_special_cases.py::test_binary[pow(x1_i is +infinity and x2_i > 0) -> +infinity] -array_api_tests/test_special_cases.py::test_binary[pow(x1_i is +infinity and x2_i < 0) -> +0] -array_api_tests/test_special_cases.py::test_binary[pow(x1_i is -infinity and x2_i > 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +infinity] -array_api_tests/test_special_cases.py::test_binary[pow(x1_i is -infinity and x2_i < 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +0] -array_api_tests/test_special_cases.py::test_binary[pow(x1_i is +0 and x2_i > 0) -> +0] -array_api_tests/test_special_cases.py::test_binary[pow(x1_i is +0 and x2_i < 0) -> +infinity] -array_api_tests/test_special_cases.py::test_binary[pow(x1_i is -0 and x2_i > 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +0] -array_api_tests/test_special_cases.py::test_binary[pow(x1_i is -0 and x2_i < 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +infinity] -array_api_tests/test_special_cases.py::test_binary[__pow__(abs(x1_i) > 1 and x2_i is +infinity) -> +infinity] -array_api_tests/test_special_cases.py::test_binary[__pow__(abs(x1_i) > 1 and x2_i is -infinity) -> +0] -array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is +infinity and x2_i > 0) -> +infinity] -array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is +infinity and x2_i < 0) -> +0] -array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is -infinity and x2_i > 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +infinity] -array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is -infinity and x2_i < 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +0] -array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is +0 and x2_i > 0) -> +0] -array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is +0 and x2_i < 0) -> +infinity] -array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is -0 and x2_i > 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +0] -array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is -0 and x2_i < 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +infinity] -array_api_tests/test_special_cases.py::test_iop[__itruediv__(x1_i is +0 and x2_i > 0) -> +0] -array_api_tests/test_special_cases.py::test_iop[__itruediv__(x1_i is -0 and x2_i > 0) -> -0] -array_api_tests/test_special_cases.py::test_iop[__itruediv__(x1_i is +0 and x2_i < 0) -> -0] -array_api_tests/test_special_cases.py::test_iop[__itruediv__(x1_i is -0 and x2_i < 0) -> +0] -array_api_tests/test_special_cases.py::test_iop[__itruediv__(x1_i > 0 and x2_i is +0) -> +infinity] -array_api_tests/test_special_cases.py::test_iop[__itruediv__(x1_i > 0 and x2_i is -0) -> -infinity] -array_api_tests/test_special_cases.py::test_iop[__itruediv__(x1_i < 0 and x2_i is +0) -> -infinity] -array_api_tests/test_special_cases.py::test_iop[__itruediv__(x1_i < 0 and x2_i is -0) -> +infinity] -array_api_tests/test_special_cases.py::test_iop[__ipow__(abs(x1_i) > 1 and x2_i is +infinity) -> +infinity] -array_api_tests/test_special_cases.py::test_iop[__ipow__(abs(x1_i) > 1 and x2_i is -infinity) -> +0] -array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i is +infinity and x2_i > 0) -> +infinity] -array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i is +infinity and x2_i < 0) -> +0] -array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i is -infinity and x2_i > 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +infinity] -array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i is -infinity and x2_i < 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +0] -array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i is +0 and x2_i > 0) -> +0] -array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i is +0 and x2_i < 0) -> +infinity] -array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i is -0 and x2_i > 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +0] -array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i is -0 and x2_i < 0 and not (x2_i.is_integer() and x2_i % 2 == 1)) -> +infinity] -array_api_tests/test_special_cases.py::test_empty_arrays[prod] -array_api_tests/test_special_cases.py::test_empty_arrays[std] -array_api_tests/test_special_cases.py::test_empty_arrays[sum] -array_api_tests/test_special_cases.py::test_nan_propagation[max] -array_api_tests/test_special_cases.py::test_nan_propagation[mean] -array_api_tests/test_special_cases.py::test_nan_propagation[min] -array_api_tests/test_special_cases.py::test_nan_propagation[prod] -array_api_tests/test_special_cases.py::test_nan_propagation[std] -array_api_tests/test_special_cases.py::test_nan_propagation[sum] -array_api_tests/test_special_cases.py::test_nan_propagation[var] -array_api_tests/test_statistical_functions.py::test_cumulative_sum -array_api_tests/test_statistical_functions.py::test_max -array_api_tests/test_statistical_functions.py::test_mean -array_api_tests/test_statistical_functions.py::test_min -array_api_tests/test_statistical_functions.py::test_prod -array_api_tests/test_statistical_functions.py::test_sum -array_api_tests/test_utility_functions.py::test_all -array_api_tests/test_utility_functions.py::test_any +# fails sometimes + +array_api_tests/test_creation_functions.py::test_asarray_scalars +array_api_tests/test_data_type_functions.py::test_can_cast +array_api_tests/test_linalg.py::test_matmul +array_api_tests/test_manipulation_functions.py::test_concat +array_api_tests/test_manipulation_functions.py::test_expand_dims +array_api_tests/test_manipulation_functions.py::test_squeeze +array_api_tests/test_manipulation_functions.py::test_flip +array_api_tests/test_manipulation_functions.py::test_permute_dims +array_api_tests/test_manipulation_functions.py::test_roll +array_api_tests/test_operators_and_elementwise_functions.py::test_add[add(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_add[__add__(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_add[__add__(x, s)] +array_api_tests/test_operators_and_elementwise_functions.py::test_add[__iadd__(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_add[__iadd__(x, s)] +array_api_tests/test_operators_and_elementwise_functions.py::test_atan2 +array_api_tests/test_operators_and_elementwise_functions.py::test_ceil +array_api_tests/test_operators_and_elementwise_functions.py::test_equal[equal(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_equal[__eq__(x, s)] +array_api_tests/test_operators_and_elementwise_functions.py::test_floor +array_api_tests/test_operators_and_elementwise_functions.py::test_greater[__gt__(x, s)] +array_api_tests/test_operators_and_elementwise_functions.py::test_greater_equal[greater_equal(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_greater_equal[__ge__(x, s)] +array_api_tests/test_operators_and_elementwise_functions.py::test_isinf +array_api_tests/test_operators_and_elementwise_functions.py::test_isnan +array_api_tests/test_operators_and_elementwise_functions.py::test_less[less(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_less[__lt__(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_less_equal[less_equal(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_less_equal[__le__(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_less_equal[__le__(x, s)] +array_api_tests/test_operators_and_elementwise_functions.py::test_log2 +array_api_tests/test_operators_and_elementwise_functions.py::test_multiply[multiply(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_multiply[__mul__(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_multiply[__mul__(x, s)] +array_api_tests/test_operators_and_elementwise_functions.py::test_multiply[__imul__(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_multiply[__imul__(x, s)] +array_api_tests/test_operators_and_elementwise_functions.py::test_not_equal[not_equal(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_not_equal[__ne__(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_not_equal[__ne__(x, s)] +array_api_tests/test_operators_and_elementwise_functions.py::test_pow[__pow__(x, s)] +array_api_tests/test_operators_and_elementwise_functions.py::test_pow[__ipow__(x, s)] +array_api_tests/test_operators_and_elementwise_functions.py::test_sign +array_api_tests/test_operators_and_elementwise_functions.py::test_square +array_api_tests/test_operators_and_elementwise_functions.py::test_subtract[subtract(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_subtract[__sub__(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_subtract[__sub__(x, s)] +array_api_tests/test_operators_and_elementwise_functions.py::test_subtract[__isub__(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_subtract[__isub__(x, s)] +array_api_tests/test_operators_and_elementwise_functions.py::test_trunc +array_api_tests/test_set_functions.py::test_unique_values +array_api_tests/test_special_cases.py::test_unary[acos(x_i > 1) -> NaN] +array_api_tests/test_special_cases.py::test_unary[asin(x_i < -1) -> NaN] +array_api_tests/test_special_cases.py::test_unary[ceil(x_i.is_integer()) -> x_i] +array_api_tests/test_special_cases.py::test_unary[floor(x_i.is_integer()) -> x_i] +array_api_tests/test_special_cases.py::test_unary[log(x_i < 0) -> NaN] +array_api_tests/test_special_cases.py::test_unary[log2(x_i < 0) -> NaN] +array_api_tests/test_special_cases.py::test_unary[round(x_i.is_integer()) -> x_i] +array_api_tests/test_special_cases.py::test_unary[round(modf(i)[0] == 0.5) -> Decimal(i).to_integral_exact(ROUND_HALF_EVEN)] +array_api_tests/test_special_cases.py::test_unary[sign(x_i > 0) -> +1] +array_api_tests/test_special_cases.py::test_unary[sqrt(x_i < 0) -> NaN] +array_api_tests/test_special_cases.py::test_binary[add((x1_i is +0 or x1_i == -0) and isfinite(x2_i) and x2_i != 0) -> x2_i] +array_api_tests/test_special_cases.py::test_binary[add(isfinite(x1_i) and x1_i != 0 and (x2_i is +0 or x2_i == -0)) -> x1_i] +array_api_tests/test_special_cases.py::test_binary[__add__((x1_i is +0 or x1_i == -0) and isfinite(x2_i) and x2_i != 0) -> x2_i] +array_api_tests/test_special_cases.py::test_binary[__add__(isfinite(x1_i) and x1_i != 0 and (x2_i is +0 or x2_i == -0)) -> x1_i] +array_api_tests/test_special_cases.py::test_binary[__add__(isfinite(x1_i) and x1_i != 0 and x2_i == -x1_i) -> +0] +array_api_tests/test_special_cases.py::test_binary[pow(x1_i < 0 and isfinite(x1_i) and isfinite(x2_i) and not x2_i.is_integer()) -> NaN] +array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i < 0 and isfinite(x1_i) and isfinite(x2_i) and not x2_i.is_integer()) -> NaN] +array_api_tests/test_special_cases.py::test_iop[__iadd__((x1_i is +0 or x1_i == -0) and isfinite(x2_i) and x2_i != 0) -> x2_i] +array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i < 0 and isfinite(x1_i) and isfinite(x2_i) and not x2_i.is_integer()) -> NaN] diff --git a/heat/array_api/test/xfails.txt b/heat/array_api/test/xfails.txt index 0004c7dda0..760f6f4fff 100644 --- a/heat/array_api/test/xfails.txt +++ b/heat/array_api/test/xfails.txt @@ -1,3 +1,4 @@ +# fails every time array_api_tests/test_array_object.py::test_getitem array_api_tests/test_array_object.py::test_setitem array_api_tests/test_array_object.py::test_getitem_masking From 36322fb7bd51d91a89cada951f8ba6fdad3a80d6 Mon Sep 17 00:00:00 2001 From: Michael Tarnawa Date: Fri, 12 Jul 2024 15:41:40 +0200 Subject: [PATCH 140/150] update skips --- heat/array_api/test/skips.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/heat/array_api/test/skips.txt b/heat/array_api/test/skips.txt index 8fc36d0c26..23cf863eb8 100644 --- a/heat/array_api/test/skips.txt +++ b/heat/array_api/test/skips.txt @@ -19,6 +19,7 @@ array_api_tests/test_operators_and_elementwise_functions.py::test_ceil array_api_tests/test_operators_and_elementwise_functions.py::test_equal[equal(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_equal[__eq__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_floor +array_api_tests/test_operators_and_elementwise_functions.py::test_greater[__gt__(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_greater[__gt__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_greater_equal[greater_equal(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_greater_equal[__ge__(x, s)] @@ -26,6 +27,7 @@ array_api_tests/test_operators_and_elementwise_functions.py::test_isinf array_api_tests/test_operators_and_elementwise_functions.py::test_isnan array_api_tests/test_operators_and_elementwise_functions.py::test_less[less(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_less[__lt__(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_less[__lt__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_less_equal[less_equal(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_less_equal[__le__(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_less_equal[__le__(x, s)] @@ -59,6 +61,7 @@ array_api_tests/test_special_cases.py::test_unary[round(x_i.is_integer()) -> x_i array_api_tests/test_special_cases.py::test_unary[round(modf(i)[0] == 0.5) -> Decimal(i).to_integral_exact(ROUND_HALF_EVEN)] array_api_tests/test_special_cases.py::test_unary[sign(x_i > 0) -> +1] array_api_tests/test_special_cases.py::test_unary[sqrt(x_i < 0) -> NaN] +array_api_tests/test_special_cases.py::test_unary[trunc(x_i.is_integer()) -> x_i] array_api_tests/test_special_cases.py::test_binary[add((x1_i is +0 or x1_i == -0) and isfinite(x2_i) and x2_i != 0) -> x2_i] array_api_tests/test_special_cases.py::test_binary[add(isfinite(x1_i) and x1_i != 0 and (x2_i is +0 or x2_i == -0)) -> x1_i] array_api_tests/test_special_cases.py::test_binary[__add__((x1_i is +0 or x1_i == -0) and isfinite(x2_i) and x2_i != 0) -> x2_i] @@ -67,4 +70,5 @@ array_api_tests/test_special_cases.py::test_binary[__add__(isfinite(x1_i) and x1 array_api_tests/test_special_cases.py::test_binary[pow(x1_i < 0 and isfinite(x1_i) and isfinite(x2_i) and not x2_i.is_integer()) -> NaN] array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i < 0 and isfinite(x1_i) and isfinite(x2_i) and not x2_i.is_integer()) -> NaN] array_api_tests/test_special_cases.py::test_iop[__iadd__((x1_i is +0 or x1_i == -0) and isfinite(x2_i) and x2_i != 0) -> x2_i] +array_api_tests/test_special_cases.py::test_iop[__iadd__(isfinite(x1_i) and x1_i != 0 and (x2_i is +0 or x2_i == -0)) -> x1_i] array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i < 0 and isfinite(x1_i) and isfinite(x2_i) and not x2_i.is_integer()) -> NaN] From 80fbe822f3cca3946e7dbed779c359078cb9b26b Mon Sep 17 00:00:00 2001 From: Michael Tarnawa Date: Mon, 15 Jul 2024 08:30:10 +0200 Subject: [PATCH 141/150] update files --- heat/array_api/test/skips.txt | 5 +++++ heat/array_api/test/xfails.txt | 3 --- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/heat/array_api/test/skips.txt b/heat/array_api/test/skips.txt index 23cf863eb8..36cd31b856 100644 --- a/heat/array_api/test/skips.txt +++ b/heat/array_api/test/skips.txt @@ -1,6 +1,7 @@ # fails sometimes array_api_tests/test_creation_functions.py::test_asarray_scalars +array_api_tests/test_data_type_functions.py::test_astype array_api_tests/test_data_type_functions.py::test_can_cast array_api_tests/test_linalg.py::test_matmul array_api_tests/test_manipulation_functions.py::test_concat @@ -9,6 +10,7 @@ array_api_tests/test_manipulation_functions.py::test_squeeze array_api_tests/test_manipulation_functions.py::test_flip array_api_tests/test_manipulation_functions.py::test_permute_dims array_api_tests/test_manipulation_functions.py::test_roll +array_api_tests/test_manipulation_functions.py::test_stack array_api_tests/test_operators_and_elementwise_functions.py::test_add[add(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_add[__add__(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_add[__add__(x, s)] @@ -17,8 +19,10 @@ array_api_tests/test_operators_and_elementwise_functions.py::test_add[__iadd__(x array_api_tests/test_operators_and_elementwise_functions.py::test_atan2 array_api_tests/test_operators_and_elementwise_functions.py::test_ceil array_api_tests/test_operators_and_elementwise_functions.py::test_equal[equal(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_equal[__eq__(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_equal[__eq__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_floor +array_api_tests/test_operators_and_elementwise_functions.py::test_greater[greater(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_greater[__gt__(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_greater[__gt__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_greater_equal[greater_equal(x1, x2)] @@ -50,6 +54,7 @@ array_api_tests/test_operators_and_elementwise_functions.py::test_subtract[__sub array_api_tests/test_operators_and_elementwise_functions.py::test_subtract[__isub__(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_subtract[__isub__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_trunc +array_api_tests/test_searching_functions.py::test_where array_api_tests/test_set_functions.py::test_unique_values array_api_tests/test_special_cases.py::test_unary[acos(x_i > 1) -> NaN] array_api_tests/test_special_cases.py::test_unary[asin(x_i < -1) -> NaN] diff --git a/heat/array_api/test/xfails.txt b/heat/array_api/test/xfails.txt index 760f6f4fff..d0cda4e8f2 100644 --- a/heat/array_api/test/xfails.txt +++ b/heat/array_api/test/xfails.txt @@ -16,7 +16,6 @@ array_api_tests/test_creation_functions.py::test_ones array_api_tests/test_creation_functions.py::test_ones_like array_api_tests/test_creation_functions.py::test_zeros array_api_tests/test_creation_functions.py::test_zeros_like -array_api_tests/test_data_type_functions.py::test_astype array_api_tests/test_data_type_functions.py::test_broadcast_arrays array_api_tests/test_data_type_functions.py::test_broadcast_to array_api_tests/test_data_type_functions.py::test_finfo[float32] @@ -89,7 +88,6 @@ array_api_tests/test_linalg.py::test_tensordot array_api_tests/test_linalg.py::test_vecdot array_api_tests/test_manipulation_functions.py::test_moveaxis array_api_tests/test_manipulation_functions.py::test_repeat -array_api_tests/test_manipulation_functions.py::test_stack array_api_tests/test_manipulation_functions.py::test_tile array_api_tests/test_manipulation_functions.py::test_unstack array_api_tests/test_operators_and_elementwise_functions.py::test_abs[abs] @@ -116,7 +114,6 @@ array_api_tests/test_operators_and_elementwise_functions.py::test_divide[__trued array_api_tests/test_operators_and_elementwise_functions.py::test_divide[__truediv__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_divide[__itruediv__(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_divide[__itruediv__(x, s)] -array_api_tests/test_operators_and_elementwise_functions.py::test_equal[__eq__(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_exp array_api_tests/test_operators_and_elementwise_functions.py::test_expm1 array_api_tests/test_operators_and_elementwise_functions.py::test_floor_divide[floor_divide(x1, x2)] From 6e0ef5110e153515c303113f1e96b1a8c9bd539f Mon Sep 17 00:00:00 2001 From: Michael Tarnawa Date: Mon, 15 Jul 2024 09:02:26 +0200 Subject: [PATCH 142/150] add more skips --- heat/array_api/test/skips.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/heat/array_api/test/skips.txt b/heat/array_api/test/skips.txt index 36cd31b856..cdf91efa3d 100644 --- a/heat/array_api/test/skips.txt +++ b/heat/array_api/test/skips.txt @@ -1,5 +1,4 @@ # fails sometimes - array_api_tests/test_creation_functions.py::test_asarray_scalars array_api_tests/test_data_type_functions.py::test_astype array_api_tests/test_data_type_functions.py::test_can_cast @@ -56,12 +55,14 @@ array_api_tests/test_operators_and_elementwise_functions.py::test_subtract[__isu array_api_tests/test_operators_and_elementwise_functions.py::test_trunc array_api_tests/test_searching_functions.py::test_where array_api_tests/test_set_functions.py::test_unique_values +array_api_tests/test_special_cases.py::test_unary[acos(x_i < -1) -> NaN] array_api_tests/test_special_cases.py::test_unary[acos(x_i > 1) -> NaN] array_api_tests/test_special_cases.py::test_unary[asin(x_i < -1) -> NaN] array_api_tests/test_special_cases.py::test_unary[ceil(x_i.is_integer()) -> x_i] array_api_tests/test_special_cases.py::test_unary[floor(x_i.is_integer()) -> x_i] array_api_tests/test_special_cases.py::test_unary[log(x_i < 0) -> NaN] array_api_tests/test_special_cases.py::test_unary[log2(x_i < 0) -> NaN] +array_api_tests/test_special_cases.py::test_unary[log10(x_i < 0) -> NaN] array_api_tests/test_special_cases.py::test_unary[round(x_i.is_integer()) -> x_i] array_api_tests/test_special_cases.py::test_unary[round(modf(i)[0] == 0.5) -> Decimal(i).to_integral_exact(ROUND_HALF_EVEN)] array_api_tests/test_special_cases.py::test_unary[sign(x_i > 0) -> +1] @@ -69,10 +70,12 @@ array_api_tests/test_special_cases.py::test_unary[sqrt(x_i < 0) -> NaN] array_api_tests/test_special_cases.py::test_unary[trunc(x_i.is_integer()) -> x_i] array_api_tests/test_special_cases.py::test_binary[add((x1_i is +0 or x1_i == -0) and isfinite(x2_i) and x2_i != 0) -> x2_i] array_api_tests/test_special_cases.py::test_binary[add(isfinite(x1_i) and x1_i != 0 and (x2_i is +0 or x2_i == -0)) -> x1_i] +array_api_tests/test_special_cases.py::test_binary[add(isfinite(x1_i) and x1_i != 0 and x2_i == -x1_i) -> +0] array_api_tests/test_special_cases.py::test_binary[__add__((x1_i is +0 or x1_i == -0) and isfinite(x2_i) and x2_i != 0) -> x2_i] array_api_tests/test_special_cases.py::test_binary[__add__(isfinite(x1_i) and x1_i != 0 and (x2_i is +0 or x2_i == -0)) -> x1_i] array_api_tests/test_special_cases.py::test_binary[__add__(isfinite(x1_i) and x1_i != 0 and x2_i == -x1_i) -> +0] array_api_tests/test_special_cases.py::test_binary[pow(x1_i < 0 and isfinite(x1_i) and isfinite(x2_i) and not x2_i.is_integer()) -> NaN] +array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is NaN and not x2_i == 0) -> NaN] array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i < 0 and isfinite(x1_i) and isfinite(x2_i) and not x2_i.is_integer()) -> NaN] array_api_tests/test_special_cases.py::test_iop[__iadd__((x1_i is +0 or x1_i == -0) and isfinite(x2_i) and x2_i != 0) -> x2_i] array_api_tests/test_special_cases.py::test_iop[__iadd__(isfinite(x1_i) and x1_i != 0 and (x2_i is +0 or x2_i == -0)) -> x1_i] From 56655af13b9330f15753e2e07ef0ee7d99bc3a39 Mon Sep 17 00:00:00 2001 From: Michael Tarnawa Date: Mon, 15 Jul 2024 11:01:22 +0200 Subject: [PATCH 143/150] add more skips --- heat/array_api/test/skips.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/heat/array_api/test/skips.txt b/heat/array_api/test/skips.txt index cdf91efa3d..8f9877b90d 100644 --- a/heat/array_api/test/skips.txt +++ b/heat/array_api/test/skips.txt @@ -25,6 +25,7 @@ array_api_tests/test_operators_and_elementwise_functions.py::test_greater[greate array_api_tests/test_operators_and_elementwise_functions.py::test_greater[__gt__(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_greater[__gt__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_greater_equal[greater_equal(x1, x2)] +array_api_tests/test_operators_and_elementwise_functions.py::test_greater_equal[__ge__(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_greater_equal[__ge__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_isinf array_api_tests/test_operators_and_elementwise_functions.py::test_isnan @@ -57,6 +58,7 @@ array_api_tests/test_searching_functions.py::test_where array_api_tests/test_set_functions.py::test_unique_values array_api_tests/test_special_cases.py::test_unary[acos(x_i < -1) -> NaN] array_api_tests/test_special_cases.py::test_unary[acos(x_i > 1) -> NaN] +array_api_tests/test_special_cases.py::test_unary[asin(x_i > 1) -> NaN] array_api_tests/test_special_cases.py::test_unary[asin(x_i < -1) -> NaN] array_api_tests/test_special_cases.py::test_unary[ceil(x_i.is_integer()) -> x_i] array_api_tests/test_special_cases.py::test_unary[floor(x_i.is_integer()) -> x_i] From 75bd67088e5e6a1190f1af59fa4794b9fcc1136f Mon Sep 17 00:00:00 2001 From: Michael Tarnawa Date: Mon, 15 Jul 2024 13:14:05 +0200 Subject: [PATCH 144/150] even more skips --- heat/array_api/test/skips.txt | 2 ++ heat/array_api/test/xfails.txt | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/heat/array_api/test/skips.txt b/heat/array_api/test/skips.txt index 8f9877b90d..1d287e2a57 100644 --- a/heat/array_api/test/skips.txt +++ b/heat/array_api/test/skips.txt @@ -27,6 +27,7 @@ array_api_tests/test_operators_and_elementwise_functions.py::test_greater[__gt__ array_api_tests/test_operators_and_elementwise_functions.py::test_greater_equal[greater_equal(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_greater_equal[__ge__(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_greater_equal[__ge__(x, s)] +array_api_tests/test_operators_and_elementwise_functions.py::test_isfinite array_api_tests/test_operators_and_elementwise_functions.py::test_isinf array_api_tests/test_operators_and_elementwise_functions.py::test_isnan array_api_tests/test_operators_and_elementwise_functions.py::test_less[less(x1, x2)] @@ -67,6 +68,7 @@ array_api_tests/test_special_cases.py::test_unary[log2(x_i < 0) -> NaN] array_api_tests/test_special_cases.py::test_unary[log10(x_i < 0) -> NaN] array_api_tests/test_special_cases.py::test_unary[round(x_i.is_integer()) -> x_i] array_api_tests/test_special_cases.py::test_unary[round(modf(i)[0] == 0.5) -> Decimal(i).to_integral_exact(ROUND_HALF_EVEN)] +array_api_tests/test_special_cases.py::test_unary[sign(x_i < 0) -> -1] array_api_tests/test_special_cases.py::test_unary[sign(x_i > 0) -> +1] array_api_tests/test_special_cases.py::test_unary[sqrt(x_i < 0) -> NaN] array_api_tests/test_special_cases.py::test_unary[trunc(x_i.is_integer()) -> x_i] diff --git a/heat/array_api/test/xfails.txt b/heat/array_api/test/xfails.txt index d0cda4e8f2..8d8958df66 100644 --- a/heat/array_api/test/xfails.txt +++ b/heat/array_api/test/xfails.txt @@ -123,7 +123,6 @@ array_api_tests/test_operators_and_elementwise_functions.py::test_floor_divide[_ array_api_tests/test_operators_and_elementwise_functions.py::test_floor_divide[__ifloordiv__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_hypot array_api_tests/test_operators_and_elementwise_functions.py::test_imag -array_api_tests/test_operators_and_elementwise_functions.py::test_isfinite array_api_tests/test_operators_and_elementwise_functions.py::test_log array_api_tests/test_operators_and_elementwise_functions.py::test_log1p array_api_tests/test_operators_and_elementwise_functions.py::test_log10 From 64a9cc201df6adce00127de42253b105f2f6b0b7 Mon Sep 17 00:00:00 2001 From: Michael Tarnawa Date: Mon, 15 Jul 2024 13:50:58 +0200 Subject: [PATCH 145/150] much more skips --- heat/array_api/test/skips.txt | 3 +++ heat/array_api/test/xfails.txt | 2 -- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/heat/array_api/test/skips.txt b/heat/array_api/test/skips.txt index 1d287e2a57..bf28b63346 100644 --- a/heat/array_api/test/skips.txt +++ b/heat/array_api/test/skips.txt @@ -37,6 +37,7 @@ array_api_tests/test_operators_and_elementwise_functions.py::test_less_equal[les array_api_tests/test_operators_and_elementwise_functions.py::test_less_equal[__le__(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_less_equal[__le__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_log2 +array_api_tests/test_operators_and_elementwise_functions.py::test_logaddexp array_api_tests/test_operators_and_elementwise_functions.py::test_multiply[multiply(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_multiply[__mul__(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_multiply[__mul__(x, s)] @@ -56,11 +57,13 @@ array_api_tests/test_operators_and_elementwise_functions.py::test_subtract[__isu array_api_tests/test_operators_and_elementwise_functions.py::test_subtract[__isub__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_trunc array_api_tests/test_searching_functions.py::test_where +array_api_tests/test_set_functions.py::test_unique_inverse array_api_tests/test_set_functions.py::test_unique_values array_api_tests/test_special_cases.py::test_unary[acos(x_i < -1) -> NaN] array_api_tests/test_special_cases.py::test_unary[acos(x_i > 1) -> NaN] array_api_tests/test_special_cases.py::test_unary[asin(x_i > 1) -> NaN] array_api_tests/test_special_cases.py::test_unary[asin(x_i < -1) -> NaN] +array_api_tests/test_special_cases.py::test_unary[atanh(x_i < -1) -> NaN] array_api_tests/test_special_cases.py::test_unary[ceil(x_i.is_integer()) -> x_i] array_api_tests/test_special_cases.py::test_unary[floor(x_i.is_integer()) -> x_i] array_api_tests/test_special_cases.py::test_unary[log(x_i < 0) -> NaN] diff --git a/heat/array_api/test/xfails.txt b/heat/array_api/test/xfails.txt index 8d8958df66..6501281c18 100644 --- a/heat/array_api/test/xfails.txt +++ b/heat/array_api/test/xfails.txt @@ -126,7 +126,6 @@ array_api_tests/test_operators_and_elementwise_functions.py::test_imag array_api_tests/test_operators_and_elementwise_functions.py::test_log array_api_tests/test_operators_and_elementwise_functions.py::test_log1p array_api_tests/test_operators_and_elementwise_functions.py::test_log10 -array_api_tests/test_operators_and_elementwise_functions.py::test_logaddexp array_api_tests/test_operators_and_elementwise_functions.py::test_maximum array_api_tests/test_operators_and_elementwise_functions.py::test_minimum array_api_tests/test_operators_and_elementwise_functions.py::test_negative[negative] @@ -151,7 +150,6 @@ array_api_tests/test_searching_functions.py::test_nonzero array_api_tests/test_searching_functions.py::test_searchsorted array_api_tests/test_set_functions.py::test_unique_all array_api_tests/test_set_functions.py::test_unique_counts -array_api_tests/test_set_functions.py::test_unique_inverse array_api_tests/test_signatures.py::test_func_signature[from_dlpack] array_api_tests/test_signatures.py::test_func_signature[take] array_api_tests/test_signatures.py::test_func_signature[unique_all] From a20c37601c581f593f836675f0705b00a5943dd3 Mon Sep 17 00:00:00 2001 From: Michael Tarnawa Date: Mon, 15 Jul 2024 14:35:50 +0200 Subject: [PATCH 146/150] and more --- heat/array_api/test/skips.txt | 2 ++ heat/array_api/test/xfails.txt | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/heat/array_api/test/skips.txt b/heat/array_api/test/skips.txt index bf28b63346..0d952d4fcc 100644 --- a/heat/array_api/test/skips.txt +++ b/heat/array_api/test/skips.txt @@ -48,6 +48,7 @@ array_api_tests/test_operators_and_elementwise_functions.py::test_not_equal[__ne array_api_tests/test_operators_and_elementwise_functions.py::test_not_equal[__ne__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_pow[__pow__(x, s)] array_api_tests/test_operators_and_elementwise_functions.py::test_pow[__ipow__(x, s)] +array_api_tests/test_operators_and_elementwise_functions.py::test_round array_api_tests/test_operators_and_elementwise_functions.py::test_sign array_api_tests/test_operators_and_elementwise_functions.py::test_square array_api_tests/test_operators_and_elementwise_functions.py::test_subtract[subtract(x1, x2)] @@ -86,4 +87,5 @@ array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i is NaN and not x array_api_tests/test_special_cases.py::test_binary[__pow__(x1_i < 0 and isfinite(x1_i) and isfinite(x2_i) and not x2_i.is_integer()) -> NaN] array_api_tests/test_special_cases.py::test_iop[__iadd__((x1_i is +0 or x1_i == -0) and isfinite(x2_i) and x2_i != 0) -> x2_i] array_api_tests/test_special_cases.py::test_iop[__iadd__(isfinite(x1_i) and x1_i != 0 and (x2_i is +0 or x2_i == -0)) -> x1_i] +array_api_tests/test_special_cases.py::test_iop[__iadd__(isfinite(x1_i) and x1_i != 0 and x2_i == -x1_i) -> +0] array_api_tests/test_special_cases.py::test_iop[__ipow__(x1_i < 0 and isfinite(x1_i) and isfinite(x2_i) and not x2_i.is_integer()) -> NaN] diff --git a/heat/array_api/test/xfails.txt b/heat/array_api/test/xfails.txt index 6501281c18..e773a3978f 100644 --- a/heat/array_api/test/xfails.txt +++ b/heat/array_api/test/xfails.txt @@ -136,7 +136,6 @@ array_api_tests/test_operators_and_elementwise_functions.py::test_pow[pow(x1, x2 array_api_tests/test_operators_and_elementwise_functions.py::test_pow[__pow__(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_pow[__ipow__(x1, x2)] array_api_tests/test_operators_and_elementwise_functions.py::test_real -array_api_tests/test_operators_and_elementwise_functions.py::test_round array_api_tests/test_operators_and_elementwise_functions.py::test_signbit array_api_tests/test_operators_and_elementwise_functions.py::test_sin array_api_tests/test_operators_and_elementwise_functions.py::test_sinh From e059414706d83015607950ba8d0c68d7e2007c16 Mon Sep 17 00:00:00 2001 From: Michael Tarnawa Date: Tue, 16 Jul 2024 11:53:38 +0200 Subject: [PATCH 147/150] change to manual trigger --- .github/workflows/array-api.yml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/.github/workflows/array-api.yml b/.github/workflows/array-api.yml index 883c013074..e58dcca242 100644 --- a/.github/workflows/array-api.yml +++ b/.github/workflows/array-api.yml @@ -1,15 +1,10 @@ name: Test Array API on: - push - # pull_request: - # types: [opened, synchronize, reopened, labeled] - #pull_request_review: - # types: [submitted] + workflow_dispatch: jobs: build: -# if: contains(github.event.pull_request.labels.*.name, 'test array API') runs-on: ubuntu-latest strategy: matrix: From f4e494fd63eddf237c933433645f36d5cb7cc02b Mon Sep 17 00:00:00 2001 From: Claudia Comito <39374113+ClaudiaComito@users.noreply.github.com> Date: Mon, 26 Aug 2024 10:58:54 +0200 Subject: [PATCH 148/150] add contributor --- CITATION.cff | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CITATION.cff b/CITATION.cff index ac0501e0b6..482b41d578 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -30,6 +30,8 @@ authors: - family-names: Tarnawa given-names: Michael # release contributors - add as needed + - family-names: Neo + given-names: Sun Han repository-code: 'https://github.com/helmholtz-analytics/heat' url: 'https://helmholtz-analytics.github.io/heat/' repository: 'https://heat.readthedocs.io/en/stable/' From 0ec11dd4ccab29627da1333d21460c521f9c5220 Mon Sep 17 00:00:00 2001 From: Michael Tarnawa <18899420+mtar@users.noreply.github.com> Date: Thu, 28 Nov 2024 16:31:00 +0100 Subject: [PATCH 149/150] Update codecov.yml ignore coverage array_api --- codecov.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/codecov.yml b/codecov.yml index 4895fc4be0..f09227b60f 100644 --- a/codecov.yml +++ b/codecov.yml @@ -5,6 +5,7 @@ ignore: - "heat/utils/data/mnist.py" - "heat/utils/data/_utils.py" - "heat/**/test_*.py" + - "heat/array_api/**" coverage: status: From bf0437b866907c29354d4e95f5147d1f10d479c1 Mon Sep 17 00:00:00 2001 From: Michael Tarnawa <18899420+mtar@users.noreply.github.com> Date: Mon, 9 Dec 2024 15:48:28 +0100 Subject: [PATCH 150/150] Update array-api.yml --- .github/workflows/array-api.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/array-api.yml b/.github/workflows/array-api.yml index e58dcca242..dc4907bbb9 100644 --- a/.github/workflows/array-api.yml +++ b/.github/workflows/array-api.yml @@ -8,7 +8,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ['3.9', '3.10', '3.11'] + python-version: ['3.9', '3.10', '3.11', '3.12', '3.13'] mpi: [ 'openmpi' ] steps: