-
-
Notifications
You must be signed in to change notification settings - Fork 398
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix various JET errors #3519
Fix various JET errors #3519
Conversation
Codecov ReportPatch coverage:
Additional details and impacted files@@ Coverage Diff @@
## master #3519 +/- ##
=======================================
Coverage 98.25% 98.25%
=======================================
Files 37 37
Lines 5550 5560 +10
=======================================
+ Hits 5453 5463 +10
Misses 97 97
☔ View full report in Codecov by Sentry. |
@@ -178,7 +178,7 @@ function _nlp_objective_function(model::GenericModel) | |||
if model.nlp_model === nothing | |||
return nothing | |||
end | |||
return model.nlp_model.objective | |||
return something(model.nlp_model).objective |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's surprising the compiler isn't able to figure this one out
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Part of this is because model.nlp_model
calls getproperty
, which may do arbitrary things.
This is another cause where the specific concrete call of a particular GenericModel{T}
might be able to, but we can't figure it out statically based on (::GenericModel)
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's nice to have a tool like JET that is able to highlight all the cases that are confusing static analysis
═════ 12 possible errors found ═════
┌ getindex(x::JuMP.Containers._AxisLookup{Dict{K, Int64}}, keys::AbstractVector) where K @ JuMP.Containers /Users/oscar/.julia/dev/JuMP/src/Containers/DenseAxisArray.jl:59
│┌ collect(itr::Base.Generator) @ Base ./array.jl:792
││┌ collect_to_with_first!(dest::Union{var"##JETVirtualModule#292".JuMP.Containers.DenseAxisArray, var"##JETVirtualModule#292".JuMP.Containers.SparseAxisArray}, first_value::Any, iterator::Base.Generator, state::Any) @ var"##JETVirtualModule#292".JuMP.Containers /Users/oscar/.julia/dev/JuMP/src/Containers/Containers.jl:48
│││┌ indexed_iterate(I::Nothing, i::Int64) @ Base ./tuple.jl:91
││││ no matching method found `iterate(::Nothing)`: x = iterate(I::Nothing)
│││└────────────────────
│││┌ indexed_iterate(I::Nothing, i::Int64, state::Int64) @ Base ./tuple.jl:96
││││ no matching method found `iterate(::Nothing, ::Int64)`: x = iterate(I::Nothing, state::Int64)
│││└────────────────────
┌ _fixed_indices(view_axes::Tuple, axes::Tuple) @ JuMP.Containers /Users/oscar/.julia/dev/JuMP/src/Containers/DenseAxisArray.jl:750
│┌ filter(f::JuMP.Containers.var"#35#37", t::Tuple{Vararg{Int64}}) @ Base ./tuple.jl:440
││┌ collect(itr::Tuple{Vararg{Int64}}) @ Base ./array.jl:707
│││┌ _collect(cont::UnitRange{Int64}, itr::Tuple{Vararg{Int64}}, ::Base.HasEltype, isz::Base.HasLength) @ Base ./array.jl:713
││││┌ copyto!(dest::Vector{Union{}}, src::Tuple{Vararg{Int64}}) @ Base ./abstractarray.jl:951
│││││┌ setindex!(A::Vector{Union{}}, x::Int64, i1::Int64) @ Base ./array.jl:969
││││││ no matching method found `convert(::Type{Union{}}, ::Int64)`: convert(T::Type{Union{}}, x::Int64)
│││││└────────────────────
││┌ filter(f::JuMP.Containers.var"#35#37", a::Vector{Union{}}) @ Base ./array.jl:2608
│││┌ iterate(A::Vector{Union{}}) @ Base ./array.jl:893
││││┌ iterate(A::Vector{Union{}}, i::Int64) @ Base ./array.jl:893
│││││┌ getindex(A::Vector{Union{}}, i1::Int64) @ Base ./essentials.jl:13
││││││ invalid builtin function call: Base.arrayref($(Expr(:boundscheck)), A::Vector{Union{}}, i1::Int64)
│││││└────────────────────
┌ normalized_coefficient(con_ref::JuMP.ConstraintRef{<:JuMP.AbstractModel, MathOptInterface.ConstraintIndex{F, S}}, variable::Any) where {S, T, F<:Union{MathOptInterface.ScalarAffineFunction{T}, MathOptInterface.ScalarQuadraticFunction{T}}} @ JuMP /Users/oscar/.julia/dev/JuMP/src/constraints.jl:828
│┌ constraint_object(con_ref::JuMP.ConstraintRef{<:JuMP.AbstractModel, MathOptInterface.ConstraintIndex{Union{}, SetType}}) where SetType<:MathOptInterface.AbstractVectorSet @ JuMP /Users/oscar/.julia/dev/JuMP/src/constraints.jl:663
││ invalid builtin function call: f = typeassert(MathOptInterface.get(model, MathOptInterface.ConstraintFunction()::MathOptInterface.ConstraintFunction, con_ref::JuMP.ConstraintRef{<:JuMP.AbstractModel, MathOptInterface.ConstraintIndex{Union{}, SetType}} where SetType<:MathOptInterface.AbstractVectorSet)::Any, FuncType::Type{Union{}})
│└────────────────────
┌ normalized_coefficient(con_ref::JuMP.ConstraintRef{<:JuMP.AbstractModel, MathOptInterface.ConstraintIndex{F, S}}, variable::Any) where {S, T, F<:Union{MathOptInterface.ScalarAffineFunction{T}, MathOptInterface.ScalarQuadraticFunction{T}}} @ JuMP /Users/oscar/.julia/dev/JuMP/src/constraints.jl:829
│ no matching method found `_affine_coefficient(::Number, ::Any)` (1/2 union split): JuMP._affine_coefficient(con.func::Union{Number, JuMP.AbstractJuMPScalar}, variable::Any)
└────────────────────
┌ constraint_object(c::JuMP.NonlinearConstraintRef) @ JuMP /Users/oscar/.julia/dev/JuMP/src/nlp_expr.jl:582
│┌ jump_function(model::JuMP.Model, expr::MathOptInterface.Nonlinear.Expression) @ JuMP /Users/oscar/.julia/dev/JuMP/src/nlp_expr.jl:599
││┌ getproperty(x::Nothing, f::Symbol) @ Base ./Base.jl:37
│││ type Nothing has no field operators: Base.getfield(x::Nothing, f::Symbol)
││└────────────────────
┌ _functionize(v::LinearAlgebra.Symmetric{V, S} where S<:(AbstractMatrix{<:V})) where V<:JuMP.AbstractVariableRef @ JuMP /Users/oscar/.julia/dev/JuMP/src/macros.jl:380
│┌ LinearAlgebra.Symmetric(A::LinearAlgebra.Hermitian) @ LinearAlgebra /Users/julia/.julia/scratchspaces/a66863c6-20e8-4ff4-8a62-49f30b1f605e/agent-cache/default-grannysmith-C07ZQ07RJYVY.0/build/default-grannysmith-C07ZQ07RJYVY-0/julialang/julia-release-1-dot-9/usr/share/julia/stdlib/v1.9/LinearAlgebra/src/symmetric.jl:179
││┌ LinearAlgebra.Symmetric(A::LinearAlgebra.Hermitian, uplo::Symbol) @ LinearAlgebra /Users/julia/.julia/scratchspaces/a66863c6-20e8-4ff4-8a62-49f30b1f605e/agent-cache/default-grannysmith-C07ZQ07RJYVY.0/build/default-grannysmith-C07ZQ07RJYVY-0/julialang/julia-release-1-dot-9/usr/share/julia/stdlib/v1.9/LinearAlgebra/src/symmetric.jl:182
│││┌ diagind(A::AbstractMatrix) @ LinearAlgebra /Users/julia/.julia/scratchspaces/a66863c6-20e8-4ff4-8a62-49f30b1f605e/agent-cache/default-grannysmith-C07ZQ07RJYVY.0/build/default-grannysmith-C07ZQ07RJYVY-0/julialang/julia-release-1-dot-9/usr/share/julia/stdlib/v1.9/LinearAlgebra/src/dense.jl:224
││││┌ diagind(A::AbstractMatrix, k::Int64) @ LinearAlgebra /Users/julia/.julia/scratchspaces/a66863c6-20e8-4ff4-8a62-49f30b1f605e/agent-cache/default-grannysmith-C07ZQ07RJYVY.0/build/default-grannysmith-C07ZQ07RJYVY-0/julialang/julia-release-1-dot-9/usr/share/julia/stdlib/v1.9/LinearAlgebra/src/dense.jl:225
│││││┌ diagind(m::Integer, n::Integer, k::Int64) @ LinearAlgebra /Users/julia/.julia/scratchspaces/a66863c6-20e8-4ff4-8a62-49f30b1f605e/agent-cache/default-grannysmith-C07ZQ07RJYVY.0/build/default-grannysmith-C07ZQ07RJYVY-0/julialang/julia-release-1-dot-9/usr/share/julia/stdlib/v1.9/LinearAlgebra/src/dense.jl:201
││││││┌ kwcall(::NamedTuple{(:step, :length), _A} where _A<:Tuple{Any, Any}, ::typeof(range), start::Int64) @ Base ./range.jl:142
│││││││┌ range(start::Int64; stop::Nothing, length::Union{Nothing, Integer}, step::Any) @ Base ./range.jl:142
││││││││┌ _range(start::Int64, step::Any, stop::Nothing, len::Integer) @ Base ./range.jl:163
│││││││││┌ range_start_step_length(a::Int64, st::Union{Float16, Float32, Float64}, len::Integer) @ Base ./twiceprecision.jl:440
││││││││││┌ range_start_step_length(a::Float16, st::Float16, len::Integer) @ Base ./twiceprecision.jl:461
│││││││││││┌ floatrange(::Type{Float16}, start_n::Int64, step_n::Int64, len::Integer, den::Int64) @ Base ./twiceprecision.jl:388
││││││││││││┌ round(::DataType, x::Float64) @ Base ./missing.jl:144
│││││││││││││┌ round(::DataType, x::Float64, r::RoundingMode{:Nearest}) @ Base ./missing.jl:144
││││││││││││││┌ round(::Core.TypeofBottom, x::Float64, r::RoundingMode{:Nearest}) @ Base ./floatfuncs.jl:124
│││││││││││││││ no matching method found `trunc(::Type{Union{}}, ::Float64)`: trunc(T::Type{Union{}}, x::Float64)
││││││││││││││└────────────────────
┌ build_constraint(_error::Function, func::Any, set::Any, args::Vararg{Any}) @ JuMP /Users/oscar/.julia/dev/JuMP/src/macros.jl:935
│┌ build_constraint(_error::Function, func::Any, set::Any, args::Vararg{Any}; kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}) @ JuMP /Users/oscar/.julia/dev/JuMP/src/macros.jl:938
││┌ join(iterator::Tuple{Vararg{Union{}}}, delim::String) @ Base ./strings/io.jl:353
│││┌ sprint(::typeof(join), ::Tuple{Vararg{Union{}}}, ::String) @ Base ./strings/io.jl:107
││││┌ sprint(::typeof(join), ::Tuple{Vararg{Union{}}}, ::String; context::Nothing, sizehint::Int64) @ Base ./strings/io.jl:114
│││││┌ join(io::IOBuffer, iterator::Tuple{Vararg{Union{}}}, delim::String) @ Base ./strings/io.jl:346
││││││┌ iterate(t::Tuple{Vararg{Union{}}}) @ Base ./tuple.jl:68
│││││││┌ iterate(t::Tuple{Vararg{Union{}}}, i::Int64) @ Base ./tuple.jl:68
││││││││┌ getindex(t::Tuple{Vararg{Union{}}}, i::Int64) @ Base ./tuple.jl:29
│││││││││ invalid builtin function call: Base.getfield(t::Tuple{Vararg{Union{}}}, i::Int64, $(Expr(:boundscheck)))
││││││││└────────────────────
┌ primal_feasibility_report(model::JuMP.GenericModel{T}, point::AbstractDict{JuMP.GenericVariableRef{T}, T}; atol::Any, skip_missing::Bool) where T @ JuMP /Users/oscar/.julia/dev/JuMP/src/feasibility_checker.jl:58
│┌ kwcall(::NamedTuple{(:atol, :skip_missing), _A} where _A<:Tuple{Any, Bool}, ::typeof(JuMP.primal_feasibility_report), point::JuMP.var"#146#147"{Bool}, model::JuMP.GenericModel{T} where T) @ JuMP /Users/oscar/.julia/dev/JuMP/src/feasibility_checker.jl:99
││┌ primal_feasibility_report(point::JuMP.var"#146#147"{Bool}, model::JuMP.GenericModel{T}; atol::Any, skip_missing::Bool) where T @ JuMP /Users/oscar/.julia/dev/JuMP/src/feasibility_checker.jl:123
│││┌ _add_infeasible_nonlinear_constraints(model::JuMP.GenericModel{T}, violated_constraints::Dict{Any, T}, point_f::JuMP.var"#146#147"{Bool}, atol::T) where T @ JuMP /Users/oscar/.julia/dev/JuMP/src/feasibility_checker.jl:158
││││┌ initialize(evaluator::MathOptInterface.Nonlinear.Evaluator{MathOptInterface.Nonlinear.ReverseAD.NLPEvaluator}, features::Vector{Symbol}) @ MathOptInterface.Nonlinear /Users/oscar/.julia/dev/MathOptInterface/src/Nonlinear/evaluator.jl:79
│││││┌ initialize(d::MathOptInterface.Nonlinear.ReverseAD.NLPEvaluator, requested_features::Vector{Symbol}) @ MathOptInterface.Nonlinear.ReverseAD /Users/oscar/.julia/dev/MathOptInterface/src/Nonlinear/ReverseAD/mathoptinterface_api.jl:163
││││││┌ append!(a::Vector{Tuple{Int64, Int64}}, iter::Base.Iterators.Zip{Tuple{Vector{Int64}, Vector{Int64}}}) @ Base ./array.jl:1126
│││││││┌ _append!(a::Vector{Tuple{Int64, Int64}}, ::Base.HasShape{1}, iter::Base.Iterators.Zip{Tuple{Vector{Int64}, Vector{Int64}}}) @ Base ./array.jl:1135
││││││││┌ iterate(z::Base.Iterators.Zip{Tuple{UnitRange{Int64}, Base.Iterators.Zip{Tuple{Vector{Int64}, Vector{Int64}}}}}) @ Base.Iterators ./iterators.jl:406
│││││││││┌ _zip_iterate_all(is::Tuple{UnitRange{Int64}, Base.Iterators.Zip{Tuple{Vector{Int64}, Vector{Int64}}}}, ss::Tuple{Tuple{}, Tuple{}}) @ Base.Iterators ./iterators.jl:416
││││││││││┌ _zip_iterate_some(is::Tuple{UnitRange{Int64}, Base.Iterators.Zip{Tuple{Vector{Int64}, Vector{Int64}}}}, ss::Tuple{Tuple{}, Tuple{}}, ds::Tuple{Missing, Missing}, f::Missing) @ Base.Iterators ./iterators.jl:426
│││││││││││┌ _zip_iterate_some(is::Tuple{Base.Iterators.Zip{Tuple{Vector{Int64}, Vector{Int64}}}}, ss::Tuple{Tuple{}}, ds::Tuple{Missing}, f::Missing) @ Base.Iterators ./iterators.jl:424
││││││││││││┌ iterate(z::Base.Iterators.Zip{Tuple{Vector{Int64}, Vector{Int64}}}) @ Base.Iterators ./iterators.jl:406
│││││││││││││┌ _zip_iterate_all(is::Tuple{Vector{Int64}, Vector{Int64}}, ss::Any) @ Base.Iterators ./iterators.jl:414
││││││││││││││┌ _zip_isdone(is::Tuple{Vector{Int64}, Vector{Int64}}, ss::Any) @ Base.Iterators ./iterators.jl:446
│││││││││││││││┌ _zip_isdone(is::Tuple{Vector{Int64}}, ss::Any) @ Base.Iterators ./iterators.jl:446
││││││││││││││││┌ _zip_isdone(is::Tuple{}, ss::Any) @ Base.Iterators ./iterators.jl:445
│││││││││││││││││┌ getindex(t::Tuple{}, i::Int64) @ Base ./tuple.jl:29
││││││││││││││││││ BoundsError: attempt to access Tuple{} at index [1]: Base.getfield(t::Tuple{}, i::Int64, $(Expr(:boundscheck)))
│││││││││││││││││└────────────────────
┌ write_to_file(model::JuMP.GenericModel, filename::String; format::MathOptInterface.FileFormats.FileFormat, kwargs::Base.Pairs{Symbol, V, Tuple{Vararg{Symbol, N}}, NamedTuple{names, T}} where {V, N, names, T<:Tuple{Vararg{Any, N}}}) @ JuMP /Users/oscar/.julia/dev/JuMP/src/file_formats.jl:52
│┌ _copy_to_bridged_model(f::JuMP.var"#150#151"{MathOptInterface.FileFormats.FileFormat, _A, String} where _A, model::JuMP.GenericModel) @ JuMP /Users/oscar/.julia/dev/JuMP/src/file_formats.jl:20
││┌ copy_to(dest::MathOptInterface.Bridges.LazyBridgeOptimizer, src::JuMP.GenericModel) @ JuMP /Users/oscar/.julia/dev/JuMP/src/copy.jl:337
│││┌ copy_to(dest::MathOptInterface.Bridges.LazyBridgeOptimizer, src::MathOptInterface.AbstractOptimizer) @ MathOptInterface.Bridges /Users/oscar/.julia/dev/MathOptInterface/src/Bridges/bridge_optimizer.jl:453
││││┌ default_copy_to(dest::MathOptInterface.Bridges.LazyBridgeOptimizer, src::MathOptInterface.AbstractOptimizer) @ MathOptInterface.Utilities /Users/oscar/.julia/dev/MathOptInterface/src/Utilities/copy.jl:490
│││││┌ collect(::Type{Any}, itr::Base.Generator) @ Base ./array.jl:642
││││││┌ _collect(::Type{Any}, itr::Base.Generator, isz::Union{Base.HasLength, Base.HasShape}) @ Base ./array.jl:644
│││││││┌ _array_for(::Type{Any}, itr::Base.HasLength, isz::Any) @ Base ./array.jl:674
││││││││┌ _similar_shape(itr::Base.HasLength, ::Base.HasShape) @ Base ./array.jl:659
│││││││││┌ axes(A::Base.HasLength) @ Base ./abstractarray.jl:98
││││││││││ no matching method found `size(::Base.HasLength)`: size(A::Base.HasLength)
│││││││││└────────────────────
││││││││┌ _similar_shape(itr::Base.HasLength, ::Base.HasLength) @ Base ./array.jl:658
│││││││││ no matching method found `length(::Base.HasLength)`: length(itr::Base.HasLength)
││││││││└──────────────────── |
There are bunch of issues stemming from MOI: jump-dev/MathOptInterface.jl#2268.
In most cases, these change nothing at runtime, but they do make things friendlier for the compiler.
A common case is:
where
model.nlp_model::Union{Nothing,MOI.Nonlinear.Model}
.We know that after the call to
_init_NLP
it will never beNothing
, but the compiler cannot (currently) prove that, and so anything trying to do static compilation will look for the methodMOI.Nonlinear.register_operator(::Nothing, ...)
which doesn't exist.We could technically ignore them, but fixing even the minor issues in JET lets us more explicitly find and track actual bugs like #3518, which would otherwise get lost in the noise of 10's or 100's of errors.