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

lanes associated const for SimdValue #53

Open
aentity opened this issue Feb 19, 2024 · 1 comment
Open

lanes associated const for SimdValue #53

aentity opened this issue Feb 19, 2024 · 1 comment

Comments

@aentity
Copy link

aentity commented Feb 19, 2024

is possible we can have associated const LANES for wide types? Or for example in SimdValue:

trait SimdValue {
  const LANES: usize;
}

This will be very useful in generic context and working with arrays.

For example:

if we have:

type WIDE = simba::simd::WideF32x4;
type WIDET = f32;

for slice in data.chunks(WIDE::LANES) {
  let arr: [WIDET; WIDE::LANES] = slice.try_into().unwrap();
  let wide = WIDE::from(arr);
}

we can now easily switch the wide type, put in generics, or change wide amount to experiment for performance. today simba::simd::WideF32x4::lanes() is trait fn, and cannot be const.

if yes, i will attempt to make PR, thank you

@audunska
Copy link

audunska commented Mar 18, 2024

For what it's worth, I've tried this approach in my own non-simba code, and it does not work very well. This is because rust does not support being generic over associated constants very well.

In fact, even using the associated constant in the trait definition fails:
https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=786e5dca82fc4bc38e7c7b6db68dc537

Instead, I ended up passing the lane count around as a parameter instead. It's more clumsy but works. It goes something like this:

pub trait HasWide<const WIDTH: usize>: Sized + Clone + Copy + Num {
    type Wide: Sized
        + Clone
        + Copy
        + SimdRealField<Element = Self>
        + std::fmt::Debug
        + Field
        + From<[Self; WIDTH]>
        + Into<[Self; WIDTH]>;
}

impl HasWide<4>for f32 {
  type Wide = AutoSimd<[f32; 4]>; // Or WideF32x4, for example
}

Use it like this (just some arbitrary computation that probably makes no sense):

fn wide_computation<const WIDTH: usize, R: HasWide<WIDTH>>(input: r) -> R {
  let arr: [R; WIDTH] = std::array::from_fn(|n| R::from_superset(&(n as f64)) * R::pi());
  let val: R::Wide = arr.into();
  val.sin().simd_horizontal_sum()
}

fn main() {
  let r = wide_computation::<4, f32>(1.0);
  println!("{r}");
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants