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
DOC: (Undefined) behavior of float to integer casts only really explained in release notes #22852
Comments
C defines this as undefined behavior. NumPy has never guaranteed any specific overflow behavior here. As C is undefined, CPUs are pretty random about what they do (plus compilers). For example for uint32 non-vectorized the compiler may spit out instructions casting to int64 (rather than uint32 directly) which then is "well defined". The linked PRs, one adds the warning which tells you are getting undefined behavior (but in one case it is implicitly well defined after all, so no warning). The other PR would just make the situation even worse probably, by using more vectorization leading to hitting more UB. I am not really convinced that we should worry about doing better than C compilers here. Is there a particular use-case? |
My scenario is that I am writing a test suite for some linear algebra routines with the signature This test suite uses hypothesis to generate input arrays ( A nice addition to numpy regarding this would be a place in the docs where I could discover that this platform-specific behavior exists. The warning on linux in v1.24 already goes a long way, but maybe it could also show up on Windows (the behavior is still undefined, even if the actual behavior turns out to be consistent). Perhaps we could also provide some more detail on this in the docs and add a link to further information into the warning? |
I also just found a smaller example that reproduces this behavior: >>> import numpy as np
>>> foo = 2 ** 32 + 1
>>> bar = np.asarray(foo, dtype=float)
>>> np.asarray((foo, foo), dtype="i1")
<stdin>:1: DeprecationWarning: NumPy will stop allowing conversion of out-of-bound Python integers to integer arrays. The conversion of 4294967297 to int8 will fail in the future.
For the old behavior, usually:
np.array(value).astype(dtype)`
will give the desired result (the cast overflows).
array([1, 1], dtype=int8)
>>> np.asarray((bar, bar), dtype="i1")
<stdin>:1: RuntimeWarning: invalid value encountered in cast
array([0, 0], dtype=int8) Interestingly, this appears to be sensitive to the value of >>> foo = 256 + 1
>>> bar = np.asarray(foo, dtype=float)
>>> np.asarray((foo, foo), dtype="i1")
<stdin>:1: DeprecationWarning: NumPy will stop allowing conversion of out-of-bound Python integers to integer arrays. The conversion of 257 to int8 will fail in the future.
For the old behavior, usually:
np.array(value).astype(dtype)`
will give the desired result (the cast overflows).
array([1, 1], dtype=int8)
>>> np.asarray((bar, bar), dtype="i1")
array([1, 1], dtype=int8) |
Right, the docs could probably mention this somewhere (not quite sure where). Runtime-wise, I doubt there is an easy win available, the new warning is probably about as good as it gets. (Not that I would mind making it more well defined if it isn't a big performance issue, and that may well be possible.) |
Hm, the first place I thought off was inside the docs for |
Describe the issue:
When running the example test case below the assertion works fine on Windows, but fails on Linux with the message below.
This is a cross-post from: https://stackoverflow.com/questions/74872407/why-does-numpy-handle-overflows-inconsistently
Related PRs: #21437 , #21123
Reproduce the code example:
Error message:
NumPy/Python version information:
1.24.0 3.8.10 (default, Jun 2 2021, 10:49:15)
[GCC 9.4.0]
Context for the issue:
I've tried to reduce the example further, but any further modifications change the behavior to make it work as expected. For example, changing from
np.eye(2)
tonp.empty((1, 1))
ornp.eye(1)
changes the behavior on linux and the test passes.The text was updated successfully, but these errors were encountered: