Skip to content
This repository was archived by the owner on Apr 28, 2025. It is now read-only.

Test against MPFR #311

Merged
merged 3 commits into from
Oct 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ci/docker/aarch64-unknown-linux-gnu/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ FROM ubuntu:24.04
RUN apt-get update && \
apt-get install -y --no-install-recommends \
gcc libc6-dev ca-certificates \
gcc-aarch64-linux-gnu libc6-dev-arm64-cross \
gcc-aarch64-linux-gnu m4 make libc6-dev-arm64-cross \
qemu-user-static

ENV TOOLCHAIN_PREFIX=aarch64-linux-gnu-
Expand Down
2 changes: 1 addition & 1 deletion ci/docker/i686-unknown-linux-gnu/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ FROM ubuntu:24.04

RUN apt-get update && \
apt-get install -y --no-install-recommends \
gcc-multilib libc6-dev ca-certificates
gcc-multilib m4 make libc6-dev ca-certificates
2 changes: 1 addition & 1 deletion ci/docker/x86_64-unknown-linux-gnu/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ FROM ubuntu:24.04

RUN apt-get update && \
apt-get install -y --no-install-recommends \
gcc libc6-dev ca-certificates
gcc m4 make libc6-dev ca-certificates
16 changes: 16 additions & 0 deletions ci/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,22 @@ case "$target" in
*) extra_flags="$extra_flags --features libm-test/build-musl" ;;
esac

# Configure which targets test against MPFR
case "$target" in
# MSVC cannot link MPFR
*windows-msvc*) ;;
# FIXME: MinGW should be able to build MPFR, but setup in CI is nontrivial.
*windows-gnu*) ;;
# Targets that aren't cross compiled work fine
# FIXME(ci): we should be able to enable aarch64 Linux here once GHA
# support rolls out.
x86_64*) extra_flags="$extra_flags --features libm-test/test-multiprecision" ;;
# i686 works fine, i586 does not
i686*) extra_flags="$extra_flags --features libm-test/test-multiprecision" ;;
# Apple aarch64 is native
aarch64*apple*) extra_flags="$extra_flags --features libm-test/test-multiprecision" ;;
esac

# FIXME: `STATUS_DLL_NOT_FOUND` testing macros on CI.
# <https://github.com/rust-lang/rust/issues/128944>
case "$target" in
Expand Down
3 changes: 3 additions & 0 deletions crates/libm-test/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,21 @@ default = []
# Generate tests which are random inputs and the outputs are calculated with
# musl libc.
test-musl-serialized = ["rand"]
test-multiprecision = ["dep:az", "dep:rug"]

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

[dependencies]
anyhow = "1.0.90"
az = { version = "1.2.1", optional = true }
libm = { path = "../.." }
libm-macros = { path = "../libm-macros" }
musl-math-sys = { path = "../musl-math-sys", optional = true }
paste = "1.0.15"
rand = "0.8.5"
rand_chacha = "0.3.1"
rug = { version = "1.26.1", optional = true, default-features = false, features = ["float", "std"] }

[target.'cfg(target_family = "wasm")'.dependencies]
# Enable randomness on WASM
Expand Down
16 changes: 8 additions & 8 deletions crates/libm-test/src/gen/random.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use rand::{Rng, SeedableRng};
use rand_chacha::ChaCha8Rng;

use super::CachedInput;
use crate::GenerateInput;
use crate::{CheckCtx, GenerateInput};

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

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

// These functions are extremely slow, limit them
cases.inputs_i32.truncate((NTESTS / 1000).max(80));
cases.inputs_f32.truncate((NTESTS / 1000).max(80));
cases.inputs_f64.truncate((NTESTS / 1000).max(80));
let ntests_jn = (NTESTS / 1000).max(80);
cases.inputs_i32.truncate(ntests_jn);
cases.inputs_f32.truncate(ntests_jn);
cases.inputs_f64.truncate(ntests_jn);

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

/// Create a test case iterator.
pub fn get_test_cases<RustArgs>(fname: &str) -> impl Iterator<Item = RustArgs>
pub fn get_test_cases<RustArgs>(ctx: &CheckCtx) -> impl Iterator<Item = RustArgs>
where
CachedInput: GenerateInput<RustArgs>,
{
let inputs = if fname == "jn" || fname == "jnf" { &TEST_CASES_JN } else { &TEST_CASES };

CachedInput::get_cases(inputs)
let inputs = if ctx.fname == "jn" || ctx.fname == "jnf" { &TEST_CASES_JN } else { &TEST_CASES };
inputs.get_cases()
}
31 changes: 29 additions & 2 deletions crates/libm-test/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
pub mod gen;
#[cfg(feature = "test-multiprecision")]
pub mod mpfloat;
mod num_traits;
mod special_case;
mod test_traits;
Expand All @@ -14,14 +16,18 @@ pub type TestResult<T = (), E = anyhow::Error> = Result<T, E>;
// List of all files present in libm's source
include!(concat!(env!("OUT_DIR"), "/all_files.rs"));

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

/// Certain functions have different allowed ULP (consider these xfail).
/// Default ULP allowed to differ from multiprecision (i.e. infinite) results.
const MULTIPREC_DEFAULT_ULP: u32 = 1;

/// ULP allowed to differ from muls results.
///
/// Note that these results were obtained using 400,000,000 rounds of random inputs, which
/// is not a value used by default.
pub fn musl_allowed_ulp(name: &str) -> u32 {
// Consider overrides xfail
match name {
#[cfg(x86_no_sse)]
"asinh" | "asinhf" => 6,
Expand All @@ -42,6 +48,27 @@ pub fn musl_allowed_ulp(name: &str) -> u32 {
}
}

/// ULP allowed to differ from multiprecision results.
pub fn multiprec_allowed_ulp(name: &str) -> u32 {
// Consider overrides xfail
match name {
"asinh" | "asinhf" => 2,
"acoshf" => 4,
"atanh" | "atanhf" => 2,
"exp10" | "exp10f" => 3,
"j0" | "j0f" | "j1" | "j1f" => {
// Results seem very target-dependent
if cfg!(target_arch = "x86_64") { 4000 } else { 800_000 }
}
"jn" | "jnf" => 1000,
"lgamma" | "lgammaf" | "lgamma_r" | "lgammaf_r" => 16,
"sinh" | "sinhf" => 2,
"tanh" | "tanhf" => 2,
"tgamma" => 20,
_ => MULTIPREC_DEFAULT_ULP,
}
}

/// Return the unsuffixed version of a function name; e.g. `abs` and `absf` both return `abs`,
/// `lgamma_r` and `lgammaf_r` both return `lgamma_r`.
pub fn canonical_name(name: &str) -> &str {
Expand Down
Loading