# Compute simplex tableau from Gurobi.jl using JuMP

**URL:** https://discourse.julialang.org/t/compute-simplex-tableau-from-gurobi-jl-using-jump/79395
**Category:** Optimization (Mathematical)
**Tags:** gurobi
**Created:** [April 12, 2022, 4:57pm UTC](https://discourse.julialang.org/t/compute-simplex-tableau-from-gurobi-jl-using-jump/79395 "2022-04-12T16:57:47Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![jacob-roth](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jacob-roth/32/1862_2.png) [@jacob-roth](https://discourse.julialang.org/u/jacob-roth)
#### Post date: [April 12, 2022, 4:57pm UTC](https://discourse.julialang.org/t/compute-simplex-tableau-from-gurobi-jl-using-jump/79395/1 "2022-04-12T16:57:48Z")

</div>

I am modeling an LP in JuMP using Gurobi. How can I obtain the optimal simplex tableau?

For example, consider the below LP:

```julia
A = [1; 2; 3]'
c = [4; 5; 6]
b = 7
M = Model(Gurobi.Optimizer)
set_optimizer_attribute(M, "Presolve", 0)
set_optimizer_attribute(M, "Method", 2)
@variable(M, x[1:3])
@objective(M, Min, c' * x)
@constraint(M, A * x >= b)
@constraint(M, x .>= 0)
optimize!(M)
value.(x)

```

and I have tried

```julia
y = zeros(3)
m = backend(M)
julia> Gurobi.GRBBinvRowi(m,1,y)
ERROR: MethodError: no method matching unsafe_convert(::Type{Ptr{Nothing}}, ::MathOptInterface.Utilities.CachingOptimizer{MathOptInterface.Bridges.LazyBridgeOptimizer{Gurobi.Optimizer}, MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}})
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}}, ::Base.RefValue{SA}) where {S, T, D, L, SA<:StaticArrays.SArray{S, T, D, L}} at /Users/.julia/packages/StaticArrays/12k3X/src/SArray.jl:125
  unsafe_convert(::Type{Ptr{T}}, ::Base.RefValue{FA}) where {N, T, D, FA<:StaticArrays.FieldArray{N, T, D}} at /Users/.julia/packages/StaticArrays/12k3X/src/FieldArray.jl:124
  ...
Stacktrace:
 [1] GRBBinvRowi(model::MathOptInterface.Utilities.CachingOptimizer{MathOptInterface.Bridges.LazyBridgeOptimizer{Gurobi.Optimizer}, MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}, i::Int64, x::Float64)
   @ Gurobi ~/.julia/packages/Gurobi/WjZv8/src/gen91/libgrb_api.jl:594
 [2] top-level scope
   @ REPL[27]:1

```

It’s not clear to me how to update `internalModel` from [here](https://discourse.julialang.org/t/simplex-tableau/6652).

---

<div class="post-metadata">

### Author: ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)
#### Post date: [April 12, 2022, 8:01pm UTC](https://discourse.julialang.org/t/compute-simplex-tableau-from-gurobi-jl-using-jump/79395/2 "2022-04-12T20:01:43Z")

</div>

To access the C API, you need to use

```julia
M = direct_model(Gurobi.Optimizer())
# ...
m = backend(M)

```

At the risk of breaking things, you can also use

```julia
M = Model(Gurobi.Optimizer)
# ...
m = unsafe_backend(M)

```

but the method is called `unsafe_` for a reason: [Models · JuMP](https://jump.dev/JuMP.jl/stable/reference/models/#JuMP.unsafe_backend)

---

<div class="post-metadata">

### Author: ![noamgold](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/noamgold/32/14473_2.png) [@noamgold](https://discourse.julialang.org/u/noamgold)
#### Post date: [April 22, 2022, 6:08pm UTC](https://discourse.julialang.org/t/compute-simplex-tableau-from-gurobi-jl-using-jump/79395/3 "2022-04-22T18:08:13Z")

</div>

Your argument y in Gurobi.GRBBinvRowi(m,1,y) should not be a Julia Vector  
Gurobi expects a sparse vector struct of type GRBsvec. However the corresponding one defined in Gurobi.jl seems to be defined as immutable so I could not get GRBBinvRowi to work (or actually GRBBinvColj in my case). I get it to work with a ccall directly in the following example:

m=direct\_model(Gurobi.Optimizer())  
grb = unsafe\_backend(m)  
@variable(m,y\>=0)  
@variable(m,x\>=0)  
@constraint(m,x\<=1)  
@constraint(m,y\<=2)  
@objective(m,Max,x+y)  
optimize!(m)

mutable struct mySvec  
len::Cint;  
ind::Ptr{Cint};  
val::Ptr{Cdouble};  
end

idxs = Vector{Cint}(undef,2) # model has 2 rows  
vals = Vector{Cdouble}(undef,2)  
ss = mySvec(0,pointer\_from\_objref(idxs),pointer\_from\_objref(vals))  
res = ccall((:GRBBinvColj, “gurobi90”), Cint, (Ptr{GRBmodel}, Cint, Ptr{mySvec}), grb, 1, Ref(ss))

println(res)  
@show ss.len  
@show unsafe\_load(ss.ind)  
@show unsafe\_load(ss.val)
