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

Commit 82a5c69

Browse files
committed
Migrate libm-bench to libm-analyze
1 parent 1d77d0a commit 82a5c69

File tree

7 files changed

+73
-133
lines changed

7 files changed

+73
-133
lines changed

crates/libm-analyze/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ macro_rules! nop {
88
id: $id:ident;
99
arg_tys: $($arg_tys:ty),*;
1010
arg_ids: $($arg_ids:ident),*;
11-
ret: $ty:ty;
11+
ret_ty: $ty:ty;
1212
) => {};
1313
}
1414

crates/libm-analyze/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ pub fn for_each_api(input: TokenStream) -> TokenStream {
2727
id: #id;
2828
arg_tys: #(#arg_tys),*;
2929
arg_ids: #(#arg_ids),*;
30-
ret: #ret_ty;
30+
ret_ty: #ret_ty;
3131
}
3232
};
3333
tokens.extend(t);

crates/libm-analyze/tests/analyze.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ macro_rules! nop {
66
id: $id:ident;
77
arg_tys: $($arg_tys:ty),*;
88
arg_ids: $($arg_ids:ident),*;
9-
ret: $ty:ty;
9+
ret_ty: $ret_ty:ty;
1010
) => {};
1111
}
1212

crates/libm-bench/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@ license = "MIT OR Apache-2.0"
77

88
[dependencies]
99
libm = { path = "../libm", default-features = false }
10+
libm-analyze = { path = "../libm-analyze", default-features = false }
11+
libm-test = { path = "../libm-test", default-features = false }
1012
rand = "0.6.5"
11-
paste = "0.1.5"
1213

1314
[features]
1415
default = []

crates/libm-bench/benches/bench.rs

Lines changed: 34 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -1,115 +1,44 @@
11
#![feature(test)]
22
extern crate test;
33

4+
use libm_test::{adjust_input, Call};
45
use rand::Rng;
56
use test::Bencher;
67

7-
macro_rules! unary {
8-
($($func:ident),*) => ($(
9-
paste::item! {
10-
#[bench]
11-
pub fn [<$func>](bh: &mut Bencher) {
12-
let mut rng = rand::thread_rng();
13-
let x = rng.gen::<f64>();
14-
bh.iter(|| test::black_box(libm::[<$func>](x)))
15-
}
16-
#[bench]
17-
pub fn [<$func f>](bh: &mut Bencher) {
18-
let mut rng = rand::thread_rng();
19-
let x = rng.gen::<f32>();
20-
bh.iter(|| test::black_box(libm::[<$func f>](x)))
21-
}
22-
}
23-
)*);
24-
}
25-
macro_rules! binary {
26-
($($func:ident),*) => ($(
27-
paste::item! {
28-
#[bench]
29-
pub fn [<$func>](bh: &mut Bencher) {
30-
let mut rng = rand::thread_rng();
31-
let x = rng.gen::<f64>();
32-
let y = rng.gen::<f64>();
33-
bh.iter(|| test::black_box(libm::[<$func>](x, y)))
34-
}
35-
#[bench]
36-
pub fn [<$func f>](bh: &mut Bencher) {
37-
let mut rng = rand::thread_rng();
38-
let x = rng.gen::<f32>();
39-
let y = rng.gen::<f32>();
40-
bh.iter(|| test::black_box(libm::[<$func f>](x, y)))
41-
}
42-
}
43-
)*);
44-
($($func:ident);*) => ($(
45-
paste::item! {
46-
#[bench]
47-
pub fn [<$func>](bh: &mut Bencher) {
48-
let mut rng = rand::thread_rng();
49-
let x = rng.gen::<f64>();
50-
let n = rng.gen::<i32>();
51-
bh.iter(|| test::black_box(libm::[<$func>](x, n)))
52-
}
53-
#[bench]
54-
pub fn [<$func f>](bh: &mut Bencher) {
55-
let mut rng = rand::thread_rng();
56-
let x = rng.gen::<f32>();
57-
let n = rng.gen::<i32>();
58-
bh.iter(|| test::black_box(libm::[<$func f>](x, n)))
59-
}
60-
}
61-
)*);
62-
}
63-
macro_rules! trinary {
64-
($($func:ident),*) => ($(
65-
paste::item! {
66-
#[bench]
67-
pub fn [<$func>](bh: &mut Bencher) {
68-
let mut rng = rand::thread_rng();
69-
let x = rng.gen::<f64>();
70-
let y = rng.gen::<f64>();
71-
let z = rng.gen::<f64>();
72-
bh.iter(|| test::black_box(libm::[<$func>](x, y, z)))
73-
}
74-
#[bench]
75-
pub fn [<$func f>](bh: &mut Bencher) {
76-
let mut rng = rand::thread_rng();
77-
let x = rng.gen::<f32>();
78-
let y = rng.gen::<f32>();
79-
let z = rng.gen::<f32>();
80-
bh.iter(|| test::black_box(libm::[<$func f>](x, y, z)))
81-
}
82-
}
83-
)*);
84-
}
85-
macro_rules! bessel {
86-
($($func:ident),*) => ($(
87-
paste::item! {
88-
#[bench]
89-
pub fn [<$func>](bh: &mut Bencher) {
90-
let mut rng = rand::thread_rng();
91-
let mut n = rng.gen::<i32>();
92-
n &= 0xffff;
93-
let x = rng.gen::<f64>();
94-
bh.iter(|| test::black_box(libm::[<$func>](n, x)))
95-
}
96-
#[bench]
97-
pub fn [<$func f>](bh: &mut Bencher) {
8+
macro_rules! bench_fn {
9+
// FIXME: jnf benches never terminate
10+
(
11+
id: jnf;
12+
arg_tys: $($arg_tys:ty),*;
13+
arg_ids: $($arg_ids:ident),*;
14+
ret_ty: $ret_ty:ty;
15+
) => {};
16+
(
17+
id: $id:ident;
18+
arg_tys: $($arg_tys:ty),*;
19+
arg_ids: $($arg_ids:ident),*;
20+
ret_ty: $ret_ty:ty;
21+
) => {
22+
#[bench]
23+
#[allow(unused_mut)]
24+
pub fn $id(bh: &mut Bencher) {
25+
// Type of the system libm fn:
26+
type FnTy = unsafe extern "C" fn ($($arg_ids: $arg_tys),*) -> $ret_ty;
27+
28+
// FIXME: extern "C" wrapper
29+
extern "C" fn libm_fn($($arg_ids: $arg_tys),*) -> $ret_ty {
30+
libm::$id($($arg_ids),*)
31+
}
32+
33+
// Generate a tuple of arguments containing random values:
9834
let mut rng = rand::thread_rng();
99-
let mut n = rng.gen::<i32>();
100-
n &= 0xffff;
101-
let x = rng.gen::<f32>();
102-
bh.iter(|| test::black_box(libm::[<$func f>](n, x)))
35+
let mut x: ( $($arg_tys,)+ ) = ( $(rng.gen::<$arg_tys>(),)+ );
36+
37+
adjust_input!(fn: $id, input: x);
38+
39+
bh.iter(|| test::black_box(x).call(libm_fn as FnTy))
10340
}
104-
}
105-
)*);
41+
};
10642
}
10743

108-
unary!(
109-
acos, acosh, asin, atan, cbrt, ceil, cos, cosh, erf, exp, exp2, exp10, expm1, fabs, floor, j0,
110-
j1, lgamma, log, log1p, log2, log10, round, sin, sinh, sqrt, tan, tanh, tgamma, trunc, y0, y1
111-
);
112-
binary!(atan2, copysign, fdim, fmax, fmin, fmod, hypot, pow);
113-
trinary!(fma);
114-
bessel!(jn, yn);
115-
binary!(ldexp; scalbn);
44+
libm_analyze::for_each_api!(bench_fn);

crates/libm-test/src/lib.rs

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,6 @@ pub trait WithinUlps {
55
fn within_ulps(self, other: Self, ulp_tol: usize) -> bool;
66
}
77

8-
// TODO: this should be moved to the libm-test/src/lib.rs library. And we
9-
// should make ulps configurable.
10-
118
// Stamp the impls for floats:
129
macro_rules! impl_within_ulps_f {
1310
($f_ty:ty, $i_ty:ty) => {
@@ -65,7 +62,6 @@ pub trait Call<F> {
6562

6663
macro_rules! impl_call {
6764
(($($arg_tys:ty),*) -> $ret_ty:ty: $self_:ident: $($xs:expr),*) => {
68-
// We only care about unsafe extern "C" functions here, safe functions coerce to them:
6965
impl Call<unsafe extern"C" fn($($arg_tys),*) -> $ret_ty> for ($($arg_tys,)+) {
7066
type Ret = $ret_ty;
7167
fn call(self, f: unsafe extern "C" fn($($arg_tys),*) -> $ret_ty) -> Self::Ret {
@@ -88,3 +84,23 @@ impl_call!((i32, f64) -> f64: x: x.0, x.1);
8884
impl_call!((i32, f32) -> f32: x: x.0, x.1);
8985
impl_call!((f32, f32, f32) -> f32: x: x.0, x.1, x.2);
9086
impl_call!((f64, f64, f64) -> f64: x: x.0, x.1, x.2);
87+
88+
// Adjust the input of a function.
89+
#[macro_export]
90+
macro_rules! adjust_input {
91+
(fn: j1, input: $arg:ident) => {
92+
adjust_input!(adjust: $arg)
93+
};
94+
(fn: jn, input: $arg:ident) => {
95+
adjust_input!(adjust: $arg)
96+
};
97+
(fn: $id:ident, input: $args:ident) => {};
98+
(adjust: $arg:ident) => {
99+
// First argument to these functions are a number of
100+
// iterations and passing large random numbers takes forever
101+
// to execute, so check if their higher bits are set and
102+
// zero them:
103+
let p = &mut $arg as *mut _ as *mut i32;
104+
unsafe { p.write(p.read() & 0xff_ffff) }
105+
};
106+
}

crates/libm-test/tests/system_libm.rs

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
//! Compare the results of the `libm` implementation against the system's libm.
22
#![cfg(test)]
3-
#![cfg(feature = "system_libm")]
3+
//#![cfg(feature = "system_libm")]
44

5-
use libm_test::{Call, WithinUlps};
5+
use libm_test::{adjust_input, Call, WithinUlps};
66

77
// Number of tests to generate for each function
88
const NTESTS: usize = 500;
@@ -18,57 +18,57 @@ macro_rules! system_libm {
1818
id: j0f;
1919
arg_tys: $($arg_tys:ty),*;
2020
arg_ids: $($arg_ids:ident),*;
21-
ret: $ret_ty:ty;
21+
ret_ty: $ret_ty:ty;
2222
) => {};
2323
(
2424
id: j1f;
2525
arg_tys: $($arg_tys:ty),*;
2626
arg_ids: $($arg_ids:ident),*;
27-
ret: $ret_ty:ty;
27+
ret_ty: $ret_ty:ty;
2828
) => {};
2929
(
3030
id: jnf;
3131
arg_tys: $($arg_tys:ty),*;
3232
arg_ids: $($arg_ids:ident),*;
33-
ret: $ret_ty:ty;
33+
ret_ty: $ret_ty:ty;
3434
) => {};
3535
(
3636
id: y0f;
3737
arg_tys: $($arg_tys:ty),*;
3838
arg_ids: $($arg_ids:ident),*;
39-
ret: $ret_ty:ty;
39+
ret_ty: $ret_ty:ty;
4040
) => {};
4141
(
4242
id: y1f;
4343
arg_tys: $($arg_tys:ty),*;
4444
arg_ids: $($arg_ids:ident),*;
45-
ret: $ret_ty:ty;
45+
ret_ty: $ret_ty:ty;
4646
) => {};
4747
(
4848
id: ynf;
4949
arg_tys: $($arg_tys:ty),*;
5050
arg_ids: $($arg_ids:ident),*;
51-
ret: $ret_ty:ty;
51+
ret_ty: $ret_ty:ty;
5252
) => {};
5353
(
5454
id: exp10;
5555
arg_tys: $($arg_tys:ty),*;
5656
arg_ids: $($arg_ids:ident),*;
57-
ret: $ret_ty:ty;
57+
ret_ty: $ret_ty:ty;
5858
) => {};
5959
(
6060
id: exp10f;
6161
arg_tys: $($arg_tys:ty),*;
6262
arg_ids: $($arg_ids:ident),*;
63-
ret: $ret_ty:ty;
63+
ret_ty: $ret_ty:ty;
6464
) => {};
6565

6666
// Generate random tests for all others:
6767
(
6868
id: $id:ident;
6969
arg_tys: $($arg_tys:ty),*;
7070
arg_ids: $($arg_ids:ident),*;
71-
ret: $ret_ty:ty;
71+
ret_ty: $ret_ty:ty;
7272
) => {
7373
#[test]
7474
#[allow(unused)]
@@ -91,15 +91,9 @@ macro_rules! system_libm {
9191
// Generate a tuple of arguments containing random values:
9292
let mut args: ( $($arg_tys,)+ ) = ( $(<$arg_tys as Rand>::gen(&mut rng),)+ );
9393

94-
// HACK
95-
if let "j1" | "jn" = stringify!($id) {
96-
// First argument to these functions are a number of
97-
// iterations and passing large random numbers takes forever
98-
// to execute, so check if their higher bits are set and
99-
// zero them:
100-
let p = &mut args as *mut _ as *mut i32;
101-
unsafe { p.write(p.read() & 0xffff) }
102-
}
94+
// Some APIs need their inputs to be "adjusted" (see macro):
95+
// correct_input!(fn: $id, input: args);
96+
adjust_input!(fn: $id, input: args);
10397

10498
let result = args.call(libm_fn as FnTy);
10599
let expected = args.call($id as FnTy);

0 commit comments

Comments
 (0)