JuliaDebug / Cthulhu.jl

The slow descent into madness
MIT License
657 stars 41 forks source link

Internal `AssertionError: label > 0` when descending a method call #523

Closed MilesCranmer closed 8 months ago

MilesCranmer commented 10 months ago

I'm seeing this weird internal assertion error when inspecting one of my method calls. Here is the current MWE. I'm setting up a search problem in SymbolicRegression and trying to descend the main search method:

julia> using Cthulhu

julia> using SymbolicRegression

julia> X = rand(2, 1000) .* 30;

julia> y = @. sin(X[1, :]) + 1.5;

julia> options = Options(; binary_operators=[+, -, *, /, mod], unary_operators=[]);

julia> @descend equation_search(X, y; options)

This triggers the following error:

julia> @descend equation_search(X, y; options)
ERROR: AssertionError: label > 0
Stacktrace:
   [1] 
     @ Core.Compiler ./compiler/ssair/ir.jl:1321
   [2] cfg_simplify!(ir::Core.Compiler.IRCode)
     @ Core.Compiler ./compiler/ssair/passes.jl:2220
   [3] create_cthulhu_source
     @ Cthulhu ~/.julia/packages/Cthulhu/O1Xhq/src/interpreter.jl:158 [inlined]
   [4] transform_result_for_cache
     @ Cthulhu ~/.julia/packages/Cthulhu/O1Xhq/src/interpreter.jl:164 [inlined]
   [5] cache_result!(interp::Cthulhu.CthulhuInterpreter, result::Core.Compiler.InferenceResult)
     @ Core.Compiler ./compiler/typeinfer.jl:405
   [6] _typeinf(interp::Cthulhu.CthulhuInterpreter, frame::Core.Compiler.InferenceState)
     @ Core.Compiler ./compiler/typeinfer.jl:283
   [7] typeinf(interp::Cthulhu.CthulhuInterpreter, frame::Core.Compiler.InferenceState)
     @ Core.Compiler ./compiler/typeinfer.jl:219
   [8] 
     @ Core.Compiler ./compiler/typeinfer.jl:930
   [9] 
     @ Core.Compiler ./compiler/abstractinterpretation.jl:629
  [10] 
     @ Core.Compiler ./compiler/abstractinterpretation.jl:95
  [11] 
     @ Core.Compiler ./compiler/abstractinterpretation.jl:2083
  [12] 
     @ Core.Compiler ./compiler/abstractinterpretation.jl:2165
  [13] 
     @ Core.Compiler ./compiler/abstractinterpretation.jl:2158
  [14] abstract_call(interp::Cthulhu.CthulhuInterpreter, arginfo::Core.Compiler.ArgInfo, sv::Core.Compiler.InferenceState)
     @ Core.Compiler ./compiler/abstractinterpretation.jl:2350
  [15] abstract_eval_call(interp::Cthulhu.CthulhuInterpreter, e::Expr, vtypes::Vector{…}, sv::Core.Compiler.InferenceState)
     @ Core.Compiler ./compiler/abstractinterpretation.jl:2366
  [16] abstract_eval_statement_expr(interp::Cthulhu.CthulhuInterpreter, e::Expr, vtypes::Vector{…}, sv::Core.Compiler.InferenceState)
     @ Core.Compiler ./compiler/abstractinterpretation.jl:2376
  [17] abstract_eval_statement(interp::Cthulhu.CthulhuInterpreter, e::Any, vtypes::Vector{…}, sv::Core.Compiler.InferenceState)
     @ Core.Compiler ./compiler/abstractinterpretation.jl:2620
  [18] abstract_eval_basic_statement(interp::Cthulhu.CthulhuInterpreter, stmt::Any, pc_vartable::Vector{…}, frame::Core.Compiler.InferenceState)
     @ Core.Compiler ./compiler/abstractinterpretation.jl:2909
  [19] typeinf_local(interp::Cthulhu.CthulhuInterpreter, frame::Core.Compiler.InferenceState)
     @ Core.Compiler ./compiler/abstractinterpretation.jl:3094
  [20] typeinf_nocycle(interp::Cthulhu.CthulhuInterpreter, frame::Core.Compiler.InferenceState)
     @ Core.Compiler ./compiler/abstractinterpretation.jl:3182
  [21] _typeinf(interp::Cthulhu.CthulhuInterpreter, frame::Core.Compiler.InferenceState)
     @ Core.Compiler ./compiler/typeinfer.jl:247
--- the last 15 lines are repeated 8 more times ---
 [142] typeinf
     @ Core.Compiler ./compiler/typeinfer.jl:219 [inlined]
 [143] do_typeinf!(interp::Cthulhu.CthulhuInterpreter, mi::Core.MethodInstance)
     @ Cthulhu ~/.julia/packages/Cthulhu/O1Xhq/src/Cthulhu.jl:730
 [144] mkinterp(interp::Core.Compiler.NativeInterpreter, args::Any)
     @ Cthulhu ~/.julia/packages/Cthulhu/O1Xhq/src/Cthulhu.jl:742
 [145] _descend(term::REPL.Terminals.TTYTerminal, args::Any; interp::Core.Compiler.NativeInterpreter, kwargs::@Kwargs{…})
     @ Cthulhu ~/.julia/packages/Cthulhu/O1Xhq/src/Cthulhu.jl:764
 [146] __descend_with_error_handling(args::Any; terminal::Any, kwargs...)
     @ Cthulhu ~/.julia/packages/Cthulhu/O1Xhq/src/Cthulhu.jl:213
 [147] _descend_with_error_handling(f::Any, argtypes::Any; kwargs::@Kwargs{iswarn::Bool})
     @ Cthulhu ~/.julia/packages/Cthulhu/O1Xhq/src/Cthulhu.jl:202
 [148] descend_code_typed(::Any, ::Vararg{Any}; kwargs::@Kwargs{})
     @ Cthulhu ~/.julia/packages/Cthulhu/O1Xhq/src/Cthulhu.jl:160
 [149] macro expansion
     @ ~/.julia/juliaup/julia-1.10.0-rc3+0.aarch64.apple.darwin14/share/julia/stdlib/v1.10/InteractiveUtils/src/macros.jl:100 [inlined]
Some type information was truncated. Use `show(err)` to see complete types.

The function runs just fine, and I can also use @code_warntype just fine:

julia> @code_warntype equation_search(X, y; options)
MethodInstance for Core.kwcall(::@NamedTuple{options::Options{Int64, DynamicExpressions.OperatorEnumModule.OperatorEnum, false, Optim.Options{Float64, Nothing}, StatsBase.Weights{Float64, Float64, Vector{Float64}}}}, ::typeof(equation_search), ::Matrix{Float64}, ::Vector{Float64})
  from kwcall(::NamedTuple, ::typeof(equation_search), X::AbstractMatrix{T1}, y::AbstractVector{T2}) where {T1<:Number, T2<:Number} @ SymbolicRegression ~/PermaDocuments/SymbolicRegression.jl/src/SymbolicRegression.jl:414
Static Parameters
  T1 = Float64
  T2 = Float64
Arguments
  _::Core.Const(Core.kwcall)
  @_2::@NamedTuple{options::Options{Int64, DynamicExpressions.OperatorEnumModule.OperatorEnum, false, Optim.Options{Float64, Nothing}, StatsBase.Weights{Float64, Float64, Vector{Float64}}}}
  @_3::Core.Const(SymbolicRegression.equation_search)
  X::Matrix{Float64}
  y::Vector{Float64}
Locals
  kw...::Base.Pairs{Symbol, Options{Int64, DynamicExpressions.OperatorEnumModule.OperatorEnum, false, Optim.Options{Float64, Nothing}, StatsBase.Weights{Float64, Float64, Vector{Float64}}}, Tuple{Symbol}, @NamedTuple{options::Options{Int64, DynamicExpressions.OperatorEnumModule.OperatorEnum, false, Optim.Options{Float64, Nothing}, StatsBase.Weights{Float64, Float64, Vector{Float64}}}}}
Body::Any
1 ─      (kw... = Base.pairs(@_2))
│   %2 = SymbolicRegression.:(var"#equation_search#26")(kw...::Core.PartialStruct(Base.Pairs{Symbol, Options{Int64, DynamicExpressions.OperatorEnumModule.OperatorEnum, false, Optim.Options{Float64, Nothing}, StatsBase.Weights{Float64, Float64, Vector{Float64}}}, Tuple{Symbol}, @NamedTuple{options::Options{Int64, DynamicExpressions.OperatorEnumModule.OperatorEnum, false, Optim.Options{Float64, Nothing}, StatsBase.Weights{Float64, Float64, Vector{Float64}}}}}, Any[@NamedTuple{options::Options{Int64, DynamicExpressions.OperatorEnumModule.OperatorEnum, false, Optim.Options{Float64, Nothing}, StatsBase.Weights{Float64, Float64, Vector{Float64}}}}, Core.Const((:options,))]), @_3, X, y)::Any
└──      return %2

Other relevant info:

julia> versioninfo()
Julia Version 1.10.0-rc3
Commit ed79752b939 (2023-12-18 09:57 UTC)
Build Info:
  Official https://julialang.org/ release
Platform Info:
  OS: macOS (arm64-apple-darwin22.4.0)
  CPU: 8 × Apple M1 Pro
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-15.0.7 (ORCJIT, apple-m1)
  Threads: 8 on 6 virtual cores
Environment:
  JULIA_FORMATTER_SO = /Users/mcranmer/julia_formatter.so
  JULIA_NUM_THREADS = auto
  JULIA_EDITOR = code

When I test this on Julia 1.9.4, I get the same error, but with a different backtrace:

julia> @descend equation_search(X, y; options)
ERROR: AssertionError: label > 0
Stacktrace:
   [1] process_node!(compact::Core.Compiler.IncrementalCompact, result_idx::Int64, inst::Core.Compiler.Instruction, idx::Int64, processed_idx::Int64, active_bb::Int64, do_rename_ssa::Bool)
     @ Core.Compiler ./compiler/ssair/ir.jl:1281
   [2] cfg_simplify!(ir::Core.Compiler.IRCode)
     @ Core.Compiler ./compiler/ssair/passes.jl:2237
   [3] create_cthulhu_source
     @ ~/.julia/packages/Cthulhu/O1Xhq/src/interpreter.jl:158 [inlined]
   [4] transform_result_for_cache
     @ ~/.julia/packages/Cthulhu/O1Xhq/src/interpreter.jl:164 [inlined]
   [5] cache_result!(interp::Cthulhu.CthulhuInterpreter, result::Core.Compiler.InferenceResult)
     @ Core.Compiler ./compiler/typeinfer.jl:403
   [6] _typeinf(interp::Cthulhu.CthulhuInterpreter, frame::Core.Compiler.InferenceState)
     @ Core.Compiler ./compiler/typeinfer.jl:293
   [7] typeinf(interp::Cthulhu.CthulhuInterpreter, frame::Core.Compiler.InferenceState)
     @ Core.Compiler ./compiler/typeinfer.jl:219
   [8] typeinf_edge(interp::Cthulhu.CthulhuInterpreter, method::Method, atype::Any, sparams::Core.SimpleVector, caller::Core.Compiler.InferenceState)
     @ Core.Compiler ./compiler/typeinfer.jl:932
   [9] abstract_call_method(interp::Cthulhu.CthulhuInterpreter, method::Method, sig::Any, sparams::Core.SimpleVector, hardlimit::Bool, si::Core.Compiler.StmtInfo, sv::Core.Compiler.InferenceState)
     @ Core.Compiler ./compiler/abstractinterpretation.jl:611
  [10] abstract_call_gf_by_type(interp::Cthulhu.CthulhuInterpreter, f::Any, arginfo::Core.Compiler.ArgInfo, si::Core.Compiler.StmtInfo, atype::Any, sv::Core.Compiler.InferenceState, max_methods::Int64)
     @ Core.Compiler ./compiler/abstractinterpretation.jl:152
  [11] abstract_call_known(interp::Cthulhu.CthulhuInterpreter, f::Any, arginfo::Core.Compiler.ArgInfo, si::Core.Compiler.StmtInfo, sv::Core.Compiler.InferenceState, max_methods::Int64)
     @ Core.Compiler ./compiler/abstractinterpretation.jl:1949
  [12] abstract_call(interp::Cthulhu.CthulhuInterpreter, arginfo::Core.Compiler.ArgInfo, si::Core.Compiler.StmtInfo, sv::Core.Compiler.InferenceState, max_methods::Nothing)
     @ Core.Compiler ./compiler/abstractinterpretation.jl:2020
  [13] abstract_call(interp::Cthulhu.CthulhuInterpreter, arginfo::Core.Compiler.ArgInfo, si::Core.Compiler.StmtInfo, sv::Core.Compiler.InferenceState)
     @ Core.Compiler ./compiler/abstractinterpretation.jl:1999
  [14] abstract_eval_statement_expr(interp::Cthulhu.CthulhuInterpreter, e::Expr, vtypes::Vector{Core.Compiler.VarState}, sv::Core.Compiler.InferenceState, mi::Nothing)
     @ Core.Compiler ./compiler/abstractinterpretation.jl:2183
  [15] abstract_eval_statement(interp::Cthulhu.CthulhuInterpreter, e::Any, vtypes::Vector{Core.Compiler.VarState}, sv::Core.Compiler.InferenceState)
     @ Core.Compiler ./compiler/abstractinterpretation.jl:2396
  [16] abstract_eval_basic_statement(interp::Cthulhu.CthulhuInterpreter, stmt::Any, pc_vartable::Vector{Core.Compiler.VarState}, frame::Core.Compiler.InferenceState)
     @ Core.Compiler ./compiler/abstractinterpretation.jl:2682
  [17] typeinf_local(interp::Cthulhu.CthulhuInterpreter, frame::Core.Compiler.InferenceState)
     @ Core.Compiler ./compiler/abstractinterpretation.jl:2867
  [18] typeinf_nocycle(interp::Cthulhu.CthulhuInterpreter, frame::Core.Compiler.InferenceState)
     @ Core.Compiler ./compiler/abstractinterpretation.jl:2955
  [19] _typeinf(interp::Cthulhu.CthulhuInterpreter, frame::Core.Compiler.InferenceState)
     @ Core.Compiler ./compiler/typeinfer.jl:246
--- the last 13 lines are repeated 8 more times ---
 [124] typeinf(interp::Cthulhu.CthulhuInterpreter, frame::Core.Compiler.InferenceState)
     @ Core.Compiler ./compiler/typeinfer.jl:219
 [125] do_typeinf!(interp::Cthulhu.CthulhuInterpreter, mi::Core.MethodInstance)
     @ Cthulhu ~/.julia/packages/Cthulhu/O1Xhq/src/Cthulhu.jl:730
 [126] mkinterp(::Core.Compiler.NativeInterpreter, ::Any, ::Vararg{Any})
     @ Cthulhu ~/.julia/packages/Cthulhu/O1Xhq/src/Cthulhu.jl:742
 [127] _descend(::REPL.Terminals.TTYTerminal, ::Any, ::Vararg{Any}; interp::Core.Compiler.NativeInterpreter, kwargs::Base.Pairs{Symbol, Bool, Tuple{Symbol}, NamedTuple{(:iswarn,), Tuple{Bool}}})
     @ Cthulhu ~/.julia/packages/Cthulhu/O1Xhq/src/Cthulhu.jl:764
 [128] __descend_with_error_handling(args::Any; terminal::Any, kwargs::Base.Pairs{Symbol, V, Tuple{Vararg{Symbol, N}}, NamedTuple{names, T}} where {V, N, names, T<:Tuple{Vararg{Any, N}}})
     @ Cthulhu ~/.julia/packages/Cthulhu/O1Xhq/src/Cthulhu.jl:213
 [129] _descend_with_error_handling(f::Any, argtypes::Any; kwargs::Base.Pairs{Symbol, Bool, Tuple{Symbol}, NamedTuple{(:iswarn,), Tuple{Bool}}})
     @ Cthulhu ~/.julia/packages/Cthulhu/O1Xhq/src/Cthulhu.jl:202
 [130] descend_code_typed(::Any, ::Vararg{Any}; kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
     @ Cthulhu ~/.julia/packages/Cthulhu/O1Xhq/src/Cthulhu.jl:160
 [131] descend_code_typed(::Any, ::Any)
     @ Cthulhu ~/.julia/packages/Cthulhu/O1Xhq/src/Cthulhu.jl:160

I'm not sure if it's relevant, but here is the method I'm trying to inspect:

https://github.com/MilesCranmer/SymbolicRegression.jl/blob/0becbf448201f933a8b097776ae57058e1837452/src/SymbolicRegression.jl#L335

of which the bulk of the code is from

https://github.com/MilesCranmer/SymbolicRegression.jl/blob/0becbf448201f933a8b097776ae57058e1837452/src/SymbolicRegression.jl#L563

(Maybe something jumps out at you from this.)

aviatesk commented 10 months ago

This particular error has been resolved in the latest master branch. The root cause was associated with the cfg_simplify! pass, currently utilized only by Cthulhu. This feature has had a history of bugs, though recent fixes have addressed these issues. Considering this, I'm contemplating whether to disable cfg_simplify! for Julia versions older than 1.10 in Cthulhu.

MilesCranmer commented 10 months ago

By latest master branch do you mean of Cthulhu or of Julia? I just tried the master branch of Cthulhu and seems to get the same error unfortunately (on Julia 1.10-rc3).

aviatesk commented 10 months ago

I meant the latest Julia itself.

MilesCranmer commented 10 months ago

I see, thanks!

ToucheSir commented 10 months ago

Is there a workaround for those of us currently on 1.10 stable? Cthulhu is basically my no. 1 debugging tool at this point, so not being able to use it is quite an impediment.

0x0f0f0f commented 10 months ago

Is there a workaround for those of us currently on 1.10 stable? Cthulhu is basically my no. 1 debugging tool at this point, so not being able to use it is quite an impediment.

up

MasonProtter commented 9 months ago

Maybe these bugfixes to cfgsimplify could be backported to v1.10? Or even pirated in by Cthulhu?

MilesCranmer commented 9 months ago

^I also think this is a good idea given Cthulhu is the only library even using it

MilesCranmer commented 8 months ago

@aviatesk This particular error has been resolved in the latest master branch.

And the master branch is currently incompatible with VSCode (just tried), so this unfortunately isn't even a solution if you do want to switch to a nightly version 😢

MilesCranmer commented 8 months ago

In the meantime I've made a workaround here: https://github.com/JuliaDebug/Cthulhu.jl/pull/546

If you just depend on that branch for now, all you need is some code in startup.jl and it seems to completely step around this issue on 1.10.

aviatesk commented 8 months ago

Will be fixed in 2.11.1.

0x0f0f0f commented 8 months ago

Will be fixed in 2.11.1.

Still having this issue in 2.11.1. Will post some details and MWE

aviatesk commented 8 months ago

Okay, please let me know if you make up a MWE.

aviatesk commented 7 months ago

This error should be (fully) fixed in 2.12.1 (hopefully).