Skip to content
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

Add more judicious enforcement of PyROS Solver time limit #2660

Merged
merged 25 commits into from
Jan 17, 2023

Conversation

shermanjasonaf
Copy link
Contributor

@shermanjasonaf shermanjasonaf commented Dec 7, 2022

Changes proposed in this PR:

  • Adjust subordinate subsolver time limit option prior to every PyROS subproblem (master feasibility, master, DR polishing, separation), based on the time_limit passed to PyROS and the time elapsed. This time limit adjustment method will be supported for 'gams', 'ipopt', and 'baron'.
  • Perform time elapsed vs time limit check after every master feasibility, master, DR polishing, and separation subproblem. Currently, this check is performed only after master and separation problems.

Todo (after #2659 merged)

  • Add unit tests, and/or resolve issues with current test set due to changes. This should resolve failing test cases.
  • Modify pyros.py such that subsolvers are copied/cloned on argument parsing, so that state of solver(s) passed by user remain unaffected.
  • Update version number, changelog

Legal Acknowledgement

By contributing to this software project, I have read the contribution guide and agree to the following terms and conditions for my contribution:

  1. I agree my contributions are submitted under the BSD license.
  2. I represent I am authorized to make the contributions and grant the license. If my employer has rights to intellectual property that includes these contributions, I represent that I have received permission to make contributions and grant the required license on behalf of that employer.

@shermanjasonaf
Copy link
Contributor Author

@jsiirola this PR is ready for review

@codecov
Copy link

codecov bot commented Dec 13, 2022

Codecov Report

Base: 87.06% // Head: 87.06% // Increases project coverage by +0.00% 🎉

Coverage data is based on head (2d97f27) compared to base (09c9e0c).
Patch coverage: 71.95% of modified lines in pull request are covered.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #2660   +/-   ##
=======================================
  Coverage   87.06%   87.06%           
=======================================
  Files         757      757           
  Lines       84513    84585   +72     
=======================================
+ Hits        73583    73647   +64     
- Misses      10930    10938    +8     
Flag Coverage Δ
linux 84.44% <28.04%> (-0.06%) ⬇️
osx 74.50% <28.04%> (-0.05%) ⬇️
other 84.63% <28.04%> (-0.06%) ⬇️
win 81.77% <28.04%> (-0.07%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
pyomo/contrib/pyros/master_problem_methods.py 88.37% <64.00%> (-2.02%) ⬇️
pyomo/contrib/pyros/pyros_algorithm_methods.py 95.18% <70.00%> (+1.27%) ⬆️
pyomo/contrib/pyros/util.py 85.17% <74.41%> (-0.87%) ⬇️
pyomo/contrib/pyros/pyros.py 94.24% <100.00%> (ø)
pyomo/contrib/pyros/separation_problem_methods.py 87.94% <100.00%> (+0.95%) ⬆️
pyomo/solvers/plugins/solvers/BARON.py 79.80% <0.00%> (+0.33%) ⬆️
pyomo/solvers/plugins/solvers/SCIPAMPL.py 75.31% <0.00%> (+0.42%) ⬆️
pyomo/common/env.py 91.16% <0.00%> (+2.00%) ⬆️

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

☔ View full report at Codecov.
📢 Do you have feedback about the report comment? Let us know in this issue.

Copy link
Member

@jsiirola jsiirola left a comment

Choose a reason for hiding this comment

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

Overall, this looks reasonable. In addition to the question and change below, can you also add a test that exercises the time_limit option (and improves the code coverage for processing timeouts)? That might be tricky (you may need to create a custom "mock solver" that does nothing but wait until the timeout and returns a prearranged state).

pyomo/contrib/pyros/pyros.py Outdated Show resolved Hide resolved
pyomo/contrib/pyros/util.py Show resolved Hide resolved
Copy link
Member

@jsiirola jsiirola left a comment

Choose a reason for hiding this comment

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

This looks good. I have two comments that are "nice-to-haves", but are not strictly required to merge.

Comment on lines 128 to 131
if isinstance(solver, type(SolverFactory("baron"))):
options_key = "MaxTime"
elif isinstance(solver, type(SolverFactory("ipopt"))):
options_key = "max_cpu_time"
Copy link
Member

Choose a reason for hiding this comment

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

Nothing wrong with this implementation, but it is slightly more efficient to use

if isinstance(solver, SolverFactory.get_class('baron')):

(This prevents creating / throwing away solver instances)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Noted.

Comment on lines +139 to +140
# ensure positive value assigned to avoid application error
solver.options[options_key] = max(30, 30 + time_remaining)
Copy link
Member

Choose a reason for hiding this comment

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

30 is somewhat random. Can you add a comment with some justification for selecting this as the minimal timeout(and why it is not - say - 1, 5, or 120)?

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.

5 participants