C+
SIMD

SIMD dot product

This example is the docs/examples/recipes/simd_dot recipe from the C+ source tree. It backs the SIMD claim with a small numeric kernel that has a scalar oracle and a vectorized implementation.

Claim How this recipe checks it
SIMD vector types are usable in ordinary C+ Uses f32x4::splat, f32x4::new, .fma, and .lane
SIMD and scalar paths agree Computes the same dot product both ways
Result is checked at runtime Exits nonzero if scalar, SIMD, or scalar-vs-SIMD comparison fails
No package dependency is needed The recipe is self-contained and uses primitive SIMD types directly

Source shape

The input is fixed at 16 lanes, enough for four f32x4 chunks:

fn dot_simd(a: [f32; 16], b: [f32; 16]) -> f32 {
    let mut acc: f32x4 = f32x4::splat(0.0f32);
    let mut i: i32 = 0;
    while i < 16 {
        let av: f32x4 = f32x4::new(
            a[(i +% 0) as usize],
            a[(i +% 1) as usize],
            a[(i +% 2) as usize],
            a[(i +% 3) as usize],
        );
        let bv: f32x4 = f32x4::new(
            b[(i +% 0) as usize],
            b[(i +% 1) as usize],
            b[(i +% 2) as usize],
            b[(i +% 3) as usize],
        );
        acc = av.fma(bv, acc);
        i = i +% 4;
    }
    return acc.lane(0 as u32) + acc.lane(1 as u32) + acc.lane(2 as u32) + acc.lane(3 as u32);
}

The self-check compares against the hand-computed reference 347:

let s: f32 = dot_scalar(a, b);
let v: f32 = dot_simd(a, b);

if abs_diff(s, 347.0f32) > 0.001f32 { return 1; }
if abs_diff(v, 347.0f32) > 0.001f32 { return 2; }
if abs_diff(s, v) > 0.001f32 { return 3; }
return 0;

Reproduce

From docs/examples/recipes/simd_dot in the C+ source tree:

cpc build
./target/debug/simd_dot

Expected result: exit code 0. Exit codes 1, 2, or 3 identify which numeric check failed.

The recipe is intentionally small. It proves the primitive SIMD path that larger matrix, ML, and DSP kernels build on: construct vectors, do lane-wise math, use FMA, then reduce lanes back to a scalar result.


‹ Back to all examples