Skip to content

Commit eab5830

Browse files
authored
Add support for un-instantiated inner optimizers (#209)
1 parent b7594e2 commit eab5830

8 files changed

Lines changed: 150 additions & 307 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ Use ParametricOptInterface with JuMP by following this brief example:
3535
```julia
3636
using JuMP, HiGHS
3737
import ParametricOptInterface as POI
38-
model = direct_model(POI.Optimizer(HiGHS.Optimizer()))
38+
model = direct_model(POI.Optimizer(HiGHS.Optimizer))
3939
@variable(model, x)
4040
@variable(model, p in Parameter(1.0))
4141
@constraint(model, cons, x + p >= 3)

benchmark/MOI_benchmarks.jl

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -165,11 +165,7 @@ function solve_moi(
165165
end
166166

167167
function POI_OPTIMIZER()
168-
return POI.Optimizer(SOLVER.Optimizer())
169-
end
170-
171-
function MOI_OPTIMIZER()
172-
return SOLVER.Optimizer()
168+
return POI.Optimizer(SOLVER.Optimizer)
173169
end
174170

175171
function solve_moi_loop(
@@ -194,7 +190,7 @@ function solve_moi_loop(
194190
for _ in 1:loops
195191
solve_moi(
196192
data,
197-
MOI_OPTIMIZER;
193+
SOLVER.Optimizer();
198194
vector_version = vector_version,
199195
params = params,
200196
)

docs/make.jl

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,7 @@ Documenter.makedocs(;
1717
),
1818
sitename = "ParametricOptInterface.jl",
1919
authors = "Tomás Gutierrez, and contributors",
20-
pages = [
21-
"Home" => "index.md",
22-
"reference.md",
23-
],
20+
pages = ["Home" => "index.md", "reference.md"],
2421
checkdocs = :none,
2522
)
2623

src/MOI_wrapper.jl

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1590,17 +1590,6 @@ function MOI.set(
15901590
return MOI.set(model.optimizer, attr, optimizer_ci, val)
15911591
end
15921592

1593-
function MOI.set(
1594-
model::Optimizer,
1595-
attr::MOI.AbstractConstraintAttribute,
1596-
c::MOI.ConstraintIndex{MOI.VariableIndex,MOI.Parameter{T}},
1597-
val,
1598-
) where {T}
1599-
return error(
1600-
"Constraint attribute $attr cannot be set for $c in ParametricOptInterface.",
1601-
)
1602-
end
1603-
16041593
function MOI.get(
16051594
model::Optimizer,
16061595
::MOI.ConstraintPrimal,

src/ParametricOptInterface.jl

Lines changed: 63 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -81,28 +81,63 @@ const DoubleDictInner{F,S,T} = MOI.Utilities.DoubleDicts.DoubleDictInner{F,S,T}
8181
include("parametric_functions.jl")
8282

8383
"""
84-
Optimizer{T, OT <: MOI.ModelLike} <: MOI.AbstractOptimizer
84+
Optimizer{T}(
85+
optimizer::Union{MOI.ModelLike,Any};
86+
evaluate_duals::Bool = true,
87+
save_original_objective_and_constraints::Bool = true,
88+
with_bridge_type = nothing,
89+
)
8590
86-
Declares a `Optimizer`, which allows the handling of parameters in a
91+
Create an `Optimizer`, which allows the handling of parameters in an
8792
optimization model.
8893
94+
If `optimizer` is not a `MOI.ModelLike,` the inner optimizer is constructed
95+
using `MOI.instantiate(optimizer; with_bridge_type)`.
96+
97+
The `{T}` type parameter is optional; it defaults to `Float64`.
98+
8999
## Keyword arguments
90100
91-
- `evaluate_duals::Bool`: If `true`, evaluates the dual of parameters. Users might want to set it to `false`
92-
to increase performance when the duals of parameters are not necessary. Defaults to `true`.
101+
- `evaluate_duals::Bool`: If `true`, evaluates the dual of parameters. Set it to
102+
`false` to increase performance when the duals of parameters are not
103+
necessary. Defaults to `true`.
93104
94-
- `save_original_objective_and_constraints`: If `true` saves the orginal function and set of the constraints
95-
as well as the original objective function inside [`Optimizer`](@ref). This is useful for printing the model
96-
but greatly increases the memory footprint. Users might want to set it to `false` to increase performance
97-
in applications where you don't need to query the original expressions provided to the model in constraints
98-
or in the objective. Note that this might break printing or queries such as `MOI.get(model, MOI.ConstraintFunction(), c)`.
99-
Defaults to `true`.
105+
- `save_original_objective_and_constraints`: If `true` saves the orginal
106+
function and set of the constraints as well as the original objective function
107+
inside [`Optimizer`](@ref). This is useful for printing the model but greatly
108+
increases the memory footprint. Users might want to set it to `false` to
109+
increase performance in applications where you don't need to query the
110+
original expressions provided to the model in constraints or in the objective.
111+
Note that this might break printing or queries such as
112+
`MOI.get(model, MOI.ConstraintFunction(), c)`. Defaults to `true`.
113+
114+
- `with_bridge_type`: this is ignroed if `optimizer::MOI.ModelLike`, otherwise
115+
it is passed to `MOI.instantiate`.
100116
101117
## Example
102118
103119
```julia-repl
104-
julia> ParametricOptInterface.Optimizer(HiGHS.Optimizer())
105-
ParametricOptInterface.Optimizer{Float64,HiGHS.Optimizer}
120+
julia> import ParametricOptInterface as POI
121+
122+
julia> import HiGHS
123+
124+
julia> POI.Optimizer(HiGHS.Optimizer(); evaluate_duals = true)
125+
ParametricOptInterface.Optimizer{Float64, HiGHS.Optimizer}
126+
├ ObjectiveSense: FEASIBILITY_SENSE
127+
├ ObjectiveFunctionType: MOI.ScalarAffineFunction{Float64}
128+
├ NumberOfVariables: 0
129+
└ NumberOfConstraints: 0
130+
131+
julia> POI.Optimizer(
132+
HiGHS.Optimizer;
133+
with_bridge_type = Float64,
134+
evaluate_duals = false,
135+
)
136+
ParametricOptInterface.Optimizer{Float64, MOIB.LazyBridgeOptimizer{HiGHS.Optimizer}}
137+
├ ObjectiveSense: FEASIBILITY_SENSE
138+
├ ObjectiveFunctionType: MOI.ScalarAffineFunction{Float64}
139+
├ NumberOfVariables: 0
140+
└ NumberOfConstraints: 0
106141
```
107142
"""
108143
mutable struct Optimizer{T,OT<:MOI.ModelLike} <: MOI.AbstractOptimizer
@@ -183,11 +218,12 @@ mutable struct Optimizer{T,OT<:MOI.ModelLike} <: MOI.AbstractOptimizer
183218

184219
# extension data
185220
ext::Dict{Symbol,Any}
221+
186222
function Optimizer{T}(
187223
optimizer::OT;
188224
evaluate_duals::Bool = true,
189225
save_original_objective_and_constraints::Bool = true,
190-
) where {T,OT}
226+
) where {T,OT<:MOI.ModelLike}
191227
return new{T,OT}(
192228
optimizer,
193229
MOI.Utilities.CleverDicts.CleverDict{ParameterIndex,T}(
@@ -251,7 +287,20 @@ mutable struct Optimizer{T,OT<:MOI.ModelLike} <: MOI.AbstractOptimizer
251287
end
252288
end
253289

254-
Optimizer(args...; kws...) = Optimizer{Float64}(args...; kws...)
290+
Optimizer(arg; kwargs...) = Optimizer{Float64}(arg; kwargs...)
291+
292+
function Optimizer{T}(
293+
optimizer_fn;
294+
with_bridge_type = nothing,
295+
kwargs...,
296+
) where {T}
297+
inner = MOI.instantiate(optimizer_fn; with_bridge_type)
298+
if !MOI.supports_incremental_interface(inner)
299+
cache = MOI.default_cache(inner, T)
300+
inner = MOI.Utilities.CachingOptimizer(cache, inner)
301+
end
302+
return Optimizer{T}(inner; kwargs...)
303+
end
255304

256305
function _next_parameter_index!(model::Optimizer)
257306
return model.last_parameter_index_added += 1

src/duals.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ function MOI.get(
149149
cp::MOI.ConstraintIndex{MOI.VariableIndex,MOI.Parameter{T}},
150150
) where {T}
151151
if !model.evaluate_duals
152-
msg = "$attr not available when evaluate_duals is set to false. Create an optimizer such as `POI.Optimizer(HiGHS.Optimizer(); evaluate_duals = true)` to enable this feature."
152+
msg = "$attr not available when evaluate_duals is set to false. Create an optimizer such as `POI.Optimizer(HiGHS.Optimizer; evaluate_duals = true)` to enable this feature."
153153
throw(MOI.GetAttributeNotAllowed(attr, msg))
154154
elseif !_is_additive(model, cp)
155155
msg = "Cannot compute the dual of a multiplicative parameter"

0 commit comments

Comments
 (0)