Skip to content

Comments

Add constructor kwarg set_inner_silent#180

Closed
sandyspiers wants to merge 1 commit intojump-dev:masterfrom
sandyspiers:add-set-inner-silent-kwarg
Closed

Add constructor kwarg set_inner_silent#180
sandyspiers wants to merge 1 commit intojump-dev:masterfrom
sandyspiers:add-set-inner-silent-kwarg

Conversation

@sandyspiers
Copy link
Contributor

Adds a keyword argument set_inner_silent to model constructor, which can be used to avoid MOA setting the inner optimizer silent.

Use case: I faced this issue when using Gurobi as in the lower level optimizer, where I could not find a way to turn back on the output. It seems like any output parameters are ignored and overwritten when optimize! is called (I guess because of Gurobi's lazy model generation?).

A workaround to get the output is if you call optimize! first, then set OutputFlag=1, then re-optimize. But this is unreasonable for large models. An example is shown below.

using JuMP, Gurobi, MultiObjectiveAlgorithms
MOA = MultiObjectiveAlgorithms

@info "First solve..."
n = 100
opt = optimizer_with_attributes(() -> MOA.Optimizer(Gurobi.Optimizer))
mdl = Model(opt)
@variable(mdl, x[1:n], Bin)
@objective(mdl, Max, [rand(n)' * x, rand(n)' * x])
set_optimizer_attribute(mdl, "OutputFlag", 1)
optimize!(mdl)

println("\n")
@info "Second attempt...."
set_optimizer_attribute(mdl, "OutputFlag", 1)
optimize!(mdl)

println("\n")
@info "With set_inner_silent=false"
n = 100
opt = optimizer_with_attributes(
    () -> MOA.Optimizer(Gurobi.Optimizer; set_inner_silent = false),
)
mdl = Model(opt)
@variable(mdl, x[1:n], Bin)
@objective(mdl, Max, [rand(n)' * x, rand(n)' * x])
set_optimizer_attribute(mdl, "OutputFlag", 1)
optimize!(mdl)

Which has the following output:

[ Info: First solve...
Set parameter WLSAccessID
Set parameter WLSSecret
Set parameter LicenseID to value 2461048
Academic license 2461048 - for non-commercial use only - registered to sa___@curtin.edu.au
Set parameter OutputFlag to value 1
----------------------------------------------
        MultiObjectiveAlgorithms.jl
----------------------------------------------
Algorithm: Nothing
----------------------------------------------
solve #     Obj. 1       Obj. 2       Time
----------------------------------------------
    1    4.67116e+01  5.29008e+01  3.58649e+00
    2    4.67116e+01  5.29008e+01  3.67085e+00
    3    4.67116e+01  5.29008e+01  4.05418e+00
    4    4.67116e+01  5.29008e+01  4.05596e+00
----------------------------------------------
termination_status: OPTIMAL
result_count: 1

Total solve time:          5.05048e+00
Time spent in subproblems: 7.92038e-01 (16%)
Number of subproblems:     6
----------------------------------------------


[ Info: Second attempt....
Set parameter OutputFlag to value 1
----------------------------------------------
        MultiObjectiveAlgorithms.jl
----------------------------------------------
Algorithm: Nothing
----------------------------------------------
solve #     Obj. 1       Obj. 2       Time
----------------------------------------------
Gurobi Optimizer version 13.0.0 build v13.0.0rc1 (linux64 - "Arch Linux")

CPU model: AMD Ryzen 7 7730U with Radeon Graphics, instruction set [SSE2|AVX|AVX2]
Thread count: 8 physical cores, 16 logical processors, using up to 16 threads

Academic license 2461048 - for non-commercial use only - registered to sa___@curtin.edu.au
Optimize a model with 0 rows, 100 columns and 0 nonzeros (Max)
Model fingerprint: 0x59950ce6
Model has 100 linear objective coefficients

*** OUTPUT TRUNCATED ***

Explored 0 nodes (0 simplex iterations) in 0.00 seconds (0.00 work units)
Thread count was 1 (of 16 available processors)

Solution count 1: 52.9008

Optimal solution found (tolerance 1.00e-04)
Best objective 5.290076734093e+01, best bound 5.290076734093e+01, gap 0.0000%

User-callback calls 30, time in user-callback 0.00 sec
Set parameter TimeLimit to value 1e+100
----------------------------------------------
termination_status: OPTIMAL
result_count: 1

Total solve time:          1.90709e-02
Time spent in subproblems: 1.27451e-02 (67%)
Number of subproblems:     6
----------------------------------------------


[ Info: With set_inner_silent=false
Set parameter WLSAccessID
Set parameter WLSSecret
Set parameter LicenseID to value 2461048
Academic license 2461048 - for non-commercial use only - registered to sa___@curtin.edu.au
Set parameter OutputFlag to value 1
Set parameter OutputFlag to value 1
----------------------------------------------
        MultiObjectiveAlgorithms.jl
----------------------------------------------
Algorithm: Nothing
----------------------------------------------
solve #     Obj. 1       Obj. 2       Time
----------------------------------------------
Set parameter OutputFlag to value 1
Gurobi Optimizer version 13.0.0 build v13.0.0rc1 (linux64 - "Arch Linux")

CPU model: AMD Ryzen 7 7730U with Radeon Graphics, instruction set [SSE2|AVX|AVX2]
Thread count: 8 physical cores, 16 logical processors, using up to 16 threads

Academic license 2461048 - for non-commercial use only - registered to sa___@curtin.edu.au
Optimize a model with 0 rows, 100 columns and 0 nonzeros (Max)
Model fingerprint: 0x892d8ed3

*** OUTPUT TRUNCATED ***

Solution count 1: 47.9289

Optimal solution found (tolerance 1.00e-04)
Best objective 4.792890566188e+01, best bound 4.792890566188e+01, gap 0.0000%

User-callback calls 30, time in user-callback 0.00 sec
Set parameter TimeLimit to value 1e+100
----------------------------------------------
termination_status: OPTIMAL
result_count: 1

Total solve time:          1.37079e-02
Time spent in subproblems: 1.00780e-02 (74%)
Number of subproblems:     6
----------------------------------------------

Thanks!

@codecov
Copy link

codecov bot commented Feb 24, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 88.11%. Comparing base (2f32152) to head (3f3199e).
⚠️ Report is 4 commits behind head on master.

❗ There is a different number of reports uploaded between BASE (2f32152) and HEAD (3f3199e). Click for more details.

HEAD has 3 uploads less than BASE
Flag BASE (2f32152) HEAD (3f3199e)
4 1
Additional details and impacted files
@@             Coverage Diff             @@
##           master     #180       +/-   ##
===========================================
- Coverage   99.92%   88.11%   -11.81%     
===========================================
  Files          12       12               
  Lines        1280     1279        -1     
===========================================
- Hits         1279     1127      -152     
- Misses          1      152      +151     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@sandyspiers
Copy link
Contributor Author

sandyspiers commented Feb 24, 2026

On second thought, I think I would prefer if there was an attribute, so that the following would work:

opt = optimizer_with_attributes(
    () -> MOA.Optimizer(Gurobi.Optimizer),
    MOA.SilentInner() => false,
)

I guess this would require moving

if MOI.supports(inner, MOI.Silent())

into the optimizer_inner! function.

Is either option preferred by the maintainers?

@odow
Copy link
Member

odow commented Feb 24, 2026

The argument option please. Otherwise I can do this tomorrow. I had assumed the inner solves are too noisy, but I guess it can hep debugging

@sandyspiers
Copy link
Contributor Author

Sounds good, I am happy to stick with the argument. Are any other changes required?

@odow
Copy link
Member

odow commented Feb 24, 2026

Oh no, I mistyped. I meant the attribute. Sorry on phone

@odow odow closed this in #181 Feb 24, 2026
@sandyspiers sandyspiers deleted the add-set-inner-silent-kwarg branch February 24, 2026 23:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants