-
-
Notifications
You must be signed in to change notification settings - Fork 390
/
solverinterface.jl
107 lines (86 loc) · 3.77 KB
/
solverinterface.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# 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/.
"""
attach(m::JuMP.Model)
Attach the JuMP model `m` to a new solver instance. All instance data is transferred to the solver instance,
and while the solver instance remains attached, all modifications to the JuMP model are immediately mirrored
in the solver instance. See also `isattached()` and `detach()`.
"""
function attach(m::Model, solverinstance::MOI.AbstractSolverInstance)
@assert !m.solverinstanceattached
m.solverinstance = solverinstance
solvervariables = MOI.addvariables!(m.solverinstance, numvar(m)) # TODO numvar shouldn't return unsigned int
m.variabletosolvervariable = Dict{MOIVAR,MOIVAR}()
# TODO: replace with ListOfVariableReferences()
# Now we're assuming all instance variables are numbered sequentially
for i in 1:numvar(m)
m.variabletosolvervariable[MOIVAR(i)] = solvervariables[i]
end
MOI.set!(m.solverinstance, MOI.ObjectiveSense(), MOI.get(m.instance, MOI.ObjectiveSense()))
MOI.set!(m.solverinstance, MOI.ObjectiveFunction(), MOI.get(m.instance, MOI.ObjectiveFunction()))
# TODO: replace with ListOfConstraintReferences()
# This would be a bit more transparent than the call below
# TODO: keep track of constraint references!
MOIU.broadcastcall( constrs -> for (cref, f, s) in constrs; MOI.addconstraint!(m.solverinstance, f, s) end, m.instance)
m.solverinstanceattached = true
nothing
end
"""
isattached(m::JuMP.Model)::Bool
Return `true` if the JuMP model `m` is currently attached to a solver instance,
`false` otherwise.
"""
function isattached(m::Model)
return m.solverinstanceattached
end
"""
detach(m::JuMP.Model)
Detach the JuMP model `m` from the attached solver instance, after calling
`MathOptInterface.free!` on it to release any resources in use.
Throws an error if no solver instance is currently attached.
"""
function detach(m::Model)
@assert m.solverinstanceattached
m.solverinstanceattached = false
MOI.free!(m.solverinstance)
m.solverinstance = nothing
end
"""
canget(m::JuMP.Model, attr::MathOptInterface.AbstractInstanceAttribute)::Bool
Return `true` if one may query the attribute `attr` from the solver instance attached to the JuMP model,
false if not.
Throws an error if no solver instance is currently attached.
"""
function MOI.canget(m::Model, attr::MOI.AbstractInstanceAttribute)
@assert m.solverinstanceattached
return MOI.canget(m.solverinstance, attr)
end
"""
get(m::JuMP.Model, attr::MathOptInterface.AbstractInstanceAttribute)
Return the value of the attribute `attr` from the solver instance attached to the JuMP model.
Throws an error if no solver instance is currently attached.
"""
function MOI.get(m::Model, attr::MOI.AbstractInstanceAttribute)
@assert m.solverinstanceattached
return MOI.get(m.solverinstance, attr)
end
function solve(m::Model;
ignore_solve_hook=(m.solvehook===nothing))
# If the user or an extension has provided a solve hook, call
# that instead of solving the model ourselves
if !ignore_solve_hook
return m.solvehook(m)
end
@assert m.solverinstanceattached
MOI.optimize!(m.solverinstance)
empty!(m.variableresult)
# If any variable has a result then all must have
if MOI.canget(m.solverinstance, MOI.VariablePrimal(), first(m.variabletosolvervariable).second)
for vref in keys(m.variabletosolvervariable)
m.variableresult[Variable(m,vref)] = MOI.get(m.solverinstance, MOI.VariablePrimal(), m.variabletosolvervariable[vref])
end
end
nothing
end