Skip to content

Commit 7c41830

Browse files
committed
Rework tests to make use of the new MathOp trait
1 parent f2dcd27 commit 7c41830

File tree

5 files changed

+278
-315
lines changed

5 files changed

+278
-315
lines changed

crates/libm-test/benches/random.rs

Lines changed: 77 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -2,72 +2,103 @@ use std::hint::black_box;
22
use std::time::Duration;
33

44
use criterion::{Criterion, criterion_main};
5-
use libm_test::gen::random;
6-
use libm_test::{CheckBasis, CheckCtx, TupleCall};
5+
use libm_test::gen::{CachedInput, random};
6+
use libm_test::{CheckBasis, CheckCtx, GenerateInput, MathOp, TupleCall};
77

88
/// Benchmark with this many items to get a variety
99
const BENCH_ITER_ITEMS: usize = if cfg!(feature = "short-benchmarks") { 50 } else { 500 };
1010

11+
/// Extra parameters we only care about if we are benchmarking against musl.
12+
#[allow(dead_code)]
13+
struct MuslExtra<F> {
14+
musl_fn: Option<F>,
15+
skip_on_i586: bool,
16+
}
17+
1118
macro_rules! musl_rand_benches {
1219
(
1320
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,
2021
fn_extra: $skip_on_i586:expr,
2122
) => {
2223
paste::paste! {
2324
fn [< musl_bench_ $fn_name >](c: &mut Criterion) {
24-
let fn_name = stringify!($fn_name);
25-
26-
let ulp = libm_test::musl_allowed_ulp(fn_name);
27-
let ctx = CheckCtx::new(ulp, fn_name, CheckBasis::Musl);
28-
let benchvec: Vec<_> = random::get_test_cases::<$RustArgs>(&ctx)
29-
.take(BENCH_ITER_ITEMS)
30-
.collect();
25+
type Op = libm_test::op::$fn_name::Routine;
3126

32-
// Perform a sanity check that we are benchmarking the same thing
33-
// Don't test against musl if it is not available
3427
#[cfg(feature = "build-musl")]
35-
for input in benchvec.iter().copied() {
36-
use anyhow::Context;
37-
use libm_test::{CheckBasis, CheckCtx, CheckOutput};
28+
let musl_extra = MuslExtra {
29+
musl_fn: Some(musl_math_sys::$fn_name as <Op as MathOp>::CFn),
30+
skip_on_i586: $skip_on_i586
31+
};
32+
33+
#[cfg(not(feature = "build-musl"))]
34+
let musl_extra = MuslExtra {
35+
musl_fn: None,
36+
skip_on_i586: $skip_on_i586
37+
};
38+
39+
bench_one::<Op>(c, musl_extra);
40+
}
41+
}
42+
};
43+
}
3844

39-
if cfg!(x86_no_sse) && $skip_on_i586 {
40-
break;
41-
}
45+
fn bench_one<Op>(c: &mut Criterion, musl_extra: MuslExtra<Op::CFn>)
46+
where
47+
Op: MathOp,
48+
CachedInput: GenerateInput<Op::RustArgs>,
49+
{
50+
let name = Op::NAME_STR;
51+
52+
let ulp = libm_test::musl_allowed_ulp(name);
53+
let ctx = CheckCtx::new(ulp, name, CheckBasis::Musl);
54+
let benchvec: Vec<_> =
55+
random::get_test_cases::<Op::RustArgs>(&ctx).take(BENCH_ITER_ITEMS).collect();
56+
57+
// Perform a sanity check that we are benchmarking the same thing
58+
// Don't test against musl if it is not available
59+
#[cfg(feature = "build-musl")]
60+
for input in benchvec.iter().copied() {
61+
use anyhow::Context;
62+
use libm_test::CheckOutput;
63+
64+
if cfg!(x86_no_sse) && musl_extra.skip_on_i586 {
65+
break;
66+
}
4267

43-
let musl_res = input.call(musl_math_sys::$fn_name as $CFn);
44-
let crate_res = input.call(libm::$fn_name as $RustFn);
68+
let musl_res = input.call(musl_extra.musl_fn.unwrap());
69+
let crate_res = input.call(Op::ROUTINE);
4570

46-
let ctx = CheckCtx::new(ulp, fn_name, CheckBasis::Musl);
47-
crate_res.validate(musl_res, input, &ctx).context(fn_name).unwrap();
48-
}
71+
crate_res.validate(musl_res, input, &ctx).context(name).unwrap();
72+
}
4973

50-
/* Function pointers are black boxed to avoid inlining in the benchmark loop */
74+
#[cfg(not(feature = "build-musl"))]
75+
let _ = musl_extra; // silence unused warnings
5176

52-
let mut group = c.benchmark_group(fn_name);
53-
group.bench_function("crate", |b| b.iter(|| {
54-
let f = black_box(libm::$fn_name as $RustFn);
55-
for input in benchvec.iter().copied() {
56-
input.call(f);
57-
}
58-
}));
77+
/* Option pointers are black boxed to avoid inlining in the benchmark loop */
5978

60-
// Don't test against musl if it is not available
61-
#[cfg(feature = "build-musl")]
62-
group.bench_function("musl", |b| b.iter(|| {
63-
let f = black_box(musl_math_sys::$fn_name as $CFn);
64-
for input in benchvec.iter().copied() {
65-
input.call(f);
66-
}
67-
}));
79+
let mut group = c.benchmark_group(name);
80+
group.bench_function("crate", |b| {
81+
b.iter(|| {
82+
let f = black_box(Op::ROUTINE);
83+
for input in benchvec.iter().copied() {
84+
input.call(f);
6885
}
69-
}
70-
};
86+
})
87+
});
88+
89+
// Don't test against musl if it is not available
90+
#[cfg(feature = "build-musl")]
91+
{
92+
let musl_fn = musl_extra.musl_fn.unwrap();
93+
group.bench_function("musl", |b| {
94+
b.iter(|| {
95+
let f = black_box(musl_fn);
96+
for input in benchvec.iter().copied() {
97+
input.call(f);
98+
}
99+
})
100+
});
101+
}
71102
}
72103

73104
libm_macros::for_each_function! {
@@ -83,12 +114,6 @@ libm_macros::for_each_function! {
83114
macro_rules! run_callback {
84115
(
85116
fn_name: $fn_name:ident,
86-
CFn: $_CFn:ty,
87-
CArgs: $_CArgs:ty,
88-
CRet: $_CRet:ty,
89-
RustFn: $_RustFn:ty,
90-
RustArgs: $_RustArgs:ty,
91-
RustRet: $_RustRet:ty,
92117
extra: [$criterion:ident],
93118
) => {
94119
paste::paste! {

0 commit comments

Comments
 (0)