Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: replace the SimdValue::lanes() function by an associated const SimdValue::LANES #60

Merged
merged 1 commit into from
Jun 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading