| ... | ... | @@ -2515,13 +2515,14 @@ test "null terminated array" { |
| 2515 | 2515 | |
| 2516 | 2516 | {#header_open|Vectors#} |
| 2517 | 2517 | <p> |
| 2518 | | A vector is a group of booleans, {#link|Integers#}, {#link|Floats#}, or {#link|Pointers#} which are operated on |
| 2519 | | in parallel using SIMD instructions. Vector types are created with the builtin function {#link|@Type#}, |
| 2520 | | or using the shorthand function {#syntax#}std.meta.Vector{#endsyntax#}. |
| 2518 | A vector is a group of booleans, {#link|Integers#}, {#link|Floats#}, or |
| 2519 | {#link|Pointers#} which are operated on in parallel, using SIMD instructions if possible. |
| 2520 | Vector types are created with the builtin function {#link|@Vector#}. |
| 2521 | 2521 | </p> |
| 2522 | 2522 | <p> |
| 2523 | | Vectors support the same builtin operators as their underlying base types. These operations are performed |
| 2524 | | element-wise, and return a vector of the same length as the input vectors. This includes: |
| 2523 | Vectors support the same builtin operators as their underlying base types. |
| 2524 | These operations are performed element-wise, and return a vector of the same length |
| 2525 | as the input vectors. This includes: |
| 2525 | 2526 | </p> |
| 2526 | 2527 | <ul> |
| 2527 | 2528 | <li>Arithmetic ({#syntax#}+{#endsyntax#}, {#syntax#}-{#endsyntax#}, {#syntax#}/{#endsyntax#}, {#syntax#}*{#endsyntax#}, |
| ... | ... | @@ -2532,10 +2533,11 @@ test "null terminated array" { |
| 2532 | 2533 | <li>Comparison operators ({#syntax#}<{#endsyntax#}, {#syntax#}>{#endsyntax#}, {#syntax#}=={#endsyntax#}, etc.)</li> |
| 2533 | 2534 | </ul> |
| 2534 | 2535 | <p> |
| 2535 | | It is prohibited to use a math operator on a mixture of scalars (individual numbers) and vectors. |
| 2536 | | Zig provides the {#link|@splat#} builtin to easily convert from scalars to vectors, and it supports {#link|@reduce#} |
| 2537 | | and array indexing syntax to convert from vectors to scalars. Vectors also support assignment to and from |
| 2538 | | fixed-length arrays with comptime known length. |
| 2536 | It is prohibited to use a math operator on a mixture of scalars (individual numbers) |
| 2537 | and vectors. Zig provides the {#link|@splat#} builtin to easily convert from scalars |
| 2538 | to vectors, and it supports {#link|@reduce#} and array indexing syntax to convert |
| 2539 | from vectors to scalars. Vectors also support assignment to and from fixed-length |
| 2540 | arrays with comptime known length. |
| 2539 | 2541 | </p> |
| 2540 | 2542 | <p> |
| 2541 | 2543 | For rearranging elements within and between vectors, Zig provides the {#link|@shuffle#} and {#link|@select#} functions. |
| ... | ... | @@ -2550,16 +2552,14 @@ test "null terminated array" { |
| 2550 | 2552 | </p> |
| 2551 | 2553 | {#code_begin|test|vector_example#} |
| 2552 | 2554 | const std = @import("std"); |
| 2553 | | const Vector = std.meta.Vector; |
| 2554 | 2555 | const expectEqual = std.testing.expectEqual; |
| 2555 | 2556 | |
| 2556 | 2557 | test "Basic vector usage" { |
| 2557 | | // Vectors have a compile-time known length and base type, |
| 2558 | | // and can be assigned to using array literal syntax |
| 2559 | | const a: Vector(4, i32) = [_]i32{ 1, 2, 3, 4 }; |
| 2560 | | const b: Vector(4, i32) = [_]i32{ 5, 6, 7, 8 }; |
| 2558 | // Vectors have a compile-time known length and base type. |
| 2559 | const a = @Vector(4, i32){ 1, 2, 3, 4 }; |
| 2560 | const b = @Vector(4, i32){ 5, 6, 7, 8 }; |
| 2561 | 2561 | |
| 2562 | | // Math operations take place element-wise |
| 2562 | // Math operations take place element-wise. |
| 2563 | 2563 | const c = a + b; |
| 2564 | 2564 | |
| 2565 | 2565 | // Individual vector elements can be accessed using array indexing syntax. |
| ... | ... | @@ -2572,19 +2572,19 @@ test "Basic vector usage" { |
| 2572 | 2572 | test "Conversion between vectors, arrays, and slices" { |
| 2573 | 2573 | // Vectors and fixed-length arrays can be automatically assigned back and forth |
| 2574 | 2574 | var arr1: [4]f32 = [_]f32{ 1.1, 3.2, 4.5, 5.6 }; |
| 2575 | | var vec: Vector(4, f32) = arr1; |
| 2575 | var vec: @Vector(4, f32) = arr1; |
| 2576 | 2576 | var arr2: [4]f32 = vec; |
| 2577 | 2577 | try expectEqual(arr1, arr2); |
| 2578 | 2578 | |
| 2579 | 2579 | // You can also assign from a slice with comptime-known length to a vector using .* |
| 2580 | | const vec2: Vector(2, f32) = arr1[1..3].*; |
| 2580 | const vec2: @Vector(2, f32) = arr1[1..3].*; |
| 2581 | 2581 | |
| 2582 | 2582 | var slice: []const f32 = &arr1; |
| 2583 | 2583 | var offset: u32 = 1; |
| 2584 | 2584 | // To extract a comptime-known length from a runtime-known offset, |
| 2585 | 2585 | // first extract a new slice from the starting offset, then an array of |
| 2586 | 2586 | // comptime known length |
| 2587 | | const vec3: Vector(2, f32) = slice[offset..][0..2].*; |
| 2587 | const vec3: @Vector(2, f32) = slice[offset..][0..2].*; |
| 2588 | 2588 | try expectEqual(slice[offset], vec2[0]); |
| 2589 | 2589 | try expectEqual(slice[offset + 1], vec2[1]); |
| 2590 | 2590 | try expectEqual(vec2, vec3); |
| ... | ... | @@ -9084,7 +9084,7 @@ pub const PrefetchOptions = struct { |
| 9084 | 9084 | {#header_close#} |
| 9085 | 9085 | |
| 9086 | 9086 | {#header_open|@select#} |
| 9087 | | <pre>{#syntax#}@select(comptime T: type, pred: std.meta.Vector(len, bool), a: std.meta.Vector(len, T), b: std.meta.Vector(len, T)) std.meta.Vector(len, T){#endsyntax#}</pre> |
| 9087 | <pre>{#syntax#}@select(comptime T: type, pred: @Vector(len, bool), a: @Vector(len, T), b: @Vector(len, T)) @Vector(len, T){#endsyntax#}</pre> |
| 9088 | 9088 | <p> |
| 9089 | 9089 | Selects values element-wise from {#syntax#}a{#endsyntax#} or {#syntax#}b{#endsyntax#} based on {#syntax#}pred{#endsyntax#}. If {#syntax#}pred[i]{#endsyntax#} is {#syntax#}true{#endsyntax#}, the corresponding element in the result will be {#syntax#}a[i]{#endsyntax#} and otherwise {#syntax#}b[i]{#endsyntax#}. |
| 9090 | 9090 | </p> |
| ... | ... | @@ -9252,7 +9252,7 @@ test "@setRuntimeSafety" { |
| 9252 | 9252 | {#header_close#} |
| 9253 | 9253 | |
| 9254 | 9254 | {#header_open|@shuffle#} |
| 9255 | | <pre>{#syntax#}@shuffle(comptime E: type, a: std.meta.Vector(a_len, E), b: std.meta.Vector(b_len, E), comptime mask: std.meta.Vector(mask_len, i32)) std.meta.Vector(mask_len, E){#endsyntax#}</pre> |
| 9255 | <pre>{#syntax#}@shuffle(comptime E: type, a: @Vector(a_len, E), b: @Vector(b_len, E), comptime mask: @Vector(mask_len, i32)) @Vector(mask_len, E){#endsyntax#}</pre> |
| 9256 | 9256 | <p> |
| 9257 | 9257 | Constructs a new {#link|vector|Vectors#} by selecting elements from {#syntax#}a{#endsyntax#} and |
| 9258 | 9258 | {#syntax#}b{#endsyntax#} based on {#syntax#}mask{#endsyntax#}. |
| ... | ... | @@ -9287,22 +9287,21 @@ test "@setRuntimeSafety" { |
| 9287 | 9287 | </p> |
| 9288 | 9288 | {#code_begin|test|vector_shuffle#} |
| 9289 | 9289 | const std = @import("std"); |
| 9290 | | const Vector = std.meta.Vector; |
| 9291 | 9290 | const expect = std.testing.expect; |
| 9292 | 9291 | |
| 9293 | 9292 | test "vector @shuffle" { |
| 9294 | | const a: Vector(7, u8) = [_]u8{ 'o', 'l', 'h', 'e', 'r', 'z', 'w' }; |
| 9295 | | const b: Vector(4, u8) = [_]u8{ 'w', 'd', '!', 'x' }; |
| 9293 | const a = @Vector(7, u8){ 'o', 'l', 'h', 'e', 'r', 'z', 'w' }; |
| 9294 | const b = @Vector(4, u8){ 'w', 'd', '!', 'x' }; |
| 9296 | 9295 | |
| 9297 | 9296 | // To shuffle within a single vector, pass undefined as the second argument. |
| 9298 | 9297 | // Notice that we can re-order, duplicate, or omit elements of the input vector |
| 9299 | | const mask1: Vector(5, i32) = [_]i32{ 2, 3, 1, 1, 0 }; |
| 9300 | | const res1: Vector(5, u8) = @shuffle(u8, a, undefined, mask1); |
| 9298 | const mask1 = @Vector(5, i32){ 2, 3, 1, 1, 0 }; |
| 9299 | const res1: @Vector(5, u8) = @shuffle(u8, a, undefined, mask1); |
| 9301 | 9300 | try expect(std.mem.eql(u8, &@as([5]u8, res1), "hello")); |
| 9302 | 9301 | |
| 9303 | 9302 | // Combining two vectors |
| 9304 | | const mask2: Vector(6, i32) = [_]i32{ -1, 0, 4, 1, -2, -3 }; |
| 9305 | | const res2: Vector(6, u8) = @shuffle(u8, a, b, mask2); |
| 9303 | const mask2 = @Vector(6, i32){ -1, 0, 4, 1, -2, -3 }; |
| 9304 | const res2: @Vector(6, u8) = @shuffle(u8, a, b, mask2); |
| 9306 | 9305 | try expect(std.mem.eql(u8, &@as([6]u8, res2), "world!")); |
| 9307 | 9306 | } |
| 9308 | 9307 | {#code_end#} |
| ... | ... | @@ -9329,7 +9328,7 @@ test "vector @shuffle" { |
| 9329 | 9328 | {#header_close#} |
| 9330 | 9329 | |
| 9331 | 9330 | {#header_open|@splat#} |
| 9332 | | <pre>{#syntax#}@splat(comptime len: u32, scalar: anytype) std.meta.Vector(len, @TypeOf(scalar)){#endsyntax#}</pre> |
| 9331 | <pre>{#syntax#}@splat(comptime len: u32, scalar: anytype) @Vector(len, @TypeOf(scalar)){#endsyntax#}</pre> |
| 9333 | 9332 | <p> |
| 9334 | 9333 | Produces a vector of length {#syntax#}len{#endsyntax#} where each element is the value |
| 9335 | 9334 | {#syntax#}scalar{#endsyntax#}: |
| ... | ... | @@ -9341,7 +9340,7 @@ const expect = std.testing.expect; |
| 9341 | 9340 | test "vector @splat" { |
| 9342 | 9341 | const scalar: u32 = 5; |
| 9343 | 9342 | const result = @splat(4, scalar); |
| 9344 | | comptime try expect(@TypeOf(result) == std.meta.Vector(4, u32)); |
| 9343 | comptime try expect(@TypeOf(result) == @Vector(4, u32)); |
| 9345 | 9344 | try expect(std.mem.eql(u32, &@as([4]u32, result), &[_]u32{ 5, 5, 5, 5 })); |
| 9346 | 9345 | } |
| 9347 | 9346 | {#code_end#} |
| ... | ... | @@ -9381,10 +9380,10 @@ const std = @import("std"); |
| 9381 | 9380 | const expect = std.testing.expect; |
| 9382 | 9381 | |
| 9383 | 9382 | test "vector @reduce" { |
| 9384 | | const value: std.meta.Vector(4, i32) = [_]i32{ 1, -1, 1, -1 }; |
| 9383 | const value = @Vector(4, i32){ 1, -1, 1, -1 }; |
| 9385 | 9384 | const result = value > @splat(4, @as(i32, 0)); |
| 9386 | 9385 | // result is { true, false, true, false }; |
| 9387 | | comptime try expect(@TypeOf(result) == std.meta.Vector(4, bool)); |
| 9386 | comptime try expect(@TypeOf(result) == @Vector(4, bool)); |
| 9388 | 9387 | const is_all_true = @reduce(.And, result); |
| 9389 | 9388 | comptime try expect(@TypeOf(is_all_true) == bool); |
| 9390 | 9389 | try expect(is_all_true == false); |
| ... | ... | @@ -9743,6 +9742,12 @@ fn foo(comptime T: type, ptr: *T) T { |
| 9743 | 9742 | {#syntax#}@unionInit{#endsyntax#} forwards its {#link|result location|Result Location Semantics#} to {#syntax#}init_expr{#endsyntax#}. |
| 9744 | 9743 | </p> |
| 9745 | 9744 | {#header_close#} |
| 9745 | |
| 9746 | |
| 9747 | {#header_open|@Vector#} |
| 9748 | <pre>{#syntax#}@Vector(len: comptime_int, Element: type) type{#endsyntax#}</pre> |
| 9749 | <p>Creates {#link|Vectors#}.</p> |
| 9750 | {#header_close#} |
| 9746 | 9751 | {#header_close#} |
| 9747 | 9752 | |
| 9748 | 9753 | {#header_open|Build Mode#} |