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

test_math.testFsum failure on release30-maint #49843

Closed
pitrou opened this issue Mar 29, 2009 · 14 comments
Closed

test_math.testFsum failure on release30-maint #49843

pitrou opened this issue Mar 29, 2009 · 14 comments
Assignees
Labels
extension-modules C modules in the Modules dir type-bug An unexpected behavior, bug, or error

Comments

@pitrou
Copy link
Member

pitrou commented Mar 29, 2009

BPO 5593
Nosy @mdickinson, @pitrou

Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

Show more details

GitHub fields:

assignee = 'https://github.com/mdickinson'
closed_at = <Date 2009-04-24.16:42:21.910>
created_at = <Date 2009-03-29.01:07:40.727>
labels = ['extension-modules', 'type-bug']
title = 'test_math.testFsum failure on release30-maint'
updated_at = <Date 2009-04-24.16:42:21.909>
user = 'https://github.com/pitrou'

bugs.python.org fields:

activity = <Date 2009-04-24.16:42:21.909>
actor = 'mark.dickinson'
assignee = 'mark.dickinson'
closed = True
closed_date = <Date 2009-04-24.16:42:21.910>
closer = 'mark.dickinson'
components = ['Extension Modules']
creation = <Date 2009-03-29.01:07:40.727>
creator = 'pitrou'
dependencies = []
files = []
hgrepos = []
issue_num = 5593
keywords = []
message_count = 14.0
messages = ['84354', '84355', '84356', '84378', '84381', '84383', '84386', '84389', '84391', '84394', '84396', '84401', '84402', '86414']
nosy_count = 2.0
nosy_names = ['mark.dickinson', 'pitrou']
pr_nums = []
priority = 'normal'
resolution = 'fixed'
stage = 'needs patch'
status = 'closed'
superseder = None
type = 'behavior'
url = 'https://bugs.python.org/issue5593'
versions = ['Python 2.6', 'Python 3.0', 'Python 3.1', 'Python 2.7']

@pitrou
Copy link
Member Author

pitrou commented Mar 29, 2009

I started getting this in release30-maint (not in py3k).

======================================================================
FAIL: testFsum (test.test_math.MathTests)
----------------------------------------------------------------------

Traceback (most recent call last):
  File "/home/antoine/py3k/30/Lib/test/test_math.py", line 443, in testFsum
    self.assertEqual(actual, expected)
AssertionError: 1.1102230246251565e-16 != 0.0

@pitrou pitrou added interpreter-core (Objects, Python, Grammar, and Parser dirs) type-bug An unexpected behavior, bug, or error labels Mar 29, 2009
@pitrou
Copy link
Member Author

pitrou commented Mar 29, 2009

It only seems to happen on a 32-bit build on a 64-bit system.

@pitrou
Copy link
Member Author

pitrou commented Mar 29, 2009

And it actually also happens in py3k (but only in 32-bit mode, too).

@mdickinson
Copy link
Member

Hmm. I can't reproduce this.

Is this a failure that just started happening recently on this
particular platform, or is this the first time you ran the
math test with this setup? I can't see any recent checkins
that could have precipitated this.

Could you attach the output of the configure script (just the
stdout output, not the config.log)?

@pitrou
Copy link
Member Author

pitrou commented Mar 29, 2009

Yikes. I can't reproduce it anymore. Perhaps "make distclean" is really
necessary when switching a working copy from a 64-bit to a 32-bit
build... Sorry for the noise.

@pitrou pitrou closed this as completed Mar 29, 2009
@pitrou pitrou added the invalid label Mar 29, 2009
@mdickinson
Copy link
Member

Sorry for the noise.

Not noise. I'd still be interested in understanding where this is coming
from; I seem to recall someone else having exactly the same experience
(reported bug, then found that it disappeared after a clean compile).

My best guess is that you somehow ended up in a situation where the math
module was using the x87 FPU for floating-point, while the interpreter
core was using SSE2. Is this possible?

Explanation: the x87 FPU has problems with double rounding (because it
uses 80-bit extended precision registers internally) while SSE2 doesn't. fsum is a bit broken on systems with double rounding problems. So there's
a pair of lines in testFsum that look like:

if 1e16+2.0 != 1e16+2.9999:
    return

These lines are supposed to skip all these tests on platforms with the
double rounding problem. But if the core is using SSE2 then the test will
fail and all the fsum tests will be executed, which is a problem if fsum
is using x87.

@mdickinson
Copy link
Member

Found the other report of this: see bpo-3421.

@mdickinson
Copy link
Member

My best guess is that you somehow ended up in a situation where the math
module was using the x87 FPU for floating-point, while the interpreter
core was using SSE2. Is this possible?

I should also have said that this would fit with the 32-bit/64-bit
stuff: I *think* it's true that for gcc on Linux, in the absence of
compiler flags, a 64-bit build defaults to using SSE2 while a 32-bit build
defaults to x87.

@pitrou
Copy link
Member Author

pitrou commented Mar 29, 2009

My best guess is that you somehow ended up in a situation where the math
module was using the x87 FPU for floating-point, while the interpreter
core was using SSE2. Is this possible?

That would be the reverse, since this occurred on a 32-bit build, i.e.
the interpreter core was using x87. But I don't understand how a 64-bit
module could be loaded by a 32-bit executable (I did check that
sys.maxsize was 2**31 - 1).

fsum is a bit broken on systems with double rounding problems. So
there's
a pair of lines in testFsum that look like:

if 1e16+2.0 != 1e16+2.9999:
return

Wouldn't it be a problem with stale pyc files then? The result of each
addition is stored as a constant when the code is compiled. Note how the
constants arrays differ:

64-bit:

>>> def f():
...   return 1e16+2.9999
... 
>>> dis.dis(f)
  2           0 LOAD_CONST               3 (10000000000000002.0) 
              3 RETURN_VALUE         
>>> zlib.crc32(marshal.dumps(f.__code__.co_consts))
2292868100

32-bit:

>>> def f():    
...   return 1e16+2.9999
... 
>>> dis.dis(f)  
  2           0 LOAD_CONST               3 (10000000000000004.0) 
              3 RETURN_VALUE         
>>> zlib.crc32(marshal.dumps(f.__code__.co_consts))
103113703

@pitrou pitrou reopened this Mar 29, 2009
@pitrou pitrou removed the invalid label Mar 29, 2009
@mdickinson
Copy link
Member

Wouldn't it be a problem with stale pyc files then?

Hah! Yes! That seems entirely likely.

So what sequence of moves does one have to go through
to reproduce this?

@pitrou
Copy link
Member Author

pitrou commented Mar 29, 2009

> Wouldn't it be a problem with stale pyc files then?

Hah! Yes! That seems entirely likely.

So what sequence of moves does one have to go through
to reproduce this?

I suppose: first run "-m test.regrtest -v test_math" in 64-bit mode,
then rebuild in 32-bit mode (*) without doing "make (dist)clean", then
run "-m test.regrtest -v test_math" again (in 32-bit mode).

(*) CC="gcc -m32" ./configure

@mdickinson
Copy link
Member

Thanks, Antoine! Yes, I can now reproduce the testFsum failure on my
MacBook Pro (OS X 10.5.6/x86_64, with Apple's gcc 4.0.1) using the
following sequence of commands: (I tested this for the trunk, but I
py3k should be just the same).

make distclean
CC="gcc -arch x86_64" ./configure && make
./python.exe -m test.regrtest -v test_math
rm Parser/*.o
CC="gcc -mfpmath=387" ./configure && make
./python.exe -m test.regrtest -v test_math

(the rm is necessary to avoid a 'wrong architecture' build failure).

It might be worth making the tests a bit more robust here; I'll
take a look. On the other hand, there are plans to replace fsum
with a double-rounding-friendly version.

@mdickinson mdickinson added extension-modules C modules in the Modules dir and removed interpreter-core (Objects, Python, Grammar, and Parser dirs) labels Mar 29, 2009
@mdickinson mdickinson self-assigned this Mar 29, 2009
@pitrou
Copy link
Member Author

pitrou commented Mar 29, 2009

I think it would be sufficient to invoke the addition through a helper
function, that is:

def add(x, y):
    return x + y

if add(1e16, 2.0) != add(1e16, 2.9999):
    return

Also, instead of "return", you might use the new "raise
unittest.SkipTest('some message')".

@mdickinson
Copy link
Member

Test fixed for 2.7, 3.1 in r71837, r71839

@ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
extension-modules C modules in the Modules dir type-bug An unexpected behavior, bug, or error
Projects
None yet
Development

No branches or pull requests

2 participants