diff --git a/doc/reference/set.rst b/doc/reference/set.rst index 702e58bb87d5..73719fba74bc 100644 --- a/doc/reference/set.rst +++ b/doc/reference/set.rst @@ -23,7 +23,6 @@ Boolean operations :toctree: generated/ :nosignatures: - in1d intersect1d isin setdiff1d diff --git a/dpnp/tests/third_party/cupy/core_tests/test_elementwise.py b/dpnp/tests/third_party/cupy/core_tests/test_elementwise.py index 729468948209..b2d6e65cd37a 100644 --- a/dpnp/tests/third_party/cupy/core_tests/test_elementwise.py +++ b/dpnp/tests/third_party/cupy/core_tests/test_elementwise.py @@ -1,4 +1,4 @@ -import unittest +from __future__ import annotations import numpy import pytest @@ -12,7 +12,7 @@ from dpnp.tests.third_party.cupy import testing -class TestElementwise(unittest.TestCase): +class TestElementwise: def check_copy(self, dtype, src_id, dst_id): with cuda.Device(src_id): @@ -33,7 +33,7 @@ def test_copy(self, dtype): def test_copy_multigpu_nopeer(self, dtype): if cuda.runtime.deviceCanAccessPeer(0, 1) == 1: pytest.skip("peer access is available") - with self.assertRaises(ValueError): + with pytest.raises(ValueError): self.check_copy(dtype, 0, 1) @pytest.mark.skip("elementwise_copy() argument isn't supported") @@ -74,10 +74,10 @@ def test_copy_orders(self, order): @pytest.mark.skip("`ElementwiseKernel` isn't supported") -class TestElementwiseInvalidShape(unittest.TestCase): +class TestElementwiseInvalidShape: def test_invalid_shape(self): - with self.assertRaisesRegex(ValueError, "Out shape is mismatched"): + with pytest.raises(ValueError, match="Out shape is mismatched"): f = cupy.ElementwiseKernel("T x", "T y", "y += x") x = cupy.arange(12).reshape(3, 4) y = cupy.arange(4) @@ -85,16 +85,15 @@ def test_invalid_shape(self): @pytest.mark.skip("`ElementwiseKernel` isn't supported") -class TestElementwiseInvalidArgument(unittest.TestCase): +class TestElementwiseInvalidArgument: def test_invalid_kernel_name(self): - with self.assertRaisesRegex(ValueError, "Invalid kernel name"): + with pytest.raises(ValueError, match="Invalid kernel name"): cupy.ElementwiseKernel("T x", "", "", "1") -class TestElementwiseType(unittest.TestCase): +class TestElementwiseType: - @testing.with_requires("numpy>=2.0") @testing.for_int_dtypes(no_bool=True) @testing.numpy_cupy_array_equal(accept_error=OverflowError) def test_large_int_upper_1(self, xp, dtype): @@ -105,14 +104,6 @@ def test_large_int_upper_1(self, xp, dtype): @testing.for_int_dtypes(no_bool=True) @testing.numpy_cupy_array_equal(accept_error=OverflowError) def test_large_int_upper_2(self, xp, dtype): - if numpy_version() < "2.0.0": - flag = dtype in [xp.int16, xp.int32, xp.int64, xp.longlong] - if xp.issubdtype(dtype, xp.unsignedinteger) or flag: - pytest.skip("numpy doesn't raise OverflowError") - - if dtype in [xp.int8, xp.intc] and is_win_platform(): - pytest.skip("numpy promotes dtype differently") - a = xp.array([1], dtype=xp.int8) b = xp.iinfo(dtype).max - 1 return a + b @@ -121,48 +112,31 @@ def test_large_int_upper_2(self, xp, dtype): @testing.numpy_cupy_array_equal() def test_large_int_upper_3(self, xp, dtype): if ( - numpy.issubdtype(dtype, numpy.unsignedinteger) - and numpy_version() < "2.0.0" - ): - pytest.skip("numpy promotes dtype differently") - elif ( dtype in (numpy.uint64, numpy.ulonglong) and not has_support_aspect64() ): pytest.skip("no fp64 support") a = xp.array([xp.iinfo(dtype).max], dtype=dtype) - b = numpy.int8(0) + b = xp.int8(0) return a + b @testing.for_int_dtypes(no_bool=True) @testing.numpy_cupy_array_equal() def test_large_int_upper_4(self, xp, dtype): if ( - numpy.issubdtype(dtype, numpy.unsignedinteger) - and numpy_version() < "2.0.0" - ): - pytest.skip("numpy promotes dtype differently") - elif ( dtype in (numpy.uint64, numpy.ulonglong) and not has_support_aspect64() ): pytest.skip("no fp64 support") a = xp.array([xp.iinfo(dtype).max - 1], dtype=dtype) - b = numpy.int8(1) + b = xp.int8(1) return a + b @testing.for_int_dtypes(no_bool=True) @testing.numpy_cupy_array_equal(accept_error=OverflowError) def test_large_int_lower_1(self, xp, dtype): - if numpy_version() < "2.0.0": - if dtype in [xp.int16, xp.int32, xp.int64, xp.longlong]: - pytest.skip("numpy doesn't raise OverflowError") - - if dtype in [xp.int8, xp.intc] and is_win_platform(): - pytest.skip("numpy promotes dtype differently") - a = xp.array([0], dtype=xp.int8) b = xp.iinfo(dtype).min return a + b @@ -170,13 +144,6 @@ def test_large_int_lower_1(self, xp, dtype): @testing.for_int_dtypes(no_bool=True) @testing.numpy_cupy_array_equal(accept_error=OverflowError) def test_large_int_lower_2(self, xp, dtype): - if numpy_version() < "2.0.0": - if dtype in [xp.int16, xp.int32, xp.int64, xp.longlong]: - pytest.skip("numpy doesn't raise OverflowError") - - if dtype in [xp.int8, xp.intc] and is_win_platform(): - pytest.skip("numpy promotes dtype differently") - a = xp.array([-1], dtype=xp.int8) b = xp.iinfo(dtype).min + 1 return a + b @@ -185,18 +152,13 @@ def test_large_int_lower_2(self, xp, dtype): @testing.numpy_cupy_array_equal() def test_large_int_lower_3(self, xp, dtype): if ( - numpy.issubdtype(dtype, numpy.unsignedinteger) - and numpy_version() < "2.0.0" - ): - pytest.skip("numpy promotes dtype differently") - elif ( dtype in (numpy.uint64, numpy.ulonglong) and not has_support_aspect64() ): pytest.skip("no fp64 support") a = xp.array([xp.iinfo(dtype).min], dtype=dtype) - b = numpy.int8(0) + b = xp.int8(0) return a + b @testing.for_int_dtypes(no_bool=True) @@ -209,5 +171,5 @@ def test_large_int_lower_4(self, xp, dtype): pytest.skip("no fp64 support") a = xp.array([xp.iinfo(dtype).min + 1], dtype=dtype) - b = numpy.int8(-1) + b = xp.int8(-1) return a + b diff --git a/dpnp/tests/third_party/cupy/core_tests/test_function.py b/dpnp/tests/third_party/cupy/core_tests/test_function.py index 5480cdf6e126..1fa4fdbac46a 100644 --- a/dpnp/tests/third_party/cupy/core_tests/test_function.py +++ b/dpnp/tests/third_party/cupy/core_tests/test_function.py @@ -1,7 +1,6 @@ from __future__ import annotations -import unittest - +import numpy import pytest import dpnp as cupy @@ -23,7 +22,7 @@ def _compile_func(kernel_name, code): return mod.get_function(kernel_name) -class TestFunction(unittest.TestCase): +class TestFunction: def test_python_scalar(self): code = """ diff --git a/dpnp/tests/third_party/cupy/core_tests/test_include.py b/dpnp/tests/third_party/cupy/core_tests/test_include.py index a45d2b40cbf4..1e738f7977bf 100644 --- a/dpnp/tests/third_party/cupy/core_tests/test_include.py +++ b/dpnp/tests/third_party/cupy/core_tests/test_include.py @@ -1,5 +1,6 @@ +from __future__ import annotations + import os -from unittest import mock import pytest @@ -71,22 +72,23 @@ def test_nvcc(self): _code_nvcc, options=options, arch=arch ) - def test_nvrtc(self): + def test_nvrtc(self, monkeypatch): cuda_ver = cupy.cuda.runtime.runtimeGetVersion() options = self._get_options() for arch in self._get_cuda_archs(): - with mock.patch( - "cupy.cuda.compiler._get_arch_for_options_for_nvrtc", + monkeypatch.setattr( + cupy.cuda.compiler, + "_get_arch_for_options_for_nvrtc", lambda _: (f"-arch=compute_{arch}", "ptx"), - ): + ) + cupy.cuda.compiler.compile_using_nvrtc(_code_nvrtc, options=options) + + if cuda_ver >= 11010: + monkeypatch.setattr( + cupy.cuda.compiler, + "_get_arch_for_options_for_nvrtc", + lambda _: (f"-arch=sm_{arch}", "cubin"), + ) cupy.cuda.compiler.compile_using_nvrtc( _code_nvrtc, options=options ) - if cuda_ver >= 11010: - with mock.patch( - "cupy.cuda.compiler._get_arch_for_options_for_nvrtc", - lambda _: (f"-arch=sm_{arch}", "cubin"), - ): - cupy.cuda.compiler.compile_using_nvrtc( - _code_nvrtc, options=options - ) diff --git a/dpnp/tests/third_party/cupy/core_tests/test_ndarray_complex_ops.py b/dpnp/tests/third_party/cupy/core_tests/test_ndarray_complex_ops.py index 3acebaaeb3ad..a2fe0e2f256c 100644 --- a/dpnp/tests/third_party/cupy/core_tests/test_ndarray_complex_ops.py +++ b/dpnp/tests/third_party/cupy/core_tests/test_ndarray_complex_ops.py @@ -1,4 +1,4 @@ -import unittest +from __future__ import annotations import numpy import pytest @@ -7,7 +7,7 @@ from dpnp.tests.third_party.cupy import testing -class TestConj(unittest.TestCase): +class TestConj: @testing.for_all_dtypes() @testing.numpy_cupy_array_almost_equal() @@ -38,7 +38,7 @@ def test_conjugate_pass(self, xp, dtype): return y -class TestAngle(unittest.TestCase): +class TestAngle: # For dtype=int8, uint8, NumPy returns float16, but dpnp returns float32 # so type_check=False @@ -49,7 +49,7 @@ def test_angle(self, xp, dtype): return xp.angle(x) -class TestRealImag(unittest.TestCase): +class TestRealImag: @testing.for_all_dtypes() @testing.numpy_cupy_array_almost_equal(accept_error=False) @@ -157,7 +157,7 @@ def test_imag_inplace(self, dtype): assert cupy.all(x == expected) -class TestScalarConversion(unittest.TestCase): +class TestScalarConversion: @testing.for_all_dtypes() def test_scalar_conversion(self, dtype): diff --git a/dpnp/tests/third_party/cupy/core_tests/test_ndarray_contiguity.py b/dpnp/tests/third_party/cupy/core_tests/test_ndarray_contiguity.py index 7331105f3b7b..f28364481c9c 100644 --- a/dpnp/tests/third_party/cupy/core_tests/test_ndarray_contiguity.py +++ b/dpnp/tests/third_party/cupy/core_tests/test_ndarray_contiguity.py @@ -1,9 +1,9 @@ -import unittest +from __future__ import annotations from dpnp.tests.third_party.cupy import testing -class TestArrayContiguity(unittest.TestCase): +class TestArrayContiguity: def test_is_contiguous(self): a = testing.shaped_arange((2, 3, 4)) diff --git a/dpnp/tests/third_party/cupy/core_tests/test_ndarray_conversion.py b/dpnp/tests/third_party/cupy/core_tests/test_ndarray_conversion.py index efd888094c94..4643dd2a60bc 100644 --- a/dpnp/tests/third_party/cupy/core_tests/test_ndarray_conversion.py +++ b/dpnp/tests/third_party/cupy/core_tests/test_ndarray_conversion.py @@ -1,56 +1,69 @@ from __future__ import annotations -import unittest - import numpy import pytest import dpnp as cupy + +# from cupy.cuda import runtime from dpnp.tests.third_party.cupy import testing -@testing.parameterize( - {"shape": ()}, - {"shape": (1,)}, - {"shape": (1, 1, 1)}, +@pytest.mark.parametrize( + "shape", + [ + (), + (1,), + (1, 1, 1), + ], ) -class TestNdarrayItem(unittest.TestCase): +class TestNdarrayItem: @testing.for_all_dtypes() @testing.numpy_cupy_equal() - def test_item(self, xp, dtype): - a = xp.full(self.shape, 3, dtype=dtype) + def test_item(self, xp, dtype, shape): + a = xp.full(shape, 3, dtype=dtype) return a.item() -@testing.parameterize( - {"shape": (0,)}, - {"shape": (2, 3)}, - {"shape": (1, 0, 1)}, +@pytest.mark.parametrize( + "shape", + [ + (0,), + (2, 3), + (1, 0, 1), + ], ) -class TestNdarrayItemRaise(unittest.TestCase): +class TestNdarrayItemRaise: - def test_item(self): + def test_item(self, shape): for xp in (numpy, cupy): - a = testing.shaped_arange(self.shape, xp, xp.float32) + a = testing.shaped_arange(shape, xp, xp.float32) with pytest.raises(ValueError): a.item() -@testing.parameterize( - {"shape": ()}, - {"shape": (1,)}, - {"shape": (2, 3)}, - {"shape": (2, 3), "order": "C"}, - {"shape": (2, 3), "order": "F"}, +@pytest.mark.parametrize( + "shape, order", + [ + ((), None), + ((1,), None), + ((2, 3), None), + ((2, 3), "C"), + ((2, 3), "F"), + ], ) -class TestNdarrayToBytes(unittest.TestCase): +class TestNdarrayToBytes: @testing.for_all_dtypes() @testing.numpy_cupy_equal() - def test_item(self, xp, dtype): - a = testing.shaped_arange(self.shape, xp, dtype) - if hasattr(self, "order"): - return a.tobytes(self.order) + def test_item(self, xp, dtype, shape, order): + # if runtime.is_hip and ( + # shape == (1,) or (shape == (2, 3) and order is None) + # ): + # pytest.xfail("ROCm/HIP may have a bug") + a = testing.shaped_arange(shape, xp, dtype) + if order is not None: + return a.tobytes(order) else: return a.tobytes() diff --git a/dpnp/tests/third_party/cupy/core_tests/test_ndarray_owndata.py b/dpnp/tests/third_party/cupy/core_tests/test_ndarray_owndata.py index dee220ab01fa..c447f52a8e39 100644 --- a/dpnp/tests/third_party/cupy/core_tests/test_ndarray_owndata.py +++ b/dpnp/tests/third_party/cupy/core_tests/test_ndarray_owndata.py @@ -1,4 +1,4 @@ -import unittest +from __future__ import annotations import pytest @@ -7,9 +7,9 @@ pytest.skip("owndata attribute is not supported", allow_module_level=True) -class TestArrayOwndata(unittest.TestCase): +class TestArrayOwndata: - def setUp(self): + def setup_method(self): self.a = _core.ndarray(()) def test_original_array(self): diff --git a/dpnp/tests/third_party/cupy/core_tests/test_scan.py b/dpnp/tests/third_party/cupy/core_tests/test_scan.py index 15eb0a653b16..111e4d5490f3 100644 --- a/dpnp/tests/third_party/cupy/core_tests/test_scan.py +++ b/dpnp/tests/third_party/cupy/core_tests/test_scan.py @@ -1,4 +1,4 @@ -import unittest +from __future__ import annotations import pytest @@ -11,12 +11,11 @@ pytest.skip("scan() is not supported", allow_module_level=True) -class TestScan(unittest.TestCase): +class TestScan: @testing.for_all_dtypes() def test_scan(self, dtype): element_num = 10000 - if dtype in {cupy.int8, cupy.uint8, cupy.float16}: element_num = 100 @@ -27,7 +26,7 @@ def test_scan(self, dtype): testing.assert_array_equal(prefix_sum, expect) def test_check_1d_array(self): - with self.assertRaises(TypeError): + with pytest.raises(TypeError): a = cupy.zeros((2, 2)) scan(a) @@ -43,7 +42,6 @@ def test_multi_gpu(self): @testing.for_all_dtypes() def test_scan_out(self, dtype): element_num = 10000 - if dtype in {cupy.int8, cupy.uint8, cupy.float16}: element_num = 100 diff --git a/dpnp/tests/third_party/cupy/core_tests/test_syncdetect.py b/dpnp/tests/third_party/cupy/core_tests/test_syncdetect.py index 57f64a7b1661..855433f53e3d 100644 --- a/dpnp/tests/third_party/cupy/core_tests/test_syncdetect.py +++ b/dpnp/tests/third_party/cupy/core_tests/test_syncdetect.py @@ -1,4 +1,4 @@ -import unittest +from __future__ import annotations import pytest @@ -9,8 +9,7 @@ pytest.skip("get() method is not supported", allow_module_level=True) -class TestSyncDetect(unittest.TestCase): - +class TestSyncDetect: def test_disallowed(self): a = cupy.array([2, 3]) with cupyx.allow_synchronize(False): diff --git a/dpnp/tests/third_party/cupy/random_tests/test_distributions.py b/dpnp/tests/third_party/cupy/random_tests/test_distributions.py index ebed860fd294..b72edc4c90c9 100644 --- a/dpnp/tests/third_party/cupy/random_tests/test_distributions.py +++ b/dpnp/tests/third_party/cupy/random_tests/test_distributions.py @@ -1,3 +1,7 @@ +from __future__ import annotations + +import concurrent.futures + import numpy import pytest @@ -1000,3 +1004,113 @@ class TestDistributionsZipf(RandomDistributionsTestCase): def test_zipf(self, a_dtype): a = numpy.full(self.a_shape, 2, dtype=a_dtype) self.check_distribution("zipf", {"a": a}) + + +@pytest.mark.parametrize( + "dist_func", + [ + # pytest.param(lambda rs: rs.beta(3.0, 3.0, size=10), id="beta"), + # pytest.param(lambda rs: rs.binomial(5, 0.5, size=10), id="binomial"), + # pytest.param(lambda rs: rs.chisquare(5.0, size=10), id="chisquare"), + # pytest.param( + # lambda rs: rs.dirichlet([1.0, 1.0, 1.0], size=10), id="dirichlet" + # ), + # pytest.param(lambda rs: rs.exponential(1.0, size=10), id="exponential"), + # pytest.param(lambda rs: rs.f(5.0, 5.0, size=10), id="f"), + # pytest.param(lambda rs: rs.gamma(5.0, 1.0, size=10), id="gamma"), + # pytest.param(lambda rs: rs.geometric(0.5, size=10), id="geometric"), + # pytest.param(lambda rs: rs.gumbel(0.0, 1.0, size=10), id="gumbel"), + # pytest.param( + # lambda rs: rs.hypergeometric(10, 10, 5, size=10), + # id="hypergeometric", + # ), + # pytest.param(lambda rs: rs.laplace(0.0, 1.0, size=10), id="laplace"), + # pytest.param(lambda rs: rs.logistic(0.0, 1.0, size=10), id="logistic"), + # pytest.param( + # lambda rs: rs.lognormal(0.0, 1.0, size=10), id="lognormal" + # ), + # pytest.param(lambda rs: rs.logseries(0.5, size=10), id="logseries"), + # pytest.param( + # lambda rs: rs.multivariate_normal( + # [0.0, 0.0], [[1.0, 0.0], [0.0, 1.0]], size=10 + # ), + # id="multivariate_normal", + # ), + # pytest.param( + # lambda rs: rs.negative_binomial(5, 0.5, size=10), + # id="negative_binomial", + # ), + # pytest.param( + # lambda rs: rs.noncentral_chisquare(5.0, 1.0, size=10), + # id="noncentral_chisquare", + # ), + # pytest.param( + # lambda rs: rs.noncentral_f(5.0, 5.0, 1.0, size=10), + # id="noncentral_f", + # ), + pytest.param(lambda rs: rs.normal(0.0, 1.0, size=10), id="normal"), + # pytest.param(lambda rs: rs.pareto(3.0, size=10), id="pareto"), + # pytest.param(lambda rs: rs.poisson(5.0, size=10), id="poisson"), + # pytest.param(lambda rs: rs.power(0.5, size=10), id="power"), + pytest.param(lambda rs: rs.random_sample(size=10), id="random_sample"), + # pytest.param(lambda rs: rs.rayleigh(1.0, size=10), id="rayleigh"), + # pytest.param( + # lambda rs: rs.standard_cauchy(size=10), id="standard_cauchy" + # ), + # pytest.param( + # lambda rs: rs.standard_exponential(size=10), + # id="standard_exponential", + # ), + # pytest.param( + # lambda rs: rs.standard_gamma(5.0, size=10), id="standard_gamma" + # ), + pytest.param( + lambda rs: rs.standard_normal(size=10), id="standard_normal" + ), + # pytest.param(lambda rs: rs.standard_t(5.0, size=10), id="standard_t"), + # pytest.param( + # lambda rs: rs.triangular(-1.0, 0.0, 2.0, size=10), id="triangular" + # ), + pytest.param(lambda rs: rs.uniform(0.0, 1.0, size=10), id="uniform"), + # pytest.param(lambda rs: rs.vonmises(0.0, 1.0, size=10), id="vonmises"), + # pytest.param(lambda rs: rs.wald(3.0, 3.0, size=10), id="wald"), + # pytest.param(lambda rs: rs.weibull(1.0, size=10), id="weibull"), + # pytest.param(lambda rs: rs.zipf(2.0, size=10), id="zipf"), + # # Integers and shuffles + # pytest.param(lambda rs: rs.choice(100, size=10), id="choice-number"), + # pytest.param( + # lambda rs: rs.choice(cupy.arange(10), size=10), id="choice-array" + # ), + # pytest.param(lambda rs: rs.tomaxint(size=10), id="tomaxint"), + # # skipping shuffle (doesn't fit lambda and uses permutation) + # pytest.param( + # lambda rs: rs.permutation(cupy.arange(20)), id="permutation" + # ), + pytest.param(lambda rs: rs.randint(0, 10, size=10), id="randint"), + pytest.param(lambda rs: rs.randn(10), id="randn"), + ], +) +# @pytest.mark.thread_unsafe("already multi-threaded") +def test_multithreaded(dist_func): + n_threads = 10 + rs = cupy.random.RandomState(seed=0) + + def call_distribution(_): + return dist_func(rs) + + # Run distribution in multiple threads with shared RandomState + with concurrent.futures.ThreadPoolExecutor( + max_workers=n_threads + ) as executor: + results = executor.map(call_distribution, range(n_threads)) + + results = list(results) + + # Check that all results are finite + for result in results: + assert cupy.isfinite(result).all() + + # Check that all results are different from each other + for i in range(len(results)): + for j in range(i + 1, len(results)): + assert not cupy.array_equal(results[i], results[j]) diff --git a/dpnp/tests/third_party/cupy/random_tests/test_generator.py b/dpnp/tests/third_party/cupy/random_tests/test_generator.py index abb58df07af9..23a86d88d8ff 100644 --- a/dpnp/tests/third_party/cupy/random_tests/test_generator.py +++ b/dpnp/tests/third_party/cupy/random_tests/test_generator.py @@ -917,7 +917,7 @@ def test_dtype_shape(self): if isinstance(self.a, numpy.ndarray): expected_dtype = "float" else: - expected_dtype = "long" + expected_dtype = "int64" assert v.dtype == expected_dtype assert v.shape == expected_shape diff --git a/dpnp/tests/third_party/cupy/statistics_tests/test_order.py b/dpnp/tests/third_party/cupy/statistics_tests/test_order.py index 58eb7999acc7..f35617e18619 100644 --- a/dpnp/tests/third_party/cupy/statistics_tests/test_order.py +++ b/dpnp/tests/third_party/cupy/statistics_tests/test_order.py @@ -28,6 +28,25 @@ ) +@pytest.fixture +def _fix_gamma(monkeypatch): + if numpy.__version__ == "2.4.1": + # NumPy 2.4.0 had a surprisingly large change, but I (seberg) + # incorrectly undid the change, making things maybe worse... + # this fixes that... + # See also https://github.com/numpy/numpy/pull/30710 + def _get_gamma(virtual_indexes, previous_indexes, method): + gamma = numpy.asanyarray(virtual_indexes - previous_indexes) + gamma = method["fix_gamma"](gamma, virtual_indexes) + return numpy.asanyarray(gamma, dtype=virtual_indexes.dtype) + + monkeypatch.setattr( + numpy.lib._function_base_impl, "_get_gamma", _get_gamma + ) + + yield + + def for_all_methods(name="method"): return pytest.mark.parametrize(name, _all_methods) @@ -83,6 +102,7 @@ def test_quantile_unexpected_method(self, dtype): @pytest.mark.skip("dpnp.quantile() is not implemented yet") +@pytest.mark.usefixtures("_fix_gamma") @testing.with_requires("numpy>=2.0") @for_all_methods() class TestQuantileMethods: