Gurobi Error 10005: Unable to retrieve attribute 'Pi'

I am trying to retrieve some Gurobi attributes for through MOI.get() function with direct_model() enabled. Everything seems to be working but when I try to get “Pi” (dual value for a constraint), I encounter the error:

Gurobi Error 10005: Unable to retrieve attribute 'Pi'
in top-level scope at initial_test.jl:53
in get at JuMP\e0Uc2\src\JuMP.jl:889
in get at Gurobi\Lci9Q\src\MOI_wrapper.jl:3657
in _get_attribute at Gurobi\Lci9Q\src\MOI_wrapper.jl:3619
in _check_ret at Gurobi\Lci9Q\src\MOI_wrapper.jl:277
versioninfo():
Commit 2d5741174c (2019-12-30 21:36 UTC)
Platform Info:
OS: Windows (x86_64-w64-mingw32)
CPU: Intel(R) Core(TM) i7-9700K CPU @ 3.60GHz
WORD_SIZE: 64
LIBM: libopenlibm
LLVM: libLLVM-6.0.1 (ORCJIT, skylake)
Environment:
JULIA_EDITOR = "C:\Users\Reza\AppData\Local\atom\app-1.54.0\atom.exe" -a
JULIA_NUM_THREADS = 4

Pkg.status():
`C:\Users\Reza\.julia\environments\v1.3\Project.toml`
[c52e3926] Atom v0.12.30
[fa961155] CEnum v0.3.0
[be33ccc6] CUDAnative v3.1.0
[8f4d0f93] Conda v1.5.0
[7806a523] DecisionTree v0.10.10
[31c24e10] Distributions v0.23.8
[587475ba] Flux v0.10.4
[60bf3e95] GLPK v0.14.5
[61eb1bfa] GPUCompiler v0.2.0
[2e9cd046] Gurobi v0.9.7
[7073ff75] IJulia v1.23.1
[b6b21f68] Ipopt v0.6.5
[4076af6c] JuMP v0.21.4
[e5e0dc1b] Juno v0.8.4
[1902f260] Knet v1.3.6
[91a5bcdd] Plots v1.6.12
[438e738f] PyCall v1.92.2
[3646fa90] ScikitLearn v0.6.3
[2913bbd2] StatsBase v0.33.2
[9a3f8284] Random

steps to reproduce:

using Gurobi
using JuMP

# define a simple UC problem

n_u = 8
n_t = 4
U = collect(1:n_u) # num units
T = collect(1:n_t) # num time steps
p_g_min = round.(0.3 <em>rand(n_u), digits=2)
p_g_max = 1 .+ round.(rand(n_u), digits=2)
cost_g = 10 .+ round.(10.0</em> rand(n_u), digits=1)
cost_g0 = round.(3.0 <em>rand(n_u), digits=1)
d0 = rand((sum(p_g_min):.01:.5</em> sum(p_g_max)),n_t)

# basic_uc_model = Model(Gurobi.Optimizer)

basic_uc_model = direct_model(Gurobi.Optimizer())
    @variable(basic_uc_model, p_g[i in U, t in T])
    @variable(basic_uc_model, I_g[i in U, t in T], Bin)
    @constraint(basic_uc_model, lower_band[i in U, t in T], p_g[i,t] >= p_g_min[i]*I_g[i,t])
    @constraint(basic_uc_model, upper_band[i in U, t in T], p_g[i,t] <= p_g_max[i]*I_g[i,t])
    @constraint(basic_uc_model, demand[t in T], sum(p_g[i,t] for i in U) == d0[t])
    @objective(basic_uc_model, Min, sum(p_g[i,t]*cost_g[i] + I_g[i,t]*cost_g0[i] for i in U, t in T))

optimize!(basic_uc_model)
JuMP.objective_value(basic_uc_model)
JuMP.value.(p_g)
JuMP.value.(I_g)

MOI.get(basic_uc_model, Gurobi.ModelAttribute("ObjVal")) # Objective value for current solution
MOI.get(basic_uc_model, Gurobi.VariableAttribute("Obj"), p_g[2,2]) # Linear objective coefficient
MOI.get(basic_uc_model, Gurobi.ConstraintAttribute("Slack"), lower_band[2,2]) #
MOI.get(basic_uc_model, Gurobi.ConstraintAttribute("Pi"), upper_band[2,2]) # Dual value (also known as the shadow price)

I can obtain other attributes as can be seen, this only happens when I try “Pi”. Also, I tried different versions of Gurobi (version 8.1 gurobi software with according julia gurobi package, instead of 9.1) but it did not help. I even tried it on both JuliaPro and Atom+Juno but that did not help neither. Finally, this is not certainly a syntax issue since if I change “Pi” with a random name that is not included, e.g. “Dual”, the error code changes : Gurobi Error 10004: Unknown attribute ‘Dual’. I would appreciate your feedback.

Please provide a link when cross-posting: https://github.com/jump-dev/Gurobi.jl/issues/390.

As I explained, dual values are not available for models with binary variables.

Thank you for your responses and I appreciate you bearing with me. I am going to delete this post if possible.

No need to delete. It may be helpful for others. The link for cross posting is just so that two people don’t reply with the same answer to a question in two places.

This post was super helpful to me as I ran into the same issue today. Thank you :slight_smile:

Glad to hear!

A reminder to future readers that you should query dual_status(model) to see if the solver has a solution before querying dual or shadow_price. Not doing so can throw an error or silently return incorrect solutions.

Relevant section in the JuMP documentation: Solutions · JuMP

This situation is more rare, but I encounter it anyway.

Set parameter OutputFlag to value 1
Set parameter QCPDual to value 1
Gurobi Optimizer version 11.0.2 build v11.0.2rc0 (win64 - Windows 11.0 (22631.2))

CPU model: 11th Gen Intel(R) Core(TM) i5-1135G7 @ 2.40GHz, instruction set [SSE2|AVX|AVX2|AVX512]
Thread count: 4 physical cores, 8 logical processors, using up to 8 threads

Optimize a model with 528 rows, 288 columns and 2047 nonzeros
Model fingerprint: 0x2b227fd8
Model has 24 quadratic constraints
Coefficient statistics:
  Matrix range     [1e-03, 6e+00]
  QMatrix range    [1e+00, 1e+00]
  Objective range  [2e-01, 2e+01]
  Bounds range     [0e+00, 0e+00]
  RHS range        [5e-02, 5e+00]
Presolve removed 370 rows and 107 columns
Presolve time: 0.00s
Presolved: 158 rows, 204 columns, 485 nonzeros
Presolved model has 24 second-order cone constraints
Ordering time: 0.00s

Barrier statistics:
 AA' NZ     : 4.190e+02
 Factor NZ  : 1.458e+03
 Factor Ops : 1.652e+04 (less than 1 second per iteration)
 Threads    : 1

                  Objective                Residual
Iter       Primal          Dual         Primal    Dual     Compl     Time
   0  -1.25354714e+02 -3.75702206e+03  1.76e+01 2.10e+01  1.18e+02     0s
   1   3.53382960e+02 -2.86354426e+03  4.14e-01 2.63e+00  1.59e+01     0s
   2   2.45527260e+02 -4.03372205e+02  2.32e-03 3.77e-01  2.52e+00     0s
   3   8.35773331e+01 -7.05132949e+01  2.17e-04 6.90e-02  5.49e-01     0s
   4   3.88871083e+01  1.27671608e+01  1.85e-05 1.03e-02  8.99e-02     0s
   5   3.43244850e+01  2.55418767e+01  5.42e-06 3.41e-03  2.99e-02     0s
   6   3.25598824e+01  2.88231832e+01  1.57e-06 1.48e-03  1.28e-02     0s
   7   3.19555238e+01  3.14579383e+01  4.31e-07 6.49e-05  1.55e-03     0s
   8   3.17528802e+01  3.16894458e+01  8.10e-08 1.04e-06  1.89e-04     0s
   9   3.17077557e+01  3.17046971e+01  4.17e-09 1.28e-08  9.05e-06     0s
  10   3.17054821e+01  3.17051501e+01  3.91e-09 9.95e-10  9.82e-07     0s

Barrier solved model in 10 iterations and 0.01 seconds (0.00 work units)
Optimal objective 3.17054821e+01

Warning: failed to compute QCP dual solution due to inaccurate barrier solution
         Try decreasing BarQCPConvTol for more accuracy

User-callback calls 101, time in user-callback 0.00 sec

@WalterMadelim did you follow the instructions in this warning?

No, I decided to use Mosek instead.
It appears that Mosek’s dual is more reliable when we are dealing with Conic programs.