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

Commit 914beca

Browse files
committed
Add a test against MPFR using random inputs
1 parent 9af1884 commit 914beca

File tree

2 files changed

+90
-3
lines changed

2 files changed

+90
-3
lines changed

crates/libm-test/src/lib.rs

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,19 @@ pub use test_traits::{CheckOutput, GenerateInput, TupleCall};
1010
// List of all files present in libm's source
1111
include!(concat!(env!("OUT_DIR"), "/all_files.rs"));
1212

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

16-
/// Certain functions have different allowed ULP (consider these xfail).
16+
/// Default ULP allowed to differ from multiprecision (i.e. infinite) results.
17+
const MULTIPREC_DEFAULT_ULP: u32 = 1;
18+
19+
/// ULP allowed to differ from muls results.
1720
///
18-
/// Currently this includes:
21+
/// Current overrides includes:
1922
/// - gamma functions that have higher errors
2023
/// - 32-bit functions fall back to a less precise algorithm.
2124
pub fn musl_allowed_ulp(name: &str) -> u32 {
25+
// Consider overrides xfail
2226
match name {
2327
#[cfg(x86_no_sse)]
2428
"asinhf" => 6,
@@ -32,3 +36,19 @@ pub fn musl_allowed_ulp(name: &str) -> u32 {
3236
_ => MUSL_DEFAULT_ULP,
3337
}
3438
}
39+
40+
/// ULP allowed to differ from multiprecision results.
41+
pub fn multiprec_allowed_ulp(name: &str) -> u32 {
42+
// Consider overrides xfail
43+
match name {
44+
"asinh" | "asinhf" => 2,
45+
"atanh" | "atanhf" => 2,
46+
"exp10" | "exp10f" => 3,
47+
"j0" | "j0f" => 2,
48+
"lgamma" | "lgammaf" | "lgamma_r" | "lgammaf_r" => 2,
49+
"sinh" | "sinhf" => 2,
50+
"tanh" | "tanhf" => 2,
51+
"tgamma" => 6,
52+
_ => MULTIPREC_DEFAULT_ULP,
53+
}
54+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
//! Test with "infinite precision"
2+
3+
#![cfg(feature = "multiprecision-tests")]
4+
5+
use libm_test::gen::random;
6+
use libm_test::mpfloat::{self, MpOp};
7+
use libm_test::multiprec_allowed_ulp;
8+
use libm_test::{CheckOutput, TupleCall};
9+
10+
/// Implement a test against MPFR with random inputs.
11+
macro_rules! multiprec_rand_tests {
12+
(
13+
fn_name: $fn_name:ident,
14+
CFn: $CFn:ty,
15+
CArgs: $CArgs:ty,
16+
CRet: $CRet:ty,
17+
RustFn: $RustFn:ty,
18+
RustArgs: $RustArgs:ty,
19+
RustRet: $RustRet:ty,
20+
attrs: [$($meta:meta)*]
21+
) => {
22+
paste::paste! {
23+
#[test]
24+
$(#[$meta])*
25+
fn [< multiprec_random_ $fn_name >]() {
26+
type MpOpTy = mpfloat::$fn_name::Operation;
27+
28+
let fname = stringify!($fn_name);
29+
let ulp = multiprec_allowed_ulp(fname);
30+
let cases = random::get_test_cases::<$RustArgs>(fname);
31+
let mut mp_vals = MpOpTy::new();
32+
33+
for input in cases {
34+
let mp_res = mp_vals.run(input);
35+
let crate_res = input.call(libm::$fn_name as $RustFn);
36+
37+
mp_res.validate(crate_res, input, ulp).unwrap();
38+
}
39+
}
40+
}
41+
};
42+
}
43+
44+
libm_macros::for_each_function! {
45+
callback: multiprec_rand_tests,
46+
attributes: [],
47+
skip: [
48+
// FIXME: MPFR tests needed
49+
frexp,
50+
frexpf,
51+
ilogb,
52+
ilogbf,
53+
ldexp,
54+
ldexpf,
55+
modf,
56+
modff,
57+
remquo,
58+
remquof,
59+
scalbn,
60+
scalbnf,
61+
],
62+
attributes: [
63+
// FIXME: we return NaN, musl returns -NaN
64+
#[cfg_attr(all(target_arch = "x86_64", target_os = "macos"), ignore)]
65+
[acosh, acoshf]
66+
],
67+
}

0 commit comments

Comments
 (0)