Skip to content

Commit

Permalink
feat: replace the SimdValue::lanes() function by an associated const …
Browse files Browse the repository at this point in the history
…SimdValue::LANES
  • Loading branch information
sebcrozet committed Jun 22, 2024
1 parent 32543cd commit 9acef5d
Show file tree
Hide file tree
Showing 6 changed files with 31 additions and 60 deletions.
1 change: 1 addition & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
traits named `ClosedAddAssign, ClosedMulAssign, etc.`
- The `ComplexField` and `SimdComplexField` (and, by extension, `RealField` and `SimdRealField`) traits now depend on the
`SupersetOf<f32>` trait in addition to `SupersetOf<f64>`.
- Replace the `SimdValue::lanes()` function by an associated constant `SimdValue::LANES`.

## Release v0.8.1 (04 Apr. 2023)
- Add implementation of `rkyv` serialization/deserialization to the `Wide*` wrapper types.
Expand Down
6 changes: 1 addition & 5 deletions src/scalar/fixed_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,14 +95,10 @@ macro_rules! impl_fixed_type (

impl<Fract: $LeEqDim> PrimitiveSimdValue for $FixedI<Fract> {}
impl<Fract: $LeEqDim> SimdValue for $FixedI<Fract> {
const LANES: usize = 1;
type Element = Self;
type SimdBool = bool;

#[inline(always)]
fn lanes() -> usize {
1
}

#[inline(always)]
fn splat(val: Self::Element) -> Self {
val
Expand Down
12 changes: 5 additions & 7 deletions src/simd/auto_simd_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ macro_rules! impl_scalar_subset_of_simd (
fn is_in_subset(c: &AutoSimd<N2>) -> bool {
let elt0 = c.extract(0);
elt0.is_in_subset() &&
(1..AutoSimd::<N2>::lanes()).all(|i| c.extract(i) == elt0)
(1..AutoSimd::<N2>::LANES).all(|i| c.extract(i) == elt0)
}
}
)*}
Expand Down Expand Up @@ -265,13 +265,14 @@ macro_rules! impl_simd_value (

impl fmt::Display for AutoSimd<$t> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if Self::lanes() == 1 {
if Self::LANES == 1 {
return self.extract(0).fmt(f);
}

write!(f, "({}", self.extract(0))?;

for i in 1..Self::lanes() {
#[allow(clippy::reversed_empty_ranges)] // Needed for LANES == 1 that’s in a different code path.
for i in 1..Self::LANES {
write!(f, ", {}", self.extract(i))?;
}

Expand All @@ -288,13 +289,10 @@ macro_rules! impl_simd_value (
impl PrimitiveSimdValue for AutoSimd<$t> {}

impl SimdValue for AutoSimd<$t> {
const LANES: usize = $lanes;
type Element = $elt;
type SimdBool = $bool;

#[inline(always)]
fn lanes() -> usize {
$lanes
}

#[inline(always)]
fn splat(val: Self::Element) -> Self {
Expand Down
30 changes: 11 additions & 19 deletions src/simd/portable_simd_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,13 @@ macro_rules! impl_bool_simd (
($($t: ty, $lanes: literal, $($i: ident),*;)*) => {$(
impl fmt::Display for Simd<$t> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if Self::lanes() == 1 {
if Self::LANES == 1 {
return self.extract(0).fmt(f);
}

write!(f, "({}", self.extract(0))?;

for i in 1..Self::lanes() {
for i in 1..Self::LANES {
write!(f, ", {}", self.extract(i))?;
}

Expand All @@ -76,14 +76,10 @@ macro_rules! impl_bool_simd (
impl PrimitiveSimdValue for Simd<$t> {}

impl SimdValue for Simd<$t> {
const LANES: usize = $lanes;
type Element = bool;
type SimdBool = Simd<$t>;

#[inline(always)]
fn lanes() -> usize {
$lanes
}

#[inline(always)]
fn splat(val: Self::Element) -> Self {
Simd(<$t>::splat(val))
Expand Down Expand Up @@ -263,7 +259,7 @@ macro_rules! impl_scalar_subset_of_simd (
fn is_in_subset(c: &Simd<N2>) -> bool {
let elt0 = c.extract(0);
elt0.is_in_subset() &&
(1..Simd::<N2>::lanes()).all(|i| c.extract(i) == elt0)
(1..Simd::<N2>::LANES).all(|i| c.extract(i) == elt0)
}
}
)*}
Expand All @@ -277,13 +273,13 @@ macro_rules! impl_simd_value (
($($t: ty, $elt: ty, $bool: ty, $($i: ident),*;)*) => ($(
impl fmt::Display for Simd<$t> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if Self::lanes() == 1 {
if Self::LANES == 1 {
return self.extract(0).fmt(f);
}

write!(f, "({}", self.extract(0))?;

for i in 1..Self::lanes() {
for i in 1..Self::LANES {
write!(f, ", {}", self.extract(i))?;
}

Expand All @@ -301,14 +297,10 @@ macro_rules! impl_simd_value (
impl PrimitiveSimdValue for Simd<$t> {}

impl SimdValue for Simd<$t> {
const LANES: usize = <$t>::LEN;
type Element = $elt;
type SimdBool = $bool;

#[inline(always)]
fn lanes() -> usize {
<$t>::LEN
}

#[inline(always)]
fn splat(val: Self::Element) -> Self {
Simd(<$t>::splat(val))
Expand Down Expand Up @@ -351,7 +343,7 @@ macro_rules! impl_uint_simd (
///
/// # Panics
///
/// If `slice.len() < Self::lanes()`.
/// If `slice.len() < Self::LANES`.
#[inline]
pub fn from_slice_unaligned(slice: &[$elt]) -> Self {
Simd(<$t>::from_slice(slice))
Expand Down Expand Up @@ -1075,7 +1067,7 @@ macro_rules! impl_float_simd (
#[inline(always)]
fn simd_horizontal_product(self) -> Self::Element {
let mut prod = self.extract(0);
for ii in 1..Self::lanes() {
for ii in 1..Self::LANES {
prod *= self.extract(ii)
}
prod
Expand Down Expand Up @@ -1589,9 +1581,9 @@ impl_bool_simd!(
//
//macro_rules! impl_simd_complex_from(
// ($($t: ty, $elt: ty $(, $i: expr)*;)*) => ($(
// impl From<[num_complex::Complex<$elt>; <$t>::lanes()]> for num_complex::Complex<Simd<$t>> {
// impl From<[num_complex::Complex<$elt>; <$t>::LANES]> for num_complex::Complex<Simd<$t>> {
// #[inline(always)]
// fn from(vals: [num_complex::Complex<$elt>; <$t>::lanes()]) -> Self {
// fn from(vals: [num_complex::Complex<$elt>; <$t>::LANES]) -> Self {
// num_complex::Complex {
// re: <$t>::from([$(vals[$i].re),*]),
// im: <$t>::from([$(vals[$i].im),*]),
Expand Down
28 changes: 10 additions & 18 deletions src/simd/simd_value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,32 @@ use crate::simd::SimdBool;

/// Base trait for every SIMD types.
pub trait SimdValue: Sized {
/// The number of lanes of this SIMD value.
const LANES: usize;
/// The type of the elements of each lane of this SIMD value.
type Element: SimdValue<Element = Self::Element, SimdBool = bool>;
/// Type of the result of comparing two SIMD values like `self`.
type SimdBool: SimdBool;

/// The number of lanes of this SIMD value.
fn lanes() -> usize;
/// Initializes an SIMD value with each lanes set to `val`.
fn splat(val: Self::Element) -> Self;
/// Extracts the i-th lane of `self`.
///
/// Panics if `i >= Self::lanes()`.
/// Panics if `i >= Self::LANES`.
fn extract(&self, i: usize) -> Self::Element;
/// Extracts the i-th lane of `self` without bound-checking.
///
/// # Safety
/// Undefined behavior if `i >= Self::lanes()`.
/// Undefined behavior if `i >= Self::LANES`.
unsafe fn extract_unchecked(&self, i: usize) -> Self::Element;
/// Replaces the i-th lane of `self` by `val`.
///
/// Panics if `i >= Self::lanes()`.
/// Panics if `i >= Self::LANES`.
fn replace(&mut self, i: usize, val: Self::Element);
/// Replaces the i-th lane of `self` by `val` without bound-checking.
///
/// # Safety
/// Undefined behavior if `i >= Self::lanes()`.
/// Undefined behavior if `i >= Self::LANES`.
unsafe fn replace_unchecked(&mut self, i: usize, val: Self::Element);

/// Merges `self` and `other` depending on the lanes of `cond`.
Expand All @@ -48,7 +48,7 @@ pub trait SimdValue: Sized {
{
let mut result = self.clone();

for i in 0..Self::lanes() {
for i in 0..Self::LANES {
unsafe { result.replace_unchecked(i, f(self.extract_unchecked(i))) }
}

Expand All @@ -71,7 +71,7 @@ pub trait SimdValue: Sized {
{
let mut result = self.clone();

for i in 0..Self::lanes() {
for i in 0..Self::LANES {
unsafe {
let a = self.extract_unchecked(i);
let b = b.extract_unchecked(i);
Expand All @@ -92,14 +92,10 @@ pub trait SimdValue: Sized {
pub trait PrimitiveSimdValue: Copy + SimdValue {}

impl<N: SimdValue> SimdValue for num_complex::Complex<N> {
const LANES: usize = N::LANES;
type Element = num_complex::Complex<N::Element>;
type SimdBool = N::SimdBool;

#[inline(always)]
fn lanes() -> usize {
N::lanes()
}

#[inline(always)]
fn splat(val: Self::Element) -> Self {
num_complex::Complex {
Expand Down Expand Up @@ -151,14 +147,10 @@ macro_rules! impl_primitive_simd_value_for_scalar (
($($t: ty),*) => {$(
impl PrimitiveSimdValue for $t {}
impl SimdValue for $t {
const LANES: usize = 1;
type Element = $t;
type SimdBool = bool;

#[inline(always)]
fn lanes() -> usize {
1
}

#[inline(always)]
fn splat(val: Self::Element) -> Self {
val
Expand Down
14 changes: 3 additions & 11 deletions src/simd/wide_simd_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,14 +153,10 @@ macro_rules! impl_wide_f32 (
}

impl SimdValue for $WideF32xX {
const LANES: usize = $lanes;
type Element = $f32;
type SimdBool = $WideBoolF32xX;

#[inline(always)]
fn lanes() -> usize {
$lanes
}

#[inline(always)]
fn splat(val: Self::Element) -> Self {
$WideF32xX(wide::$f32xX::from(val))
Expand Down Expand Up @@ -197,14 +193,10 @@ macro_rules! impl_wide_f32 (
}

impl SimdValue for $WideBoolF32xX {
const LANES: usize = $lanes;
type Element = bool;
type SimdBool = Self;

#[inline(always)]
fn lanes() -> usize {
$lanes
}

#[inline(always)]
fn splat(val: bool) -> Self {
let results = [
Expand Down Expand Up @@ -1090,7 +1082,7 @@ macro_rules! impl_wide_f32 (
#[inline(always)]
fn simd_horizontal_product(self) -> Self::Element {
let mut prod = self.extract(0);
for ii in 1..Self::lanes() {
for ii in 1..Self::LANES {
prod *= self.extract(ii)
}
prod
Expand Down

0 comments on commit 9acef5d

Please sign in to comment.