1

Rust newbie here.

The following code throws a compiler error:

#![feature(portable_simd)]

use std::simd::Simd;
use std::simd::SimdElement;

fn test_mul<T: SimdElement, const N: usize>(x: [T; N]) -> Simd<T, N> 
where 
    std::simd::LaneCount<N>: std::simd::SupportedLaneCount,
{
    type InputType<T: SimdElement, const N: usize> = Simd<T, N>;
    let v = InputType::from_array(x);
    let result = v*v;
    return result;
}

Error:

error[E0369]: cannot multiply `Simd<T, N>` by `Simd<T, N>`
   --> src\lib.rs:12:19
    |
 12 |     let result = v*v;
    |                  -^- Simd<T, N>
    |                  |
    |                  Simd<T, N>
    |
note: `Simd<T, N>` does not implement `Mul`
help: consider extending the `where` clause, but there might be an alternative better way to express this requirement
    |
  8 |     std::simd::LaneCount<N>: std::simd::SupportedLaneCount, Simd<T, N>: Mul
    |                                                             +++++++++++++++

Which does not make sense to me, since Simd definitely implements Mul, and if I define my function with only the generic N, the compiler certainly finds it:

fn test_mul_2<const N: usize>(x: [f64; N]) -> Simd<f64, N> 
where 
    std::simd::LaneCount<N>: std::simd::SupportedLaneCount,
{
    type InputType<const N: usize> = Simd<f64, N>;
    let v = InputType::from_array(x);
    let result = v*v;
    return result;
}

The help also seems dubious, as the Simd declaration already declares that trait, and trying to use the suggestion gets me even further into the weeds:

 6 | fn test_mul<T: SimdElement, const N: usize>(x: [T; N]) -> Simd<T, N> 
   |                                                           ---------- expected `std::simd::Simd<T, N>` because of return type
...
13 |     return result;
   |            ^^^^^^ expected `Simd<T, N>`, found associated type
   |
   = note:       expected struct `std::simd::Simd<T, N>`
           found associated type `<std::simd::Simd<T, N> as std::ops::Mul>::Output`
   = help: consider constraining the associated type `<std::simd::Simd<T, N> as std::ops::Mul>::Output` to `std::simd::Simd<T, N>`

So why is the first function not compiling? I really would like to be able to pass both T and N as generic parameters.

1 Answer 1

2

Operators over Simd are not implemented generically; that is, Mul is implemented separately for Simd<f32, N> and for Simd<f64, N> and likewise for all supported types.

If you want a generic T, the compiler suggestion is a good start, but to avoid the error you also need to constraint Output:

Simd<T, N>: std::ops::Mul<Output = Simd<T, N>>
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.