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

API to specify max number of elements #373

Open
AdamWRichardson opened this issue Nov 15, 2023 · 5 comments
Open

API to specify max number of elements #373

AdamWRichardson opened this issue Nov 15, 2023 · 5 comments
Labels
C-feature-request Category: a feature request, i.e. not implemented / a PR

Comments

@AdamWRichardson
Copy link

Thanks all for the great project, I can't wait until this is made stable!

To help with the portability I thought it would be useful to have some way of asking for a SIMD struct with the maximum number of elements supported by the target, such that you could write something like:

let a = f32::with_max_elements();

And that would give you Simd<f32, 16> for a target which supports 512 bits but Simd<f32, 4> on targets which only support 128 bits.

I thought this would be a fairly easy addition so I tried a couple of different implementations (including the one above) but each on so far has had problems. I'm very keen to contribute to the project and would happily write this up but wanted to check a couple of things:

  • Is this something that would be useful and worth implementing?
  • What do you think is the best way to go about this?
@AdamWRichardson AdamWRichardson added the C-feature-request Category: a feature request, i.e. not implemented / a PR label Nov 15, 2023
@calebzulawski
Copy link
Member

calebzulawski commented Nov 18, 2023

I think something like this would be nice, but difficult to implement. The difficult part is accounting for detected target features. My target-features and multiversion crates support this, this may help: https://calebzulawski.github.io/rust-simd-book/4.2-native-vector-width.html

@programmerjake
Copy link
Member

other things that make this harder is that on some architectures you can't get the maximum length at compile time, e.g. on RISC-V V, the maximum length is decided by the cpu manufacturer and may be all the way up to 16384 but can be much shorter. Some architectures you can't get a reasonable maximum length, e.g. SVP64 on PowerISA has a maximum length of 64, but you can only have 3 u64x64 vectors in registers, but you can instead easily have dozens of u64x4 vectors in registers which may even be faster.

@calebzulawski
Copy link
Member

That's another good point--you could conceivably have two versions of such a function, one that's const and one that isn't. In target-features I simply return 128-bit vectors for the v extension, even though they can of course be much larger. If rust adds zvl*b target features, that would at least make it possible to statically detect a larger minimum.

@AdamWRichardson
Copy link
Author

AdamWRichardson commented Nov 19, 2023

Thanks for the responses, I hadn't even considered non-mainstream architectures yet! Your target-features crate seems to do similar things to my plan which was just having a load of #[cfg(target-feature = "...")] within a function although the crate is a much nicer way to do this.

One potential annoyance one could have with the suggested_vector_width API is that a user could conceivably do something like:
const N: usize = selected_target!().suggested_vector_width::<f32>().unwrap_or(1);
let vector = Simd<f64, N>;

Which is why I thought an associated method on the Simd struct might have been nicer because it just has to care about one instance of T.

To implement this functionality within portable_simd it would be good to use the target-features and multiversion crates but is that allowed when thinking about up-streaming to stable?

@calebzulawski
Copy link
Member

It would be difficult to make it an associated function because the return type needs to have the number of elements in it, and that number of elements is contextual, at least on the statically enabled features but also potentially from the #[target_feature] attributes. This is definitely something I'd like to be easier to do, but unfortunately it's a bit difficult in Rust today.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-feature-request Category: a feature request, i.e. not implemented / a PR
Projects
None yet
Development

No branches or pull requests

3 participants