Error when trying the first example for LoopVectorization

I am trying the first example from https://github.com/chriselrod/LoopVectorization.jl . That is:

using LoopVectorization, BenchmarkTools
function mydot(a, b)
    s = 0.0
    @inbounds @simd for i ∈ eachindex(a,b)
        s += a[i]*b[i]
    end
    s
end
function mydotavx(a, b)
    s = 0.0
    @avx for i ∈ eachindex(a,b)
        s += a[i]*b[i]
    end
    s
end
a = rand(256); b = rand(256);
@btime mydot($a, $b)
@btime mydotavx($a, $b)
a = rand(43); b = rand(43);
@btime mydot($a, $b)
@btime mydotavx($a, $b)

I get an error from “s += a[i]*b[i]” which is

ERROR: LoadError: “Don’t know how to handle expression:\ns += a[i] * b[i]”

Stacktrace:

[1] push!( ::LoopVectorization.LoopSet, ::Expr, ::Int64 ) at /Users/user/.julia/packages/LoopVectorization/WdP5f/src/graphs.jl:539

[2] add_block!( ::LoopVectorization.LoopSet, ::Expr, ::Int64 ) at /Users/user/.julia/packages/LoopVectorization/WdP5f/src/graphs.jl:310

[3] add_loop!( ::LoopVectorization.LoopSet, ::Expr, ::Int64 ) at /Users/user/.julia/packages/LoopVectorization/WdP5f/src/graphs.jl:401

[4] add_loop! at /Users/user/.julia/packages/LoopVectorization/WdP5f/src/graphs.jl:398 [inlined]

[5] copyto! at /Users/user/.julia/packages/LoopVectorization/WdP5f/src/constructors.jl:6 [inlined]

[6] LoopVectorization.LoopSet( ::Expr ) at /Users/user/.julia/packages/LoopVectorization/WdP5f/src/constructors.jl:45

[7] @avx( ::LineNumberNode, ::Module, ::Any ) at /Users/user/.julia/packages/LoopVectorization/WdP5f/src/constructors.jl:93

in expression starting at REPL[25]:3

Am I doing something dim or is this a bug?

My apologies.
I messed up and tagged a bad commit. As soon as CI passes on the latest commit, I will tag a new one (which will take another few minutes to merge).

EDIT: PR on general registry.

3 Likes

Thank you. It looks like that process has finished but it can’t register the version number (which I guess should be 0.3.11?). I see: " JuliaRegistrator commented on 4192003 14 minutes ago

Error while trying to register: “Tag with name 0.3.10 already exists and points to a different commit”"

When I do “update LoopVectorization” I still get 0.3.10.

Yes. Tests passed, but I forgot to bump the version number. I edited my earlier post to add a link to the PR on the general registry with 0.3.11.

EDIT: To clarify, you need to wait until that PR merges before it is available. It has now.
@JeffreySarnoff also recommended loosening version bounds, which I did for now. This is despite the fact that they do have lower bounds. This means you may need to make sure you’re on SIMDPirates 0.1.8.
I’ll go back to micromanaging versions, and wait until CI passes before tagging so that this does not happen again.

1 Like

It works perfectly now. Just for interest, I get:

julia> a = rand(256); b = rand(256);
julia> @btime mydot($a, $b)

20.066 ns (0 allocations: 0 bytes)

70.72502598935759

julia> @btime mydotavx($a, $b)

19.365 ns (0 allocations: 0 bytes)

70.72502598935759

julia> a = rand(43); b = rand(43);

julia> @btime mydot($a, $b)

10.704 ns (0 allocations: 0 bytes)

10.22360436556094

julia> @btime mydotavx($a, $b)

7.602 ns (0 allocations: 0 bytes)

10.22360436556094

This is on an OS X iMac (Retina 5K, 27-inch, Late 2015)

1 Like

For simple loops like mydot, the main optimization is calculating the remainder faster than LLVM normally does.

On CPUs with the avx(2) instruction set, like your laptop, performance should be similar at multiples of 16. However, mydot will slow down more on average for each extra length you add. By the time length(a) % 16 == 15, mydot will probably be be a few nanoseconds slower than mydotavx.

1 Like