From ecf781739252f9cd6239b40e03b47fd9d385e05f Mon Sep 17 00:00:00 2001 From: Matthew Date: Tue, 4 Jan 2022 11:48:56 +0000 Subject: [PATCH] Filter undefined dtypes, skip test cases where appropiate --- xptests/hypothesis_helpers.py | 8 ++++- xptests/test_array2scalar.py | 10 +++++- xptests/test_elementwise_functions.py | 4 +++ xptests/test_type_promotion.py | 46 +++++++++++---------------- 4 files changed, 39 insertions(+), 29 deletions(-) diff --git a/xptests/hypothesis_helpers.py b/xptests/hypothesis_helpers.py index d8c5f976..4cbb1ab3 100644 --- a/xptests/hypothesis_helpers.py +++ b/xptests/hypothesis_helpers.py @@ -67,7 +67,13 @@ def _dtypes_sorter(dtype_pair: Tuple[DataType, DataType]): key += 1 return key -promotable_dtypes: List[Tuple[DataType, DataType]] = sorted(dh.promotion_table.keys(), key=_dtypes_sorter) +_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: List[Tuple[DataType, DataType]] = sorted(_promotable_dtypes, key=_dtypes_sorter) def mutually_promotable_dtypes( max_size: Optional[int] = 2, diff --git a/xptests/test_array2scalar.py b/xptests/test_array2scalar.py index 55fb2fe3..162d2da3 100644 --- a/xptests/test_array2scalar.py +++ b/xptests/test_array2scalar.py @@ -17,8 +17,16 @@ def make_param(method_name: str, dtype: DataType) -> Param: stype = method_stype[method_name] + if isinstance(dtype, xp._UndefinedStub): + marks = pytest.mark.skip(reason=f"xp.{dtype.name} not defined") + else: + marks = () return pytest.param( - method_name, dtype, stype, id=f"{method_name}({dh.dtype_to_name[dtype]})" + method_name, + dtype, + stype, + id=f"{method_name}({dh.dtype_to_name[dtype]})", + marks=marks, ) diff --git a/xptests/test_elementwise_functions.py b/xptests/test_elementwise_functions.py index 345eec44..b0c2e8f3 100644 --- a/xptests/test_elementwise_functions.py +++ b/xptests/test_elementwise_functions.py @@ -53,6 +53,8 @@ def make_unary_params( elwise_func_name: str, dtypes: Sequence[DataType] ) -> List[UnaryParam]: + if hh.FILTER_UNDEFINED_DTYPES: + dtypes = [d for d in dtypes if not isinstance(d, xp._UndefinedStub)] strat = xps.arrays(dtype=st.sampled_from(dtypes), shape=hh.shapes()) func = getattr(xp, elwise_func_name) op_name = func_to_op[elwise_func_name] @@ -93,6 +95,8 @@ class FuncType(Enum): def make_binary_params( elwise_func_name: str, dtypes: Sequence[DataType] ) -> List[BinaryParam]: + if hh.FILTER_UNDEFINED_DTYPES: + dtypes = [d for d in dtypes if not isinstance(d, xp._UndefinedStub)] dtypes_strat = st.sampled_from(dtypes) def make_param( diff --git a/xptests/test_type_promotion.py b/xptests/test_type_promotion.py index 2fb669e6..9abb6aee 100644 --- a/xptests/test_type_promotion.py +++ b/xptests/test_type_promotion.py @@ -1,9 +1,8 @@ """ https://data-apis.github.io/array-api/latest/API_specification/type_promotion.html """ -import math from collections import defaultdict -from typing import Tuple, Union, List +from typing import List, Tuple, Union import pytest from hypothesis import assume, given, reject @@ -14,9 +13,8 @@ from . import hypothesis_helpers as hh from . import pytest_helpers as ph from . import xps -from .typing import DataType, ScalarType, Param from .function_stubs import elementwise_functions - +from .typing import DataType, Param, ScalarType # TODO: move tests not covering elementwise funcs/ops into standalone tests # result_type, meshgrid, tensordor, vecdot @@ -28,29 +26,6 @@ def test_result_type(dtypes): ph.assert_dtype("result_type", dtypes, out, repr_name="out") -# The number and size of generated arrays is arbitrarily limited to prevent -# meshgrid() running out of memory. -@given( - dtypes=hh.mutually_promotable_dtypes(5, dtypes=dh.numeric_dtypes), - data=st.data(), -) -def test_meshgrid(dtypes, data): - arrays = [] - shapes = data.draw( - hh.mutually_broadcastable_shapes( - len(dtypes), min_dims=1, max_dims=1, max_side=5 - ), - label="shapes", - ) - for i, (dtype, shape) in enumerate(zip(dtypes, shapes), 1): - x = data.draw(xps.arrays(dtype=dtype, shape=shape), label=f"x{i}") - arrays.append(x) - assert math.prod(x.size for x in arrays) <= hh.MAX_ARRAY_SIZE # sanity check - out = xp.meshgrid(*arrays) - for i, x in enumerate(out): - ph.assert_dtype("meshgrid", dtypes, x.dtype, repr_name=f"out[{i}].dtype") - - bitwise_shift_funcs = [ "bitwise_left_shift", "bitwise_right_shift", @@ -78,6 +53,14 @@ def make_id( return f"{func_name}({f_args}) -> {f_out_dtype}" +def mark_stubbed_dtypes(*dtypes): + for dtype in dtypes: + if isinstance(dtype, xp._UndefinedStub): + return pytest.mark.skip(reason=f"xp.{dtype.name} not defined") + else: + return () + + func_params: List[Param[str, Tuple[DataType, ...], DataType]] = [] for func_name in elementwise_functions.__all__: valid_in_dtypes = dh.func_in_dtypes[func_name] @@ -90,6 +73,7 @@ def make_id( (in_dtype,), out_dtype, id=make_id(func_name, (in_dtype,), out_dtype), + marks=mark_stubbed_dtypes(in_dtype, out_dtype), ) func_params.append(p) elif ndtypes == 2: @@ -103,6 +87,7 @@ def make_id( (in_dtype1, in_dtype2), out_dtype, id=make_id(func_name, (in_dtype1, in_dtype2), out_dtype), + marks=mark_stubbed_dtypes(in_dtype1, in_dtype2, out_dtype), ) func_params.append(p) else: @@ -143,6 +128,7 @@ def test_func_promotion(func_name, in_dtypes, out_dtype, data): (dtype1, dtype2), promoted_dtype, id=make_id("", (dtype1, dtype2), promoted_dtype), + marks=mark_stubbed_dtypes(dtype1, dtype2, promoted_dtype), ) promotion_params.append(p) @@ -194,6 +180,7 @@ def test_vecdot(in_dtypes, out_dtype, shapes, data): (in_dtype,), out_dtype, id=make_id(op, (in_dtype,), out_dtype), + marks=mark_stubbed_dtypes(in_dtype, out_dtype), ) op_params.append(p) else: @@ -206,6 +193,7 @@ def test_vecdot(in_dtypes, out_dtype, shapes, data): (in_dtype1, in_dtype2), out_dtype, id=make_id(op, (in_dtype1, in_dtype2), out_dtype), + marks=mark_stubbed_dtypes(in_dtype1, in_dtype2, out_dtype), ) op_params.append(p) # We generate params for abs seperately as it does not have an associated symbol @@ -216,6 +204,7 @@ def test_vecdot(in_dtypes, out_dtype, shapes, data): (in_dtype,), in_dtype, id=make_id("__abs__", (in_dtype,), in_dtype), + marks=mark_stubbed_dtypes(in_dtype), ) op_params.append(p) @@ -263,6 +252,7 @@ def test_op_promotion(op, expr, in_dtypes, out_dtype, data): (in_dtype1, in_dtype2), promoted_dtype, id=make_id(op, (in_dtype1, in_dtype2), promoted_dtype), + marks=mark_stubbed_dtypes(in_dtype1, in_dtype2, promoted_dtype), ) inplace_params.append(p) @@ -301,6 +291,7 @@ def test_inplace_op_promotion(op, expr, in_dtypes, out_dtype, shapes, data): in_stype, out_dtype, id=make_id(op, (in_dtype, in_stype), out_dtype), + marks=mark_stubbed_dtypes(in_dtype, out_dtype), ) op_scalar_params.append(p) @@ -333,6 +324,7 @@ def test_op_scalar_promotion(op, expr, in_dtype, in_stype, out_dtype, data): dtype, in_stype, id=make_id(op, (dtype, in_stype), dtype), + marks=mark_stubbed_dtypes(dtype), ) inplace_scalar_params.append(p)