From e90168712db7c35d268618c4eb87ef8744c74463 Mon Sep 17 00:00:00 2001 From: Matthew Barber Date: Fri, 1 Dec 2023 12:39:44 +0000 Subject: [PATCH 1/3] Remove all references to `FILTER_UNDEFINED_DTYPES` Never used and inconsistent checking across the test suite --- array_api_tests/hypothesis_helpers.py | 28 ++++++------------- ...est_operators_and_elementwise_functions.py | 8 +++--- array_api_tests/test_statistical_functions.py | 4 +-- 3 files changed, 14 insertions(+), 26 deletions(-) diff --git a/array_api_tests/hypothesis_helpers.py b/array_api_tests/hypothesis_helpers.py index 538d73ab..8ca4034e 100644 --- a/array_api_tests/hypothesis_helpers.py +++ b/array_api_tests/hypothesis_helpers.py @@ -22,15 +22,6 @@ from .pytest_helpers import nargs from .typing import Array, DataType, Shape -# Set this to True to not fail tests just because a dtype isn't implemented. -# If no compatible dtype is implemented for a given test, the test will fail -# with a hypothesis health check error. Note that this functionality will not -# work for floating point dtypes as those are assumed to be defined in other -# places in the tests. -FILTER_UNDEFINED_DTYPES = True -# TODO: currently we assume this to be true - we probably can remove this completely -assert FILTER_UNDEFINED_DTYPES - integer_dtypes = xps.integer_dtypes() | xps.unsigned_integer_dtypes() floating_dtypes = xps.floating_dtypes() numeric_dtypes = xps.numeric_dtypes() @@ -62,11 +53,10 @@ def _dtypes_sorter(dtype_pair: Tuple[DataType, DataType]): return key _promotable_dtypes = list(dh.promotion_table.keys()) -if FILTER_UNDEFINED_DTYPES: - _promotable_dtypes = [ - (d1, d2) for d1, d2 in _promotable_dtypes - if not isinstance(d1, _UndefinedStub) or not isinstance(d2, _UndefinedStub) - ] +_promotable_dtypes = [ + (d1, d2) for d1, d2 in _promotable_dtypes + if not isinstance(d1, _UndefinedStub) or not isinstance(d2, _UndefinedStub) +] promotable_dtypes: List[Tuple[DataType, DataType]] = sorted(_promotable_dtypes, key=_dtypes_sorter) def mutually_promotable_dtypes( @@ -74,9 +64,8 @@ def mutually_promotable_dtypes( *, dtypes: Sequence[DataType] = dh.all_dtypes, ) -> SearchStrategy[Tuple[DataType, ...]]: - if FILTER_UNDEFINED_DTYPES: - dtypes = [d for d in dtypes if not isinstance(d, _UndefinedStub)] - assert len(dtypes) > 0, "all dtypes undefined" # sanity check + dtypes = [d for d in dtypes if not isinstance(d, _UndefinedStub)] + assert len(dtypes) > 0, "all dtypes undefined" # sanity check if max_size == 2: return sampled_from( [(i, j) for i, j in promotable_dtypes if i in dtypes and j in dtypes] @@ -424,9 +413,8 @@ def two_mutual_arrays( ) -> Tuple[SearchStrategy[Array], SearchStrategy[Array]]: if not isinstance(dtypes, Sequence): raise TypeError(f"{dtypes=} not a sequence") - if FILTER_UNDEFINED_DTYPES: - dtypes = [d for d in dtypes if not isinstance(d, _UndefinedStub)] - assert len(dtypes) > 0 # sanity check + dtypes = [d for d in dtypes if not isinstance(d, _UndefinedStub)] + assert len(dtypes) > 0 # sanity check mutual_dtypes = shared(mutually_promotable_dtypes(dtypes=dtypes)) mutual_shapes = shared(two_shapes) arrays1 = xps.arrays( diff --git a/array_api_tests/test_operators_and_elementwise_functions.py b/array_api_tests/test_operators_and_elementwise_functions.py index d82edc62..d19cb5c4 100644 --- a/array_api_tests/test_operators_and_elementwise_functions.py +++ b/array_api_tests/test_operators_and_elementwise_functions.py @@ -468,8 +468,8 @@ def make_unary_params( *, min_version: str = "2021.12", ) -> List[Param[UnaryParamContext]]: - if hh.FILTER_UNDEFINED_DTYPES: - dtypes = [d for d in dtypes if not isinstance(d, xp._UndefinedStub)] + dtypes = [d for d in dtypes if not isinstance(d, xp._UndefinedStub)] + assert len(dtypes) > 0 # sanity check if api_version < "2022.12": dtypes = [d for d in dtypes if d not in dh.complex_dtypes] dtypes_strat = st.sampled_from(dtypes) @@ -523,8 +523,8 @@ def __repr__(self): def make_binary_params( elwise_func_name: str, dtypes: Sequence[DataType] ) -> List[Param[BinaryParamContext]]: - if hh.FILTER_UNDEFINED_DTYPES: - dtypes = [d for d in dtypes if not isinstance(d, xp._UndefinedStub)] + dtypes = [d for d in dtypes if not isinstance(d, xp._UndefinedStub)] + assert len(dtypes) > 0 # sanity check shared_oneway_dtypes = st.shared(hh.oneway_promotable_dtypes(dtypes)) left_dtypes = shared_oneway_dtypes.map(lambda D: D.result_dtype) right_dtypes = shared_oneway_dtypes.map(lambda D: D.input_dtype) diff --git a/array_api_tests/test_statistical_functions.py b/array_api_tests/test_statistical_functions.py index b00284c9..9969fa52 100644 --- a/array_api_tests/test_statistical_functions.py +++ b/array_api_tests/test_statistical_functions.py @@ -20,8 +20,8 @@ def kwarg_dtypes(dtype: DataType) -> st.SearchStrategy[Optional[DataType]]: dtypes = [d2 for d1, d2 in dh.promotion_table if d1 == dtype] - if hh.FILTER_UNDEFINED_DTYPES: - dtypes = [d for d in dtypes if not isinstance(d, _UndefinedStub)] + dtypes = [d for d in dtypes if not isinstance(d, _UndefinedStub)] + assert len(dtypes) > 0 # sanity check return st.none() | st.sampled_from(dtypes) From 73c47d8e98c79457448252f285969ddabfb41a4a Mon Sep 17 00:00:00 2001 From: Matthew Barber Date: Fri, 1 Dec 2023 14:10:35 +0000 Subject: [PATCH 2/3] Remove redundant dtype strategies in `hypothesis_helpers.py` --- array_api_tests/hypothesis_helpers.py | 12 +--------- .../meta/test_hypothesis_helpers.py | 10 ++++---- array_api_tests/test_creation_functions.py | 24 ++++++------------- 3 files changed, 13 insertions(+), 33 deletions(-) diff --git a/array_api_tests/hypothesis_helpers.py b/array_api_tests/hypothesis_helpers.py index 8ca4034e..80d14b4f 100644 --- a/array_api_tests/hypothesis_helpers.py +++ b/array_api_tests/hypothesis_helpers.py @@ -22,16 +22,6 @@ from .pytest_helpers import nargs from .typing import Array, DataType, Shape -integer_dtypes = xps.integer_dtypes() | xps.unsigned_integer_dtypes() -floating_dtypes = xps.floating_dtypes() -numeric_dtypes = xps.numeric_dtypes() -integer_or_boolean_dtypes = xps.boolean_dtypes() | integer_dtypes -boolean_dtypes = xps.boolean_dtypes() -dtypes = xps.scalar_dtypes() - -shared_dtypes = shared(dtypes, key="dtype") -shared_floating_dtypes = shared(floating_dtypes, key="dtype") - _dtype_categories = [(xp.bool,), dh.uint_dtypes, dh.int_dtypes, dh.real_float_dtypes, dh.complex_dtypes] _sorted_dtypes = [d for category in _dtype_categories for d in category] @@ -337,7 +327,7 @@ def python_integer_indices(draw, sizes): def integer_indices(draw, sizes): # Return either a Python integer or a 0-D array with some integer dtype idx = draw(python_integer_indices(sizes)) - dtype = draw(integer_dtypes) + dtype = draw(xps.integer_dtypes() | xps.unsigned_integer_dtypes()) m, M = dh.dtype_ranges[dtype] if m <= idx <= M: return draw(one_of(just(idx), diff --git a/array_api_tests/meta/test_hypothesis_helpers.py b/array_api_tests/meta/test_hypothesis_helpers.py index 6cce7d2a..f63c009f 100644 --- a/array_api_tests/meta/test_hypothesis_helpers.py +++ b/array_api_tests/meta/test_hypothesis_helpers.py @@ -128,10 +128,9 @@ def run(n, d, data): assert any("d" in kw.keys() and kw["d"] is xp.float64 for kw in results) - @given(finite=st.booleans(), dtype=xps.floating_dtypes(), data=st.data()) def test_symmetric_matrices(finite, dtype, data): - m = data.draw(hh.symmetric_matrices(st.just(dtype), finite=finite)) + m = data.draw(hh.symmetric_matrices(st.just(dtype), finite=finite), label="m") assert m.dtype == dtype # TODO: This part of this test should be part of the .mT test ah.assert_exactly_equal(m, m.mT) @@ -139,9 +138,10 @@ def test_symmetric_matrices(finite, dtype, data): if finite: ah.assert_finite(m) -@given(m=hh.positive_definite_matrices(hh.shared_floating_dtypes), - dtype=hh.shared_floating_dtypes) -def test_positive_definite_matrices(m, dtype): + +@given(dtype=xps.floating_dtypes(), data=st.data()) +def test_positive_definite_matrices(dtype, data): + m = data.draw(hh.positive_definite_matrices(st.just(dtype)), label="m") assert m.dtype == dtype # TODO: Test that it actually is positive definite diff --git a/array_api_tests/test_creation_functions.py b/array_api_tests/test_creation_functions.py index 94b6b0ec..c631bab0 100644 --- a/array_api_tests/test_creation_functions.py +++ b/array_api_tests/test_creation_functions.py @@ -427,21 +427,11 @@ def test_full(shape, fill_value, kw): ph.assert_fill("full", fill_value=fill_value, dtype=dtype, out=out, kw=dict(fill_value=fill_value)) -@st.composite -def full_like_fill_values(draw): - kw = draw( - st.shared(hh.kwargs(dtype=st.none() | xps.scalar_dtypes()), key="full_like_kw") - ) - dtype = kw.get("dtype", None) or draw(hh.shared_dtypes) - return draw(xps.from_dtype(dtype)) - - -@given( - x=xps.arrays(dtype=hh.shared_dtypes, shape=hh.shapes()), - fill_value=full_like_fill_values(), - kw=st.shared(hh.kwargs(dtype=st.none() | xps.scalar_dtypes()), key="full_like_kw"), -) -def test_full_like(x, fill_value, kw): +@given(kw=hh.kwargs(dtype=st.none() | xps.scalar_dtypes()), data=st.data()) +def test_full_like(kw, data): + dtype = kw.get("dtype", None) or data.draw(xps.scalar_dtypes(), label="dtype") + x = data.draw(xps.arrays(dtype=dtype, shape=hh.shapes()), label="x") + fill_value = data.draw(xps.from_dtype(dtype), label="fill_value") out = xp.full_like(x, fill_value, **kw) dtype = kw.get("dtype", None) or x.dtype if kw.get("dtype", None) is None: @@ -551,7 +541,7 @@ def test_ones(shape, kw): @given( - x=xps.arrays(dtype=hh.dtypes, shape=hh.shapes()), + x=xps.arrays(dtype=xps.scalar_dtypes(), shape=hh.shapes()), kw=hh.kwargs(dtype=st.none() | xps.scalar_dtypes()), ) def test_ones_like(x, kw): @@ -589,7 +579,7 @@ def test_zeros(shape, kw): @given( - x=xps.arrays(dtype=hh.dtypes, shape=hh.shapes()), + x=xps.arrays(dtype=xps.scalar_dtypes(), shape=hh.shapes()), kw=hh.kwargs(dtype=st.none() | xps.scalar_dtypes()), ) def test_zeros_like(x, kw): From 4d223008c5d7b7b7a55ac102b4792dc127a0df70 Mon Sep 17 00:00:00 2001 From: Matthew Barber Date: Thu, 14 Dec 2023 19:50:24 +0000 Subject: [PATCH 3/3] Prevent hypothesis testing boundary numbers --- array_api_tests/hypothesis_helpers.py | 80 ++++++++++++++++--- array_api_tests/test_array_object.py | 18 ++--- array_api_tests/test_creation_functions.py | 36 ++++----- array_api_tests/test_data_type_functions.py | 12 +-- array_api_tests/test_fft.py | 20 ++--- array_api_tests/test_indexing_functions.py | 2 +- array_api_tests/test_linalg.py | 32 ++++---- .../test_manipulation_functions.py | 16 ++-- ...est_operators_and_elementwise_functions.py | 78 +++++++++--------- array_api_tests/test_searching_functions.py | 14 ++-- array_api_tests/test_set_functions.py | 8 +- array_api_tests/test_sorting_functions.py | 4 +- array_api_tests/test_special_cases.py | 14 ++-- array_api_tests/test_statistical_functions.py | 14 ++-- array_api_tests/test_utility_functions.py | 4 +- 15 files changed, 203 insertions(+), 149 deletions(-) diff --git a/array_api_tests/hypothesis_helpers.py b/array_api_tests/hypothesis_helpers.py index 80d14b4f..131726b7 100644 --- a/array_api_tests/hypothesis_helpers.py +++ b/array_api_tests/hypothesis_helpers.py @@ -1,15 +1,16 @@ import re import itertools from contextlib import contextmanager -from functools import reduce -from math import sqrt +from functools import reduce, wraps +import math from operator import mul -from typing import Any, List, NamedTuple, Optional, Sequence, Tuple, Union +import struct +from typing import Any, List, Mapping, NamedTuple, Optional, Sequence, Tuple, Union from hypothesis import assume, reject from hypothesis.strategies import (SearchStrategy, booleans, composite, floats, integers, just, lists, none, one_of, - sampled_from, shared) + sampled_from, shared, builds) from . import _array_module as xp, api_version from . import dtype_helpers as dh @@ -20,7 +21,60 @@ from ._array_module import broadcast_to, eye, float32, float64, full from .stubs import category_to_funcs from .pytest_helpers import nargs -from .typing import Array, DataType, Shape +from .typing import Array, DataType, Scalar, Shape + + +def _float32ify(n: Union[int, float]) -> float: + n = float(n) + return struct.unpack("!f", struct.pack("!f", n))[0] + + +@wraps(xps.from_dtype) +def from_dtype(dtype, **kwargs) -> SearchStrategy[Scalar]: + """xps.from_dtype() without the crazy large numbers.""" + if dtype == xp.bool: + return xps.from_dtype(dtype, **kwargs) + + if dtype in dh.complex_dtypes: + component_dtype = dh.dtype_components[dtype] + else: + component_dtype = dtype + + min_, max_ = dh.dtype_ranges[component_dtype] + + if "min_value" not in kwargs.keys() and min_ != 0: + assert min_ < 0 # sanity check + min_value = -1 * math.floor(math.sqrt(abs(min_))) + if component_dtype == xp.float32: + min_value = _float32ify(min_value) + kwargs["min_value"] = min_value + if "max_value" not in kwargs.keys(): + assert max_ > 0 # sanity check + max_value = math.floor(math.sqrt(max_)) + if component_dtype == xp.float32: + max_value = _float32ify(max_value) + kwargs["max_value"] = max_value + + if dtype in dh.complex_dtypes: + component_strat = xps.from_dtype(dh.dtype_components[dtype], **kwargs) + return builds(complex, component_strat, component_strat) + else: + return xps.from_dtype(dtype, **kwargs) + + +@wraps(xps.arrays) +def arrays(dtype, *args, elements=None, **kwargs) -> SearchStrategy[Array]: + """xps.arrays() without the crazy large numbers.""" + if isinstance(dtype, SearchStrategy): + return dtype.flatmap(lambda d: arrays(d, *args, elements=elements, **kwargs)) + + if elements is None: + elements = from_dtype(dtype) + elif isinstance(elements, Mapping): + elements = from_dtype(dtype, **elements) + + return xps.arrays(dtype, *args, elements=elements, **kwargs) + _dtype_categories = [(xp.bool,), dh.uint_dtypes, dh.int_dtypes, dh.real_float_dtypes, dh.complex_dtypes] _sorted_dtypes = [d for category in _dtype_categories for d in category] @@ -145,7 +199,7 @@ def all_floating_dtypes() -> SearchStrategy[DataType]: # Limit the total size of an array shape MAX_ARRAY_SIZE = 10000 # Size to use for 2-dim arrays -SQRT_MAX_ARRAY_SIZE = int(sqrt(MAX_ARRAY_SIZE)) +SQRT_MAX_ARRAY_SIZE = int(math.sqrt(MAX_ARRAY_SIZE)) # np.prod and others have overflow and math.prod is Python 3.8+ only def prod(seq): @@ -181,7 +235,7 @@ def matrix_shapes(draw, stack_shapes=shapes()): @composite def finite_matrices(draw, shape=matrix_shapes()): - return draw(xps.arrays(dtype=xps.floating_dtypes(), + return draw(arrays(dtype=xps.floating_dtypes(), shape=shape, elements=dict(allow_nan=False, allow_infinity=False))) @@ -190,7 +244,7 @@ def finite_matrices(draw, shape=matrix_shapes()): # Should we set a max_value here? _rtol_float_kw = dict(allow_nan=False, allow_infinity=False, min_value=0) rtols = one_of(floats(**_rtol_float_kw), - xps.arrays(dtype=xps.floating_dtypes(), + arrays(dtype=xps.floating_dtypes(), shape=rtol_shared_matrix_shapes.map(lambda shape: shape[:-2]), elements=_rtol_float_kw)) @@ -233,7 +287,7 @@ def symmetric_matrices(draw, dtypes=xps.floating_dtypes(), finite=True): if not isinstance(finite, bool): finite = draw(finite) elements = {'allow_nan': False, 'allow_infinity': False} if finite else None - a = draw(xps.arrays(dtype=dtype, shape=shape, elements=elements)) + a = draw(arrays(dtype=dtype, shape=shape, elements=elements)) upper = xp.triu(a) lower = xp.triu(a, k=1).mT return upper + lower @@ -256,7 +310,7 @@ def invertible_matrices(draw, dtypes=xps.floating_dtypes(), stack_shapes=shapes( n = draw(integers(0, SQRT_MAX_ARRAY_SIZE),) stack_shape = draw(stack_shapes) shape = stack_shape + (n, n) - d = draw(xps.arrays(dtypes, shape=n*prod(stack_shape), + d = draw(arrays(dtypes, shape=n*prod(stack_shape), elements=dict(allow_nan=False, allow_infinity=False))) # Functions that require invertible matrices may do anything when it is # singular, including raising an exception, so we make sure the diagonals @@ -282,7 +336,7 @@ def two_broadcastable_shapes(draw): sizes = integers(0, MAX_ARRAY_SIZE) sqrt_sizes = integers(0, SQRT_MAX_ARRAY_SIZE) -numeric_arrays = xps.arrays( +numeric_arrays = arrays( dtype=shared(xps.floating_dtypes(), key='dtypes'), shape=shared(xps.array_shapes(), key='shapes'), ) @@ -407,11 +461,11 @@ def two_mutual_arrays( assert len(dtypes) > 0 # sanity check mutual_dtypes = shared(mutually_promotable_dtypes(dtypes=dtypes)) mutual_shapes = shared(two_shapes) - arrays1 = xps.arrays( + arrays1 = arrays( dtype=mutual_dtypes.map(lambda pair: pair[0]), shape=mutual_shapes.map(lambda pair: pair[0]), ) - arrays2 = xps.arrays( + arrays2 = arrays( dtype=mutual_dtypes.map(lambda pair: pair[1]), shape=mutual_shapes.map(lambda pair: pair[1]), ) diff --git a/array_api_tests/test_array_object.py b/array_api_tests/test_array_object.py index d44bdeba..6d550f60 100644 --- a/array_api_tests/test_array_object.py +++ b/array_api_tests/test_array_object.py @@ -24,7 +24,7 @@ def scalar_objects( ) -> st.SearchStrategy[Union[Scalar, List[Scalar]]]: """Generates scalars or nested sequences which are valid for xp.asarray()""" size = math.prod(shape) - return st.lists(xps.from_dtype(dtype), min_size=size, max_size=size).map( + return st.lists(hh.from_dtype(dtype), min_size=size, max_size=size).map( lambda l: sh.reshape(l, shape) ) @@ -123,10 +123,10 @@ def test_setitem(shape, dtypes, data): key = data.draw(xps.indices(shape=shape), label="key") _key = normalise_key(key, shape) axes_indices, out_shape = get_indexed_axes_and_out_shape(_key, shape) - value_strat = xps.arrays(dtype=dtypes.result_dtype, shape=out_shape) + value_strat = hh.arrays(dtype=dtypes.result_dtype, shape=out_shape) if out_shape == (): # We can pass scalars if we're only indexing one element - value_strat |= xps.from_dtype(dtypes.result_dtype) + value_strat |= hh.from_dtype(dtypes.result_dtype) value = data.draw(value_strat, label="value") res = xp.asarray(x, copy=True) @@ -157,7 +157,7 @@ def test_setitem(shape, dtypes, data): @pytest.mark.data_dependent_shapes @given(hh.shapes(), st.data()) def test_getitem_masking(shape, data): - x = data.draw(xps.arrays(xps.scalar_dtypes(), shape=shape), label="x") + x = data.draw(hh.arrays(xps.scalar_dtypes(), shape=shape), label="x") mask_shapes = st.one_of( st.sampled_from([x.shape, ()]), st.lists(st.booleans(), min_size=x.ndim, max_size=x.ndim).map( @@ -165,7 +165,7 @@ def test_getitem_masking(shape, data): ), hh.shapes(), ) - key = data.draw(xps.arrays(dtype=xp.bool, shape=mask_shapes), label="key") + key = data.draw(hh.arrays(dtype=xp.bool, shape=mask_shapes), label="key") if key.ndim > x.ndim or not all( ks in (xs, 0) for xs, ks in zip(x.shape, key.shape) @@ -201,10 +201,10 @@ def test_getitem_masking(shape, data): @given(hh.shapes(), st.data()) def test_setitem_masking(shape, data): - x = data.draw(xps.arrays(xps.scalar_dtypes(), shape=shape), label="x") - key = data.draw(xps.arrays(dtype=xp.bool, shape=shape), label="key") + x = data.draw(hh.arrays(xps.scalar_dtypes(), shape=shape), label="x") + key = data.draw(hh.arrays(dtype=xp.bool, shape=shape), label="key") value = data.draw( - xps.from_dtype(x.dtype) | xps.arrays(dtype=x.dtype, shape=()), label="value" + hh.from_dtype(x.dtype) | hh.arrays(dtype=x.dtype, shape=()), label="value" ) res = xp.asarray(x, copy=True) @@ -263,7 +263,7 @@ def test_scalar_casting(method_name, dtype_name, stype, data): dtype = getattr(_xp, dtype_name) except AttributeError as e: pytest.skip(str(e)) - x = data.draw(xps.arrays(dtype, shape=()), label="x") + x = data.draw(hh.arrays(dtype, shape=()), label="x") method = getattr(x, method_name) out = method() assert isinstance( diff --git a/array_api_tests/test_creation_functions.py b/array_api_tests/test_creation_functions.py index c631bab0..19e945ca 100644 --- a/array_api_tests/test_creation_functions.py +++ b/array_api_tests/test_creation_functions.py @@ -86,8 +86,8 @@ def test_arange(dtype, data): start = data.draw(reals(), label="start") stop = data.draw(reals() | st.none(), label="stop") else: - start = data.draw(xps.from_dtype(dtype), label="start") - stop = data.draw(xps.from_dtype(dtype), label="stop") + start = data.draw(hh.from_dtype(dtype), label="start") + stop = data.draw(hh.from_dtype(dtype), label="stop") if stop is None: _start = 0 _stop = start @@ -107,9 +107,9 @@ def test_arange(dtype, data): step_strats = [] if dtype in dh.int_dtypes: step_min = min(math.floor(-tol), -1) - step_strats.append(xps.from_dtype(dtype, max_value=step_min)) + step_strats.append(hh.from_dtype(dtype, max_value=step_min)) step_max = max(math.ceil(tol), 1) - step_strats.append(xps.from_dtype(dtype, min_value=step_max)) + step_strats.append(hh.from_dtype(dtype, min_value=step_max)) step = data.draw(st.one_of(step_strats), label="step") assert step != 0, "step must not equal 0" # sanity check @@ -215,11 +215,11 @@ def test_asarray_scalars(shape, data): else: _dtype = dtype if dh.is_float_dtype(_dtype): - elements_strat = xps.from_dtype(_dtype) | xps.from_dtype(xp.int32) + elements_strat = hh.from_dtype(_dtype) | hh.from_dtype(xp.int32) elif dh.is_int_dtype(_dtype): - elements_strat = xps.from_dtype(_dtype) | st.booleans() + elements_strat = hh.from_dtype(_dtype) | st.booleans() else: - elements_strat = xps.from_dtype(_dtype) + elements_strat = hh.from_dtype(_dtype) size = math.prod(shape) obj_strat = st.lists(elements_strat, min_size=size, max_size=size) scalar_type = dh.get_scalar_type(_dtype) @@ -267,7 +267,7 @@ def scalar_eq(s1: Scalar, s2: Scalar) -> bool: data=st.data(), ) def test_asarray_arrays(shape, dtypes, data): - x = data.draw(xps.arrays(dtype=dtypes.input_dtype, shape=shape), label="x") + x = data.draw(hh.arrays(dtype=dtypes.input_dtype, shape=shape), label="x") dtypes_strat = st.just(dtypes.input_dtype) if dtypes.input_dtype == dtypes.result_dtype: dtypes_strat |= st.none() @@ -290,7 +290,7 @@ def test_asarray_arrays(shape, dtypes, data): stype = dh.get_scalar_type(x.dtype) idx = data.draw(xps.indices(x.shape, max_dims=0), label="mutating idx") old_value = stype(x[idx]) - scalar_strat = xps.from_dtype(dtypes.input_dtype).filter( + scalar_strat = hh.from_dtype(dtypes.input_dtype).filter( lambda n: not scalar_eq(n, old_value) ) value = data.draw( @@ -326,7 +326,7 @@ def test_empty(shape, kw): @given( - x=xps.arrays(dtype=xps.scalar_dtypes(), shape=hh.shapes()), + x=hh.arrays(dtype=xps.scalar_dtypes(), shape=hh.shapes()), kw=hh.kwargs(dtype=st.none() | xps.scalar_dtypes()), ) def test_empty_like(x, kw): @@ -382,7 +382,7 @@ def full_fill_values(draw) -> Union[bool, int, float, complex]: st.shared(hh.kwargs(dtype=st.none() | xps.scalar_dtypes()), key="full_kw") ) dtype = kw.get("dtype", None) or draw(default_safe_dtypes) - return draw(xps.from_dtype(dtype)) + return draw(hh.from_dtype(dtype)) @given( @@ -430,8 +430,8 @@ def test_full(shape, fill_value, kw): @given(kw=hh.kwargs(dtype=st.none() | xps.scalar_dtypes()), data=st.data()) def test_full_like(kw, data): dtype = kw.get("dtype", None) or data.draw(xps.scalar_dtypes(), label="dtype") - x = data.draw(xps.arrays(dtype=dtype, shape=hh.shapes()), label="x") - fill_value = data.draw(xps.from_dtype(dtype), label="fill_value") + x = data.draw(hh.arrays(dtype=dtype, shape=hh.shapes()), label="x") + fill_value = data.draw(hh.from_dtype(dtype), label="fill_value") out = xp.full_like(x, fill_value, **kw) dtype = kw.get("dtype", None) or x.dtype if kw.get("dtype", None) is None: @@ -454,8 +454,8 @@ def test_full_like(kw, data): def test_linspace(num, dtype, endpoint, data): _dtype = dh.default_float if dtype is None else dtype - start = data.draw(xps.from_dtype(_dtype, **finite_kw), label="start") - stop = data.draw(xps.from_dtype(_dtype, **finite_kw), label="stop") + start = data.draw(hh.from_dtype(_dtype, **finite_kw), label="start") + stop = data.draw(hh.from_dtype(_dtype, **finite_kw), label="stop") # avoid overflow errors assume(not xp.isnan(xp.asarray(stop - start, dtype=_dtype))) assume(not xp.isnan(xp.asarray(start - stop, dtype=_dtype))) @@ -509,7 +509,7 @@ def test_meshgrid(dtype, data): ) arrays = [] for i, shape in enumerate(shapes, 1): - x = data.draw(xps.arrays(dtype=dtype, shape=shape), label=f"x{i}") + x = data.draw(hh.arrays(dtype=dtype, shape=shape), label=f"x{i}") arrays.append(x) # sanity check assert math.prod(math.prod(x.shape) for x in arrays) <= hh.MAX_ARRAY_SIZE @@ -541,7 +541,7 @@ def test_ones(shape, kw): @given( - x=xps.arrays(dtype=xps.scalar_dtypes(), shape=hh.shapes()), + x=hh.arrays(dtype=xps.scalar_dtypes(), shape=hh.shapes()), kw=hh.kwargs(dtype=st.none() | xps.scalar_dtypes()), ) def test_ones_like(x, kw): @@ -579,7 +579,7 @@ def test_zeros(shape, kw): @given( - x=xps.arrays(dtype=xps.scalar_dtypes(), shape=hh.shapes()), + x=hh.arrays(dtype=xps.scalar_dtypes(), shape=hh.shapes()), kw=hh.kwargs(dtype=st.none() | xps.scalar_dtypes()), ) def test_zeros_like(x, kw): diff --git a/array_api_tests/test_data_type_functions.py b/array_api_tests/test_data_type_functions.py index ccae9930..ebad915f 100644 --- a/array_api_tests/test_data_type_functions.py +++ b/array_api_tests/test_data_type_functions.py @@ -34,7 +34,7 @@ def float32(n: Union[int, float]) -> float: ) def test_astype(x_dtype, dtype, kw, data): if xp.bool in (x_dtype, dtype): - elements_strat = xps.from_dtype(x_dtype) + elements_strat = hh.from_dtype(x_dtype) else: m1, M1 = dh.dtype_ranges[x_dtype] m2, M2 = dh.dtype_ranges[dtype] @@ -46,7 +46,7 @@ def test_astype(x_dtype, dtype, kw, data): cast = float min_value = cast(max(m1, m2)) max_value = cast(min(M1, M2)) - elements_strat = xps.from_dtype( + elements_strat = hh.from_dtype( x_dtype, min_value=min_value, max_value=max_value, @@ -54,7 +54,7 @@ def test_astype(x_dtype, dtype, kw, data): allow_infinity=False, ) x = data.draw( - xps.arrays(dtype=x_dtype, shape=hh.shapes(), elements=elements_strat), label="x" + hh.arrays(dtype=x_dtype, shape=hh.shapes(), elements=elements_strat), label="x" ) out = xp.astype(x, dtype, **kw) @@ -71,7 +71,7 @@ def test_astype(x_dtype, dtype, kw, data): def test_broadcast_arrays(shapes, data): arrays = [] for c, shape in enumerate(shapes, 1): - x = data.draw(xps.arrays(dtype=xps.scalar_dtypes(), shape=shape), label=f"x{c}") + x = data.draw(hh.arrays(dtype=xps.scalar_dtypes(), shape=shape), label=f"x{c}") arrays.append(x) out = xp.broadcast_arrays(*arrays) @@ -94,7 +94,7 @@ def test_broadcast_arrays(shapes, data): # TODO: test values -@given(x=xps.arrays(dtype=xps.scalar_dtypes(), shape=hh.shapes()), data=st.data()) +@given(x=hh.arrays(dtype=xps.scalar_dtypes(), shape=hh.shapes()), data=st.data()) def test_broadcast_to(x, data): shape = data.draw( hh.mutually_broadcastable_shapes(1, base_shape=x.shape) @@ -113,7 +113,7 @@ def test_broadcast_to(x, data): @given(_from=non_complex_dtypes(), to=non_complex_dtypes(), data=st.data()) def test_can_cast(_from, to, data): from_ = data.draw( - st.just(_from) | xps.arrays(dtype=_from, shape=hh.shapes()), label="from_" + st.just(_from) | hh.arrays(dtype=_from, shape=hh.shapes()), label="from_" ) out = xp.can_cast(from_, to) diff --git a/array_api_tests/test_fft.py b/array_api_tests/test_fft.py index 97740d47..334caad2 100644 --- a/array_api_tests/test_fft.py +++ b/array_api_tests/test_fft.py @@ -146,7 +146,7 @@ def assert_s_axes_shape( @given( - x=xps.arrays(dtype=hh.all_floating_dtypes(), shape=fft_shapes_strat), + x=hh.arrays(dtype=hh.all_floating_dtypes(), shape=fft_shapes_strat), data=st.data(), ) def test_fft(x, data): @@ -159,7 +159,7 @@ def test_fft(x, data): @given( - x=xps.arrays(dtype=hh.all_floating_dtypes(), shape=fft_shapes_strat), + x=hh.arrays(dtype=hh.all_floating_dtypes(), shape=fft_shapes_strat), data=st.data(), ) def test_ifft(x, data): @@ -172,7 +172,7 @@ def test_ifft(x, data): @given( - x=xps.arrays(dtype=hh.all_floating_dtypes(), shape=fft_shapes_strat), + x=hh.arrays(dtype=hh.all_floating_dtypes(), shape=fft_shapes_strat), data=st.data(), ) def test_fftn(x, data): @@ -185,7 +185,7 @@ def test_fftn(x, data): @given( - x=xps.arrays(dtype=hh.all_floating_dtypes(), shape=fft_shapes_strat), + x=hh.arrays(dtype=hh.all_floating_dtypes(), shape=fft_shapes_strat), data=st.data(), ) def test_ifftn(x, data): @@ -198,7 +198,7 @@ def test_ifftn(x, data): @given( - x=xps.arrays(dtype=xps.floating_dtypes(), shape=fft_shapes_strat), + x=hh.arrays(dtype=xps.floating_dtypes(), shape=fft_shapes_strat), data=st.data(), ) def test_rfft(x, data): @@ -211,7 +211,7 @@ def test_rfft(x, data): @given( - x=xps.arrays(dtype=xps.complex_dtypes(), shape=fft_shapes_strat), + x=hh.arrays(dtype=xps.complex_dtypes(), shape=fft_shapes_strat), data=st.data(), ) def test_irfft(x, data): @@ -231,7 +231,7 @@ def test_irfft(x, data): @given( - x=xps.arrays(dtype=xps.floating_dtypes(), shape=fft_shapes_strat), + x=hh.arrays(dtype=xps.floating_dtypes(), shape=fft_shapes_strat), data=st.data(), ) def test_rfftn(x, data): @@ -244,7 +244,7 @@ def test_rfftn(x, data): @given( - x=xps.arrays( + x=hh.arrays( dtype=xps.complex_dtypes(), shape=fft_shapes_strat.filter(lambda s: s[-1] > 1) ), data=st.data(), @@ -259,7 +259,7 @@ def test_irfftn(x, data): @given( - x=xps.arrays(dtype=hh.all_floating_dtypes(), shape=fft_shapes_strat), + x=hh.arrays(dtype=hh.all_floating_dtypes(), shape=fft_shapes_strat), data=st.data(), ) def test_hfft(x, data): @@ -279,7 +279,7 @@ def test_hfft(x, data): @given( - x=xps.arrays(dtype=xps.floating_dtypes(), shape=fft_shapes_strat), + x=hh.arrays(dtype=xps.floating_dtypes(), shape=fft_shapes_strat), data=st.data(), ) def test_ihfft(x, data): diff --git a/array_api_tests/test_indexing_functions.py b/array_api_tests/test_indexing_functions.py index 7f35e73a..9f2cf319 100644 --- a/array_api_tests/test_indexing_functions.py +++ b/array_api_tests/test_indexing_functions.py @@ -14,7 +14,7 @@ @pytest.mark.min_version("2022.12") @given( - x=xps.arrays(xps.scalar_dtypes(), hh.shapes(min_dims=1, min_side=1)), + x=hh.arrays(xps.scalar_dtypes(), hh.shapes(min_dims=1, min_side=1)), data=st.data(), ) def test_take(x, data): diff --git a/array_api_tests/test_linalg.py b/array_api_tests/test_linalg.py index a289a1f2..18395a20 100644 --- a/array_api_tests/test_linalg.py +++ b/array_api_tests/test_linalg.py @@ -21,7 +21,7 @@ from ndindex import iter_indices from .array_helpers import assert_exactly_equal, asarray -from .hypothesis_helpers import (xps, shapes, kwargs, matrix_shapes, +from .hypothesis_helpers import (arrays, xps, shapes, kwargs, matrix_shapes, square_matrix_shapes, symmetric_matrices, positive_definite_matrices, MAX_ARRAY_SIZE, invertible_matrices, two_mutual_arrays, @@ -136,11 +136,11 @@ def cross_args(draw, dtype_objects=dh.real_dtypes): shape = tuple(shape) mutual_dtypes = shared(mutually_promotable_dtypes(dtypes=dtype_objects)) - arrays1 = xps.arrays( + arrays1 = arrays( dtype=mutual_dtypes.map(lambda pair: pair[0]), shape=shape, ) - arrays2 = xps.arrays( + arrays2 = arrays( dtype=mutual_dtypes.map(lambda pair: pair[1]), shape=shape, ) @@ -179,7 +179,7 @@ def exact_cross(a, b): @pytest.mark.xp_extension('linalg') @given( - x=xps.arrays(dtype=xps.floating_dtypes(), shape=square_matrix_shapes), + x=arrays(dtype=xps.floating_dtypes(), shape=square_matrix_shapes), ) def test_det(x): res = linalg.det(x) @@ -193,7 +193,7 @@ def test_det(x): @pytest.mark.xp_extension('linalg') @given( - x=xps.arrays(dtype=xps.real_dtypes(), shape=matrix_shapes()), + x=arrays(dtype=xps.real_dtypes(), shape=matrix_shapes()), # offset may produce an overflow if it is too large. Supporting offsets # that are way larger than the array shape isn't very important. kw=kwargs(offset=integers(-MAX_ARRAY_SIZE, MAX_ARRAY_SIZE)) @@ -342,7 +342,7 @@ def test_matrix_norm(x, kw): @given( # Generate any square matrix if n >= 0 but only invertible matrices if n < 0 x=matrix_power_n.flatmap(lambda n: invertible_matrices() if n < 0 else - xps.arrays(dtype=xps.floating_dtypes(), + arrays(dtype=xps.floating_dtypes(), shape=square_matrix_shapes)), n=matrix_power_n, ) @@ -369,7 +369,7 @@ def test_matrix_rank(x, kw): linalg.matrix_rank(x, **kw) @given( - x=xps.arrays(dtype=xps.real_dtypes(), shape=matrix_shapes()), + x=arrays(dtype=xps.real_dtypes(), shape=matrix_shapes()), ) def test_matrix_transpose(x): res = _array_module.matrix_transpose(x) @@ -419,7 +419,7 @@ def test_pinv(x, kw): @pytest.mark.xp_extension('linalg') @given( - x=xps.arrays(dtype=xps.floating_dtypes(), shape=matrix_shapes()), + x=arrays(dtype=xps.floating_dtypes(), shape=matrix_shapes()), kw=kwargs(mode=sampled_from(['reduced', 'complete'])) ) def test_qr(x, kw): @@ -455,7 +455,7 @@ def test_qr(x, kw): @pytest.mark.xp_extension('linalg') @given( - x=xps.arrays(dtype=xps.floating_dtypes(), shape=square_matrix_shapes), + x=arrays(dtype=xps.floating_dtypes(), shape=square_matrix_shapes), ) def test_slogdet(x): res = linalg.slogdet(x) @@ -510,7 +510,7 @@ def _x2_shapes(draw): return draw(stack_shapes)[1] + draw(x1).shape[-1:] + (end,) x2_shapes = one_of(x1.map(lambda x: (x.shape[-1],)), _x2_shapes()) - x2 = xps.arrays(dtype=xps.floating_dtypes(), shape=x2_shapes) + x2 = arrays(dtype=xps.floating_dtypes(), shape=x2_shapes) return x1, x2 @pytest.mark.xp_extension('linalg') @@ -582,8 +582,8 @@ def test_svdvals(x): ) def test_tensordot(dtypes, shape, data): # TODO: vary shapes, vary contracted axes, test different axes arguments - x1 = data.draw(xps.arrays(dtype=dtypes[0], shape=shape), label="x1") - x2 = data.draw(xps.arrays(dtype=dtypes[1], shape=shape), label="x2") + x1 = data.draw(arrays(dtype=dtypes[0], shape=shape), label="x1") + x2 = data.draw(arrays(dtype=dtypes[1], shape=shape), label="x2") out = xp.tensordot(x1, x2, axes=len(shape)) @@ -593,7 +593,7 @@ def test_tensordot(dtypes, shape, data): @pytest.mark.xp_extension('linalg') @given( - x=xps.arrays(dtype=xps.real_dtypes(), shape=matrix_shapes()), + x=arrays(dtype=xps.real_dtypes(), shape=matrix_shapes()), # offset may produce an overflow if it is too large. Supporting offsets # that are way larger than the array shape isn't very important. kw=kwargs(offset=integers(-MAX_ARRAY_SIZE, MAX_ARRAY_SIZE)) @@ -638,8 +638,8 @@ def true_trace(x_stack): ) def test_vecdot(dtypes, shape, data): # TODO: vary shapes, test different axis arguments - x1 = data.draw(xps.arrays(dtype=dtypes[0], shape=shape), label="x1") - x2 = data.draw(xps.arrays(dtype=dtypes[1], shape=shape), label="x2") + x1 = data.draw(arrays(dtype=dtypes[0], shape=shape), label="x1") + x2 = data.draw(arrays(dtype=dtypes[1], shape=shape), label="x2") kw = data.draw(kwargs(axis=just(-1))) out = xp.vecdot(x1, x2, **kw) @@ -650,7 +650,7 @@ def test_vecdot(dtypes, shape, data): @pytest.mark.xp_extension('linalg') @given( - x=xps.arrays(dtype=xps.floating_dtypes(), shape=shapes()), + x=arrays(dtype=xps.floating_dtypes(), shape=shapes()), kw=kwargs(axis=todo, keepdims=todo, ord=todo) ) def test_vector_norm(x, kw): diff --git a/array_api_tests/test_manipulation_functions.py b/array_api_tests/test_manipulation_functions.py index 8f48dd9d..fd27b2dc 100644 --- a/array_api_tests/test_manipulation_functions.py +++ b/array_api_tests/test_manipulation_functions.py @@ -72,7 +72,7 @@ def test_concat(dtypes, base_shape, data): ) arrays = [] for i, dtype in enumerate(dtypes, 1): - x = data.draw(xps.arrays(dtype=dtype, shape=shape_strat), label=f"x{i}") + x = data.draw(hh.arrays(dtype=dtype, shape=shape_strat), label=f"x{i}") arrays.append(x) out = xp.concat(arrays, **kw) @@ -122,7 +122,7 @@ def test_concat(dtypes, base_shape, data): @given( - x=xps.arrays(dtype=xps.scalar_dtypes(), shape=shared_shapes()), + x=hh.arrays(dtype=xps.scalar_dtypes(), shape=shared_shapes()), axis=shared_shapes().flatmap( # Generate both valid and invalid axis lambda s: st.integers(2 * (-len(s) - 1), 2 * len(s)) @@ -150,7 +150,7 @@ def test_expand_dims(x, axis): @given( - x=xps.arrays( + x=hh.arrays( dtype=xps.scalar_dtypes(), shape=hh.shapes(min_side=1).filter(lambda s: 1 in s) ), data=st.data(), @@ -187,7 +187,7 @@ def test_squeeze(x, data): @given( - x=xps.arrays(dtype=xps.scalar_dtypes(), shape=hh.shapes()), + x=hh.arrays(dtype=xps.scalar_dtypes(), shape=hh.shapes()), data=st.data(), ) def test_flip(x, data): @@ -211,7 +211,7 @@ def test_flip(x, data): @given( - x=xps.arrays(dtype=xps.scalar_dtypes(), shape=shared_shapes(min_dims=1)), + x=hh.arrays(dtype=xps.scalar_dtypes(), shape=shared_shapes(min_dims=1)), axes=shared_shapes(min_dims=1).flatmap( lambda s: st.lists( st.integers(0, len(s) - 1), @@ -251,7 +251,7 @@ def reshape_shapes(draw, shape): @given( - x=xps.arrays(dtype=xps.scalar_dtypes(), shape=hh.shapes(max_side=MAX_SIDE)), + x=hh.arrays(dtype=xps.scalar_dtypes(), shape=hh.shapes(max_side=MAX_SIDE)), data=st.data(), ) def test_reshape(x, data): @@ -281,7 +281,7 @@ def roll_ndindex(shape: Shape, shifts: Tuple[int], axes: Tuple[int]) -> Iterator yield tuple((i + sh) % si for i, sh, si in zip(idx, all_shifts, shape)) -@given(xps.arrays(dtype=xps.scalar_dtypes(), shape=shared_shapes()), st.data()) +@given(hh.arrays(dtype=xps.scalar_dtypes(), shape=shared_shapes()), st.data()) def test_roll(x, data): shift_strat = st.integers(-hh.MAX_ARRAY_SIZE, hh.MAX_ARRAY_SIZE) if x.ndim > 0: @@ -333,7 +333,7 @@ def test_roll(x, data): def test_stack(shape, dtypes, kw, data): arrays = [] for i, dtype in enumerate(dtypes, 1): - x = data.draw(xps.arrays(dtype=dtype, shape=shape), label=f"x{i}") + x = data.draw(hh.arrays(dtype=dtype, shape=shape), label=f"x{i}") arrays.append(x) out = xp.stack(arrays, **kw) diff --git a/array_api_tests/test_operators_and_elementwise_functions.py b/array_api_tests/test_operators_and_elementwise_functions.py index d19cb5c4..3ceab0b0 100644 --- a/array_api_tests/test_operators_and_elementwise_functions.py +++ b/array_api_tests/test_operators_and_elementwise_functions.py @@ -473,7 +473,7 @@ def make_unary_params( if api_version < "2022.12": dtypes = [d for d in dtypes if d not in dh.complex_dtypes] dtypes_strat = st.sampled_from(dtypes) - strat = xps.arrays(dtype=dtypes_strat, shape=hh.shapes()) + strat = hh.arrays(dtype=dtypes_strat, shape=hh.shapes()) func_ctx = UnaryParamContext( func_name=elwise_func_name, func=getattr(xp, elwise_func_name), strat=strat ) @@ -540,16 +540,16 @@ def make_param( right_sym = "x2" if right_is_scalar: - left_strat = xps.arrays(dtype=left_dtypes, shape=hh.shapes(**shapes_kw)) - right_strat = right_dtypes.flatmap(lambda d: xps.from_dtype(d, **finite_kw)) + left_strat = hh.arrays(dtype=left_dtypes, shape=hh.shapes(**shapes_kw)) + right_strat = right_dtypes.flatmap(lambda d: hh.from_dtype(d, **finite_kw)) else: if func_type is FuncType.IOP: shared_oneway_shapes = st.shared(hh.oneway_broadcastable_shapes()) - left_strat = xps.arrays( + left_strat = hh.arrays( dtype=left_dtypes, shape=shared_oneway_shapes.map(lambda S: S.result_shape), ) - right_strat = xps.arrays( + right_strat = hh.arrays( dtype=right_dtypes, shape=shared_oneway_shapes.map(lambda S: S.input_shape), ) @@ -557,10 +557,10 @@ def make_param( mutual_shapes = st.shared( hh.mutually_broadcastable_shapes(2, **shapes_kw) ) - left_strat = xps.arrays( + left_strat = hh.arrays( dtype=left_dtypes, shape=mutual_shapes.map(lambda pair: pair[0]) ) - right_strat = xps.arrays( + right_strat = hh.arrays( dtype=right_dtypes, shape=mutual_shapes.map(lambda pair: pair[1]) ) @@ -723,7 +723,7 @@ def test_abs(ctx, data): ) -@given(xps.arrays(dtype=hh.all_floating_dtypes(), shape=hh.shapes())) +@given(hh.arrays(dtype=hh.all_floating_dtypes(), shape=hh.shapes())) def test_acos(x): out = xp.acos(x) ph.assert_dtype("acos", in_dtype=x.dtype, out_dtype=out.dtype) @@ -733,7 +733,7 @@ def test_acos(x): ) -@given(xps.arrays(dtype=hh.all_floating_dtypes(), shape=hh.shapes())) +@given(hh.arrays(dtype=hh.all_floating_dtypes(), shape=hh.shapes())) def test_acosh(x): out = xp.acosh(x) ph.assert_dtype("acosh", in_dtype=x.dtype, out_dtype=out.dtype) @@ -757,7 +757,7 @@ def test_add(ctx, data): binary_param_assert_against_refimpl(ctx, left, right, res, "+", operator.add) -@given(xps.arrays(dtype=hh.all_floating_dtypes(), shape=hh.shapes())) +@given(hh.arrays(dtype=hh.all_floating_dtypes(), shape=hh.shapes())) def test_asin(x): out = xp.asin(x) ph.assert_dtype("asin", in_dtype=x.dtype, out_dtype=out.dtype) @@ -767,7 +767,7 @@ def test_asin(x): ) -@given(xps.arrays(dtype=hh.all_floating_dtypes(), shape=hh.shapes())) +@given(hh.arrays(dtype=hh.all_floating_dtypes(), shape=hh.shapes())) def test_asinh(x): out = xp.asinh(x) ph.assert_dtype("asinh", in_dtype=x.dtype, out_dtype=out.dtype) @@ -775,7 +775,7 @@ def test_asinh(x): unary_assert_against_refimpl("asinh", x, out, math.asinh) -@given(xps.arrays(dtype=hh.all_floating_dtypes(), shape=hh.shapes())) +@given(hh.arrays(dtype=hh.all_floating_dtypes(), shape=hh.shapes())) def test_atan(x): out = xp.atan(x) ph.assert_dtype("atan", in_dtype=x.dtype, out_dtype=out.dtype) @@ -791,7 +791,7 @@ def test_atan2(x1, x2): binary_assert_against_refimpl("atan2", x1, x2, out, math.atan2) -@given(xps.arrays(dtype=hh.all_floating_dtypes(), shape=hh.shapes())) +@given(hh.arrays(dtype=hh.all_floating_dtypes(), shape=hh.shapes())) def test_atanh(x): out = xp.atanh(x) ph.assert_dtype("atanh", in_dtype=x.dtype, out_dtype=out.dtype) @@ -923,7 +923,7 @@ def test_bitwise_xor(ctx, data): binary_param_assert_against_refimpl(ctx, left, right, res, "^", refimpl) -@given(xps.arrays(dtype=xps.real_dtypes(), shape=hh.shapes())) +@given(hh.arrays(dtype=xps.real_dtypes(), shape=hh.shapes())) def test_ceil(x): out = xp.ceil(x) ph.assert_dtype("ceil", in_dtype=x.dtype, out_dtype=out.dtype) @@ -933,7 +933,7 @@ def test_ceil(x): if api_version >= "2022.12": - @given(xps.arrays(dtype=xps.complex_dtypes(), shape=hh.shapes())) + @given(hh.arrays(dtype=xps.complex_dtypes(), shape=hh.shapes())) def test_conj(x): out = xp.conj(x) ph.assert_dtype("conj", in_dtype=x.dtype, out_dtype=out.dtype) @@ -941,7 +941,7 @@ def test_conj(x): unary_assert_against_refimpl("conj", x, out, operator.methodcaller("conjugate")) -@given(xps.arrays(dtype=hh.all_floating_dtypes(), shape=hh.shapes())) +@given(hh.arrays(dtype=hh.all_floating_dtypes(), shape=hh.shapes())) def test_cos(x): out = xp.cos(x) ph.assert_dtype("cos", in_dtype=x.dtype, out_dtype=out.dtype) @@ -949,7 +949,7 @@ def test_cos(x): unary_assert_against_refimpl("cos", x, out, math.cos) -@given(xps.arrays(dtype=hh.all_floating_dtypes(), shape=hh.shapes())) +@given(hh.arrays(dtype=hh.all_floating_dtypes(), shape=hh.shapes())) def test_cosh(x): out = xp.cosh(x) ph.assert_dtype("cosh", in_dtype=x.dtype, out_dtype=out.dtype) @@ -1010,7 +1010,7 @@ def test_equal(ctx, data): ) -@given(xps.arrays(dtype=hh.all_floating_dtypes(), shape=hh.shapes())) +@given(hh.arrays(dtype=hh.all_floating_dtypes(), shape=hh.shapes())) def test_exp(x): out = xp.exp(x) ph.assert_dtype("exp", in_dtype=x.dtype, out_dtype=out.dtype) @@ -1018,7 +1018,7 @@ def test_exp(x): unary_assert_against_refimpl("exp", x, out, math.exp) -@given(xps.arrays(dtype=hh.all_floating_dtypes(), shape=hh.shapes())) +@given(hh.arrays(dtype=hh.all_floating_dtypes(), shape=hh.shapes())) def test_expm1(x): out = xp.expm1(x) ph.assert_dtype("expm1", in_dtype=x.dtype, out_dtype=out.dtype) @@ -1026,7 +1026,7 @@ def test_expm1(x): unary_assert_against_refimpl("expm1", x, out, math.expm1) -@given(xps.arrays(dtype=xps.real_dtypes(), shape=hh.shapes())) +@given(hh.arrays(dtype=xps.real_dtypes(), shape=hh.shapes())) def test_floor(x): out = xp.floor(x) ph.assert_dtype("floor", in_dtype=x.dtype, out_dtype=out.dtype) @@ -1095,7 +1095,7 @@ def test_greater_equal(ctx, data): if api_version >= "2022.12": - @given(xps.arrays(dtype=xps.complex_dtypes(), shape=hh.shapes())) + @given(hh.arrays(dtype=xps.complex_dtypes(), shape=hh.shapes())) def test_imag(x): out = xp.imag(x) ph.assert_dtype("imag", in_dtype=x.dtype, out_dtype=out.dtype, expected=dh.dtype_components[x.dtype]) @@ -1103,7 +1103,7 @@ def test_imag(x): unary_assert_against_refimpl("imag", x, out, operator.attrgetter("imag")) -@given(xps.arrays(dtype=xps.numeric_dtypes(), shape=hh.shapes())) +@given(hh.arrays(dtype=xps.numeric_dtypes(), shape=hh.shapes())) def test_isfinite(x): out = xp.isfinite(x) ph.assert_dtype("isfinite", in_dtype=x.dtype, out_dtype=out.dtype, expected=xp.bool) @@ -1111,7 +1111,7 @@ def test_isfinite(x): unary_assert_against_refimpl("isfinite", x, out, math.isfinite, res_stype=bool) -@given(xps.arrays(dtype=xps.numeric_dtypes(), shape=hh.shapes())) +@given(hh.arrays(dtype=xps.numeric_dtypes(), shape=hh.shapes())) def test_isinf(x): out = xp.isinf(x) ph.assert_dtype("isfinite", in_dtype=x.dtype, out_dtype=out.dtype, expected=xp.bool) @@ -1119,7 +1119,7 @@ def test_isinf(x): unary_assert_against_refimpl("isinf", x, out, math.isinf, res_stype=bool) -@given(xps.arrays(dtype=xps.numeric_dtypes(), shape=hh.shapes())) +@given(hh.arrays(dtype=xps.numeric_dtypes(), shape=hh.shapes())) def test_isnan(x): out = xp.isnan(x) ph.assert_dtype("isnan", in_dtype=x.dtype, out_dtype=out.dtype, expected=xp.bool) @@ -1167,7 +1167,7 @@ def test_less_equal(ctx, data): ) -@given(xps.arrays(dtype=hh.all_floating_dtypes(), shape=hh.shapes())) +@given(hh.arrays(dtype=hh.all_floating_dtypes(), shape=hh.shapes())) def test_log(x): out = xp.log(x) ph.assert_dtype("log", in_dtype=x.dtype, out_dtype=out.dtype) @@ -1177,7 +1177,7 @@ def test_log(x): ) -@given(xps.arrays(dtype=hh.all_floating_dtypes(), shape=hh.shapes())) +@given(hh.arrays(dtype=hh.all_floating_dtypes(), shape=hh.shapes())) def test_log1p(x): out = xp.log1p(x) ph.assert_dtype("log1p", in_dtype=x.dtype, out_dtype=out.dtype) @@ -1187,7 +1187,7 @@ def test_log1p(x): ) -@given(xps.arrays(dtype=hh.all_floating_dtypes(), shape=hh.shapes())) +@given(hh.arrays(dtype=hh.all_floating_dtypes(), shape=hh.shapes())) def test_log2(x): out = xp.log2(x) ph.assert_dtype("log2", in_dtype=x.dtype, out_dtype=out.dtype) @@ -1197,7 +1197,7 @@ def test_log2(x): ) -@given(xps.arrays(dtype=hh.all_floating_dtypes(), shape=hh.shapes())) +@given(hh.arrays(dtype=hh.all_floating_dtypes(), shape=hh.shapes())) def test_log10(x): out = xp.log10(x) ph.assert_dtype("log10", in_dtype=x.dtype, out_dtype=out.dtype) @@ -1229,7 +1229,7 @@ def test_logical_and(x1, x2): ) -@given(xps.arrays(dtype=xp.bool, shape=hh.shapes())) +@given(hh.arrays(dtype=xp.bool, shape=hh.shapes())) def test_logical_not(x): out = xp.logical_not(x) ph.assert_dtype("logical_not", in_dtype=x.dtype, out_dtype=out.dtype) @@ -1344,7 +1344,7 @@ def test_pow(ctx, data): if api_version >= "2022.12": - @given(xps.arrays(dtype=xps.complex_dtypes(), shape=hh.shapes())) + @given(hh.arrays(dtype=xps.complex_dtypes(), shape=hh.shapes())) def test_real(x): out = xp.real(x) ph.assert_dtype("real", in_dtype=x.dtype, out_dtype=out.dtype, expected=dh.dtype_components[x.dtype]) @@ -1370,7 +1370,7 @@ def test_remainder(ctx, data): binary_param_assert_against_refimpl(ctx, left, right, res, "%", operator.mod) -@given(xps.arrays(dtype=xps.numeric_dtypes(), shape=hh.shapes())) +@given(hh.arrays(dtype=xps.numeric_dtypes(), shape=hh.shapes())) def test_round(x): out = xp.round(x) ph.assert_dtype("round", in_dtype=x.dtype, out_dtype=out.dtype) @@ -1378,7 +1378,7 @@ def test_round(x): unary_assert_against_refimpl("round", x, out, round, strict_check=True) -@given(xps.arrays(dtype=xps.numeric_dtypes(), shape=hh.shapes(), elements=finite_kw)) +@given(hh.arrays(dtype=xps.numeric_dtypes(), shape=hh.shapes(), elements=finite_kw)) def test_sign(x): out = xp.sign(x) ph.assert_dtype("sign", in_dtype=x.dtype, out_dtype=out.dtype) @@ -1388,7 +1388,7 @@ def test_sign(x): ) -@given(xps.arrays(dtype=hh.all_floating_dtypes(), shape=hh.shapes())) +@given(hh.arrays(dtype=hh.all_floating_dtypes(), shape=hh.shapes())) def test_sin(x): out = xp.sin(x) ph.assert_dtype("sin", in_dtype=x.dtype, out_dtype=out.dtype) @@ -1396,7 +1396,7 @@ def test_sin(x): unary_assert_against_refimpl("sin", x, out, math.sin) -@given(xps.arrays(dtype=hh.all_floating_dtypes(), shape=hh.shapes())) +@given(hh.arrays(dtype=hh.all_floating_dtypes(), shape=hh.shapes())) def test_sinh(x): out = xp.sinh(x) ph.assert_dtype("sinh", in_dtype=x.dtype, out_dtype=out.dtype) @@ -1404,7 +1404,7 @@ def test_sinh(x): unary_assert_against_refimpl("sinh", x, out, math.sinh) -@given(xps.arrays(dtype=xps.numeric_dtypes(), shape=hh.shapes())) +@given(hh.arrays(dtype=xps.numeric_dtypes(), shape=hh.shapes())) def test_square(x): out = xp.square(x) ph.assert_dtype("square", in_dtype=x.dtype, out_dtype=out.dtype) @@ -1414,7 +1414,7 @@ def test_square(x): ) -@given(xps.arrays(dtype=hh.all_floating_dtypes(), shape=hh.shapes())) +@given(hh.arrays(dtype=hh.all_floating_dtypes(), shape=hh.shapes())) def test_sqrt(x): out = xp.sqrt(x) ph.assert_dtype("sqrt", in_dtype=x.dtype, out_dtype=out.dtype) @@ -1438,7 +1438,7 @@ def test_subtract(ctx, data): binary_param_assert_against_refimpl(ctx, left, right, res, "-", operator.sub) -@given(xps.arrays(dtype=hh.all_floating_dtypes(), shape=hh.shapes())) +@given(hh.arrays(dtype=hh.all_floating_dtypes(), shape=hh.shapes())) def test_tan(x): out = xp.tan(x) ph.assert_dtype("tan", in_dtype=x.dtype, out_dtype=out.dtype) @@ -1446,7 +1446,7 @@ def test_tan(x): unary_assert_against_refimpl("tan", x, out, math.tan) -@given(xps.arrays(dtype=hh.all_floating_dtypes(), shape=hh.shapes())) +@given(hh.arrays(dtype=hh.all_floating_dtypes(), shape=hh.shapes())) def test_tanh(x): out = xp.tanh(x) ph.assert_dtype("tanh", in_dtype=x.dtype, out_dtype=out.dtype) @@ -1454,7 +1454,7 @@ def test_tanh(x): unary_assert_against_refimpl("tanh", x, out, math.tanh) -@given(xps.arrays(dtype=xps.real_dtypes(), shape=xps.array_shapes())) +@given(hh.arrays(dtype=xps.real_dtypes(), shape=xps.array_shapes())) def test_trunc(x): out = xp.trunc(x) ph.assert_dtype("trunc", in_dtype=x.dtype, out_dtype=out.dtype) diff --git a/array_api_tests/test_searching_functions.py b/array_api_tests/test_searching_functions.py index b459499c..987fbb5f 100644 --- a/array_api_tests/test_searching_functions.py +++ b/array_api_tests/test_searching_functions.py @@ -15,7 +15,7 @@ @given( - x=xps.arrays( + x=hh.arrays( dtype=xps.real_dtypes(), shape=hh.shapes(min_dims=1, min_side=1), elements={"allow_nan": False}, @@ -52,7 +52,7 @@ def test_argmax(x, data): @given( - x=xps.arrays( + x=hh.arrays( dtype=xps.real_dtypes(), shape=hh.shapes(min_dims=1, min_side=1), elements={"allow_nan": False}, @@ -87,14 +87,14 @@ def test_argmin(x, data): ph.assert_scalar_equals("argmin", type_=int, idx=out_idx, out=min_i, expected=expected) -@given(xps.arrays(dtype=xps.scalar_dtypes(), shape=())) +@given(hh.arrays(dtype=xps.scalar_dtypes(), shape=())) def test_nonzero_zerodim_error(x): with pytest.raises(Exception): xp.nonzero(x) @pytest.mark.data_dependent_shapes -@given(xps.arrays(dtype=xps.scalar_dtypes(), shape=hh.shapes(min_dims=1, min_side=1))) +@given(hh.arrays(dtype=xps.scalar_dtypes(), shape=hh.shapes(min_dims=1, min_side=1))) def test_nonzero(x): out = xp.nonzero(x) assert len(out) == x.ndim, f"{len(out)=}, but should be {x.ndim=}" @@ -137,9 +137,9 @@ def test_nonzero(x): data=st.data(), ) def test_where(shapes, dtypes, data): - cond = data.draw(xps.arrays(dtype=xp.bool, shape=shapes[0]), label="condition") - x1 = data.draw(xps.arrays(dtype=dtypes[0], shape=shapes[1]), label="x1") - x2 = data.draw(xps.arrays(dtype=dtypes[1], shape=shapes[2]), label="x2") + cond = data.draw(hh.arrays(dtype=xp.bool, shape=shapes[0]), label="condition") + x1 = data.draw(hh.arrays(dtype=dtypes[0], shape=shapes[1]), label="x1") + x2 = data.draw(hh.arrays(dtype=dtypes[1], shape=shapes[2]), label="x2") out = xp.where(cond, x1, x2) diff --git a/array_api_tests/test_set_functions.py b/array_api_tests/test_set_functions.py index e31b63cd..2ad3d852 100644 --- a/array_api_tests/test_set_functions.py +++ b/array_api_tests/test_set_functions.py @@ -16,7 +16,7 @@ pytestmark = [pytest.mark.ci, pytest.mark.data_dependent_shapes] -@given(xps.arrays(dtype=xps.scalar_dtypes(), shape=hh.shapes(min_side=1))) +@given(hh.arrays(dtype=xps.scalar_dtypes(), shape=hh.shapes(min_side=1))) def test_unique_all(x): out = xp.unique_all(x) @@ -116,7 +116,7 @@ def test_unique_all(x): assert nans == expected, f"{nans} NaNs in out, but should be {expected}" -@given(xps.arrays(dtype=xps.scalar_dtypes(), shape=hh.shapes(min_side=1))) +@given(hh.arrays(dtype=xps.scalar_dtypes(), shape=hh.shapes(min_side=1))) def test_unique_counts(x): out = xp.unique_counts(x) assert hasattr(out, "values") @@ -163,7 +163,7 @@ def test_unique_counts(x): assert nans == expected, f"{nans} NaNs in out, but should be {expected}" -@given(xps.arrays(dtype=xps.scalar_dtypes(), shape=hh.shapes(min_side=1))) +@given(hh.arrays(dtype=xps.scalar_dtypes(), shape=hh.shapes(min_side=1))) def test_unique_inverse(x): out = xp.unique_inverse(x) assert hasattr(out, "values") @@ -216,7 +216,7 @@ def test_unique_inverse(x): assert nans == expected, f"{nans} NaNs in out.values, but should be {expected}" -@given(xps.arrays(dtype=xps.scalar_dtypes(), shape=hh.shapes(min_side=1))) +@given(hh.arrays(dtype=xps.scalar_dtypes(), shape=hh.shapes(min_side=1))) def test_unique_values(x): out = xp.unique_values(x) ph.assert_dtype("unique_values", in_dtype=x.dtype, out_dtype=out.dtype) diff --git a/array_api_tests/test_sorting_functions.py b/array_api_tests/test_sorting_functions.py index 67b6ff50..df0610ee 100644 --- a/array_api_tests/test_sorting_functions.py +++ b/array_api_tests/test_sorting_functions.py @@ -33,7 +33,7 @@ def assert_scalar_in_set( # TODO: Test with signed zeros and NaNs (and ignore them somehow) @given( - x=xps.arrays( + x=hh.arrays( dtype=xps.real_dtypes(), shape=hh.shapes(min_dims=1, min_side=1), elements={"allow_nan": False}, @@ -93,7 +93,7 @@ def test_argsort(x, data): # TODO: Test with signed zeros and NaNs (and ignore them somehow) @given( - x=xps.arrays( + x=hh.arrays( dtype=xps.real_dtypes(), shape=hh.shapes(min_dims=1, min_side=1), elements={"allow_nan": False}, diff --git a/array_api_tests/test_special_cases.py b/array_api_tests/test_special_cases.py index 4bc3cc69..d6335293 100644 --- a/array_api_tests/test_special_cases.py +++ b/array_api_tests/test_special_cases.py @@ -263,7 +263,7 @@ class BoundFromDtype(FromDtypeFunc): def __call__(self, dtype: DataType, **kw) -> st.SearchStrategy[float]: assert len(kw) == 0 # sanity check - from_dtype = self.base_func or xps.from_dtype + from_dtype = self.base_func or hh.from_dtype strat = from_dtype(dtype, **self.kwargs) if self.filter_ is not None: strat = strat.filter(self.filter_) @@ -1010,7 +1010,7 @@ def _x1_cond_from_dtype(dtype, **kw) -> st.SearchStrategy[float]: return use_x1_or_x2_strat.flatmap( lambda t: cond_from_dtype(dtype) if t[0] - else xps.from_dtype(dtype) + else hh.from_dtype(dtype) ) def _x2_cond_from_dtype(dtype, **kw) -> st.SearchStrategy[float]: @@ -1018,7 +1018,7 @@ def _x2_cond_from_dtype(dtype, **kw) -> st.SearchStrategy[float]: return use_x1_or_x2_strat.flatmap( lambda t: cond_from_dtype(dtype) if t[1] - else xps.from_dtype(dtype) + else hh.from_dtype(dtype) ) x1_cond_from_dtypes.append( @@ -1214,7 +1214,7 @@ def parse_binary_case_block(case_block: str) -> List[BinaryCase]: @pytest.mark.parametrize("func_name, func, case", unary_params) @given( - x=xps.arrays(dtype=xps.floating_dtypes(), shape=hh.shapes(min_side=1)), + x=hh.arrays(dtype=xps.floating_dtypes(), shape=hh.shapes(min_side=1)), data=st.data(), ) def test_unary(func_name, func, case, x, data): @@ -1302,11 +1302,11 @@ def test_binary(func_name, func, case, x1, x2, data): ) def test_iop(iop_name, iop, case, oneway_dtypes, oneway_shapes, data): x1 = data.draw( - xps.arrays(dtype=oneway_dtypes.result_dtype, shape=oneway_shapes.result_shape), + hh.arrays(dtype=oneway_dtypes.result_dtype, shape=oneway_shapes.result_shape), label="x1", ) x2 = data.draw( - xps.arrays(dtype=oneway_dtypes.input_dtype, shape=oneway_shapes.input_shape), + hh.arrays(dtype=oneway_dtypes.input_dtype, shape=oneway_shapes.input_shape), label="x2", ) @@ -1374,7 +1374,7 @@ def test_empty_arrays(func_name, expected): # TODO: parse docstrings to get exp "func_name", [f.__name__ for f in category_to_funcs["statistical"]] ) @given( - x=xps.arrays(dtype=xps.floating_dtypes(), shape=hh.shapes(min_side=1)), + x=hh.arrays(dtype=xps.floating_dtypes(), shape=hh.shapes(min_side=1)), data=st.data(), ) def test_nan_propagation(func_name, x, data): diff --git a/array_api_tests/test_statistical_functions.py b/array_api_tests/test_statistical_functions.py index 9969fa52..05d64e55 100644 --- a/array_api_tests/test_statistical_functions.py +++ b/array_api_tests/test_statistical_functions.py @@ -26,7 +26,7 @@ def kwarg_dtypes(dtype: DataType) -> st.SearchStrategy[Optional[DataType]]: @given( - x=xps.arrays( + x=hh.arrays( dtype=xps.real_dtypes(), shape=hh.shapes(min_side=1), elements={"allow_nan": False}, @@ -56,7 +56,7 @@ def test_max(x, data): @given( - x=xps.arrays( + x=hh.arrays( dtype=xps.floating_dtypes(), shape=hh.shapes(min_side=1), elements={"allow_nan": False}, @@ -78,7 +78,7 @@ def test_mean(x, data): @given( - x=xps.arrays( + x=hh.arrays( dtype=xps.real_dtypes(), shape=hh.shapes(min_side=1), elements={"allow_nan": False}, @@ -108,7 +108,7 @@ def test_min(x, data): @given( - x=xps.arrays( + x=hh.arrays( dtype=xps.numeric_dtypes(), shape=hh.shapes(min_side=1), elements={"allow_nan": False}, @@ -188,7 +188,7 @@ def test_prod(x, data): @given( - x=xps.arrays( + x=hh.arrays( dtype=xps.floating_dtypes(), shape=hh.shapes(min_side=1), elements={"allow_nan": False}, @@ -224,7 +224,7 @@ def test_std(x, data): @given( - x=xps.arrays( + x=hh.arrays( dtype=xps.numeric_dtypes(), shape=hh.shapes(min_side=1), elements={"allow_nan": False}, @@ -304,7 +304,7 @@ def test_sum(x, data): @given( - x=xps.arrays( + x=hh.arrays( dtype=xps.floating_dtypes(), shape=hh.shapes(min_side=1), elements={"allow_nan": False}, diff --git a/array_api_tests/test_utility_functions.py b/array_api_tests/test_utility_functions.py index ead5c9d2..96da2bdd 100644 --- a/array_api_tests/test_utility_functions.py +++ b/array_api_tests/test_utility_functions.py @@ -13,7 +13,7 @@ @given( - x=xps.arrays(dtype=xps.scalar_dtypes(), shape=hh.shapes(min_side=1)), + x=hh.arrays(dtype=xps.scalar_dtypes(), shape=hh.shapes(min_side=1)), data=st.data(), ) def test_all(x, data): @@ -40,7 +40,7 @@ def test_all(x, data): @given( - x=xps.arrays(dtype=xps.scalar_dtypes(), shape=hh.shapes()), + x=hh.arrays(dtype=xps.scalar_dtypes(), shape=hh.shapes()), data=st.data(), ) def test_any(x, data):