Skip to content

Commit

Permalink
Updates for MOI 0.8.2 (#84)
Browse files Browse the repository at this point in the history
* Updates for MOI 0.8.2

* Bump versions of test/MINLPTests
  • Loading branch information
odow authored Feb 13, 2019
1 parent b03be7f commit 0aaad31
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 59 deletions.
2 changes: 1 addition & 1 deletion REQUIRE
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
julia 0.6
Compat 1.0
MathProgBase 0.5 0.8
MathOptInterface 0.8.1 0.9
MathOptInterface 0.8.2 0.9
74 changes: 21 additions & 53 deletions src/MOI_wrapper.jl
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
# TODO(odow):
# - remove the `try-catch`es once the following PR is merged
# https://github.com/JuliaOpt/MathOptInterface.jl/pull/623

using MathOptInterface
import MathOptInterface
const MOI = MathOptInterface
const MOIU = MOI.Utilities

Expand Down Expand Up @@ -63,9 +59,9 @@ end
Optimizer(Ipopt.amplexe, ["print_level=0"])
"""
function Optimizer(
solver_command::String,
options::Vector{String} = String[];
filename::String = "")
solver_command::String,
options::Vector{String} = String[];
filename::String = "")
model = MOIU.UniversalFallback(InnerModel{Float64}())
MOI.set(model, MPBSolver(),
AmplNLSolver(solver_command, options, filename = filename)
Expand Down Expand Up @@ -136,7 +132,6 @@ function replace_variableindex_by_int(variable_map, expr::MOI.VariableIndex)
end
replace_variableindex_by_int(variable_map, expr) = expr

# ==============================================================================
# In the next section we match up the MPB nonlinear functions to the MOI API.
# This is basically just a rename.
function MPB.initialize(d::NLPEvaluator, requested_features::Vector{Symbol})
Expand Down Expand Up @@ -184,7 +179,6 @@ function MPB.constr_expr(d::NLPEvaluator, i)
end
end

# ==============================================================================
# In the next section, we need to convert MOI functions and sets into expression
# graphs. First, we convert functions (SingleVariable, ScalarAffine, and
# ScalarQuadratic) into expression graphs.
Expand Down Expand Up @@ -251,7 +245,6 @@ function moi_to_expr_graph(func, set, variable_map)
return funcset_to_expr_graph(func_expr, set)
end

# ==============================================================================
# Now we're ready to optimize model.
function MOI.optimize!(model::Model)
# Extract the MathProgBase solver from the model. Recall it's a MOI
Expand All @@ -269,7 +262,6 @@ function MOI.optimize!(model::Model)
nothing
end

# ==========================================================================
# Extract the nonlinear constraint bounds. We're going to append to these
# g_l and g_u vectors later.
num_con = 0
Expand All @@ -286,7 +278,6 @@ function MOI.optimize!(model::Model)
end
end

# ==========================================================================
# Intialize the variables. We need to form a mapping between the MOI
# VariableIndex and an Int in order to replace instances of
# `x[VariableIndex]` with `x[i]` in the expression graphs.
Expand All @@ -297,7 +288,6 @@ function MOI.optimize!(model::Model)
variable_map[variable] = i
end

# ==========================================================================
# Extract variable bounds.
x_l = fill(-Inf, num_var)
x_u = fill(Inf, num_var)
Expand All @@ -320,7 +310,6 @@ function MOI.optimize!(model::Model)
end
end

# ==========================================================================
# We have to convert all ScalarAffineFunction-in-Set constraints to an
# expression graph.
scalar_constraint_expr = Expr[]
Expand All @@ -339,7 +328,6 @@ function MOI.optimize!(model::Model)
end
end

# ==========================================================================
# MOI objective
obj_type = MOI.get(model, MOI.ObjectiveFunctionType())
obj_func = MOI.get(model, MOI.ObjectiveFunction{obj_type}())
Expand All @@ -348,20 +336,17 @@ function MOI.optimize!(model::Model)
obj_func_expr = nothing
end

# ==========================================================================
# Build the nlp_evaluator
nlp_evaluator = NLPEvaluator(moi_nlp_evaluator, variable_map, num_con,
obj_func_expr, scalar_constraint_expr)

# ==========================================================================
# Create the MathProgBase model. Note that we pass `num_con` and the number
# of linear constraints.
mpb_model = MPB.NonlinearModel(mpb_solver)
MPB.loadproblem!(mpb_model, num_var,
num_con + length(scalar_constraint_expr), x_l, x_u, g_l, g_u, sense,
nlp_evaluator)

# ==========================================================================
# Set any variables to :Bin if they are in ZeroOne and :Int if they are
# Integer. The default is just :Cont.
x_cat = fill(:Cont, num_var)
Expand All @@ -376,25 +361,19 @@ function MOI.optimize!(model::Model)
end
MPB.setvartype!(mpb_model, x_cat)

# ==========================================================================
# Set the VariablePrimalStart attributes for variables.
variable_primal_start = fill(0.0, num_var)
for (i, variable) in enumerate(variables)
try
start_val = MOI.get(model, MOI.VariablePrimalStart(), variable)
if start_val !== nothing
variable_primal_start[i] = start_val
end
catch
start_val = MOI.get(model, MOI.VariablePrimalStart(), variable)
if start_val !== nothing
variable_primal_start[i] = start_val
end
end
MPB.setwarmstart!(mpb_model, variable_primal_start)

# ==========================================================================
# Set the VariablePrimalStart attributes for variables.
# Solve the model!
MPB.optimize!(mpb_model)

# ==========================================================================
# Extract and save the MathProgBase solution.
primal_solution = Dict{MOI.VariableIndex, Float64}()
for (variable, sol) in zip(variables, MPB.getsolution(mpb_model))
Expand All @@ -409,17 +388,18 @@ function MOI.optimize!(model::Model)
return
end

# ==============================================================================
# MOI accessors for the solution info.

function mpb_solution_attribute(model::Model)
# We'd like to call MOI.get(model, MPBSolutionAttribute()), but it throws an
# error if not set rather than return `nothing`.
return get(model.modattr, MPBSolutionAttribute(), nothing)
end

function MOI.get(model::Model, ::MOI.VariablePrimal, var::MOI.VariableIndex)
mpb_solution = try
MOI.get(model, MPBSolutionAttribute())
catch
nothing
end
mpb_solution = mpb_solution_attribute(model)
if mpb_solution === nothing
return nothing
return
end
return mpb_solution.primal_solution[var]
end
Expand All @@ -429,23 +409,15 @@ function MOI.get(model::Model, ::MOI.ConstraintPrimal, idx::MOI.ConstraintIndex)
end

function MOI.get(model::Model, ::MOI.ObjectiveValue)
mpb_solution = try
MOI.get(model, MPBSolutionAttribute())
catch
nothing
end
mpb_solution = mpb_solution_attribute(model)
if mpb_solution === nothing
return nothing
return
end
return mpb_solution.objective_value
end

function MOI.get(model::Model, ::MOI.TerminationStatus)
mpb_solution = try
MOI.get(model, MPBSolutionAttribute())
catch
nothing
end
mpb_solution = mpb_solution_attribute(model)
if mpb_solution === nothing
return MOI.OPTIMIZE_NOT_CALLED
end
Expand All @@ -467,11 +439,7 @@ function MOI.get(model::Model, ::MOI.TerminationStatus)
end

function MOI.get(model::Model, ::MOI.PrimalStatus)
mpb_solution = try
MOI.get(model, MPBSolutionAttribute())
catch
nothing
end
mpb_solution = mpb_solution_attribute(model)
if mpb_solution === nothing
return MOI.NO_SOLUTION
end
Expand All @@ -482,7 +450,7 @@ function MOI.get(model::Model, ::MOI.PrimalStatus)
return MOI.NO_SOLUTION
end

function MOI.get(model::Model, ::MOI.DualStatus)
function MOI.get(::Model, ::MOI.DualStatus)
return MOI.NO_SOLUTION
end

Expand Down
10 changes: 5 additions & 5 deletions test/MINLPTests/Manifest.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab"

[[DiffResults]]
deps = ["Compat", "StaticArrays"]
git-tree-sha1 = "db8acf46717b13d6c48deb7a12007c7f85a70cf7"
git-tree-sha1 = "34a4a1e8be7bc99bc9c611b895b5baf37a80584c"
uuid = "163ba53b-c6d8-5494-b064-1a9d43ac40c5"
version = "0.0.3"
version = "0.0.4"

[[DiffRules]]
deps = ["Random", "Test"]
Expand Down Expand Up @@ -79,7 +79,7 @@ version = "0.5.3"

[[JuMP]]
deps = ["Calculus", "DataStructures", "ForwardDiff", "LinearAlgebra", "MathOptInterface", "NaNMath", "Random", "SparseArrays", "Statistics", "Test"]
git-tree-sha1 = "fb4c9d5a3cf974859c2090eb3b71d06d948307af"
git-tree-sha1 = "205bce386c5647adfac47f9b60de715748aabd20"
repo-rev = "master"
repo-url = "https://github.com/JuliaOpt/JuMP.jl.git"
uuid = "4076af6c-e467-56ae-b986-b466b2749572"
Expand Down Expand Up @@ -112,9 +112,9 @@ uuid = "d6f4376e-aef5-505a-96c1-9c027394607a"

[[MathOptInterface]]
deps = ["Compat", "Unicode"]
git-tree-sha1 = "6f3df4b5346485b299ae5d2b313ecb428bb46bb9"
git-tree-sha1 = "e3c7fb842078f5cd9a21ecb911dc59a4282e3d01"
uuid = "b8f27783-ece8-5eb3-8dc8-9495eed66fee"
version = "0.8.1"
version = "0.8.2"

[[MathProgBase]]
deps = ["Compat"]
Expand Down
1 change: 1 addition & 0 deletions test/MOI_wrapper.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const CONFIG = MOIT.TestConfig(
"solve_objbound_edge_cases", # ObjectiveBound not implemented
"solve_integer_edge_cases", # Ipopt doesn't handle integer
"solve_affine_deletion_edge_cases", # VectorAffineFunction
"solve_duplicate_terms_vector_affine", # VectorAffineFunction
# It seems that the AMPL NL reader declares NL files with no objective
# and no constraints as corrupt, even if they have variable bounds. Yuk.
"solve_blank_obj"
Expand Down

0 comments on commit 0aaad31

Please sign in to comment.