Skip to content

Commit

Permalink
WIP: breaking changes for MOI 0.10.0
Browse files Browse the repository at this point in the history
  • Loading branch information
odow committed Aug 10, 2021
1 parent 94427d2 commit 84b60fc
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 59 deletions.
1 change: 1 addition & 0 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ version = "0.2.1"
[deps]
HiGHS_jll = "8fd58aa0-07eb-5a78-9b36-339c94fd15ea"
MathOptInterface = "b8f27783-ece8-5eb3-8dc8-9495eed66fee"
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"

[compat]
Expand Down
49 changes: 23 additions & 26 deletions src/MOI_wrapper.jl
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,7 @@ function MOI.get(model::Optimizer, ::MOI.NumberOfConstraints{F,S}) where {F,S}
return length(MOI.get(model, MOI.ListOfConstraintIndices{F,S}()))
end

function MOI.get(model::Optimizer, ::MOI.ListOfConstraints)
function MOI.get(model::Optimizer, ::MOI.ListOfConstraintTypesPresent)
constraints = Set{Tuple{DataType,DataType}}()
for info in values(model.variable_info)
if info.bound == _BOUND_NONE
Expand Down Expand Up @@ -464,13 +464,10 @@ function MOI.get(model::Optimizer, ::MOI.ListOfConstraints)
end

###
### MOI.RawParameter
### MOI.RawOptimizerAttribute
###

function MOI.supports(model::Optimizer, param::MOI.RawParameter)
if !(param.name isa String)
return false
end
function MOI.supports(model::Optimizer, param::MOI.RawOptimizerAttribute)
typeP = Ref{Cint}()
return Highs_getOptionType(model, param.name, typeP) == 0
end
Expand Down Expand Up @@ -498,7 +495,7 @@ function _set_option(model::Optimizer, option::String, value::String)
return Highs_setStringOptionValue(model, option, value)
end

function MOI.set(model::Optimizer, param::MOI.RawParameter, value)
function MOI.set(model::Optimizer, param::MOI.RawOptimizerAttribute, value)
if !MOI.supports(model, param)
throw(MOI.UnsupportedAttribute(param))
end
Expand Down Expand Up @@ -540,7 +537,7 @@ function _get_string_option(model::Optimizer, option::String)
end
end

function MOI.get(model::Optimizer, param::MOI.RawParameter)
function MOI.get(model::Optimizer, param::MOI.RawOptimizerAttribute)
if !(param.name isa String)
throw(MOI.UnsupportedAttribute(param))
end
Expand All @@ -567,15 +564,15 @@ end
MOI.supports(::Optimizer, ::MOI.TimeLimitSec) = true

function MOI.set(model::Optimizer, ::MOI.TimeLimitSec, ::Nothing)
return MOI.set(model, MOI.RawParameter("time_limit"), Inf)
return MOI.set(model, MOI.RawOptimizerAttribute("time_limit"), Inf)
end

function MOI.set(model::Optimizer, ::MOI.TimeLimitSec, limit::Real)
return MOI.set(model, MOI.RawParameter("time_limit"), Float64(limit))
return MOI.set(model, MOI.RawOptimizerAttribute("time_limit"), Float64(limit))
end

function MOI.get(model::Optimizer, ::MOI.TimeLimitSec)
return MOI.get(model, MOI.RawParameter("time_limit"))
return MOI.get(model, MOI.RawOptimizerAttribute("time_limit"))
end

###
Expand Down Expand Up @@ -779,7 +776,7 @@ function MOI.set(
num_vars = length(model.variable_info)
obj = zeros(Float64, num_vars)
for term in f.terms
col = column(model, term.variable_index)
col = column(model, term.variable)
obj[col+1] += term.coefficient
end
# TODO(odow): cache the mask.
Expand Down Expand Up @@ -1256,7 +1253,7 @@ function _indices_and_coefficients(
)
i = 1
for term in f.terms
indices[i] = column(model, term.variable_index)
indices[i] = column(model, term.variable)
coefficients[i] = term.coefficient
i += 1
end
Expand Down Expand Up @@ -1534,9 +1531,9 @@ function MOI.set(
# complains but it will require some upstream changes to introduce a faster
# way of modifying a list of coefficients.
old = MOI.get(model, MOI.ConstraintFunction(), c)
terms = Dict(x.variable_index => 0.0 for x in old.terms)
terms = Dict(x.variable => 0.0 for x in old.terms)
for term in f.terms
terms[term.variable_index] = term.coefficient
terms[term.variable] = term.coefficient
end
r = row(model, c)
for (k, v) in terms
Expand Down Expand Up @@ -1676,7 +1673,7 @@ function MOI.get(model::Optimizer, ::MOI.RawStatusString)
end

function MOI.get(model::Optimizer, attr::MOI.PrimalStatus)
if attr.N != 1
if attr.result_index != 1
return MOI.NO_SOLUTION
elseif model.solution.has_primal_solution
return MOI.FEASIBLE_POINT
Expand All @@ -1687,7 +1684,7 @@ function MOI.get(model::Optimizer, attr::MOI.PrimalStatus)
end

function MOI.get(model::Optimizer, attr::MOI.DualStatus)
if attr.N != 1
if attr.result_index != 1
return MOI.NO_SOLUTION
elseif model.solution.has_dual_solution
return MOI.FEASIBLE_POINT
Expand Down Expand Up @@ -1718,7 +1715,7 @@ function MOI.get(model::Optimizer, ::MOI.ObjectiveBound)
return sense == -1 ? max(primal, -p[]) : min(primal, p[])
end

function MOI.get(model::Optimizer, ::MOI.SolveTime)
function MOI.get(model::Optimizer, ::MOI.SolveTimeSec)
return Highs_getRunTime(model)
end

Expand Down Expand Up @@ -2107,11 +2104,11 @@ function _extract_bound_data(
MOI.get(src, MOI.ListOfConstraintIndices{MOI.SingleVariable,S}())
f = MOI.get(src, MOI.ConstraintFunction(), c_index)
s = MOI.get(src, MOI.ConstraintSet(), c_index)
new_f = mapping.varmap[f.variable]
new_f = mapping[f.variable]
info = _info(dest, new_f)
_add_bounds(collower, colupper, info.column + 1, s)
_update_info(info, s)
mapping.conmap[c_index] =
mapping[c_index] =
MOI.ConstraintIndex{MOI.SingleVariable,S}(new_f.value)
end
return
Expand All @@ -2129,13 +2126,13 @@ function _copy_to_columns(dest::Optimizer, src::MOI.ModelLike, mapping)
info.name = MOI.get(dest, MOI.VariableName(), x_src[i])
info.index = index
info.column = Cint(i - 1)
mapping.varmap[x_src[i]] = index
mapping[x_src[i]] = index
end
fobj =
MOI.get(src, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}())
c = fill(0.0, numcols)
for term in fobj.terms
i = mapping.varmap[term.variable_index].value
i = mapping[term.variable].value
c[i] += term.coefficient
end
ret = Highs_changeObjectiveOffset(dest, fobj.constant)
Expand Down Expand Up @@ -2180,7 +2177,7 @@ function _extract_row_data(
)
dest.affine_constraint_info[key].row =
Cint(length(dest.affine_constraint_info) - 1)
mapping.conmap[c_index] =
mapping[c_index] =
MOI.ConstraintIndex{MOI.ScalarAffineFunction{Float64},S}(key.value)
end
_add_sizehint!(I, n_terms)
Expand All @@ -2189,7 +2186,7 @@ function _extract_row_data(
for f in fs
for term in f.terms
push!(I, row)
push!(J, Cint(mapping.varmap[term.variable_index].value))
push!(J, Cint(mapping[term.variable].value))
push!(V, term.coefficient)
end
row += 1
Expand All @@ -2198,7 +2195,7 @@ function _extract_row_data(
end

function _check_input_data(dest::Optimizer, src::MOI.ModelLike)
for (F, S) in MOI.get(src, MOI.ListOfConstraints())
for (F, S) in MOI.get(src, MOI.ListOfConstraintTypesPresent())
if !MOI.supports_constraint(dest, F, S)
throw(
MOI.UnsupportedConstraint{F,S}(
Expand All @@ -2214,7 +2211,7 @@ function _check_input_data(dest::Optimizer, src::MOI.ModelLike)
return
end

MOI.Utilities.supports_default_copy_to(::Optimizer, ::Bool) = true
MOI.supports_incremental_interface(::Optimizer, ::Bool) = true

function MOI.copy_to(
dest::Optimizer,
Expand Down
60 changes: 27 additions & 33 deletions test/MOI_wrapper.jl
Original file line number Diff line number Diff line change
Expand Up @@ -413,28 +413,29 @@ end

function test_HiGHS_custom_options(::Any, ::Any)
model = HiGHS.Optimizer()
@test MOI.supports(model, MOI.RawParameter("solver"))
@test MOI.get(model, MOI.RawParameter("solver")) == "choose"
MOI.set(model, MOI.RawParameter("solver"), "simplex")
@test MOI.get(model, MOI.RawParameter("solver")) == "simplex"
@test MOI.supports(model, MOI.RawOptimizerAttribute("solver"))
@test MOI.get(model, MOI.RawOptimizerAttribute("solver")) == "choose"
MOI.set(model, MOI.RawOptimizerAttribute("solver"), "simplex")
@test MOI.get(model, MOI.RawOptimizerAttribute("solver")) == "simplex"
@test MOI.get(model, MOI.RawParameter("output_flag")) == true
MOI.set(model, MOI.RawParameter("output_flag"), false)
@test MOI.get(model, MOI.RawParameter("output_flag")) == false
@test MOI.get(model, MOI.RawParameter("time_limit")) > 1000
MOI.set(model, MOI.RawParameter("time_limit"), 1000.0)
@test MOI.get(model, MOI.RawParameter("time_limit")) == 1000.0
@test MOI.get(model, MOI.RawOptimizerAttribute("time_limit")) > 1000
MOI.set(model, MOI.RawOptimizerAttribute("time_limit"), 1000.0)
@test MOI.get(model, MOI.RawOptimizerAttribute("time_limit")) == 1000.0
# unsupported test
@test MOI.supports(model, MOI.RawParameter("wrong_param")) == false
@test_throws MOI.UnsupportedAttribute MOI.get(
model,
MOI.RawParameter("wrong_param"),
@test MOI.supports(model, MOI.RawOptimizerAttribute("wrong_param")) == false
@test_throws(
MOI.UnsupportedAttribute,
MOI.get(model, MOI.RawOptimizerAttribute("wrong_param")),
)
for v in [false, 1, 1.0, "A"]
@test_throws(
MOI.UnsupportedAttribute,
MOI.set(model, MOI.RawParameter("wrong_param"), v)
MOI.set(model, MOI.RawOptimizerAttribute("wrong_param"), v)
)
end
return
end

function test_Model_empty(model, ::Any)
Expand Down Expand Up @@ -483,9 +484,9 @@ function test_options(model, ::Any)
"presolve", # String
]
for key in options
v = MOI.get(model, MOI.RawParameter(key))
MOI.set(model, MOI.RawParameter(key), v)
v2 = MOI.get(model, MOI.RawParameter(key))
v = MOI.get(model, MOI.RawOptimizerAttribute(key))
MOI.set(model, MOI.RawOptimizerAttribute(key), v)
v2 = MOI.get(model, MOI.RawOptimizerAttribute(key))
@test v == v2
end
return
Expand All @@ -496,16 +497,7 @@ function test_option_invalid(model, ::Any)
ErrorException(
"Encountered an error in HiGHS: Check the log for details.",
),
MOI.set(model, MOI.RawParameter("time_limit"), -1.0),
)
return
end

function test_option_invalid(model, ::Any)
MOI.supports(model, MOI.RawParameter(:presolve)) == false
@test_throws MOI.UnsupportedAttribute MOI.get(
model,
MOI.RawParameter(:presolve),
MOI.set(model, MOI.RawOptimizerAttribute("time_limit"), -1.0),
)
return
end
Expand All @@ -514,14 +506,16 @@ function test_option_unknown_option(model, ::Any)
err = ErrorException(
"Encountered an error in HiGHS: Check the log for details.",
)
@test_throws err MOI.set(
model,
MOI.RawParameter("write_solution_to_file"),
1,
@test_throws(
err,
MOI.set(model, MOI.RawOptimizerAttribute("write_solution_to_file"), 1),
)
@test_throws(
err,
MOI.set(model, MOI.RawOptimizerAttribute("simplex_strategy"), "on"),
)
@test_throws err MOI.set(model, MOI.RawParameter("simplex_strategy"), "on")
@test_throws err MOI.set(model, MOI.RawParameter("time_limit"), 1)
@test_throws err MOI.set(model, MOI.RawParameter("presolve"), 1)
@test_throws err MOI.set(model, MOI.RawOptimizerAttribute("time_limit"), 1)
@test_throws err MOI.set(model, MOI.RawOptimizerAttribute("presolve"), 1)
return
end

Expand All @@ -545,7 +539,7 @@ c8: w + x in MathOptInterface.Interval(1.0, 2.0)
dest = HiGHS.Optimizer()
MOI.copy_to(dest, src)
@test MOI.get(dest, MOI.NumberOfVariables()) == 4
list = MOI.get(dest, MOI.ListOfConstraints())
list = MOI.get(dest, MOI.ListOfConstraintTypesPresent())
@test length(list) == 8
for S in (
MOI.GreaterThan{Float64},
Expand Down
5 changes: 5 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
if get(ENV, "GITHUB_ACTIONS", "") == "true"
import Pkg
Pkg.add(Pkg.PackageSpec(name = "MathOptInterface", rev = "master"))
end

using Test

@testset "$(file)" for file in readdir(@__DIR__)
Expand Down

0 comments on commit 84b60fc

Please sign in to comment.