From b839939af794fa00d9170f9523d00b382e14b2c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Crozet?= Date: Sat, 22 Jun 2024 16:41:28 +0200 Subject: [PATCH] feat: add ZERO and ONE consts, and Default impl to simd types (#61) --- CHANGELOG | 2 ++ src/simd/auto_simd_impl.rs | 28 ++++++++++++++++++++-------- src/simd/portable_simd_impl.rs | 5 ++++- src/simd/wide_simd_impl.rs | 15 +++++++++------ 4 files changed, 35 insertions(+), 15 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index c43349d..f2631a6 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -8,6 +8,8 @@ - The `ComplexField` and `SimdComplexField` (and, by extension, `RealField` and `SimdRealField`) traits now depend on the `SupersetOf` trait in addition to `SupersetOf`. - Replace the `SimdValue::lanes()` function by an associated constant `SimdValue::LANES`. +- Add `ZERO` and `ONE` associated consts to all the simd newtypes. +- Implement `Default` for all simd newtypes. ## Release v0.8.1 (04 Apr. 2023) - Add implementation of `rkyv` serialization/deserialization to the `Wide*` wrapper types. diff --git a/src/simd/auto_simd_impl.rs b/src/simd/auto_simd_impl.rs index 1da962f..9a48ce8 100644 --- a/src/simd/auto_simd_impl.rs +++ b/src/simd/auto_simd_impl.rs @@ -40,7 +40,7 @@ macro_rules! ident_to_value ( /// /// This is needed to overcome the orphan rules. #[repr(align(16))] -#[derive(Copy, Clone, PartialEq, Eq, Debug)] +#[derive(Copy, Clone, PartialEq, Eq, Debug, Default)] #[cfg_attr( feature = "rkyv", derive(rkyv::Archive, rkyv::Deserialize, rkyv::Serialize), @@ -64,6 +64,15 @@ macro_rules! impl_bool_simd ( ($($t: ty, $lanes: expr, $($i: ident),*;)*) => {$( impl_simd_value!($t, bool, $lanes, AutoSimd<$t> $(, $i)*;); + impl AutoSimd<$t> { + pub const ZERO: Self = AutoSimd([false; $lanes]); + pub const ONE: Self = AutoSimd([true; $lanes]); + + pub fn new($($i: bool),*) -> Self { + AutoSimd([$($i),*]) + } + } + impl From<[bool; $lanes]> for AutoSimd<$t> { #[inline(always)] fn from(vals: [bool; $lanes]) -> Self { @@ -280,12 +289,6 @@ macro_rules! impl_simd_value ( } } - impl AutoSimd<$t> { - pub fn new($($i: $elt),*) -> Self { - AutoSimd([$($i),*]) - } - } - impl PrimitiveSimdValue for AutoSimd<$t> {} impl SimdValue for AutoSimd<$t> { @@ -334,6 +337,15 @@ macro_rules! impl_uint_simd ( ($($t: ty, $elt: ty, $lanes: expr, $bool: ty, $($i: ident),*;)*) => ($( impl_simd_value!($t, $elt, $lanes, $bool $(, $i)*;); + impl AutoSimd<$t> { + pub const ZERO: Self = AutoSimd([0 as $elt; $lanes]); + pub const ONE: Self = AutoSimd([1 as $elt; $lanes]); + + pub fn new($($i: $elt),*) -> Self { + AutoSimd([$($i),*]) + } + } + impl From<[$elt; $lanes]> for AutoSimd<$t> { #[inline(always)] fn from(vals: [$elt; $lanes]) -> Self { @@ -1534,7 +1546,7 @@ impl_bool_simd!( [bool; 8], 8, _0, _1, _2, _3, _4, _5, _6, _7; [bool; 16], 16, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15; [bool; 32], 32, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31; - // [bool; 64], 64, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63; + // [bool; 64], 64, 0, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63; ); // diff --git a/src/simd/portable_simd_impl.rs b/src/simd/portable_simd_impl.rs index 8e73da7..766fd20 100644 --- a/src/simd/portable_simd_impl.rs +++ b/src/simd/portable_simd_impl.rs @@ -45,7 +45,7 @@ macro_rules! ident_to_value ( /// /// This is needed to overcome the orphan rules. #[repr(transparent)] -#[derive(Copy, Clone, PartialEq, Eq, Debug)] +#[derive(Copy, Clone, PartialEq, Eq, Debug, Default)] pub struct Simd(pub N); macro_rules! impl_bool_simd ( @@ -288,6 +288,9 @@ macro_rules! impl_simd_value ( } impl Simd<$t> { + pub const ZERO: Self = Simd(<$t>::from_array([0 as $elt; <$t>::LEN])); + pub const ONE: Self = Simd(<$t>::from_array([1 as $elt; <$t>::LEN])); + #[inline] pub fn new($($i: $elt),*) -> Self { Simd(<$t>::from_array([$($i),*])) diff --git a/src/simd/wide_simd_impl.rs b/src/simd/wide_simd_impl.rs index 427a0c4..ead5e24 100644 --- a/src/simd/wide_simd_impl.rs +++ b/src/simd/wide_simd_impl.rs @@ -53,7 +53,7 @@ macro_rules! impl_rkyv { /// /// This is needed to overcome the orphan rules. #[repr(transparent)] -#[derive(Copy, Clone, Debug)] +#[derive(Copy, Clone, Debug, Default)] pub struct WideF32x4(pub wide::f32x4); #[cfg(feature = "rkyv")] @@ -63,7 +63,7 @@ impl_rkyv!(WideF32x4, [f32; 4]); /// /// This is needed to overcome the orphan rules. #[repr(transparent)] -#[derive(Copy, Clone, Debug)] +#[derive(Copy, Clone, Debug, Default)] pub struct WideBoolF32x4(pub wide::f32x4); #[cfg(feature = "rkyv")] @@ -73,7 +73,7 @@ impl_rkyv!(WideBoolF32x4, [f32; 4]); /// /// This is needed to overcome the orphan rules. #[repr(transparent)] -#[derive(Copy, Clone, Debug)] +#[derive(Copy, Clone, Debug, Default)] pub struct WideF32x8(pub wide::f32x8); #[cfg(feature = "rkyv")] @@ -83,7 +83,7 @@ impl_rkyv!(WideF32x8, [f32; 8]); /// /// This is needed to overcome the orphan rules. #[repr(transparent)] -#[derive(Copy, Clone, Debug)] +#[derive(Copy, Clone, Debug, Default)] pub struct WideBoolF32x8(pub wide::f32x8); #[cfg(feature = "rkyv")] @@ -93,7 +93,7 @@ impl_rkyv!(WideBoolF32x8, [f32; 8]); /// /// This is needed to overcome the orphan rules. #[repr(transparent)] -#[derive(Copy, Clone, Debug)] +#[derive(Copy, Clone, Debug, Default)] pub struct WideF64x4(pub wide::f64x4); #[cfg(feature = "rkyv")] @@ -103,7 +103,7 @@ impl_rkyv!(WideF64x4, [f64; 4]); /// /// This is needed to overcome the orphan rules. #[repr(transparent)] -#[derive(Copy, Clone, Debug)] +#[derive(Copy, Clone, Debug, Default)] pub struct WideBoolF64x4(pub wide::f64x4); #[cfg(feature = "rkyv")] @@ -115,6 +115,9 @@ macro_rules! impl_wide_f32 ( impl PrimitiveSimdValue for $WideBoolF32xX {} impl $WideF32xX { + pub const ZERO: Self = $WideF32xX(::ZERO); + pub const ONE: Self = $WideF32xX(::ONE); + #[inline(always)] fn into_arr(self) -> [$f32; $lanes] { self.0.into()