97 Commits

Author SHA1 Message Date
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
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
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
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
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
Trevor Gross
7082f9baf7 Use CheckCtx in more places
Rather than passing names or identifiers, just pass `CheckCtx` in a few
more places.
2024-12-29 03:23:57 -05:00
Trevor Gross
86aeee818b Move CheckBasis and CheckCtx to a new run_cfg module
These are used more places than just test traits, so this new module
should be a better home. `run_cfg` will also be expanded in the near
future.
2024-12-29 03:23:57 -05:00
Trevor Gross
6e97fef9c9 Add ALL, from_str and math_op to Identifier
Introduce new API to iterate the function list and associate items with
their `MathOp`.
2024-12-29 08:07:40 +00:00
Trevor Gross
b9ecacf03b Add new trait implementations for Identifier and BaseName
These allow for more convenient printing, as well as storage in map
types.
2024-12-29 08:07:21 +00:00
Trevor Gross
fc4b88aecd Include shared.rs in libm_test::op
These types from `libm-macros` provide a way to get information about an
operation at runtime, rather than only being encoded in the type system.
Include the file and reexport relevant types.
2024-12-29 08:06:46 +00:00
Trevor Gross
1069346b6d Move the macro's input function list to a new module shared
This will enable us to `include!` the file to access these types in
`libm-test`, rather than somehow reproducing the types as part of the
macro. Ideally `libm-test` would just `use` the types from `libm-macros`
but proc macro crates cannot currently export anything else.

This also adjusts naming to closer match the scheme described in
`libm_test::op`.
2024-12-29 08:03:19 +00:00
Trevor Gross
d86f8bee8b Add a way to plot the output from generators
For visualization, add a simple script for generating scatter plots and
a binary (via examples) to plot the inputs given various domains.
2024-12-29 07:47:21 +00:00
Trevor Gross
3c61c560ac Update allowed precision to account for new tests 2024-12-29 07:47:21 +00:00
Trevor Gross
13611a1b76 Add tests for edge cases
Introduce a generator that will tests various points of interest
including zeros, infinities, and NaNs.
2024-12-29 07:47:21 +00:00
Trevor Gross
a8a2f70ae6 Add interfaces and tests based on function domains
Create a type representing a function's domain and a test that does a
logarithmic sweep of points within the domain.
2024-12-29 07:47:21 +00:00
Trevor Gross
163ed2a133 Introduce a float extension trait and some numerical routines 2024-12-29 07:47:21 +00:00
Trevor Gross
8d224a0de0 Add an 8-bit float type for testing purposes
Introduce `f8`, which is an 8-bit float compliant with IEEE-754. This
type is useful for testing since it is easily possible to enumerate all
values.
2024-12-29 07:47:21 +00:00
Trevor Gross
f2e16b6ac1 Add f16 and f128 configuration from compiler-builtins
In preparation of adding routines from these two types, duplicate the
`compiler-builtins` configuration here.
2024-12-29 02:33:41 -05:00
Trevor Gross
4e5a156cd0 Allow Clippy lints in compiler-builtins-smoke-test
Rather than always needing to exclude `cb` when running `cargo clippy`,
just disable Clippy for the included module.
2024-12-27 11:02:40 +00:00
Trevor Gross
723e68d137 Replace string function name matching with enums where possible 2024-12-26 09:30:47 +00:00
Trevor Gross
ba1d271158 Rename associated type helpers, add OpITy
Change the names to make them less ambiguous. Additionally add `OpITy`
for accessing the same-sized integer of an operation's float type.
2024-12-22 23:56:45 +00:00
Trevor Gross
4cdb9ec674 Introduce helper types for accessing trait items
The ambiguous associated types error sometimes fires in cases where it
shouldn't be ambiguous ([1]), which can make things clunky when working
with chained associated types (e.g. `Op::FTy::Int::*` does not work).
Add helper types that we can use instead of the full syntax.

There aren't too many cases in-crate now but this is relevant for some
open PRs.

[1]: https://github.com/rust-lang/rust/issues/38078
2024-12-22 23:33:02 +00:00
Trevor Gross
76f37552e7 Remove tests against system musl
We now have tests against our custom-built musl as well as tests against
MPFR. The tests against system musl covers less than those against
custom-built musl, and are less portable; there isn't much benefit to
keeping them around so just remove them.
2024-12-22 12:39:27 +00:00
Trevor Gross
9a2774a0ae Move some numeric trait logic to default implementations
There are a handful of functions we can move out of the macro and to the
numeric traits as default implementations; do that here.

Additionally, add some bounds that make sense for completeness.
2024-11-03 21:11:34 -06:00
Trevor Gross
fcf8670668 Change the multiprec_ prefix to mp_
Currently there is a combination of names starting with
`multiprecision_`, `mp_` and `multiprec_`. Update so `multiprecision_`
is always used when a long form makes sense, `mp_` otherwise
(eliminating `multiprec_`).
2024-11-03 20:42:10 -06:00
Trevor Gross
5032fcf139 Change default ULP to use enum matching
Migrate from string to enum matching and tie this to `CheckCtx::new`, so
no tests need to explicitly set ULP.
2024-11-02 23:22:09 -05:00
Trevor Gross
f113f2be1e Rename Name to Identifier to avoid some ambiguity of "name" 2024-11-02 22:42:05 -05:00
Trevor Gross
2fab4f4580 Change the CheckCtx constructor to take a Name enum
This prepares to eliminate some reliance on string matching but does not
yet make those changes.
2024-11-02 22:35:30 -05:00
Trevor Gross
6aef9e17c8 Correct the proc macro to emit pub functions 2024-11-02 17:01:39 -05:00
Trevor Gross
f7f24a4ed8 Rework tests to make use of the new MathOp trait 2024-11-02 16:36:17 -05:00
Trevor Gross
7db74d78e8 Introduce a op module with struct representations of each routine
This contains:

1. Per-function and per-operation enums created by the proc macro
2. The `MathOp` trait which is implemented once per struct representing
   a function
3. Submodules for each function, each containing a `Routine` struct that
   implements `MathOp`
2024-11-02 16:36:17 -05:00