-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Miri: non-deterministic floating point operations in foreign_items
#143906
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
base: master
Are you sure you want to change the base?
Miri: non-deterministic floating point operations in foreign_items
#143906
Conversation
The Miri subtree was changed cc @rust-lang/miri |
There are some holes in the behaviour of some operations, because I did not know how I could efficiently handle them, I'll mark them and add some explanation. Also, |
Please create a PR for the libstd changes on their own so a libs reviewer can review it. Once that is done and synced, you can open a PR against the miri repo with the miri changes. |
In a previous PR we had both in one PR with two reviewers since we needed to go back and forth a bit. We could do that again? I think it worked well.
|
It's the same for me, I kept the commits for Miri and stdlib separate, so if I have to split it up, it's pretty straightforward. |
🤷 I'm also fine either way, it'll just be a bunch of work to port the commits to the Miri repo.
Functions where C does not give an output range shouldn't get their value clamped, I would say. |
Please don't, that file is already too big.^^ If the helpers are only needed in one file, keep them there. |
Reopening. |
You're right, but this has some consequences. For example, the The C standard for the return values of
The range of sine x is [-1, 1], but is not explicitly defined. But
I think we have 2 approaches:
|
If we run into libm implementations that can't even guarantee to return a value within the math function's output domain, tbh I would consider that downright broken and worthy of a bug report, or strong reason to just always use our If it's mostly a concern about following the specification to the letter, I think it might be worth a defect report to see if the C committee is willing to codeify the output domain. |
I would suggest a third:
|
The arcsin function likely states this not as a means of guaranteeing precision, but because the inverse sine of |
library/std/src/num/f32.rs
Outdated
@@ -1067,7 +1067,7 @@ impl f32 { | |||
/// | |||
/// let abs_difference = (f - x).abs(); | |||
/// | |||
/// assert!(abs_difference <= 1e-7); | |||
/// assert!(abs_difference <= 1e-4); |
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.
It's this one that failed, not the one I commented here https://github.com/rust-lang/rust/pull/143906/files#r2225770166
Maybe we should change the test to an area where asin is more stable -- like pi/4, which the other 2 tests are already using?
Agreed.
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.
This one might be amplifying an underlying error introduced in hypot
or ln_1p
due to how it is implemented.
But 1000 tests should still be enough for all practical purposes... strange.
Testing with It's Friday, and I don't have much to do, so I'm going to extract every changed f32/f64 test that was changed and run it with Miri with a much larger range. (In isolation, it is manageable.) If some tests still fail under CI I propose we just change them so they can never fail with Miri and track them elsewhere? |
With
|
Can you put them in this PR, except for the cases where the limit before the PR also already works (i.e., minimize the diff)? |
Sorry for the delay, stuck with some other work and wanted to be sure of the current changes. Std changes are in the last commits, the extra 3 commits are the requested changes after the CI failure. I can squash them once they are approved. Also, squash with @rustbot ready |
This comment has been minimized.
This comment has been minimized.
library/std/src/num/f32.rs
Outdated
/// | ||
/// // asin(sin(pi/2)) | ||
/// let abs_difference = (f.sin().asin() - std::f32::consts::FRAC_PI_2).abs(); | ||
/// | ||
/// assert!(abs_difference <= 1e-3); | ||
/// assert!(abs_difference <= 1e-1); |
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.
What is going on here? Surely we can do better than 1e-1
?!
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.
These faulty tests were used when finding the limits. I have changed them accordingly.
This comment has been minimized.
This comment has been minimized.
library/std/src/num/f32.rs
Outdated
@@ -1095,7 +1095,7 @@ impl f32 { | |||
/// | |||
/// let abs_difference = (f - x).abs(); | |||
/// | |||
/// assert!(abs_difference <= 1e-6); | |||
/// assert!(abs_difference <= 1e-5); |
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.
Why did this change again? It's super hard to keep track when you just keep doing random-looking changes without explanation...
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.
Excuse me, it shouldn't. I should not be implementing this while sick :).
I confused it with cosh
, which is a foreign_item
that should be changed in this pr, I just thought I forgot this one. I should've mentioned it.
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.
So, does 1e-6 work here or not?
Get well soon. :)
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.
According to the many-seeds runs on the extracted doctests it should change to 1e-5
, but it did pass CI multiple times, while asin
doesn't. You mentioned "minimizing the diff" if previous values already worked.
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.
Right, and minimizing the diff would be 1e-6 if that worked. Now you changed it to 1e-5 in the last commit. Or did I misread?
This comment has been minimized.
This comment has been minimized.
All tests should be set to their respective limits, and the diff is minimized; only tests that are affected by the changes in Miri are changed accordingly. |
Sounds good, thanks. :) Please squash the commits a little. |
e38120b
to
71add2f
Compare
|
Now that I think of it, did you mean without --keep-base? |
No, --keep-base is fine. GH CI still checks your branch merged with latest master so I think the bot is a bit overeager here. Thanks! |
…-foreign-items, r=RalfJung Miri: non-deterministic floating point operations in `foreign_items` Part of [rust-lang/miri/rust-lang#3555](rust-lang/miri#3555 (comment)), this pr does the `foreign_items` work. Some things have changed since rust-lang#138062 and rust-lang#142514. I moved the "helpers" used for creating fixed outputs and clamping operations to their defined ranges to `math.rs`. These are now also extended to handle the floating-point operations in `foreign_items`. Tests in `miri/tests/float.rs` were changed/added. Failing tests in `std` were extracted, run under miri with `-Zmiri-many-seeds=0..1000` and changed accordingly. Double checked with `-Zmiri-many-seeds`. I noticed that the C standard doesn't specify the output ranges for all of its mathematical operations; it just specifies them as: ``` Returns The sinh functions return sinh x. ``` So I used [Wolfram|Alpha](https://www.wolframalpha.com/).
…-foreign-items, r=RalfJung Miri: non-deterministic floating point operations in `foreign_items` Part of [rust-lang/miri/rust-lang#3555](rust-lang/miri#3555 (comment)), this pr does the `foreign_items` work. Some things have changed since rust-lang#138062 and rust-lang#142514. I moved the "helpers" used for creating fixed outputs and clamping operations to their defined ranges to `math.rs`. These are now also extended to handle the floating-point operations in `foreign_items`. Tests in `miri/tests/float.rs` were changed/added. Failing tests in `std` were extracted, run under miri with `-Zmiri-many-seeds=0..1000` and changed accordingly. Double checked with `-Zmiri-many-seeds`. I noticed that the C standard doesn't specify the output ranges for all of its mathematical operations; it just specifies them as: ``` Returns The sinh functions return sinh x. ``` So I used [Wolfram|Alpha](https://www.wolframalpha.com/).
…-foreign-items, r=RalfJung Miri: non-deterministic floating point operations in `foreign_items` Part of [rust-lang/miri/rust-lang#3555](rust-lang/miri#3555 (comment)), this pr does the `foreign_items` work. Some things have changed since rust-lang#138062 and rust-lang#142514. I moved the "helpers" used for creating fixed outputs and clamping operations to their defined ranges to `math.rs`. These are now also extended to handle the floating-point operations in `foreign_items`. Tests in `miri/tests/float.rs` were changed/added. Failing tests in `std` were extracted, run under miri with `-Zmiri-many-seeds=0..1000` and changed accordingly. Double checked with `-Zmiri-many-seeds`. I noticed that the C standard doesn't specify the output ranges for all of its mathematical operations; it just specifies them as: ``` Returns The sinh functions return sinh x. ``` So I used [Wolfram|Alpha](https://www.wolframalpha.com/).
…-foreign-items, r=RalfJung Miri: non-deterministic floating point operations in `foreign_items` Part of [rust-lang/miri/rust-lang#3555](rust-lang/miri#3555 (comment)), this pr does the `foreign_items` work. Some things have changed since rust-lang#138062 and rust-lang#142514. I moved the "helpers" used for creating fixed outputs and clamping operations to their defined ranges to `math.rs`. These are now also extended to handle the floating-point operations in `foreign_items`. Tests in `miri/tests/float.rs` were changed/added. Failing tests in `std` were extracted, run under miri with `-Zmiri-many-seeds=0..1000` and changed accordingly. Double checked with `-Zmiri-many-seeds`. I noticed that the C standard doesn't specify the output ranges for all of its mathematical operations; it just specifies them as: ``` Returns The sinh functions return sinh x. ``` So I used [Wolfram|Alpha](https://www.wolframalpha.com/).
Rollup of 20 pull requests Successful merges: - #137831 (Tweak auto trait errors) - #143028 (emit `StorageLive` and schedule `StorageDead` for `let`-`else`'s bindings after matching) - #143764 (lower pattern bindings in the order they're written and base drop order on primary bindings' order) - #143808 (Port `#[should_panic]` to the new attribute parsing infrastructure ) - #143906 (Miri: non-deterministic floating point operations in `foreign_items`) - #143929 (Mark all deprecation lints in name resolution as deny-by-default and report-in-deps) - #144133 (Stabilize const TypeId::of) - #144439 (Introduce ModernIdent type to unify macro 2.0 hygiene handling) - #144473 (Address libunwind.a inconsistency issues in the bootstrap program) - #144659 (bootstrap: refactor mingw dist and fix gnullvm) - #144705 (compiler-builtins: plumb LSE support for aarch64 on linux/gnu when optimized-compiler-builtins not enabled) - #144807 (Streamline config in bootstrap) - #144900 (Stabilize `unsigned_signed_diff` feature) - #144903 (Rename `begin_panic_handler` to `panic_handler`) - #144931 ([win][arm64ec] Fix msvc-wholearchive for Arm64EC) - #144974 (compiler-builtins subtree update) - #144997 (bump bootstrap compiler to 1.90 beta) - #145004 (Couple of minor cleanups) - #145009 (A couple small changes for rust-analyzer next-solver work) - #145014 (Revert "Preserve the .debug_gdb_scripts section") r? `@ghost` `@rustbot` modify labels: rollup
Part of rust-lang/miri/#3555, this pr does the
foreign_items
work.Some things have changed since #138062 and #142514. I moved the "helpers" used for creating fixed outputs and clamping operations to their defined ranges to
math.rs
. These are now also extended to handle the floating-point operations inforeign_items
. Tests inmiri/tests/float.rs
were changed/added.Failing tests in
std
were extracted, run under miri with-Zmiri-many-seeds=0..1000
and changed accordingly. Double checked with-Zmiri-many-seeds
.I noticed that the C standard doesn't specify the output ranges for all of its mathematical operations; it just specifies them as:
So I used Wolfram|Alpha.