Gurobi 9.5 MemLimit usage

I found a solution. Thanks to @jd-foster I could check if I set the memory limit correctly.
The struggle as you sad is that the environment is already started.

The constructor function in Gurobi would need to be extended to the following for which i already created a pull request in order to set the parameter before the environment is started.

function Env(; output_flag::Int = 1, memory_limit::Number = 1.0e100)
        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"
            ret = GRBsetdblparam(env, GRB_DBL_PAR_MEMLIMIT, memory_limit)
            _check_ret(env, ret)
        end
        ret = GRBstartenv(env.ptr_env)
        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
        end
        # Even if the loadenv fails, the pointer is still valid.
        _check_ret(env, ret)
        return env
    end

Since we are working on scaling virtual machines where the memory limit should be variable the usage of an environmental file is not really an option. For a workaround until this the memory limit usage is shipped I found the following to work for me:

env = create_gurobi_env(optimizer.Env(); memlimit = 1.0)
model = Model(() -> optimizer.Optimizer(env))

function create_gurobi_env(env::Gurobi.Env; output_flag::Int = 1, memlimit::Number = 1.0e100)
    a = Gurobi.Ref{Ptr{Cvoid}}()
    ret = Gurobi.GRBemptyenv(a)
    env.ptr_env = a[]
    env.finalize_called = false
    env.attached_models = 0
    Gurobi._check_ret(env, ret)
    ret = Gurobi.GRBsetintparam(env.ptr_env, GRB_INT_PAR_OUTPUTFLAG, output_flag)
    Gurobi.GRBsetdblparam(env, GRB_DBL_PAR_MEMLIMIT, memlimit)
    Gurobi._check_ret(env, ret)
    ret = Gurobi.GRBstartenv(env.ptr_env)
    Gurobi.finalizer(env) do e
        e.finalize_called = true
        if e.attached_models == 0
            # Only finalize the model if there are no models using it.
            Gurobi.GRBfreeenv(e.ptr_env)
            e.ptr_env = C_NULL
        end
    end
    # Even if the loadenv fails, the pointer is still valid.
    Gurobi._check_ret(env, ret)
    return env
end

Since the struct Env cannot be created without the constructor function we need to create an environment first and change the struct to a new one which contains the memory limit.

3 Likes