BlueBrain / NeuroR

A collection of tools to repair morphologies
https://neuror.readthedocs.io/
GNU Lesser General Public License v3.0
9 stars 6 forks source link

Different results depending on availability of AVX-512 instruction set and numpy>1.25 's vectorized sort/argsort #115

Closed eleftherioszisis closed 11 months ago

eleftherioszisis commented 1 year ago

numpy==1.25 introduced simd vectorized version of quicksort with: https://github.com/numpy/numpy/pull/23707

That change affects the behavior of the sort and argsort functions when using quicksort (default) based on the existence of the avx-512 instruction set.

In NeuroR, one of the functions that are affected is scipy.optimize.minimize: https://github.com/BlueBrain/NeuroR/blob/ae524119d4ed15a6df410e34720dac13df5d2f34/neuror/cut_plane/detection.py#L279

which uses internally numpy's argsort in: https://github.com/scipy/scipy/blob/cfe80116aaa145061246b8aec0e98248fbefb835/scipy/optimize/_optimize.py#L907

See also: https://github.com/numpy/numpy/issues/24064

Github hosted runners for ubuntu-latest seem to have enabled the aforementioned instruction set as they output different values than the expected ones in the past: https://github.com/BlueBrain/NeuroR/actions/runs/5484236591/jobs/9991722132

mgeplf commented 1 year ago

On bb5, I can repro:

____________________________________________________________________________________________________________________________________________________________________ test_minimize_more17 ____________________________________________________________________________________________________________________________________________________________________

    @pytest.mark.skipif(version.parse(scipy.__version__) < version.parse('1.7'),
                        reason="requires scipy >= 1.7")
    def test_minimize_more17():
        params = 4, 45, -21, 0, 0, 61

        result = _minimize(params, _get_points(), bin_width=10)
>       assert_allclose(result,
                        [4.1510e+00, 4.6763e+01, -2.0966e+01, -2.7207e-04, -4.5070e-04, 6.8804e+01],
                        rtol=1e-4)

tests/cut-plane/test_detection.py:83:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

args = (<function assert_allclose.<locals>.compare at 0x7fffdcbac280>, array([ 4.09910404e+00,  4.67742676e+01, -2.06672325e+...3e-04,  6.88124012e+01]), array([ 4.1510e+00,  4.6763e+01, -2.0966e+01, -2.7207e-04, -4.5070e-04,
        6.8804e+01]))
kwds = {'equal_nan': True, 'err_msg': '', 'header': 'Not equal to tolerance rtol=0.0001, atol=0', 'verbose': True}

    @wraps(func)
    def inner(*args, **kwds):
        with self._recreate_cm():
>           return func(*args, **kwds)
E           AssertionError:
E           Not equal to tolerance rtol=0.0001, atol=0
E
E           Mismatched elements: 6 / 6 (100%)
E           Max absolute difference: 0.29876749
E           Max relative difference: 0.40725429
E            x: array([ 4.099104e+00,  4.677427e+01, -2.066723e+01, -2.980689e-04,
E                  -2.671505e-04,  6.881240e+01])
E            y: array([ 4.1510e+00,  4.6763e+01, -2.0966e+01, -2.7207e-04, -4.5070e-04,
E                   6.8804e+01])

../../../../../ssd/apps/bsd/2022-01-10/stage_externals/install_gcc-11.2.0-skylake/python-3.9.7-yj5alh/lib/python3.9/contextlib.py:79: AssertionError

Architecture is:

processor       : 71
vendor_id       : GenuineIntel
cpu family      : 6
model           : 85
model name      : Intel(R) Xeon(R) Gold 6140 CPU @ 2.30GHz
mgeplf commented 11 months ago

This was worked around, for the time being, with: https://github.com/BlueBrain/NeuroR/pull/116