Setting up gurobi environment inside a module

I have a module that has some functions that run some optimization problems modeling using the JuMP package and the Gurobi solver.
a very generic structure of the code is as follows:

module TestModule

using JuMP
using Gurobi

const GRB_ENV = Ref{Gurobi.Env}()
function __init__()
    GRB_ENV[] = Gurobi.Env()
    return
end

function run_optimization()
    model = Model(() -> Gurobi.Optimizer(GRB_ENV))
    set_optimizer_attribute(model, "TimeLimit", 3600.0)
    
    #some constraints, variables, objective modeled using JuMP

   optimize!(model)
end

export run_optimization
end

When I call the run_optimization function, I get the following error:

using TestModule

run_optimization() #exported from the module

#Error

ERROR: LoadError: MethodError: no method matching Gurobi.Optimizer(::Base.RefValue{Gurobi.Env})
Closest candidates are:
  Gurobi.Optimizer() at ~/.julia/packages/Gurobi/vStLK/src/MOI_wrapper/MOI_wrapper.jl:325
  Gurobi.Optimizer(::Union{Nothing, Gurobi.Env}; enable_interrupts) at ~/.julia/packages/Gurobi/vStLK/src/MOI_wrapper/MOI_wrapper.jl:325

I am probably doing something silly here. If someone could point out the correct way to call it, that would be great. Thanks!

Could this just be

const GRB_ENV = Gurobi.Env()

without the __init__()?

I was doing the same thing before, but apparently, it won’t work inside a package/module as is mentioned here.

Maybe you could just “de-reference” using [] here:

 model = Model(() -> Gurobi.Optimizer(GRB_ENV[]))

Nope, it doesn’t work. I get the following error:

ERROR: LoadError: Gurobi Error 10002:
Stacktrace:
  [1] _check_ret
    @ ~/.julia/packages/Gurobi/vStLK/src/MOI_wrapper/MOI_wrapper.jl:375 [inlined]
  [2] empty!(model::Gurobi.Optimizer)
    @ Gurobi ~/.julia/packages/Gurobi/vStLK/src/MOI_wrapper/MOI_wrapper.jl:443
  [3] Gurobi.Optimizer(env::Gurobi.Env; enable_interrupts::Bool)
    @ Gurobi ~/.julia/packages/Gurobi/vStLK/src/MOI_wrapper/MOI_wrapper.jl:348
  [4] Optimizer
    @ ~/.julia/packages/Gurobi/vStLK/src/MOI_wrapper/MOI_wrapper.jl:325 [inlined]

This is a different error. The Gurobi Reference Manual says this is:

10002     NULL input value provided for a required argument

But I can’t reproduce that one. This works for me in the REPL:

module TestModule

using JuMP
using Gurobi

const GRB_ENV = Ref{Gurobi.Env}()
function __init__()
    const GRB_ENV[] = Gurobi.Env()
    return
end

function run_optimization()
    model = Model(() -> Gurobi.Optimizer(GRB_ENV[]))  # <-- Added []
    set_optimizer_attribute(model, "TimeLimit", 3600.0)
    
    #some constraints, variables, objective modeled using JuMP

   optimize!(model)
end

export run_optimization

end

using .TestModule
run_optimization()
2 Likes

Totally my fault. I changed GRB_ENV to GRB_ENV[] at all places but one (I have multiple functions solving optimization problems). It works now; however, I am just curious why does it work now and not before. Also, the person who made the post here didn’t seem to have any issue with using just GRB_ENV. Further, as @odow mentioned in this comment, any calls to GRB_ENV should be GRB_ENV[]. Any leads to why it works now would be helpful. Thanks again!!

The [] is needed to get or set the element inside a Ref object.

The __init__ is needed so that a new environment is created each time you start Julia. Otherwise, the C pointer will be precompiled and it won’t exist the next time you load the model.

2 Likes

Oh, I understand now. Thanks for the clarification!

1 Like