From 9c44b342a2e25712fc12a24199045011194dcad8 Mon Sep 17 00:00:00 2001 From: Evgeni Burovski Date: Tue, 17 Mar 2026 11:56:15 +0100 Subject: [PATCH] BUG: limit the range of elements in test_{eig,eigvals} Otherwise torch fails to converge if the matrix is too ill-conditioned. Notice 6.7e+111, 6.9e+128, 7e+90 values in this failing example: ``` > res = linalg.eigvals(x) E torch._C._LinAlgError: torch.linalg.eigvals: (Batch element 1): The algorithm failed to converge because the input matrix is ill-conditioned or has too many repeated eigenvalues (error code: 6). E Falsifying example: test_eigvals( E x=tensor([[[ 0.0000e+00, 2.0000e+00, 2.0000e+00, 2.0000e+00, 2.0000e+00, E 2.0000e+00], E [ 2.0000e+00, 2.0000e+00, 2.0000e+00, 2.0000e+00, 2.0000e+00, E 2.0000e+00], E [ 2.0000e+00, 2.0000e+00, 2.0000e+00, 2.0000e+00, 2.0000e+00, E 2.0000e+00], E [ 2.0000e+00, 2.0000e+00, 2.0000e+00, 2.0000e+00, 2.0000e+00, E 2.0000e+00], E [ 2.0000e+00, 2.0000e+00, 2.0000e+00, 2.0000e+00, 2.0000e+00, E 2.0000e+00], E [ 2.0000e+00, 2.0000e+00, 2.0000e+00, 2.0000e+00, 2.0000e+00, E 2.0000e+00]], E E [[ 2.0000e+00, 2.0000e+00, 2.0000e+00, 2.0000e+00, 2.0000e+00, E 2.0000e+00], E [6.7525e+111, 2.0000e+00, 2.0000e+00, 6.9317e+128, 2.0000e+00, E 2.0000e+00], E [ 2.0000e+00, 2.0000e+00, 2.0000e+00, 2.0000e+00, 2.0000e+00, E 2.0000e+00], E [ 2.0000e+00, 0.0000e+00, 2.0000e+00, 2.0000e+00, 7.5592e+90, E 2.0000e+00], E [ 2.0000e+00, 2.0000e+00, 2.0000e+00, 2.0000e+00, 2.0000e+00, E 2.0000e+00], E [ 2.0000e+00, 2.0000e+00, 2.0000e+00, 2.0000e+00, 2.0000e+00, E 2.0000e+00]]], dtype=torch.float64), E ) array_api_tests/test_linalg.py:375: _LinAlgError ``` --- array_api_tests/hypothesis_helpers.py | 13 ++++++++----- array_api_tests/test_linalg.py | 4 ++-- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/array_api_tests/hypothesis_helpers.py b/array_api_tests/hypothesis_helpers.py index 7e8780ae..e870a61c 100644 --- a/array_api_tests/hypothesis_helpers.py +++ b/array_api_tests/hypothesis_helpers.py @@ -331,11 +331,14 @@ def matrix_shapes(draw, stack_shapes=shapes()): square_matrix_shapes = matrix_shapes().filter(lambda shape: shape[-1] == shape[-2]) @composite -def finite_matrices(draw, shape=matrix_shapes()): - return draw(arrays(dtype=floating_dtypes, - shape=shape, - elements=dict(allow_nan=False, - allow_infinity=False))) +def finite_matrices(draw, shape=matrix_shapes(), dtype=floating_dtypes, bound=None): + # for now, only generate elements from (1, bound); cf symmetric_matrices + elements = dict(allow_nan=False, allow_infinity=False) + if bound is not None: + elements.update(**dict(min_value=1, max_value=bound)) + + return draw(arrays(dtype=dtype, shape=shape, elements=elements)) + rtol_shared_matrix_shapes = shared(matrix_shapes()) # Should we set a max_value here? diff --git a/array_api_tests/test_linalg.py b/array_api_tests/test_linalg.py index 61ec8e0e..9fbee39e 100644 --- a/array_api_tests/test_linalg.py +++ b/array_api_tests/test_linalg.py @@ -335,7 +335,7 @@ def test_eigvalsh(x): @pytest.mark.unvectorized @pytest.mark.xp_extension('linalg') @pytest.mark.min_version("2025.12") -@given(x=arrays(dtype=all_floating_dtypes(), shape=square_matrix_shapes)) +@given(x=finite_matrices(dtype=all_floating_dtypes(), shape=square_matrix_shapes, bound=10)) def test_eig(x): res = linalg.eig(x) @@ -370,7 +370,7 @@ def test_eig(x): @pytest.mark.unvectorized @pytest.mark.xp_extension('linalg') @pytest.mark.min_version("2025.12") -@given(x=arrays(dtype=all_floating_dtypes(), shape=square_matrix_shapes)) +@given(x=finite_matrices(dtype=all_floating_dtypes(), shape=square_matrix_shapes, bound=10)) def test_eigvals(x): res = linalg.eigvals(x) expected_dtype = dh.complex_dtype_for(x.dtype)