Tullio.jl icon indicating copy to clipboard operation
Tullio.jl copied to clipboard

Warning: LoopVectorization failed, from `|> f(_)` finaliser

Open ParadaCarleton opened this issue 4 years ago • 10 comments

When trying to use Tullio with LoopVectorization, I get the following warning from verbose:

┌ Warning: LoopVectorization failed 
│   err =
│    LoadError: type Expr has no field value
│    in expression starting at /home/lime/.julia/packages/Tullio/IHd6P/src/macro.jl:1111
└ @ Tullio ~/.julia/packages/Tullio/IHd6P/src/macro.jl:1122

I'm not sure what this means, and I'm not sure whether this indicates a problem or not -- is this an indication that I should rewrite my code so that I can take advantage of LoopVectorization, or that the process doesn't need LoopVectorization and wouldn't benefit from using it? The full code can be viewed here.

ParadaCarleton avatar Jun 10 '21 19:06 ParadaCarleton

It means that LoopVectorization through an error while processing the macro. Sounds like it may've been code with getproperty.I'll take a look later.

chriselrod avatar Jun 10 '21 22:06 chriselrod

This is the problematic expression:

julia> @tullio grad=false ξHats[x] := log1p(- θHats[x] * sample[y]) |> (_ / n) verbose=2
...
│   verbosetidy(lex) =
│    quote
│        local @inline(function 𝒜𝒸𝓉!(::Type{<:Array{<:Union{Base.HWReal, Bool}}}, ℛ::AbstractArray{𝒯}, θHats, sample, 𝒶𝓍x, 𝒶𝓍y, ♻️ = nothing, 💀 = true) where 𝒯
│                    @info "running LoopVectorization actor " maxlog = 3 _id = 0x078e4a14a946c06b
│                    LoopVectorization.check_args(θHats, sample) || @error("rejected by LoopVectorization's check_args! ", maxlog = 3, _id = 0x078e4a14a946c06b)
│                    if 💀 === nothing
│                        LoopVectorization.@avx unroll = 0 for x = 𝒶𝓍x
│                                𝒜𝒸𝒸 = if ♻️ === nothing
│                                        zero(𝒯)
│                                    else
│                                        ℛ[x]
│                                    end
│                                for y = 𝒶𝓍y
│                                    𝒜𝒸𝒸 = 𝒜𝒸𝒸 + log1p(-(θHats[x]) * sample[y])
│                                end
│                                ℛ[x] = 𝒜𝒸𝒸
│                            end
│                    else
│                        LoopVectorization.@avx unroll = 0 for x = 𝒶𝓍x
│                                𝒜𝒸𝒸 = if ♻️ === nothing
│                                        zero(𝒯)
│                                    else
│                                        ℛ[x]
│                                    end
│                                for y = 𝒶𝓍y
│                                    𝒜𝒸𝒸 = 𝒜𝒸𝒸 + log1p(-(θHats[x]) * sample[y])
│                                end
│                                ℛ[x] = ((𝓇𝒽𝓈->begin
│                                            𝓇𝒽𝓈 / n
│                                        end))(𝒜𝒸𝒸)
│                            end
│                    end
│                end)
└    end
┌ Warning: LoopVectorization failed 
│   err =
│    LoadError: type Expr has no field value

I've been meaning to re-write how it handles finalisers |> (_ / n) for a while, but haven't got there, sorry! It should really write this expression directly into the generated code, rather than writing a function which is called.

mcabbott avatar Jun 11 '21 00:06 mcabbott

Note also that this is just @tullio ξHats[x] := log1p(- θHats[x] * sample[y]) / n. Dividing inside the loop or outside it gives the same result; you could invert invn = 1/n outside the loop, although I'm not sure it will matter much.

mcabbott avatar Jun 11 '21 02:06 mcabbott

I've been meaning to re-write how it handles finalisers |> (_ / n)

Ah, yeah, it doesn't like anonymous functions:

julia> LoopVectorization.@avx unroll = 0 for x = 𝒶𝓍x
           𝒜𝒸𝒸 = if ♻️ === nothing
               zero(𝒯)
           else
               ℛ[x]
           end
           for y = 𝒶𝓍y
               𝒜𝒸𝒸 = 𝒜𝒸𝒸 + log1p(-(θHats[x]) * sample[y])
           end
           ℛ[x] = ((𝓇𝒽𝓈->begin
           𝓇𝒽𝓈 / n
           end))(𝒜𝒸𝒸)
       end
x = :(Base.FastMath.sub_fast)
x = :(𝓇𝒽𝓈->begin
          #= REPL[14]:10 =#
          #= REPL[14]:11 =#
          𝓇𝒽𝓈 / n
      end)
ERROR: LoadError: type Expr has no field value
Stacktrace:
  [1] getproperty(x::Expr, f::Symbol)
    @ Base ./Base.jl:33
  [2] instruction!(ls::LoopVectorization.LoopSet, x::Expr)
    @ LoopVectorization ~/.julia/packages/LoopVectorization/kZV0n/src/modeling/graphs.jl:981
  [3] add_compute!(ls::LoopVectorization.LoopSet, var::Symbol, ex::Expr, elementbytes::Int64, position::Int64, mpref::LoopVectorization.ArrayReferenceMetaPosition)
    @ LoopVectorization ~/.julia/packages/LoopVectorization/kZV0n/src/parse/add_compute.jl:256
  [4] add_operation!(ls::LoopVectorization.LoopSet, LHS_sym::Symbol, RHS::Expr, LHS_ref::LoopVectorization.ArrayReferenceMetaPosition, elementbytes::Int64, position::Int64)
    @ LoopVectorization ~/.julia/packages/LoopVectorization/kZV0n/src/modeling/graphs.jl:1075

It doesn't like anonymous functions at the moment. One simple fix would be checking for x.head === :->, and if so taking the unknown-function route. A better solution would be to disassemble it and replace it with the code inside, but I'll do the simple solution for now. The problem with the simple solution is that it renders everything inside the anonymous function opaque to LV.

chriselrod avatar Jun 11 '21 09:06 chriselrod

Should be fixed by https://github.com/JuliaSIMD/LoopVectorization.jl/commit/a97368d10a8361f3bc8e6179247af6defdc8c24a

chriselrod avatar Jun 11 '21 09:06 chriselrod

@chriselrod Can you let me know when the fix is merged so I can close this?

ParadaCarleton avatar Jun 25 '21 17:06 ParadaCarleton

Should've been 14 days ago. So you should be able to close this now.

chriselrod avatar Jun 25 '21 17:06 chriselrod

You can also leave it open as a reminder to me, to make this generate less ugly code... if you like. I have not started, though.

mcabbott avatar Jun 25 '21 17:06 mcabbott

Ahh, I see -- I had a different bug (this one in my code) that generated a similar warning message, so I thought it was the same bug.

ParadaCarleton avatar Jun 25 '21 21:06 ParadaCarleton

Tullio is certainly a powerful tool for discovering LoopVectorization bugs :) If you have an example do make an issue... or if energetic you can find the loop in @tullio verbose=2 & make a LoopVectorization issue directly.

mcabbott avatar Jun 25 '21 21:06 mcabbott