diff --git a/REQUIRE b/REQUIRE index 3328a21..819a910 100644 --- a/REQUIRE +++ b/REQUIRE @@ -1,3 +1,3 @@ julia 0.6 -MathOptInterface 0.6 0.7 +MathOptInterface 0.7 0.8 Compat 1.0.1 diff --git a/src/SemidefiniteOptInterface.jl b/src/SemidefiniteOptInterface.jl index 8621a71..d1999e1 100644 --- a/src/SemidefiniteOptInterface.jl +++ b/src/SemidefiniteOptInterface.jl @@ -69,6 +69,10 @@ SDOIOptimizer(sdoptimizer::AbstractSDOptimizer, T=Float64) = SOItoMOIBridge{T}(s include("load.jl") +function MOI.get(optimizer::SOItoMOIBridge, attr::MOI.SolverName) + return MOI.get(optimizer.sdoptimizer, attr) +end + function MOI.is_empty(optimizer::SOItoMOIBridge) isempty(optimizer.double) && isempty(optimizer.setconstant) && @@ -89,6 +93,7 @@ function MOI.empty!(optimizer::SOItoMOIBridge{T}) where T for s in optimizer.double MOI.delete(m, s) end + MOI.empty!(optimizer.sdoptimizer) optimizer.double = CI[] optimizer.setconstant = Dict{Int64, T}() optimizer.blkconstant = Dict{Int, T}() @@ -136,10 +141,10 @@ function MOI.supports_constraint(::SOItoMOIBridge{T}, return true end -function MOI.copy_to(dest::SOItoMOIBridge, src::MOI.ModelLike; - copy_names = true) - return MOIU.allocate_load(dest, src, copy_names) +function MOI.copy_to(dest::SOItoMOIBridge, src::MOI.ModelLike; kws...) + return MOIU.automatic_copy_to(dest, src; kws...) end +MOIU.supports_allocate_load(::SOItoMOIBridge, copy_names::Bool) = !copy_names MOI.optimize!(m::SOItoMOIBridge) = MOI.optimize!(m.sdoptimizer) @@ -157,15 +162,15 @@ MOI.get(m::SOItoMOIBridge, s::SolverStatus) = MOI.get(m.sdoptimizer, s) MOI.get(m::SOItoMOIBridge, ::MOI.ResultCount) = 1 -function _getblock(M, blk::Int, s::Type{<:Union{NS, ZS}}) +function _getblock(M, blk::Integer, s::Type{<:Union{NS, ZS}}) diag(block(M, blk)) end -function _getblock(M, blk::Int, s::Type{<:PS}) +function _getblock(M, blk::Integer, s::Type{<:PS}) -diag(block(M, blk)) end # Vectorized length for matrix dimension d sympackedlen(d::Integer) = (d*(d+1)) >> 1 -function _getblock(M::AbstractMatrix{T}, blk::Int, s::Type{<:DS}) where T +function _getblock(M::AbstractMatrix{T}, blk::Integer, s::Type{<:DS}) where T B = block(M, blk) d = Compat.LinearAlgebra.checksquare(B) n = sympackedlen(d) @@ -180,17 +185,17 @@ function _getblock(M::AbstractMatrix{T}, blk::Int, s::Type{<:DS}) where T @assert k == n v end -function getblock(M, blk::Int, s::Type{<:MOI.AbstractScalarSet}) +function getblock(M, blk::Integer, s::Type{<:MOI.AbstractScalarSet}) vd = _getblock(M, blk, s) @assert length(vd) == 1 vd[1] end -function getblock(M, blk::Int, s::Type{<:MOI.AbstractVectorSet}) +function getblock(M, blk::Integer, s::Type{<:MOI.AbstractVectorSet}) _getblock(M, blk, s) end -getvarprimal(m::SOItoMOIBridge, blk::Int, S) = getblock(getX(m.sdoptimizer), blk, S) -function getvardual(m::SOItoMOIBridge, blk::Int, S) +getvarprimal(m::SOItoMOIBridge, blk::Integer, S) = getblock(getX(m.sdoptimizer), blk, S) +function getvardual(m::SOItoMOIBridge, blk::Integer, S) getblock(getZ(m.sdoptimizer), blk, S) end @@ -218,7 +223,7 @@ function _getattribute(m::SOItoMOIBridge, ci::CI{<:AVF}, f) f.(m, m.constrmap[ci]) end -function getslack(m::SOItoMOIBridge{T}, c::Int) where T +function getslack(m::SOItoMOIBridge{T}, c::Integer) where T X = getX(m.sdoptimizer) blk, i, j, coef = m.slackmap[c] if iszero(blk) @@ -269,7 +274,7 @@ function MOI.get(m::SOItoMOIBridge, ::MOI.ConstraintDual, ci::CI{<:VF, S}) where end end -function getdual(m::SOItoMOIBridge{T}, c::Int) where T +function getdual(m::SOItoMOIBridge{T}, c::Integer) where T if c == 0 zero(T) else diff --git a/src/mock.jl b/src/mock.jl index 2603434..d2b238d 100644 --- a/src/mock.jl +++ b/src/mock.jl @@ -53,19 +53,38 @@ MockSDOptimizer{T}() where T = MockSDOptimizer{T}(0, (::MockSDOptimizer) -> begin end, false, false, - MOI.Success, - MOI.UnknownResultStatus, - MOI.UnknownResultStatus, + MOI.OptimizeNotCalled, + MOI.NoSolution, + MOI.NoSolution, BlockMatrix{T}(Matrix{T}[]), BlockMatrix{T}(Matrix{T}[]), T[]) mockSDoptimizer(T::Type) = SDOIOptimizer(MockSDOptimizer{T}(), T) + +MOI.get(::MockSDOptimizer, ::MOI.SolverName) = "MockSD" + +function MOI.empty!(mock::MockSDOptimizer{T}) where T + mock.nconstrs = 0 + mock.blkdims = Int[] + mock.constraint_constants = T[] + mock.objective_coefficients = Tuple{T, Int, Int, Int}[] + mock.constraint_coefficients = Vector{Tuple{T, Int, Int, Int}}[] + mock.hasprimal = false + mock.hasdual = false + mock.terminationstatus = MOI.OptimizeNotCalled + mock.primalstatus = MOI.NoSolution + mock.dualstatus = MOI.NoSolution + mock.X = BlockMatrix{T}(Matrix{T}[]) + mock.Z = BlockMatrix{T}(Matrix{T}[]) + mock.y = T[] +end coefficienttype(::MockSDOptimizer{T}) where T = T getnumberofconstraints(optimizer::MockSDOptimizer) = optimizer.nconstrs getnumberofblocks(optimizer::MockSDOptimizer) = length(optimizer.blkdims) getblockdimension(optimizer::MockSDOptimizer, blk) = optimizer.blkdims[blk] -function init!(optimizer::MockSDOptimizer{T}, blkdims::Vector{Int}, nconstrs::Integer) where T +function init!(optimizer::MockSDOptimizer{T}, blkdims::Vector{Int}, + nconstrs::Integer) where T optimizer.nconstrs = nconstrs optimizer.blkdims = blkdims optimizer.constraint_constants = zeros(T, nconstrs) @@ -84,12 +103,16 @@ function setobjectivecoefficient!(optimizer::MockSDOptimizer, val, blk::Integer, end getconstraintcoefficients(optimizer::MockSDOptimizer, c) = optimizer.constraint_coefficients[c] -function setconstraintcoefficient!(optimizer::MockSDOptimizer, val, c::Integer, blk::Integer, i::Integer, j::Integer) +function setconstraintcoefficient!(optimizer::MockSDOptimizer, val, c::Integer, + blk::Integer, i::Integer, j::Integer) push!(optimizer.constraint_coefficients[c], (val, blk, i, j)) end MOI.get(mock::MockSDOptimizer, ::MOI.TerminationStatus) = mock.terminationstatus -MOI.set(mock::MockSDOptimizer, ::MOI.TerminationStatus, value::MOI.TerminationStatusCode) = (mock.terminationstatus = value) +function MOI.set(mock::MockSDOptimizer, ::MOI.TerminationStatus, + value::MOI.TerminationStatusCode) + mock.terminationstatus = value +end MOI.get(mock::MockSDOptimizer, ::MOI.PrimalStatus) = mock.primalstatus MOI.set(mock::MockSDOptimizer, ::MOI.PrimalStatus, value::MOI.ResultStatusCode) = (mock.primalstatus = value) MOI.get(mock::MockSDOptimizer, ::MOI.DualStatus) = mock.dualstatus @@ -129,7 +152,10 @@ end function MOIU.rec_mock_optimize(mock::MockSDOptimizer, opt::Function, opts::Function...) # TODO replace mock.optimize! = ... by MOI.set(..., MOIU.MockOptimizeFunction, ...) # where MOIU.MockOptimizeFunction is a MockModelAttribute - (mock::MockSDOptimizer) -> (opt(mock); mock.optimize! = MOIU.rec_mock_optimize(mock, opts...)) + (mock::MockSDOptimizer) -> begin + opt(mock) + mock.optimize! = MOIU.rec_mock_optimize(mock, opts...) + end end MOIU.rec_mock_optimize(mock::MockSDOptimizer, opt::Function) = opt @@ -140,7 +166,9 @@ function MOIU.mock_optimize!(mock::MockSDOptimizer, termstatus::MOI.TerminationS MOIU.mock_dual!(mock, dual...) end # Default termination status -MOIU.mock_optimize!(mock::MockSDOptimizer, primdual...) = MOIU.mock_optimize!(mock, MOI.Success, primdual...) +function MOIU.mock_optimize!(mock::MockSDOptimizer, primdual...) + MOIU.mock_optimize!(mock, MOI.Optimal, primdual...) +end function MOIU.mock_optimize!(mock::MockSDOptimizer, termstatus::MOI.TerminationStatusCode) MOI.set(mock, MOI.TerminationStatus(), termstatus) end diff --git a/test/contconic.jl b/test/contconic.jl index d045c97..7d2b886 100644 --- a/test/contconic.jl +++ b/test/contconic.jl @@ -17,10 +17,12 @@ [70.2006, -7.0, -2.0, 4.0])) MOIT.lin2vtest(cached_mock_optimizer, config) MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock, + MOI.Infeasible, MOI.InfeasiblePoint, [-0.5, 0.5])) MOIT.lin3test(cached_mock_optimizer, config) MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock, + MOI.Infeasible, MOI.InfeasiblePoint, [-1.0])) MOIT.lin4test(cached_mock_optimizer, config) @@ -43,6 +45,7 @@ [-1.4142, 1.0, -0.7071, -1.0, -0.3536, 1.0, 0.7071, -0.3536])) MOIT.soc2ptest(MOIB.SOCtoPSD{Float64}(cached_mock_optimizer), config) MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock, + MOI.Infeasible, MOI.InfeasiblePoint, [-1.0, 1.0, -0.5, 1.0, -0.5])) MOIT.soc3test(MOIB.SOCtoPSD{Float64}(cached_mock_optimizer), config) @@ -61,6 +64,7 @@ [5183.15, 5182.44, -1.4142, 1.0, -0.1768, 1.0, -0.3536, -0.1768])) MOIT.rotatedsoc1vtest(MOIB.RSOCtoPSD{Float64}(cached_mock_optimizer), config) MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock, + MOI.Infeasible, tuple(), [141.088, -47.8864, 47.5533, -46.2201])) MOIT.rotatedsoc2test(MOIB.RSOCtoPSD{Float64}(cached_mock_optimizer), config) diff --git a/test/contlinear.jl b/test/contlinear.jl index 1a0adcf..9602055 100644 --- a/test/contlinear.jl +++ b/test/contlinear.jl @@ -80,13 +80,16 @@ MOIT.linear7test(cached_mock_optimizer, config) MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock, + MOI.Infeasible, tuple(), [1.0])) MOIT.linear8atest(cached_mock_optimizer, config) MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock, + MOI.DualInfeasible, (MOI.InfeasibilityCertificate, [[0.7709], [0.2291], [0.3126]]))) MOIT.linear8btest(cached_mock_optimizer, config) MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock, + MOI.DualInfeasible, (MOI.InfeasibilityCertificate, [[0.5], [0.5]]))) MOIT.linear8ctest(cached_mock_optimizer, config) MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock, @@ -114,6 +117,7 @@ [-1.0, 0.0])) MOIT.linear11test(cached_mock_optimizer, config) MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock, + MOI.Infeasible, tuple(), [1.0, 3.0])) MOIT.linear12test(cached_mock_optimizer, config) diff --git a/test/runtests.jl b/test/runtests.jl index 63691d8..dbd2d74 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -25,8 +25,17 @@ MOIU.@model(SDModelData, mock = SDOI.MockSDOptimizer{Float64}() mock_optimizer = SDOI.SDOIOptimizer(mock, Float64) +@testset "supports_allocate_load" begin + @test MOIU.supports_allocate_load(mock_optimizer, false) + @test !MOIU.supports_allocate_load(mock_optimizer, true) +end cached_mock_optimizer = MOIU.CachingOptimizer(SDModelData{Float64}(), mock_optimizer) +@testset "SolverName" begin + @test MOI.get( mock, MOI.SolverName()) == "MockSD" + @test MOI.get( mock_optimizer, MOI.SolverName()) == "MockSD" + @test MOI.get(cached_mock_optimizer, MOI.SolverName()) == "MockSD" +end config = MOIT.TestConfig(atol=1e-4, rtol=1e-4) include("unit.jl")