Document how to use C API
Hello,
I am attempting to get the lower bound from an integer program using the Gurobi C API. Here is my example
using JuMP, Gurobi
const GRB_ENV = Gurobi.Env()
model = Model(() -> Gurobi.Optimizer(GRB_ENV))
@variable(model, 0 <= y <= 2.5,Int)
@objective(model, Max, y)
optimize!(model)
p = Ref{Cdouble}()
Gurobi.GRBgetdblattr(model, "ObjBound", p)
When I run this code I get the following error:
ERROR: LoadError: MethodError: no method matching unsafe_convert(::Type{Ptr{Nothing}}, ::Model)
Closest candidates are:
unsafe_convert(::Union{Type{Ptr{Nothing}}, Type{Ptr{Base.Libc.FILE}}}, ::Base.Libc.FILE) at libc.jl:94
unsafe_convert(::Type{Ptr{T}}, ::StaticArrays.SizedArray) where T at /home/dsigler/.julia/packages/StaticArrays/xV8rq/src/SizedArray.jl:129
unsafe_convert(::Type{Ptr{T}}, ::Ptr{Tuple{Vararg{T, N}}}) where {N, T} at refpointer.jl:176
...
Stacktrace:
[1] GRBgetdblattr(model::Model, attrname::String, valueP::Base.RefValue{Float64})
@ Gurobi ~/.julia/packages/Gurobi/HtUHB/src/gen90/libgrb_api.jl:70
[2] top-level scope
@ /lustre/eaglefs/scratch/dsigler/ADMM.jl/experimental/ParConsensusADMM/examples/LB_gurobi_test.jl:14
[3] include(fname::String)
@ Base.MainInclude ./client.jl:444
[4] top-level scope
@ REPL[1]:1
in expression starting at /lustre/eaglefs/scratch/dsigler/ADMM.jl/experimental/ParConsensusADMM/examples/LB_gurobi_test.jl:14
I am not sure if my code is incorrect or if there is a bug here. Any help you can provide would be much appreciated.
Use objective_bound(model) from JuMP instead.
Using the C API is an advanced an largely undocumented feature. You need to use JuMP in direct mode:
using JuMP, Gurobi
const GRB_ENV = Gurobi.Env()
model = direct_model(Gurobi.Optimizer(GRB_ENV))
@variable(model, 0 <= y <= 2.5, Int)
@objective(model, Max, y)
optimize!(model)
grb = backend(model)
p = Ref{Cdouble}()
Gurobi.GRBgetdblattr(grb, "ObjBound", p)
I'll leave this issue open as a reminder we need to better document this.
Sounds good! Thanks for your help.
Hi, @odow
I wonder is there a convenient way to call the general constraints from Gurobi, e.g.,
julia> import MathOptInterface as MOI
julia> import Gurobi
julia> const GRB_ENV = Gurobi.Env()
Set parameter Username
Academic license - for non-commercial use only - expires 2024-08-09
Gurobi.Env(Ptr{Nothing} @0x000001fe29b2f6d0, false, 0)
julia> o = Gurobi.Optimizer(GRB_ENV);
julia> x,sin_x = MOI.add_variable(o),MOI.add_variable(o) # input 5
(MOI.VariableIndex(1), MOI.VariableIndex(2))
julia> error_code = Gurobi.GRBaddgenconstrSin(o, "sin_constr", 1, 2, "") # input 6
10006 # probably means GRB_ERROR_INDEX_OUT_OF_RANGE
Can we just model as usual (up to input 5) conveniently with the help of MOI, and we insert such a C-API portion as in input 6?
To be more specific, the intention is to build a constraint sin_x = sin(x), which is natively supported by Gurobi (see Approach 2, https://www.gurobi.com/documentation/current/examples/gc_pwl_func_c_c.html).
Thanks!
For the columns, you need to use a 0-indexed Cint.
import MathOptInterface as MOI
import Gurobi
model = Gurobi.Optimizer()
x, sin_x = MOI.add_variables(model, 2)
Gurobi.GRBaddgenconstrSin(
model,
"sin_constr",
Cint(Gurobi.column(model, x) - 1),
Cint(Gurobi.column(model, sin_x) - 1),
"",
)
I've added a minimal amount of documentation here: https://github.com/jump-dev/Gurobi.jl/pull/526