Skip to content
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 README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ Use ParametricOptInterface with JuMP by following this brief example:
```julia
using JuMP, HiGHS
import ParametricOptInterface as POI
model = direct_model(POI.Optimizer(HiGHS.Optimizer()))
model = direct_model(POI.Optimizer(HiGHS.Optimizer))
@variable(model, x)
@variable(model, p in Parameter(1.0))
@constraint(model, cons, x + p >= 3)
Expand Down
8 changes: 2 additions & 6 deletions benchmark/MOI_benchmarks.jl
Original file line number Diff line number Diff line change
Expand Up @@ -165,11 +165,7 @@ function solve_moi(
end

function POI_OPTIMIZER()
return POI.Optimizer(SOLVER.Optimizer())
end

function MOI_OPTIMIZER()
return SOLVER.Optimizer()
return POI.Optimizer(SOLVER.Optimizer)
end

function solve_moi_loop(
Expand All @@ -194,7 +190,7 @@ function solve_moi_loop(
for _ in 1:loops
solve_moi(
data,
MOI_OPTIMIZER;
SOLVER.Optimizer();
vector_version = vector_version,
params = params,
)
Expand Down
5 changes: 1 addition & 4 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,7 @@ Documenter.makedocs(;
),
sitename = "ParametricOptInterface.jl",
authors = "Tomás Gutierrez, and contributors",
pages = [
"Home" => "index.md",
"reference.md",
],
pages = ["Home" => "index.md", "reference.md"],
checkdocs = :none,
)

Expand Down
11 changes: 0 additions & 11 deletions src/MOI_wrapper.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1590,17 +1590,6 @@ function MOI.set(
return MOI.set(model.optimizer, attr, optimizer_ci, val)
end

function MOI.set(
model::Optimizer,
attr::MOI.AbstractConstraintAttribute,
c::MOI.ConstraintIndex{MOI.VariableIndex,MOI.Parameter{T}},
val,
) where {T}
return error(
"Constraint attribute $attr cannot be set for $c in ParametricOptInterface.",
)
end

function MOI.get(
model::Optimizer,
::MOI.ConstraintPrimal,
Expand Down
77 changes: 63 additions & 14 deletions src/ParametricOptInterface.jl
Original file line number Diff line number Diff line change
Expand Up @@ -81,28 +81,63 @@ const DoubleDictInner{F,S,T} = MOI.Utilities.DoubleDicts.DoubleDictInner{F,S,T}
include("parametric_functions.jl")

"""
Optimizer{T, OT <: MOI.ModelLike} <: MOI.AbstractOptimizer
Optimizer{T}(
optimizer::Union{MOI.ModelLike,Any};
evaluate_duals::Bool = true,
save_original_objective_and_constraints::Bool = true,
with_bridge_type = nothing,
)

Declares a `Optimizer`, which allows the handling of parameters in a
Create an `Optimizer`, which allows the handling of parameters in an
optimization model.

If `optimizer` is not a `MOI.ModelLike,` the inner optimizer is constructed
using `MOI.instantiate(optimizer; with_bridge_type)`.

The `{T}` type parameter is optional; it defaults to `Float64`.

## Keyword arguments

- `evaluate_duals::Bool`: If `true`, evaluates the dual of parameters. Users might want to set it to `false`
to increase performance when the duals of parameters are not necessary. Defaults to `true`.
- `evaluate_duals::Bool`: If `true`, evaluates the dual of parameters. Set it to
`false` to increase performance when the duals of parameters are not
necessary. Defaults to `true`.

- `save_original_objective_and_constraints`: If `true` saves the orginal function and set of the constraints
as well as the original objective function inside [`Optimizer`](@ref). This is useful for printing the model
but greatly increases the memory footprint. Users might want to set it to `false` to increase performance
in applications where you don't need to query the original expressions provided to the model in constraints
or in the objective. Note that this might break printing or queries such as `MOI.get(model, MOI.ConstraintFunction(), c)`.
Defaults to `true`.
- `save_original_objective_and_constraints`: If `true` saves the orginal
function and set of the constraints as well as the original objective function
inside [`Optimizer`](@ref). This is useful for printing the model but greatly
increases the memory footprint. Users might want to set it to `false` to
increase performance in applications where you don't need to query the
original expressions provided to the model in constraints or in the objective.
Note that this might break printing or queries such as
`MOI.get(model, MOI.ConstraintFunction(), c)`. Defaults to `true`.

- `with_bridge_type`: this is ignroed if `optimizer::MOI.ModelLike`, otherwise
it is passed to `MOI.instantiate`.

## Example

```julia-repl
julia> ParametricOptInterface.Optimizer(HiGHS.Optimizer())
ParametricOptInterface.Optimizer{Float64,HiGHS.Optimizer}
julia> import ParametricOptInterface as POI

julia> import HiGHS

julia> POI.Optimizer(HiGHS.Optimizer(); evaluate_duals = true)
ParametricOptInterface.Optimizer{Float64, HiGHS.Optimizer}
├ ObjectiveSense: FEASIBILITY_SENSE
├ ObjectiveFunctionType: MOI.ScalarAffineFunction{Float64}
├ NumberOfVariables: 0
└ NumberOfConstraints: 0

julia> POI.Optimizer(
HiGHS.Optimizer;
with_bridge_type = Float64,
evaluate_duals = false,
)
ParametricOptInterface.Optimizer{Float64, MOIB.LazyBridgeOptimizer{HiGHS.Optimizer}}
├ ObjectiveSense: FEASIBILITY_SENSE
├ ObjectiveFunctionType: MOI.ScalarAffineFunction{Float64}
├ NumberOfVariables: 0
└ NumberOfConstraints: 0
```
"""
mutable struct Optimizer{T,OT<:MOI.ModelLike} <: MOI.AbstractOptimizer
Expand Down Expand Up @@ -183,11 +218,12 @@ mutable struct Optimizer{T,OT<:MOI.ModelLike} <: MOI.AbstractOptimizer

# extension data
ext::Dict{Symbol,Any}

function Optimizer{T}(
optimizer::OT;
evaluate_duals::Bool = true,
save_original_objective_and_constraints::Bool = true,
) where {T,OT}
) where {T,OT<:MOI.ModelLike}
return new{T,OT}(
optimizer,
MOI.Utilities.CleverDicts.CleverDict{ParameterIndex,T}(
Expand Down Expand Up @@ -251,7 +287,20 @@ mutable struct Optimizer{T,OT<:MOI.ModelLike} <: MOI.AbstractOptimizer
end
end

Optimizer(args...; kws...) = Optimizer{Float64}(args...; kws...)
Optimizer(arg; kwargs...) = Optimizer{Float64}(arg; kwargs...)

function Optimizer{T}(
optimizer_fn;
with_bridge_type = nothing,
kwargs...,
) where {T}
inner = MOI.instantiate(optimizer_fn; with_bridge_type)
if !MOI.supports_incremental_interface(inner)
cache = MOI.default_cache(inner, T)
inner = MOI.Utilities.CachingOptimizer(cache, inner)
end
return Optimizer{T}(inner; kwargs...)
end

function _next_parameter_index!(model::Optimizer)
return model.last_parameter_index_added += 1
Expand Down
2 changes: 1 addition & 1 deletion src/duals.jl
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ function MOI.get(
cp::MOI.ConstraintIndex{MOI.VariableIndex,MOI.Parameter{T}},
) where {T}
if !model.evaluate_duals
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."
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."
throw(MOI.GetAttributeNotAllowed(attr, msg))
elseif !_is_additive(model, cp)
msg = "Cannot compute the dual of a multiplicative parameter"
Expand Down
Loading
Loading