Tullio 0.3.3 fails in Julia 1.7.2

I have some Tullio 0.3.3.) code that works in 1.7.1 but not 1.7.2. I get a fairly large error message which I attach at the bottom. Before I try to produce a MWE I was wondering if someone knows something already. Thanks.
–shiv–

ERROR: MethodError: no method matching vconvert(::Type{VectorizationBase.VecUnroll{N, 16, Float32, VectorizationBase.Vec{16, Float32}} where N}, ::VectorizationBase.VecUnroll{7, 16, Float32, VectorizationBase.Vec{16, Float32}}) Closest candidates are: vconvert(::Type{VectorizationBase.VecUnroll{N, W, T, V}}, ::VectorizationBase.VecUnroll{N, W, T} where {W, T}) where {N, W, T, V} at C:\Users\00shi.julia\packages\VectorizationBase\yDGcX\src\llvm_intrin\conversion.jl:137 vconvert(::Type{VectorizationBase.VecUnroll{N, W, T, V}}, ::VectorizationBase.VecUnroll{N, W, T, V}) where {N, W, T, V} at C:\Users\00shi.julia\packages\VectorizationBase\yDGcX\src\llvm_intrin\conversion.jl:140 vconvert(::Type{V}, ::VectorizationBase.VecUnroll{N, W, T, V}) where {N, W, T, V<:VectorizationBase.AbstractSIMDVector} at C:\Users\00shi.julia\packages\VectorizationBase\yDGcX\src\llvm_intrin\conversion.jl:107 … Stacktrace: [1] convert @ C:\Users\00shi.julia\packages\VectorizationBase\yDGcX\src\base_defs.jl:154 [inlined] [2] _promote @ .\promotion.jl:327 [inlined] [3] promote @ .\promotion.jl:350 [inlined] [4] add_fast @ C:\Users\00shi.julia\packages\VectorizationBase\yDGcX\src\base_defs.jl:88 [inlined] [5] macro expansion @ C:\Users\00shi.julia\packages\LoopVectorization\ndGJi\src\reconstruct_loopset.jl:713 [inlined] [6] turbo!(::Val{(false, 0, 0, 0, false, 16, 64, 32, 64, 49152, 1310720, 12582912, 0x0000000000000001)}, ::Val{(Symbol("##DROPPED#CONSTANT##"), Symbol("##DROPPED#CONSTANT##"), LoopVectorization.OperationStruct(0x00000000000000000000000000000000, 0x00000000000000000000000000000000, 0x00000000000000000000000000000000, 0x00000000000000000000000000000000, 0x00000000000000000000000000000000, LoopVectorization.constant, 0x0001, 0x00), Symbol("##GLOBAL##CONSTANT##"), :nothing, LoopVectorization.OperationStruct(0x00000000000000000000000000000000, 0x00000000000000000000000000000000, 0x00000000000000000000000000000000, 0x00000000000000000000000000000000, 0x00000000000000000000000000000000, LoopVectorization.constant, 0x0002, 0x00), Symbol("##DROPPED#CONSTANT##"), Symbol("##DROPPED#CONSTANT##"), LoopVectorization.OperationStruct(0x00000000000000000000000000000000, 0x00000000000000000000000000000000, 0x00000000000000000000000000000000, 0x00000000000000000000000000000000, 0x00000000000000000000000000000000, LoopVectorization.constant, 0x0003, 0x00), :numericconstant, Symbol("###zero###8###"), LoopVectorization.OperationStruct(0x00000000000000000000000000000001, 0x00000000000000000000000000000000, 0x00000000000000000000000000000000, 0x00000000000000000000000000000000, 0x00000000000000000000000000000000, LoopVectorization.constant, 0x0004, 0x00), :LoopVectorization, :conditionalload, LoopVectorization.OperationStruct(0x00000000000000000000000000000001, 0x00000000000000000000000000000000, 0x00000000000000000000000000000000, 0x00000000000000000000000000000006, 0x00000000000000000000000000000000, LoopVectorization.memload, 0x0005, 0x01), :LoopVectorization, :LOOPCONSTANTINSTRUCTION, LoopVectorization.OperationStruct(0x00000000000000000000000000000000, 0x00000000000000000000000000000000, 0x00000000000000000000000000000000, 0x00000000000000000000000000000000, 0x00000000000000000000000000000000, LoopVectorization.constant, 0x0006, 0x00), :LoopVectorization, :getindex, LoopVectorization.OperationStruct(0x00000000000000000000000000000654, 0x00000000000000000000000000000000, 0x00000000000000000000000000000000, 0x00000000000000000000000000000000, 0x00000000000000000000000000000000, LoopVectorization.memload, 0x0007, 0x02), :LoopVectorization, :getindex, LoopVectorization.OperationStruct(0x00000000000000000000000000654132, 0x00000000000000000000000000000000, 0x00000000000000000000000000000000, 0x00000000000000000000000000000000, 0x00000000000000000000000000000000, LoopVectorization.memload, 0x0008, 0x03), :LoopVectorization, :sub_fast, LoopVectorization.OperationStruct(0x00000000000000000000000000654132, 0x00000000000000000000000000000000, 0x00000000000000000000000000000000, 0x00000000000000000000000000070008, 0x00000000000000000000000000000000, LoopVectorization.compute, 0x0009, 0x00), :LoopVectorization, :abs, LoopVectorization.OperationStruct(0x00000000000000000000000000654132, 0x00000000000000000000000000000000, 0x00000000000000000000000000000000, 0x00000000000000000000000000000009, 0x00000000000000000000000000000000, LoopVectorization.compute, 0x000a, 0x00), :numericconstant, Symbol("###reduction##zero###41###"), LoopVectorization.OperationStruct(0x00000000000000000000000000000001, 0x00000000000000000000000000000000, 0x00000000000000000000000000065432, 0x00000000000000000000000000000000, 0x00000000000000000000000000000000, LoopVectorization.constant, 0x000b, 0x00), :LoopVectorization, :add_fast, LoopVectorization.OperationStruct(0x00000000000000000000000000654132, 0x00000000000000000000000000065432, 0x00000000000000000000000000000000, 0x000000000000000000000000000b000a, 0x00000000000000000000000000000000, LoopVectorization.compute, 0x000b, 0x00), :LoopVectorization, :reduced_add, LoopVectorization.OperationStruct(0x00000000000000000000000000000001, 0x00000000000000000000000000065432, 0x00000000000000000000000000000000, 0x000000000000000000000000000c0005, 0x00000000000000000000000000000000, LoopVectorization.compute, 0x0005, 0x00), :LoopVectorization, :setindex!, LoopVectorization.OperationStruct(0x00000000000000000000000000000001, 0x00000000000000000000000000065432, 0x00000000000000000000000000000000, 0x0000000000000000000000000000000d, 0x00000000000000000000000000000000, LoopVectorization.memstore, 0x000c, 0x01))}, ::Val{(LoopVectorization.ArrayRefStruct{:β„›, Symbol("##vptr##_β„›")}(0x00000000000000000000000000000001, 0x00000000000000000000000000000001, 0x00000000000000000000000000000000, 0x00000000000000000000000000000001), LoopVectorization.ArrayRefStruct{:tileij, Symbol("##vptr##_tileij")}(0x00000000000000000000000000010101, 0x00000000000000000000000000060504, 0x00000000000000000000000000000000, 0x00000000000000000000000000010101), LoopVectorization.ArrayRefStruct{:filtData, Symbol("##vptr##_filtData")}(0x00000000000000000000010101010101, 0x00000000000000000000060504010302, 0x00000000000000000000000000000000, 0x00000000000000000000010101010101))}, ::Val{(0, (), (1, 3, 6), (), (), ((4, LoopVectorization.IntOrFloat), (11, LoopVectorization.IntOrFloat)), ())}, ::Val{(:n, :j, :i, :ch, :s, :r)}, ::Val{Tuple{NTuple{6, ArrayInterface.OptionallyStaticUnitRange{Static.StaticInt{0}, Int64}}, Tuple{LayoutPointers.GroupedStridedPointers{Tuple{Ptr{Float32}, Ptr{Float32}, Ptr{Float32}}, (1, 1, 1), (0, 0, 0), ((1,), (1, 2, 3), (1, 2, 3, 4, 5, 6)), ((1,), (2, 3, 4), (5, 6, 7, 8, 9, 10)), Tuple{Static.StaticInt{4}, Static.StaticInt{4}, Int64, Int64, Static.StaticInt{4}, Int64, Int64, Int64, Int64, Int64}, NTuple{10, Static.StaticInt{0}}}, Bool}}}, ::Int64, ::Int64, ::Int64, ::Int64, ::Int64, ::Int64, ::Ptr{Float32}, ::Ptr{Float32}, ::Ptr{Float32}, ::Int64, ::Int64, ::Int64, ::Int64, ::Int64, ::Int64, ::Int64, ::Bool) @ LoopVectorization C:\Users\00shi.julia\packages\LoopVectorization\ndGJi\src\reconstruct_loopset.jl:713 [7] π’œπ’Έπ“‰! @ C:\Users\00shi.julia\packages\Tullio\u7Tk0\src\macro.jl:1094 [inlined] [8] tile_halves(fun!::Main.Tst.DownDraw.var"#π’œπ’Έπ“‰!#35" , ::Type{Array{Float32}}, As::Tuple{Vector{Float32}, Array{Float32, 3}, Array{Float32, 6}}, Is::Tuple{UnitRange{Int64}}, Js::NTuple{5, UnitRange{Int64}}, keep::Nothing, final::Bool) @ Tullio C:\Users\00shi.julia\packages\Tullio\u7Tk0\src\threads.jl:139 [9] tile_halves @ C:\Users\00shi.julia\packages\Tullio\u7Tk0\src\threads.jl:136 [inlined] [10] thread_halves(fun!::Main.Tst.DownDraw.var"#π’œπ’Έπ“‰!#35" , ::Type{Array{Float32}}, As::Tuple{Vector{Float32}, Array{Float32, 3}, Array{Float32, 6}}, Is::Tuple{UnitRange{Int64}}, Js::NTuple{5, UnitRange{Int64}}, threads::Int64, keep::Nothing) @ Tullio C:\Users\00shi.julia\packages\Tullio\u7Tk0\src\threads.jl:128 [11] thread_halves(fun!::Main.Tst.DownDraw.var"#π’œπ’Έπ“‰!#35" , ::Type{Array{Float32}}, As::Tuple{Vector{Float32}, Array{Float32, 3}, Array{Float32, 6}}, Is::Tuple{UnitRange{Int64}}, Js::NTuple{5, UnitRange{Int64}}, threads::Int64, keep::Nothing) (repeats 2 times) @ Tullio C:\Users\00shi.julia\packages\Tullio\u7Tk0\src\threads.jl:125 [12] threader @ C:\Users\00shi.julia\packages\Tullio\u7Tk0\src\threads.jl:63 [inlined]

The following search doesn’t show any meaningful results (yet;).

VectorizationBase is part of LoopVectorization, it’s possible that @elrod can see what’s wrong from the stack trace? The versions of those two packages would also be useful.

From Tullio you can write avx=false to disable LoopVectorization, in case this helps work around it for now.

I should add that the offending line of code seems to be:
@tullio dists[n] := abs( img[r, s, ch] - data[r, s, ch, n, i, j] )
where i, j are for-loop variables that contain this statement.
Thanks.
–shiv–

LoopVectorization is at 0.12.101. I could not find a package called VectorizationBase.

ERROR: MethodError: no method matching vconvert(::Type{VectorizationBase.VecUnroll{N, 16, Float32, VectorizationBase.Vec{16, Float32}} where N}, ::VectorizationBase.VecUnroll{7, 16, Float32, VectorizationBase.Vec{16, Float32}}) Closest candidates are: 

Perhaps 1.7.2 is type unstable where 1.7.1 was type unstable, resulting in the generation of the call

vconvert(::Type{VectorizationBase.VecUnroll{N, 16, Float32, VectorizationBase.Vec{16, Float32}} where N}, ::VectorizationBase.VecUnroll{7, 16, Float32, VectorizationBase.Vec{16, Float32}}) 

instead of

vconvert(::Type{VectorizationBase.VecUnroll{7, 16, Float32, VectorizationBase.Vec{16, Float32}}}, ::VectorizationBase.VecUnroll{7, 16, Float32, VectorizationBase.Vec{16, Float32}}) 

But I’d need a reproducer.

Interesting. VectorizationBase was not installed on either of my machines even though both had LoopVectorization. I added VectorizationBase 0.21.24 but the code continues to fail. Actually it seems to fail on 1.7.1 but for different sizes of the array. I will try to come up with a MWE now.

I can reproduce this on a recent nightly, and check that it works fine on 1.7.0. With the code from @tullio verbose=2:

julia> using Tullio

julia> img = rand(Float32, 7,7,7); data = rand(Float32, 7,7,7,7,7,7);

julia> @tullio dists[n] := abs( img[r, s, ch] - data[r, s, ch, n, i, j] )
7-element Vector{Float32}:
 5559.8164
 5539.7
 5532.371
 5556.563
 5537.142
 5556.714
 5561.525

julia> using LoopVectorization

julia> @tullio dists[n] := abs( img[r, s, ch] - data[r, s, ch, n, i, j] )
ERROR: MethodError: no method matching vconvert(::Type{VectorizationBase.VecUnroll{N, 4, Float32, VectorizationBase.Vec{4, Float32}} where N}, ::VectorizationBase.VecUnroll{7, 4, Float32, VectorizationBase.Vec{4, Float32}})

julia> VERSION  # works fine on 1.7.0
v"1.8.0-DEV.1491"

julia> out = zeros(Float32, 7);

julia> function act!(β„›::AbstractArray{𝒯}, img, data, 𝒢𝓍n=1:7, 𝒢𝓍r=1:7, 𝒢𝓍s=1:7, 𝒢𝓍ch=1:7, 𝒢𝓍i=1:7, 𝒢𝓍j=1:7, ♻️ = nothing, πŸ’€ = true) where 𝒯
       LoopVectorization.@avx unroll = 0 for n = 𝒢𝓍n
               π’œπ’Έπ’Έ = if ♻️ === nothing
                       zero(𝒯)
                   else
                       β„›[n]
                   end
               for j = 𝒢𝓍j
                   for i = 𝒢𝓍i
                       for ch = 𝒢𝓍ch
                           for s = 𝒢𝓍s
                               for r = 𝒢𝓍r
                                   π’œπ’Έπ’Έ = π’œπ’Έπ’Έ + abs(img[r, s, ch] - data[r, s, ch, n, i, j])
                               end
                           end
                       end
                   end
               end
               β„›[n] = π’œπ’Έπ’Έ
           end
           β„›
       end
act! (generic function with 9 methods)

julia> act!(out, img, data)
ERROR: MethodError: no method matching vconvert(::Type{VectorizationBase.VecUnroll{N, 4, Float32, VectorizationBase.Vec{4, Float32}} where N}, ::VectorizationBase.VecUnroll{7, 4, Float32, VectorizationBase.Vec{4, Float32}})
1 Like

For me i and j were fixed variables set inside an outer for loop:
for j=1:10, i=1:10
@tullio dists[n] := abs( img[r, s, ch] - data[r, s, ch, n, i, j] )
…
end
I still need to produce a MWE…

If you want it to look for i, j from outside, not regard them as its own loop variables, you need to add a dollar sign. This appears to avoid the above problem:

julia> res = 0.0;

julia> for j=1:7, i=1:7
       @tullio dists[n] := abs( img[r, s, ch] - data[r, s, ch, n, $i, $j] )
       res += sum(dists)
       end
       res
38843.843200683594

So this does not crash but it does seem to produce a bug when it runs. Note that each iteration of the for loop should print a different random number, but in 1.7.2 it produces the same constant number for me:

using Tullio
img = randn( Float32, 10, 10, 3 )
data = randn( Float32, 10, 10, 3, 100, 20, 20 )
for j = 1:10, 1 = 1:10
  @tullio dists[n] := abs( img[r, s, ch] - data[r, s, ch, n, i, j] )
  println( minimum( dists ) )
end

Thanks. Let me try that.

Putting $i, $j rather than i, j seems to fix the crash. But I guess now the crash itself remains a mystery!
Thanks for all the help!