How to make this generic SIMD more beautiful?

⚓ Rust    📅 2026-02-05    👤 surdeus    👁️ 10      

surdeus

I'm learning portable SIMD, but I found somewhat Rust one is verbose

#![feature(portable_simd)]

use std::simd::{Simd, SimdElement};
use std::ops::{Add, Mul, Sub, Div};

fn generic_simd<T, const N: usize>(a: [T; N], b: [T; N]) -> [T; N]
where
    T: SimdElement,
    Simd<T, N>: Add<Output = Simd<T, N>>
                + Mul<Output = Simd<T, N>>
                + Sub<Output = Simd<T, N>> 
                + Div<Output = Simd<T, N>>
{
    let av = Simd::from_array(a);
    let bv = Simd::from_array(b);
    let res = (av + bv) * av - bv / (av *bv);
    res.to_array()
}

fn main() {
    let a = [1, 2, 3, 4];
    let b = [1, 2, 3, 4];
    
    let res = generic_simd(a, b);
    
    println!("{:?}", res);
    
    let a_f32 = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0];
    let b_f32 = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0];
    
    let res_f32 = generic_simd(a_f32, b_f32);
    
    println!("{:?}", res_f32);
}

This is the Zig version

const std = @import("std");

fn generic_simd(comptime T: type, comptime len: T, a: [len]T, b: [len]T) [len]T {
    const av: @Vector(len, T) = a;
    const bv: @Vector(len, T) = b;
    const res = (av + bv) * av - bv / (av * bv);
    const array: [len]T = res;
    return array;
}

pub fn main() void {
    const a: [4]i32 = .{1,2,3,4};
    const b: [4]i32 = .{1,2,3,4};
  
    const res = generic_simd(i32, 4, a, b);
  
    const a_f32: [8]f32 = .{1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0};
    const b_f32: [8]f32 = .{1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0};
 
    const res_f32 = generic_simd(f32, 8, a_f32, b_f32);  
  
    std.debug.print("{any}\n{any}", .{ res, res_f32 });
}

Is there a more elegant way to write this in Rust?

1 post - 1 participant

Read full topic

🏷️ Rust_feed