Skip to content

Add progress info for OptimizationBBO #336

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 16 commits into from
Aug 20, 2022

Conversation

SebastianM-C
Copy link
Contributor

@SebastianM-C SebastianM-C commented Aug 10, 2022

It would be useful to be able to use OptimizationBBO without having all the output printed to stdout. In order to do this, we can use the TraceMode keyword argument, but that's specific to OptimizationBBO and doesn't translate to all the optimizers.
I propose in this PR a new common keyword argument, verbose that could be translated to backend specific keywords, like TraceMode in BBO. This is the first commit of the PR.

A more general approach would be to avoid anything from getting to stdout and use the logging system for any messages. This would allow us to translate the stdout in progress information and more optimization backends could show progress bars.
I have WIP implementation in the second commit which shows how this could work for OptimizationBBO. The stdout forwarding is based on JuliaLang/julia#12711 (comment)

For the moment you need to set the verbose keyword to :compact and progress to true to get progress logging, but maybe we could auto-set verbose to that if the user uses progress=true.

@Vaibhavdixit02 @ChrisRackauckas Let me know what you think about this. Should I try to go more on the logging route or should we just do the verbose keyword for now?

As an example, this is how VS Code would show the progress with the current implementation.
image

@codecov
Copy link

codecov bot commented Aug 10, 2022

Codecov Report

Merging #336 (0f31a23) into master (fe73975) will not change coverage.
The diff coverage is n/a.

@@           Coverage Diff           @@
##           master     #336   +/-   ##
=======================================
  Coverage   79.34%   79.34%           
=======================================
  Files           9        9           
  Lines         276      276           
=======================================
  Hits          219      219           
  Misses         57       57           

📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more

function SciMLBase.__solve(prob::SciMLBase.OptimizationProblem, opt::BBO, data=Optimization.DEFAULT_DATA;
callback=(args...) -> (false),
maxiters::Union{Number,Nothing}=nothing,
maxtime::Union{Number,Nothing}=nothing,
abstol::Union{Number,Nothing}=nothing,
reltol::Union{Number,Nothing}=nothing,
progress=false, kwargs...)
verbose::Symbol=:compact,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we only allow true/false

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we separate between progress and verbose?

I'm not sure how to handle

  • progress=false, verbose=true. Do we show all logs with @info here?
  • progress=true, verbose=false. Do we just show the progress here?
  • progress=true, verbose=true. And here we also add other info like in the screenshot?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Progress and verbose are different. Trace logs should all be handled by progress. Verbose should be left to things like throwing warnings.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, so in that case all the functionality of the PR should be captured by progress and verbose will be reserved for warnings?
For the progress, should we display anything besides number of steps/maxiters?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ChrisRackauckas Should I remove verbose from this PR and just always redirect the stdout and use it for progress logging when progress=true?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We shouldn't just redirect to stdout. We should always control it with progress and verbose ourselves.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the comment. I reimplemented the PR using the callback and querying the BlackBoxOptim.OptRunController for info. I've also implemented time based or maxiters based progress.

if !isnothing(m)
s = tryparse(Int, m[1])
isnothing(s) && continue
isnothing(maxiters) && continue
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is maxiters silently using that value? Should we have the maxiters set to that value if the user doesn't provide anything? I think we shouldn't assume a maxiters in the progress logging and have something else passed to BBO.

From what I understood from @ChrisRackauckas we want maxiters to be always explicitely provided by the users.

Copy link
Member

@ChrisRackauckas ChrisRackauckas Aug 18, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No. If the solver can do exiting properly, let it exit when tolerances are hit. A lot of solvers just don't do this. When there is no other exit criteria, maxiters is required.

wait(task)
end
end

function SciMLBase.__solve(prob::SciMLBase.OptimizationProblem, opt::BBO, data=Optimization.DEFAULT_DATA;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is data and why do we set maxiters to length(data) if this is provided.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's used for passing a dataset if you want to write a data based loss, for example if you have observations from a system and then write a dynamic model for it and estimate the parameters. Unfortunately it looks like we don't use it much in the docs, we should probably do that more. Minibatching is a good use case for this https://docs.sciml.ai/dev/modules/Optimization/tutorials/minibatch/.

why do we set maxiters to length(data) if this is provided.

I think this was a consequence of copy-pasting the optimizationflux implementation, it is done for two reasons, that the callback iterates over the data hence it is required that the number of calls of it are <= length of data else there will be a index error and second for minibatching where the length is the number of batches. I agree it should probably not be set to that

SebastianM-C and others added 4 commits August 15, 2022 22:25
Reimplement progress logging using a callback. The required information
is now extracted directly from the OptRunController.
@SebastianM-C SebastianM-C changed the title [RFC] Redirect stdout and extract progress info Add progress info for OptimizationBBO Aug 18, 2022
@SebastianM-C
Copy link
Contributor Author

I've reimplemented progress logging without doing any stdout redirection. The implementation is now simpler and it should be more robust. I've also added progress for time based limits. The only remaining part would be tests (and formatting).

@SebastianM-C SebastianM-C marked this pull request as ready for review August 18, 2022 20:18
@Vaibhavdixit02
Copy link
Member

Vaibhavdixit02 commented Aug 19, 2022

I think it looks good now, I will go over it once more later today and merge, the test failures are unrelated

@ChrisRackauckas
Copy link
Member

This looks good to go, just needs to run the formatter.


if progress
# Set progressbar to 1 to finish it
Base.@logmsg(Base.LogLevel(-1), msg, progress=1, _id=:OptimizationBBO)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

msg is not defined here. Should it be ""?
Also, shouldn't this be after the bboptimize call?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added a commit to do that

@ChrisRackauckas ChrisRackauckas merged commit 5fc872e into SciML:master Aug 20, 2022
@SebastianM-C SebastianM-C deleted the redirect_stdout branch August 20, 2022 08:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants