Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Breaking changes for MOI 0.10.0 #178

Merged
merged 10 commits into from
Sep 7, 2021
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
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ MathOptInterface = "b8f27783-ece8-5eb3-8dc8-9495eed66fee"
BinaryProvider = "~0.5"
CEnum = "0.3, 0.4"
GLPK_jll = "=5.0.0"
MathOptInterface = "~0.9.19"
MathOptInterface = "~0.10.0"
julia = "1"

[extras]
Expand Down
20 changes: 9 additions & 11 deletions perf/runbench.jl
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,8 @@ function generate_moi_problem(model, At, b, c;
A_vals = nonzeros(At)
if var_bounds
for col in 1:cols
MOI.add_constraint(model, MOI.SingleVariable(x[col]),
MOI.LessThan(10.0))
MOI.add_constraint(model, MOI.SingleVariable(x[col]),
MOI.GreaterThan(-10.0))
MOI.add_constraint(model, x[col], MOI.LessThan(10.0))
MOI.add_constraint(model, x[col], MOI.GreaterThan(-10.0))
end
end
if scalar
Expand All @@ -37,7 +35,7 @@ function generate_moi_problem(model, At, b, c;
else
for row in 1:rows
MOI.add_constraint(model, MOI.VectorAffineFunction(
[MOI.VectorAffineTerm(1,
[MOI.VectorAffineTerm(1,
MOI.ScalarAffineTerm(A_vals[i], x[A_cols[i]])
) for i in nzrange(At, row)], [-b[row]]),
MOI.Nonpositives(1))
Expand Down Expand Up @@ -113,7 +111,7 @@ function time_build_and_solve(to_build, to_solve, At, b, c, scalar = true)
end
MOI.set(to_solve, MOI.TimeLimitSec(), 0.0010)
@time @timeit "opt" MOI.optimize!(to_solve)
val = MOI.get(to_solve, MOI.SolveTime())
val = MOI.get(to_solve, MOI.SolveTimeSec())
println(val)
@show MOI.get(to_solve, MOI.ObjectiveValue())
@show MOI.get(to_solve, MOI.TerminationStatus())
Expand All @@ -129,19 +127,19 @@ function solve_GLPK(seed, data; time_limit_sec=Inf)
GC.gc()
bridged_cache, pure_solver = bridged_cache_and_solver()
@timeit "bc + s" time_build_and_solve(bridged_cache, pure_solver, At, b, c)

GC.gc()
cache, pure_solver2 = cache_and_solver()
@timeit "c + s" time_build_and_solve(cache, pure_solver2, At, b, c)

GC.gc()
full_solver = bridged_cached_solver()
@timeit "bcs" time_build_and_solve(full_solver, full_solver, At, b, c)

GC.gc()
full_solver = bridged_cached_solver()
@timeit "bcs + v" time_build_and_solve(full_solver, full_solver, At, b, c, false)

GC.gc()
cache_solver = cached_solver()
@timeit "cs" time_build_and_solve(cache_solver, cache_solver, At, b, c)
Expand All @@ -153,4 +151,4 @@ function solve_GLPK(seed, data; time_limit_sec=Inf)
end

solve_GLPK(2, RandomLP(11, 11, 0.5); time_limit_sec=5)
solve_GLPK(20, RandomLP(10000, 10000, 0.005); time_limit_sec=5)
solve_GLPK(20, RandomLP(10000, 10000, 0.005); time_limit_sec=5)
5 changes: 4 additions & 1 deletion src/GLPK.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ if haskey(ENV, "JULIA_GLPK_LIBRARY_PATH") || VERSION < v"1.3"
if isfile(deps_file)
include(deps_file)
else
error("GLPK not properly installed. Please run import `Pkg; Pkg.build(\"GLPK\")`.")
error(
"GLPK not properly installed. Please run " *
"`import Pkg; Pkg.build(\"GLPK\")`.",
)
end
else
import GLPK_jll: libglpk
Expand Down
59 changes: 32 additions & 27 deletions src/MOI_wrapper/MOI_copy.jl
Original file line number Diff line number Diff line change
Expand Up @@ -37,25 +37,36 @@ Throw an error if unsupported constraint or objective types are present in
`src`.
"""
function _validate_constraint_types(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}(
"GLPK.Optimizer does not support constraints of type $F-in-$S.",
),
)
end
for attr in MOI.get(src, MOI.ListOfConstraintAttributesSet{F,S}())
if !MOI.supports(dest, attr, MOI.ConstraintIndex{F,S})
throw(MOI.UnsupportedAttribute(attr))
end
end
end
for attr in MOI.get(src, MOI.ListOfModelAttributesSet())
if !MOI.supports(dest, attr)
throw(MOI.UnsupportedAttribute(attr))
end
end
fobj_type = MOI.get(src, MOI.ObjectiveFunctionType())
if !MOI.supports(dest, MOI.ObjectiveFunction{fobj_type}())
throw(MOI.UnsupportedAttribute(MOI.ObjectiveFunction(fobj_type)))
for attr in MOI.get(src, MOI.ListOfVariableAttributesSet())
if !MOI.supports(dest, attr, MOI.VariableIndex)
throw(MOI.UnsupportedAttribute(attr))
end
end
return
end

function _init_index_map(src::MOI.ModelLike)
variables = MOI.get(src, MOI.ListOfVariableIndices())
map = MOIU.IndexMap()
map = MOI.Utilities.IndexMap()
N = 0
for x in variables
N += 1
Expand All @@ -82,22 +93,22 @@ function _add_set_data(cache, i, s::MOI.Interval{Float64})
end

function _extract_bound_data(src, map, cache, s::Type{S}) where {S}
for ci in MOI.get(src, MOI.ListOfConstraintIndices{MOI.SingleVariable,S}())
for ci in MOI.get(src, MOI.ListOfConstraintIndices{MOI.VariableIndex,S}())
f = MOI.get(src, MOI.ConstraintFunction(), ci)
s = MOI.get(src, MOI.ConstraintSet(), ci)
column = map[f.variable].value
column = map[f].value
_add_set_data(cache, column, s)
map[ci] = MOI.ConstraintIndex{MOI.SingleVariable,S}(column)
map[ci] = MOI.ConstraintIndex{MOI.VariableIndex,S}(column)
end
return
end

function _extract_type_data(src, map, cache, ::Type{S}) where {S}
for ci in MOI.get(src, MOI.ListOfConstraintIndices{MOI.SingleVariable,S}())
for ci in MOI.get(src, MOI.ListOfConstraintIndices{MOI.VariableIndex,S}())
f = MOI.get(src, MOI.ConstraintFunction(), ci)
column = map[f.variable].value
column = map[f].value
cache.types[column] = S == MOI.Integer ? INTEGER : BINARY
map[ci] = MOI.ConstraintIndex{MOI.SingleVariable,S}(column)
map[ci] = MOI.ConstraintIndex{MOI.VariableIndex,S}(column)
end
return
end
Expand All @@ -110,8 +121,8 @@ function _extract_row_data(src, map, cache, ::Type{S}) where {S}
MOI.ListOfConstraintIndices{MOI.ScalarAffineFunction{Float64},S}(),
)::Vector{MOI.ConstraintIndex{MOI.ScalarAffineFunction{Float64},S}}
f = MOI.get(src, MOI.ConstraintFunction(), ci)
if !MOIU.is_canonical(f)
f = MOIU.canonical(f)
if !MOI.Utilities.is_canonical(f)
f = MOI.Utilities.canonical(f)
end
l, u = _bounds(MOI.get(src, MOI.ConstraintSet(), ci))
push!(cache.rl, l === nothing ? -Inf : l - f.constant)
Expand All @@ -122,7 +133,7 @@ function _extract_row_data(src, map, cache, ::Type{S}) where {S}
for term in f.terms
nnz += 1
cache.I[nnz] = row
cache.J[nnz] = Cint(map[term.variable_index].value::Int64)
cache.J[nnz] = Cint(map[term.variable].value::Int64)
cache.V[nnz] = term.coefficient
end
map[ci] = MOI.ConstraintIndex{MOI.ScalarAffineFunction{Float64},S}(row)
Expand All @@ -137,9 +148,9 @@ function _add_all_variables(model::Optimizer, cache::_OptimizerCache)
sizehint!(model.variable_info, N)
for i in 1:N
bound = get_moi_bound_type(cache.cl[i], cache.cu[i], cache.bounds[i])
index = CleverDicts.add_item(
CleverDicts.add_item(
model.variable_info,
VariableInfo(MOI.VariableIndex(i), i, bound, cache.types[i]),
VariableInfo(MOI.VariableIndex(i), i, bound, cache.types[i], ""),
)
glp_bound_type = get_glp_bound_type(cache.cl[i], cache.cu[i])
glp_set_col_bnds(model, i, glp_bound_type, cache.cl[i], cache.cu[i])
Expand Down Expand Up @@ -193,12 +204,7 @@ function _add_all_constraints(dest::Optimizer, cache::_OptimizerCache)
return
end

function MOI.copy_to(
dest::Optimizer,
src::MOI.ModelLike;
copy_names::Bool = false,
kwargs...,
)
function MOI.copy_to(dest::Optimizer, src::MOI.ModelLike)
@assert MOI.is_empty(dest)
_validate_constraint_types(dest, src)
# Initialize the problem storage
Expand All @@ -221,12 +227,11 @@ function MOI.copy_to(
_add_all_variables(dest, cache)
_add_all_constraints(dest, cache)
# Copy model attributes:
MOIU.pass_attributes(dest, src, copy_names, map)
MOIU.pass_attributes(dest, src, copy_names, map, variables)
for (F, S) in MOI.get(src, MOI.ListOfConstraints())
MOI.Utilities.pass_attributes(dest, src, map)
MOI.Utilities.pass_attributes(dest, src, map, variables)
for (F, S) in MOI.get(src, MOI.ListOfConstraintTypesPresent())
indices = MOI.get(src, MOI.ListOfConstraintIndices{F,S}())
# TODO(odow): fix copy_names = false.
MOIU.pass_attributes(dest, src, false, map, indices)
MOI.Utilities.pass_attributes(dest, src, map, indices)
end
return map
end
Loading