From 78a8d615b51195c9154f95afdd5f870857ae512b Mon Sep 17 00:00:00 2001 From: Caleb Zulawski Date: Sun, 22 Nov 2020 15:18:31 -0500 Subject: [PATCH] Implement missing traits on opaque masks, fix tests --- crates/core_simd/src/masks/mod.rs | 130 ++++++++++++++++++ crates/core_simd/tests/helpers/biteq.rs | 19 ++- crates/core_simd/tests/ops_impl/mask128.rs | 6 +- crates/core_simd/tests/ops_impl/mask16.rs | 10 +- crates/core_simd/tests/ops_impl/mask32.rs | 10 +- crates/core_simd/tests/ops_impl/mask64.rs | 8 +- crates/core_simd/tests/ops_impl/mask8.rs | 10 +- .../core_simd/tests/ops_impl/mask_macros.rs | 118 +++++++++------- crates/core_simd/tests/ops_impl/masksize.rs | 8 +- 9 files changed, 233 insertions(+), 86 deletions(-) diff --git a/crates/core_simd/src/masks/mod.rs b/crates/core_simd/src/masks/mod.rs index 6688db290e2..676a5560d2f 100644 --- a/crates/core_simd/src/masks/mod.rs +++ b/crates/core_simd/src/masks/mod.rs @@ -158,6 +158,136 @@ macro_rules! define_opaque_mask { self.0.partial_cmp(&other.0) } } + + impl core::fmt::Debug for $name { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + f.debug_list() + .entries((0..$lanes).map(|i| self.test(i))) + .finish() + } + } + + impl core::ops::BitAnd for $name { + type Output = Self; + #[inline] + fn bitand(self, rhs: Self) -> Self { + Self(self.0 & rhs.0) + } + } + + impl core::ops::BitAnd for $name { + type Output = Self; + #[inline] + fn bitand(self, rhs: bool) -> Self { + self & Self::splat(rhs) + } + } + + impl core::ops::BitAnd<$name> for bool { + type Output = $name; + #[inline] + fn bitand(self, rhs: $name) -> $name { + $name::splat(self) & rhs + } + } + + impl core::ops::BitOr for $name { + type Output = Self; + #[inline] + fn bitor(self, rhs: Self) -> Self { + Self(self.0 | rhs.0) + } + } + + impl core::ops::BitOr for $name { + type Output = Self; + #[inline] + fn bitor(self, rhs: bool) -> Self { + self | Self::splat(rhs) + } + } + + impl core::ops::BitOr<$name> for bool { + type Output = $name; + #[inline] + fn bitor(self, rhs: $name) -> $name { + $name::splat(self) | rhs + } + } + + impl core::ops::BitXor for $name { + type Output = Self; + #[inline] + fn bitxor(self, rhs: Self) -> Self::Output { + Self(self.0 ^ rhs.0) + } + } + + impl core::ops::BitXor for $name { + type Output = Self; + #[inline] + fn bitxor(self, rhs: bool) -> Self::Output { + self ^ Self::splat(rhs) + } + } + + impl core::ops::BitXor<$name> for bool { + type Output = $name; + #[inline] + fn bitxor(self, rhs: $name) -> Self::Output { + $name::splat(self) ^ rhs + } + } + + impl core::ops::Not for $name { + type Output = $name; + #[inline] + fn not(self) -> Self::Output { + Self(!self.0) + } + } + + impl core::ops::BitAndAssign for $name { + #[inline] + fn bitand_assign(&mut self, rhs: Self) { + self.0 &= rhs.0; + } + } + + impl core::ops::BitAndAssign for $name { + #[inline] + fn bitand_assign(&mut self, rhs: bool) { + *self &= Self::splat(rhs); + } + } + + impl core::ops::BitOrAssign for $name { + #[inline] + fn bitor_assign(&mut self, rhs: Self) { + self.0 |= rhs.0; + } + } + + impl core::ops::BitOrAssign for $name { + #[inline] + fn bitor_assign(&mut self, rhs: bool) { + *self |= Self::splat(rhs); + } + } + + impl core::ops::BitXorAssign for $name { + #[inline] + fn bitxor_assign(&mut self, rhs: Self) { + self.0 ^= rhs.0; + } + } + + impl core::ops::BitXorAssign for $name { + #[inline] + fn bitxor_assign(&mut self, rhs: bool) { + *self ^= Self::splat(rhs); + } + } }; { new [$width:ty; $lanes:tt] $($var:ident)* } => { /// Construct a vector by setting each lane to the given values. diff --git a/crates/core_simd/tests/helpers/biteq.rs b/crates/core_simd/tests/helpers/biteq.rs index f932eba907c..00fc31f3d05 100644 --- a/crates/core_simd/tests/helpers/biteq.rs +++ b/crates/core_simd/tests/helpers/biteq.rs @@ -70,7 +70,12 @@ impl_biteq! { integer impl BitEq for u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize, - core_simd::mask8, core_simd::mask16, core_simd::mask32, core_simd::mask64, core_simd::mask128, core_simd::masksize, + core_simd::masks::wide::m8, + core_simd::masks::wide::m16, + core_simd::masks::wide::m32, + core_simd::masks::wide::m64, + core_simd::masks::wide::m128, + core_simd::masks::wide::msize, } impl_biteq! { @@ -93,12 +98,12 @@ impl_biteq! { 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, - core_simd::mask8x8, core_simd::mask8x16, core_simd::mask8x32, core_simd::mask8x64, - core_simd::mask16x4, core_simd::mask16x8, core_simd::mask16x16, core_simd::mask16x32, - core_simd::mask32x2, core_simd::mask32x4, core_simd::mask32x8, core_simd::mask32x16, - core_simd::mask64x2, core_simd::mask64x4, core_simd::mask64x8, - core_simd::mask128x2, core_simd::mask128x4, - core_simd::masksizex2, core_simd::masksizex4, core_simd::masksizex8, + core_simd::masks::wide::m8x8, core_simd::masks::wide::m8x16, core_simd::masks::wide::m8x32, core_simd::masks::wide::m8x64, + core_simd::masks::wide::m16x4, core_simd::masks::wide::m16x8, core_simd::masks::wide::m16x16, core_simd::masks::wide::m16x32, + core_simd::masks::wide::m32x2, core_simd::masks::wide::m32x4, core_simd::masks::wide::m32x8, core_simd::masks::wide::m32x16, + core_simd::masks::wide::m64x2, core_simd::masks::wide::m64x4, core_simd::masks::wide::m64x8, + core_simd::masks::wide::m128x2, core_simd::masks::wide::m128x4, + core_simd::masks::wide::msizex2, core_simd::masks::wide::msizex4, core_simd::masks::wide::msizex8, } pub(crate) struct BitEqWrapper<'a, T>(pub(crate) &'a T); diff --git a/crates/core_simd/tests/ops_impl/mask128.rs b/crates/core_simd/tests/ops_impl/mask128.rs index f0bcdb4d4df..27ba4e2d29f 100644 --- a/crates/core_simd/tests/ops_impl/mask128.rs +++ b/crates/core_simd/tests/ops_impl/mask128.rs @@ -1,4 +1,2 @@ -use super::helpers; - -mask_tests! { mask128x2, mask128 } -mask_tests! { mask128x4, mask128 } +mask_tests! { mask128x2, 2 } +mask_tests! { mask128x4, 4 } diff --git a/crates/core_simd/tests/ops_impl/mask16.rs b/crates/core_simd/tests/ops_impl/mask16.rs index 6f3f8e0ee02..0fe82fa6804 100644 --- a/crates/core_simd/tests/ops_impl/mask16.rs +++ b/crates/core_simd/tests/ops_impl/mask16.rs @@ -1,6 +1,4 @@ -use super::helpers; - -mask_tests! { mask16x4, mask16 } -mask_tests! { mask16x8, mask16 } -mask_tests! { mask16x16, mask16 } -mask_tests! { mask16x32, mask16 } +mask_tests! { mask16x4, 4 } +mask_tests! { mask16x8, 8 } +mask_tests! { mask16x16, 16 } +mask_tests! { mask16x32, 32 } diff --git a/crates/core_simd/tests/ops_impl/mask32.rs b/crates/core_simd/tests/ops_impl/mask32.rs index 5c35885a2f5..66d987a43ce 100644 --- a/crates/core_simd/tests/ops_impl/mask32.rs +++ b/crates/core_simd/tests/ops_impl/mask32.rs @@ -1,6 +1,4 @@ -use super::helpers; - -mask_tests! { mask32x2, mask32 } -mask_tests! { mask32x4, mask32 } -mask_tests! { mask32x8, mask32 } -mask_tests! { mask32x16, mask32 } +mask_tests! { mask32x2, 2 } +mask_tests! { mask32x4, 4 } +mask_tests! { mask32x8, 8 } +mask_tests! { mask32x16, 16 } diff --git a/crates/core_simd/tests/ops_impl/mask64.rs b/crates/core_simd/tests/ops_impl/mask64.rs index 88d3211465c..a1f1f67b238 100644 --- a/crates/core_simd/tests/ops_impl/mask64.rs +++ b/crates/core_simd/tests/ops_impl/mask64.rs @@ -1,5 +1,3 @@ -use super::helpers; - -mask_tests! { mask64x2, mask64 } -mask_tests! { mask64x4, mask64 } -mask_tests! { mask64x8, mask64 } +mask_tests! { mask64x2, 2 } +mask_tests! { mask64x4, 4 } +mask_tests! { mask64x8, 8 } diff --git a/crates/core_simd/tests/ops_impl/mask8.rs b/crates/core_simd/tests/ops_impl/mask8.rs index fa4bcf09f36..218fa9fe895 100644 --- a/crates/core_simd/tests/ops_impl/mask8.rs +++ b/crates/core_simd/tests/ops_impl/mask8.rs @@ -1,6 +1,4 @@ -use super::helpers; - -mask_tests! { mask8x8, mask8 } -mask_tests! { mask8x16, mask8 } -mask_tests! { mask8x32, mask8 } -mask_tests! { mask8x64, mask8 } +mask_tests! { mask8x8, 8 } +mask_tests! { mask8x16, 16 } +mask_tests! { mask8x32, 32 } +mask_tests! { mask8x64, 64 } diff --git a/crates/core_simd/tests/ops_impl/mask_macros.rs b/crates/core_simd/tests/ops_impl/mask_macros.rs index e6aee4c1d30..795f9e27c44 100644 --- a/crates/core_simd/tests/ops_impl/mask_macros.rs +++ b/crates/core_simd/tests/ops_impl/mask_macros.rs @@ -1,9 +1,9 @@ macro_rules! mask_tests { - { $vector:ident, $scalar:ident } => { + { $vector:ident, $lanes:literal } => { #[cfg(test)] mod $vector { - use super::*; - use helpers::lanewise::*; + use core_simd::$vector as Vector; + const LANES: usize = $lanes; #[cfg(target_arch = "wasm32")] use wasm_bindgen_test::*; @@ -11,15 +11,44 @@ macro_rules! mask_tests { #[cfg(target_arch = "wasm32")] wasm_bindgen_test_configure!(run_in_browser); - fn from_slice(slice: &[bool]) -> core_simd::$vector { - let mut value = core_simd::$vector::default(); - let value_slice: &mut [_] = value.as_mut(); - for (m, b) in value_slice.iter_mut().zip(slice.iter()) { - *m = (*b).into(); + fn from_slice(slice: &[bool]) -> Vector { + let mut value = Vector::default(); + for (i, b) in slice.iter().take(LANES).enumerate() { + value.set(i, *b); } value } + fn apply_unary_lanewise(x: Vector, f: impl Fn(bool) -> bool) -> Vector { + let mut value = Vector::default(); + for i in 0..LANES { + value.set(i, f(x.test(i))); + } + value + } + + fn apply_binary_lanewise(x: Vector, y: Vector, f: impl Fn(bool, bool) -> bool) -> Vector { + let mut value = Vector::default(); + for i in 0..LANES { + value.set(i, f(x.test(i), y.test(i))); + } + value + } + + fn apply_binary_scalar_lhs_lanewise(x: bool, mut y: Vector, f: impl Fn(bool, bool) -> bool) -> Vector { + for i in 0..LANES { + y.set(i, f(x, y.test(i))); + } + y + } + + fn apply_binary_scalar_rhs_lanewise(mut x: Vector, y: bool, f: impl Fn(bool, bool) -> bool) -> Vector { + for i in 0..LANES { + x.set(i, f(x.test(i), y)); + } + x + } + const A: [bool; 64] = [ false, true, false, true, false, false, true, true, false, true, false, true, false, false, true, true, @@ -41,18 +70,13 @@ macro_rules! mask_tests { false, false, true, true, false, true, false, true, ]; - const SET_SCALAR: core_simd::$scalar = core_simd::$scalar::new(true); - const UNSET_SCALAR: core_simd::$scalar = core_simd::$scalar::new(false); - const SET_VECTOR: core_simd::$vector = core_simd::$vector::splat(SET_SCALAR); - const UNSET_VECTOR: core_simd::$vector = core_simd::$vector::splat(UNSET_SCALAR); - #[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); + assert_eq!(a & b, expected); } #[test] @@ -62,7 +86,7 @@ macro_rules! mask_tests { let b = from_slice(&B); let expected = apply_binary_lanewise(a, b, core::ops::BitAnd::bitand); a &= b; - assert_biteq!(a, expected); + assert_eq!(a, expected); } #[test] @@ -70,8 +94,8 @@ macro_rules! mask_tests { fn bitand_scalar_rhs() { let a = from_slice(&A); let expected = a; - assert_biteq!(a & SET_SCALAR, expected); - assert_biteq!(a & UNSET_SCALAR, UNSET_VECTOR); + assert_eq!(a & true, expected); + assert_eq!(a & false, Vector::splat(false)); } #[test] @@ -79,8 +103,8 @@ macro_rules! mask_tests { fn bitand_scalar_lhs() { let a = from_slice(&A); let expected = a; - assert_biteq!(SET_SCALAR & a, expected); - assert_biteq!(UNSET_SCALAR & a, UNSET_VECTOR); + assert_eq!(true & a, expected); + assert_eq!(false & a, Vector::splat(false)); } #[test] @@ -88,10 +112,10 @@ macro_rules! mask_tests { fn bitand_assign_scalar() { let mut a = from_slice(&A); let expected = a; - a &= SET_SCALAR; - assert_biteq!(a, expected); - a &= UNSET_SCALAR; - assert_biteq!(a, UNSET_VECTOR); + a &= true; + assert_eq!(a, expected); + a &= false; + assert_eq!(a, Vector::splat(false)); } #[test] @@ -100,7 +124,7 @@ macro_rules! mask_tests { 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); + assert_eq!(a | b, expected); } #[test] @@ -110,23 +134,23 @@ macro_rules! mask_tests { let b = from_slice(&B); let expected = apply_binary_lanewise(a, b, core::ops::BitOr::bitor); a |= b; - assert_biteq!(a, expected); + assert_eq!(a, expected); } #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn bitor_scalar_rhs() { let a = from_slice(&A); - assert_biteq!(a | UNSET_SCALAR, a); - assert_biteq!(a | SET_SCALAR, SET_VECTOR); + assert_eq!(a | false, a); + assert_eq!(a | true, Vector::splat(true)); } #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn bitor_scalar_lhs() { let a = from_slice(&A); - assert_biteq!(UNSET_SCALAR | a, a); - assert_biteq!(SET_SCALAR | a, SET_VECTOR); + assert_eq!(false | a, a); + assert_eq!(true | a, Vector::splat(true)); } #[test] @@ -134,10 +158,10 @@ macro_rules! mask_tests { fn bitor_assign_scalar() { let mut a = from_slice(&A); let expected = a; - a |= UNSET_SCALAR; - assert_biteq!(a, expected); - a |= SET_SCALAR; - assert_biteq!(a, SET_VECTOR); + a |= false; + assert_eq!(a, expected); + a |= true; + assert_eq!(a, Vector::splat(true)); } #[test] @@ -146,7 +170,7 @@ macro_rules! mask_tests { 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); + assert_eq!(a ^ b, expected); } #[test] @@ -156,25 +180,25 @@ macro_rules! mask_tests { let b = from_slice(&B); let expected = apply_binary_lanewise(a, b, core::ops::BitXor::bitxor); a ^= b; - assert_biteq!(a, expected); + assert_eq!(a, expected); } #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn bitxor_scalar_rhs() { let a = from_slice(&A); - let expected = apply_binary_scalar_rhs_lanewise(a, SET_SCALAR, core::ops::BitXor::bitxor); - assert_biteq!(a ^ UNSET_SCALAR, a); - assert_biteq!(a ^ SET_SCALAR, expected); + let expected = apply_binary_scalar_rhs_lanewise(a, true, core::ops::BitXor::bitxor); + assert_eq!(a ^ false, a); + assert_eq!(a ^ true, expected); } #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn bitxor_scalar_lhs() { let a = from_slice(&A); - let expected = apply_binary_scalar_lhs_lanewise(SET_SCALAR, a, core::ops::BitXor::bitxor); - assert_biteq!(UNSET_SCALAR ^ a, a); - assert_biteq!(SET_SCALAR ^ a, expected); + let expected = apply_binary_scalar_lhs_lanewise(true, a, core::ops::BitXor::bitxor); + assert_eq!(false ^ a, a); + assert_eq!(true ^ a, expected); } #[test] @@ -182,11 +206,11 @@ macro_rules! mask_tests { fn bitxor_assign_scalar() { let mut a = from_slice(&A); let expected_unset = a; - let expected_set = apply_binary_scalar_rhs_lanewise(a, SET_SCALAR, core::ops::BitXor::bitxor); - a ^= UNSET_SCALAR; - assert_biteq!(a, expected_unset); - a ^= SET_SCALAR; - assert_biteq!(a, expected_set); + let expected_set = apply_binary_scalar_rhs_lanewise(a, true, core::ops::BitXor::bitxor); + a ^= false; + assert_eq!(a, expected_unset); + a ^= true; + assert_eq!(a, expected_set); } #[test] @@ -194,7 +218,7 @@ macro_rules! mask_tests { fn not() { let v = from_slice(&A); let expected = apply_unary_lanewise(v, core::ops::Not::not); - assert_biteq!(!v, expected); + assert_eq!(!v, expected); } } } diff --git a/crates/core_simd/tests/ops_impl/masksize.rs b/crates/core_simd/tests/ops_impl/masksize.rs index 76e333f3c15..e0a44d870ca 100644 --- a/crates/core_simd/tests/ops_impl/masksize.rs +++ b/crates/core_simd/tests/ops_impl/masksize.rs @@ -1,5 +1,3 @@ -use super::helpers; - -mask_tests! { masksizex2, masksize } -mask_tests! { masksizex4, masksize } -mask_tests! { masksizex8, masksize } +mask_tests! { masksizex2, 2 } +mask_tests! { masksizex4, 4 } +mask_tests! { masksizex8, 8 }