Is there a consistent way to suppress the solver output in JuMP v0.19 or MOI? It isn’t clear to me if there is.
Not really; it’s all handled through each individual solver’s options API. As a hack, I suppose you could use
redirect_stdout(devnull) do
# code here
end
but that doesn’t remove the overhead of the solver printing status info (which may or may not be a problem).
devnull
is of type IO
not IOStream
:
ERROR: MethodError: no method matching redirect_stderr(::Base.DevNull)
Closest candidates are:
redirect_stderr() at stream.jl:1001
redirect_stderr(::Union{IOStream, Base.LibuvStream}) at stream.jl:995
redirect_stderr(::Function, ::Any) at stream.jl:1051
What’s the best way to convert from IO
to IOStream
?
The solution I ended up with was:
redirect_stdout((()->optimize!(model)),open("/dev/null", "w"))
Yep. Sorry, should have tested my code. Related issue: Proposal: Allow DevNull to be used in redirect_stdout · Issue #22879 · JuliaLang/julia · GitHub.
Just came across this old problem. If you want to use parts of the output you can redirect stdout to a string:
function capture_stdout(f)
stdout_orig = stdout
(rd, wr) = redirect_stdout()
f()
close(wr)
redirect_stdout(stdout_orig)
read(rd, String)
end
s = capture_stdout() do
optimize!(model)
end
#print the summary (which starts with "Number of Iterations")
try
s[findlast("Number of Iterations", s)[1]:end] |> print
catch
print(s)
end
EDIT:
Digged a bit further and found that most solvers support some kind of loglevel setting, e.g.:
- Ipopt: “print_level”
- Cbc: “LogLevel”
- Clp: “logLevel”
These options can be set either when initialising the model, e.g.
model = Model(with_optimizer(Ipopt.Optimizer, tol = 1e-8, max_iter = 1000, print_level = 1))`
or afterwards using the MOI Api (which is currently not so nicely documented …)
MOI.set(model, MOI.RawParameter("print_level"), 1)
Is this a portable solution or it works only in Linux/Mac ?
Use set_silent
:
model = Model(Ipopt.Optimizer)
set_silent(model)
Had some trouble with this where output was still printed.
It was due to the C level output not being flushed before the stdout gets restored.
So might be helpful to call :
Base.Libc.flush_cstdio()
Can use the following to print to a file as well :
open("/dev/null", "w") do f
redirect_stdout(f) do
# redirect_stdio(stdout=f,stderr=f) do
optimize!(model)
Base.Libc.flush_cstdio()
end
end