Open
Description
I wanted to put together a more technical list of issues to be solved before we can stabilize (see rust-lang/rust#86656).
There are many more important issues like performance on some targets, or important missing functions, but IMO those don't prevent stabilization. In this list I've trimmed down the issues to major API-related issues that can't be changed, or are difficult to change, after stabilization.
Issues to be solved
- Restricting the number of lanes. In my opinion, the
LaneCount<N>: SupportedLaneCount
bound makes the API exceptionally cumbersome. I've also had some trouble writing generics around it, particularly when making functions that change the number of lanes (the trait solver sometimes simply fails). Adding the bound often feels like boilerplate, and I found myself looking for ways to launder the bound, like adding unnecessary const parameters. Making this a post-monomorphization error (I found Design meeting: Non-local errors (aka post-monomorphization errors) lang-team#195 helpful) might be the way to go, or perhaps there's a way to make a const fn panic. Cons: the trait bound is very explicit and hiding the error states could possibly do more harm than good when identifying the source of a build failure. - Mask element type. I'm not confident that the mask type for
Simd<f32, N>
should beSimd<i32, N>
(see Change Mask element to match Simd element #322 for discussion). I think it would be much more straightforward if the types simply matched. Cons: this would require an extra cast when usingi32
masks forf32
vectors or similar, and makes implementingFrom<Mask> for Mask
impossible (since pointer masks must be genericMask<*const T, N>
, maybe all pointers could use the same mask element?). - Swizzle functions. They're difficult to use and not a very good API, but Rust doesn't currently allow for anything much better. We could hold off stabilizing arbitrary swizzles, but that's a big limitation.
Non-issues, but things that should be done
- Are we happy with the traits the way they are? e.g.
SimdPartialEq
,SimdInt
. - The API should be partitioned into multiple unstable features that can be stabilized independently.
Updates (after filing this issue)
Lane count
- I tried condensing
LaneCount
anSimdElement
into a single boundSimd<T, N>: Supported
. This doesn't work well for a variety of reasons. One example: scatter/gather useSimd<T, N>
,Simd<*const T, N>
, andSimd<usize, N>
. Each of these would need their own bound, rather than using oneLaneCount
bound since they all shareN
. - I recommend either keeping the bounds as they are now (
LaneCount
andSimdElement
) or turningLaneCount
into a non-local error.
Swizzles
I tried the following swizzle code. It requires the incomplete adt_const_params
feature. Even with this feature enabled, it's impossible to implement functions like reverse
, because const generics can't access the generic const parameters.
pub fn swizzle<const M: usize, const INDEX: &'static [usize]>(self) -> Simd<T, M>
where
LaneCount<M>: SupportedLaneCount,
{
// SAFETY: `self` is a vector and the swizzle index is a const array of u32
unsafe {
intrinsics::simd_shuffle(
self,
self,
const {
assert!(M == INDEX.len(), "`M` must equal the length of `INDEX`");
let mut r = [0; M];
let mut i = 0;
while i < M {
assert!(
INDEX[i] < N,
"indices must be less than the input vector length"
);
r[i] = INDEX[i] as u32;
i += 1;
}
r
},
)
}
}
Metadata
Metadata
Assignees
Labels
No labels