Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BUG: failing scipy tests on i686 architecture #17213

Open
psimovec opened this issue Oct 12, 2022 · 2 comments
Open

BUG: failing scipy tests on i686 architecture #17213

psimovec opened this issue Oct 12, 2022 · 2 comments
Labels
defect A clear bug or issue that prevents SciPy from being installed or used as expected scipy.sparse.linalg

Comments

@psimovec
Copy link

psimovec commented Oct 12, 2022

Describe your issue.

I want to make latest scipy version 1.9.2 available on Fedora, but 3 tests are failing specifically on i686 architecture.
There were the same tests fails on 1.9.1, and no such fails on 1.8.1.

build.log in case I missed any important information: https://kojipkgs.fedoraproject.org//work/tasks/1373/92881373/build.log

Reproducing Code Example

=========================== short test summary info ============================
FAILED scipy/sparse/linalg/tests/test_propack.py::test_examples[False-double]
FAILED scipy/sparse/linalg/tests/test_propack.py::test_examples[True-single]
FAILED scipy/sparse/tests/test_base.py::TestCSR::test_fancy_assignment_dtypes

Error message

=================================== FAILURES ===================================
_________________________ test_examples[False-double] __________________________
[gw1] linux -- Python 3.11.0 /usr/bin/python3
precision = 'double', irl = False
    @pytest.mark.parametrize('precision', _dtype_testing)
    @pytest.mark.parametrize('irl', (False, True))
    def test_examples(precision, irl):
        # Note: atol for complex8 bumped from 1e-4 to 1e-3 because of test failures
        # with BLIS, Netlib, and MKL+AVX512 - see
        # https://github.com/conda-forge/scipy-feedstock/pull/198#issuecomment-999180432
        atol = {
            'single': 1.3e-4,
            'double': 1e-9,
            'complex8': 1e-3,
            'complex16': 1e-9,
        }[precision]
    
        path_prefix = os.path.dirname(__file__)
        # Test matrices from `illc1850.coord` and `mhd1280b.cua` distributed with
        # PROPACK 2.1: http://sun.stanford.edu/~rmunk/PROPACK/
        relative_path = "propack_test_data.npz"
        filename = os.path.join(path_prefix, relative_path)
        data = np.load(filename, allow_pickle=True)
    
        dtype = _dtype_map[precision]
        if precision in {'single', 'double'}:
            A = data['A_real'].item().astype(dtype)
        elif precision in {'complex8', 'complex16'}:
            A = data['A_complex'].item().astype(dtype)
    
        k = 200
        u, s, vh, _ = _svdp(A, k, irl_mode=irl, random_state=0)
    
        # complex example matrix has many repeated singular values, so check only
        # beginning non-repeated singular vectors to avoid permutations
        sv_check = 27 if precision in {'complex8', 'complex16'} else k
        u = u[:, :sv_check]
        vh = vh[:sv_check, :]
        s = s[:sv_check]
    
        # Check orthogonality of singular vectors
        assert_allclose(np.eye(u.shape[1]), u.conj().T @ u, atol=atol)
        assert_allclose(np.eye(vh.shape[0]), vh @ vh.conj().T, atol=atol)
    
        # Ensure the norm of the difference between the np.linalg.svd and
        # PROPACK reconstructed matrices is small
        u3, s3, vh3 = np.linalg.svd(A.todense())
        u3 = u3[:, :sv_check]
        s3 = s3[:sv_check]
        vh3 = vh3[:sv_check, :]
        A3 = u3 @ np.diag(s3) @ vh3
        recon = u @ np.diag(s) @ vh
>       assert_allclose(np.linalg.norm(A3 - recon), 0, atol=atol)
E       AssertionError: 
E       Not equal to tolerance rtol=1e-07, atol=1e-09
E       
E       Mismatched elements: 1 / 1 (100%)
E       Max absolute difference: 1.84554848
E       Max relative difference: inf
E        x: array(1.845548)
E        y: array(0)
scipy/sparse/linalg/tests/test_propack.py:166: AssertionError
__________________________ test_examples[True-single] __________________________
[gw1] linux -- Python 3.11.0 /usr/bin/python3
precision = 'single', irl = True
    @pytest.mark.parametrize('precision', _dtype_testing)
    @pytest.mark.parametrize('irl', (False, True))
    def test_examples(precision, irl):
        # Note: atol for complex8 bumped from 1e-4 to 1e-3 because of test failures
        # with BLIS, Netlib, and MKL+AVX512 - see
        # https://github.com/conda-forge/scipy-feedstock/pull/198#issuecomment-999180432
        atol = {
            'single': 1.3e-4,
            'double': 1e-9,
            'complex8': 1e-3,
            'complex16': 1e-9,
        }[precision]
    
        path_prefix = os.path.dirname(__file__)
        # Test matrices from `illc1850.coord` and `mhd1280b.cua` distributed with
        # PROPACK 2.1: http://sun.stanford.edu/~rmunk/PROPACK/
        relative_path = "propack_test_data.npz"
        filename = os.path.join(path_prefix, relative_path)
        data = np.load(filename, allow_pickle=True)
    
        dtype = _dtype_map[precision]
        if precision in {'single', 'double'}:
            A = data['A_real'].item().astype(dtype)
        elif precision in {'complex8', 'complex16'}:
            A = data['A_complex'].item().astype(dtype)
    
        k = 200
        u, s, vh, _ = _svdp(A, k, irl_mode=irl, random_state=0)
    
        # complex example matrix has many repeated singular values, so check only
        # beginning non-repeated singular vectors to avoid permutations
        sv_check = 27 if precision in {'complex8', 'complex16'} else k
        u = u[:, :sv_check]
        vh = vh[:sv_check, :]
        s = s[:sv_check]
    
        # Check orthogonality of singular vectors
        assert_allclose(np.eye(u.shape[1]), u.conj().T @ u, atol=atol)
        assert_allclose(np.eye(vh.shape[0]), vh @ vh.conj().T, atol=atol)
    
        # Ensure the norm of the difference between the np.linalg.svd and
        # PROPACK reconstructed matrices is small
        u3, s3, vh3 = np.linalg.svd(A.todense())
        u3 = u3[:, :sv_check]
        s3 = s3[:sv_check]
        vh3 = vh3[:sv_check, :]
        A3 = u3 @ np.diag(s3) @ vh3
        recon = u @ np.diag(s) @ vh
>       assert_allclose(np.linalg.norm(A3 - recon), 0, atol=atol)
E       AssertionError: 
E       Not equal to tolerance rtol=1e-07, atol=0.00013
E       
E       Mismatched elements: 1 / 1 (100%)
E       Max absolute difference: 1.84415603
E       Max relative difference: inf
E        x: array(1.844156, dtype=float32)
E        y: array(0)
scipy/sparse/linalg/tests/test_propack.py:166: AssertionError
_____________________ TestCSR.test_fancy_assignment_dtypes _____________________
[gw1] linux -- Python 3.11.0 /usr/bin/python3
actual = (nan+nanj), desired = (2+0j), err_msg = '', verbose = True
    def assert_equal(actual, desired, err_msg='', verbose=True):
        """
        Raises an AssertionError if two objects are not equal.
    
        Given two objects (scalars, lists, tuples, dictionaries or numpy arrays),
        check that all elements of these objects are equal. An exception is raised
        at the first conflicting values.
    
        When one of `actual` and `desired` is a scalar and the other is array_like,
        the function checks that each element of the array_like object is equal to
        the scalar.
    
        This function handles NaN comparisons as if NaN was a "normal" number.
        That is, AssertionError is not raised if both objects have NaNs in the same
        positions.  This is in contrast to the IEEE standard on NaNs, which says
        that NaN compared to anything must return False.
    
        Parameters
        ----------
        actual : array_like
            The object to check.
        desired : array_like
            The expected object.
        err_msg : str, optional
            The error message to be printed in case of failure.
        verbose : bool, optional
            If True, the conflicting values are appended to the error message.
    
        Raises
        ------
        AssertionError
            If actual and desired are not equal.
    
        Examples
        --------
        >>> np.testing.assert_equal([4,5], [4,6])
        Traceback (most recent call last):
            ...
        AssertionError:
        Items are not equal:
        item=1
         ACTUAL: 5
         DESIRED: 6
    
        The following comparison does not raise an exception.  There are NaNs
        in the inputs, but they are in the same positions.
    
        >>> np.testing.assert_equal(np.array([1.0, 2.0, np.nan]), [1, 2, np.nan])
    
        """
        __tracebackhide__ = True  # Hide traceback for py.test
        if isinstance(desired, dict):
            if not isinstance(actual, dict):
                raise AssertionError(repr(type(actual)))
            assert_equal(len(actual), len(desired), err_msg, verbose)
            for k, i in desired.items():
                if k not in actual:
                    raise AssertionError(repr(k))
                assert_equal(actual[k], desired[k], f'key={k!r}\n{err_msg}',
                             verbose)
            return
        if isinstance(desired, (list, tuple)) and isinstance(actual, (list, tuple)):
            assert_equal(len(actual), len(desired), err_msg, verbose)
            for k in range(len(desired)):
                assert_equal(actual[k], desired[k], f'item={k!r}\n{err_msg}',
                             verbose)
            return
        from numpy.core import ndarray, isscalar, signbit
        from numpy.lib import iscomplexobj, real, imag
        if isinstance(actual, ndarray) or isinstance(desired, ndarray):
            return assert_array_equal(actual, desired, err_msg, verbose)
        msg = build_err_msg([actual, desired], err_msg, verbose=verbose)
    
        # Handle complex numbers: separate into real/imag to handle
        # nan/inf/negative zero correctly
        # XXX: catch ValueError for subclasses of ndarray where iscomplex fail
        try:
            usecomplex = iscomplexobj(actual) or iscomplexobj(desired)
        except (ValueError, TypeError):
            usecomplex = False
    
        if usecomplex:
            if iscomplexobj(actual):
                actualr = real(actual)
                actuali = imag(actual)
            else:
                actualr = actual
                actuali = 0
            if iscomplexobj(desired):
                desiredr = real(desired)
                desiredi = imag(desired)
            else:
                desiredr = desired
                desiredi = 0
            try:
>               assert_equal(actualr, desiredr)
/usr/lib/python3.11/site-packages/numpy/testing/_private/utils.py:370: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
actual = nan, desired = 2.0, err_msg = '', verbose = True
    def assert_equal(actual, desired, err_msg='', verbose=True):
        """
        Raises an AssertionError if two objects are not equal.
    
        Given two objects (scalars, lists, tuples, dictionaries or numpy arrays),
        check that all elements of these objects are equal. An exception is raised
        at the first conflicting values.
    
        When one of `actual` and `desired` is a scalar and the other is array_like,
        the function checks that each element of the array_like object is equal to
        the scalar.
    
        This function handles NaN comparisons as if NaN was a "normal" number.
        That is, AssertionError is not raised if both objects have NaNs in the same
        positions.  This is in contrast to the IEEE standard on NaNs, which says
        that NaN compared to anything must return False.
    
        Parameters
        ----------
        actual : array_like
            The object to check.
        desired : array_like
            The expected object.
        err_msg : str, optional
            The error message to be printed in case of failure.
        verbose : bool, optional
            If True, the conflicting values are appended to the error message.
    
        Raises
        ------
        AssertionError
            If actual and desired are not equal.
    
        Examples
        --------
        >>> np.testing.assert_equal([4,5], [4,6])
        Traceback (most recent call last):
            ...
        AssertionError:
        Items are not equal:
        item=1
         ACTUAL: 5
         DESIRED: 6
    
        The following comparison does not raise an exception.  There are NaNs
        in the inputs, but they are in the same positions.
    
        >>> np.testing.assert_equal(np.array([1.0, 2.0, np.nan]), [1, 2, np.nan])
    
        """
        __tracebackhide__ = True  # Hide traceback for py.test
        if isinstance(desired, dict):
            if not isinstance(actual, dict):
                raise AssertionError(repr(type(actual)))
            assert_equal(len(actual), len(desired), err_msg, verbose)
            for k, i in desired.items():
                if k not in actual:
                    raise AssertionError(repr(k))
                assert_equal(actual[k], desired[k], f'key={k!r}\n{err_msg}',
                             verbose)
            return
        if isinstance(desired, (list, tuple)) and isinstance(actual, (list, tuple)):
            assert_equal(len(actual), len(desired), err_msg, verbose)
            for k in range(len(desired)):
                assert_equal(actual[k], desired[k], f'item={k!r}\n{err_msg}',
                             verbose)
            return
        from numpy.core import ndarray, isscalar, signbit
        from numpy.lib import iscomplexobj, real, imag
        if isinstance(actual, ndarray) or isinstance(desired, ndarray):
            return assert_array_equal(actual, desired, err_msg, verbose)
        msg = build_err_msg([actual, desired], err_msg, verbose=verbose)
    
        # Handle complex numbers: separate into real/imag to handle
        # nan/inf/negative zero correctly
        # XXX: catch ValueError for subclasses of ndarray where iscomplex fail
        try:
            usecomplex = iscomplexobj(actual) or iscomplexobj(desired)
        except (ValueError, TypeError):
            usecomplex = False
    
        if usecomplex:
            if iscomplexobj(actual):
                actualr = real(actual)
                actuali = imag(actual)
            else:
                actualr = actual
                actuali = 0
            if iscomplexobj(desired):
                desiredr = real(desired)
                desiredi = imag(desired)
            else:
                desiredr = desired
                desiredi = 0
            try:
                assert_equal(actualr, desiredr)
                assert_equal(actuali, desiredi)
            except AssertionError:
                raise AssertionError(msg)
    
        # isscalar test to check cases such as [np.nan] != np.nan
        if isscalar(desired) != isscalar(actual):
            raise AssertionError(msg)
    
        try:
            isdesnat = isnat(desired)
            isactnat = isnat(actual)
            dtypes_match = (np.asarray(desired).dtype.type ==
                            np.asarray(actual).dtype.type)
            if isdesnat and isactnat:
                # If both are NaT (and have the same dtype -- datetime or
                # timedelta) they are considered equal.
                if dtypes_match:
                    return
                else:
                    raise AssertionError(msg)
    
        except (TypeError, ValueError, NotImplementedError):
            pass
    
        # Inf/nan/negative zero handling
        try:
            isdesnan = gisnan(desired)
            isactnan = gisnan(actual)
            if isdesnan and isactnan:
                return  # both nan, so equal
    
            # handle signed zero specially for floats
            array_actual = np.asarray(actual)
            array_desired = np.asarray(desired)
            if (array_actual.dtype.char in 'Mm' or
                    array_desired.dtype.char in 'Mm'):
                # version 1.18
                # until this version, gisnan failed for datetime64 and timedelta64.
                # Now it succeeds but comparison to scalar with a different type
                # emits a DeprecationWarning.
                # Avoid that by skipping the next check
                raise NotImplementedError('cannot compare to a scalar '
                                          'with a different type')
    
            if desired == 0 and actual == 0:
                if not signbit(desired) == signbit(actual):
                    raise AssertionError(msg)
    
        except (TypeError, ValueError, NotImplementedError):
            pass
    
        try:
            # Explicitly use __eq__ for comparison, gh-2552
            if not (desired == actual):
>               raise AssertionError(msg)
E               AssertionError: 
E               Items are not equal:
E                ACTUAL: nan
E                DESIRED: 2.0
/usr/lib/python3.11/site-packages/numpy/testing/_private/utils.py:425: AssertionError
During handling of the above exception, another exception occurred:
self = <scipy.sparse.tests.test_base.TestCSR object at 0xed1c3710>
    def test_fancy_assignment_dtypes(self):
        def check(dtype):
            A = self.spmatrix((5, 5), dtype=dtype)
            with suppress_warnings() as sup:
                sup.filter(SparseEfficiencyWarning,
                           "Changing the sparsity structure of a cs[cr]_matrix is expensive")
                A[[0,1],[0,1]] = dtype.type(1)
                assert_equal(A.sum(), dtype.type(1)*2)
                A[0:2,0:2] = dtype.type(1.0)
                assert_equal(A.sum(), dtype.type(1)*4)
                A[2,2] = dtype.type(1.0)
                assert_equal(A.sum(), dtype.type(1)*4 + dtype.type(1))
    
        for dtype in supported_dtypes:
>           check(np.dtype(dtype))
scipy/sparse/tests/test_base.py:3006: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
dtype = dtype('complex192')
    def check(dtype):
        A = self.spmatrix((5, 5), dtype=dtype)
        with suppress_warnings() as sup:
            sup.filter(SparseEfficiencyWarning,
                       "Changing the sparsity structure of a cs[cr]_matrix is expensive")
            A[[0,1],[0,1]] = dtype.type(1)
>           assert_equal(A.sum(), dtype.type(1)*2)
E           AssertionError: 
E           Items are not equal:
E            ACTUAL: (nan+nanj)
E            DESIRED: (2+0j)
scipy/sparse/tests/test_base.py:2999: AssertionError

SciPy/NumPy/Python version information

scipy1.9.2/numpy1.22.0/python3.11

@psimovec psimovec added the defect A clear bug or issue that prevents SciPy from being installed or used as expected label Oct 12, 2022
@andyfaff
Copy link
Contributor

Unfortunately we don't have a 686 entry in our CI.

@rgommers
Copy link
Member

@andyfaff we do, for both Windows and Linux on Azure:

  • Main Linux_Python_38_32bit_full
  • Main Windows Python38-32bit-fast

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
defect A clear bug or issue that prevents SciPy from being installed or used as expected scipy.sparse.linalg
Projects
None yet
Development

No branches or pull requests

4 participants