Troubles with vectors

Hi,

Thankyou for any advice in advance.

I have a function that I was using to experiment with using Zig vectors. it functions correctly for applying the collatz conjecture to all i32 in the vector:

fn collatzVector() [4]i32 {
    const V = @Vector(4, i32);

    const v_one = @as(V, @splat(1));
    const arr = [_]i32{ 2, 4, 6, 7 };

    const in: @Vector(4, i32) = arr;

    const v_even_mask = in & @as(V, @splat(1));
    const multiply_mask = (v_even_mask << v_one) | v_one;
    const multiply_operation = (in * multiply_mask);
    const add_one_operation = multiply_operation + v_even_mask;
    const flipped_mask = v_even_mask ^ v_one;
    const out = add_one_operation >> flipped_mask;

    return out;
}

However, the issue I am encountering, is trying to repeat this set of instructions. The below amendment results in an error: expected type ‘u5’, found ‘i32’.

fn collatzVector() [4]i32 {
    const V = @Vector(4, i32);

    const v_one = @as(V, @splat(1));
    const arr = [_]i32{ 2, 4, 6, 7 };

    var in: @Vector(4, i32) = arr;

    const v_even_mask = in & @as(V, @splat(1));
    const multiply_mask = (v_even_mask << v_one) | v_one;
    const multiply_operation = (in * multiply_mask);
    const add_one_operation = multiply_operation + v_even_mask;
    const flipped_mask = v_even_mask ^ v_one;
    in = add_one_operation >> flipped_mask;

    return in;
}

The reason for doing this is with the intent to use @reduce & .And to see if all elements in the vector are == 1 and repeat this block within a while loop.

Can anyone explain to me where I am going wrong here?

Bit shift operations, same as here:

2 Likes

You may be asking why this error didn’t happen before. After all, you basically only changed a const to a var without changing any of the logic. The important difference here is that in Zig all const’s are automatically comptime if their initialization is comptime known. So in this case the first function will just evaluate everything at compile-time.
For comptime-known numbers and vectors the compiler is allowed to automatically cast the values to the required type. And since the comptime-known numbers fit into a u5 this was not producing any errors.

Also one quick side-note: Don’t hardcode the vector size. Most modern processors will support 8, on AVX512 even 16, i32 operations. You should use std.simd.suggestVectorSize(i32) instead of hardcoding the value, so that it always uses the optimal value for the given target.

3 Likes

Thank you both, really useful information here.

1 Like