Skip to content

Commit

Permalink
Add a test against MPFR using random inputs
Browse files Browse the repository at this point in the history
  • Loading branch information
tgross35 committed Oct 21, 2024
1 parent 9af1884 commit 914beca
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 3 deletions.
26 changes: 23 additions & 3 deletions crates/libm-test/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,19 @@ pub use test_traits::{CheckOutput, GenerateInput, TupleCall};
// 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.
///
/// Currently this includes:
/// Current overrides includes:
/// - gamma functions that have higher errors
/// - 32-bit functions fall back to a less precise algorithm.
pub fn musl_allowed_ulp(name: &str) -> u32 {
// Consider overrides xfail
match name {
#[cfg(x86_no_sse)]
"asinhf" => 6,
Expand All @@ -32,3 +36,19 @@ pub fn musl_allowed_ulp(name: &str) -> u32 {
_ => MUSL_DEFAULT_ULP,
}
}

/// ULP allowed to differ from multiprecision results.
pub fn multiprec_allowed_ulp(name: &str) -> u32 {
// Consider overrides xfail
match name {
"asinh" | "asinhf" => 2,
"atanh" | "atanhf" => 2,
"exp10" | "exp10f" => 3,
"j0" | "j0f" => 2,
"lgamma" | "lgammaf" | "lgamma_r" | "lgammaf_r" => 2,
"sinh" | "sinhf" => 2,
"tanh" | "tanhf" => 2,
"tgamma" => 6,
_ => MULTIPREC_DEFAULT_ULP,
}
}
67 changes: 67 additions & 0 deletions crates/libm-test/tests/multiprecision.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
//! Test with "infinite precision"

#![cfg(feature = "multiprecision-tests")]

use libm_test::gen::random;
use libm_test::mpfloat::{self, MpOp};
use libm_test::multiprec_allowed_ulp;
use libm_test::{CheckOutput, TupleCall};

/// Implement a test against MPFR with random inputs.
macro_rules! multiprec_rand_tests {
(
fn_name: $fn_name:ident,
CFn: $CFn:ty,
CArgs: $CArgs:ty,
CRet: $CRet:ty,
RustFn: $RustFn:ty,
RustArgs: $RustArgs:ty,
RustRet: $RustRet:ty,
attrs: [$($meta:meta)*]
) => {
paste::paste! {
#[test]
$(#[$meta])*
fn [< multiprec_random_ $fn_name >]() {
type MpOpTy = mpfloat::$fn_name::Operation;

let fname = stringify!($fn_name);
let ulp = multiprec_allowed_ulp(fname);
let cases = random::get_test_cases::<$RustArgs>(fname);
let mut mp_vals = MpOpTy::new();

for input in cases {
let mp_res = mp_vals.run(input);
let crate_res = input.call(libm::$fn_name as $RustFn);

mp_res.validate(crate_res, input, ulp).unwrap();
}
}
}
};
}

libm_macros::for_each_function! {
callback: multiprec_rand_tests,
attributes: [],
skip: [
// FIXME: MPFR tests needed
frexp,
frexpf,
ilogb,
ilogbf,
ldexp,
ldexpf,
modf,
modff,
remquo,
remquof,
scalbn,
scalbnf,
],
attributes: [
// FIXME: we return NaN, musl returns -NaN
#[cfg_attr(all(target_arch = "x86_64", target_os = "macos"), ignore)]
[acosh, acoshf]
],
}

0 comments on commit 914beca

Please sign in to comment.