Skip to content

Commit

Permalink
update for MOI 0.7 (#82)
Browse files Browse the repository at this point in the history
* update for MOI 0.7

* implement supports_allocate_load

* switch to automatic_copy_to

* implement SolverName
  • Loading branch information
mlubin committed Dec 17, 2018
1 parent 032ad78 commit a5df368
Show file tree
Hide file tree
Showing 8 changed files with 60 additions and 32 deletions.
2 changes: 1 addition & 1 deletion REQUIRE
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
julia 0.6
MathProgBase 0.5 0.8
MathOptInterface 0.6.2 0.7
MathOptInterface 0.7 0.8
Compat 0.68
BinaryProvider 0.3
4 changes: 2 additions & 2 deletions src/ECOS.jl
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ function cleanup(problem::Ptr{Cpwork}, keepvars::Int = 0)
ccall((:ECOS_cleanup, ECOS.ecos), Cvoid, (Ptr{Cpwork}, Clong), problem, keepvars)
end

include("MPBWrapper.jl")
include("MOIWrapper.jl")
include("MPB_wrapper.jl")
include("MOI_wrapper.jl")

end # module
69 changes: 44 additions & 25 deletions src/MOIWrapper.jl → src/MOI_wrapper.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ struct Solution
objval::Float64
objbnd::Float64
end
Solution() = Solution(0, Float64[], Float64[], Float64[], Float64[], NaN, NaN)
const OPTIMIZE_NOT_CALLED = -1
Solution() = Solution(OPTIMIZE_NOT_CALLED, Float64[], Float64[], Float64[],
Float64[], NaN, NaN)

# Used to build the data with allocate-load during `copy_to`.
# When `optimize!` is called, a the data is used to build `ECOSMatrix`
Expand Down Expand Up @@ -69,16 +71,19 @@ mutable struct Optimizer <: MOI.AbstractOptimizer
end
end

MOI.get(::Optimizer, ::MOI.SolverName) = "ECOS"

function MOI.is_empty(instance::Optimizer)
!instance.maxsense && instance.data === nothing
end

function MOI.empty!(instance::Optimizer)
instance.maxsense = false
instance.data = nothing # It should already be nothing except if an error is thrown inside copy_to
instance.sol = Solution()
end

MOIU.needs_allocate_load(instance::Optimizer) = true
MOIU.supports_allocate_load(::Optimizer, copy_names::Bool) = !copy_names

function MOI.supports(::Optimizer,
::Union{MOI.ObjectiveSense,
Expand All @@ -89,8 +94,8 @@ end

MOI.supports_constraint(::Optimizer, ::Type{<:SF}, ::Type{<:SS}) = true

function MOI.copy_to(dest::Optimizer, src::MOI.ModelLike; copy_names = true)
return MOIU.allocate_load(dest, src, copy_names)
function MOI.copy_to(dest::Optimizer, src::MOI.ModelLike; kws...)
return MOIU.automatic_copy_to(dest, src; kws...)
end

using Compat.SparseArrays
Expand Down Expand Up @@ -285,19 +290,25 @@ end
# Implements getter for result value and statuses
function MOI.get(instance::Optimizer, ::MOI.TerminationStatus)
flag = instance.sol.ret_val
if flag == ECOS.ECOS_OPTIMAL
MOI.Success
if flag == OPTIMIZE_NOT_CALLED
return MOI.OptimizeNotCalled
elseif flag == ECOS.ECOS_OPTIMAL
return MOI.Optimal
elseif flag == ECOS.ECOS_PINF
MOI.Success
elseif flag == ECOS.ECOS_DINF # Dual infeasible = primal unbounded, probably
MOI.Success
return MOI.Infeasible
elseif flag == ECOS.ECOS_DINF
return MOI.DualInfeasible
elseif flag == ECOS.ECOS_MAXIT
MOI.IterationLimit
return MOI.IterationLimit
elseif flag == ECOS.ECOS_OPTIMAL + ECOS.ECOS_INACC_OFFSET
m.solve_stat = MOI.AlmostSuccess
return MOI.AlmostOptimal
elseif flag == ECOS.ECOS_PINF + ECOS.ECOS_INACC_OFFSET
return MOI.AlmostInfeasible
else
m.solve_stat = MOI.OtherError
return MOI.OtherError
end
# TODO: AlmostDualInfeasible for ECOS.ECOS_DINF + ECOS.ECOS_INACC_OFFSET
# https://github.com/JuliaOpt/MathOptInterface.jl/issues/601
end

MOI.get(instance::Optimizer, ::MOI.ObjectiveValue) = instance.sol.objval
Expand All @@ -306,17 +317,21 @@ MOI.get(instance::Optimizer, ::MOI.ObjectiveBound) = instance.sol.objbnd
function MOI.get(instance::Optimizer, ::MOI.PrimalStatus)
flag = instance.sol.ret_val
if flag == ECOS.ECOS_OPTIMAL
MOI.FeasiblePoint
return MOI.FeasiblePoint
elseif flag == ECOS.ECOS_PINF
MOI.InfeasiblePoint
elseif flag == ECOS.ECOS_DINF # Dual infeasible = primal unbounded, probably
MOI.InfeasibilityCertificate
return MOI.InfeasiblePoint
elseif flag == ECOS.ECOS_DINF
return MOI.InfeasibilityCertificate
elseif flag == ECOS.ECOS_MAXIT
MOI.UnknownResultStatus
return MOI.UnknownResultStatus
elseif flag == ECOS.ECOS_OPTIMAL + ECOS.ECOS_INACC_OFFSET
m.solve_stat = MOI.NearlyFeasiblePoint
return MOI.NearlyFeasiblePoint
elseif flag == ECOS.ECOS_PINF + ECOS.ECOS_INACC_OFFSET
return MOI.InfeasiblePoint
elseif flag == ECOS.ECOS_DINF + ECOS.ECOS_INACC_OFFSET
return MOI.NearlyInfeasibilityCertificate
else
m.solve_stat = MOI.OtherResultStatus
return MOI.OtherResultStatus
end
end
# Swapping indices 2 <-> 3 is an involution (it is its own inverse)
Expand Down Expand Up @@ -347,15 +362,19 @@ end
function MOI.get(instance::Optimizer, ::MOI.DualStatus)
flag = instance.sol.ret_val
if flag == ECOS.ECOS_OPTIMAL
MOI.FeasiblePoint
return MOI.FeasiblePoint
elseif flag == ECOS.ECOS_PINF
MOI.InfeasibilityCertificate
elseif flag == ECOS.ECOS_DINF # Dual infeasible = primal unbounded, probably
MOI.InfeasiblePoint
return MOI.InfeasibilityCertificate
elseif flag == ECOS.ECOS_DINF
return MOI.InfeasiblePoint
elseif flag == ECOS.ECOS_MAXIT
MOI.UnknownResultStatus
return MOI.UnknownResultStatus
elseif flag == ECOS.ECOS_OPTIMAL + ECOS.ECOS_INACC_OFFSET
m.solve_stat = MOI.NearlyFeasiblePoint
return MOI.NearlyFeasiblePoint
elseif flag == ECOS.ECOS_PINF + ECOS.ECOS_INACC_OFFSET
return MOI.NearlyInfeasibilityCertificate
elseif flag == ECOS.ECOS_DINF + ECOS.ECOS_INACC_OFFSET
return MOI.InfeasiblePoint
else
m.solve_stat = MOI.OtherResultStatus
end
Expand Down
File renamed without changes.
9 changes: 9 additions & 0 deletions test/MOIWrapper.jl → test/MOI_wrapper.jl
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,12 @@ end
MOIT.contconictest(MOIB.GeoMean{Float64}(MOIB.RSOC{Float64}(optimizer)),
config, exclude)
end

@testset "SolverName" begin
@test MOI.get(optimizer, MOI.SolverName()) == "ECOS"
end

@testset "supports_allocate_load" begin
@test MOIU.supports_allocate_load(optimizer.optimizer, false)
@test !MOIU.supports_allocate_load(optimizer.optimizer, true)
end
2 changes: 1 addition & 1 deletion test/mpb_linear.jl → test/MPB_linear.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# Wrapper around the ECOS solver https://github.com/ifa-ethz/ecos
# See http://github.com/JuliaOpt/ECOS.jl
#############################################################################
# test/mpb_linear.jl
# test/MPB_linear.jl
# Test the MathProgBase.jl interface for the ECOS.jl solver wrapper
#############################################################################

Expand Down
2 changes: 1 addition & 1 deletion test/MPBWrapper.jl → test/MPB_wrapper.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
#############################################################################

@testset "Test the MPB wrapper with linprog" begin
include("mpb_linear.jl")
include("MPB_linear.jl")
end

import ECOS
Expand Down
4 changes: 2 additions & 2 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ end
end

@testset "MathProgBase" begin
include("MPBWrapper.jl")
include("MPB_wrapper.jl")
end

@testset "MathOptInterface" begin
include("MOIWrapper.jl")
include("MOI_wrapper.jl")
end

0 comments on commit a5df368

Please sign in to comment.