# Get MIPGap in Gurobi callbacks JuMP 0.21

**URL:** https://discourse.julialang.org/t/get-mipgap-in-gurobi-callbacks-jump-0-21/37232
**Category:** Optimization (Mathematical)
**Created:** [April 8, 2020, 3:41pm UTC](https://discourse.julialang.org/t/get-mipgap-in-gurobi-callbacks-jump-0-21/37232 "2020-04-08T15:41:51Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![bnarum](https://avatars.discourse-cdn.com/v4/letter/b/f14d63/32.png) [@bnarum](https://discourse.julialang.org/u/bnarum)
#### Post date: [April 8, 2020, 3:41pm UTC](https://discourse.julialang.org/t/get-mipgap-in-gurobi-callbacks-jump-0-21/37232/1 "2020-04-08T15:41:51Z")

</div>

Hi

I’ve implemented a model with callbacks in Gurobi and experienced that `cbget_mipsol_obj` and `cbget_mipsol_objbst` returns the same value.

```julia
    Nodes | Current Node | Objective Bounds | Work
 Expl Unexpl | Obj Depth IntInf | Incumbent BestBd Gap | It/Node Time

     0 0 660.03417 0 2 - 660.03417 - - 156s
cbget_mipsol_obj(cb_data, cb_where) = 1063.9392486610595
cbget_mipsol_objbst(cb_data, cb_where) = 1063.9392486610595
cbget_mipsol_solcnt(cb_data, cb_where) = 0

H 0 0 1063.9392487 660.03417 38.0% - 173s
cbget_mipsol_obj(cb_data, cb_where) = 755.5376433127967
cbget_mipsol_objbst(cb_data, cb_where) = 755.5376433127967
cbget_mipsol_solcnt(cb_data, cb_where) = 1

```

where the first line is the output from Gurobi and next three lines are printed in the callback function:

```julia
function optimality_callback(cb_data::Gurobi.CallbackData, cb_where::Int32)
		cb_where != Gurobi.CB_MIPSOL && return

		@show cbget_mipsol_obj(cb_data, cb_where)
		@show cbget_mipsol_objbst(cb_data, cb_where)
		@show cbget_mipsol_solcnt(cb_data, cb_where)
		
		... Making cuts ...
end

```

The cut is submitted to the model by

```julia
MOI.set(mdl_mstr, MOI.RawParameter("LazyConstraints"), 1)
MOI.set(mdl_mstr, Gurobi.CallbackFunction(), optimality_callback)

```

I would think that `cbget_mipsol_objbst` returns the objective of the best feasible MIP solution, while `cbget_mipsol_obj` returns the objective of the current suggested solution.

How can I obtain the objective of the best feasible solution in callbacks?

Ultimately I’d like to obtain the MIPGap, and it seems like `get_dblattr(cb_data.model, "MIPGap")` doesn’t work in callbacks:

```julia
Gurobi.GurobiError(10005, "Unable to retrieve attribute 'MIPGap'")
get_dblattr(::Gurobi.Model, ::String) at grb_attrs.jl:28
...

```

I’m using versions

```julia
JuMP v0.21.1
Gurobi v0.7.6

```

---

<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 8, 2020, 6:56pm UTC](https://discourse.julialang.org/t/get-mipgap-in-gurobi-callbacks-jump-0-21/37232/2 "2020-04-08T18:56:22Z")

</div>

Per the Gurobi documentation, [Callback Codes](https://www.gurobi.com/documentation/9.0/refman/cb_codes.html#sec:CallbackCodes)

```julia
MIPSOL_OBJ MIPSOL	double	Objective value for new solution.
MIPSOL_OBJBST	MIPSOL	double	Current best objective.
MIPSOL_OBJBND	MIPSOL	double	Current best objective bound.

```

So `cbget_mipsol_objbst` does return the best feasible MIP solution, and `cbget_mipsol_obj` does return the current solution. Your callback is just being called at new integer solutions that are the best found so far.

---

<div class="post-metadata">

### Author: ![bnarum](https://avatars.discourse-cdn.com/v4/letter/b/f14d63/32.png) [@bnarum](https://discourse.julialang.org/u/bnarum)
#### Post date: [April 9, 2020, 6:33am UTC](https://discourse.julialang.org/t/get-mipgap-in-gurobi-callbacks-jump-0-21/37232/3 "2020-04-09T06:33:25Z")

</div>

Actually I meant the best feasible after the callback has been called for a given solution. The same value as appears under “Incumbent” in the Gurobi output. I guess it would be possible to check feasibility within the callback and store the value from there. Thank you for taking the time to answer @odow.

---

<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 9, 2020, 2:06pm UTC](https://discourse.julialang.org/t/get-mipgap-in-gurobi-callbacks-jump-0-21/37232/4 "2020-04-09T14:06:17Z")

</div>

`cbget_mipsol_objbst` is the objective of the new incumbent. Your callback checks that you are at a `MIPSOL` node.

I suggest you read the Gurobi documentation to understand where the callbacks can get called from: [https://www.gurobi.com/documentation/9.0/refman/cb\_codes.html](https://www.gurobi.com/documentation/9.0/refman/cb_codes.html)

---

<div class="post-metadata">

### Author: ![rezabayani](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rezabayani/32/25954_2.png) [@rezabayani](https://discourse.julialang.org/u/rezabayani)
#### Post date: [September 30, 2022, 6:04pm UTC](https://discourse.julialang.org/t/get-mipgap-in-gurobi-callbacks-jump-0-21/37232/5 "2022-09-30T18:04:03Z")

</div>

Hi Oscar. I have had success using callback functions to record incumbent and gap with Gurobi during solving MIP. Is there a general method to store solver progress that works for all solvers without using callbacks? I need to store the same information with SCIP solver but I could not find any example or documentation for SCIP callbacks in JuMP.

---

<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: [September 30, 2022, 7:44pm UTC](https://discourse.julialang.org/t/get-mipgap-in-gurobi-callbacks-jump-0-21/37232/6 "2022-09-30T19:44:23Z")

</div>

> [@rezabayani](#):
>
> Is there a general method to store solver progress that works for all solvers without using callbacks?

Unfortunately, no.
