diff --git a/Project.toml b/Project.toml index 768186d..70e713b 100644 --- a/Project.toml +++ b/Project.toml @@ -14,7 +14,7 @@ SemidefiniteModels = "169818f4-1a3d-53bf-95b3-11177825b1e3" SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" [compat] -MathOptInterface = "0.9.1" +MathOptInterface = "0.9.5" MathProgBase = "~0.7.0" SemidefiniteModels = "~0.1.1" julia = "1" diff --git a/src/MOI_wrapper.jl b/src/MOI_wrapper.jl index d1efbaa..fbfb78f 100644 --- a/src/MOI_wrapper.jl +++ b/src/MOI_wrapper.jl @@ -281,7 +281,10 @@ function MOI.get(m::Optimizer, ::MOI.TerminationStatus) end end -function MOI.get(m::Optimizer, ::MOI.PrimalStatus) +function MOI.get(m::Optimizer, attr::MOI.PrimalStatus) + if attr.N > MOI.get(m, MOI.ResultCount()) + return MOI.NO_SOLUTION + end status = m.status if status == 0 return MOI.FEASIBLE_POINT @@ -298,7 +301,10 @@ function MOI.get(m::Optimizer, ::MOI.PrimalStatus) end end -function MOI.get(m::Optimizer, ::MOI.DualStatus) +function MOI.get(m::Optimizer, attr::MOI.DualStatus) + if attr.N > MOI.get(m, MOI.ResultCount()) + return MOI.NO_SOLUTION + end status = m.status if status == 0 return MOI.FEASIBLE_POINT @@ -316,10 +322,12 @@ function MOI.get(m::Optimizer, ::MOI.DualStatus) end MOI.get(m::Optimizer, ::MOI.ResultCount) = 1 -function MOI.get(m::Optimizer, ::MOI.ObjectiveValue) +function MOI.get(m::Optimizer, attr::MOI.ObjectiveValue) + MOI.check_result_index_bounds(m, attr) return m.objsign * m.pobj + m.objconstant end -function MOI.get(m::Optimizer, ::MOI.DualObjectiveValue) +function MOI.get(m::Optimizer, attr::MOI.DualObjectiveValue) + MOI.check_result_index_bounds(m, attr) return m.objsign * m.dobj + m.objconstant end struct PrimalSolutionMatrix <: MOI.AbstractModelAttribute end @@ -364,23 +372,28 @@ function vectorize_block(M::AbstractMatrix{Cdouble}, blk::Integer, s::Type{MOI.P return v end -function MOI.get(optimizer::Optimizer, ::MOI.VariablePrimal, vi::MOI.VariableIndex) +function MOI.get(optimizer::Optimizer, attr::MOI.VariablePrimal, vi::MOI.VariableIndex) + MOI.check_result_index_bounds(optimizer, attr) blk, i, j = varmap(optimizer, vi) return block(MOI.get(optimizer, PrimalSolutionMatrix()), blk)[i, j] end -function MOI.get(optimizer::Optimizer, ::MOI.ConstraintPrimal, +function MOI.get(optimizer::Optimizer, attr::MOI.ConstraintPrimal, ci::MOI.ConstraintIndex{MOI.VectorOfVariables, S}) where S<:SupportedSets + MOI.check_result_index_bounds(optimizer, attr) return vectorize_block(MOI.get(optimizer, PrimalSolutionMatrix()), block(optimizer, ci), S) end -function MOI.get(m::Optimizer, ::MOI.ConstraintPrimal, ci::AFFEQ) - return m.b[ci.value] +function MOI.get(optimizer::Optimizer, attr::MOI.ConstraintPrimal, ci::AFFEQ) + MOI.check_result_index_bounds(optimizer, attr) + return optimizer.b[ci.value] end -function MOI.get(optimizer::Optimizer, ::MOI.ConstraintDual, +function MOI.get(optimizer::Optimizer, attr::MOI.ConstraintDual, ci::MOI.ConstraintIndex{MOI.VectorOfVariables, S}) where S<:SupportedSets + MOI.check_result_index_bounds(optimizer, attr) return vectorize_block(MOI.get(optimizer, DualSlackMatrix()), block(optimizer, ci), S) end -function MOI.get(optimizer::Optimizer, ::MOI.ConstraintDual, ci::AFFEQ) +function MOI.get(optimizer::Optimizer, attr::MOI.ConstraintDual, ci::AFFEQ) + MOI.check_result_index_bounds(optimizer, attr) return -MOI.get(optimizer, DualSolutionVector())[ci.value] end diff --git a/test/MOI_wrapper.jl b/test/MOI_wrapper.jl index 3220b70..973e45c 100644 --- a/test/MOI_wrapper.jl +++ b/test/MOI_wrapper.jl @@ -33,6 +33,8 @@ end @testset "Unit" begin MOIT.unittest(bridged, config, [ + # `NumberOfThreads` not supported. + "number_threads", # `TimeLimitSec` not supported. "time_limit_sec", # SingleVariable objective of bridged variables, will be solved by objective bridges @@ -64,5 +66,5 @@ end # Missing bridges "rootdets", # Does not support power and exponential cone - "pow", "logdet", "exp"]) + "pow", "dualpow", "logdet", "exp", "dualexp"]) end