Method Error in simple LoopVectorization call

With this simple example, I get an error where I do not expect it when looping over a Vector{Int} with length 2.

using LoopVectorization
function f(v)
    x = zero(eltype(v))
    @turbo for i ∈ eachindex(v)
        amt = v[i] * 0.1
        x += amt
    end
    x
end

These work:

f(rand(Int,3))  # Integer length 3 
f(rand(2))      # Float length 2

But integers with a vector length of 2 do not:

julia> f(rand(Int,2))
ERROR: MethodError: no method matching VectorizationBase.VecUnroll(::Tuple{VectorizationBase.Vec{2, Float64}, VectorizationBase.Vec{2, Int64}})

Am I doing something wrong? If I removed the * 0.1 from the amt = v[i] * 0.1 line then an integer vector of length two works.

When I run your code the example with f(rand(Int, 3)) also fails. I don’t think this is too surprising since your code is type unstable. x is changing from an Int to a Float64 here. If we initialize x in a type stable manner, everything is fine:

julia> function f(v)
           x = zero(promote_type(Float64, eltype(v)))
           @turbo for i ∈ eachindex(v)
               amt = v[i] * 0.1
               x += amt
           end
           x
       end
f (generic function with 1 method)

julia> f(rand(Int, 2))
2.6610511336745555e17

julia> f([1, 2])
0.30000000000000004

julia> f([1, 2, 3])
0.6000000000000001

LoopVectorization.jl is pretty brittle around things like this.

2 Likes

Yes, it generally assumes code is type stable.
This is a case where a better error message would be preferable over getting the example to work.
Unfortunately, an error message would probably be more difficult.

1 Like