JuliaDebug / JuliaDebug/Cthulhu.jl
`descend` results disagree with `code_typed`
Nobody has claimed this yet.
- Dominant language
- Julia
- Stars
- 709
- Forks
- 46
- Avg merge
- 1d 13h
- Merged PRs (30d)
- 2
Description
I apologize for this being an extremely non-minimal MWE.
I thought it was better to file something, even if it is a lot of dependencies.
To reproduce, use 1.12.0-rc1 with https://github.com/topolarity/NonlinearSolve.jl/commit/3a192c2f865ed012bd11e62b7857db08bccaa1a0
$ julia +1.12 --project=./NonlinearSolve.jl/test/trim -q
julia> include("./NonlinearSolve.jl/test/trim/optimization_once_per_process.jl")
julia> using Cthulhu
julia> using NonlinearSolveFirstOrder, OrdinaryDiffEqCore, LinearAlgebra, ADTypes, OrdinaryDiffEqNonlinearSolve, FiniteDiff, LinearSolve
julia> const DifferentiationInterfaceFiniteDiffExt = Base.loaded_modules_array()[findfirst((m)->nameof(m) === :DifferentiationInterfaceFiniteDiffExt, Base.loaded_modules_array())]
julia> CacheType = NonlinearSolveFirstOrder.GeneralizedFirstOrderAlgorithmCache{Vector{Float64}, Vector{Float64}, Vector{Float64}, Tuple{Vector{Float64}, Vector{Float64}, Float64, Float64, Float64, Vector{Float64}, Float64, OrdinaryDiffEqCore.MethodType, SciMLBase.NullParameters, Float64, SciMLBase.ODEFunction{true, SciMLBase.FullSpecialize, typeof(Main.TestModuleTrimmable.lorenz), UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing, Nothing, Nothing}}, Vector{Float64}, Matrix{Float64}, NonlinearSolveFirstOrder.GeneralizedFirstOrderAlgorithm{Missing, Missing, NonlinearSolveBase.NewtonDescent{Nothing}, ADTypes.AutoFiniteDiff{Val{:forward}, Val{:forward}, Val{:hcentral}, Nothing, Nothing, Bool}, ADTypes.AutoFiniteDiff{Val{:forward}, Val{:forward}, Val{:hcentral}, Nothing, Nothing, Bool}, ADTypes.AutoFiniteDiff{Val{:forward}, Val{:forward}, Val{:hcentral}, Nothing, Nothing, Bool}, Val{false}}, SciMLBase.NonlinearProblem{Vector{Float64}, true, Tuple{Vector{Float64}, Vector{Float64}, Float64, Float64, Float64, Vector{Float64}, Float64, OrdinaryDiffEqCore.MethodType, SciMLBase.NullParameters, Float64, SciMLBase.ODEFunction{true, SciMLBase.FullSpecialize, typeof(Main.TestModuleTrimmable.lorenz), UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing, Nothing, Nothing}}, SciMLBase.NonlinearFunction{true, SciMLBase.FullSpecialize, typeof(OrdinaryDiffEqNonlinearSolve.odenlf), UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED_NO_TIME), Nothing, Nothing, Nothing, Nothing}, @Kwargs{}, SciMLBase.StandardNonlinearProblem}, Val{:None}, NonlinearSolveBase.JacobianCache{Matrix{Float64}, SciMLBase.NonlinearFunction{true, SciMLBase.FullSpecialize, typeof(OrdinaryDiffEqNonlinearSolve.odenlf), UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED_NO_TIME), Nothing, Nothing, Nothing, Nothing}, Vector{Float64}, Vector{Float64}, Tuple{Vector{Float64}, Vector{Float64}, Float64, Float64, Float64, Vector{Float64}, Float64, OrdinaryDiffEqCore.MethodType, SciMLBase.NullParameters, Float64, SciMLBase.ODEFunction{true, SciMLBase.FullSpecialize, typeof(Main.TestModuleTrimmable.lorenz), UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing, Nothing, Nothing}}, ADTypes.AutoFiniteDiff{Val{:forward}, Val{:forward}, Val{:hcentral}, Nothing, Nothing, Bool}, DifferentiationInterfaceFiniteDiffExt.FiniteDiffTwoArgJacobianPrep{Nothing, FiniteDiff.JacobianCache{Vector{Float64}, Vector{Float64}, Vector{Float64}, Vector{Float64}, UnitRange{Int64}, Nothing, Val{:forward}(), Float64}, Float64, Float64, Bool}}, NonlinearSolveBase.NewtonDescentCache{Vector{Float64}, Nothing, NonlinearSolveBase.LinearSolveJLCache{LinearSolve.LinearCache{Matrix{Float64}, Vector{Float64}, Vector{Float64}, SciMLBase.NullParameters, LinearSolve.DefaultLinearSolver, LinearSolve.DefaultLinearSolverInit{LU{Float64, Matrix{Float64}, Vector{Int64}}, LinearAlgebra.QRCompactWY{Float64, Matrix{Float64}, Matrix{Float64}}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Tuple{LU{Float64, Matrix{Float64}, Vector{Int64}}, Vector{Int64}}, Tuple{LU{Float64, Matrix{Float64}, Vector{Int64}}, Vector{Int64}}, Nothing, Nothing, Nothing, SVD{Float64, Float64, Matrix{Float64}, Vector{Float64}}, Cholesky{Float64, Matrix{Float64}}, Cholesky{Float64, Matrix{Float64}}, Tuple{LU{Float64, Matrix{Float64}, Vector{Int32}}, Base.RefValue{Int32}}, Tuple{LU{Float64, Matrix{Float64}, Vector{Int64}}, Base.RefValue{Int64}}, QRPivoted{Float64, Matrix{Float64}, Vector{Float64}, Vector{Int64}}, Nothing, Nothing, Nothing, Nothing, Nothing}, SciMLOperators.IdentityOperator, SciMLOperators.IdentityOperator, Float64, Bool, LinearSolve.LinearSolveAdjoint{Missing}}, Nothing}, Nothing, Nothing, Nothing, Val{false}, Val{false}}, Nothing, Nothing, Nothing, Nothing, NonlinearSolveBase.NonlinearTerminationModeCache{Vector{Float64}, Float64, NonlinearSolveBase.AbsNormSafeBestTerminationMode{typeof(NonlinearSolveBase.Linf_NORM), Nothing, Int64, Float64, Int64}, Float64, Vector{Float64}, Nothing, Nothing, Vector{Float64}, Int64}, NonlinearSolveBase.NonlinearSolveTrace{Val{false}, Val{false}, Nothing, NonlinearSolveBase.NonlinearSolveTracing{Val{:minimal}}, SciMLBase.NonlinearProblem{Vector{Float64}, true, Tuple{Vector{Float64}, Vector{Float64}, Float64, Float64, Float64, Vector{Float64}, Float64, OrdinaryDiffEqCore.MethodType, SciMLBase.NullParameters, Float64, SciMLBase.ODEFunction{true, SciMLBase.FullSpecialize, typeof(Main.TestModuleTrimmable.lorenz), UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing, Nothing, Nothing}}, SciMLBase.NonlinearFunction{true, SciMLBase.FullSpecialize, typeof(OrdinaryDiffEqNonlinearSolve.odenlf), UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED_NO_TIME), Nothing, Nothing, Nothing, Nothing}, @Kwargs{}, SciMLBase.StandardNonlinearProblem}}, @Kwargs{}, NonlinearSolveBase.NonlinearSolveDefaultInit};
Now compare the code_typed, which contains a dynamic call:
julia> code_typed(NonlinearSolveFirstOrder.var"#step!#5", (Nothing, typeof(NonlinearSolveFirstOrder.InternalAPI.step!), CacheType))
1-element Vector{Any}:
CodeInfo(
...
│ %81 = builtin NonlinearSolveBase.getfield(cache, :u)::Vector{Float64}
│ dynamic (MaybeInplace.__safe_axpy!)(1, %74, %81)::Any
...
) => Nothing
versus the result from Cthulhu descend, which claims this is resolved to an invoke (and has quite different IR in general):
julia> descend(NonlinearSolveFirstOrder.var"#step!#5", (Nothing, typeof(NonlinearSolveFirstOrder.InternalAPI.step!), CacheType))
# press <T>
# inspect the optimized IR and notice:
312 │ %65 = builtin NonlinearSolveBase.getfield(cache, :u)::Vector{Float64} │╻╷ macro expansion
│ invoke LinearAlgebra.BLAS.axpy!(1::Int64, %61::Vector{Float64}, %65::Vector{Float64}) getproperty
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce with Julia 1.12.0-rc1 using the NonlinearSolve.jl commit and test/trim/optimization_once_per_process.jl, then compare code_typed for NonlinearSolveFirstOrder.var"#step!#5" with Cthulhu's descend output. Inspect the descend entry point and the displayed optimized IR; done means the discrepancy is explained and the two views are consistent or the behavior is covered by a regression test.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- julia
- Domain
- compilers, devtools
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 32/100