Skip to content

Commit d5c2279

Browse files
committed
Add proptest float tests
1 parent d3c58da commit d5c2279

File tree

12 files changed

+572
-435
lines changed

12 files changed

+572
-435
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22

33
members = [
44
"crates/core_simd",
5+
"crates/test_helpers",
56
]

crates/core_simd/Cargo.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,11 @@ version = "0.2"
1414

1515
[dev-dependencies.wasm-bindgen-test]
1616
version = "0.3"
17+
18+
[dev-dependencies.proptest]
19+
version = "0.10"
20+
default-features = false
21+
features = ["alloc"]
22+
23+
[dev-dependencies.test_helpers]
24+
path = "../test_helpers"

crates/core_simd/src/macros.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,12 @@ macro_rules! impl_vector {
141141
}
142142
}
143143

144+
impl <const LANES: usize> From<$name<LANES>> for [$type; LANES] {
145+
fn from(vector: $name<LANES>) -> Self {
146+
vector.0
147+
}
148+
}
149+
144150
// splat
145151
impl<const LANES: usize> From<$type> for $name<LANES> where Self: crate::LanesAtMost64 {
146152
#[inline]

crates/core_simd/tests/float.rs

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
#[cfg(target_arch = "wasm32")]
2+
wasm_bindgen_test_configure!(run_in_browser);
3+
4+
macro_rules! impl_op_test {
5+
{ unary, $vector:ty, $scalar:ty, $trait:ident :: $fn:ident } => {
6+
test_helpers::test_lanes! {
7+
fn $fn<const LANES: usize>() {
8+
test_helpers::test_unary_elementwise(
9+
<$vector as core::ops::$trait>::$fn,
10+
<$scalar as core::ops::$trait>::$fn,
11+
);
12+
}
13+
}
14+
};
15+
{ binary, $vector:ty, $scalar:ty, $trait:ident :: $fn:ident, $trait_assign:ident :: $fn_assign:ident } => {
16+
mod $fn {
17+
use super::*;
18+
19+
test_helpers::test_lanes! {
20+
fn normal<const LANES: usize>() {
21+
test_helpers::test_binary_elementwise(
22+
<$vector as core::ops::$trait>::$fn,
23+
<$scalar as core::ops::$trait>::$fn,
24+
);
25+
}
26+
27+
fn scalar_rhs<const LANES: usize>() {
28+
test_helpers::test_binary_scalar_rhs_elementwise(
29+
<$vector as core::ops::$trait<$scalar>>::$fn,
30+
<$scalar as core::ops::$trait>::$fn,
31+
);
32+
}
33+
34+
fn scalar_lhs<const LANES: usize>() {
35+
test_helpers::test_binary_scalar_lhs_elementwise(
36+
<$scalar as core::ops::$trait<$vector>>::$fn,
37+
<$scalar as core::ops::$trait>::$fn,
38+
);
39+
}
40+
41+
fn assign<const LANES: usize>() {
42+
test_helpers::test_binary_elementwise(
43+
|mut a, b| { <$vector as core::ops::$trait_assign>::$fn_assign(&mut a, b); a },
44+
|mut a, b| { <$scalar as core::ops::$trait_assign>::$fn_assign(&mut a, b); a },
45+
)
46+
}
47+
48+
fn assign_scalar_rhs<const LANES: usize>() {
49+
test_helpers::test_binary_scalar_rhs_elementwise(
50+
|mut a, b| { <$vector as core::ops::$trait_assign<$scalar>>::$fn_assign(&mut a, b); a },
51+
|mut a, b| { <$scalar as core::ops::$trait_assign>::$fn_assign(&mut a, b); a },
52+
)
53+
}
54+
}
55+
}
56+
};
57+
}
58+
59+
macro_rules! impl_tests {
60+
{ $vector:ident, $scalar:tt, $int_scalar:tt } => {
61+
mod $scalar {
62+
type Vector<const LANES: usize> = core_simd::$vector<LANES>;
63+
type Scalar = $scalar;
64+
type IntScalar = $int_scalar;
65+
66+
impl_op_test! { unary, Vector<LANES>, Scalar, Neg::neg }
67+
impl_op_test! { binary, Vector<LANES>, Scalar, Add::add, AddAssign::add_assign }
68+
impl_op_test! { binary, Vector<LANES>, Scalar, Sub::sub, SubAssign::sub_assign }
69+
impl_op_test! { binary, Vector<LANES>, Scalar, Mul::mul, SubAssign::sub_assign }
70+
impl_op_test! { binary, Vector<LANES>, Scalar, Div::div, DivAssign::div_assign }
71+
impl_op_test! { binary, Vector<LANES>, Scalar, Rem::rem, RemAssign::rem_assign }
72+
73+
test_helpers::test_lanes! {
74+
fn abs<const LANES: usize>() {
75+
test_helpers::test_unary_elementwise(
76+
Vector::<LANES>::abs,
77+
Scalar::abs,
78+
)
79+
}
80+
81+
fn ceil<const LANES: usize>() {
82+
test_helpers::test_unary_elementwise(
83+
Vector::<LANES>::ceil,
84+
Scalar::ceil,
85+
)
86+
}
87+
88+
fn floor<const LANES: usize>() {
89+
test_helpers::test_unary_elementwise(
90+
Vector::<LANES>::floor,
91+
Scalar::floor,
92+
)
93+
}
94+
95+
fn round_from_int<const LANES: usize>() {
96+
test_helpers::test_unary_elementwise(
97+
Vector::<LANES>::round_from_int,
98+
|x| x as Scalar,
99+
)
100+
}
101+
102+
fn to_int_unchecked<const LANES: usize>() {
103+
// The maximum integer that can be represented by the equivalently sized float has
104+
// all of the mantissa digits set to 1, pushed up to the MSB.
105+
const ALL_MANTISSA_BITS: IntScalar = ((1 << <Scalar>::MANTISSA_DIGITS) - 1);
106+
const MAX_REPRESENTABLE_VALUE: Scalar =
107+
(ALL_MANTISSA_BITS << (core::mem::size_of::<Scalar>() * 8 - <Scalar>::MANTISSA_DIGITS as usize - 1)) as Scalar;
108+
109+
let mut runner = proptest::test_runner::TestRunner::default();
110+
runner.run(
111+
&test_helpers::array::UniformArrayStrategy::new(-MAX_REPRESENTABLE_VALUE..MAX_REPRESENTABLE_VALUE),
112+
|x| {
113+
let result_1 = unsafe { Vector::from_array(x).to_int_unchecked().to_array() };
114+
let result_2 = {
115+
let mut result = [0; LANES];
116+
for (i, o) in x.iter().zip(result.iter_mut()) {
117+
*o = unsafe { i.to_int_unchecked() };
118+
}
119+
result
120+
};
121+
test_helpers::prop_assert_biteq!(result_1, result_2);
122+
Ok(())
123+
},
124+
).unwrap();
125+
}
126+
}
127+
}
128+
}
129+
}
130+
131+
impl_tests! { SimdF32, f32, i32 }
132+
impl_tests! { SimdF64, f64, i64 }

crates/core_simd/tests/ops_impl/f32.rs

Lines changed: 0 additions & 6 deletions
This file was deleted.

crates/core_simd/tests/ops_impl/f64.rs

Lines changed: 0 additions & 5 deletions
This file was deleted.

0 commit comments

Comments
 (0)