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

Commit c15a115

Browse files
committed
Add a test against MPFR using random inputs
1 parent 2fbe1e8 commit c15a115

File tree

3 files changed

+92
-3
lines changed

3 files changed

+92
-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::{CheckBasis, CheckCtx, CheckOutput, GenerateInput, TupleCal
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
"asinh" | "asinhf" => 6,
@@ -33,6 +37,22 @@ pub fn musl_allowed_ulp(name: &str) -> u32 {
3337
}
3438
}
3539

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+
}
55+
3656
/// If only a few checks are incorrect, xfail them here rather than skipping the entire test.
3757
pub fn xfail<F: Float>(actual: F, expected: F, ctx: &CheckCtx) -> bool {
3858
match (&ctx.basis, ctx.fname) {

crates/libm-test/src/test_traits.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ pub struct CheckCtx {
4141
pub enum CheckBasis {
4242
/// Check against Musl's math sources.
4343
Musl,
44+
/// Check against infinite precision (MPFR).
45+
MultiPrecision,
4446
}
4547

4648
/// A trait to implement on any output type so we can verify it in a generic way.
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::{CheckBasis, CheckCtx, 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+
let ctx = CheckCtx {
33+
ulp,
34+
fname,
35+
basis: CheckBasis::MultiPrecision
36+
};
37+
38+
for input in cases {
39+
let mp_res = mp_vals.run(input);
40+
let crate_res = input.call(libm::$fn_name as $RustFn);
41+
42+
mp_res.validate(crate_res, input, &ctx).unwrap();
43+
}
44+
}
45+
}
46+
};
47+
}
48+
49+
libm_macros::for_each_function! {
50+
callback: multiprec_rand_tests,
51+
attributes: [],
52+
skip: [
53+
// FIXME: MPFR tests needed
54+
frexp,
55+
frexpf,
56+
ilogb,
57+
ilogbf,
58+
ldexp,
59+
ldexpf,
60+
modf,
61+
modff,
62+
remquo,
63+
remquof,
64+
scalbn,
65+
scalbnf,
66+
],
67+
}

0 commit comments

Comments
 (0)