timholy / SnoopCompile.jl

Provide insights about latency (TTFX) for Julia packages
https://timholy.github.io/SnoopCompile.jl/dev/
Other
309 stars 48 forks source link

`invalidation_trees` AssertionError: leaf !== nothing #315

Closed roflmaostc closed 1 year ago

roflmaostc commented 1 year ago

Hi,

not quite sure, what's going wrong but while testing this, I encountered this:

(@v1.8) pkg> st
Status `~/.julia/environments/v1.8/Project.toml`
  [7073ff75] IJulia v1.23.3
  [5fb14364] OhMyREPL v0.5.12
⌃ [c3e4b0f8] Pluto v0.19.15
  [295af30f] Revise v3.4.0
  [aa65fe97] SnoopCompile v2.9.5
  [e2b509da] SnoopCompileCore v2.9.0
⌅ [1e6cf692] TestEnv v1.8.0

(@v1.8) pkg> activate .
  Activating project at `~/.julia/dev/FourierTools.jl`

julia> using SnoopCompileCore

julia> invalidations = @snoopr begin
           # package loads and/or method definitions that might invalidate other code
           using FourierTools
       end
1246-element Vector{Any}:
  MethodInstance for similar(::Type{Array{Union{Int64, Symbol}, _A}}, ::Tuple{Union{Integer, Base.OneTo}}) where _A
 0
  MethodInstance for similar(::Type{Array{Union{Int64, Symbol}, _A}}, ::Tuple{Union{Integer, Base.OneTo}}) where _A
 1
  MethodInstance for similar(::Type{Array{Union{Int64, Symbol}, _A}}, ::Union{Integer, AbstractUnitRange}) where _A
 1
  MethodInstance for Base._array_for(::Type{Union{Int64, Symbol}}, ::Base.HasShape, ::Any)
 2
 u MethodInstance for Base._collect(::Type{Union{Int64, Symbol}}, ::Base.Generator{_A, typeof(identity)} where _A, ::Union{Base.HasLength, Base.HasShape})
 3
  MethodInstance for collect(::Type{Union{Int64, Symbol}}, ::Base.Generator{_A, typeof(identity)} where _A)
 4
  MethodInstance for Base.vectorfilter(::Type{Union{Int64, Symbol}}, ::Base.var"#132#133"{typeof(in), typeof(pop!)}, ::Vector{Union{Int64, Symbol}})
 5
  MethodInstance for Base._shrink(::Function, ::Vector{Union{Int64, Symbol}}, ::Tuple{Vector{Symbol}})
 6
  MethodInstance for intersect(::Vector{Union{Int64, Symbol}}, ::Vector{Symbol})
 7
  MethodInstance for setdiff(::Vector{Union{Int64, Symbol}}, ::Vector{Symbol})
 7
  Tuple{typeof(similar), Type{Array{Union{Int64, Symbol}, _A}} where _A, Tuple{Union{Integer, AbstractUnitRange}}}
 ⋮
 3
  MethodInstance for (::FourierTools.var"#ft_fix_after##kw")(::NamedTuple{(:start_dim,), Tuple{Int64}}, ::typeof(ft_fix_after), ::PaddedViews.PaddedView{ComplexF32, 2, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}}, OffsetArrays.OffsetMatrix{ComplexF32, ShiftedArrays.CircShiftedArray{ComplexF32, 2, Matrix{ComplexF32}}}}, ::Tuple{Int64, Int64}, ::Tuple{Int64, Int64})
 4
  MethodInstance for FourierTools.rft_fix_after(::PaddedViews.PaddedView{ComplexF32, 2, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}}, OffsetArrays.OffsetMatrix{ComplexF32, ShiftedArrays.CircShiftedArray{ComplexF32, 2, Matrix{ComplexF32}}}}, ::Tuple{Int64, Int64}, ::Tuple{Int64, Int64})
 5
  MethodInstance for FourierTools.var"#ft_fix_after#40"(::Int64, ::typeof(ft_fix_after), ::FourierTools.FourierSplit{ComplexF32, 2, PaddedViews.PaddedView{ComplexF32, 2, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}}, OffsetArrays.OffsetMatrix{ComplexF32, FourierTools.FourierJoin{ComplexF32, 2, FourierTools.FourierJoin{ComplexF32, 2, ShiftedArrays.CircShiftedArray{ComplexF32, 2, Matrix{ComplexF32}}}}}}}, ::Tuple{Int64, Int64}, ::Tuple{Int64, Int64})
 3
  MethodInstance for (::FourierTools.var"#ft_fix_after##kw")(::NamedTuple{(:start_dim,), Tuple{Int64}}, ::typeof(ft_fix_after), ::FourierTools.FourierSplit{ComplexF32, 2, PaddedViews.PaddedView{ComplexF32, 2, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}}, OffsetArrays.OffsetMatrix{ComplexF32, FourierTools.FourierJoin{ComplexF32, 2, FourierTools.FourierJoin{ComplexF32, 2, ShiftedArrays.CircShiftedArray{ComplexF32, 2, Matrix{ComplexF32}}}}}}}, ::Tuple{Int64, Int64}, ::Tuple{Int64, Int64})
 4
  MethodInstance for FourierTools.rft_fix_after(::PaddedViews.PaddedView{ComplexF32, 2, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}}, OffsetArrays.OffsetMatrix{ComplexF32, FourierTools.FourierJoin{ComplexF32, 2, FourierTools.FourierJoin{ComplexF32, 2, ShiftedArrays.CircShiftedArray{ComplexF32, 2, Matrix{ComplexF32}}}}}}, ::Tuple{Int64, Int64}, ::Tuple{Int64, Int64})
 5
  MethodInstance for FourierTools.var"#ft_fix_after#40"(::Int64, ::typeof(ft_fix_after), ::PaddedViews.PaddedView{ComplexF32, 2, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}}, OffsetArrays.OffsetMatrix{ComplexF32, FourierTools.FourierJoin{ComplexF32, 2, FourierTools.FourierJoin{ComplexF32, 2, ShiftedArrays.CircShiftedArray{ComplexF32, 2, Matrix{ComplexF32}}}}}}, ::Tuple{Int64, Int64}, ::Tuple{Int64, Int64})
 3
  MethodInstance for (::FourierTools.var"#ft_fix_after##kw")(::NamedTuple{(:start_dim,), Tuple{Int64}}, ::typeof(ft_fix_after), ::PaddedViews.PaddedView{ComplexF32, 2, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}}, OffsetArrays.OffsetMatrix{ComplexF32, FourierTools.FourierJoin{ComplexF32, 2, FourierTools.FourierJoin{ComplexF32, 2, ShiftedArrays.CircShiftedArray{ComplexF32, 2, Matrix{ComplexF32}}}}}}, ::Tuple{Int64, Int64}, ::Tuple{Int64, Int64})
 4
  MethodInstance for FourierTools.rft_fix_after(::PaddedViews.PaddedView{ComplexF32, 2, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}}, OffsetArrays.OffsetMatrix{ComplexF32, FourierTools.FourierJoin{ComplexF32, 2, FourierTools.FourierJoin{ComplexF32, 2, ShiftedArrays.CircShiftedArray{ComplexF32, 2, Matrix{ComplexF32}}}}}}, ::Tuple{Int64, Int64}, ::Tuple{Int64, Int64})
 5
  MethodInstance for convert(::Type{T}, ::T) where T<:(FourierTools.FourierSplit{ComplexF32, 2} where {T, N})
  "jl_insert_method_instance"
  convert(::Type{T}, a::T) where T<:AbstractArray in Base at abstractarray.jl:16
  "jl_method_table_insert"

julia> using SnoopCompile

julia> trees = invalidation_trees(invalidations)
ERROR: AssertionError: leaf !== nothing
Stacktrace:
 [1] invalidation_trees(list::Vector{Any}; exclude_corecompiler::Bool)
   @ SnoopCompile ~/.julia/packages/SnoopCompile/Q8zUg/src/invalidations.jl:365
 [2] invalidation_trees(list::Vector{Any})
   @ SnoopCompile ~/.julia/packages/SnoopCompile/Q8zUg/src/invalidations.jl:294
 [3] top-level scope
   @ REPL[5]:1

julia> versioninfo()
Julia Version 1.8.3
Commit 0434deb161e (2022-11-14 20:14 UTC)
Platform Info:
  OS: Linux (x86_64-linux-gnu)
  CPU: 12 × AMD Ryzen 5 5600X 6-Core Processor
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-13.0.1 (ORCJIT, znver3)
  Threads: 12 on 12 virtual cores
Environment:
  JULIA_NUM_THREADS = 12

Is it my fault somewhere?

Thanks!

Felix

MilesCranmer commented 1 year ago

Got this too, for DynamicExpressions.jl (I'm also on 1.8.3 Julia; though on a mac M1 rather than linux)

using SnoopCompile

invalidations = @snoopr begin
    using DynamicExpressions
end;

trees = SnoopCompile.invalidation_trees(invalidations)

Output:

ERROR: AssertionError: leaf !== nothing
Stacktrace:
 [1] invalidation_trees(list::Vector{Any}; exclude_corecompiler::Bool)
   @ SnoopCompile ~/.julia/packages/SnoopCompile/Q8zUg/src/invalidations.jl:365
 [2] invalidation_trees(list::Vector{Any})
   @ SnoopCompile ~/.julia/packages/SnoopCompile/Q8zUg/src/invalidations.jl:294
 [3] top-level scope
   @ REPL[11]:1
MilesCranmer commented 1 year ago

Tried SnoopCompile 2.8.1, and get this instead:

ERROR: unexpected loctag jl_insert_method_instance at 20156
Stacktrace:
 [1] error(::String, ::String, ::String, ::Int64)
   @ Base ./error.jl:44
 [2] invalidation_trees(list::Vector{Any}; exclude_corecompiler::Bool)
   @ SnoopCompile ~/.julia/packages/SnoopCompile/wiBT1/src/invalidations.jl:373
 [3] invalidation_trees(list::Vector{Any})
   @ SnoopCompile ~/.julia/packages/SnoopCompile/wiBT1/src/invalidations.jl:287
 [4] top-level scope
   @ REPL[3]:1
MilesCranmer commented 1 year ago

I just realized this issue is a duplicate of #302 FYI

MilesCranmer commented 1 year ago

Looks like #302 was solved in https://github.com/SciML/ModelingToolkit.jl/pull/1821 somehow... @ChrisRackauckas @YingboMa @lamorton how did you end up solving it? Sounds like it is known to show up on at least FourierTools.jl, ModelingToolkit.jl, and DynamicExpressions.jl.

lamorton commented 1 year ago

@MilesCranmer not sure we did anything different. Like I said, it was intermittent, so could still be lurking.

MilesCranmer commented 1 year ago

By intermittent, do you mean it randomly appears sometimes if you re-run the exact same code on same OS/dependencies/etc, or do you mean it shows up for certain combinations of dependencies?

lamorton commented 1 year ago

@MilesCranmer I wasn't able to reproduce it on my machine, and on Github it came and went between runs. IDK if the maintainers made any changes on the GH Actions.

MilesCranmer commented 1 year ago

Thanks! Very weird bug.

Luckily these ones FourierTools.jl and DynamicExpressions.jl seem to be locally reproducible, so maybe the bug can finally be tracked down.

roflmaostc commented 1 year ago

In my case it seemed to be reproducible, the couple of times I checked it.

ChrisRackauckas commented 1 year ago

I never knew that existed so any fix was accidental.

JordiManyer commented 1 year ago

I'm having the same issue while tracking invalidations for Gridap.jl. Any progress on what might be going on?

timholy commented 1 year ago

Not reproducible for me on SnoopCompile 2.9.7 and either Julia 1.8.4 or nightly. Can you still reproduce it?

This package has had many changes and so has Julia. It's worth nothing that 1.8.4 backported some changes from 1.9 in how it handles and logs invalidations, so it's quite possible this is what fixed the bug.

Let me know if you can reproduce this, otherwise I will close.

MilesCranmer commented 1 year ago

Thanks @timholy. I can report that my issue on DynamicExpressions.jl went away on Julia 1.9.0-beta2 with SnoopCompile 2.9.7! Everything works smoothly now 🎉

JordiManyer commented 1 year ago

Thanks @timholy. The issue has also been resolved on Gridap.jl using SnoopCompile 2.9.7 and Julia 1.8.5. Thanks to everybody who has been contributing to this!

timholy commented 1 year ago

Thanks for the feedback!