Skip to content

Commit

Permalink
[Performance] don't pass names by default (#393)
Browse files Browse the repository at this point in the history
  • Loading branch information
odow authored Apr 3, 2022
1 parent 4fedf7b commit f79a6ed
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 8 deletions.
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "CPLEX"
uuid = "a076750e-1247-5638-91d2-ce28b192dca0"
repo = "https://github.com/jump-dev/CPLEX.jl"
version = "0.9.1"
version = "0.9.2"

[deps]
CEnum = "fa961155-64e5-5f13-b03f-caf6b980ea82"
Expand Down
40 changes: 33 additions & 7 deletions src/MOI/MOI_wrapper.jl
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ function _check_ret_optimize(model)
end

"""
Optimizer(env::Union{Nothing, Env} = nothing)
Optimizer(env::Union{Nothing, Env} = nothing; pass_names::Bool = false)
Create a new Optimizer object.
Expand All @@ -140,12 +140,22 @@ first argument.
Set optimizer attributes using `MOI.RawOptimizerAttribute` or
`JuMP.set_optimizer_atttribute`.
## Names
By default, variable and constraint names are stored in the MOI wrapper, but are
_not_ passed to the inner CPLEX model object because doing so can lead to a
large performance degradation. The downside of not passing names is that various
log messages from CPLEX will report names like constraint "R1" and variable "C2"
instead of their actual names. You can change this behavior using
`pass_names = true` to force CPLEX.jl to pass variable and constraint names to
the inner CPLEX model object.
## Example
```julia
using JuMP, CPLEX
const env = CPLEX.Env()
model = JuMP.Model(() -> CPLEX.Optimizer(env))
model = JuMP.Model(() -> CPLEX.Optimizer(env; pass_names = true))
set_optimizer_attribute(model, "CPXPARAM_ScreenOutput", 0)
```
"""
Expand Down Expand Up @@ -231,7 +241,19 @@ mutable struct Optimizer <: MOI.AbstractOptimizer
heuristic_callback::Union{Nothing,Function}
generic_callback::Any

function Optimizer(env::Union{Nothing,Env} = nothing)
# For more information on why `pass_names` is necessary, read:
# https://github.com/jump-dev/CPLEX.jl/issues/392
# The underlying problem is that we observed that add_variable, then set
# VariableName then add_variable (i.e., what CPLEX in direct-mode does) is
# faster than adding variable in batch then setting names in batch (i.e.,
# what default_copy_to does). If implementing MOI.copy_to, you should take
# this into consideration.
pass_names::Bool

function Optimizer(
env::Union{Nothing,Env} = nothing;
pass_names::Bool = false,
)
model = new()
model.lp = C_NULL
model.env = env === nothing ? Env() : env
Expand All @@ -248,6 +270,7 @@ mutable struct Optimizer <: MOI.AbstractOptimizer
Dict{Int,Tuple{_ConstraintInfo,MOI.VectorAffineFunction{Float64}}}()
model.callback_variable_primal = Float64[]
model.certificate = Float64[]
model.pass_names = pass_names
MOI.empty!(model)
finalizer(model) do m
ret = CPXfreeprob(m.env, Ref(m.lp))
Expand Down Expand Up @@ -489,6 +512,9 @@ end

MOI.supports_incremental_interface(::Optimizer) = true

# !!! info
# If modifying this function, read the comment in the defintion of Optimizer
# about the need for `pass_names`.
function MOI.copy_to(dest::Optimizer, src::MOI.ModelLike)
return MOI.Utilities.default_copy_to(dest, src)
end
Expand Down Expand Up @@ -821,8 +847,7 @@ function MOI.set(
name::String,
)
info = _info(model, v)
info.name = name
if isascii(name)
if model.pass_names && info.name != name && isascii(name)
ret = CPXchgname(
model.env,
model.lp,
Expand All @@ -832,6 +857,7 @@ function MOI.set(
)
_check_ret(model, ret)
end
info.name = name
model.name_to_variable = nothing
return
end
Expand Down Expand Up @@ -2057,8 +2083,7 @@ function MOI.set(
name::String,
)
info = _info(model, c)
info.name = name
if isascii(name)
if model.pass_names && info.name != name && isascii(name)
ret = CPXchgname(
model.env,
model.lp,
Expand All @@ -2068,6 +2093,7 @@ function MOI.set(
)
_check_ret(model, ret)
end
info.name = name
model.name_to_constraint_index = nothing
return
end
Expand Down

0 comments on commit f79a6ed

Please sign in to comment.