497 Commits

Author SHA1 Message Date
Trevor Gross
2912076e50 Always use the same seed for benchmarking
It would be preferable to switch to a different generator, or at least
set the seed within the benchmark, but this is the most straightforward
way to make things simple.
2025-01-11 23:36:11 -05:00
Trevor Gross
e1749bdb6d Add biteq and exp_unbiased to Float
These are two convenience methods. Additionally, add tests for the trait
methods, and an `assert_biteq!` macro to check and print the output.
2025-01-11 22:58:00 -05:00
Trevor Gross
5c94cce6b2 Add a release-checked profile with debug and overflow assertions
A failing debug assertion or overflow without correctly wrapping or
saturating is a bug, but the `debug` profile that has these enabled does
not run enough test cases to hit edge cases that may trigger these. Add
a new `release-checked` profile that enables debug assertions and
overflow checks. This seems to only extend per-function test time by a
few seconds (or around a minute on longer extensive tests), so enable
this as the default on CI.

In order to ensure `no_panic` still gets checked, add a build-only step
to CI.
2025-01-11 20:35:30 -05:00
Trevor Gross
721960c172 Remove ExpInt from Float, always use i32 instead
`ExpInt` is likely to only have performance benefits on 16-bit
platforms, but makes working with the exponent more difficult. It seems
like a worthwhile tradeoff to instead just use `i32`, so do that here.
2025-01-11 19:22:01 -05:00
Trevor Gross
5e13eeca01 Reorder tests in run.sh
I do not believe Cargo separately caches crates with different sets of
features enabled. So, ensuring that tests run with `unstable-intrinsics`
are always grouped should slightly reduce runtime.

As an added benefit, all the debug mode tests run first so initial
feedback is available faster.
2025-01-11 18:48:08 -05:00
Trevor Gross
beb34db83d Split cast into cast and cast_lossy
There is a difference in intent between wishing to cast and truncate the
value, and expecting the input to be within range. To make this clear,
add separate `cast_lossy` and `cast_from_lossy` to indicate what that
truncation is intended, leaving `cast` and `cast_from` to only be casts
that expected not to truncate.

Actually enforcing this at runtime is likely to have a cost, so just
`debug_assert!` that `cast` doesn't truncate.
2025-01-11 18:28:45 -05:00
Trevor Gross
ab1038a32b Use core::arch::wasm functions rather than intrinsics
These wasm functions are available in `core::arch::wasm32` since [1], so
we can use them while avoiding the possibly-recursive `intrinsics::*`
calls (in practice none of those should always lower to libcalls on
wasm, but that is up to LLVM).

Since these require an unstable feature, they are still gated under
`unstable-intrinsics`.

[1]: https://github.com/rust-lang/stdarch/pull/1677
2025-01-11 17:04:29 -05:00
Trevor Gross
a0c03b2537 Add tests against MPFR for remquo and remquof
Rug does not yet expose this function, but it is possible to use the
MPFR bindings directly.
2025-01-10 16:04:16 -05:00
Trevor Gross
2b99475df3 Account for optimization levels other than numbers
The build script currently panics with `opt-level=z` or `opt-level=s`.
Account for this here.
2025-01-07 17:58:54 -05:00
beetrees
76714a5657 Make extensive tests exhaustive if there are enough iterations available 2025-01-07 17:44:06 -05:00
Trevor Gross
0359db23c7 Increase the allowed ULP for tgammaf
Extensive tests report that the precision isn't actually 0:

    ---- mp_extensive_tgammaf ----

        input:    (-0.00063536887,) (0xba268ee2,)
        expected: -1574.4668             0xc4c4cef0
        actual:   -1574.4667             0xc4c4ceef

    Caused by:
        ulp 1 > 0

Update ULP to reflect this. After this change, `tgammaf` extensive tests
pass.
2025-01-06 22:19:49 -05:00
Trevor Gross
f3ad123a09 Replace "intrinsic" config with "arch" config
WASM is the only architecture we use `intrinsics::` for. We probably
don't want to do this for any other architectures since it is better to
use assembly, or work toward getting the functions available in `core`.

To more accurately reflect the relationship between arch and intrinsics,
make wasm32 an `arch` module and call the intrinsics from there.
2025-01-06 20:17:01 -05:00
Trevor Gross
c574145577 Don't use intrinsics abs for f16 and f128 on wasm32
This configuration was duplicated from `fabs` and `fabsf`, but wasm is
unlikely to have an intrinsic lowering for these float types. So, just
always use the generic.
2025-01-06 18:33:24 -05:00
Trevor Gross
b5a217b11c Remove an unused feature = "force-soft-floats" gate 2025-01-06 18:06:38 -05:00
Trevor Gross
ac9fec04ef Switch from using unstable-intrinsics to intrinsics_enabled
Unlike `unstable-intrinsics`, `intrinsics_enabled` gets disabled with
`force-soft-floats` which is what we want here.
2025-01-06 17:28:01 -05:00
Trevor Gross
05b87887f4 Increase the allowed precision for failing tests on i586
These will need to be fixed, for now just xfail them so this doesn't
block better test coverage.
2025-01-06 15:41:39 -05:00
Trevor Gross
a9407010b4 Enable MPFR tests on i586
MPFR does build and run correctly without SSE, but requires
`force-cross` be enabled.
2025-01-06 15:41:39 -05:00
Trevor Gross
a882639e7f ci: Only update the github ref for pull requests
On master, this fetch fails with:

    fatal: refusing to fetch into branch 'refs/heads/master' checked out at '/home/runner/work/libm/libm'

Just skip the command when this shouldn't be needed.
2025-01-06 15:37:16 -05:00
Trevor Gross
449d41a24f Loosen precision on i586 based on new tests 2025-01-06 11:46:01 +00:00
Trevor Gross
4b014bff40 Add an override for failing ceil/floor tests on i586 2025-01-06 11:44:28 +00:00
Trevor Gross
a3363785ea Add domain and edge case tests to musl
This provides an increase in test coverage on platforms that cannot test
against MPFR.
2025-01-06 09:30:41 +00:00
Trevor Gross
6b5e8b20f0 Add test infrastructure for f16 and f128
Update test traits to support `f16` and `f128`, as applicable. Add the
new routines (`fabs` and `copysign` for `f16` and `f128`) to the list of
all operations.
2025-01-06 04:10:51 -05:00
Trevor Gross
42c7ace5ba Add fabsf16, fabsf128, copysignf16, and copysignf128
Use the generic implementations to provide these simple methods.
2025-01-06 04:10:51 -05:00
Trevor Gross
aabb7d9dcc Enable f16 and f128 when creating the API change list
Additionally, read glob output as absoulte paths. This enables the
script to work properly even when invoked from a different directory.
2025-01-06 04:10:51 -05:00
Trevor Gross
f8a184e6af Run extensive tests in CI when relevant files change
Add a CI job with a dynamically calculated matrix that runs extensive
jobs on changed files. This makes use of the new
`function-definitions.json` file to determine which changed files
require full tests for a routine to run.
2025-01-06 08:56:22 +00:00
Trevor Gross
05a1f4a982 Update precision based on failures from extensive tests 2025-01-06 08:22:13 +00:00
Trevor Gross
1bbf8b12da Add extensive and exhaustive tests
Add a generator that will test all inputs for input spaces `u32::MAX` or
smaller (e.g. single-argument `f32` routines).  For anything larger,
still run approximately `u32::MAX` tests, but distribute inputs evenly
across the function domain.

Since we often only want to run one of these tests at a time, this
implementation parallelizes within each test using `rayon`. A custom
test runner is used so a progress bar is possible.

Specific tests must be enabled by setting the `LIBM_EXTENSIVE_TESTS`
environment variable, e.g.

    LIBM_EXTENSIVE_TESTS=all_f16,cos,cosf cargo run ...

Testing on a recent machine, most tests take about two minutes or less.
The Bessel functions are quite slow and take closer to 10 minutes, and
FMA is increased to run for about the same.
2025-01-06 08:22:13 +00:00
Trevor Gross
7c04b1916a Add more detailed definition output for update-api-list.py
Update the script to produce, in addition to the simple text list, a
JSON file listing routine names, the types they work with, and the
source files that contain a function with the routine name. This gets
consumed by another script and will be used to determine which extensive
CI jobs to run.
2025-01-06 02:25:59 -05:00
Trevor Gross
f453f5e5b5 Add tests against MPFR for ilogb and ilogbf 2025-01-06 01:29:22 -05:00
Trevor Gross
206bf326d5 Increase the precision for jn and jnf
New random seeds seem to indicate that this test does have some more
failures, this is a recent failure on i586:

    ---- musl_random_jnf stdout ----
    Random Musl jnf arg 1/2: 100 iterations (10000 total) using `LIBM_SEED=nLfzQ3U1OBVvqWaMBcto84UTMsC5FIaC`
    Random Musl jnf arg 2/2: 100 iterations (10000 total) using `LIBM_SEED=nLfzQ3U1OBVvqWaMBcto84UTMsC5FIaC`

    thread 'musl_random_jnf' panicked at crates/libm-test/tests/compare_built_musl.rs:43:51:
    called `Result::unwrap()` on an `Err` value:
        input:    (205, 5497.891) (0x000000cd, 0x45abcf21)
        expected: 7.3291517e-6           0x36f5ecef
        actual:   7.331668e-6            0x36f6028c

    Caused by:
        ulp 5533 > 4000

It seems unlikely that `jn` would somehow have better precision than
`j0`/`j1`, so just use the same precision.
2025-01-05 23:37:12 -05:00
Trevor Gross
ea21b6045f Rename unstable-test-support to unstable-public-internals
The `support` module that this feature makes public will be useful for
implementations in `compiler-builtins`, not only for testing. Give this
feature a more accurate name.
2025-01-05 22:13:11 -05:00
Trevor Gross
cc6a84bf43 Update precision based on new test results 2025-01-06 01:51:37 +00:00
Trevor Gross
37dbc534cb Rewrite the random test generator
Currently, all inputs are generated and then cached. This works
reasonably well but it isn't very configurable or extensible (adding
`f16` and `f128` is awkward).

Replace this with a trait for generating random sequences of tuples.
This also removes possible storage limitations of caching all inputs.
2025-01-06 00:32:21 +00:00
Trevor Gross
b78f7b7b48 Add an iterator that ensures known size
Introduce the `KnownSize` iterator wrapper, which allows providing the
size at construction time. This provides an `ExactSizeIterator`
implemenation so we can check a generator's value count during testing.
2025-01-06 00:32:21 +00:00
Trevor Gross
9a7a519370 Streamline the way that test iteration count is determined
Currently, tests use a handful of constants to determine how many
iterations to perform: `NTESTS`, `AROUND`, and `MAX_CHECK_POINTS`. This
configuration is not very straightforward to adjust and needs to be
repeated everywhere it is used.

Replace this with new functions in the `run_cfg` module that determine
iteration counts in a more reusable and documented way.

This only updates `edge_cases` and `domain_logspace`, `random` is
refactored in a later commit.
2025-01-06 00:32:21 +00:00
Trevor Gross
b7b22b54c0 Add a way for tests to log to a file
Occasionally it is useful to see some information from running tests
without making everything noisy from `--nocapture`. Add a function to
log this kind of output to a file, and print the file as part of CI.
2025-01-06 00:32:21 +00:00
Trevor Gross
4b15d9e5e3 Add tests against MPFR for scalbn{f} and ldexp{f} 2025-01-05 18:49:54 -05:00
Trevor Gross
e9bc33e8d3 Add tests against MPFR for frexp and frexpf
This implementation comes from `rug::Float::to_f32_exp` [1].

[1]: https://docs.rs/rug/1.26.1/rug/struct.Float.html#method.to_f32_exp
2025-01-05 18:33:20 -05:00
Trevor Gross
59964fbbca Add tests against MPFR for modf and modff
Rug provides `trunc_fract_round`, which implements `modf`, use it to add
a test.
2025-01-05 18:17:27 -05:00
Trevor Gross
f99d8acc20 Clean up integers stored in MpTy
There isn't any need to cache the integer since it gets provided as an
argument anyway. Simplify this in `jn` and `yn`.
2025-01-04 21:25:22 -05:00
Trevor Gross
d50c12b219 precision: Sort ilogb with other precise operations
This is a nonfunctional change.
2025-01-04 06:32:38 -05:00
Trevor Gross
3030182c66 Change to exhaustive matching for default_ulp
Make it more obvious what the expected ULP for a given routine is. This
also narrows ULP to 0 for operations that require exact results.
2025-01-03 18:47:34 -05:00
Trevor Gross
14e6d05dfb Use intrinsics for abs and copysign when available
Currently our implementations for `abs` and `copysign` are defined on
the trait, and these are then called from `generic`. It would be better
to call core's `.abs()` / `.copysign(y)`, but we can't do this in the
generic because calling the standalone function could become recursive
(`fabsf` becomes `intrinsics::fabsf32`, that may lower to a call to
`fabsf`).

Change this so the traits uses the call to `core` if available, falling
back to a call to the standalone generic function.

In practice the recursion isn't likely to be a problem since LLVM
probably always lowers `abs`/`copysign` to assembly, but this pattern
should be more correct for functions that we will add in the future
(e.g. `fma`).

This should eventually be followed by a change to call the trait methods
rather than `fabs`/`copysign` directly.
2025-01-03 07:50:56 -05:00
Trevor Gross
a277ec6954 Rename generic abs to fabs
Using the same name as the routines themselves means this will correctly
get picked up by the CI job looking for exhaustive tests.
2025-01-02 18:01:45 -05:00
Trevor Gross
3fb16fbdbe macros: Always emit f16_enabled and f128_enabled attributes
Once we start addinf `f16` and `f128` routines, we will need to have
this cfg for almost all uses of `for_each_function`. Rather than needing
to specify this each time, always emit `#[cfg(f16_enabled)]` or
`#[cfg(f128_enabled)]` for each function that uses `f16` or `f128`,
respectively.
2025-01-02 17:38:09 -05:00
Trevor Gross
e754ecb6d9 Add missing functions to the macro list
Now that we are using rustdoc output to locate public functions, the
test is indicating a few that were missed since they don't have their
own function. Update everything to now include the following routines:

* `erfc`
* `erfcf`
* `y0`
* `y0f`
* `y1`
* `y1f`
* `yn`
* `ynf`
2025-01-01 11:15:48 +00:00
Trevor Gross
ed72c4ec69 Use rustdoc output to create a list of public API
Rather than collecting a list of file names in `libm-test/build.rs`,
just use a script to parse rustdoc's JSON output.
2025-01-01 11:01:50 +00:00
Trevor Gross
489524413b Forward the CI environment variable when running in Docker
We want to be able to adjust our configuration based on whether we are
running in CI, propagate this so our tests can use it.
2025-01-01 10:56:56 +00:00
Trevor Gross
cf58a7ce90 Remove lossy casting in logspace
Currently `logspace` does a lossy cast from `F::Int` to `usize`. This
could be problematic in the rare cases that this is called with a step
count exceeding what is representable in `usize`.

Resolve this by instead adding bounds so the float's integer type itself
can be iterated.
2024-12-30 01:11:59 -05:00
Trevor Gross
e8c501861a Set the allowed FMA ULP to 0
It is currently getting the default of 1 or 2. Since this operation
should always be infinite precision, no deviation is allowed.
2024-12-29 21:10:57 -05:00