With the correctly rounded implementation, we can reduce the ULP
requirement for `cbrt` to zero. There is still an override required for
`i586` because of the imprecise FMA.
We only round using nearest, but some incoming code has more handling of
rounding modes that would be nice to `match` on. Rather than checking
integer values, add an enum representation.
Usually `cargo binstall iai-callgrind-runner` handles apt dependencies.
However, the following has been happening:
Err:11 mirror+file:/etc/apt/apt-mirrors.txt noble-updates/main amd64 libc6-dbg amd64 2.39-0ubuntu8.3
404 Not Found [IP: 40.81.13.82 80]
E: Failed to fetch mirror+file:/etc/apt/apt-mirrors.txt/pool/main/g/glibc/libc6-dbg_2.39-0ubuntu8.3_amd64.deb 404 Not Found [IP: 40.81.13.82 80]
Fetched 19.8 MB in 6s (3138 kB/s)
E: Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?
Installing the dependencies manually seems to resolve the issue.
Introduce a version of generic `fma` that works when there is a larger
hardware-backed float type available to compute the result with more
precision. This is currently used only for `f32`, but with some minor
adjustments it should work for `f16` as well.
When `fmaf128` was introduced in [1], it included a bug where `self`
gets returned rather than the expected minimum positive value. Resolve
this and add a regression test.
[1]: https://github.com/rust-lang/libm/pull/494
Add checks at the max subnormal value and a couple values scatted
throughout the subnormal range. This helped identifiy a bug in
`fmaf128`.
As part of this, slightly reduce the amount of edge cases checked
without optimizations because the change makes it become noticible.
To ensure we don't waste time running extensive tests when there is an
easily identifiable failure, run the normal test suite for relevant
functions before starting extensive tests.
Adjust paths such that these macros don't go through the private `math`
module. `feature = "private-test-deps"` is still needed.
Additionally, ensure that `cargo check` for this crate gets run in CI
because `cargo test` does not seem to identify this problem.
`compiler_builtins` will need to reexport the `support` module.
We need someplace to collect known failures, previous regressions, edge
cases that are difficult to construct from generics, and similar.
Introduce this here.
A few bugs have been fixed, including the sign of `fma(tiny, -tiny,
0.0)`. Switch to tracking `master` rather than the latest tag so we
don't need to xfail these tests.
Currently, `fma(tiny, -tiny, 0.0)` returns 0.0 while the answer should
be -0.0. This is because `-0.0 + 0.0 = +0.0` in the default rounding
mode; however, the result should be negative. Musl has the same pattern
but that version worked because the C compiler was contracting `x*y + z`
to (ironically) `fmadd`.
Musl was fixed in 9683bd6241 ("math: fix fma(x,y,0) when x*y rounds to
-0"). Add the same fix here, which allows dropping the xfails.
Now that we have a hex float formatter, make use of it for test output.
This produces values that are easier to read than the bitwise hex
representation.
Example:
thread 'mp_quickspace_fmaf128' panicked at crates/libm-test/tests/multiprecision.rs:17:48:
called `Result::unwrap()` on an `Err` value:
input: (0xe38d71c71c71c71c71c71c71c71c71c8, 0xe38d71c71c71c71c71c71c71c71c71c8, 0xffff0000000000000000000000000000)
as hex: (-0x1.71c71c71c71c71c71c71c71c71c8p+9102, -0x1.71c71c71c71c71c71c71c71c71c8p+9102, -inf)
as bits: (0xe38d71c71c71c71c71c71c71c71c71c8, 0xe38d71c71c71c71c71c71c71c71c71c8, 0xffff0000000000000000000000000000)
expected: 0xffff0000000000000000000000000000 -inf 0xffff0000000000000000000000000000
actual: 0x7fff8000000000000000000000000000 NaN 0x7fff8000000000000000000000000000
Caused by:
real value != NaN
In order to make these more interchangeable in more places, always
return `(impl Iterator, u64)`. This will facilitate using other
generators for extensive tests.
This is the first step toward making `fma` usable for `f128`, and
possibly `f32` on platforms where growing to `f64` is not fast. This
does not yet work for anything other than `f64`.
This crate has a handful of lists that need to list all API and can't
easily be verified. Additionally, some longer lists should be kept
sorted so they are easier to look through. Resolve both of these by
adding a check in `update-api-list.py` that looks for annotations and
verifies the contents are as expected.
Annotations are `verify-apilist-start`, `verify-apilist-end`,
`verify-sorted-start`, and `verify-sorted-end`.
This includes fixes for anything that did not meet the criteria.
Use the generic `scalbn` to provide `f16` and `f128` versions, which
also work for `ldexp`.
This involves a new algorithm for `f16` because the default does not
converge fast enough with a limited number of rounds.
`EXP_MAX` sounds like it would be the maximum value representable by
that float type's exponent, rather than the maximum unsigned value of
its bits. Clarify this by renaming to `EXP_SAT`, the "saturated"
exponent representation.
Simplify the SPDX string to the user-facing version to make it easier for
users and tooling to understand. Contributions must still be `MIT OR Apache-2.0`.
[ add commit body with context - Trevor ]
0.17.10 introduced a change that removes `Sync` from `ProgressStyle`,
which makes it more difficult to share in a callback. Pin the dependency
for now until we see if `indicatif` will change this back or if we need
to find a workaround.
There seems to be a case of unsoundness with the `i586` version of
`atan2`. For the following test:
assert_eq!(atan2(2.0, -1.0), atan(2.0 / -1.0) + PI);atan2(2.0, -1.0)
The output is optimization-dependent. The new `release-checked` profile
produces the following failure:
thread 'math::atan2::sanity_check' panicked at src/math/atan2.rs:123:5:
assertion `left == right` failed
left: 2.0344439357957027
right: 2.0344439357957027
Similarly, `sin::test_near_pi` fails with the following:
thread 'math::sin::test_near_pi' panicked at src/math/sin.rs:91:5:
assertion `left == right` failed
left: 6.273720864039203e-7
right: 6.273720864039205e-7
Mark the tests ignored on `i586` for now.
Currently the default release profile enables LTO and single CGU builds,
which is very slow to build. Most tests are better run with
optimizations enabled since it allows testing a much larger number of
inputs, so it is inconvenient that building can sometimes take
significantly longer than the tests.
Remedy this by doing the following:
* Move the existing `release` profile to `release-opt`.
* With the above, the default `release` profile is untouched (16 CGUs
and thin local LTO).
* `release-checked` inherits `release`, so no LTO or single CGU.
This means that the simple `cargo test --release` becomes much faster
for local development. We are able to enable the other profiles as
needed in CI.
Tests should ideally still be run with `--profile release-checked` to
ensure there are no debug assetions or unexpected wrapping math hit.
`no-panic` still needs a single CGU, so must be run with `--profile
release-opt`. Since it is not possible to detect CGU or profilel
configuration from within build scripts, the `ENSURE_NO_PANIC`
environment variable must now always be set.
The Cargo feature `checked` was added in 410b0633a6b9 ("Overhaul tests")
and later removed in e4ac1399062c ("swap stable to be unstable, checked
is now debug_assertions"). However, there are a few remaining uses of
`feature = "checked"` that did not get removed. Clean these up here.
This function is significantly slower than all others so includes an
override in `EXTREMELY_SLOW_TESTS`. Without it, PR CI takes ~1hour and
the extensive tests in CI take ~1day.
Certain functions (`fmodf128`) are significantly slower than others,
to the point that running the default number of tests adds tens of
minutes to PR CI and extensive test time increases to ~1day. It does not
make sense to do this by default; so, introduce `EXTREMELY_SLOW_TESTS`
to test configuration that allows setting specific tests that need to
have a reduced iteration count.
With the new routines, some of our tests are running close to their
timeouts. Increase the timeout for test jobs, and set a short timeout
for all other jobs that did not have one.