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

`solve` not type-inferrable

Open sethaxen opened this issue 2 years ago • 5 comments

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

sethaxen avatar Jun 26 '23 09:06 sethaxen

@ValentinKaisermayer I think this type-noninferrability may have been introduced in #406 . Is this something that can be fixed?

sethaxen avatar Jun 27 '23 11:06 sethaxen

@sethaxen thanks for the issue. I plan to prioritize this, have been stuck at getting the CI to pass on #553 hence the delay.

Vaibhavdixit02 avatar Jun 27 '23 11:06 Vaibhavdixit02

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?

Vaibhavdixit02 avatar Jun 27 '23 11:06 Vaibhavdixit02

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

sethaxen avatar Jun 27 '23 12:06 sethaxen

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.

Vaibhavdixit02 avatar Jul 09 '23 08:07 Vaibhavdixit02