Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/MosekTools.jl
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,11 @@ mutable struct Optimizer <: MOI.AbstractOptimizer
dpars::Dict{String,Float64}
# String parameters, i.e. parameters starting with `MSK_SPAR_`
spars::Dict{String,AbstractString}

# Mosek stores the primal start in the solution vector. We don't want to
# overwrite it, so keep a separate copy.
variable_primal_start::Dict{MOI.VariableIndex,Float64}

has_variable_names::Bool

# Mappings for MOI.ConstraintName
Expand Down Expand Up @@ -161,6 +166,7 @@ mutable struct Optimizer <: MOI.AbstractOptimizer
Dict{String,Int32}(), # ipars
Dict{String,Float64}(), # dpars
Dict{String,AbstractString}(), # spars
Dict{MOI.VariableIndex,Float64}(), # variable_primal_start
false, # has_variable_names
Dict{MOI.ConstraintIndex,String}(), # con_to_name
nothing, # name_to_con
Expand Down Expand Up @@ -501,6 +507,7 @@ function MOI.empty!(model::Optimizer)
if !model.be_quiet
Mosek.putstreamfunc(model.task, Mosek.MSK_STREAM_LOG, m -> print(m))
end
empty!(model.variable_primal_start)
model.has_variable_names = false
empty!(model.con_to_name)
model.name_to_con = nothing
Expand Down
71 changes: 21 additions & 50 deletions src/attributes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,51 +7,6 @@
# TASK ########################################################################
###### The `task` field should not be accessed outside this section. ##########

function set_primal_start(task::Mosek.MSKtask, col::ColumnIndex, value::Float64)
xx = Float64[value]
for sol in [Mosek.MSK_SOL_BAS, Mosek.MSK_SOL_ITG]
Mosek.putxxslice(task, sol, col.value, col.value + Int32(1), xx)
end
return
end

function set_primal_start(m::Optimizer, vi::MOI.VariableIndex, value::Float64)
set_primal_start(m.task, mosek_index(m, vi), value)
return
end

function set_primal_start(
task::Mosek.MSKtask,
cols::ColumnIndices,
values::Vector{Float64},
)
for sol in [Mosek.MSK_SOL_BAS, Mosek.MSK_SOL_ITG]
if Mosek.solutiondef(task, sol)
xx = Mosek.getxx(task, sol)
else
xx = zeros(Float64, Mosek.getnumvar(task))
end
xx[cols.values] = values
Mosek.putxx(task, sol, xx)
end
return
end

function set_primal_start(
m::Optimizer,
vis::Vector{MOI.VariableIndex},
values::Vector{Float64},
)
if all(vi -> is_scalar(m, vi), vis)
set_primal_start(m.task, columns(m, vis), values)
else
for (vi, value) in zip(vis, values)
set_primal_start(m.task, mosek_index(m, vi), value)
end
end
return
end

###############################################################################
## INDEXING ###################################################################
###############################################################################
Expand Down Expand Up @@ -271,26 +226,42 @@
return true
end

function _putxxslice(task::Mosek.MSKtask, col::ColumnIndex, value::Float64)
for sol in [Mosek.MSK_SOL_BAS, Mosek.MSK_SOL_ITG]
Mosek.putxxslice(task, sol, col.value, col.value + Int32(1), [value])
end
return
end

# TODO(odow): I'm not sure how to warm-start PSD matrices
_putxxslice(::Mosek.MSKtask, ::MatrixIndex, ::Float64) = nothing

Check warning on line 237 in src/attributes.jl

View check run for this annotation

Codecov / codecov/patch

src/attributes.jl#L237

Added line #L237 was not covered by tests

function MOI.set(
m::Optimizer,
::MOI.VariablePrimalStart,
v::MOI.VariableIndex,
val::Union{Nothing,Float64},
val::Real,
)
set_primal_start(m, v, something(val, 0.0))
_putxxslice(m.task, mosek_index(m, v), convert(Float64, val))
m.variable_primal_start[v] = convert(Float64, val)
return
end

function MOI.set(
m::Optimizer,
::MOI.VariablePrimalStart,
vis::Vector{MOI.VariableIndex},
values::Vector{Float64},
v::MOI.VariableIndex,
::Nothing,
)
set_primal_start(m, vis, values)
_putxxslice(m.task, mosek_index(m, v), 0.0)
delete!(m.variable_primal_start, v)
return
end

function MOI.get(m::Optimizer, ::MOI.VariablePrimalStart, v::MOI.VariableIndex)
return get(m.variable_primal_start, v, nothing)
end

# function MOI.set(m::Optimizer,attr::MOI.ConstraintDualStart, vs::Vector{MOI.ConstraintIndex}, vals::Vector{Float64})
# subj = columns(vs)

Expand Down
10 changes: 6 additions & 4 deletions src/variable.jl
Original file line number Diff line number Diff line change
Expand Up @@ -290,12 +290,14 @@
end

function MOI.get(m::Optimizer, ::MOI.ListOfVariableAttributesSet)
set = MOI.AbstractVariableAttribute[]
ret = MOI.AbstractVariableAttribute[]
if m.has_variable_names
push!(set, MOI.VariableName())
push!(ret, MOI.VariableName())

Check warning on line 295 in src/variable.jl

View check run for this annotation

Codecov / codecov/patch

src/variable.jl#L295

Added line #L295 was not covered by tests
end
# TODO add VariablePrimalStart when get is implemented on it
return set
if !isempty(m.variable_primal_start)
push!(ret, MOI.VariablePrimalStart())

Check warning on line 298 in src/variable.jl

View check run for this annotation

Codecov / codecov/patch

src/variable.jl#L298

Added line #L298 was not covered by tests
end
return ret
end

## Name #######################################################################
Expand Down
4 changes: 0 additions & 4 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -361,8 +361,6 @@ function test_moi_test_runtests_Mosek()
MosekOptimizerWithFallback(),
config;
exclude = [
# FIXME ArgumentError: MosekTools.Optimizer does not support getting the attribute MathOptInterface.VariablePrimalStart().
"test_model_VariablePrimalStart",
# FIXME
"test_model_duplicate_VariableName",
# Expression: status in (config.optimal_status, MOI.INVALID_MODEL)
Expand Down Expand Up @@ -391,7 +389,6 @@ function test_moi_test_runtests_Bridge_Mosek()
config;
exclude = [
"test_model_duplicate_VariableName",
"test_model_VariablePrimalStart", # able to set but not to get VariablePrimalStart
# Cannot put multiple bound sets of the same type on a variable
"test_basic_VectorAffineFunction_Circuit",
"test_basic_VectorOfVariables_Circuit",
Expand All @@ -405,7 +402,6 @@ function test_moi_test_runtests_Bridge_Mosek()
"test_conic_HermitianPositiveSemidefiniteConeTriangle_1",
],
)
@test MOI.supports(model, MOI.VariablePrimalStart(), MOI.VariableIndex)
return
end

Expand Down
Loading