From d5c227998bdc854938bdbf7dea96a58d2f7395a2 Mon Sep 17 00:00:00 2001 From: Caleb Zulawski Date: Sun, 3 Jan 2021 16:09:26 -0500 Subject: [PATCH 01/13] Add proptest float tests --- Cargo.toml | 1 + crates/core_simd/Cargo.toml | 8 + crates/core_simd/src/macros.rs | 6 + crates/core_simd/tests/float.rs | 132 ++++++ crates/core_simd/tests/ops_impl/f32.rs | 6 - crates/core_simd/tests/ops_impl/f64.rs | 5 - .../core_simd/tests/ops_impl/float_macros.rs | 418 ------------------ crates/core_simd/tests/ops_impl/mod.rs | 6 - crates/test_helpers/Cargo.toml | 9 + crates/test_helpers/src/array.rs | 98 ++++ crates/test_helpers/src/biteq.rs | 94 ++++ crates/test_helpers/src/lib.rs | 224 ++++++++++ 12 files changed, 572 insertions(+), 435 deletions(-) create mode 100644 crates/core_simd/tests/float.rs delete mode 100644 crates/core_simd/tests/ops_impl/f32.rs delete mode 100644 crates/core_simd/tests/ops_impl/f64.rs delete mode 100644 crates/core_simd/tests/ops_impl/float_macros.rs create mode 100644 crates/test_helpers/Cargo.toml create mode 100644 crates/test_helpers/src/array.rs create mode 100644 crates/test_helpers/src/biteq.rs create mode 100644 crates/test_helpers/src/lib.rs diff --git a/Cargo.toml b/Cargo.toml index f3538db75590..3f1abd73519b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,4 +2,5 @@ members = [ "crates/core_simd", + "crates/test_helpers", ] diff --git a/crates/core_simd/Cargo.toml b/crates/core_simd/Cargo.toml index f9e8a62e4857..d76bd547cde6 100644 --- a/crates/core_simd/Cargo.toml +++ b/crates/core_simd/Cargo.toml @@ -14,3 +14,11 @@ version = "0.2" [dev-dependencies.wasm-bindgen-test] version = "0.3" + +[dev-dependencies.proptest] +version = "0.10" +default-features = false +features = ["alloc"] + +[dev-dependencies.test_helpers] +path = "../test_helpers" diff --git a/crates/core_simd/src/macros.rs b/crates/core_simd/src/macros.rs index 5328f22b42ab..3e428379b74d 100644 --- a/crates/core_simd/src/macros.rs +++ b/crates/core_simd/src/macros.rs @@ -141,6 +141,12 @@ macro_rules! impl_vector { } } + impl From<$name> for [$type; LANES] { + fn from(vector: $name) -> Self { + vector.0 + } + } + // splat impl From<$type> for $name where Self: crate::LanesAtMost64 { #[inline] diff --git a/crates/core_simd/tests/float.rs b/crates/core_simd/tests/float.rs new file mode 100644 index 000000000000..939c18559d2a --- /dev/null +++ b/crates/core_simd/tests/float.rs @@ -0,0 +1,132 @@ +#[cfg(target_arch = "wasm32")] +wasm_bindgen_test_configure!(run_in_browser); + +macro_rules! impl_op_test { + { unary, $vector:ty, $scalar:ty, $trait:ident :: $fn:ident } => { + test_helpers::test_lanes! { + fn $fn() { + test_helpers::test_unary_elementwise( + <$vector as core::ops::$trait>::$fn, + <$scalar as core::ops::$trait>::$fn, + ); + } + } + }; + { binary, $vector:ty, $scalar:ty, $trait:ident :: $fn:ident, $trait_assign:ident :: $fn_assign:ident } => { + mod $fn { + use super::*; + + test_helpers::test_lanes! { + fn normal() { + test_helpers::test_binary_elementwise( + <$vector as core::ops::$trait>::$fn, + <$scalar as core::ops::$trait>::$fn, + ); + } + + fn scalar_rhs() { + test_helpers::test_binary_scalar_rhs_elementwise( + <$vector as core::ops::$trait<$scalar>>::$fn, + <$scalar as core::ops::$trait>::$fn, + ); + } + + fn scalar_lhs() { + test_helpers::test_binary_scalar_lhs_elementwise( + <$scalar as core::ops::$trait<$vector>>::$fn, + <$scalar as core::ops::$trait>::$fn, + ); + } + + fn assign() { + test_helpers::test_binary_elementwise( + |mut a, b| { <$vector as core::ops::$trait_assign>::$fn_assign(&mut a, b); a }, + |mut a, b| { <$scalar as core::ops::$trait_assign>::$fn_assign(&mut a, b); a }, + ) + } + + fn assign_scalar_rhs() { + test_helpers::test_binary_scalar_rhs_elementwise( + |mut a, b| { <$vector as core::ops::$trait_assign<$scalar>>::$fn_assign(&mut a, b); a }, + |mut a, b| { <$scalar as core::ops::$trait_assign>::$fn_assign(&mut a, b); a }, + ) + } + } + } + }; +} + +macro_rules! impl_tests { + { $vector:ident, $scalar:tt, $int_scalar:tt } => { + mod $scalar { + type Vector = core_simd::$vector; + type Scalar = $scalar; + type IntScalar = $int_scalar; + + impl_op_test! { unary, Vector, Scalar, Neg::neg } + impl_op_test! { binary, Vector, Scalar, Add::add, AddAssign::add_assign } + impl_op_test! { binary, Vector, Scalar, Sub::sub, SubAssign::sub_assign } + impl_op_test! { binary, Vector, Scalar, Mul::mul, SubAssign::sub_assign } + impl_op_test! { binary, Vector, Scalar, Div::div, DivAssign::div_assign } + impl_op_test! { binary, Vector, Scalar, Rem::rem, RemAssign::rem_assign } + + test_helpers::test_lanes! { + fn abs() { + test_helpers::test_unary_elementwise( + Vector::::abs, + Scalar::abs, + ) + } + + fn ceil() { + test_helpers::test_unary_elementwise( + Vector::::ceil, + Scalar::ceil, + ) + } + + fn floor() { + test_helpers::test_unary_elementwise( + Vector::::floor, + Scalar::floor, + ) + } + + fn round_from_int() { + test_helpers::test_unary_elementwise( + Vector::::round_from_int, + |x| x as Scalar, + ) + } + + fn to_int_unchecked() { + // The maximum integer that can be represented by the equivalently sized float has + // all of the mantissa digits set to 1, pushed up to the MSB. + const ALL_MANTISSA_BITS: IntScalar = ((1 << ::MANTISSA_DIGITS) - 1); + const MAX_REPRESENTABLE_VALUE: Scalar = + (ALL_MANTISSA_BITS << (core::mem::size_of::() * 8 - ::MANTISSA_DIGITS as usize - 1)) as Scalar; + + let mut runner = proptest::test_runner::TestRunner::default(); + runner.run( + &test_helpers::array::UniformArrayStrategy::new(-MAX_REPRESENTABLE_VALUE..MAX_REPRESENTABLE_VALUE), + |x| { + let result_1 = unsafe { Vector::from_array(x).to_int_unchecked().to_array() }; + let result_2 = { + let mut result = [0; LANES]; + for (i, o) in x.iter().zip(result.iter_mut()) { + *o = unsafe { i.to_int_unchecked() }; + } + result + }; + test_helpers::prop_assert_biteq!(result_1, result_2); + Ok(()) + }, + ).unwrap(); + } + } + } + } +} + +impl_tests! { SimdF32, f32, i32 } +impl_tests! { SimdF64, f64, i64 } diff --git a/crates/core_simd/tests/ops_impl/f32.rs b/crates/core_simd/tests/ops_impl/f32.rs deleted file mode 100644 index 1472822fe1fe..000000000000 --- a/crates/core_simd/tests/ops_impl/f32.rs +++ /dev/null @@ -1,6 +0,0 @@ -use super::helpers; - -float_tests! { f32x2, f32, i32x2, i32 } -float_tests! { f32x4, f32, i32x4, i32 } -float_tests! { f32x8, f32, i32x8, i32 } -float_tests! { f32x16, f32, i32x16, i32 } diff --git a/crates/core_simd/tests/ops_impl/f64.rs b/crates/core_simd/tests/ops_impl/f64.rs deleted file mode 100644 index 8f573baa1ad2..000000000000 --- a/crates/core_simd/tests/ops_impl/f64.rs +++ /dev/null @@ -1,5 +0,0 @@ -use super::helpers; - -float_tests! { f64x2, f64, i64x2, i64 } -float_tests! { f64x4, f64, i64x4, i64 } -float_tests! { f64x8, f64, i64x8, i64 } diff --git a/crates/core_simd/tests/ops_impl/float_macros.rs b/crates/core_simd/tests/ops_impl/float_macros.rs deleted file mode 100644 index fe347a5362da..000000000000 --- a/crates/core_simd/tests/ops_impl/float_macros.rs +++ /dev/null @@ -1,418 +0,0 @@ -macro_rules! float_tests { - { $vector:ident, $scalar:ident, $int_vector:ident, $int_scalar:ident } => { - #[cfg(test)] - mod $vector { - use super::*; - use helpers::lanewise::*; - - #[cfg(target_arch = "wasm32")] - use wasm_bindgen_test::*; - - #[cfg(target_arch = "wasm32")] - wasm_bindgen_test_configure!(run_in_browser); - - // TODO impl this as an associated fn on vectors - fn from_slice(slice: &[$scalar]) -> core_simd::$vector { - let mut value = core_simd::$vector::default(); - let value_slice: &mut [_] = value.as_mut(); - value_slice.copy_from_slice(&slice[0..value_slice.len()]); - value - } - - fn slice_chunks(slice: &[$scalar]) -> impl Iterator + '_ { - let lanes = core::mem::size_of::() / core::mem::size_of::<$scalar>(); - slice.chunks_exact(lanes).map(from_slice) - } - - fn from_slice_int(slice: &[$int_scalar]) -> core_simd::$int_vector { - let mut value = core_simd::$int_vector::default(); - let value_slice: &mut [_] = value.as_mut(); - value_slice.copy_from_slice(&slice[0..value_slice.len()]); - value - } - - fn slice_chunks_int(slice: &[$int_scalar]) -> impl Iterator + '_ { - let lanes = core::mem::size_of::() / core::mem::size_of::<$int_scalar>(); - slice.chunks_exact(lanes).map(from_slice_int) - } - - const A: [$scalar; 16] = [0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15.]; - const B: [$scalar; 16] = [16., 17., 18., 19., 20., 21., 22., 23., 24., 25., 26., 27., 28., 29., 30., 31.]; - const C: [$scalar; 16] = [ - -0.0, - 0.0, - -1.0, - 1.0, - <$scalar>::MIN, - <$scalar>::MAX, - <$scalar>::INFINITY, - <$scalar>::NEG_INFINITY, - <$scalar>::MIN_POSITIVE, - -<$scalar>::MIN_POSITIVE, - <$scalar>::EPSILON, - -<$scalar>::EPSILON, - <$scalar>::NAN, - -<$scalar>::NAN, - // TODO: Would be nice to check sNaN... - 100.0 / 3.0, - -100.0 / 3.0, - ]; - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn add() { - let a = from_slice(&A); - let b = from_slice(&B); - let expected = apply_binary_lanewise(a, b, core::ops::Add::add); - assert_biteq!(a + b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn add_assign() { - let mut a = from_slice(&A); - let b = from_slice(&B); - let expected = apply_binary_lanewise(a, b, core::ops::Add::add); - a += b; - assert_biteq!(a, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn add_scalar_rhs() { - let a = from_slice(&A); - let b = 5.; - let expected = apply_binary_scalar_rhs_lanewise(a, b, core::ops::Add::add); - assert_biteq!(a + b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn add_scalar_lhs() { - let a = 5.; - let b = from_slice(&B); - let expected = apply_binary_scalar_lhs_lanewise(a, b, core::ops::Add::add); - assert_biteq!(a + b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn add_assign_scalar() { - let mut a = from_slice(&A); - let b = 5.; - let expected = apply_binary_scalar_rhs_lanewise(a, b, core::ops::Add::add); - a += b; - assert_biteq!(a, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn sub() { - let a = from_slice(&A); - let b = from_slice(&B); - let expected = apply_binary_lanewise(a, b, core::ops::Sub::sub); - assert_biteq!(a - b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn sub_assign() { - let mut a = from_slice(&A); - let b = from_slice(&B); - let expected = apply_binary_lanewise(a, b, core::ops::Sub::sub); - a -= b; - assert_biteq!(a, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn sub_scalar_rhs() { - let a = from_slice(&A); - let b = 5.; - let expected = apply_binary_scalar_rhs_lanewise(a, b, core::ops::Sub::sub); - assert_biteq!(a - b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn sub_scalar_lhs() { - let a = 5.; - let b = from_slice(&B); - let expected = apply_binary_scalar_lhs_lanewise(a, b, core::ops::Sub::sub); - assert_biteq!(a - b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn sub_assign_scalar() { - let mut a = from_slice(&A); - let b = 5.; - let expected = apply_binary_scalar_rhs_lanewise(a, b, core::ops::Sub::sub); - a -= b; - assert_biteq!(a, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn mul() { - let a = from_slice(&A); - let b = from_slice(&B); - let expected = apply_binary_lanewise(a, b, core::ops::Mul::mul); - assert_biteq!(a * b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn mul_assign() { - let mut a = from_slice(&A); - let b = from_slice(&B); - let expected = apply_binary_lanewise(a, b, core::ops::Mul::mul); - a *= b; - assert_biteq!(a, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn mul_scalar_rhs() { - let a = from_slice(&A); - let b = 5.; - let expected = apply_binary_scalar_rhs_lanewise(a, b, core::ops::Mul::mul); - assert_biteq!(a * b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn mul_scalar_lhs() { - let a = 5.; - let b = from_slice(&B); - let expected = apply_binary_scalar_lhs_lanewise(a, b, core::ops::Mul::mul); - assert_biteq!(a * b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn mul_assign_scalar() { - let mut a = from_slice(&A); - let b = 5.; - let expected = apply_binary_scalar_rhs_lanewise(a, b, core::ops::Mul::mul); - a *= b; - assert_biteq!(a, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn div() { - let a = from_slice(&A); - let b = from_slice(&B); - let expected = apply_binary_lanewise(a, b, core::ops::Div::div); - assert_biteq!(a / b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn div_assign() { - let mut a = from_slice(&A); - let b = from_slice(&B); - let expected = apply_binary_lanewise(a, b, core::ops::Div::div); - a /= b; - assert_biteq!(a, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn div_scalar_rhs() { - let a = from_slice(&A); - let b = 5.; - let expected = apply_binary_scalar_rhs_lanewise(a, b, core::ops::Div::div); - assert_biteq!(a / b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn div_scalar_lhs() { - let a = 5.; - let b = from_slice(&B); - let expected = apply_binary_scalar_lhs_lanewise(a, b, core::ops::Div::div); - assert_biteq!(a / b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn div_assign_scalar() { - let mut a = from_slice(&A); - let b = 5.; - let expected = apply_binary_scalar_rhs_lanewise(a, b, core::ops::Div::div); - a /= b; - assert_biteq!(a, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn rem() { - let a = from_slice(&A); - let b = from_slice(&B); - let expected = apply_binary_lanewise(a, b, core::ops::Rem::rem); - assert_biteq!(a % b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn rem_assign() { - let mut a = from_slice(&A); - let b = from_slice(&B); - let expected = apply_binary_lanewise(a, b, core::ops::Rem::rem); - a %= b; - assert_biteq!(a, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn rem_scalar_rhs() { - let a = from_slice(&A); - let b = 5.; - let expected = apply_binary_scalar_rhs_lanewise(a, b, core::ops::Rem::rem); - assert_biteq!(a % b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn rem_scalar_lhs() { - let a = 5.; - let b = from_slice(&B); - let expected = apply_binary_scalar_lhs_lanewise(a, b, core::ops::Rem::rem); - assert_biteq!(a % b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn rem_assign_scalar() { - let mut a = from_slice(&A); - let b = 5.; - let expected = apply_binary_scalar_rhs_lanewise(a, b, core::ops::Rem::rem); - a %= b; - assert_biteq!(a, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn neg() { - let v = from_slice(&A); - let expected = apply_unary_lanewise(v, core::ops::Neg::neg); - assert_biteq!(-v, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn neg_odd_floats() { - for v in slice_chunks(&C) { - let expected = apply_unary_lanewise(v, core::ops::Neg::neg); - assert_biteq!(-v, expected); - } - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn abs_negative() { - let v = -from_slice(&A); - let expected = apply_unary_lanewise(v, <$scalar>::abs); - assert_biteq!(v.abs(), expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn abs_positive() { - let v = from_slice(&B); - let expected = apply_unary_lanewise(v, <$scalar>::abs); - assert_biteq!(v.abs(), expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn abs_odd_floats() { - for v in slice_chunks(&C) { - let expected = apply_unary_lanewise(v, <$scalar>::abs); - assert_biteq!(v.abs(), expected); - } - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn ceil_odd_floats() { - for v in slice_chunks(&C) { - let expected = apply_unary_lanewise(v, <$scalar>::ceil); - assert_biteq!(v.ceil(), expected); - } - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn floor_odd_floats() { - for v in slice_chunks(&C) { - let expected = apply_unary_lanewise(v, <$scalar>::floor); - assert_biteq!(v.floor(), expected); - } - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn to_int_unchecked() { - // The maximum integer that can be represented by the equivalently sized float has - // all of the mantissa digits set to 1, pushed up to the MSB. - const ALL_MANTISSA_BITS: $int_scalar = ((1 << <$scalar>::MANTISSA_DIGITS) - 1); - const MAX_REPRESENTABLE_VALUE: $int_scalar = - ALL_MANTISSA_BITS << (core::mem::size_of::<$scalar>() * 8 - <$scalar>::MANTISSA_DIGITS as usize - 1); - const VALUES: [$scalar; 16] = [ - -0.0, - 0.0, - -1.0, - 1.0, - ALL_MANTISSA_BITS as $scalar, - -ALL_MANTISSA_BITS as $scalar, - MAX_REPRESENTABLE_VALUE as $scalar, - -MAX_REPRESENTABLE_VALUE as $scalar, - (MAX_REPRESENTABLE_VALUE / 2) as $scalar, - (-MAX_REPRESENTABLE_VALUE / 2) as $scalar, - <$scalar>::MIN_POSITIVE, - -<$scalar>::MIN_POSITIVE, - <$scalar>::EPSILON, - -<$scalar>::EPSILON, - 100.0 / 3.0, - -100.0 / 3.0, - ]; - - for v in slice_chunks(&VALUES) { - let expected = apply_unary_lanewise(v, |x| unsafe { x.to_int_unchecked() }); - assert_biteq!(unsafe { v.to_int_unchecked() }, expected); - } - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn round_from_int() { - const VALUES: [$int_scalar; 16] = [ - 0, - 0, - 1, - -1, - 100, - -100, - 200, - -200, - 413, - -413, - 1017, - -1017, - 1234567, - -1234567, - <$int_scalar>::MAX, - <$int_scalar>::MIN, - ]; - - for v in slice_chunks_int(&VALUES) { - let expected = apply_unary_lanewise(v, |x| x as $scalar); - assert_biteq!(core_simd::$vector::round_from_int(v), expected); - } - } - } - } -} diff --git a/crates/core_simd/tests/ops_impl/mod.rs b/crates/core_simd/tests/ops_impl/mod.rs index 814f2d04b59c..5819eb6beafa 100644 --- a/crates/core_simd/tests/ops_impl/mod.rs +++ b/crates/core_simd/tests/ops_impl/mod.rs @@ -2,12 +2,6 @@ #[path = "../helpers/mod.rs"] mod helpers; -#[macro_use] -mod float_macros; - -mod r#f32; -mod r#f64; - #[macro_use] mod int_macros; diff --git a/crates/test_helpers/Cargo.toml b/crates/test_helpers/Cargo.toml new file mode 100644 index 000000000000..0a8c3344334c --- /dev/null +++ b/crates/test_helpers/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "test_helpers" +version = "0.1.0" +authors = ["Caleb Zulawski "] +edition = "2018" +publish = false + +[dependencies] +proptest = "0.10" diff --git a/crates/test_helpers/src/array.rs b/crates/test_helpers/src/array.rs new file mode 100644 index 000000000000..d9cae96ca2ff --- /dev/null +++ b/crates/test_helpers/src/array.rs @@ -0,0 +1,98 @@ +// Adapted from proptest's array code +// Copyright 2017 Jason Lingle + +use proptest::{ + strategy::{NewTree, Strategy, ValueTree}, + test_runner::TestRunner, +}; +use core::{ + marker::PhantomData, + mem::MaybeUninit, +}; + +#[must_use = "strategies do nothing unless used"] +#[derive(Clone, Copy, Debug)] +pub struct UniformArrayStrategy { + strategy: S, + _marker: PhantomData, +} + +impl UniformArrayStrategy { + pub fn new(strategy: S) -> Self { + Self { + strategy, + _marker: PhantomData, + } + } +} + +pub struct ArrayValueTree { + tree: T, + shrinker: usize, + last_shrinker: Option, +} + +impl Strategy for UniformArrayStrategy +where + T: core::fmt::Debug, + S: Strategy, +{ + type Tree = ArrayValueTree<[S::Tree; LANES]>; + type Value = [T; LANES]; + + fn new_tree(&self, runner: &mut TestRunner) -> NewTree { + let tree: [S::Tree; LANES] = unsafe { + let mut tree: [MaybeUninit; LANES] = MaybeUninit::uninit().assume_init(); + for t in tree.iter_mut() { + *t = MaybeUninit::new(self.strategy.new_tree(runner)?) + } + core::mem::transmute_copy(&tree) + }; + Ok(ArrayValueTree { + tree, + shrinker: 0, + last_shrinker: None, + }) + } +} + +impl ValueTree for ArrayValueTree<[T; LANES]> { + type Value = [T::Value; LANES]; + + fn current(&self) -> Self::Value { + unsafe { + let mut value: [MaybeUninit; LANES] = MaybeUninit::uninit().assume_init(); + for (tree_elem, value_elem) in self.tree.iter().zip(value.iter_mut()) { + *value_elem = MaybeUninit::new(tree_elem.current()); + } + core::mem::transmute_copy(&value) + } + } + + fn simplify(&mut self) -> bool { + while self.shrinker < LANES { + if self.tree[self.shrinker].simplify() { + self.last_shrinker = Some(self.shrinker); + return true; + } else { + self.shrinker += 1; + } + } + + false + } + + fn complicate(&mut self) -> bool { + if let Some(shrinker) = self.last_shrinker { + self.shrinker = shrinker; + if self.tree[shrinker].complicate() { + true + } else { + self.last_shrinker = None; + false + } + } else { + false + } + } +} diff --git a/crates/test_helpers/src/biteq.rs b/crates/test_helpers/src/biteq.rs new file mode 100644 index 000000000000..23aa7d4d908e --- /dev/null +++ b/crates/test_helpers/src/biteq.rs @@ -0,0 +1,94 @@ +pub trait BitEq { + fn biteq(&self, other: &Self) -> bool; + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result; +} + +macro_rules! impl_integer_biteq { + { $($type:ty),* } => { + $( + impl BitEq for $type { + fn biteq(&self, other: &Self) -> bool { + self == other + } + + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{:?} ({:x})", self, self) + } + } + )* + }; +} + +impl_integer_biteq! { u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize } + +macro_rules! impl_float_biteq { + { $($type:ty),* } => { + $( + impl BitEq for $type { + fn biteq(&self, other: &Self) -> bool { + if self.is_nan() && other.is_nan() { + true // exact nan bits don't matter + } else { + self.to_bits() == other.to_bits() + } + } + + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{:?} ({:x})", self, self.to_bits()) + } + } + )* + }; +} + +impl_float_biteq! { f32, f64 } + +impl BitEq for [T; N] { + fn biteq(&self, other: &Self) -> bool { + self.iter() + .zip(other.iter()) + .fold(true, |value, (left, right)| value && left.biteq(right)) + } + + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + #[repr(transparent)] + struct Wrapper<'a, T: BitEq>(&'a T); + + impl core::fmt::Debug for Wrapper<'_, T> { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + self.0.fmt(f) + } + } + + f.debug_list() + .entries(self.iter().map(|x| Wrapper(x))) + .finish() + } +} + +#[doc(hidden)] +pub struct BitEqWrapper<'a, T>(pub &'a T); + +impl PartialEq for BitEqWrapper<'_, T> { + fn eq(&self, other: &Self) -> bool { + self.0.biteq(other.0) + } +} + +impl core::fmt::Debug for BitEqWrapper<'_, T> { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + self.0.fmt(f) + } +} + +#[macro_export] +macro_rules! prop_assert_biteq { + { $a:expr, $b:expr } => { + { + use $crate::biteq::BitEqWrapper; + let a = $a; + let b = $b; + proptest::prop_assert_eq!(BitEqWrapper(&a), BitEqWrapper(&b)); + } + } +} diff --git a/crates/test_helpers/src/lib.rs b/crates/test_helpers/src/lib.rs new file mode 100644 index 000000000000..2aaa4641fdfd --- /dev/null +++ b/crates/test_helpers/src/lib.rs @@ -0,0 +1,224 @@ +pub mod array; + +#[macro_use] +pub mod biteq; + +pub trait DefaultStrategy { + type Strategy: proptest::strategy::Strategy; + fn default_strategy() -> Self::Strategy; +} + +macro_rules! impl_num { + { $type:tt } => { + impl DefaultStrategy for $type { + type Strategy = proptest::num::$type::Any; + fn default_strategy() -> Self::Strategy { + proptest::num::$type::ANY + } + } + } +} + +impl_num! { i8 } +impl_num! { i16 } +impl_num! { i32 } +impl_num! { i64 } +impl_num! { i128 } +impl_num! { isize } +impl_num! { u8 } +impl_num! { u16 } +impl_num! { u32 } +impl_num! { u64 } +impl_num! { u128 } +impl_num! { usize } +impl_num! { f32 } +impl_num! { f64 } + +impl DefaultStrategy for [T; LANES] { + type Strategy = crate::array::UniformArrayStrategy; + fn default_strategy() -> Self::Strategy { + Self::Strategy::new(T::default_strategy()) + } +} + +pub fn test_1( + f: impl Fn(A) -> proptest::test_runner::TestCaseResult, +) { + let mut runner = proptest::test_runner::TestRunner::default(); + runner.run(&A::default_strategy(), f).unwrap(); +} + +pub fn test_2( + f: impl Fn(A, B) -> proptest::test_runner::TestCaseResult, +) { + let mut runner = proptest::test_runner::TestRunner::default(); + runner + .run(&(A::default_strategy(), B::default_strategy()), |(a, b)| { + f(a, b) + }) + .unwrap(); +} + +pub fn test_unary_elementwise( + fv: impl Fn(Vector) -> VectorResult, + fs: impl Fn(Scalar) -> ScalarResult, +) where + Scalar: Copy + Default + core::fmt::Debug + DefaultStrategy, + ScalarResult: Copy + Default + biteq::BitEq + core::fmt::Debug + DefaultStrategy, + Vector: Into<[Scalar; LANES]> + From<[Scalar; LANES]> + Copy, + VectorResult: Into<[ScalarResult; LANES]> + From<[ScalarResult; LANES]> + Copy, +{ + test_1(|x: [Scalar; LANES]| { + let result_1: [ScalarResult; LANES] = fv(x.into()).into(); + let result_2: [ScalarResult; LANES] = { + let mut result = [ScalarResult::default(); LANES]; + for (i, o) in x.iter().zip(result.iter_mut()) { + *o = fs(*i); + } + result + }; + crate::prop_assert_biteq!(result_1, result_2); + Ok(()) + }); +} + +pub fn test_binary_elementwise< + Scalar1, + Scalar2, + ScalarResult, + Vector1, + Vector2, + VectorResult, + const LANES: usize, +>( + fv: impl Fn(Vector1, Vector2) -> VectorResult, + fs: impl Fn(Scalar1, Scalar2) -> ScalarResult, +) where + Scalar1: Copy + Default + core::fmt::Debug + DefaultStrategy, + Scalar2: Copy + Default + core::fmt::Debug + DefaultStrategy, + ScalarResult: Copy + Default + biteq::BitEq + core::fmt::Debug + DefaultStrategy, + Vector1: Into<[Scalar1; LANES]> + From<[Scalar1; LANES]> + Copy, + Vector2: Into<[Scalar2; LANES]> + From<[Scalar2; LANES]> + Copy, + VectorResult: Into<[ScalarResult; LANES]> + From<[ScalarResult; LANES]> + Copy, +{ + test_2(|x: [Scalar1; LANES], y: [Scalar2; LANES]| { + let result_1: [ScalarResult; LANES] = fv(x.into(), y.into()).into(); + let result_2: [ScalarResult; LANES] = { + let mut result = [ScalarResult::default(); LANES]; + for ((i1, i2), o) in x.iter().zip(y.iter()).zip(result.iter_mut()) { + *o = fs(*i1, *i2); + } + result + }; + crate::prop_assert_biteq!(result_1, result_2); + Ok(()) + }); +} + +pub fn test_binary_scalar_rhs_elementwise< + Scalar1, + Scalar2, + ScalarResult, + Vector, + VectorResult, + const LANES: usize, +>( + fv: impl Fn(Vector, Scalar2) -> VectorResult, + fs: impl Fn(Scalar1, Scalar2) -> ScalarResult, +) where + Scalar1: Copy + Default + core::fmt::Debug + DefaultStrategy, + Scalar2: Copy + Default + core::fmt::Debug + DefaultStrategy, + ScalarResult: Copy + Default + biteq::BitEq + core::fmt::Debug + DefaultStrategy, + Vector: Into<[Scalar1; LANES]> + From<[Scalar1; LANES]> + Copy, + VectorResult: Into<[ScalarResult; LANES]> + From<[ScalarResult; LANES]> + Copy, +{ + test_2(|x: [Scalar1; LANES], y: Scalar2| { + let result_1: [ScalarResult; LANES] = fv(x.into(), y).into(); + let result_2: [ScalarResult; LANES] = { + let mut result = [ScalarResult::default(); LANES]; + for (i, o) in x.iter().zip(result.iter_mut()) { + *o = fs(*i, y); + } + result + }; + crate::prop_assert_biteq!(result_1, result_2); + Ok(()) + }); +} + +pub fn test_binary_scalar_lhs_elementwise< + Scalar1, + Scalar2, + ScalarResult, + Vector, + VectorResult, + const LANES: usize, +>( + fv: impl Fn(Scalar1, Vector) -> VectorResult, + fs: impl Fn(Scalar1, Scalar2) -> ScalarResult, +) where + Scalar1: Copy + Default + core::fmt::Debug + DefaultStrategy, + Scalar2: Copy + Default + core::fmt::Debug + DefaultStrategy, + ScalarResult: Copy + Default + biteq::BitEq + core::fmt::Debug + DefaultStrategy, + Vector: Into<[Scalar2; LANES]> + From<[Scalar2; LANES]> + Copy, + VectorResult: Into<[ScalarResult; LANES]> + From<[ScalarResult; LANES]> + Copy, +{ + test_2(|x: Scalar1, y: [Scalar2; LANES]| { + let result_1: [ScalarResult; LANES] = fv(x, y.into()).into(); + let result_2: [ScalarResult; LANES] = { + let mut result = [ScalarResult::default(); LANES]; + for (i, o) in y.iter().zip(result.iter_mut()) { + *o = fs(x, *i); + } + result + }; + crate::prop_assert_biteq!(result_1, result_2); + Ok(()) + }); +} + +#[macro_export] +#[doc(hidden)] +macro_rules! test_lanes_impl { + { + fn $test:ident() $body:tt + + $($name:ident => $lanes_lit:literal,)* + } => { + mod $test { + use super::*; + $( + #[test] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + fn $name() { + const $lanes: usize = $lanes_lit; + $body + } + )* + } + } +} + +#[macro_export] +macro_rules! test_lanes { + { + $(fn $test:ident() $body:tt)* + } => { + $( + $crate::test_lanes_impl! { + fn $test() $body + + lanes_2 => 2, + lanes_3 => 3, + lanes_4 => 4, + lanes_7 => 7, + lanes_8 => 8, + lanes_16 => 16, + lanes_32 => 32, + lanes_64 => 64, + lanes_128 => 128, + lanes_256 => 256, + } + )* + } +} From 0ac057a354a00b4329a47266ea184e5177c7b584 Mon Sep 17 00:00:00 2001 From: Caleb Zulawski Date: Thu, 7 Jan 2021 01:26:29 -0500 Subject: [PATCH 02/13] Add integer tests --- crates/core_simd/tests/float.rs | 12 +- crates/core_simd/tests/integer.rs | 189 ++++++++++++++++++++++++++++++ crates/test_helpers/src/lib.rs | 11 +- 3 files changed, 208 insertions(+), 4 deletions(-) create mode 100644 crates/core_simd/tests/integer.rs diff --git a/crates/core_simd/tests/float.rs b/crates/core_simd/tests/float.rs index 939c18559d2a..56d66239e806 100644 --- a/crates/core_simd/tests/float.rs +++ b/crates/core_simd/tests/float.rs @@ -8,6 +8,7 @@ macro_rules! impl_op_test { test_helpers::test_unary_elementwise( <$vector as core::ops::$trait>::$fn, <$scalar as core::ops::$trait>::$fn, + |_| true, ); } } @@ -21,6 +22,7 @@ macro_rules! impl_op_test { test_helpers::test_binary_elementwise( <$vector as core::ops::$trait>::$fn, <$scalar as core::ops::$trait>::$fn, + |_, _| true, ); } @@ -28,6 +30,7 @@ macro_rules! impl_op_test { test_helpers::test_binary_scalar_rhs_elementwise( <$vector as core::ops::$trait<$scalar>>::$fn, <$scalar as core::ops::$trait>::$fn, + |_, _| true, ); } @@ -35,6 +38,7 @@ macro_rules! impl_op_test { test_helpers::test_binary_scalar_lhs_elementwise( <$scalar as core::ops::$trait<$vector>>::$fn, <$scalar as core::ops::$trait>::$fn, + |_, _| true, ); } @@ -42,6 +46,7 @@ macro_rules! impl_op_test { test_helpers::test_binary_elementwise( |mut a, b| { <$vector as core::ops::$trait_assign>::$fn_assign(&mut a, b); a }, |mut a, b| { <$scalar as core::ops::$trait_assign>::$fn_assign(&mut a, b); a }, + |_, _| true, ) } @@ -49,6 +54,7 @@ macro_rules! impl_op_test { test_helpers::test_binary_scalar_rhs_elementwise( |mut a, b| { <$vector as core::ops::$trait_assign<$scalar>>::$fn_assign(&mut a, b); a }, |mut a, b| { <$scalar as core::ops::$trait_assign>::$fn_assign(&mut a, b); a }, + |_, _| true, ) } } @@ -62,7 +68,7 @@ macro_rules! impl_tests { type Vector = core_simd::$vector; type Scalar = $scalar; type IntScalar = $int_scalar; - + impl_op_test! { unary, Vector, Scalar, Neg::neg } impl_op_test! { binary, Vector, Scalar, Add::add, AddAssign::add_assign } impl_op_test! { binary, Vector, Scalar, Sub::sub, SubAssign::sub_assign } @@ -75,6 +81,7 @@ macro_rules! impl_tests { test_helpers::test_unary_elementwise( Vector::::abs, Scalar::abs, + |_| true, ) } @@ -82,6 +89,7 @@ macro_rules! impl_tests { test_helpers::test_unary_elementwise( Vector::::ceil, Scalar::ceil, + |_| true, ) } @@ -89,6 +97,7 @@ macro_rules! impl_tests { test_helpers::test_unary_elementwise( Vector::::floor, Scalar::floor, + |_| true, ) } @@ -96,6 +105,7 @@ macro_rules! impl_tests { test_helpers::test_unary_elementwise( Vector::::round_from_int, |x| x as Scalar, + |_| true, ) } diff --git a/crates/core_simd/tests/integer.rs b/crates/core_simd/tests/integer.rs new file mode 100644 index 000000000000..4f38cdb1ed63 --- /dev/null +++ b/crates/core_simd/tests/integer.rs @@ -0,0 +1,189 @@ +#[cfg(target_arch = "wasm32")] +wasm_bindgen_test_configure!(run_in_browser); + +macro_rules! impl_unary_op_test { + { $vector:ty, $scalar:ty, $trait:ident :: $fn:ident, $scalar_fn:expr } => { + test_helpers::test_lanes! { + fn $fn() { + test_helpers::test_unary_elementwise( + <$vector as core::ops::$trait>::$fn, + $scalar_fn, + |_| true, + ); + } + } + }; + { $vector:ty, $scalar:ty, $trait:ident :: $fn:ident } => { + impl_unary_op_test! { $vector, $scalar, $trait::$fn, <$scalar as core::ops::$trait>::$fn } + }; +} + +macro_rules! impl_binary_op_test { + { $vector:ty, $scalar:ty, $trait:ident :: $fn:ident, $trait_assign:ident :: $fn_assign:ident, $scalar_fn:expr } => { + mod $fn { + use super::*; + + test_helpers::test_lanes! { + fn normal() { + test_helpers::test_binary_elementwise( + <$vector as core::ops::$trait>::$fn, + $scalar_fn, + |_, _| true, + ); + } + + fn scalar_rhs() { + test_helpers::test_binary_scalar_rhs_elementwise( + <$vector as core::ops::$trait<$scalar>>::$fn, + $scalar_fn, + |_, _| true, + ); + } + + fn scalar_lhs() { + test_helpers::test_binary_scalar_lhs_elementwise( + <$scalar as core::ops::$trait<$vector>>::$fn, + $scalar_fn, + |_, _| true, + ); + } + + fn assign() { + test_helpers::test_binary_elementwise( + |mut a, b| { <$vector as core::ops::$trait_assign>::$fn_assign(&mut a, b); a }, + $scalar_fn, + |_, _| true, + ) + } + + fn assign_scalar_rhs() { + test_helpers::test_binary_scalar_rhs_elementwise( + |mut a, b| { <$vector as core::ops::$trait_assign<$scalar>>::$fn_assign(&mut a, b); a }, + $scalar_fn, + |_, _| true, + ) + } + } + } + }; + { $vector:ty, $scalar:ty, $trait:ident :: $fn:ident, $trait_assign:ident :: $fn_assign:ident } => { + impl_binary_op_test! { $vector, $scalar, $trait::$fn, $trait_assign::$fn_assign, <$scalar as core::ops::$trait>::$fn } + }; +} + +macro_rules! impl_binary_checked_op_test { + { $vector:ty, $scalar:ty, $trait:ident :: $fn:ident, $trait_assign:ident :: $fn_assign:ident, $scalar_fn:expr, $check_fn:expr } => { + mod $fn { + use super::*; + + test_helpers::test_lanes! { + fn normal() { + test_helpers::test_binary_elementwise( + <$vector as core::ops::$trait>::$fn, + $scalar_fn, + |x, y| x.iter().zip(y.iter()).all(|(x, y)| $check_fn(*x, *y)), + ); + } + + fn scalar_rhs() { + test_helpers::test_binary_scalar_rhs_elementwise( + <$vector as core::ops::$trait<$scalar>>::$fn, + $scalar_fn, + |x, y| x.iter().all(|x| $check_fn(*x, y)), + ); + } + + fn scalar_lhs() { + test_helpers::test_binary_scalar_lhs_elementwise( + <$scalar as core::ops::$trait<$vector>>::$fn, + $scalar_fn, + |x, y| y.iter().all(|y| $check_fn(x, *y)), + ); + } + + fn assign() { + test_helpers::test_binary_elementwise( + |mut a, b| { <$vector as core::ops::$trait_assign>::$fn_assign(&mut a, b); a }, + $scalar_fn, + |x, y| x.iter().zip(y.iter()).all(|(x, y)| $check_fn(*x, *y)), + ) + } + + fn assign_scalar_rhs() { + test_helpers::test_binary_scalar_rhs_elementwise( + |mut a, b| { <$vector as core::ops::$trait_assign<$scalar>>::$fn_assign(&mut a, b); a }, + $scalar_fn, + |x, y| x.iter().all(|x| $check_fn(*x, y)), + ) + } + } + } + }; + { $vector:ty, $scalar:ty, $trait:ident :: $fn:ident, $trait_assign:ident :: $fn_assign:ident, $check_fn:expr } => { + impl_binary_nonzero_rhs_op_test! { $vector, $scalar, $trait::$fn, $trait_assign::$fn_assign, <$scalar as core::ops::$trait>::$fn, $check_fn } + }; +} + +macro_rules! impl_signed_tests { + { $vector:ident, $scalar:tt } => { + mod $scalar { + type Vector = core_simd::$vector; + type Scalar = $scalar; + + test_helpers::test_lanes! { + fn neg() { + test_helpers::test_unary_elementwise( + as core::ops::Neg>::neg, + ::neg, + |x| !x.contains(&Scalar::MIN), + ); + } + } + + impl_binary_op_test!(Vector, Scalar, Add::add, AddAssign::add_assign, Scalar::wrapping_add); + impl_binary_op_test!(Vector, Scalar, Sub::sub, SubAssign::sub_assign, Scalar::wrapping_sub); + impl_binary_op_test!(Vector, Scalar, Mul::mul, MulAssign::mul_assign, Scalar::wrapping_mul); + impl_binary_checked_op_test!(Vector, Scalar, Div::div, DivAssign::div_assign, Scalar::wrapping_div, |x, y| y != 0 && !(x == Scalar::MIN && y == -1)); + impl_binary_checked_op_test!(Vector, Scalar, Rem::rem, RemAssign::rem_assign, Scalar::wrapping_rem, |x, y| y != 0 && !(x == Scalar::MIN && y == -1)); + + impl_unary_op_test!(Vector, Scalar, Not::not); + impl_binary_op_test!(Vector, Scalar, BitAnd::bitand, BitAndAssign::bitand_assign); + impl_binary_op_test!(Vector, Scalar, BitOr::bitor, BitOrAssign::bitor_assign); + impl_binary_op_test!(Vector, Scalar, BitXor::bitxor, BitXorAssign::bitxor_assign); + } + } +} + +macro_rules! impl_unsigned_tests { + { $vector:ident, $scalar:tt } => { + mod $scalar { + type Vector = core_simd::$vector; + type Scalar = $scalar; + + impl_binary_op_test!(Vector, Scalar, Add::add, AddAssign::add_assign, Scalar::wrapping_add); + impl_binary_op_test!(Vector, Scalar, Sub::sub, SubAssign::sub_assign, Scalar::wrapping_sub); + impl_binary_op_test!(Vector, Scalar, Mul::mul, MulAssign::mul_assign, Scalar::wrapping_mul); + impl_binary_checked_op_test!(Vector, Scalar, Div::div, DivAssign::div_assign, Scalar::wrapping_div, |_, y| y != 0); + impl_binary_checked_op_test!(Vector, Scalar, Rem::rem, RemAssign::rem_assign, Scalar::wrapping_rem, |_, y| y != 0); + + impl_unary_op_test!(Vector, Scalar, Not::not); + impl_binary_op_test!(Vector, Scalar, BitAnd::bitand, BitAndAssign::bitand_assign); + impl_binary_op_test!(Vector, Scalar, BitOr::bitor, BitOrAssign::bitor_assign); + impl_binary_op_test!(Vector, Scalar, BitXor::bitxor, BitXorAssign::bitxor_assign); + } + } +} + +impl_signed_tests! { SimdI8, i8 } +impl_signed_tests! { SimdI16, i16 } +impl_signed_tests! { SimdI32, i32 } +impl_signed_tests! { SimdI64, i64 } +impl_signed_tests! { SimdI128, i128 } +impl_signed_tests! { SimdIsize, isize } + +impl_unsigned_tests! { SimdU8, u8 } +impl_unsigned_tests! { SimdU16, u16 } +impl_unsigned_tests! { SimdU32, u32 } +impl_unsigned_tests! { SimdU64, u64 } +impl_unsigned_tests! { SimdU128, u128 } +impl_unsigned_tests! { SimdUsize, usize } diff --git a/crates/test_helpers/src/lib.rs b/crates/test_helpers/src/lib.rs index 2aaa4641fdfd..c9b2858ccc24 100644 --- a/crates/test_helpers/src/lib.rs +++ b/crates/test_helpers/src/lib.rs @@ -62,6 +62,7 @@ pub fn test_2( fv: impl Fn(Vector) -> VectorResult, fs: impl Fn(Scalar) -> ScalarResult, + check: impl Fn([Scalar; LANES]) -> bool, ) where Scalar: Copy + Default + core::fmt::Debug + DefaultStrategy, ScalarResult: Copy + Default + biteq::BitEq + core::fmt::Debug + DefaultStrategy, @@ -69,6 +70,7 @@ pub fn test_unary_elementwise + From<[ScalarResult; LANES]> + Copy, { test_1(|x: [Scalar; LANES]| { + proptest::prop_assume!(check(x)); let result_1: [ScalarResult; LANES] = fv(x.into()).into(); let result_2: [ScalarResult; LANES] = { let mut result = [ScalarResult::default(); LANES]; @@ -93,6 +95,7 @@ pub fn test_binary_elementwise< >( fv: impl Fn(Vector1, Vector2) -> VectorResult, fs: impl Fn(Scalar1, Scalar2) -> ScalarResult, + check: impl Fn([Scalar1; LANES], [Scalar2; LANES]) -> bool, ) where Scalar1: Copy + Default + core::fmt::Debug + DefaultStrategy, Scalar2: Copy + Default + core::fmt::Debug + DefaultStrategy, @@ -102,6 +105,7 @@ pub fn test_binary_elementwise< VectorResult: Into<[ScalarResult; LANES]> + From<[ScalarResult; LANES]> + Copy, { test_2(|x: [Scalar1; LANES], y: [Scalar2; LANES]| { + proptest::prop_assume!(check(x, y)); let result_1: [ScalarResult; LANES] = fv(x.into(), y.into()).into(); let result_2: [ScalarResult; LANES] = { let mut result = [ScalarResult::default(); LANES]; @@ -125,6 +129,7 @@ pub fn test_binary_scalar_rhs_elementwise< >( fv: impl Fn(Vector, Scalar2) -> VectorResult, fs: impl Fn(Scalar1, Scalar2) -> ScalarResult, + check: impl Fn([Scalar1; LANES], Scalar2) -> bool, ) where Scalar1: Copy + Default + core::fmt::Debug + DefaultStrategy, Scalar2: Copy + Default + core::fmt::Debug + DefaultStrategy, @@ -133,6 +138,7 @@ pub fn test_binary_scalar_rhs_elementwise< VectorResult: Into<[ScalarResult; LANES]> + From<[ScalarResult; LANES]> + Copy, { test_2(|x: [Scalar1; LANES], y: Scalar2| { + proptest::prop_assume!(check(x, y)); let result_1: [ScalarResult; LANES] = fv(x.into(), y).into(); let result_2: [ScalarResult; LANES] = { let mut result = [ScalarResult::default(); LANES]; @@ -156,6 +162,7 @@ pub fn test_binary_scalar_lhs_elementwise< >( fv: impl Fn(Scalar1, Vector) -> VectorResult, fs: impl Fn(Scalar1, Scalar2) -> ScalarResult, + check: impl Fn(Scalar1, [Scalar2; LANES]) -> bool, ) where Scalar1: Copy + Default + core::fmt::Debug + DefaultStrategy, Scalar2: Copy + Default + core::fmt::Debug + DefaultStrategy, @@ -164,6 +171,7 @@ pub fn test_binary_scalar_lhs_elementwise< VectorResult: Into<[ScalarResult; LANES]> + From<[ScalarResult; LANES]> + Copy, { test_2(|x: Scalar1, y: [Scalar2; LANES]| { + proptest::prop_assume!(check(x, y)); let result_1: [ScalarResult; LANES] = fv(x, y.into()).into(); let result_2: [ScalarResult; LANES] = { let mut result = [ScalarResult::default(); LANES]; @@ -215,9 +223,6 @@ macro_rules! test_lanes { lanes_8 => 8, lanes_16 => 16, lanes_32 => 32, - lanes_64 => 64, - lanes_128 => 128, - lanes_256 => 256, } )* } From 5b0818a2217f2d8030f25f99b566ed5a35394f6c Mon Sep 17 00:00:00 2001 From: Caleb Zulawski Date: Thu, 7 Jan 2021 01:28:17 -0500 Subject: [PATCH 03/13] Remove old integer tests --- crates/core_simd/tests/ops_impl/i128.rs | 4 - crates/core_simd/tests/ops_impl/i16.rs | 6 - crates/core_simd/tests/ops_impl/i32.rs | 6 - crates/core_simd/tests/ops_impl/i64.rs | 5 - crates/core_simd/tests/ops_impl/i8.rs | 6 - crates/core_simd/tests/ops_impl/int_macros.rs | 392 ------------------ crates/core_simd/tests/ops_impl/isize.rs | 5 - crates/core_simd/tests/ops_impl/mod.rs | 20 - 8 files changed, 444 deletions(-) delete mode 100644 crates/core_simd/tests/ops_impl/i128.rs delete mode 100644 crates/core_simd/tests/ops_impl/i16.rs delete mode 100644 crates/core_simd/tests/ops_impl/i32.rs delete mode 100644 crates/core_simd/tests/ops_impl/i64.rs delete mode 100644 crates/core_simd/tests/ops_impl/i8.rs delete mode 100644 crates/core_simd/tests/ops_impl/isize.rs diff --git a/crates/core_simd/tests/ops_impl/i128.rs b/crates/core_simd/tests/ops_impl/i128.rs deleted file mode 100644 index 8a0a279b8dce..000000000000 --- a/crates/core_simd/tests/ops_impl/i128.rs +++ /dev/null @@ -1,4 +0,0 @@ -use super::helpers; - -int_tests! { i128x2, i128 } -int_tests! { i128x4, i128 } diff --git a/crates/core_simd/tests/ops_impl/i16.rs b/crates/core_simd/tests/ops_impl/i16.rs deleted file mode 100644 index 445436b77a89..000000000000 --- a/crates/core_simd/tests/ops_impl/i16.rs +++ /dev/null @@ -1,6 +0,0 @@ -use super::helpers; - -int_tests! { i16x4, i16 } -int_tests! { i16x8, i16 } -int_tests! { i16x16, i16 } -int_tests! { i16x32, i16 } diff --git a/crates/core_simd/tests/ops_impl/i32.rs b/crates/core_simd/tests/ops_impl/i32.rs deleted file mode 100644 index f13ab833a335..000000000000 --- a/crates/core_simd/tests/ops_impl/i32.rs +++ /dev/null @@ -1,6 +0,0 @@ -use super::helpers; - -int_tests! { i32x2, i32 } -int_tests! { i32x4, i32 } -int_tests! { i32x8, i32 } -int_tests! { i32x16, i32 } diff --git a/crates/core_simd/tests/ops_impl/i64.rs b/crates/core_simd/tests/ops_impl/i64.rs deleted file mode 100644 index 08479c4b994b..000000000000 --- a/crates/core_simd/tests/ops_impl/i64.rs +++ /dev/null @@ -1,5 +0,0 @@ -use super::helpers; - -int_tests! { i64x2, i64 } -int_tests! { i64x4, i64 } -int_tests! { i64x8, i64 } diff --git a/crates/core_simd/tests/ops_impl/i8.rs b/crates/core_simd/tests/ops_impl/i8.rs deleted file mode 100644 index 2a7db7906ac1..000000000000 --- a/crates/core_simd/tests/ops_impl/i8.rs +++ /dev/null @@ -1,6 +0,0 @@ -use super::helpers; - -int_tests! { i8x8, i8 } -int_tests! { i8x16, i8 } -int_tests! { i8x32, i8 } -int_tests! { i8x64, i8 } diff --git a/crates/core_simd/tests/ops_impl/int_macros.rs b/crates/core_simd/tests/ops_impl/int_macros.rs index 43c75c6a9c49..f565ae2f04df 100644 --- a/crates/core_simd/tests/ops_impl/int_macros.rs +++ b/crates/core_simd/tests/ops_impl/int_macros.rs @@ -40,194 +40,6 @@ macro_rules! int_tests { -1, -2, -3, -4, -5, -6, -7, -8, ]; - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn add() { - let a = from_slice(&A); - let b = from_slice(&B); - let expected = apply_binary_lanewise(a, b, core::ops::Add::add); - assert_biteq!(a + b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn add_assign() { - let mut a = from_slice(&A); - let b = from_slice(&B); - let expected = apply_binary_lanewise(a, b, core::ops::Add::add); - a += b; - assert_biteq!(a, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn add_scalar_rhs() { - let a = from_slice(&A); - let b = 5; - let expected = apply_binary_scalar_rhs_lanewise(a, b, core::ops::Add::add); - assert_biteq!(a + b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn add_scalar_lhs() { - let a = 5; - let b = from_slice(&B); - let expected = apply_binary_scalar_lhs_lanewise(a, b, core::ops::Add::add); - assert_biteq!(a + b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn add_assign_scalar() { - let mut a = from_slice(&A); - let b = 5; - let expected = apply_binary_scalar_rhs_lanewise(a, b, core::ops::Add::add); - a += b; - assert_biteq!(a, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn sub() { - let a = from_slice(&A); - let b = from_slice(&B); - let expected = apply_binary_lanewise(a, b, core::ops::Sub::sub); - assert_biteq!(a - b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn sub_assign() { - let mut a = from_slice(&A); - let b = from_slice(&B); - let expected = apply_binary_lanewise(a, b, core::ops::Sub::sub); - a -= b; - assert_biteq!(a, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn sub_scalar_rhs() { - let a = from_slice(&A); - let b = 5; - let expected = apply_binary_scalar_rhs_lanewise(a, b, core::ops::Sub::sub); - assert_biteq!(a - b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn sub_scalar_lhs() { - let a = 5; - let b = from_slice(&B); - let expected = apply_binary_scalar_lhs_lanewise(a, b, core::ops::Sub::sub); - assert_biteq!(a - b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn sub_assign_scalar() { - let mut a = from_slice(&A); - let b = 5; - let expected = apply_binary_scalar_rhs_lanewise(a, b, core::ops::Sub::sub); - a -= b; - assert_biteq!(a, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn mul() { - let a = from_slice(&A); - let b = from_slice(&B); - let expected = apply_binary_lanewise(a, b, core::ops::Mul::mul); - assert_biteq!(a * b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn mul_assign() { - let mut a = from_slice(&A); - let b = from_slice(&B); - let expected = apply_binary_lanewise(a, b, core::ops::Mul::mul); - a *= b; - assert_biteq!(a, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn mul_scalar_rhs() { - let a = from_slice(&A); - let b = 5; - let expected = apply_binary_scalar_rhs_lanewise(a, b, core::ops::Mul::mul); - assert_biteq!(a * b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn mul_scalar_lhs() { - let a = 5; - let b = from_slice(&B); - let expected = apply_binary_scalar_lhs_lanewise(a, b, core::ops::Mul::mul); - assert_biteq!(a * b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn mul_assign_scalar() { - let mut a = from_slice(&A); - let b = 5; - let expected = apply_binary_scalar_rhs_lanewise(a, b, core::ops::Mul::mul); - a *= b; - assert_biteq!(a, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn div() { - let a = from_slice(&A); - let b = from_slice(&B); - let expected = apply_binary_lanewise(a, b, core::ops::Div::div); - assert_biteq!(a / b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn div_assign() { - let mut a = from_slice(&A); - let b = from_slice(&B); - let expected = apply_binary_lanewise(a, b, core::ops::Div::div); - a /= b; - assert_biteq!(a, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn div_scalar_rhs() { - let a = from_slice(&A); - let b = 5; - let expected = apply_binary_scalar_rhs_lanewise(a, b, core::ops::Div::div); - assert_biteq!(a / b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn div_scalar_lhs() { - let a = 5; - let b = from_slice(&B); - let expected = apply_binary_scalar_lhs_lanewise(a, b, core::ops::Div::div); - assert_biteq!(a / b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn div_assign_scalar() { - let mut a = from_slice(&A); - let b = 5; - let expected = apply_binary_scalar_rhs_lanewise(a, b, core::ops::Div::div); - a /= b; - assert_biteq!(a, expected); - } - #[test] #[should_panic] fn div_min_panics() { @@ -261,53 +73,6 @@ macro_rules! int_tests { let _ = a / b; } - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn rem() { - let a = from_slice(&A); - let b = from_slice(&B); - let expected = apply_binary_lanewise(a, b, core::ops::Rem::rem); - assert_biteq!(a % b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn rem_assign() { - let mut a = from_slice(&A); - let b = from_slice(&B); - let expected = apply_binary_lanewise(a, b, core::ops::Rem::rem); - a %= b; - assert_biteq!(a, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn rem_scalar_rhs() { - let a = from_slice(&A); - let b = 5; - let expected = apply_binary_scalar_rhs_lanewise(a, b, core::ops::Rem::rem); - assert_biteq!(a % b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn rem_scalar_lhs() { - let a = 5; - let b = from_slice(&B); - let expected = apply_binary_scalar_lhs_lanewise(a, b, core::ops::Rem::rem); - assert_biteq!(a % b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn rem_assign_scalar() { - let mut a = from_slice(&A); - let b = 5; - let expected = apply_binary_scalar_rhs_lanewise(a, b, core::ops::Rem::rem); - a %= b; - assert_biteq!(a, expected); - } - #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn rem_min_neg_one_no_panic() { @@ -331,163 +96,6 @@ macro_rules! int_tests { let b = from_slice(&vec![0 ; 64]); let _ = a % b; } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn bitand() { - let a = from_slice(&A); - let b = from_slice(&B); - let expected = apply_binary_lanewise(a, b, core::ops::BitAnd::bitand); - assert_biteq!(a & b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn bitand_assign() { - let mut a = from_slice(&A); - let b = from_slice(&B); - let expected = apply_binary_lanewise(a, b, core::ops::BitAnd::bitand); - a &= b; - assert_biteq!(a, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn bitand_scalar_rhs() { - let a = from_slice(&A); - let b = 5; - let expected = apply_binary_scalar_rhs_lanewise(a, b, core::ops::BitAnd::bitand); - assert_biteq!(a & b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn bitand_scalar_lhs() { - let a = 5; - let b = from_slice(&B); - let expected = apply_binary_scalar_lhs_lanewise(a, b, core::ops::BitAnd::bitand); - assert_biteq!(a & b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn bitand_assign_scalar() { - let mut a = from_slice(&A); - let b = 5; - let expected = apply_binary_scalar_rhs_lanewise(a, b, core::ops::BitAnd::bitand); - a &= b; - assert_biteq!(a, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn bitor() { - let a = from_slice(&A); - let b = from_slice(&B); - let expected = apply_binary_lanewise(a, b, core::ops::BitOr::bitor); - assert_biteq!(a | b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn bitor_assign() { - let mut a = from_slice(&A); - let b = from_slice(&B); - let expected = apply_binary_lanewise(a, b, core::ops::BitOr::bitor); - a |= b; - assert_biteq!(a, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn bitor_scalar_rhs() { - let a = from_slice(&A); - let b = 5; - let expected = apply_binary_scalar_rhs_lanewise(a, b, core::ops::BitOr::bitor); - assert_biteq!(a | b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn bitor_scalar_lhs() { - let a = 5; - let b = from_slice(&B); - let expected = apply_binary_scalar_lhs_lanewise(a, b, core::ops::BitOr::bitor); - assert_biteq!(a | b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn bitor_assign_scalar() { - let mut a = from_slice(&A); - let b = 5; - let expected = apply_binary_scalar_rhs_lanewise(a, b, core::ops::BitOr::bitor); - a |= b; - assert_biteq!(a, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn bitxor() { - let a = from_slice(&A); - let b = from_slice(&B); - let expected = apply_binary_lanewise(a, b, core::ops::BitXor::bitxor); - assert_biteq!(a ^ b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn bitxor_assign() { - let mut a = from_slice(&A); - let b = from_slice(&B); - let expected = apply_binary_lanewise(a, b, core::ops::BitXor::bitxor); - a ^= b; - assert_biteq!(a, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn bitxor_scalar_rhs() { - let a = from_slice(&A); - let b = 5; - let expected = apply_binary_scalar_rhs_lanewise(a, b, core::ops::BitXor::bitxor); - assert_biteq!(a ^ b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn bitxor_scalar_lhs() { - let a = 5; - let b = from_slice(&B); - let expected = apply_binary_scalar_lhs_lanewise(a, b, core::ops::BitXor::bitxor); - assert_biteq!(a ^ b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn bitxor_assign_scalar() { - let mut a = from_slice(&A); - let b = 5; - let expected = apply_binary_scalar_rhs_lanewise(a, b, core::ops::BitXor::bitxor); - a ^= b; - assert_biteq!(a, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn neg() { - let v = from_slice(&A); - let expected = apply_unary_lanewise(v, core::ops::Neg::neg); - assert_biteq!(-v, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn not() { - let v = from_slice(&A); - let expected = apply_unary_lanewise(v, core::ops::Not::not); - assert_biteq!(!v, expected); - } } } } diff --git a/crates/core_simd/tests/ops_impl/isize.rs b/crates/core_simd/tests/ops_impl/isize.rs deleted file mode 100644 index 9943e9c357a4..000000000000 --- a/crates/core_simd/tests/ops_impl/isize.rs +++ /dev/null @@ -1,5 +0,0 @@ -use super::helpers; - -int_tests! { isizex2, isize } -int_tests! { isizex4, isize } -int_tests! { isizex8, isize } diff --git a/crates/core_simd/tests/ops_impl/mod.rs b/crates/core_simd/tests/ops_impl/mod.rs index 5819eb6beafa..89f5e1b0b52a 100644 --- a/crates/core_simd/tests/ops_impl/mod.rs +++ b/crates/core_simd/tests/ops_impl/mod.rs @@ -2,26 +2,6 @@ #[path = "../helpers/mod.rs"] mod helpers; -#[macro_use] -mod int_macros; - -mod r#i8; -mod r#i16; -mod r#i32; -mod r#i64; -mod r#i128; -mod r#isize; - -#[macro_use] -mod uint_macros; - -mod r#u8; -mod r#u16; -mod r#u32; -mod r#u64; -mod r#u128; -mod r#usize; - #[macro_use] mod mask_macros; From 223daea83ea60c725944e62815ffae2639a8d652 Mon Sep 17 00:00:00 2001 From: Caleb Zulawski Date: Wed, 10 Feb 2021 23:22:32 -0500 Subject: [PATCH 04/13] Update supported lane counts --- crates/test_helpers/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/test_helpers/src/lib.rs b/crates/test_helpers/src/lib.rs index c9b2858ccc24..845dc1fcc44d 100644 --- a/crates/test_helpers/src/lib.rs +++ b/crates/test_helpers/src/lib.rs @@ -216,13 +216,13 @@ macro_rules! test_lanes { $crate::test_lanes_impl! { fn $test() $body + lanes_1 => 1, lanes_2 => 2, - lanes_3 => 3, lanes_4 => 4, - lanes_7 => 7, lanes_8 => 8, lanes_16 => 16, lanes_32 => 32, + lanes_64 => 64, } )* } From b38d342d7727287c994aefcaa9b74c87e22e2dab Mon Sep 17 00:00:00 2001 From: Caleb Zulawski Date: Sat, 13 Feb 2021 00:41:58 -0500 Subject: [PATCH 05/13] Simplify test creation --- crates/test_helpers/src/lib.rs | 78 ++++++++++++++++++++-------------- 1 file changed, 46 insertions(+), 32 deletions(-) diff --git a/crates/test_helpers/src/lib.rs b/crates/test_helpers/src/lib.rs index 845dc1fcc44d..77dafe38a10a 100644 --- a/crates/test_helpers/src/lib.rs +++ b/crates/test_helpers/src/lib.rs @@ -185,45 +185,59 @@ pub fn test_binary_scalar_lhs_elementwise< }); } -#[macro_export] -#[doc(hidden)] -macro_rules! test_lanes_impl { - { - fn $test:ident() $body:tt - - $($name:ident => $lanes_lit:literal,)* - } => { - mod $test { - use super::*; - $( - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn $name() { - const $lanes: usize = $lanes_lit; - $body - } - )* - } - } -} - #[macro_export] macro_rules! test_lanes { { $(fn $test:ident() $body:tt)* } => { $( - $crate::test_lanes_impl! { - fn $test() $body + mod $test { + use super::*; - lanes_1 => 1, - lanes_2 => 2, - lanes_4 => 4, - lanes_8 => 8, - lanes_16 => 16, - lanes_32 => 32, - lanes_64 => 64, - } + fn implementation() $body + + #[test] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + fn lanes_1() { + implementation::<1>(); + } + + #[test] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + fn lanes_2() { + implementation::<2>(); + } + + #[test] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + fn lanes_4() { + implementation::<4>(); + } + + #[test] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + fn lanes_8() { + implementation::<8>(); + } + + #[test] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + fn lanes_16() { + implementation::<16>(); + } + + #[test] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + fn lanes_32() { + implementation::<32>(); + } + + #[test] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + fn lanes_64() { + implementation::<64>(); + } + } )* } } From 38b18904d0399d8dcfee5dfc94e38d78a8fbba66 Mon Sep 17 00:00:00 2001 From: Caleb Zulawski Date: Sat, 13 Feb 2021 01:11:01 -0500 Subject: [PATCH 06/13] Remove obsolete helpers --- crates/core_simd/tests/helpers/lanewise.rs | 61 ---------------------- crates/core_simd/tests/helpers/mod.rs | 2 - 2 files changed, 63 deletions(-) delete mode 100644 crates/core_simd/tests/helpers/lanewise.rs diff --git a/crates/core_simd/tests/helpers/lanewise.rs b/crates/core_simd/tests/helpers/lanewise.rs deleted file mode 100644 index 3a9f47968080..000000000000 --- a/crates/core_simd/tests/helpers/lanewise.rs +++ /dev/null @@ -1,61 +0,0 @@ -//! These helpers provide a way to easily emulate a vectorized SIMD op on two SIMD vectors, -//! except using scalar ops that iterate through each lane, one at a time, so as to remove -//! the vagaries of compilation. -//! -//! Do note, however, that when testing that vectorized operations #[should_panic], these -//! "scalarized SIMD ops" will trigger scalar code paths that may also normally panic. - -pub fn apply_unary_lanewise, V2: AsMut<[T2]> + Default>( - x: V1, - f: impl Fn(T1) -> T2, -) -> V2 { - let mut y = V2::default(); - assert_eq!(x.as_ref().len(), y.as_mut().len()); - for (x, y) in x.as_ref().iter().zip(y.as_mut().iter_mut()) { - *y = f(*x); - } - y -} - -pub fn apply_binary_lanewise + AsMut<[T]> + Default>( - a: V, - b: V, - f: impl Fn(T, T) -> T, -) -> V { - let mut out = V::default(); - let out_slice = out.as_mut(); - let a_slice = a.as_ref(); - let b_slice = b.as_ref(); - for (o, (a, b)) in out_slice.iter_mut().zip(a_slice.iter().zip(b_slice.iter())) { - *o = f(*a, *b); - } - out -} - -pub fn apply_binary_scalar_rhs_lanewise + AsMut<[T]> + Default>( - a: V, - b: T, - f: impl Fn(T, T) -> T, -) -> V { - let mut out = V::default(); - let out_slice = out.as_mut(); - let a_slice = a.as_ref(); - for (o, a) in out_slice.iter_mut().zip(a_slice.iter()) { - *o = f(*a, b); - } - out -} - -pub fn apply_binary_scalar_lhs_lanewise + AsMut<[T]> + Default>( - a: T, - b: V, - f: impl Fn(T, T) -> T, -) -> V { - let mut out = V::default(); - let out_slice = out.as_mut(); - let b_slice = b.as_ref(); - for (o, b) in out_slice.iter_mut().zip(b_slice.iter()) { - *o = f(a, *b); - } - out -} diff --git a/crates/core_simd/tests/helpers/mod.rs b/crates/core_simd/tests/helpers/mod.rs index b128f8251ca3..41b4fea9d95d 100644 --- a/crates/core_simd/tests/helpers/mod.rs +++ b/crates/core_simd/tests/helpers/mod.rs @@ -1,4 +1,2 @@ #[macro_use] pub mod biteq; - -pub mod lanewise; From 8d5702e437e051333dcf1005fcce140c5c96f759 Mon Sep 17 00:00:00 2001 From: Caleb Zulawski Date: Sat, 13 Feb 2021 02:14:47 -0500 Subject: [PATCH 07/13] Fix performance issues --- crates/core_simd/tests/float.rs | 60 ++++++++++++------------ crates/core_simd/tests/integer.rs | 76 +++++++++++++++---------------- crates/test_helpers/src/lib.rs | 40 ++++++++-------- 3 files changed, 90 insertions(+), 86 deletions(-) diff --git a/crates/core_simd/tests/float.rs b/crates/core_simd/tests/float.rs index 56d66239e806..03d132ae0468 100644 --- a/crates/core_simd/tests/float.rs +++ b/crates/core_simd/tests/float.rs @@ -6,9 +6,9 @@ macro_rules! impl_op_test { test_helpers::test_lanes! { fn $fn() { test_helpers::test_unary_elementwise( - <$vector as core::ops::$trait>::$fn, - <$scalar as core::ops::$trait>::$fn, - |_| true, + &<$vector as core::ops::$trait>::$fn, + &<$scalar as core::ops::$trait>::$fn, + &|_| true, ); } } @@ -20,41 +20,41 @@ macro_rules! impl_op_test { test_helpers::test_lanes! { fn normal() { test_helpers::test_binary_elementwise( - <$vector as core::ops::$trait>::$fn, - <$scalar as core::ops::$trait>::$fn, - |_, _| true, + &<$vector as core::ops::$trait>::$fn, + &<$scalar as core::ops::$trait>::$fn, + &|_, _| true, ); } fn scalar_rhs() { test_helpers::test_binary_scalar_rhs_elementwise( - <$vector as core::ops::$trait<$scalar>>::$fn, - <$scalar as core::ops::$trait>::$fn, - |_, _| true, + &<$vector as core::ops::$trait<$scalar>>::$fn, + &<$scalar as core::ops::$trait>::$fn, + &|_, _| true, ); } fn scalar_lhs() { test_helpers::test_binary_scalar_lhs_elementwise( - <$scalar as core::ops::$trait<$vector>>::$fn, - <$scalar as core::ops::$trait>::$fn, - |_, _| true, + &<$scalar as core::ops::$trait<$vector>>::$fn, + &<$scalar as core::ops::$trait>::$fn, + &|_, _| true, ); } fn assign() { test_helpers::test_binary_elementwise( - |mut a, b| { <$vector as core::ops::$trait_assign>::$fn_assign(&mut a, b); a }, - |mut a, b| { <$scalar as core::ops::$trait_assign>::$fn_assign(&mut a, b); a }, - |_, _| true, + &|mut a, b| { <$vector as core::ops::$trait_assign>::$fn_assign(&mut a, b); a }, + &|mut a, b| { <$scalar as core::ops::$trait_assign>::$fn_assign(&mut a, b); a }, + &|_, _| true, ) } fn assign_scalar_rhs() { test_helpers::test_binary_scalar_rhs_elementwise( - |mut a, b| { <$vector as core::ops::$trait_assign<$scalar>>::$fn_assign(&mut a, b); a }, - |mut a, b| { <$scalar as core::ops::$trait_assign>::$fn_assign(&mut a, b); a }, - |_, _| true, + &|mut a, b| { <$vector as core::ops::$trait_assign<$scalar>>::$fn_assign(&mut a, b); a }, + &|mut a, b| { <$scalar as core::ops::$trait_assign>::$fn_assign(&mut a, b); a }, + &|_, _| true, ) } } @@ -79,33 +79,33 @@ macro_rules! impl_tests { test_helpers::test_lanes! { fn abs() { test_helpers::test_unary_elementwise( - Vector::::abs, - Scalar::abs, - |_| true, + &Vector::::abs, + &Scalar::abs, + &|_| true, ) } fn ceil() { test_helpers::test_unary_elementwise( - Vector::::ceil, - Scalar::ceil, - |_| true, + &Vector::::ceil, + &Scalar::ceil, + &|_| true, ) } fn floor() { test_helpers::test_unary_elementwise( - Vector::::floor, - Scalar::floor, - |_| true, + &Vector::::floor, + &Scalar::floor, + &|_| true, ) } fn round_from_int() { test_helpers::test_unary_elementwise( - Vector::::round_from_int, - |x| x as Scalar, - |_| true, + &Vector::::round_from_int, + &|x| x as Scalar, + &|_| true, ) } diff --git a/crates/core_simd/tests/integer.rs b/crates/core_simd/tests/integer.rs index 4f38cdb1ed63..878b3f0329a4 100644 --- a/crates/core_simd/tests/integer.rs +++ b/crates/core_simd/tests/integer.rs @@ -6,9 +6,9 @@ macro_rules! impl_unary_op_test { test_helpers::test_lanes! { fn $fn() { test_helpers::test_unary_elementwise( - <$vector as core::ops::$trait>::$fn, - $scalar_fn, - |_| true, + &<$vector as core::ops::$trait>::$fn, + &$scalar_fn, + &|_| true, ); } } @@ -26,42 +26,42 @@ macro_rules! impl_binary_op_test { test_helpers::test_lanes! { fn normal() { test_helpers::test_binary_elementwise( - <$vector as core::ops::$trait>::$fn, - $scalar_fn, - |_, _| true, + &<$vector as core::ops::$trait>::$fn, + &$scalar_fn, + &|_, _| true, ); } fn scalar_rhs() { test_helpers::test_binary_scalar_rhs_elementwise( - <$vector as core::ops::$trait<$scalar>>::$fn, - $scalar_fn, - |_, _| true, + &<$vector as core::ops::$trait<$scalar>>::$fn, + &$scalar_fn, + &|_, _| true, ); } fn scalar_lhs() { test_helpers::test_binary_scalar_lhs_elementwise( - <$scalar as core::ops::$trait<$vector>>::$fn, - $scalar_fn, - |_, _| true, + &<$scalar as core::ops::$trait<$vector>>::$fn, + &$scalar_fn, + &|_, _| true, ); } fn assign() { test_helpers::test_binary_elementwise( - |mut a, b| { <$vector as core::ops::$trait_assign>::$fn_assign(&mut a, b); a }, - $scalar_fn, - |_, _| true, - ) + &|mut a, b| { <$vector as core::ops::$trait_assign>::$fn_assign(&mut a, b); a }, + &$scalar_fn, + &|_, _| true, + ); } fn assign_scalar_rhs() { test_helpers::test_binary_scalar_rhs_elementwise( - |mut a, b| { <$vector as core::ops::$trait_assign<$scalar>>::$fn_assign(&mut a, b); a }, - $scalar_fn, - |_, _| true, - ) + &|mut a, b| { <$vector as core::ops::$trait_assign<$scalar>>::$fn_assign(&mut a, b); a }, + &$scalar_fn, + &|_, _| true, + ); } } } @@ -79,41 +79,41 @@ macro_rules! impl_binary_checked_op_test { test_helpers::test_lanes! { fn normal() { test_helpers::test_binary_elementwise( - <$vector as core::ops::$trait>::$fn, - $scalar_fn, - |x, y| x.iter().zip(y.iter()).all(|(x, y)| $check_fn(*x, *y)), + &<$vector as core::ops::$trait>::$fn, + &$scalar_fn, + &|x, y| x.iter().zip(y.iter()).all(|(x, y)| $check_fn(*x, *y)), ); } fn scalar_rhs() { test_helpers::test_binary_scalar_rhs_elementwise( - <$vector as core::ops::$trait<$scalar>>::$fn, - $scalar_fn, - |x, y| x.iter().all(|x| $check_fn(*x, y)), + &<$vector as core::ops::$trait<$scalar>>::$fn, + &$scalar_fn, + &|x, y| x.iter().all(|x| $check_fn(*x, y)), ); } fn scalar_lhs() { test_helpers::test_binary_scalar_lhs_elementwise( - <$scalar as core::ops::$trait<$vector>>::$fn, - $scalar_fn, - |x, y| y.iter().all(|y| $check_fn(x, *y)), + &<$scalar as core::ops::$trait<$vector>>::$fn, + &$scalar_fn, + &|x, y| y.iter().all(|y| $check_fn(x, *y)), ); } fn assign() { test_helpers::test_binary_elementwise( - |mut a, b| { <$vector as core::ops::$trait_assign>::$fn_assign(&mut a, b); a }, - $scalar_fn, - |x, y| x.iter().zip(y.iter()).all(|(x, y)| $check_fn(*x, *y)), + &|mut a, b| { <$vector as core::ops::$trait_assign>::$fn_assign(&mut a, b); a }, + &$scalar_fn, + &|x, y| x.iter().zip(y.iter()).all(|(x, y)| $check_fn(*x, *y)), ) } fn assign_scalar_rhs() { test_helpers::test_binary_scalar_rhs_elementwise( - |mut a, b| { <$vector as core::ops::$trait_assign<$scalar>>::$fn_assign(&mut a, b); a }, - $scalar_fn, - |x, y| x.iter().all(|x| $check_fn(*x, y)), + &|mut a, b| { <$vector as core::ops::$trait_assign<$scalar>>::$fn_assign(&mut a, b); a }, + &$scalar_fn, + &|x, y| x.iter().all(|x| $check_fn(*x, y)), ) } } @@ -133,9 +133,9 @@ macro_rules! impl_signed_tests { test_helpers::test_lanes! { fn neg() { test_helpers::test_unary_elementwise( - as core::ops::Neg>::neg, - ::neg, - |x| !x.contains(&Scalar::MIN), + & as core::ops::Neg>::neg, + &::neg, + &|x| !x.contains(&Scalar::MIN), ); } } diff --git a/crates/test_helpers/src/lib.rs b/crates/test_helpers/src/lib.rs index 77dafe38a10a..134b4073a4e2 100644 --- a/crates/test_helpers/src/lib.rs +++ b/crates/test_helpers/src/lib.rs @@ -42,14 +42,14 @@ impl DefaultStrategy } pub fn test_1( - f: impl Fn(A) -> proptest::test_runner::TestCaseResult, + f: &dyn Fn(A) -> proptest::test_runner::TestCaseResult, ) { let mut runner = proptest::test_runner::TestRunner::default(); runner.run(&A::default_strategy(), f).unwrap(); } pub fn test_2( - f: impl Fn(A, B) -> proptest::test_runner::TestCaseResult, + f: &dyn Fn(A, B) -> proptest::test_runner::TestCaseResult, ) { let mut runner = proptest::test_runner::TestRunner::default(); runner @@ -59,17 +59,18 @@ pub fn test_2( - fv: impl Fn(Vector) -> VectorResult, - fs: impl Fn(Scalar) -> ScalarResult, - check: impl Fn([Scalar; LANES]) -> bool, + fv: &dyn Fn(Vector) -> VectorResult, + fs: &dyn Fn(Scalar) -> ScalarResult, + check: &dyn Fn([Scalar; LANES]) -> bool, ) where Scalar: Copy + Default + core::fmt::Debug + DefaultStrategy, ScalarResult: Copy + Default + biteq::BitEq + core::fmt::Debug + DefaultStrategy, Vector: Into<[Scalar; LANES]> + From<[Scalar; LANES]> + Copy, VectorResult: Into<[ScalarResult; LANES]> + From<[ScalarResult; LANES]> + Copy, { - test_1(|x: [Scalar; LANES]| { + test_1(&|x: [Scalar; LANES]| { proptest::prop_assume!(check(x)); let result_1: [ScalarResult; LANES] = fv(x.into()).into(); let result_2: [ScalarResult; LANES] = { @@ -84,6 +85,7 @@ pub fn test_unary_elementwise( - fv: impl Fn(Vector1, Vector2) -> VectorResult, - fs: impl Fn(Scalar1, Scalar2) -> ScalarResult, - check: impl Fn([Scalar1; LANES], [Scalar2; LANES]) -> bool, + fv: &dyn Fn(Vector1, Vector2) -> VectorResult, + fs: &dyn Fn(Scalar1, Scalar2) -> ScalarResult, + check: &dyn Fn([Scalar1; LANES], [Scalar2; LANES]) -> bool, ) where Scalar1: Copy + Default + core::fmt::Debug + DefaultStrategy, Scalar2: Copy + Default + core::fmt::Debug + DefaultStrategy, @@ -104,7 +106,7 @@ pub fn test_binary_elementwise< Vector2: Into<[Scalar2; LANES]> + From<[Scalar2; LANES]> + Copy, VectorResult: Into<[ScalarResult; LANES]> + From<[ScalarResult; LANES]> + Copy, { - test_2(|x: [Scalar1; LANES], y: [Scalar2; LANES]| { + test_2(&|x: [Scalar1; LANES], y: [Scalar2; LANES]| { proptest::prop_assume!(check(x, y)); let result_1: [ScalarResult; LANES] = fv(x.into(), y.into()).into(); let result_2: [ScalarResult; LANES] = { @@ -119,6 +121,7 @@ pub fn test_binary_elementwise< }); } +#[inline(never)] pub fn test_binary_scalar_rhs_elementwise< Scalar1, Scalar2, @@ -127,9 +130,9 @@ pub fn test_binary_scalar_rhs_elementwise< VectorResult, const LANES: usize, >( - fv: impl Fn(Vector, Scalar2) -> VectorResult, - fs: impl Fn(Scalar1, Scalar2) -> ScalarResult, - check: impl Fn([Scalar1; LANES], Scalar2) -> bool, + fv: &dyn Fn(Vector, Scalar2) -> VectorResult, + fs: &dyn Fn(Scalar1, Scalar2) -> ScalarResult, + check: &dyn Fn([Scalar1; LANES], Scalar2) -> bool, ) where Scalar1: Copy + Default + core::fmt::Debug + DefaultStrategy, Scalar2: Copy + Default + core::fmt::Debug + DefaultStrategy, @@ -137,7 +140,7 @@ pub fn test_binary_scalar_rhs_elementwise< Vector: Into<[Scalar1; LANES]> + From<[Scalar1; LANES]> + Copy, VectorResult: Into<[ScalarResult; LANES]> + From<[ScalarResult; LANES]> + Copy, { - test_2(|x: [Scalar1; LANES], y: Scalar2| { + test_2(&|x: [Scalar1; LANES], y: Scalar2| { proptest::prop_assume!(check(x, y)); let result_1: [ScalarResult; LANES] = fv(x.into(), y).into(); let result_2: [ScalarResult; LANES] = { @@ -152,6 +155,7 @@ pub fn test_binary_scalar_rhs_elementwise< }); } +#[inline(never)] pub fn test_binary_scalar_lhs_elementwise< Scalar1, Scalar2, @@ -160,9 +164,9 @@ pub fn test_binary_scalar_lhs_elementwise< VectorResult, const LANES: usize, >( - fv: impl Fn(Scalar1, Vector) -> VectorResult, - fs: impl Fn(Scalar1, Scalar2) -> ScalarResult, - check: impl Fn(Scalar1, [Scalar2; LANES]) -> bool, + fv: &dyn Fn(Scalar1, Vector) -> VectorResult, + fs: &dyn Fn(Scalar1, Scalar2) -> ScalarResult, + check: &dyn Fn(Scalar1, [Scalar2; LANES]) -> bool, ) where Scalar1: Copy + Default + core::fmt::Debug + DefaultStrategy, Scalar2: Copy + Default + core::fmt::Debug + DefaultStrategy, @@ -170,7 +174,7 @@ pub fn test_binary_scalar_lhs_elementwise< Vector: Into<[Scalar2; LANES]> + From<[Scalar2; LANES]> + Copy, VectorResult: Into<[ScalarResult; LANES]> + From<[ScalarResult; LANES]> + Copy, { - test_2(|x: Scalar1, y: [Scalar2; LANES]| { + test_2(&|x: Scalar1, y: [Scalar2; LANES]| { proptest::prop_assume!(check(x, y)); let result_1: [ScalarResult; LANES] = fv(x, y.into()).into(); let result_2: [ScalarResult; LANES] = { From 976fafcf4fb8008255ce57bc62738a46f8a9152f Mon Sep 17 00:00:00 2001 From: Caleb Zulawski Date: Sat, 13 Feb 2021 11:40:10 -0500 Subject: [PATCH 08/13] Fix wasm tests --- crates/core_simd/src/macros.rs | 2 +- crates/core_simd/tests/float.rs | 3 -- crates/core_simd/tests/integer.rs | 3 -- crates/test_helpers/Cargo.toml | 6 ++-- crates/test_helpers/src/array.rs | 2 +- crates/test_helpers/src/lib.rs | 54 +++++++++++++++++++++++++------ crates/test_helpers/src/wasm.rs | 49 ++++++++++++++++++++++++++++ 7 files changed, 100 insertions(+), 19 deletions(-) create mode 100644 crates/test_helpers/src/wasm.rs diff --git a/crates/core_simd/src/macros.rs b/crates/core_simd/src/macros.rs index 3e428379b74d..75104dc50e45 100644 --- a/crates/core_simd/src/macros.rs +++ b/crates/core_simd/src/macros.rs @@ -143,7 +143,7 @@ macro_rules! impl_vector { impl From<$name> for [$type; LANES] { fn from(vector: $name) -> Self { - vector.0 + vector.to_array() } } diff --git a/crates/core_simd/tests/float.rs b/crates/core_simd/tests/float.rs index 03d132ae0468..618a75250bda 100644 --- a/crates/core_simd/tests/float.rs +++ b/crates/core_simd/tests/float.rs @@ -1,6 +1,3 @@ -#[cfg(target_arch = "wasm32")] -wasm_bindgen_test_configure!(run_in_browser); - macro_rules! impl_op_test { { unary, $vector:ty, $scalar:ty, $trait:ident :: $fn:ident } => { test_helpers::test_lanes! { diff --git a/crates/core_simd/tests/integer.rs b/crates/core_simd/tests/integer.rs index 878b3f0329a4..336126283563 100644 --- a/crates/core_simd/tests/integer.rs +++ b/crates/core_simd/tests/integer.rs @@ -1,6 +1,3 @@ -#[cfg(target_arch = "wasm32")] -wasm_bindgen_test_configure!(run_in_browser); - macro_rules! impl_unary_op_test { { $vector:ty, $scalar:ty, $trait:ident :: $fn:ident, $scalar_fn:expr } => { test_helpers::test_lanes! { diff --git a/crates/test_helpers/Cargo.toml b/crates/test_helpers/Cargo.toml index 0a8c3344334c..c9f6397b23b9 100644 --- a/crates/test_helpers/Cargo.toml +++ b/crates/test_helpers/Cargo.toml @@ -5,5 +5,7 @@ authors = ["Caleb Zulawski "] edition = "2018" publish = false -[dependencies] -proptest = "0.10" +[dependencies.proptest] +version = "0.10" +default-features = false +features = ["alloc"] diff --git a/crates/test_helpers/src/array.rs b/crates/test_helpers/src/array.rs index d9cae96ca2ff..3953d0bbea5e 100644 --- a/crates/test_helpers/src/array.rs +++ b/crates/test_helpers/src/array.rs @@ -18,7 +18,7 @@ pub struct UniformArrayStrategy { } impl UniformArrayStrategy { - pub fn new(strategy: S) -> Self { + pub const fn new(strategy: S) -> Self { Self { strategy, _marker: PhantomData, diff --git a/crates/test_helpers/src/lib.rs b/crates/test_helpers/src/lib.rs index 134b4073a4e2..e1832bf63779 100644 --- a/crates/test_helpers/src/lib.rs +++ b/crates/test_helpers/src/lib.rs @@ -1,5 +1,8 @@ pub mod array; +#[cfg(target_arch = "wasm32")] +pub mod wasm; + #[macro_use] pub mod biteq; @@ -23,17 +26,47 @@ impl_num! { i8 } impl_num! { i16 } impl_num! { i32 } impl_num! { i64 } -impl_num! { i128 } impl_num! { isize } impl_num! { u8 } impl_num! { u16 } impl_num! { u32 } impl_num! { u64 } -impl_num! { u128 } impl_num! { usize } impl_num! { f32 } impl_num! { f64 } +#[cfg(not(target_arch = "wasm32"))] +impl DefaultStrategy for u128 { + type Strategy = proptest::num::u128::Any; + fn default_strategy() -> Self::Strategy { + proptest::num::u128::ANY + } +} + +#[cfg(not(target_arch = "wasm32"))] +impl DefaultStrategy for i128 { + type Strategy = proptest::num::i128::Any; + fn default_strategy() -> Self::Strategy { + proptest::num::i128::ANY + } +} + +#[cfg(target_arch = "wasm32")] +impl DefaultStrategy for u128 { + type Strategy = crate::wasm::u128::Any; + fn default_strategy() -> Self::Strategy { + crate::wasm::u128::ANY + } +} + +#[cfg(target_arch = "wasm32")] +impl DefaultStrategy for i128 { + type Strategy = crate::wasm::i128::Any; + fn default_strategy() -> Self::Strategy { + crate::wasm::i128::ANY + } +} + impl DefaultStrategy for [T; LANES] { type Strategy = crate::array::UniformArrayStrategy; fn default_strategy() -> Self::Strategy { @@ -200,44 +233,47 @@ macro_rules! test_lanes { fn implementation() $body + #[cfg(target_arch = "wasm32")] + wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser); + #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] fn lanes_1() { implementation::<1>(); } #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] fn lanes_2() { implementation::<2>(); } #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] fn lanes_4() { implementation::<4>(); } #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] fn lanes_8() { implementation::<8>(); } #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] fn lanes_16() { implementation::<16>(); } #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] fn lanes_32() { implementation::<32>(); } #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] fn lanes_64() { implementation::<64>(); } diff --git a/crates/test_helpers/src/wasm.rs b/crates/test_helpers/src/wasm.rs new file mode 100644 index 000000000000..02cb9264d7c7 --- /dev/null +++ b/crates/test_helpers/src/wasm.rs @@ -0,0 +1,49 @@ +macro_rules! impl_num { + { $name:ident } => { + pub(crate) mod $name { + type InnerStrategy = crate::array::UniformArrayStrategy; + use proptest::strategy::{Strategy, ValueTree, NewTree}; + + + #[must_use = "strategies do nothing unless used"] + #[derive(Clone, Copy, Debug)] + pub struct Any { + strategy: InnerStrategy, + } + + pub struct BinarySearch { + inner: ::Tree, + } + + impl ValueTree for BinarySearch { + type Value = $name; + + fn current(&self) -> $name { + unsafe { core::mem::transmute(self.inner.current()) } + } + + fn simplify(&mut self) -> bool { + self.inner.simplify() + } + + fn complicate(&mut self) -> bool { + self.inner.complicate() + } + } + + impl Strategy for Any { + type Tree = BinarySearch; + type Value = $name; + + fn new_tree(&self, runner: &mut proptest::test_runner::TestRunner) -> NewTree { + Ok(BinarySearch { inner: self.strategy.new_tree(runner)? }) + } + } + + pub const ANY: Any = Any { strategy: InnerStrategy::new(proptest::num::u64::ANY) }; + } + } +} + +impl_num! { u128 } +impl_num! { i128 } From 0ec3ecfab15fe5baf45cfd452c2317a7f18f69bd Mon Sep 17 00:00:00 2001 From: Caleb Zulawski Date: Sat, 13 Feb 2021 14:19:16 -0500 Subject: [PATCH 09/13] Split ops tests --- crates/core_simd/tests/f32_ops.rs | 4 + crates/core_simd/tests/f64_ops.rs | 4 + crates/core_simd/tests/float.rs | 139 ------------------ crates/core_simd/tests/i128_ops.rs | 4 + crates/core_simd/tests/i16_ops.rs | 4 + crates/core_simd/tests/i32_ops.rs | 4 + crates/core_simd/tests/i64_ops.rs | 4 + crates/core_simd/tests/i8_ops.rs | 4 + crates/core_simd/tests/isize_ops.rs | 4 + .../tests/{integer.rs => ops_macros.rs} | 92 ++++++++++-- crates/core_simd/tests/u128_ops.rs | 4 + crates/core_simd/tests/u16_ops.rs | 4 + crates/core_simd/tests/u32_ops.rs | 4 + crates/core_simd/tests/u64_ops.rs | 4 + crates/core_simd/tests/u8_ops.rs | 4 + crates/core_simd/tests/usize_ops.rs | 4 + 16 files changed, 136 insertions(+), 151 deletions(-) create mode 100644 crates/core_simd/tests/f32_ops.rs create mode 100644 crates/core_simd/tests/f64_ops.rs delete mode 100644 crates/core_simd/tests/float.rs create mode 100644 crates/core_simd/tests/i128_ops.rs create mode 100644 crates/core_simd/tests/i16_ops.rs create mode 100644 crates/core_simd/tests/i32_ops.rs create mode 100644 crates/core_simd/tests/i64_ops.rs create mode 100644 crates/core_simd/tests/i8_ops.rs create mode 100644 crates/core_simd/tests/isize_ops.rs rename crates/core_simd/tests/{integer.rs => ops_macros.rs} (69%) create mode 100644 crates/core_simd/tests/u128_ops.rs create mode 100644 crates/core_simd/tests/u16_ops.rs create mode 100644 crates/core_simd/tests/u32_ops.rs create mode 100644 crates/core_simd/tests/u64_ops.rs create mode 100644 crates/core_simd/tests/u8_ops.rs create mode 100644 crates/core_simd/tests/usize_ops.rs diff --git a/crates/core_simd/tests/f32_ops.rs b/crates/core_simd/tests/f32_ops.rs new file mode 100644 index 000000000000..6e3802aae6a4 --- /dev/null +++ b/crates/core_simd/tests/f32_ops.rs @@ -0,0 +1,4 @@ +#[macro_use] +#[path = "ops_macros.rs"] +mod macros; +impl_float_tests! { SimdF32, f32, i32 } diff --git a/crates/core_simd/tests/f64_ops.rs b/crates/core_simd/tests/f64_ops.rs new file mode 100644 index 000000000000..da31cc3161bd --- /dev/null +++ b/crates/core_simd/tests/f64_ops.rs @@ -0,0 +1,4 @@ +#[macro_use] +#[path = "ops_macros.rs"] +mod macros; +impl_float_tests! { SimdF64, f64, i64 } diff --git a/crates/core_simd/tests/float.rs b/crates/core_simd/tests/float.rs deleted file mode 100644 index 618a75250bda..000000000000 --- a/crates/core_simd/tests/float.rs +++ /dev/null @@ -1,139 +0,0 @@ -macro_rules! impl_op_test { - { unary, $vector:ty, $scalar:ty, $trait:ident :: $fn:ident } => { - test_helpers::test_lanes! { - fn $fn() { - test_helpers::test_unary_elementwise( - &<$vector as core::ops::$trait>::$fn, - &<$scalar as core::ops::$trait>::$fn, - &|_| true, - ); - } - } - }; - { binary, $vector:ty, $scalar:ty, $trait:ident :: $fn:ident, $trait_assign:ident :: $fn_assign:ident } => { - mod $fn { - use super::*; - - test_helpers::test_lanes! { - fn normal() { - test_helpers::test_binary_elementwise( - &<$vector as core::ops::$trait>::$fn, - &<$scalar as core::ops::$trait>::$fn, - &|_, _| true, - ); - } - - fn scalar_rhs() { - test_helpers::test_binary_scalar_rhs_elementwise( - &<$vector as core::ops::$trait<$scalar>>::$fn, - &<$scalar as core::ops::$trait>::$fn, - &|_, _| true, - ); - } - - fn scalar_lhs() { - test_helpers::test_binary_scalar_lhs_elementwise( - &<$scalar as core::ops::$trait<$vector>>::$fn, - &<$scalar as core::ops::$trait>::$fn, - &|_, _| true, - ); - } - - fn assign() { - test_helpers::test_binary_elementwise( - &|mut a, b| { <$vector as core::ops::$trait_assign>::$fn_assign(&mut a, b); a }, - &|mut a, b| { <$scalar as core::ops::$trait_assign>::$fn_assign(&mut a, b); a }, - &|_, _| true, - ) - } - - fn assign_scalar_rhs() { - test_helpers::test_binary_scalar_rhs_elementwise( - &|mut a, b| { <$vector as core::ops::$trait_assign<$scalar>>::$fn_assign(&mut a, b); a }, - &|mut a, b| { <$scalar as core::ops::$trait_assign>::$fn_assign(&mut a, b); a }, - &|_, _| true, - ) - } - } - } - }; -} - -macro_rules! impl_tests { - { $vector:ident, $scalar:tt, $int_scalar:tt } => { - mod $scalar { - type Vector = core_simd::$vector; - type Scalar = $scalar; - type IntScalar = $int_scalar; - - impl_op_test! { unary, Vector, Scalar, Neg::neg } - impl_op_test! { binary, Vector, Scalar, Add::add, AddAssign::add_assign } - impl_op_test! { binary, Vector, Scalar, Sub::sub, SubAssign::sub_assign } - impl_op_test! { binary, Vector, Scalar, Mul::mul, SubAssign::sub_assign } - impl_op_test! { binary, Vector, Scalar, Div::div, DivAssign::div_assign } - impl_op_test! { binary, Vector, Scalar, Rem::rem, RemAssign::rem_assign } - - test_helpers::test_lanes! { - fn abs() { - test_helpers::test_unary_elementwise( - &Vector::::abs, - &Scalar::abs, - &|_| true, - ) - } - - fn ceil() { - test_helpers::test_unary_elementwise( - &Vector::::ceil, - &Scalar::ceil, - &|_| true, - ) - } - - fn floor() { - test_helpers::test_unary_elementwise( - &Vector::::floor, - &Scalar::floor, - &|_| true, - ) - } - - fn round_from_int() { - test_helpers::test_unary_elementwise( - &Vector::::round_from_int, - &|x| x as Scalar, - &|_| true, - ) - } - - fn to_int_unchecked() { - // The maximum integer that can be represented by the equivalently sized float has - // all of the mantissa digits set to 1, pushed up to the MSB. - const ALL_MANTISSA_BITS: IntScalar = ((1 << ::MANTISSA_DIGITS) - 1); - const MAX_REPRESENTABLE_VALUE: Scalar = - (ALL_MANTISSA_BITS << (core::mem::size_of::() * 8 - ::MANTISSA_DIGITS as usize - 1)) as Scalar; - - let mut runner = proptest::test_runner::TestRunner::default(); - runner.run( - &test_helpers::array::UniformArrayStrategy::new(-MAX_REPRESENTABLE_VALUE..MAX_REPRESENTABLE_VALUE), - |x| { - let result_1 = unsafe { Vector::from_array(x).to_int_unchecked().to_array() }; - let result_2 = { - let mut result = [0; LANES]; - for (i, o) in x.iter().zip(result.iter_mut()) { - *o = unsafe { i.to_int_unchecked() }; - } - result - }; - test_helpers::prop_assert_biteq!(result_1, result_2); - Ok(()) - }, - ).unwrap(); - } - } - } - } -} - -impl_tests! { SimdF32, f32, i32 } -impl_tests! { SimdF64, f64, i64 } diff --git a/crates/core_simd/tests/i128_ops.rs b/crates/core_simd/tests/i128_ops.rs new file mode 100644 index 000000000000..874324463cf1 --- /dev/null +++ b/crates/core_simd/tests/i128_ops.rs @@ -0,0 +1,4 @@ +#[macro_use] +#[path = "ops_macros.rs"] +mod macros; +impl_signed_tests! { SimdI128, i128 } diff --git a/crates/core_simd/tests/i16_ops.rs b/crates/core_simd/tests/i16_ops.rs new file mode 100644 index 000000000000..ebdbf60bce49 --- /dev/null +++ b/crates/core_simd/tests/i16_ops.rs @@ -0,0 +1,4 @@ +#[macro_use] +#[path = "ops_macros.rs"] +mod macros; +impl_signed_tests! { SimdI16, i16 } diff --git a/crates/core_simd/tests/i32_ops.rs b/crates/core_simd/tests/i32_ops.rs new file mode 100644 index 000000000000..5c2c41cdb18d --- /dev/null +++ b/crates/core_simd/tests/i32_ops.rs @@ -0,0 +1,4 @@ +#[macro_use] +#[path = "ops_macros.rs"] +mod macros; +impl_signed_tests! { SimdI32, i32 } diff --git a/crates/core_simd/tests/i64_ops.rs b/crates/core_simd/tests/i64_ops.rs new file mode 100644 index 000000000000..9321755d6719 --- /dev/null +++ b/crates/core_simd/tests/i64_ops.rs @@ -0,0 +1,4 @@ +#[macro_use] +#[path = "ops_macros.rs"] +mod macros; +impl_signed_tests! { SimdI64, i64 } diff --git a/crates/core_simd/tests/i8_ops.rs b/crates/core_simd/tests/i8_ops.rs new file mode 100644 index 000000000000..bea49c3a6468 --- /dev/null +++ b/crates/core_simd/tests/i8_ops.rs @@ -0,0 +1,4 @@ +#[macro_use] +#[path = "ops_macros.rs"] +mod macros; +impl_signed_tests! { SimdI8, i8 } diff --git a/crates/core_simd/tests/isize_ops.rs b/crates/core_simd/tests/isize_ops.rs new file mode 100644 index 000000000000..5ec29f232738 --- /dev/null +++ b/crates/core_simd/tests/isize_ops.rs @@ -0,0 +1,4 @@ +#[macro_use] +#[path = "ops_macros.rs"] +mod macros; +impl_signed_tests! { SimdIsize, isize } diff --git a/crates/core_simd/tests/integer.rs b/crates/core_simd/tests/ops_macros.rs similarity index 69% rename from crates/core_simd/tests/integer.rs rename to crates/core_simd/tests/ops_macros.rs index 336126283563..dc920c649d55 100644 --- a/crates/core_simd/tests/integer.rs +++ b/crates/core_simd/tests/ops_macros.rs @@ -1,3 +1,4 @@ +#[macro_export] macro_rules! impl_unary_op_test { { $vector:ty, $scalar:ty, $trait:ident :: $fn:ident, $scalar_fn:expr } => { test_helpers::test_lanes! { @@ -15,6 +16,7 @@ macro_rules! impl_unary_op_test { }; } +#[macro_export] macro_rules! impl_binary_op_test { { $vector:ty, $scalar:ty, $trait:ident :: $fn:ident, $trait_assign:ident :: $fn_assign:ident, $scalar_fn:expr } => { mod $fn { @@ -68,6 +70,7 @@ macro_rules! impl_binary_op_test { }; } +#[macro_export] macro_rules! impl_binary_checked_op_test { { $vector:ty, $scalar:ty, $trait:ident :: $fn:ident, $trait_assign:ident :: $fn_assign:ident, $scalar_fn:expr, $check_fn:expr } => { mod $fn { @@ -121,6 +124,7 @@ macro_rules! impl_binary_checked_op_test { }; } +#[macro_export] macro_rules! impl_signed_tests { { $vector:ident, $scalar:tt } => { mod $scalar { @@ -151,6 +155,7 @@ macro_rules! impl_signed_tests { } } +#[macro_export] macro_rules! impl_unsigned_tests { { $vector:ident, $scalar:tt } => { mod $scalar { @@ -171,16 +176,79 @@ macro_rules! impl_unsigned_tests { } } -impl_signed_tests! { SimdI8, i8 } -impl_signed_tests! { SimdI16, i16 } -impl_signed_tests! { SimdI32, i32 } -impl_signed_tests! { SimdI64, i64 } -impl_signed_tests! { SimdI128, i128 } -impl_signed_tests! { SimdIsize, isize } +#[macro_export] +macro_rules! impl_float_tests { + { $vector:ident, $scalar:tt, $int_scalar:tt } => { + mod $scalar { + type Vector = core_simd::$vector; + type Scalar = $scalar; + type IntScalar = $int_scalar; -impl_unsigned_tests! { SimdU8, u8 } -impl_unsigned_tests! { SimdU16, u16 } -impl_unsigned_tests! { SimdU32, u32 } -impl_unsigned_tests! { SimdU64, u64 } -impl_unsigned_tests! { SimdU128, u128 } -impl_unsigned_tests! { SimdUsize, usize } + impl_unary_op_test!(Vector, Scalar, Neg::neg); + impl_binary_op_test!(Vector, Scalar, Add::add, AddAssign::add_assign); + impl_binary_op_test!(Vector, Scalar, Sub::sub, SubAssign::sub_assign); + impl_binary_op_test!(Vector, Scalar, Mul::mul, SubAssign::sub_assign); + impl_binary_op_test!(Vector, Scalar, Div::div, DivAssign::div_assign); + impl_binary_op_test!(Vector, Scalar, Rem::rem, RemAssign::rem_assign); + + test_helpers::test_lanes! { + fn abs() { + test_helpers::test_unary_elementwise( + &Vector::::abs, + &Scalar::abs, + &|_| true, + ) + } + + fn ceil() { + test_helpers::test_unary_elementwise( + &Vector::::ceil, + &Scalar::ceil, + &|_| true, + ) + } + + fn floor() { + test_helpers::test_unary_elementwise( + &Vector::::floor, + &Scalar::floor, + &|_| true, + ) + } + + fn round_from_int() { + test_helpers::test_unary_elementwise( + &Vector::::round_from_int, + &|x| x as Scalar, + &|_| true, + ) + } + + fn to_int_unchecked() { + // The maximum integer that can be represented by the equivalently sized float has + // all of the mantissa digits set to 1, pushed up to the MSB. + const ALL_MANTISSA_BITS: IntScalar = ((1 << ::MANTISSA_DIGITS) - 1); + const MAX_REPRESENTABLE_VALUE: Scalar = + (ALL_MANTISSA_BITS << (core::mem::size_of::() * 8 - ::MANTISSA_DIGITS as usize - 1)) as Scalar; + + let mut runner = proptest::test_runner::TestRunner::default(); + runner.run( + &test_helpers::array::UniformArrayStrategy::new(-MAX_REPRESENTABLE_VALUE..MAX_REPRESENTABLE_VALUE), + |x| { + let result_1 = unsafe { Vector::from_array(x).to_int_unchecked().to_array() }; + let result_2 = { + let mut result = [0; LANES]; + for (i, o) in x.iter().zip(result.iter_mut()) { + *o = unsafe { i.to_int_unchecked() }; + } + result + }; + test_helpers::prop_assert_biteq!(result_1, result_2); + Ok(()) + }, + ).unwrap(); + } + } + } + } +} diff --git a/crates/core_simd/tests/u128_ops.rs b/crates/core_simd/tests/u128_ops.rs new file mode 100644 index 000000000000..eea7e3297c66 --- /dev/null +++ b/crates/core_simd/tests/u128_ops.rs @@ -0,0 +1,4 @@ +#[macro_use] +#[path = "ops_macros.rs"] +mod macros; +impl_unsigned_tests! { SimdU128, u128 } diff --git a/crates/core_simd/tests/u16_ops.rs b/crates/core_simd/tests/u16_ops.rs new file mode 100644 index 000000000000..ce9951a87c0a --- /dev/null +++ b/crates/core_simd/tests/u16_ops.rs @@ -0,0 +1,4 @@ +#[macro_use] +#[path = "ops_macros.rs"] +mod macros; +impl_unsigned_tests! { SimdU16, u16 } diff --git a/crates/core_simd/tests/u32_ops.rs b/crates/core_simd/tests/u32_ops.rs new file mode 100644 index 000000000000..87bedbd43b7c --- /dev/null +++ b/crates/core_simd/tests/u32_ops.rs @@ -0,0 +1,4 @@ +#[macro_use] +#[path = "ops_macros.rs"] +mod macros; +impl_unsigned_tests! { SimdU32, u32 } diff --git a/crates/core_simd/tests/u64_ops.rs b/crates/core_simd/tests/u64_ops.rs new file mode 100644 index 000000000000..ec76891da66e --- /dev/null +++ b/crates/core_simd/tests/u64_ops.rs @@ -0,0 +1,4 @@ +#[macro_use] +#[path = "ops_macros.rs"] +mod macros; +impl_unsigned_tests! { SimdU64, u64 } diff --git a/crates/core_simd/tests/u8_ops.rs b/crates/core_simd/tests/u8_ops.rs new file mode 100644 index 000000000000..00a63d846133 --- /dev/null +++ b/crates/core_simd/tests/u8_ops.rs @@ -0,0 +1,4 @@ +#[macro_use] +#[path = "ops_macros.rs"] +mod macros; +impl_unsigned_tests! { SimdU8, u8 } diff --git a/crates/core_simd/tests/usize_ops.rs b/crates/core_simd/tests/usize_ops.rs new file mode 100644 index 000000000000..dd49c656cbe8 --- /dev/null +++ b/crates/core_simd/tests/usize_ops.rs @@ -0,0 +1,4 @@ +#[macro_use] +#[path = "ops_macros.rs"] +mod macros; +impl_unsigned_tests! { SimdUsize, usize } From 714ad639b39f7a35422b3fc342eb843013cc89ba Mon Sep 17 00:00:00 2001 From: Caleb Zulawski Date: Sat, 13 Feb 2021 15:42:04 -0500 Subject: [PATCH 10/13] Fix MulAssign typo in tests, move panic tests --- crates/core_simd/tests/f32_ops.rs | 3 +- crates/core_simd/tests/f64_ops.rs | 3 +- crates/core_simd/tests/i128_ops.rs | 3 +- crates/core_simd/tests/i16_ops.rs | 3 +- crates/core_simd/tests/i32_ops.rs | 3 +- crates/core_simd/tests/i64_ops.rs | 3 +- crates/core_simd/tests/i8_ops.rs | 3 +- crates/core_simd/tests/isize_ops.rs | 3 +- crates/core_simd/tests/mask_ops.rs | 1 + .../{ops_impl => mask_ops_impl}/mask128.rs | 0 .../{ops_impl => mask_ops_impl}/mask16.rs | 0 .../{ops_impl => mask_ops_impl}/mask32.rs | 0 .../{ops_impl => mask_ops_impl}/mask64.rs | 0 .../{ops_impl => mask_ops_impl}/mask8.rs | 0 .../mask_macros.rs | 0 .../{ops_impl => mask_ops_impl}/masksize.rs | 0 .../tests/{ops_impl => mask_ops_impl}/mod.rs | 0 crates/core_simd/tests/ops.rs | 1 - crates/core_simd/tests/ops_impl/int_macros.rs | 101 ----- crates/core_simd/tests/ops_impl/u128.rs | 4 - crates/core_simd/tests/ops_impl/u16.rs | 6 - crates/core_simd/tests/ops_impl/u32.rs | 6 - crates/core_simd/tests/ops_impl/u64.rs | 5 - crates/core_simd/tests/ops_impl/u8.rs | 6 - .../core_simd/tests/ops_impl/uint_macros.rs | 428 ------------------ crates/core_simd/tests/ops_impl/usize.rs | 5 - crates/core_simd/tests/ops_macros.rs | 57 ++- crates/core_simd/tests/u128_ops.rs | 3 +- crates/core_simd/tests/u16_ops.rs | 3 +- crates/core_simd/tests/u32_ops.rs | 3 +- crates/core_simd/tests/u64_ops.rs | 3 +- crates/core_simd/tests/u8_ops.rs | 3 +- crates/core_simd/tests/usize_ops.rs | 3 +- crates/test_helpers/src/lib.rs | 59 ++- 34 files changed, 129 insertions(+), 592 deletions(-) create mode 100644 crates/core_simd/tests/mask_ops.rs rename crates/core_simd/tests/{ops_impl => mask_ops_impl}/mask128.rs (100%) rename crates/core_simd/tests/{ops_impl => mask_ops_impl}/mask16.rs (100%) rename crates/core_simd/tests/{ops_impl => mask_ops_impl}/mask32.rs (100%) rename crates/core_simd/tests/{ops_impl => mask_ops_impl}/mask64.rs (100%) rename crates/core_simd/tests/{ops_impl => mask_ops_impl}/mask8.rs (100%) rename crates/core_simd/tests/{ops_impl => mask_ops_impl}/mask_macros.rs (100%) rename crates/core_simd/tests/{ops_impl => mask_ops_impl}/masksize.rs (100%) rename crates/core_simd/tests/{ops_impl => mask_ops_impl}/mod.rs (100%) delete mode 100644 crates/core_simd/tests/ops.rs delete mode 100644 crates/core_simd/tests/ops_impl/int_macros.rs delete mode 100644 crates/core_simd/tests/ops_impl/u128.rs delete mode 100644 crates/core_simd/tests/ops_impl/u16.rs delete mode 100644 crates/core_simd/tests/ops_impl/u32.rs delete mode 100644 crates/core_simd/tests/ops_impl/u64.rs delete mode 100644 crates/core_simd/tests/ops_impl/u8.rs delete mode 100644 crates/core_simd/tests/ops_impl/uint_macros.rs delete mode 100644 crates/core_simd/tests/ops_impl/usize.rs diff --git a/crates/core_simd/tests/f32_ops.rs b/crates/core_simd/tests/f32_ops.rs index 6e3802aae6a4..ac5499b7ffeb 100644 --- a/crates/core_simd/tests/f32_ops.rs +++ b/crates/core_simd/tests/f32_ops.rs @@ -1,4 +1,3 @@ #[macro_use] -#[path = "ops_macros.rs"] -mod macros; +mod ops_macros; impl_float_tests! { SimdF32, f32, i32 } diff --git a/crates/core_simd/tests/f64_ops.rs b/crates/core_simd/tests/f64_ops.rs index da31cc3161bd..dcdb2aa31522 100644 --- a/crates/core_simd/tests/f64_ops.rs +++ b/crates/core_simd/tests/f64_ops.rs @@ -1,4 +1,3 @@ #[macro_use] -#[path = "ops_macros.rs"] -mod macros; +mod ops_macros; impl_float_tests! { SimdF64, f64, i64 } diff --git a/crates/core_simd/tests/i128_ops.rs b/crates/core_simd/tests/i128_ops.rs index 874324463cf1..3e3fa1d20682 100644 --- a/crates/core_simd/tests/i128_ops.rs +++ b/crates/core_simd/tests/i128_ops.rs @@ -1,4 +1,3 @@ #[macro_use] -#[path = "ops_macros.rs"] -mod macros; +mod ops_macros; impl_signed_tests! { SimdI128, i128 } diff --git a/crates/core_simd/tests/i16_ops.rs b/crates/core_simd/tests/i16_ops.rs index ebdbf60bce49..4d2a7b053b5c 100644 --- a/crates/core_simd/tests/i16_ops.rs +++ b/crates/core_simd/tests/i16_ops.rs @@ -1,4 +1,3 @@ #[macro_use] -#[path = "ops_macros.rs"] -mod macros; +mod ops_macros; impl_signed_tests! { SimdI16, i16 } diff --git a/crates/core_simd/tests/i32_ops.rs b/crates/core_simd/tests/i32_ops.rs index 5c2c41cdb18d..90079d727e4b 100644 --- a/crates/core_simd/tests/i32_ops.rs +++ b/crates/core_simd/tests/i32_ops.rs @@ -1,4 +1,3 @@ #[macro_use] -#[path = "ops_macros.rs"] -mod macros; +mod ops_macros; impl_signed_tests! { SimdI32, i32 } diff --git a/crates/core_simd/tests/i64_ops.rs b/crates/core_simd/tests/i64_ops.rs index 9321755d6719..ebc3e194974b 100644 --- a/crates/core_simd/tests/i64_ops.rs +++ b/crates/core_simd/tests/i64_ops.rs @@ -1,4 +1,3 @@ #[macro_use] -#[path = "ops_macros.rs"] -mod macros; +mod ops_macros; impl_signed_tests! { SimdI64, i64 } diff --git a/crates/core_simd/tests/i8_ops.rs b/crates/core_simd/tests/i8_ops.rs index bea49c3a6468..082422b86d29 100644 --- a/crates/core_simd/tests/i8_ops.rs +++ b/crates/core_simd/tests/i8_ops.rs @@ -1,4 +1,3 @@ #[macro_use] -#[path = "ops_macros.rs"] -mod macros; +mod ops_macros; impl_signed_tests! { SimdI8, i8 } diff --git a/crates/core_simd/tests/isize_ops.rs b/crates/core_simd/tests/isize_ops.rs index 5ec29f232738..1509d701c29a 100644 --- a/crates/core_simd/tests/isize_ops.rs +++ b/crates/core_simd/tests/isize_ops.rs @@ -1,4 +1,3 @@ #[macro_use] -#[path = "ops_macros.rs"] -mod macros; +mod ops_macros; impl_signed_tests! { SimdIsize, isize } diff --git a/crates/core_simd/tests/mask_ops.rs b/crates/core_simd/tests/mask_ops.rs new file mode 100644 index 000000000000..96330550b40b --- /dev/null +++ b/crates/core_simd/tests/mask_ops.rs @@ -0,0 +1 @@ +mod mask_ops_impl; diff --git a/crates/core_simd/tests/ops_impl/mask128.rs b/crates/core_simd/tests/mask_ops_impl/mask128.rs similarity index 100% rename from crates/core_simd/tests/ops_impl/mask128.rs rename to crates/core_simd/tests/mask_ops_impl/mask128.rs diff --git a/crates/core_simd/tests/ops_impl/mask16.rs b/crates/core_simd/tests/mask_ops_impl/mask16.rs similarity index 100% rename from crates/core_simd/tests/ops_impl/mask16.rs rename to crates/core_simd/tests/mask_ops_impl/mask16.rs diff --git a/crates/core_simd/tests/ops_impl/mask32.rs b/crates/core_simd/tests/mask_ops_impl/mask32.rs similarity index 100% rename from crates/core_simd/tests/ops_impl/mask32.rs rename to crates/core_simd/tests/mask_ops_impl/mask32.rs diff --git a/crates/core_simd/tests/ops_impl/mask64.rs b/crates/core_simd/tests/mask_ops_impl/mask64.rs similarity index 100% rename from crates/core_simd/tests/ops_impl/mask64.rs rename to crates/core_simd/tests/mask_ops_impl/mask64.rs diff --git a/crates/core_simd/tests/ops_impl/mask8.rs b/crates/core_simd/tests/mask_ops_impl/mask8.rs similarity index 100% rename from crates/core_simd/tests/ops_impl/mask8.rs rename to crates/core_simd/tests/mask_ops_impl/mask8.rs diff --git a/crates/core_simd/tests/ops_impl/mask_macros.rs b/crates/core_simd/tests/mask_ops_impl/mask_macros.rs similarity index 100% rename from crates/core_simd/tests/ops_impl/mask_macros.rs rename to crates/core_simd/tests/mask_ops_impl/mask_macros.rs diff --git a/crates/core_simd/tests/ops_impl/masksize.rs b/crates/core_simd/tests/mask_ops_impl/masksize.rs similarity index 100% rename from crates/core_simd/tests/ops_impl/masksize.rs rename to crates/core_simd/tests/mask_ops_impl/masksize.rs diff --git a/crates/core_simd/tests/ops_impl/mod.rs b/crates/core_simd/tests/mask_ops_impl/mod.rs similarity index 100% rename from crates/core_simd/tests/ops_impl/mod.rs rename to crates/core_simd/tests/mask_ops_impl/mod.rs diff --git a/crates/core_simd/tests/ops.rs b/crates/core_simd/tests/ops.rs deleted file mode 100644 index 60aff06a76a6..000000000000 --- a/crates/core_simd/tests/ops.rs +++ /dev/null @@ -1 +0,0 @@ -mod ops_impl; diff --git a/crates/core_simd/tests/ops_impl/int_macros.rs b/crates/core_simd/tests/ops_impl/int_macros.rs deleted file mode 100644 index f565ae2f04df..000000000000 --- a/crates/core_simd/tests/ops_impl/int_macros.rs +++ /dev/null @@ -1,101 +0,0 @@ -macro_rules! int_tests { - { $vector:ident, $scalar:ident } => { - #[cfg(test)] - mod $vector { - use super::*; - use helpers::lanewise::*; - - #[cfg(target_arch = "wasm32")] - use wasm_bindgen_test::*; - - #[cfg(target_arch = "wasm32")] - wasm_bindgen_test_configure!(run_in_browser); - - // TODO impl this as an associated fn on vectors - fn from_slice(slice: &[$scalar]) -> core_simd::$vector { - let mut value = core_simd::$vector::default(); - let value_slice: &mut [_] = value.as_mut(); - value_slice.copy_from_slice(&slice[0..value_slice.len()]); - value - } - - const A: [$scalar; 64] = [ - 7, 7, 7, 7, -7, -7, -7, -7, - 6, 6, 6, 6, -6, -6, -6, -6, - 5, 5, 5, 5, -5, -5, -5, -5, - 4, 4, 4, 4, -4, -4, -4, -4, - 3, 3, 3, 3, -3, -3, -3, -3, - 2, 2, 2, 2, -2, -2, -2, -2, - 1, 1, 1, 1, -1, -1, -1, -1, - 0, 0, 0, 0, 0, 0, 0, 0, - ]; - const B: [$scalar; 64] = [ - 1, 2, 3, 4, 5, 6, 7, 8, - 1, 2, 3, 4, 5, 6, 7, 8, - 1, 2, 3, 4, 5, 6, 7, 8, - 1, 2, 3, 4, 5, 6, 7, 8, - -1, -2, -3, -4, -5, -6, -7, -8, - -1, -2, -3, -4, -5, -6, -7, -8, - -1, -2, -3, -4, -5, -6, -7, -8, - -1, -2, -3, -4, -5, -6, -7, -8, - ]; - - #[test] - #[should_panic] - fn div_min_panics() { - let a = from_slice(&vec![$scalar::MIN; 64]); - let b = from_slice(&vec![-1; 64]); - let _ = a / b; - } - - #[test] - #[should_panic] - fn div_by_all_zeros_panics() { - let a = from_slice(&A); - let b = from_slice(&vec![0 ; 64]); - let _ = a / b; - } - - #[test] - #[should_panic] - fn div_by_one_zero_panics() { - let a = from_slice(&A); - let mut b = from_slice(&B); - b[0] = 0 as _; - let _ = a / b; - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn div_min_neg_one_no_panic() { - let a = from_slice(&A); - let b = from_slice(&vec![-1; 64]); - let _ = a / b; - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn rem_min_neg_one_no_panic() { - let a = from_slice(&A); - let b = from_slice(&vec![-1; 64]); - let _ = a % b; - } - - #[test] - #[should_panic] - fn rem_min_panic() { - let a = from_slice(&vec![$scalar::MIN; 64]); - let b = from_slice(&vec![-1 ; 64]); - let _ = a % b; - } - - #[test] - #[should_panic] - fn rem_min_zero_panic() { - let a = from_slice(&A); - let b = from_slice(&vec![0 ; 64]); - let _ = a % b; - } - } - } -} diff --git a/crates/core_simd/tests/ops_impl/u128.rs b/crates/core_simd/tests/ops_impl/u128.rs deleted file mode 100644 index cfd849640ffe..000000000000 --- a/crates/core_simd/tests/ops_impl/u128.rs +++ /dev/null @@ -1,4 +0,0 @@ -use super::helpers; - -uint_tests! { u128x2, u128 } -uint_tests! { u128x4, u128 } diff --git a/crates/core_simd/tests/ops_impl/u16.rs b/crates/core_simd/tests/ops_impl/u16.rs deleted file mode 100644 index 50af4dd48b38..000000000000 --- a/crates/core_simd/tests/ops_impl/u16.rs +++ /dev/null @@ -1,6 +0,0 @@ -use super::helpers; - -uint_tests! { u16x4, u16 } -uint_tests! { u16x8, u16 } -uint_tests! { u16x16, u16 } -uint_tests! { u16x32, u16 } diff --git a/crates/core_simd/tests/ops_impl/u32.rs b/crates/core_simd/tests/ops_impl/u32.rs deleted file mode 100644 index 8e7faa9d7403..000000000000 --- a/crates/core_simd/tests/ops_impl/u32.rs +++ /dev/null @@ -1,6 +0,0 @@ -use super::helpers; - -uint_tests! { u32x2, u32 } -uint_tests! { u32x4, u32 } -uint_tests! { u32x8, u32 } -uint_tests! { u32x16, u32 } diff --git a/crates/core_simd/tests/ops_impl/u64.rs b/crates/core_simd/tests/ops_impl/u64.rs deleted file mode 100644 index 1a6385d37bae..000000000000 --- a/crates/core_simd/tests/ops_impl/u64.rs +++ /dev/null @@ -1,5 +0,0 @@ -use super::helpers; - -uint_tests! { u64x2, u64 } -uint_tests! { u64x4, u64 } -uint_tests! { u64x8, u64 } diff --git a/crates/core_simd/tests/ops_impl/u8.rs b/crates/core_simd/tests/ops_impl/u8.rs deleted file mode 100644 index 31568b1eacbe..000000000000 --- a/crates/core_simd/tests/ops_impl/u8.rs +++ /dev/null @@ -1,6 +0,0 @@ -use super::helpers; - -uint_tests! { u8x8, u8 } -uint_tests! { u8x16, u8 } -uint_tests! { u8x32, u8 } -uint_tests! { u8x64, u8 } diff --git a/crates/core_simd/tests/ops_impl/uint_macros.rs b/crates/core_simd/tests/ops_impl/uint_macros.rs deleted file mode 100644 index bc8b3be74860..000000000000 --- a/crates/core_simd/tests/ops_impl/uint_macros.rs +++ /dev/null @@ -1,428 +0,0 @@ -macro_rules! uint_tests { - { $vector:ident, $scalar:ident } => { - #[cfg(test)] - mod $vector { - use super::*; - use helpers::lanewise::*; - - #[cfg(target_arch = "wasm32")] - use wasm_bindgen_test::*; - - #[cfg(target_arch = "wasm32")] - wasm_bindgen_test_configure!(run_in_browser); - - // TODO impl this as an associated fn on vectors - fn from_slice(slice: &[$scalar]) -> core_simd::$vector { - let mut value = core_simd::$vector::default(); - let value_slice: &mut [_] = value.as_mut(); - value_slice.copy_from_slice(&slice[0..value_slice.len()]); - value - } - - const A: [$scalar; 64] = [ - 16, 16, 16, 16, 16, 16, 16, 16, - 14, 14, 14, 14, 14, 14, 14, 14, - 12, 12, 12, 12, 12, 12, 12, 12, - 10, 10, 10, 10, 10, 10, 10, 10, - 8, 8, 8, 8, 8, 8, 8, 8, - 6, 6, 6, 6, 6, 6, 7, 8, - 4, 4, 4, 4, 5, 6, 7, 8, - 1, 2, 3, 4, 5, 6, 7, 8, - ]; - const B: [$scalar; 64] = [ - 1, 2, 3, 4, 1, 2, 3, 4, - 1, 2, 3, 4, 5, 6, 7, 8, - 1, 2, 3, 4, 5, 6, 7, 8, - 1, 2, 3, 4, 5, 6, 7, 8, - 1, 2, 3, 4, 5, 6, 7, 8, - 1, 2, 3, 4, 5, 6, 7, 8, - 1, 2, 3, 4, 5, 6, 7, 8, - 1, 2, 3, 4, 5, 6, 7, 8, - ]; - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn add() { - let a = from_slice(&A); - let b = from_slice(&B); - let expected = apply_binary_lanewise(a, b, core::ops::Add::add); - assert_biteq!(a + b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn add_assign() { - let mut a = from_slice(&A); - let b = from_slice(&B); - let expected = apply_binary_lanewise(a, b, core::ops::Add::add); - a += b; - assert_biteq!(a, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn add_scalar_rhs() { - let a = from_slice(&A); - let b = 5; - let expected = apply_binary_scalar_rhs_lanewise(a, b, core::ops::Add::add); - assert_biteq!(a + b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn add_scalar_lhs() { - let a = 5; - let b = from_slice(&B); - let expected = apply_binary_scalar_lhs_lanewise(a, b, core::ops::Add::add); - assert_biteq!(a + b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn add_assign_scalar() { - let mut a = from_slice(&A); - let b = 5; - let expected = apply_binary_scalar_rhs_lanewise(a, b, core::ops::Add::add); - a += b; - assert_biteq!(a, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn sub() { - let a = from_slice(&A); - let b = from_slice(&B); - let expected = apply_binary_lanewise(a, b, core::ops::Sub::sub); - assert_biteq!(a - b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn sub_assign() { - let mut a = from_slice(&A); - let b = from_slice(&B); - let expected = apply_binary_lanewise(a, b, core::ops::Sub::sub); - a -= b; - assert_biteq!(a, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn sub_scalar_rhs() { - let a = from_slice(&A); - let b = 1; - let expected = apply_binary_scalar_rhs_lanewise(a, b, core::ops::Sub::sub); - assert_biteq!(a - b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn sub_scalar_lhs() { - let a = 40; - let b = from_slice(&B); - let expected = apply_binary_scalar_lhs_lanewise(a, b, core::ops::Sub::sub); - assert_biteq!(a - b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn sub_assign_scalar() { - let mut a = from_slice(&A); - let b = 1; - let expected = apply_binary_scalar_rhs_lanewise(a, b, core::ops::Sub::sub); - a -= b; - assert_biteq!(a, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn mul() { - let a = from_slice(&A); - let b = from_slice(&B); - let expected = apply_binary_lanewise(a, b, core::ops::Mul::mul); - assert_biteq!(a * b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn mul_assign() { - let mut a = from_slice(&A); - let b = from_slice(&B); - let expected = apply_binary_lanewise(a, b, core::ops::Mul::mul); - a *= b; - assert_biteq!(a, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn mul_scalar_rhs() { - let a = from_slice(&A); - let b = 5; - let expected = apply_binary_scalar_rhs_lanewise(a, b, core::ops::Mul::mul); - assert_biteq!(a * b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn mul_scalar_lhs() { - let a = 5; - let b = from_slice(&B); - let expected = apply_binary_scalar_lhs_lanewise(a, b, core::ops::Mul::mul); - assert_biteq!(a * b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn mul_assign_scalar() { - let mut a = from_slice(&A); - let b = 5; - let expected = apply_binary_scalar_rhs_lanewise(a, b, core::ops::Mul::mul); - a *= b; - assert_biteq!(a, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn div() { - let a = from_slice(&A); - let b = from_slice(&B); - let expected = apply_binary_lanewise(a, b, core::ops::Div::div); - assert_biteq!(a / b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn div_assign() { - let mut a = from_slice(&A); - let b = from_slice(&B); - let expected = apply_binary_lanewise(a, b, core::ops::Div::div); - a /= b; - assert_biteq!(a, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn div_scalar_rhs() { - let a = from_slice(&A); - let b = 5; - let expected = apply_binary_scalar_rhs_lanewise(a, b, core::ops::Div::div); - assert_biteq!(a / b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn div_scalar_lhs() { - let a = 5; - let b = from_slice(&B); - let expected = apply_binary_scalar_lhs_lanewise(a, b, core::ops::Div::div); - assert_biteq!(a / b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn div_assign_scalar() { - let mut a = from_slice(&A); - let b = 5; - let expected = apply_binary_scalar_rhs_lanewise(a, b, core::ops::Div::div); - a /= b; - assert_biteq!(a, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn rem() { - let a = from_slice(&A); - let b = from_slice(&B); - let expected = apply_binary_lanewise(a, b, core::ops::Rem::rem); - assert_biteq!(a % b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn rem_assign() { - let mut a = from_slice(&A); - let b = from_slice(&B); - let expected = apply_binary_lanewise(a, b, core::ops::Rem::rem); - a %= b; - assert_biteq!(a, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn rem_scalar_rhs() { - let a = from_slice(&A); - let b = 5; - let expected = apply_binary_scalar_rhs_lanewise(a, b, core::ops::Rem::rem); - assert_biteq!(a % b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn rem_scalar_lhs() { - let a = 5; - let b = from_slice(&B); - let expected = apply_binary_scalar_lhs_lanewise(a, b, core::ops::Rem::rem); - assert_biteq!(a % b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn rem_assign_scalar() { - let mut a = from_slice(&A); - let b = 5; - let expected = apply_binary_scalar_rhs_lanewise(a, b, core::ops::Rem::rem); - a %= b; - assert_biteq!(a, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn bitand() { - let a = from_slice(&A); - let b = from_slice(&B); - let expected = apply_binary_lanewise(a, b, core::ops::BitAnd::bitand); - assert_biteq!(a & b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn bitand_assign() { - let mut a = from_slice(&A); - let b = from_slice(&B); - let expected = apply_binary_lanewise(a, b, core::ops::BitAnd::bitand); - a &= b; - assert_biteq!(a, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn bitand_scalar_rhs() { - let a = from_slice(&A); - let b = 5; - let expected = apply_binary_scalar_rhs_lanewise(a, b, core::ops::BitAnd::bitand); - assert_biteq!(a & b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn bitand_scalar_lhs() { - let a = 5; - let b = from_slice(&B); - let expected = apply_binary_scalar_lhs_lanewise(a, b, core::ops::BitAnd::bitand); - assert_biteq!(a & b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn bitand_assign_scalar() { - let mut a = from_slice(&A); - let b = 5; - let expected = apply_binary_scalar_rhs_lanewise(a, b, core::ops::BitAnd::bitand); - a &= b; - assert_biteq!(a, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn bitor() { - let a = from_slice(&A); - let b = from_slice(&B); - let expected = apply_binary_lanewise(a, b, core::ops::BitOr::bitor); - assert_biteq!(a | b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn bitor_assign() { - let mut a = from_slice(&A); - let b = from_slice(&B); - let expected = apply_binary_lanewise(a, b, core::ops::BitOr::bitor); - a |= b; - assert_biteq!(a, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn bitor_scalar_rhs() { - let a = from_slice(&A); - let b = 5; - let expected = apply_binary_scalar_rhs_lanewise(a, b, core::ops::BitOr::bitor); - assert_biteq!(a | b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn bitor_scalar_lhs() { - let a = 5; - let b = from_slice(&B); - let expected = apply_binary_scalar_lhs_lanewise(a, b, core::ops::BitOr::bitor); - assert_biteq!(a | b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn bitor_assign_scalar() { - let mut a = from_slice(&A); - let b = 5; - let expected = apply_binary_scalar_rhs_lanewise(a, b, core::ops::BitOr::bitor); - a |= b; - assert_biteq!(a, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn bitxor() { - let a = from_slice(&A); - let b = from_slice(&B); - let expected = apply_binary_lanewise(a, b, core::ops::BitXor::bitxor); - assert_biteq!(a ^ b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn bitxor_assign() { - let mut a = from_slice(&A); - let b = from_slice(&B); - let expected = apply_binary_lanewise(a, b, core::ops::BitXor::bitxor); - a ^= b; - assert_biteq!(a, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn bitxor_scalar_rhs() { - let a = from_slice(&A); - let b = 5; - let expected = apply_binary_scalar_rhs_lanewise(a, b, core::ops::BitXor::bitxor); - assert_biteq!(a ^ b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn bitxor_scalar_lhs() { - let a = 5; - let b = from_slice(&B); - let expected = apply_binary_scalar_lhs_lanewise(a, b, core::ops::BitXor::bitxor); - assert_biteq!(a ^ b, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn bitxor_assign_scalar() { - let mut a = from_slice(&A); - let b = 5; - let expected = apply_binary_scalar_rhs_lanewise(a, b, core::ops::BitXor::bitxor); - a ^= b; - assert_biteq!(a, expected); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn not() { - let v = from_slice(&A); - let expected = apply_unary_lanewise(v, core::ops::Not::not); - assert_biteq!(!v, expected); - } - } - } -} diff --git a/crates/core_simd/tests/ops_impl/usize.rs b/crates/core_simd/tests/ops_impl/usize.rs deleted file mode 100644 index 13da57f15869..000000000000 --- a/crates/core_simd/tests/ops_impl/usize.rs +++ /dev/null @@ -1,5 +0,0 @@ -use super::helpers; - -uint_tests! { usizex2, usize } -uint_tests! { usizex4, usize } -uint_tests! { usizex8, usize } diff --git a/crates/core_simd/tests/ops_macros.rs b/crates/core_simd/tests/ops_macros.rs index dc920c649d55..a4b26a1777af 100644 --- a/crates/core_simd/tests/ops_macros.rs +++ b/crates/core_simd/tests/ops_macros.rs @@ -141,6 +141,53 @@ macro_rules! impl_signed_tests { } } + test_helpers::test_lanes_panic! { + fn div_min_overflow_panics() { + let a = Vector::::splat(Scalar::MIN); + let b = Vector::::splat(-1); + let _ = a / b; + } + + fn div_by_all_zeros_panics() { + let a = Vector::::splat(42); + let b = Vector::::splat(0); + let _ = a / b; + } + + fn div_by_one_zero_panics() { + let a = Vector::::splat(42); + let mut b = Vector::::splat(21); + b[0] = 0 as _; + let _ = a / b; + } + + fn rem_min_overflow_panic() { + let a = Vector::::splat(Scalar::MIN); + let b = Vector::::splat(-1); + let _ = a % b; + } + + fn rem_zero_panic() { + let a = Vector::::splat(42); + let b = Vector::::splat(0); + let _ = a % b; + } + } + + test_helpers::test_lanes! { + fn div_neg_one_no_panic() { + let a = Vector::::splat(42); + let b = Vector::::splat(-1); + let _ = a / b; + } + + fn rem_neg_one_no_panic() { + let a = Vector::::splat(42); + let b = Vector::::splat(-1); + let _ = a % b; + } + } + impl_binary_op_test!(Vector, Scalar, Add::add, AddAssign::add_assign, Scalar::wrapping_add); impl_binary_op_test!(Vector, Scalar, Sub::sub, SubAssign::sub_assign, Scalar::wrapping_sub); impl_binary_op_test!(Vector, Scalar, Mul::mul, MulAssign::mul_assign, Scalar::wrapping_mul); @@ -162,6 +209,14 @@ macro_rules! impl_unsigned_tests { type Vector = core_simd::$vector; type Scalar = $scalar; + test_helpers::test_lanes_panic! { + fn rem_zero_panic() { + let a = Vector::::splat(42); + let b = Vector::::splat(0); + let _ = a % b; + } + } + impl_binary_op_test!(Vector, Scalar, Add::add, AddAssign::add_assign, Scalar::wrapping_add); impl_binary_op_test!(Vector, Scalar, Sub::sub, SubAssign::sub_assign, Scalar::wrapping_sub); impl_binary_op_test!(Vector, Scalar, Mul::mul, MulAssign::mul_assign, Scalar::wrapping_mul); @@ -187,7 +242,7 @@ macro_rules! impl_float_tests { impl_unary_op_test!(Vector, Scalar, Neg::neg); impl_binary_op_test!(Vector, Scalar, Add::add, AddAssign::add_assign); impl_binary_op_test!(Vector, Scalar, Sub::sub, SubAssign::sub_assign); - impl_binary_op_test!(Vector, Scalar, Mul::mul, SubAssign::sub_assign); + impl_binary_op_test!(Vector, Scalar, Mul::mul, MulAssign::mul_assign); impl_binary_op_test!(Vector, Scalar, Div::div, DivAssign::div_assign); impl_binary_op_test!(Vector, Scalar, Rem::rem, RemAssign::rem_assign); diff --git a/crates/core_simd/tests/u128_ops.rs b/crates/core_simd/tests/u128_ops.rs index eea7e3297c66..4be7d751ffd8 100644 --- a/crates/core_simd/tests/u128_ops.rs +++ b/crates/core_simd/tests/u128_ops.rs @@ -1,4 +1,3 @@ #[macro_use] -#[path = "ops_macros.rs"] -mod macros; +mod ops_macros; impl_unsigned_tests! { SimdU128, u128 } diff --git a/crates/core_simd/tests/u16_ops.rs b/crates/core_simd/tests/u16_ops.rs index ce9951a87c0a..488e703d54fb 100644 --- a/crates/core_simd/tests/u16_ops.rs +++ b/crates/core_simd/tests/u16_ops.rs @@ -1,4 +1,3 @@ #[macro_use] -#[path = "ops_macros.rs"] -mod macros; +mod ops_macros; impl_unsigned_tests! { SimdU16, u16 } diff --git a/crates/core_simd/tests/u32_ops.rs b/crates/core_simd/tests/u32_ops.rs index 87bedbd43b7c..bf0631029e37 100644 --- a/crates/core_simd/tests/u32_ops.rs +++ b/crates/core_simd/tests/u32_ops.rs @@ -1,4 +1,3 @@ #[macro_use] -#[path = "ops_macros.rs"] -mod macros; +mod ops_macros; impl_unsigned_tests! { SimdU32, u32 } diff --git a/crates/core_simd/tests/u64_ops.rs b/crates/core_simd/tests/u64_ops.rs index ec76891da66e..e52fc3cfce1f 100644 --- a/crates/core_simd/tests/u64_ops.rs +++ b/crates/core_simd/tests/u64_ops.rs @@ -1,4 +1,3 @@ #[macro_use] -#[path = "ops_macros.rs"] -mod macros; +mod ops_macros; impl_unsigned_tests! { SimdU64, u64 } diff --git a/crates/core_simd/tests/u8_ops.rs b/crates/core_simd/tests/u8_ops.rs index 00a63d846133..45be3580ec39 100644 --- a/crates/core_simd/tests/u8_ops.rs +++ b/crates/core_simd/tests/u8_ops.rs @@ -1,4 +1,3 @@ #[macro_use] -#[path = "ops_macros.rs"] -mod macros; +mod ops_macros; impl_unsigned_tests! { SimdU8, u8 } diff --git a/crates/core_simd/tests/usize_ops.rs b/crates/core_simd/tests/usize_ops.rs index dd49c656cbe8..1ce6e7180045 100644 --- a/crates/core_simd/tests/usize_ops.rs +++ b/crates/core_simd/tests/usize_ops.rs @@ -1,4 +1,3 @@ #[macro_use] -#[path = "ops_macros.rs"] -mod macros; +mod ops_macros; impl_unsigned_tests! { SimdUsize, usize } diff --git a/crates/test_helpers/src/lib.rs b/crates/test_helpers/src/lib.rs index e1832bf63779..253435dea336 100644 --- a/crates/test_helpers/src/lib.rs +++ b/crates/test_helpers/src/lib.rs @@ -280,4 +280,61 @@ macro_rules! test_lanes { } )* } -} +} + +#[macro_export] +macro_rules! test_lanes_panic { + { + $(fn $test:ident() $body:tt)* + } => { + $( + mod $test { + use super::*; + + fn implementation() $body + + #[test] + #[should_panic] + fn lanes_1() { + implementation::<1>(); + } + + #[test] + #[should_panic] + fn lanes_2() { + implementation::<2>(); + } + + #[test] + #[should_panic] + fn lanes_4() { + implementation::<4>(); + } + + #[test] + #[should_panic] + fn lanes_8() { + implementation::<8>(); + } + + #[test] + #[should_panic] + fn lanes_16() { + implementation::<16>(); + } + + #[test] + #[should_panic] + fn lanes_32() { + implementation::<32>(); + } + + #[test] + #[should_panic] + fn lanes_64() { + implementation::<64>(); + } + } + )* + } +} From 8c378d30271de8cb9e09a4b70f28db71f282f413 Mon Sep 17 00:00:00 2001 From: Caleb Zulawski Date: Sat, 13 Feb 2021 15:58:44 -0500 Subject: [PATCH 11/13] Add documentation --- crates/core_simd/tests/helpers/biteq.rs | 120 -------------------- crates/core_simd/tests/helpers/mod.rs | 2 - crates/core_simd/tests/mask_ops_impl/mod.rs | 4 - crates/core_simd/tests/ops_macros.rs | 19 ++++ crates/test_helpers/src/array.rs | 2 + crates/test_helpers/src/biteq.rs | 2 + crates/test_helpers/src/lib.rs | 11 ++ crates/test_helpers/src/wasm.rs | 2 + 8 files changed, 36 insertions(+), 126 deletions(-) delete mode 100644 crates/core_simd/tests/helpers/biteq.rs delete mode 100644 crates/core_simd/tests/helpers/mod.rs diff --git a/crates/core_simd/tests/helpers/biteq.rs b/crates/core_simd/tests/helpers/biteq.rs deleted file mode 100644 index 9da2bdfce42e..000000000000 --- a/crates/core_simd/tests/helpers/biteq.rs +++ /dev/null @@ -1,120 +0,0 @@ -pub(crate) trait BitEq { - fn biteq(&self, other: &Self) -> bool; - fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result; -} - -macro_rules! impl_biteq { - { integer impl BitEq for $($type:ty,)* } => { - $( - impl BitEq for $type { - fn biteq(&self, other: &Self) -> bool { - self == other - } - - fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { - write!(f, "{:?} ({:x})", self, self) - } - } - )* - }; - { float impl BitEq for $($type:ty,)* } => { - $( - impl BitEq for $type { - fn biteq(&self, other: &Self) -> bool { - self.to_bits() == other.to_bits() - } - - fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { - write!(f, "{:?} ({:x})", self, self.to_bits()) - } - } - )* - }; - { vector impl BitEq for $($type:ty,)* } => { - $( - impl BitEq for $type { - fn biteq(&self, other: &Self) -> bool { - let a: &[_] = self.as_ref(); - let b: &[_] = other.as_ref(); - if a.len() == b.len() { - a.iter().zip(b.iter()).fold(true, |value, (left, right)| { - value && left.biteq(right) - }) - } else { - false - } - } - - fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { - #[repr(transparent)] - struct Wrapper<'a, T: BitEq>(&'a T); - - impl core::fmt::Debug for Wrapper<'_, T> { - fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { - self.0.fmt(f) - } - } - - let slice: &[_] = self.as_ref(); - - f.debug_list() - .entries(slice.iter().map(|x| Wrapper(x))) - .finish() - } - } - )* - }; -} - -impl_biteq! { - integer impl BitEq for - u8, u16, u32, u64, u128, usize, - i8, i16, i32, i64, i128, isize, -} - -impl_biteq! { - float impl BitEq for f32, f64, -} - -impl_biteq! { - vector impl BitEq for - core_simd::u8x8, core_simd::u8x16, core_simd::u8x32, core_simd::u8x64, - core_simd::i8x8, core_simd::i8x16, core_simd::i8x32, core_simd::i8x64, - core_simd::u16x4, core_simd::u16x8, core_simd::u16x16, core_simd::u16x32, - core_simd::i16x4, core_simd::i16x8, core_simd::i16x16, core_simd::i16x32, - core_simd::u32x2, core_simd::u32x4, core_simd::u32x8, core_simd::u32x16, - core_simd::i32x2, core_simd::i32x4, core_simd::i32x8, core_simd::i32x16, - core_simd::u64x2, core_simd::u64x4, core_simd::u64x8, - core_simd::i64x2, core_simd::i64x4, core_simd::i64x8, - core_simd::u128x2, core_simd::u128x4, - core_simd::i128x2, core_simd::i128x4, - core_simd::usizex2, core_simd::usizex4, core_simd::usizex8, - core_simd::isizex2, core_simd::isizex4, core_simd::isizex8, - core_simd::f32x2, core_simd::f32x4, core_simd::f32x8, core_simd::f32x16, - core_simd::f64x2, core_simd::f64x4, core_simd::f64x8, -} - -pub(crate) struct BitEqWrapper<'a, T>(pub(crate) &'a T); - -impl PartialEq for BitEqWrapper<'_, T> { - fn eq(&self, other: &Self) -> bool { - self.0.biteq(other.0) - } -} - -impl core::fmt::Debug for BitEqWrapper<'_, T> { - fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { - self.0.fmt(f) - } -} - -macro_rules! assert_biteq { - { $a:expr, $b:expr } => { - { - use helpers::biteq::BitEqWrapper; - let a = $a; - let b = $b; - assert_eq!(BitEqWrapper(&a), BitEqWrapper(&b)); - } - } -} diff --git a/crates/core_simd/tests/helpers/mod.rs b/crates/core_simd/tests/helpers/mod.rs deleted file mode 100644 index 41b4fea9d95d..000000000000 --- a/crates/core_simd/tests/helpers/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -#[macro_use] -pub mod biteq; diff --git a/crates/core_simd/tests/mask_ops_impl/mod.rs b/crates/core_simd/tests/mask_ops_impl/mod.rs index 89f5e1b0b52a..99d735be2935 100644 --- a/crates/core_simd/tests/mask_ops_impl/mod.rs +++ b/crates/core_simd/tests/mask_ops_impl/mod.rs @@ -1,7 +1,3 @@ -#[macro_use] -#[path = "../helpers/mod.rs"] -mod helpers; - #[macro_use] mod mask_macros; diff --git a/crates/core_simd/tests/ops_macros.rs b/crates/core_simd/tests/ops_macros.rs index a4b26a1777af..58e80a8f277e 100644 --- a/crates/core_simd/tests/ops_macros.rs +++ b/crates/core_simd/tests/ops_macros.rs @@ -1,3 +1,6 @@ +/// Implements a test on a unary operation using proptest. +/// +/// Compares the vector operation to the equivalent scalar operation. #[macro_export] macro_rules! impl_unary_op_test { { $vector:ty, $scalar:ty, $trait:ident :: $fn:ident, $scalar_fn:expr } => { @@ -16,6 +19,9 @@ macro_rules! impl_unary_op_test { }; } +/// Implements a test on a binary operation using proptest. +/// +/// Compares the vector operation to the equivalent scalar operation. #[macro_export] macro_rules! impl_binary_op_test { { $vector:ty, $scalar:ty, $trait:ident :: $fn:ident, $trait_assign:ident :: $fn_assign:ident, $scalar_fn:expr } => { @@ -70,6 +76,12 @@ macro_rules! impl_binary_op_test { }; } +/// Implements a test on a binary operation using proptest. +/// +/// Like `impl_binary_op_test`, but allows providing a function for rejecting particular inputs +/// (like the `proptest_assume` macro). +/// +/// Compares the vector operation to the equivalent scalar operation. #[macro_export] macro_rules! impl_binary_checked_op_test { { $vector:ty, $scalar:ty, $trait:ident :: $fn:ident, $trait_assign:ident :: $fn_assign:ident, $scalar_fn:expr, $check_fn:expr } => { @@ -124,6 +136,7 @@ macro_rules! impl_binary_checked_op_test { }; } +/// Implement tests for signed integers. #[macro_export] macro_rules! impl_signed_tests { { $vector:ident, $scalar:tt } => { @@ -191,6 +204,8 @@ macro_rules! impl_signed_tests { impl_binary_op_test!(Vector, Scalar, Add::add, AddAssign::add_assign, Scalar::wrapping_add); impl_binary_op_test!(Vector, Scalar, Sub::sub, SubAssign::sub_assign, Scalar::wrapping_sub); impl_binary_op_test!(Vector, Scalar, Mul::mul, MulAssign::mul_assign, Scalar::wrapping_mul); + + // Exclude Div and Rem panicking cases impl_binary_checked_op_test!(Vector, Scalar, Div::div, DivAssign::div_assign, Scalar::wrapping_div, |x, y| y != 0 && !(x == Scalar::MIN && y == -1)); impl_binary_checked_op_test!(Vector, Scalar, Rem::rem, RemAssign::rem_assign, Scalar::wrapping_rem, |x, y| y != 0 && !(x == Scalar::MIN && y == -1)); @@ -202,6 +217,7 @@ macro_rules! impl_signed_tests { } } +/// Implement tests for unsigned integers. #[macro_export] macro_rules! impl_unsigned_tests { { $vector:ident, $scalar:tt } => { @@ -220,6 +236,8 @@ macro_rules! impl_unsigned_tests { impl_binary_op_test!(Vector, Scalar, Add::add, AddAssign::add_assign, Scalar::wrapping_add); impl_binary_op_test!(Vector, Scalar, Sub::sub, SubAssign::sub_assign, Scalar::wrapping_sub); impl_binary_op_test!(Vector, Scalar, Mul::mul, MulAssign::mul_assign, Scalar::wrapping_mul); + + // Exclude Div and Rem panicking cases impl_binary_checked_op_test!(Vector, Scalar, Div::div, DivAssign::div_assign, Scalar::wrapping_div, |_, y| y != 0); impl_binary_checked_op_test!(Vector, Scalar, Rem::rem, RemAssign::rem_assign, Scalar::wrapping_rem, |_, y| y != 0); @@ -231,6 +249,7 @@ macro_rules! impl_unsigned_tests { } } +/// Implement tests for floating point numbers. #[macro_export] macro_rules! impl_float_tests { { $vector:ident, $scalar:tt, $int_scalar:tt } => { diff --git a/crates/test_helpers/src/array.rs b/crates/test_helpers/src/array.rs index 3953d0bbea5e..c64bfee4f2d1 100644 --- a/crates/test_helpers/src/array.rs +++ b/crates/test_helpers/src/array.rs @@ -1,3 +1,5 @@ +//! Generic-length array strategy. + // Adapted from proptest's array code // Copyright 2017 Jason Lingle diff --git a/crates/test_helpers/src/biteq.rs b/crates/test_helpers/src/biteq.rs index 23aa7d4d908e..8c6280643803 100644 --- a/crates/test_helpers/src/biteq.rs +++ b/crates/test_helpers/src/biteq.rs @@ -1,3 +1,5 @@ +//! Compare numeric types by exact bit value. + pub trait BitEq { fn biteq(&self, other: &Self) -> bool; fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result; diff --git a/crates/test_helpers/src/lib.rs b/crates/test_helpers/src/lib.rs index 253435dea336..a81713e865b7 100644 --- a/crates/test_helpers/src/lib.rs +++ b/crates/test_helpers/src/lib.rs @@ -6,6 +6,9 @@ pub mod wasm; #[macro_use] pub mod biteq; +/// Specifies the default strategy for testing a type. +/// +/// This strategy should be what "makes sense" to test. pub trait DefaultStrategy { type Strategy: proptest::strategy::Strategy; fn default_strategy() -> Self::Strategy; @@ -74,6 +77,7 @@ impl DefaultStrategy } } +/// Test a function that takes a single value. pub fn test_1( f: &dyn Fn(A) -> proptest::test_runner::TestCaseResult, ) { @@ -81,6 +85,7 @@ pub fn test_1( runner.run(&A::default_strategy(), f).unwrap(); } +/// Test a function that takes two values. pub fn test_2( f: &dyn Fn(A, B) -> proptest::test_runner::TestCaseResult, ) { @@ -92,6 +97,7 @@ pub fn test_2( fv: &dyn Fn(Vector) -> VectorResult, @@ -118,6 +124,7 @@ pub fn test_unary_elementwise { pub(crate) mod $name { From 15dd0ae14f01bd6f12e2323c1cd36e1a5ed2b048 Mon Sep 17 00:00:00 2001 From: Caleb Zulawski Date: Sat, 13 Feb 2021 17:13:55 -0500 Subject: [PATCH 12/13] Disable CI on branches without PR --- .travis.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.travis.yml b/.travis.yml index c1fda2e4f170..a06fa62d50fd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,7 @@ +branches: + only: + - master + language: rust rust: - nightly From 2b3f4b258ce59285d8cd556ac8803eefd716ba49 Mon Sep 17 00:00:00 2001 From: Caleb Zulawski Date: Mon, 15 Feb 2021 18:38:35 -0500 Subject: [PATCH 13/13] Add LanesAtMost64 bounds --- crates/core_simd/src/macros.rs | 2 +- crates/test_helpers/src/lib.rs | 38 ++++++++++++++++++++++++++++++++-- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/crates/core_simd/src/macros.rs b/crates/core_simd/src/macros.rs index 75104dc50e45..db90c4e3149b 100644 --- a/crates/core_simd/src/macros.rs +++ b/crates/core_simd/src/macros.rs @@ -141,7 +141,7 @@ macro_rules! impl_vector { } } - impl From<$name> for [$type; LANES] { + impl From<$name> for [$type; LANES] where $name: crate::LanesAtMost64 { fn from(vector: $name) -> Self { vector.to_array() } diff --git a/crates/test_helpers/src/lib.rs b/crates/test_helpers/src/lib.rs index a81713e865b7..2c74c02d48a0 100644 --- a/crates/test_helpers/src/lib.rs +++ b/crates/test_helpers/src/lib.rs @@ -241,7 +241,24 @@ macro_rules! test_lanes { mod $test { use super::*; - fn implementation() $body + fn implementation() + where + core_simd::SimdU8<$lanes>: core_simd::LanesAtMost64, + core_simd::SimdU16<$lanes>: core_simd::LanesAtMost64, + core_simd::SimdU32<$lanes>: core_simd::LanesAtMost64, + core_simd::SimdU64<$lanes>: core_simd::LanesAtMost64, + core_simd::SimdU128<$lanes>: core_simd::LanesAtMost64, + core_simd::SimdUsize<$lanes>: core_simd::LanesAtMost64, + core_simd::SimdI8<$lanes>: core_simd::LanesAtMost64, + core_simd::SimdI16<$lanes>: core_simd::LanesAtMost64, + core_simd::SimdI32<$lanes>: core_simd::LanesAtMost64, + core_simd::SimdI64<$lanes>: core_simd::LanesAtMost64, + core_simd::SimdI128<$lanes>: core_simd::LanesAtMost64, + core_simd::SimdIsize<$lanes>: core_simd::LanesAtMost64, + core_simd::SimdF32<$lanes>: core_simd::LanesAtMost64, + core_simd::SimdF64<$lanes>: core_simd::LanesAtMost64, + core_simd::BitMask<$lanes>: core_simd::LanesAtMost64, + $body #[cfg(target_arch = "wasm32")] wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser); @@ -302,7 +319,24 @@ macro_rules! test_lanes_panic { mod $test { use super::*; - fn implementation() $body + fn implementation() + where + core_simd::SimdU8<$lanes>: core_simd::LanesAtMost64, + core_simd::SimdU16<$lanes>: core_simd::LanesAtMost64, + core_simd::SimdU32<$lanes>: core_simd::LanesAtMost64, + core_simd::SimdU64<$lanes>: core_simd::LanesAtMost64, + core_simd::SimdU128<$lanes>: core_simd::LanesAtMost64, + core_simd::SimdUsize<$lanes>: core_simd::LanesAtMost64, + core_simd::SimdI8<$lanes>: core_simd::LanesAtMost64, + core_simd::SimdI16<$lanes>: core_simd::LanesAtMost64, + core_simd::SimdI32<$lanes>: core_simd::LanesAtMost64, + core_simd::SimdI64<$lanes>: core_simd::LanesAtMost64, + core_simd::SimdI128<$lanes>: core_simd::LanesAtMost64, + core_simd::SimdIsize<$lanes>: core_simd::LanesAtMost64, + core_simd::SimdF32<$lanes>: core_simd::LanesAtMost64, + core_simd::SimdF64<$lanes>: core_simd::LanesAtMost64, + core_simd::BitMask<$lanes>: core_simd::LanesAtMost64, + $body #[test] #[should_panic]