Skip to content

Instantly share code, notes, and snippets.

@travisstaloch
Last active August 15, 2025 06:17
Show Gist options
  • Select an option

  • Save travisstaloch/7ba38f380c3af2b229e661716074d3f4 to your computer and use it in GitHub Desktop.

Select an option

Save travisstaloch/7ba38f380c3af2b229e661716074d3f4 to your computer and use it in GitHub Desktop.
This doesn't need usingnamespace since all methods are defined in a single extern struct.
export fn add(a: [*]u32, b: [*]u32, out: [*]u32) void {
const avec: Vec(u32, 3) = .fromArr(a[0..3].*);
const bvec: Vec(u32, 3) = .fromArr(b[0..3].*);
out[0..3].* = avec.add(bvec).toArr();
}
export fn add_simd(a: [*]u32, b: [*]u32, out: [*]u32) void {
const avec: Vec(u32, 3) = .fromArr(a[0..3].*);
const bvec: Vec(u32, 3) = .fromArr(b[0..3].*);
out[0..3].* = avec.addSimd(bvec).toArr();
}
pub fn Vec(T: type, comptime size: u16) type {
return extern struct {
x: T,
y: if (size > 1) T else void,
z: if (size > 2) T else void,
rest: if (size > 3) [size - 3]T else void,
const Self = @This();
pub fn toArr(self: Self) [size]T {
return @bitCast(self);
}
pub fn fromArr(arr: [size]T) Self {
return @bitCast(arr);
}
pub fn splat(value: T) Self {
return fromArr(@splat(value));
}
pub fn add(a: Self, b: Self) Self {
var result: [size]T = undefined;
for (&result, a.toArr(), b.toArr()) |*comp, acomp, bcomp| {
comp.* = acomp + bcomp;
}
return fromArr(result);
}
pub const V = @Vector(size, T);
pub fn fromSimd(v: V) Self {
return @bitCast(v);
}
pub fn toSimd(self: Self) V {
return @bitCast(self);
}
pub fn addSimd(a: Self, b: Self) Self {
return fromSimd(a.toSimd() + b.toSimd());
}
};
}
test Vec {
inline for ([_]type{ u8, u32, usize, f32, f64 }) |Child| {
inline for ([_]u16{ 1, 2, 3, 4, 5, 6, 7, 8 }) |size| {
const V = Vec(Child, size);
const x: V = .splat(1);
const y: V = .splat(2);
try std.testing.expectEqual(V.splat(3), x.add(y));
}
}
}
const std = @import("std");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment