How should I write generic SIMD code without putting massive requirements into my where clauses?

⚓ Rust    📅 2025-12-17    👤 surdeus    👁️ 1      

surdeus

I have a lot of SIMD code that relies on a function that looks like this:

#![feature(portable_simd)]

use std::simd::prelude::*;
use std::simd::*;

unsafe fn do_things<T, const L: usize>(
    x: Simd<T, L>,
    cmp: Simd<T, L>,
    tests: &[T],
) -> Simd<T, L> where
    LaneCount<L>: SupportedLaneCount,
    T: SimdElement + Default,
    Simd<T, L>: SimdPartialOrd,
    Mask<isize, L>: From<<Simd<T, L> as SimdPartialEq>::Mask>,
{
    // this function is mostly nonsense but uses real operations from my code
    let results: Mask<isize, L> = x.simd_le(cmp).into();
    let offsets = results.to_int();
    let ptrs = Simd::splat(tests.as_ptr()).wrapping_offset(offsets);
    unsafe { Simd::gather_ptr(ptrs) }
}

(this is not the "real" function, but an abstracted version of this, if you want to see the exact version).

In the ideal world, I would like to be able to have user-facing library have a much simpler signature that also does not leak all the implementation details :

// the below traits will be sealed to avoid leaking
pub trait MyTrait {}     // can modify this however I like
pub trait MySimdTrait {} // and this too

pub fn public_math<T, const L: usize>( /* ... */ ) where
    T: MyTrait,
    Simd<T, L>: MySimdTrait,
    LaneCount<L>: SupportedLaneCount,
{
    // do other things...
    unsafe { do_things::<T, L>(/* ... */) };
    // ...
}

So far, I've been decently successful at just requiring that T and Simd<T, L> support certain traits, but specifically the following requirement has caused me a lot of grief:

Mask<isize, L>: From<<Simd<T, L> as SimdPartialEq>::Mask>,

since I can't seem to be able to capture it into MyTrait or MySimdTrait. I have a few questions:

  • Is it possible to avoid this trait requirement altogether in do_things?
  • If not, is it possible to fold the requirement into MyTrait or MySimdTrait?
  • In general, is there a better way to do this? Can I reduce the number of traits and where clauses somehow?

2 posts - 2 participants

Read full topic

🏷️ Rust_feed