-
-
Notifications
You must be signed in to change notification settings - Fork 10.8k
ENH: hard-code finfo parameters for known types #8504
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
Conversation
There's a test error from |
Hmm, not sure. @seberg Thoughts? EDIT: I suspect that there is no guarantee that the warning filter will be properly reset, but exactly why that would be the case here I'm not sure. You could probably use |
So the |
Sure - but how should I do what I'm trying to do if I'm not allowed to ignore the warning inside the context manager block? |
698f3d6
to
bf5d15a
Compare
OK - found a |
What's the warning here? |
ee63c6f
to
4ff8433
Compare
Well, to be honest, for some code doing funny warning stuff may make sense and the test should likely be relaxed to only tests. On the other hand, I think |
Or if the warning makes sense/does not matter, moving the context to the tests makes more sense. |
seterr is threadsafe iirc
|
numpy/numpy/core/src/umath/ufunc_object.c Line 4517 in 20d6ca1
|
@matthew-brett on ppc64, I get a mantissa (significand) size of 116 bits for long doubles (double double in this case). But you seem to set it to 105, ( |
4ff8433
to
a0dee35
Compare
OK - I used the |
@mraspaud - I got the number of digits from looking at the |
I was thinking of something more along the lines of the build time determination, basically viewing a value as a string and then looking that up. See |
Chuck - a) I think we'd need most of this machinery anyway, to replicate the old finfo behavior. Then the only difference between build-time and run-time detection is the small fragment of code here to detect the |
Other somewhat trivial advantage of this approach - finfo is a lot faster. With this PR:
With 1.12 release wheel:
Of course, this is a one-time only cost, as the results are cached. |
91964cd
to
b5bd561
Compare
@mraspaud - also see https://en.wikipedia.org/wiki/Quadruple-precision_floating-point_format#Double-double_arithmetic - which says these have 106 digits in the significand. The numpy figures for significand digits are all N-1, I guess omitting the implicit first. Also see : http://mrob.com/pub/math/f161.html (the paper explains that using the sign bit of the second double makes the actual number 107...). |
Longdoubles are especially slow in the old implementation:
Same command takes 263 microseconds from code in this PR. |
b5bd561
to
7cd0846
Compare
@matthew-brett indeed, I was just mislead by HDF5 reporting 116 bits significand... |
Chuck - would you consider merging this one, with a hoped-for follow-up to do build-time detection? |
@matthew-brett I'll take a look at this later today. I wasn't actually suggesting doing build-time detection, but rather doing the same sort of type detection at runtime. It is/can be all done in python. But I will need to take a closer look here before deciding if it is worthwhile. |
OK - thanks. If you're unhappy with the float32, float64, float80 detection, I'm happy to drop those, leaving only the PPC longdouble, which does need a fix. |
Check that finfo returns somewhat reasonable parameters for all floating point types.
@mraspaud - can you test the results of:
with the current branch? |
I think this one is ready now. The detection doesn't cover IEEE float128, hence the lack of warning when the byte-string detection fails and falls back to the discovery code. If anyone has an AIX machine they have access to, it would be good to check on that - but at least, this code falls back to the previous code when it fails to detect a signature, so it shouldn't be worse at detection. |
Planning on getting access to a SPARC with actual IEEE 754 128-bit floats to test against. |
|
numpy/core/getlimits.py
Outdated
if key in _KNOWN_TYPES: | ||
return _KNOWN_TYPES[key] | ||
# Fall back to parameter discovery | ||
return _discovered_machar(ftype) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might be worth raising a warning here so that we might get reports of new types we should cover.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe include the missing key in the message.
Warn if we don't have a signature for the float type.
Still needs test on platform with IEEE float128, to check MachAr-like parameters are correct.
nextafter is AFAIK present in umath on all platforms and defined for all
float types. I think things are written so that Numpy compilation will
fail if the long double float format is not recognized (cf
src/private/npy_fpmath.h, src/npymath/npy_math_private.h).
.
Can the numpy C code that understands the float formats be leveraged
here, instead of needing to reimplement?
|
@pv The C code just writes a structure that is then read and analysed in python, but is otherwise similar to the current code. Nextafter isn't really defined for double_double, so depends on the library choices, although the libraries are likely to follow the IBM recommendation. If we ever expose the build time macros the code here can be modified, but as it stands should serve as good check for hardcoding the types. The only thing that worries me a bit is that the |
I should say that by C code analysed is the object file and the Python code looks for the structure in that file. |
Chuck - I believe (though happy to be corrected) that all the floating point implementations specify a unique correspondence between bit pattern and input number (here -0.1). I mean, they guarantee the closest representable number, and there is only one bit pattern for any given representable number. I can see how there might be more than one pattern for double double (1.0 + 0.01 == 1.1 - 0.09), but I haven't looked into it. The patterns we're getting also match with those recorded in the perl configure script I pointed to - here - so I guess we can depend on them, but in any case, all that will happen, if they are wrong, is that the code will return to the original behavior. |
Tests pass on SPARC, with IEEE float128. Ready to merge from my point of view. |
In it goes, thanks @matthew-brett . |
How do the timings compare? |
Timings, macOS Intel, numpy 1.12:
This branch:
|
@matthew-brett This commit is causing me a bit of trouble as described in this comment. The problem revolves around the fact that you are calling numpy functions before numpy modules are fully loaded here, specifically you are calling Do you think we might delay the evaluations here until after numpy modules are fully loaded? |
Just to verify, this went is for 1.13 and did not get backported further? |
@tacaswell |
Hard-code the MachAr parameters for float64, float32, 80-bit extended
precision, to save time, and provide skeleton for more difficult types
such as the double double on PPC; see
#2669