Skip to content

Commit 47bfc9b

Browse files
authored
Merge pull request rust-lang#311 from tgross35/mpfr-test
Test against MPFR
2 parents 4b89115 + 2dbbebd commit 47bfc9b

File tree

12 files changed

+620
-52
lines changed

12 files changed

+620
-52
lines changed

ci/docker/aarch64-unknown-linux-gnu/Dockerfile

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ FROM ubuntu:24.04
33
RUN apt-get update && \
44
apt-get install -y --no-install-recommends \
55
gcc libc6-dev ca-certificates \
6-
gcc-aarch64-linux-gnu libc6-dev-arm64-cross \
6+
gcc-aarch64-linux-gnu m4 make libc6-dev-arm64-cross \
77
qemu-user-static
88

99
ENV TOOLCHAIN_PREFIX=aarch64-linux-gnu-

ci/docker/i686-unknown-linux-gnu/Dockerfile

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ FROM ubuntu:24.04
22

33
RUN apt-get update && \
44
apt-get install -y --no-install-recommends \
5-
gcc-multilib libc6-dev ca-certificates
5+
gcc-multilib m4 make libc6-dev ca-certificates

ci/docker/x86_64-unknown-linux-gnu/Dockerfile

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ FROM ubuntu:24.04
22

33
RUN apt-get update && \
44
apt-get install -y --no-install-recommends \
5-
gcc libc6-dev ca-certificates
5+
gcc m4 make libc6-dev ca-certificates

ci/run.sh

+16
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,22 @@ case "$target" in
3535
*) extra_flags="$extra_flags --features libm-test/build-musl" ;;
3636
esac
3737

38+
# Configure which targets test against MPFR
39+
case "$target" in
40+
# MSVC cannot link MPFR
41+
*windows-msvc*) ;;
42+
# FIXME: MinGW should be able to build MPFR, but setup in CI is nontrivial.
43+
*windows-gnu*) ;;
44+
# Targets that aren't cross compiled work fine
45+
# FIXME(ci): we should be able to enable aarch64 Linux here once GHA
46+
# support rolls out.
47+
x86_64*) extra_flags="$extra_flags --features libm-test/test-multiprecision" ;;
48+
# i686 works fine, i586 does not
49+
i686*) extra_flags="$extra_flags --features libm-test/test-multiprecision" ;;
50+
# Apple aarch64 is native
51+
aarch64*apple*) extra_flags="$extra_flags --features libm-test/test-multiprecision" ;;
52+
esac
53+
3854
# FIXME: `STATUS_DLL_NOT_FOUND` testing macros on CI.
3955
# <https://github.com/rust-lang/rust/issues/128944>
4056
case "$target" in

crates/libm-test/Cargo.toml

+3
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,21 @@ default = []
1010
# Generate tests which are random inputs and the outputs are calculated with
1111
# musl libc.
1212
test-musl-serialized = ["rand"]
13+
test-multiprecision = ["dep:az", "dep:rug"]
1314

1415
# Build our own musl for testing and benchmarks
1516
build-musl = ["dep:musl-math-sys"]
1617

1718
[dependencies]
1819
anyhow = "1.0.90"
20+
az = { version = "1.2.1", optional = true }
1921
libm = { path = "../.." }
2022
libm-macros = { path = "../libm-macros" }
2123
musl-math-sys = { path = "../musl-math-sys", optional = true }
2224
paste = "1.0.15"
2325
rand = "0.8.5"
2426
rand_chacha = "0.3.1"
27+
rug = { version = "1.26.1", optional = true, default-features = false, features = ["float", "std"] }
2528

2629
[target.'cfg(target_family = "wasm")'.dependencies]
2730
# Enable randomness on WASM

crates/libm-test/src/gen/random.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use rand::{Rng, SeedableRng};
77
use rand_chacha::ChaCha8Rng;
88

99
use super::CachedInput;
10-
use crate::GenerateInput;
10+
use crate::{CheckCtx, GenerateInput};
1111

1212
const SEED: [u8; 32] = *b"3.141592653589793238462643383279";
1313

@@ -40,9 +40,10 @@ static TEST_CASES_JN: LazyLock<CachedInput> = LazyLock::new(|| {
4040
let mut cases = (&*TEST_CASES).clone();
4141

4242
// These functions are extremely slow, limit them
43-
cases.inputs_i32.truncate((NTESTS / 1000).max(80));
44-
cases.inputs_f32.truncate((NTESTS / 1000).max(80));
45-
cases.inputs_f64.truncate((NTESTS / 1000).max(80));
43+
let ntests_jn = (NTESTS / 1000).max(80);
44+
cases.inputs_i32.truncate(ntests_jn);
45+
cases.inputs_f32.truncate(ntests_jn);
46+
cases.inputs_f64.truncate(ntests_jn);
4647

4748
// It is easy to overflow the stack with these in debug mode
4849
let max_iterations = if cfg!(optimizations_enabled) && cfg!(target_pointer_width = "64") {
@@ -105,11 +106,10 @@ fn make_test_cases(ntests: usize) -> CachedInput {
105106
}
106107

107108
/// Create a test case iterator.
108-
pub fn get_test_cases<RustArgs>(fname: &str) -> impl Iterator<Item = RustArgs>
109+
pub fn get_test_cases<RustArgs>(ctx: &CheckCtx) -> impl Iterator<Item = RustArgs>
109110
where
110111
CachedInput: GenerateInput<RustArgs>,
111112
{
112-
let inputs = if fname == "jn" || fname == "jnf" { &TEST_CASES_JN } else { &TEST_CASES };
113-
114-
CachedInput::get_cases(inputs)
113+
let inputs = if ctx.fname == "jn" || ctx.fname == "jnf" { &TEST_CASES_JN } else { &TEST_CASES };
114+
inputs.get_cases()
115115
}

crates/libm-test/src/lib.rs

+29-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
pub mod gen;
2+
#[cfg(feature = "test-multiprecision")]
3+
pub mod mpfloat;
24
mod num_traits;
35
mod special_case;
46
mod test_traits;
@@ -14,14 +16,18 @@ pub type TestResult<T = (), E = anyhow::Error> = Result<T, E>;
1416
// List of all files present in libm's source
1517
include!(concat!(env!("OUT_DIR"), "/all_files.rs"));
1618

17-
/// ULP allowed to differ from musl (note that musl itself may not be accurate).
19+
/// Default ULP allowed to differ from musl (note that musl itself may not be accurate).
1820
const MUSL_DEFAULT_ULP: u32 = 2;
1921

20-
/// Certain functions have different allowed ULP (consider these xfail).
22+
/// Default ULP allowed to differ from multiprecision (i.e. infinite) results.
23+
const MULTIPREC_DEFAULT_ULP: u32 = 1;
24+
25+
/// ULP allowed to differ from muls results.
2126
///
2227
/// Note that these results were obtained using 400,000,000 rounds of random inputs, which
2328
/// is not a value used by default.
2429
pub fn musl_allowed_ulp(name: &str) -> u32 {
30+
// Consider overrides xfail
2531
match name {
2632
#[cfg(x86_no_sse)]
2733
"asinh" | "asinhf" => 6,
@@ -42,6 +48,27 @@ pub fn musl_allowed_ulp(name: &str) -> u32 {
4248
}
4349
}
4450

51+
/// ULP allowed to differ from multiprecision results.
52+
pub fn multiprec_allowed_ulp(name: &str) -> u32 {
53+
// Consider overrides xfail
54+
match name {
55+
"asinh" | "asinhf" => 2,
56+
"acoshf" => 4,
57+
"atanh" | "atanhf" => 2,
58+
"exp10" | "exp10f" => 3,
59+
"j0" | "j0f" | "j1" | "j1f" => {
60+
// Results seem very target-dependent
61+
if cfg!(target_arch = "x86_64") { 4000 } else { 800_000 }
62+
}
63+
"jn" | "jnf" => 1000,
64+
"lgamma" | "lgammaf" | "lgamma_r" | "lgammaf_r" => 16,
65+
"sinh" | "sinhf" => 2,
66+
"tanh" | "tanhf" => 2,
67+
"tgamma" => 20,
68+
_ => MULTIPREC_DEFAULT_ULP,
69+
}
70+
}
71+
4572
/// Return the unsuffixed version of a function name; e.g. `abs` and `absf` both return `abs`,
4673
/// `lgamma_r` and `lgammaf_r` both return `lgamma_r`.
4774
pub fn canonical_name(name: &str) -> &str {

0 commit comments

Comments
 (0)