diff --git a/src/JuMP.jl b/src/JuMP.jl index cb13acbafbb..2b6e5444f51 100644 --- a/src/JuMP.jl +++ b/src/JuMP.jl @@ -84,7 +84,7 @@ value_type(::Type{<:AbstractModel}) = Float64 mutable struct GenericModel{T<:Real} <: AbstractModel # In MANUAL and AUTOMATIC modes, CachingOptimizer. # In DIRECT mode, will hold an AbstractOptimizer. - moi_backend::MOI.AbstractOptimizer + moi_backend::MOI.ModelLike # List of shapes of constraints that are not `ScalarShape` or `VectorShape`. shapes::Dict{MOI.ConstraintIndex,AbstractShape} # List of bridges to add in addition to the ones added in diff --git a/src/optimizer_interface.jl b/src/optimizer_interface.jl index 474a6819fd8..533b4ed0c5b 100644 --- a/src/optimizer_interface.jl +++ b/src/optimizer_interface.jl @@ -444,6 +444,15 @@ function optimize!( if mode(model) != DIRECT && MOIU.state(backend(model)) == MOIU.NO_OPTIMIZER throw(NoOptimizer()) end + optimizer = unsafe_backend(model) + if !(optimizer isa MOI.AbstractOptimizer) + error( + "Cannot call `optimize!` because the provided optimizer is not " * + "a subtype of `MOI.AbstractOptimizer`.\n\nThe optimizer is:\n\n" * + sprint(show, optimizer) * + "\n", + ) + end try MOI.optimize!(backend(model)) catch err diff --git a/src/print.jl b/src/print.jl index 5847ab3922b..66bedbd4a4e 100644 --- a/src/print.jl +++ b/src/print.jl @@ -273,7 +273,12 @@ function show_backend_summary(io::IO, model::GenericModel) println(io, "CachingOptimizer state: ", MOIU.state(backend(model))) end # The last print shouldn't have a new line - print(io, "Solver name: ", solver_name(model)) + name = try + solver_name(model) + catch + "unknown" + end + print(io, "Solver name: ", name) return end diff --git a/test/test_model.jl b/test/test_model.jl index 57bf1f60266..20bcb345d6e 100644 --- a/test/test_model.jl +++ b/test/test_model.jl @@ -1216,4 +1216,32 @@ function test_show_variable_not_owned() return end +function test_direct_mps_model() + model = direct_model(MOI.FileFormats.MPS.Model()) + @test occursin("unknown", sprint(show, model)) + @variable(model, x >= 0) + io = IOBuffer() + write(io, backend(model)) + seekstart(io) + data = String(take!(io)) + @test startswith(data, "NAME") + @test endswith(data, "ENDATA\n") + return +end + +function test_caching_mps_model() + model = Model(MOI.FileFormats.MPS.Model) + @test occursin("unknown", sprint(show, model)) + @variable(model, x >= 0) + @test_throws( + ErrorException( + "Cannot call `optimize!` because the provided optimizer is not " * + "a subtype of `MOI.AbstractOptimizer`.\n\nThe optimizer is:\n\n" * + "A Mathematical Programming System (MPS) model\n", + ), + optimize!(model), + ) + return +end + end # module TestModels