# How to handle an optimizer which doesn't support an attribute of MathOptInterface?

**URL:** https://discourse.julialang.org/t/how-to-handle-an-optimizer-which-doesnt-support-an-attribute-of-mathoptinterface/117133
**Category:** Optimization (Mathematical)
**Tags:** jump, attributes, glpk
**Created:** [July 17, 2024, 11:06am UTC](https://discourse.julialang.org/t/how-to-handle-an-optimizer-which-doesnt-support-an-attribute-of-mathoptinterface/117133 "2024-07-17T11:06:09Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![K5Julien](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/k5julien/32/210626_2.png) [@K5Julien](https://discourse.julialang.org/u/K5Julien)
#### Post date: [July 17, 2024, 11:06am UTC](https://discourse.julialang.org/t/how-to-handle-an-optimizer-which-doesnt-support-an-attribute-of-mathoptinterface/117133/1 "2024-07-17T11:06:10Z")

</div>

Dear Julia Discourse’s optimization community,

Because getting Node Count: `MOI.get(m, MOI.NodeCount())` is not supported by GLPK.jl, at the end of my optimization model, I tried the following:

```julia
    nodecount = -1
    try
        nodecount = MOI.get(m, MOI.NodeCount())
    catch e
        println("Getting Node Count is not supported by the solver you use")
        rethrow(e)
    end

```

Unfortunately, it fails and target `] test`

```julia
	@test RSP.rspoptimize(pars, 1; solutionchecker = true, optimizer =
		optimizer_with_attributes(GLPK.Optimizer,
			"msg_lev" => GLPK.GLP_MSG_ALL,
			"tm_lm" => pars.timelimit)
	) == 0

```

returns an error:

```julia
RingStarProblems.jl: Error During Test at /home/julien/Documents/Travail/Julia/RingStarProblems.jl/test/runtests.jl:33
  Test threw exception
  Expression: RSP.rspoptimize(pars, 1; solutionchecker = true, optimizer = optimizer_with_attributes(GLPK.Optimizer, "msg_lev" => GLPK.GLP_MSG_ALL, "tm_lim" => pars.timelimit)) == 0
  MathOptInterface.GetAttributeNotAllowed{MathOptInterface.NodeCount}: Getting attribute MathOptInterface.NodeCount() cannot be performed: GLPK.Optimizer does not support getting the attribute MathOptInterface.NodeCount(). You may want to use a `CachingOptimizer` in `AUTOMATIC` mode or you may need to call `reset_optimizer` before doing this operation if the `CachingOptimizer` is in `MANUAL` mode.
  Stacktrace:
    [1] get_fallback(model::GLPK.Optimizer, attr::MathOptInterface.NodeCount)
      @ MathOptInterface ~/.julia/packages/MathOptInterface/aJZbq/src/attributes.jl:409
    [2] get(::GLPK.Optimizer, ::MathOptInterface.NodeCount)
      @ MathOptInterface ~/.julia/packages/MathOptInterface/aJZbq/src/attributes.jl:390
    [3] get(b::MathOptInterface.Bridges.LazyBridgeOptimizer{GLPK.Optimizer}, attr::MathOptInterface.NodeCount)
      @ MathOptInterface.Bridges ~/.julia/packages/MathOptInterface/aJZbq/src/Bridges/bridge_optimizer.jl:889
    [4] _get_model_attribute(model::MathOptInterface.Utilities.CachingOptimizer{MathOptInterface.Bridges.LazyBridgeOptimizer{GLPK.Optimizer}, MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}, attr::MathOptInterface.NodeCount)
      @ MathOptInterface.Utilities ~/.julia/packages/MathOptInterface/aJZbq/src/Utilities/cachingoptimizer.jl:865
    [5] get(model::MathOptInterface.Utilities.CachingOptimizer{MathOptInterface.Bridges.LazyBridgeOptimizer{GLPK.Optimizer}, MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}, attr::MathOptInterface.NodeCount)
      @ MathOptInterface.Utilities ~/.julia/packages/MathOptInterface/aJZbq/src/Utilities/cachingoptimizer.jl:900
    [6] _moi_get_result(model::MathOptInterface.Utilities.CachingOptimizer{MathOptInterface.Bridges.LazyBridgeOptimizer{GLPK.Optimizer}, MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}, args::MathOptInterface.NodeCount)
      @ JuMP ~/.julia/packages/JuMP/7rBNn/src/optimizer_interface.jl:1053
    [7] get(model::Model, attr::MathOptInterface.NodeCount)
      @ JuMP ~/.julia/packages/JuMP/7rBNn/src/optimizer_interface.jl:1073
    [8] benders_st_optimize_lazy!(m::Model, x::JuMP.Containers.SparseAxisArray{VariableRef, 2, Tuple{Int64, Int64}}, y::JuMP.Containers.DenseAxisArray{VariableRef, 2, Tuple{UnitRange{Int64}, UnitRange{Int64}}, Tuple{JuMP.Containers._AxisLookup{Tuple{Int64, Int64}}, JuMP.Containers._AxisLookup{Tuple{Int64, Int64}}}}, f::RingStarProblems.var"#f#256"{Dict{Tuple{Int64, Int64}, Float64}, Vector{Float64}, UnitRange{Int64}, Int64}, F::Float64, B::VariableRef, inst::RingStarProblems.RRSPInstance, pars::RingStarProblems.SolverParameters, start_time::Float64; optimizer::MathOptInterface.OptimizerWithAttributes)
      @ RingStarProblems ~/Documents/Travail/Julia/RingStarProblems.jl/src/benders_rrsp.jl:661
    [9] rrspcreatebenders_modellazy(filename::String, inst::RingStarProblems.RRSPInstance, pars::RingStarProblems.SolverParameters; optimizer::MathOptInterface.OptimizerWithAttributes)
      @ RingStarProblems ~/Documents/Travail/Julia/RingStarProblems.jl/src/benders_rrsp.jl:176
   [10] rrspcreatebenders_modellazy
      @ ~/Documents/Travail/Julia/RingStarProblems.jl/src/benders_rrsp.jl:48 [inlined]
   [11] main(pars::RingStarProblems.SolverParameters, filename::Vector{String}; solutionchecker::Bool, optimizer::MathOptInterface.OptimizerWithAttributes)
      @ RingStarProblems ~/Documents/Travail/Julia/RingStarProblems.jl/src/main.jl:181
   [12] main
      @ ~/Documents/Travail/Julia/RingStarProblems.jl/src/main.jl:91 [inlined]
   [13] rspoptimize(pars::RingStarProblems.SolverParameters, id_instance::Int64; solutionchecker::Bool, optimizer::MathOptInterface.OptimizerWithAttributes)
      @ RingStarProblems ~/Documents/Travail/Julia/RingStarProblems.jl/src/main.jl:83
   [14] macro expansion
      @ ~/.julia/juliaup/julia-1.10.4+0.x64.linux.gnu/share/julia/stdlib/v1.10/Test/src/Test.jl:669 [inlined]
   [15] macro expansion
      @ ~/Documents/Travail/Julia/RingStarProblems.jl/test/runtests.jl:33 [inlined]
   [16] macro expansion
      @ ~/.julia/juliaup/julia-1.10.4+0.x64.linux.gnu/share/julia/stdlib/v1.10/Test/src/Test.jl:1577 [inlined]
   [17] top-level scope
      @ ~/Documents/Travail/Julia/RingStarProblems.jl/test/runtests.jl:8

```

Because the error suggests I should use a CachingOptimizer:

```julia
GLPK.Optimizer does not support getting the attribute MathOptInterface.NodeCount(). You may want to use a `CachingOptimizer` in `AUTOMATIC` mode or you may need to call `reset_optimizer` before doing this operation if the `CachingOptimizer` is in `MANUAL` mode.`

```

I tried:

````julia
@test RSP.rspoptimize(pars, 1; solutionchecker = true, optimizer =
		() -> MOI.Utilities.CachingOptimizer(
            MOI.Utilities.Model{Float64}(),MOI.OptimizerWithAttributes(GLPK.Optimizer,
			"msg_lev" => GLPK.GLP_MSG_ALL,
			"tm_lim" => pars.timelimit))
	) == 0```

````

But now the error is:

```julia
    RingStarProblems.jl: Error During Test at /home/julien/Documents/Travail/Julia/RingStarProblems.jl/test/runtests.jl:34
      Test threw exception
      Expression: RSP.rspoptimize(pars, 1; solutionchecker = true, optimizer = (()->begin
                        #= /home/julien/Documents/Travail/Julia/RingStarProblems.jl/test/runtests.jl:35 =#
                        MOI.Utilities.CachingOptimizer(MOI.Utilities.Model{Float64}(), MOI.OptimizerWithAttributes(GLPK.Optimizer, "msg_lev" => GLPK.GLP_MSG_ALL, "tm_lim" => pars.timelimit))
                    end)) == 0
      MethodError: no method matching MathOptInterface.Utilities.CachingOptimizer(::MathOptInterface.Utilities.Model{Float64}, ::MathOptInterface.OptimizerWithAttributes)
      
      Closest candidates are:
        MathOptInterface.Utilities.CachingOptimizer(::MathOptInterface.ModelLike, ::MathOptInterface.Utilities.CachingOptimizerMode)
         @ MathOptInterface ~/.julia/packages/MathOptInterface/aJZbq/src/Utilities/cachingoptimizer.jl:88
        MathOptInterface.Utilities.CachingOptimizer(::MathOptInterface.ModelLike, ::MathOptInterface.ModelLike)

```

And now, I have no idea how to persue 😅  
Does someone know?

---

<div class="post-metadata">

### Author: ![K5Julien](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/k5julien/32/210626_2.png) [@K5Julien](https://discourse.julialang.org/u/K5Julien)
#### Post date: [July 17, 2024, 12:20pm UTC](https://discourse.julialang.org/t/how-to-handle-an-optimizer-which-doesnt-support-an-attribute-of-mathoptinterface/117133/2 "2024-07-17T12:20:31Z")

</div>

> [@K5Julien](#):
>
> ```julia
> nodecount = -1
> try
> nodecount = MOI.get(m, MOI.NodeCount())
> catch e
> println("Getting Node Count is not supported by the solver you use")
> rethrow(e)
> end
> 
> ```

Ok, seems like the problem came from `rethrow(e)` which I just removed to make everything work 😃

---

<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: [July 17, 2024, 9:59pm UTC](https://discourse.julialang.org/t/how-to-handle-an-optimizer-which-doesnt-support-an-attribute-of-mathoptinterface/117133/3 "2024-07-17T21:59:12Z")

</div>

> Ok, seems like the problem came from `rethrow(e)`

Yes, see

```julia
help?> rethrow
search: rethrow

  rethrow()

  Rethrow the current exception from within a catch block. The rethrown exception will continue
  propagation as if it had not been caught.

  │ Note
  │
  │ The alternative form rethrow(e) allows you to associate an alternative exception object
  │ e with the current backtrace. However this misrepresents the program state at the time
  │ of the error so you're encouraged to instead throw a new exception using throw(e). In
  │ Julia 1.1 and above, using throw(e) will preserve the root cause exception on the
  │ stack, as described in current_exceptions.

```
