`solve` not type-inferrable
Before v3.13.1, which implemented init, calling solve(prob, optimizer) was type-inferrable, but with v3.13.1, it became non-type-inferrable.
julia> using Optimization, OptimizationOptimJL, Test
julia> f(x, p) = sum(abs2, x)/2;
julia> fun = OptimizationFunction(f);
julia> prob = OptimizationProblem(fun, randn(3));
julia> optimizer = NelderMead();
julia> @inferred solve(prob, optimizer)
on v3.13.0:
u: 3-element Vector{Float64}:
-9.550802798460414e-5
8.410929885505606e-5
3.509039964423626e-5
on v3.13.1 and master:
ERROR: return type SciMLBase.OptimizationSolution{Float64, 1, Vector{Float64}, OptimizationOptimJL.OptimJLOptimizationCache{OptimizationFunction{true, SciMLBase.NoAD, typeof(f), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED_NO_TIME), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, Optimization.ReInitCache{Vector{Float64}, SciMLBase.NullParameters}, Nothing, Nothing, Nothing, Nothing, Nothing, NelderMead{Optim.AffineSimplexer, Optim.AdaptiveParameters}, Base.Iterators.Cycle{Tuple{Optimization.NullData}}, Bool, OptimizationOptimJL.var"#5#7"}, NelderMead{Optim.AffineSimplexer, Optim.AdaptiveParameters}, Float64, Optim.MultivariateOptimizationResults{NelderMead{Optim.AffineSimplexer, Optim.AdaptiveParameters}, Vector{Float64}, Float64, Float64, Vector{OptimizationState{Float64, NelderMead{Optim.AffineSimplexer, Optim.AdaptiveParameters}}}, Bool, NamedTuple{(:f_limit_reached, :g_limit_reached, :h_limit_reached, :time_limit, :callback, :f_increased), NTuple{6, Bool}}}, Float64, Nothing} does not match inferred return type SciMLBase.OptimizationSolution{_A, _B, _C, OptimizationOptimJL.OptimJLOptimizationCache{OptimizationFunction{true, SciMLBase.NoAD, typeof(f), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED_NO_TIME), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, Optimization.ReInitCache{Vector{Float64}, SciMLBase.NullParameters}, Nothing, Nothing, Nothing, Nothing, Nothing, NelderMead{Optim.AffineSimplexer, Optim.AdaptiveParameters}, Base.Iterators.Cycle{Tuple{Optimization.NullData}}, Bool, OptimizationOptimJL.var"#5#7"}, _D, _E, _F, Float64, Nothing} where {_A, _B, _C, _D, _E, _F}
Stacktrace:
[1] error(s::String)
@ Base ./error.jl:35
[2] top-level scope
@ REPL[8]:1
@ValentinKaisermayer I think this type-noninferrability may have been introduced in #406 . Is this something that can be fixed?
@sethaxen thanks for the issue. I plan to prioritize this, have been stuck at getting the CI to pass on #553 hence the delay.
We had an update to the caching after #406 in #536 also. Did you git bisect to find #406 as the point where it started showing up?
git bisect starting with c67d6301b128d567ea9233481f0d86b8342869fe as a good commit terminates with #406, but the above code fails then with a different error:
julia> @inferred solve(prob, optimizer)
ERROR: MethodError: Cannot `convert` an object of type Nothing to an object of type SciMLBase.AbstractOptimizationCache
Closest candidates are:
convert(::Type{T}, ::T) where T
@ Base Base.jl:64
Stacktrace:
[1] init(::OptimizationProblem{true, OptimizationFunction{true, SciMLBase.NoAD, typeof(f), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED_NO_TIME), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, Vector{Float64}, SciMLBase.NullParameters, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}}, ::NelderMead{Optim.AffineSimplexer, Optim.AdaptiveParameters}; kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
@ SciMLBase ~/.julia/packages/SciMLBase/s9wrq/src/solve.jl:149
[2] init(::OptimizationProblem{true, OptimizationFunction{true, SciMLBase.NoAD, typeof(f), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED_NO_TIME), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, Vector{Float64}, SciMLBase.NullParameters, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}}, ::NelderMead{Optim.AffineSimplexer, Optim.AdaptiveParameters})
@ SciMLBase ~/.julia/packages/SciMLBase/s9wrq/src/solve.jl:146
[3] solve(::OptimizationProblem{true, OptimizationFunction{true, SciMLBase.NoAD, typeof(f), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED_NO_TIME), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, Vector{Float64}, SciMLBase.NullParameters, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}}, ::NelderMead{Optim.AffineSimplexer, Optim.AdaptiveParameters}; kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
@ SciMLBase ~/.julia/packages/SciMLBase/s9wrq/src/solve.jl:83
[4] solve(::OptimizationProblem{true, OptimizationFunction{true, SciMLBase.NoAD, typeof(f), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED_NO_TIME), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, Vector{Float64}, SciMLBase.NullParameters, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}}, ::NelderMead{Optim.AffineSimplexer, Optim.AdaptiveParameters})
@ SciMLBase ~/.julia/packages/SciMLBase/s9wrq/src/solve.jl:80
[5] top-level scope
@ REPL[8]:1
I made some attempts on this but haven't been successful yet. The parametric types in OptimizationSolution for some fields are not inferred which doesn't make sense immediately.