Skip to content

Commit

Permalink
update for big MOI renaming
Browse files Browse the repository at this point in the history
solver -> optimizer
solve() -> optimize()
  • Loading branch information
mlubin committed Feb 11, 2018
1 parent 1cc5e7f commit eb38219
Show file tree
Hide file tree
Showing 6 changed files with 157 additions and 153 deletions.
80 changes: 42 additions & 38 deletions src/JuMP.jl
Expand Up @@ -38,7 +38,7 @@ export
setobjectivesense,
writeLP, writeMPS,
#addSOS1, addSOS2,
solve,
optimize,
internalmodel,
# Variable
setname,
Expand Down Expand Up @@ -74,16 +74,16 @@ const MOIFIX = MOICON{MOI.SingleVariable,MOI.EqualTo{Float64}}
const MOIINT = MOICON{MOI.SingleVariable,MOI.Integer}
const MOIBIN = MOICON{MOI.SingleVariable,MOI.ZeroOne}

@MOIU.instance JuMPInstance (ZeroOne, Integer) (EqualTo, GreaterThan, LessThan, Interval) (Zeros, Nonnegatives, Nonpositives, SecondOrderCone, RotatedSecondOrderCone, GeometricMeanCone, PositiveSemidefiniteConeTriangle, PositiveSemidefiniteConeSquare, RootDetConeTriangle, RootDetConeSquare, LogDetConeTriangle, LogDetConeSquare) () (SingleVariable,) (ScalarAffineFunction,ScalarQuadraticFunction) (VectorOfVariables,) (VectorAffineFunction,)
@MOIU.model JuMPMOIModel (ZeroOne, Integer) (EqualTo, GreaterThan, LessThan, Interval) (Zeros, Nonnegatives, Nonpositives, SecondOrderCone, RotatedSecondOrderCone, GeometricMeanCone, PositiveSemidefiniteConeTriangle, PositiveSemidefiniteConeSquare, RootDetConeTriangle, RootDetConeSquare, LogDetConeTriangle, LogDetConeSquare) () (SingleVariable,) (ScalarAffineFunction,ScalarQuadraticFunction) (VectorOfVariables,) (VectorAffineFunction,)

###############################################################################
# Model

# Model has three modes:
# 1) Automatic: moibackend field holds an InstanceManager in Automatic mode.
# 2) Manual: moibackend field holds an InstanceManager in Manual mode.
# 3) Direct: moibackend field holds an AbstractSolverInstance. No extra copy of the instance is stored. The moibackend must support adddconstraint! etc.
# Methods to interact with the InstanceManager are defined in solverinterface.jl.
# 1) Automatic: moibackend field holds a CachingOptimizer in Automatic mode.
# 2) Manual: moibackend field holds a CachingOptimizer in Manual mode.
# 3) Direct: moibackend field holds an AbstractOptimizer. No extra copy of the model is stored. The moibackend must support adddconstraint! etc.
# Methods to interact with the CachingOptimizer are defined in solverinterface.jl.
@enum ModelMode Automatic Manual Direct

abstract type AbstractModel end
Expand Down Expand Up @@ -115,7 +115,7 @@ mutable struct Model <: AbstractModel
# # such that a symmetry-enforcing constraint has been created
# # between sdpconstr[c].terms[i,j] and sdpconstr[c].terms[j,i]
# sdpconstrSym::Vector{Vector{Tuple{Int,Int}}}
moibackend::Union{MOI.AbstractSolverInstance,MOIU.InstanceManager}
moibackend::Union{MOI.AbstractOptimizer,MOIU.CachingOptimizer}
# callbacks
callbacks
# lazycallback
Expand All @@ -124,7 +124,7 @@ mutable struct Model <: AbstractModel

# hook into a solve call...function of the form f(m::Model; kwargs...),
# where kwargs get passed along to subsequent solve calls
solvehook
optimizehook
# # ditto for a print hook
# printhook

Expand All @@ -145,8 +145,7 @@ mutable struct Model <: AbstractModel
# dictionary keyed on an extension-specific symbol
ext::Dict{Symbol,Any}
# Default constructor
function Model(; mode::ModelMode=Automatic, solver=nothing, simplify_nonlinear_expressions::Bool=false)
# TODO need to support MPB also
function Model(; mode::ModelMode=Automatic, backend=nothing, optimizer=nothing, simplify_nonlinear_expressions::Bool=false)
m = new()
# TODO make pretty
m.variabletolowerbound = Dict{MOIVAR,MOILB}()
Expand All @@ -157,23 +156,28 @@ mutable struct Model <: AbstractModel
m.customnames = Variable[]
m.objbound = 0.0
m.objval = 0.0
if mode == Automatic
m.moibackend = MOIU.InstanceManager(JuMPInstance{Float64}(), MOIU.Automatic)
if solver !== nothing
MOIU.resetsolver!(m, solver)
if backend != nothing
# TODO: It would make more sense to not force users to specify Direct mode if they also provide a backend.
@assert mode == Direct
@assert optimizer === nothing
@assert MOI.isempty(backend)
m.moibackend = backend
else
@assert mode != Direct
if mode == Automatic
m.moibackend = MOIU.CachingOptimizer(JuMPMOIModel{Float64}(), MOIU.Automatic)
if optimizer !== nothing
MOIU.resetoptimizer!(m, optimizer)
end
elseif mode == Manual
m.moibackend = MOIU.CachingOptimizer(JuMPMOIModel{Float64}(), MOIU.Manual)
if optimizer !== nothing
MOIU.resetoptimizer!(m, optimizer)
end
end
elseif mode == Manual
m.moibackend = MOIU.InstanceManager(JuMPInstance{Float64}(), MOIU.Manual)
if solver !== nothing
MOIU.resetsolver!(m, solver)
end
else # Direct
@assert solver isa MOI.AbstractSolverInstance
@assert MOI.isempty(solver)
m.moibackend = solver
end
m.callbacks = Any[]
m.solvehook = nothing
m.optimizehook = nothing
# m.printhook = nothing
m.nlpdata = nothing
m.simplify_nonlinear_expressions = simplify_nonlinear_expressions
Expand All @@ -188,7 +192,7 @@ end
# Getters/setters

function mode(m::Model)
if m.moibackend isa MOI.AbstractSolverInstance
if !(m.moibackend isa MOIU.CachingOptimizer)
return Direct
elseif m.moibackend.mode == MOIU.Automatic
return Automatic
Expand Down Expand Up @@ -245,7 +249,7 @@ dualstatus(m::Model) = MOI.get(m, MOI.DualStatus())

# TODO: Implement Base.copy.

setsolvehook(m::Model, f) = (m.solvehook = f)
setoptimizehook(m::Model, f) = (m.optimizehook = f)
setprinthook(m::Model, f) = (m.printhook = f)


Expand Down Expand Up @@ -320,21 +324,21 @@ Base.copy(x::Void, new_model::Model) = nothing
Base.copy(v::AbstractArray{Variable}, new_model::Model) = (var -> Variable(new_model, var.col)).(v)


function solverindex(v::Variable)
function optimizerindex(v::Variable)
if mode(v.m) == Direct
return index(v)
else
@assert v.m.moibackend.state == MOIU.AttachedSolver
return v.m.moibackend.instancetosolvermap[index(v)]
@assert v.m.moibackend.state == MOIU.AttachedOptimizer
return v.m.moibackend.model_to_optimizer_map[index(v)]
end
end

function solverindex(cr::ConstraintRef{Model})
function optimizerindex(cr::ConstraintRef{Model})
if mode(cr.m) == Direct
return index(cr)
else
@assert cr.m.moibackend.state == MOIU.AttachedSolver
return cr.m.moibackend.instancetosolvermap[index(cr)]
@assert cr.m.moibackend.state == MOIU.AttachedOptimizer
return cr.m.moibackend.model_to_optimizer_map[index(cr)]
end
end

Expand Down Expand Up @@ -365,21 +369,21 @@ name(cr::ConstraintRef{Model,<:MOICON}) = MOI.get(cr.m, MOI.ConstraintName(), cr
setname(cr::ConstraintRef{Model,<:MOICON}, s::String) = MOI.set!(cr.m, MOI.ConstraintName(), cr, s)

"""
canget(m::JuMP.Model, attr::MathOptInterface.AbstractInstanceAttribute)::Bool
canget(m::JuMP.Model, attr::MathOptInterface.AbstractModelAttribute)::Bool
Return `true` if one may query the attribute `attr` from the model's MOI backend.
false if not.
"""
MOI.canget(m::Model, attr::MOI.AbstractInstanceAttribute) = MOI.canget(m.moibackend, attr)
MOI.canget(m::Model, attr::MOI.AbstractModelAttribute) = MOI.canget(m.moibackend, attr)
MOI.canget(m::Model, attr::MOI.AbstractVariableAttribute, ::Type{Variable}) = MOI.canget(m.moibackend, attr, MOIVAR)
MOI.canget(m::Model, attr::MOI.AbstractConstraintAttribute, ::Type{ConstraintRef{Model,T}}) where {T <: MOICON} = MOI.canget(m.moibackend, attr, T)

"""
get(m::JuMP.Model, attr::MathOptInterface.AbstractInstanceAttribute)
get(m::JuMP.Model, attr::MathOptInterface.AbstractModelAttribute)
Return the value of the attribute `attr` from model's MOI backend.
"""
MOI.get(m::Model, attr::MOI.AbstractInstanceAttribute) = MOI.get(m.moibackend, attr)
MOI.get(m::Model, attr::MOI.AbstractModelAttribute) = MOI.get(m.moibackend, attr)
function MOI.get(m::Model, attr::MOI.AbstractVariableAttribute, v::Variable)
@assert m === v.m
MOI.get(m.moibackend, attr, index(v))
Expand All @@ -389,7 +393,7 @@ function MOI.get(m::Model, attr::MOI.AbstractConstraintAttribute, cr::Constraint
MOI.get(m.moibackend, attr, index(cr))
end

MOI.set!(m::Model, attr::MOI.AbstractInstanceAttribute, value) = MOI.set!(m.moibackend, attr, value)
MOI.set!(m::Model, attr::MOI.AbstractModelAttribute, value) = MOI.set!(m.moibackend, attr, value)
function MOI.set!(m::Model, attr::MOI.AbstractVariableAttribute, v::Variable, value)
@assert m === v.m
MOI.set!(m.moibackend, attr, index(v), value)
Expand Down Expand Up @@ -520,7 +524,7 @@ include("containers.jl")
include("operators.jl")
# include("writers.jl")
include("macros.jl")
include("solverinterface.jl")
include("optimizerinterface.jl")
# include("callbacks.jl")
include("nlp.jl")
include("print.jl")
Expand Down
2 changes: 1 addition & 1 deletion src/macros.jl
Expand Up @@ -898,7 +898,7 @@ function constructvariable!(m::Model, _error::Function, haslb::Bool, lowerbound:
if integer
setinteger(v)
end
# TODO: MOIU.Instance does not support VariablePrimalStart
# TODO: MOIU.Model does not support VariablePrimalStart
#if hasstart
# setstartvalue(v, start)
#end
Expand Down
44 changes: 44 additions & 0 deletions src/optimizerinterface.jl
@@ -0,0 +1,44 @@
# Copyright 2017, Iain Dunning, Joey Huchette, Miles Lubin, and contributors
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

# These methods directly map to CachingOptimizer methods.
# They cannot be called in Direct mode.
function MOIU.resetoptimizer!(m::Model, optimizer::MOI.AbstractOptimizer)
@assert mode(m) != Direct
MOIU.resetoptimizer!(m.moibackend, optimizer)
end

function MOIU.resetoptimizer!(m::Model)
@assert mode(m) != Direct
MOIU.resetoptimizer!(m.moibackend)
end

function MOIU.dropoptimizer!(m::Model)
@assert mode(m) != Direct
MOIU.dropoptimizer!(m.moibackend)
end

function MOIU.attachoptimizer!(m::Model)
@assert mode(m) != Direct
copyresult = MOIU.attachoptimizer!(m.moibackend)
# TODO: more reliable error reporting
@assert copyresult.status == MOI.CopySuccess
@assert m.moibackend.state == MOIU.AttachedOptimizer
return copyresult
end


function optimize(m::Model;
ignore_optimize_hook=(m.optimizehook===nothing))
# If the user or an extension has provided an optimize hook, call
# that instead of solving the model ourselves
if !ignore_optimize_hook
return m.optimizehook(m)
end

MOI.optimize!(m.moibackend)

return
end
44 changes: 0 additions & 44 deletions src/solverinterface.jl

This file was deleted.

0 comments on commit eb38219

Please sign in to comment.