64 lines
2.3 KiB
Zig
64 lines
2.3 KiB
Zig
const expect = @import("std").testing.expect;
|
|
|
|
// Zig provides vector types for SIMD.
|
|
// These are not to be conflated with vectors in a mathematical sense,
|
|
// or vectors like C++'s `std::vector` (for this, see "Arraylist" in chapter 2).
|
|
// Vectors may be created using the `@Type` built-in we used earlier, and `std.meta.Vector` provides a shorthand for this.
|
|
|
|
// Vectors can only have child types of booleans, integers, floats and pointers.
|
|
|
|
// Operations between vectors with the same child type and length can take place.
|
|
// These operations are performed on each of the values in the vector.`std.meta.eql` is used here
|
|
// to check for equality between two vectors (also useful for other types like structs).
|
|
|
|
const meta = @import("std").meta;
|
|
|
|
test "vector add" {
|
|
const x: @Vector(4, f32) = .{ 1, -10, 20, -1 };
|
|
const y: @Vector(4, f32) = .{ 2, 10, 0, 1 };
|
|
const z = x + y;
|
|
try expect(meta.eql(z, @Vector(4, f32){ 3, 0, 20, 0 }));
|
|
}
|
|
|
|
// Vectors are indexable.
|
|
test "vector indexing" {
|
|
const x: @Vector(4, u8) = .{ 255, 0, 255, 0 };
|
|
try expect(x[0] == 255);
|
|
}
|
|
|
|
// The built-in function `@splat` may be used to construct a vector where all of the values are the same.
|
|
// Here we use it to multiply a vector by a scalar.
|
|
test "vector * scalar" {
|
|
const x: @Vector(3, f32) = .{ 12.5, 37.5, 2.5 };
|
|
const y = x * @as(@Vector(3, f32), @splat(2)); // as to @Vector(3, f32) = .{ 2, 2, 2 }
|
|
try expect(meta.eql(y, @Vector(3, f32){ 25, 75, 5 }));
|
|
}
|
|
|
|
// Vectors do not have a len field like arrays, but may still be looped over.
|
|
test "vector looping" {
|
|
const x = @Vector(4, u8){ 255, 0, 255, 0 };
|
|
const sum = blk: {
|
|
var tmp: u10 = 0;
|
|
var i: u8 = 0;
|
|
while (i < 4) : (i += 1) tmp += x[i];
|
|
break :blk tmp;
|
|
};
|
|
try expect(sum == 510);
|
|
}
|
|
|
|
// Vectors coerce to their respective arrays.
|
|
const arr: [4]f32 = @Vector(4, f32){ 1, 2, 3, 4 };
|
|
// XXX: My tests
|
|
test "vector coercion" {
|
|
const x: @Vector(4, f32) = .{ 1, 2, 3, 4 };
|
|
const y: [4]f32 = x;
|
|
try expect(y[0] == 1);
|
|
try expect(y[1] == 2);
|
|
try expect(y[2] == 3);
|
|
try expect(y[3] == 4);
|
|
try expect(y.len == 4);
|
|
}
|
|
|
|
// It is worth noting that using explicit vectors may result in slower software if you do not make the right decisions
|
|
// - the compiler's auto-vectorisation is fairly smart as-is.
|