Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Env(params::Dict) for setting parameters before GRBstartenv #596

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
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
85 changes: 58 additions & 27 deletions src/MOI_wrapper/MOI_wrapper.jl
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,36 @@ mutable struct _NLConstraintInfo
end
end

"""
Env(
params::Dict{String,Any} = Dict{String,Any}();
started::Bool = true,
)

Create a new Gurobi environment object.

Optionally pass a `params` dictionary which sets parameters for the created
environment before starting.

## kwargs

The extra keyword argument `started` delays starting the environment if set to
`false`.

## Example

```julia
using JuMP, Gurobi
const GRB_ENV = Gurobi.Env(
Dict(
"ComputeServer" => "localhost:61000",
"OutputFlag" => 0,
);
started = true,
)
model = Model(() -> Gurobi.Optimizer(GRB_ENV))
```
"""
mutable struct Env
ptr_env::Ptr{Cvoid}
# These fields keep track of how many models the `Env` is used for to help
Expand All @@ -110,34 +140,41 @@ mutable struct Env
finalize_called::Bool
attached_models::Int

function Env(;
function Env(
params::Union{Nothing,Dict{String,Any}} = nothing;
started::Bool = true,
# These kwargs are provided for legacy backwards compatibility
output_flag::Int = 1,
memory_limit::Union{Nothing,Real} = nothing,
started::Bool = true,
)
a = Ref{Ptr{Cvoid}}()
ret = GRBemptyenv(a)
env = new(a[], false, 0)
_check_ret(env, ret)
ret = GRBsetintparam(env.ptr_env, GRB_INT_PAR_OUTPUTFLAG, output_flag)
_check_ret(env, ret)
if _GUROBI_VERSION >= v"9.5.0" && memory_limit !== nothing
ret = GRBsetdblparam(env, GRB_DBL_PAR_MEMLIMIT, memory_limit)
_check_ret(env, ret)
end
if started
ret = GRBstartenv(env.ptr_env)
end
finalizer(env) do e
e.finalize_called = true
if e.attached_models == 0
# Only finalize the model if there are no models using it.
GRBfreeenv(e.ptr_env)
e.ptr_env = C_NULL
end
return
end
if params === nothing
# These two parameters are provided for backwards compability
_set_param(env.ptr_env, GRB_INT_PAR_OUTPUTFLAG, 1)
if _GUROBI_VERSION >= v"9.5.0" && memory_limit !== nothing
_set_param(env.ptr_env, GRB_DBL_PAR_MEMLIMIT, memory_limit)
end
else
for (param_name, value) in params
_set_param(env.ptr_env, param_name, value)
end
end
if started
ret = GRBstartenv(env.ptr_env)
_check_ret(env, ret)
end
# Even if the loadenv fails, the pointer is still valid.
_check_ret(env, ret)
return env
end
end
Expand Down Expand Up @@ -170,22 +207,11 @@ function Env(
server_password::Union{String,Nothing} = nothing;
started::Bool = true,
)
env = Env(; started = false)
ret = GRBsetstrparam(env.ptr_env, GRB_STR_PAR_COMPUTESERVER, server_address)
_check_ret(env, ret)
params = Dict{String,Any}(GRB_STR_PAR_COMPUTESERVER => server_address)
if server_password !== nothing
ret = GRBsetstrparam(
env.ptr_env,
GRB_STR_PAR_SERVERPASSWORD,
server_password,
)
_check_ret(env, ret)
params[GRB_STR_PAR_SERVERPASSWORD] = server_password
end
if started
ret = GRBstartenv(env.ptr_env)
_check_ret(env, ret)
end
return env
return Env(params; started)
end

Base.cconvert(::Type{Ptr{Cvoid}}, x::Env) = x
Expand Down Expand Up @@ -685,6 +711,11 @@ function MOI.set(model::Optimizer, raw::MOI.RawOptimizerAttribute, value)
env = GRBgetenv(model)
param = raw.name
model.params[param] = value
_set_param(env, param, value)
return
end

function _set_param(env, param::String, value)
param_type = GRBgetparamtype(env, param)
ret = if param_type == -1
throw(MOI.UnsupportedAttribute(MOI.RawOptimizerAttribute(param)))
Expand Down
19 changes: 19 additions & 0 deletions test/MOI/MOI_wrapper.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1508,6 +1508,25 @@ function test_multiple_solution_nonlinear_objective()
return
end

function test_Env()
function test_err(f)
try
f()
@assert false
catch err
@test occursin("Gurobi Error 10022:", err.msg)
end
end
test_err(() -> Gurobi.Env("localhost:1234"))
test_err(() -> Gurobi.Env("localhost:1234", "password"))
test_err(() -> Gurobi.Env("localhost:1234", "password"; started = true))
env = Gurobi.Env(; output_flag = 2, memory_limit = 1)
p = Ref{Cdouble}()
@test GRBgetdblparam(env, "MemLimit", p) == 0
@test p[] == 1.0
return
end

end # TestMOIWrapper

TestMOIWrapper.runtests()
Loading