[SciPy-Dev] Floating point differences in CPython

Stanley Seibert sseibert at anaconda.com
Mon Dec 2 13:22:26 EST 2019


Given how much platform-to-platform variation there is (this gives us
headaches all the time on Numba), I was wondering how CPython got these
tests to pass without shipping their own cross-platform C math library.  It
turns out the test runner is pretty generous:

https://github.com/python/cpython/blob/5fd5cb8d85fab3393dd76c7f3de1cdeb8ecf7203/Lib/test/test_math.py#L1614-L1679

The default test precision is 5 ulps (with some functions getting much
more), and the original example differs by only 1 ulp between glibc
versions, so CPython's testing would not have flagged a discrepancy this
small.

On Mon, Dec 2, 2019 at 7:38 AM Matti Picus <matti.picus at gmail.com> wrote:

>
> On 2/12/19 3:28 pm, Stanley Seibert wrote:
>
>
> On Mon, Dec 2, 2019 at 1:06 AM Juan Luis Cano <juanlu001 at gmail.com> wrote:
>
>> Hi all,
>>
>> I admit this is not strictly about SciPy, but there is lots of people in
>> this list that care about compilers and floating point math so I still
>> wanted to give it a try.
>>
>> I am observing floating point differences between two different versions
>> of CPython 3.7.5, one compiled with GCC 7.4.0 (latest Linux Mint) and other
>> compared with GCC 8.3.0 (Debian Buster) that can be reproduced like this:
>>
>> $ docker run --rm -it python:3.7.5-stretch python -c 'print("{:.10f}".format((7091.17117297555159893818 ** 2 + 7118.70008070942458289210 ** 2 + (-1513.67274389594149397453) ** 2) ** 1.5))'
>> 1049171479739.7584228516
>> $ docker run --rm -it python:3.7.5-buster  python -c 'print("{:.10f}".format((7091.17117297555159893818 ** 2 + 7118.70008070942458289210 ** 2 + (-1513.67274389594149397453) ** 2) ** 1.5))'
>> 1049171479739.7585449219
>>
>>
>> I highlight the GCC version because as far as I understand is the only
>> thing that could have changed between the two. Does anybody have a more
>> detailed explanation of what's going on here?
>>
>> Best,
>>
>> --
>> Juan Luis Cano
>>
>> I'm speculating, but what jumped out at me is the **1.5, which will
> likely invoke the pow() function in glibc.  Since there is no IEEE spec for
> pow() precision, it is possible that a change there could produce this
> effect.  Stretch uses glibc 2.24 and Buster uses glibc 2.28.  The changelog
> for glibc 2.27 (https://sourceware.org/ml/libc-announce/2018/msg00000.html)
> mentions this:
>
> * Optimized x86-64 asin, atan2, exp, expf, log, pow, atan, sin, cosf,
>   sinf, sincosf and tan with FMA, contributed by Arjan van de Ven and
>   H.J. Lu from Intel.
>
> Which seems like a likely culprit, although I haven't done the work to
> exactly pinpoint it to this change.
>
>
> CPython has extensive tests to verify the functions in the cmath[0] and
> math[1] modules, but the latter does not seem to include tests for `pow`.
> Maybe after 9 years it is time to update it.
>
>
> [0]
> https://github.com/python/cpython/blob/master/Lib/test/cmath_testcases.txt
>
> [1]
> https://github.com/python/cpython/blob/master/Lib/test/math_testcases.txt
>
>
> Matti
> _______________________________________________
> SciPy-Dev mailing list
> SciPy-Dev at python.org
> https://mail.python.org/mailman/listinfo/scipy-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/scipy-dev/attachments/20191202/3bbea747/attachment.html>


More information about the SciPy-Dev mailing list