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

Mindtpy rewrite #2887

Merged
merged 88 commits into from
Aug 23, 2023
Merged

Mindtpy rewrite #2887

merged 88 commits into from
Aug 23, 2023

Conversation

ZedongPeng
Copy link
Contributor

@ZedongPeng ZedongPeng commented Jun 26, 2023

Summary/Motivation:

This Pull Request completes several tasks left in MindtPy rewrite TODO list (#2709).

Changes proposed in this PR:

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.

Copy link
Contributor

@bernalde bernalde left a comment

Choose a reason for hiding this comment

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

Good PR @ZedongPeng I put several comments there. Some of them are really minor, others are considerable. I'm not quite following why the mip and nlp solve files are gone.
There are some open TODOs which should be addressed now.
Finally, I'm concerned about the effect on performance. While this PR is in review, can you submit the runs in Euler to see that there are not making much difference?

@@ -17,7 +17,8 @@
from pyomo.contrib.mindtpy.tests.feasibility_pump1 import Feasibility_Pump1
from pyomo.contrib.mindtpy.tests.feasibility_pump2 import Feasibility_Pump2

required_solvers = ('ipopt', 'glpk', 'cplex')
required_solvers = ('ipopt', 'cplex')
# TODO: 'appsi_highs' will fail here.
Copy link
Contributor

Choose a reason for hiding this comment

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

Why does it fail? It breaks or just does not converge?

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 thinks this is related to a bug inside appsi_solver. I just submitted an issue #2888.

Copy link
Contributor

Choose a reason for hiding this comment

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

Add the issue # in a comment and let's not wait for that to be solved to merge this PR

Copy link
Contributor

Choose a reason for hiding this comment

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

#2888 was closed yesterday, so you should verify that this works now and remove the comment.

Copy link
Contributor

Choose a reason for hiding this comment

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

+1 on this; does this work now?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

appsi_highs still does not work well with MindtPy, more specifically the feasibility pump method.
Here is the related issue #2951

pyomo/contrib/mindtpy/tests/test_mindtpy_feas_pump.py Outdated Show resolved Hide resolved
pyomo/contrib/mindtpy/util.py Outdated Show resolved Hide resolved
pyomo/contrib/mindtpy/algorithm_base_class.py Outdated Show resolved Hide resolved
pyomo/contrib/mindtpy/algorithm_base_class.py Outdated Show resolved Hide resolved
pyomo/contrib/mindtpy/nlp_solve.py Show resolved Hide resolved
pyomo/contrib/mindtpy/single_tree.py Outdated Show resolved Hide resolved
pyomo/contrib/mindtpy/single_tree.py Outdated Show resolved Hide resolved
pyomo/contrib/mindtpy/single_tree.py Outdated Show resolved Hide resolved
pyomo/contrib/mindtpy/single_tree.py Show resolved Hide resolved
@ZedongPeng
Copy link
Contributor Author

ZedongPeng commented Jun 26, 2023

@bernalde No problem. I'll run the benchmarks on Euler.
For your confusion about nlp_solve.py and mip_solver.py, here is the answer.

  • Before PR Mindtpy rewrite #2654 , the whole MindtPy algorithm relies heavily on solve_data.
  • In Mindtpy rewrite #2654 , we defined the algorithm base class and defined the elements in solve_data as the attributes of the class and defined the util functions as the methods of the class. However, this only applies to the multi-tree implementation since I didn't find a good way to interact between the algorithm base class and the callback functions of the MIP solvers.
  • After PR Mindtpy rewrite #2654 , the functions in nlp_solve.py and mip_solver.py are only used in the single-tree implementation. The multi-tree implementation can use the corresponding methods defined in algorithm_base_class.py.
  • The biggest change in this pull request is the single-tree implementation. Previously, the single-tree implementation relies on solve_data and can not access the attributes and methods of the algorithm base class. Now, I pass the mindtpy object to the persistent solvers, so that we can access the attributes and methods of the algorithm base class inside the callbacks of MIP solvers. Therefore, we can remove nlp_solve.py and mip_solver.py.

@bernalde
Copy link
Contributor

Thank you for the clarification! The tests seem to be running well, and once you address the comments in my review, this should be ready for revision and merging. I would like to have the performance results by then just to be sure that we are not merging anything that makes us way slower. Feel free to report on those here.

@ZedongPeng
Copy link
Contributor Author

No problem. Since this PR includes the UpdateConfig of appsi_solver, I'll also run benchmarks using appsi_solvers to see if it will improve the performance.

@jsiirola
Copy link
Member

Note: test failures on Jenkins are collection failures on Python 3.11:

.pyomo.contrib.mindtpy.tests.test_mindtpy
.pyomo.contrib.mindtpy.tests.test_mindtpy_ECP

exception:

pyomo/pyomo/contrib/mindtpy/tests/test_mindtpy.py:60: in <module>
    if all(SolverFactory(s).available() for s in required_solvers):
pyomo/pyomo/contrib/mindtpy/tests/test_mindtpy.py:60: in <genexpr>
    if all(SolverFactory(s).available() for s in required_solvers):
pyomo/pyomo/contrib/appsi/base.py:1633: in available
    raise ApplicationError(f'Solver {self.__class__} is not available ({ans}).')
E   pyomo.common.errors.ApplicationError: Solver <class 'pyomo.contrib.appsi.base.SolverFactoryClass.register.<locals>.decorator.<locals>.LegacySolver'> is not available (NotFound).

...both appear to be because an APPSI solver is not available.

@blnicho blnicho requested a review from emma58 June 27, 2023 18:42
@bernalde
Copy link
Contributor

bernalde commented Jul 5, 2023

We need to address all the open comments and manage the test failures when APPSI is not available, as reported on Jenkins @ZedongPeng

@ZedongPeng
Copy link
Contributor Author

In MINLP3_simple.py, if X equals -1, then log(0) will happen in const1 and result in the math domain error.
Therefore, I change the lower bound of X to -0.9.

PS: This will only happen with Python 3.7 or 3.8. If we use Python 3.10, math domain error will not be reported. Since this error happens inside the Gurobi callback function, I think gurobipy in Python 3.10 might have some special handling with the math domain error.

Y = m.Y = Var(J, domain=Binary, initialize=initY)
# CONTINUOUS VARIABLES
X = m.X = Var(I, domain=Reals, initialize=initX, bounds=(-1, 50))
"""Constraint definitions"""
# CONSTRAINTS
m.const1 = Constraint(expr=-X[2] + 5 * log(X[1] + 1) + 3 * Y[1] >= 0)
m.const2 = Constraint(expr=-X[2] + X[1] ** 2 - Y[1] <= 1)
m.const3 = Constraint(expr=X[1] + X[2] + 20 * Y[1] <= 24)
m.const4 = Constraint(expr=2 * X[2] + 3 * X[1] <= 10)

Copy link
Contributor

@mrmundt mrmundt 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 pretty good; I found a few places where the docstrings aren't correct.

pyomo/contrib/mindtpy/algorithm_base_class.py Show resolved Hide resolved
pyomo/contrib/mindtpy/algorithm_base_class.py Outdated Show resolved Hide resolved
pyomo/contrib/mindtpy/algorithm_base_class.py Outdated Show resolved Hide resolved
pyomo/contrib/mindtpy/algorithm_base_class.py Outdated Show resolved Hide resolved
pyomo/contrib/mindtpy/extended_cutting_plane.py Outdated Show resolved Hide resolved
@@ -17,7 +17,8 @@
from pyomo.contrib.mindtpy.tests.feasibility_pump1 import Feasibility_Pump1
from pyomo.contrib.mindtpy.tests.feasibility_pump2 import Feasibility_Pump2

required_solvers = ('ipopt', 'glpk', 'cplex')
required_solvers = ('ipopt', 'cplex')
# TODO: 'appsi_highs' will fail here.
Copy link
Contributor

Choose a reason for hiding this comment

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

+1 on this; does this work now?

Copy link
Contributor

@emma58 emma58 left a comment

Choose a reason for hiding this comment

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

@ZedongPeng, it looks like there are a couple changes you missed, but otherwise this looks good.

pyomo/contrib/mindtpy/algorithm_base_class.py Outdated Show resolved Hide resolved
Comment on lines 2282 to 2283
"APPSI-CPLEX cannot get duals for mixed-integer problems"
"mip_solver will be changed to CPLEX."
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm still confused about this logging message: What duals are you getting for a MIP and why do you have to change to cplex?

pyomo/contrib/mindtpy/util.py Outdated Show resolved Hide resolved
@ZedongPeng
Copy link
Contributor Author

I resolved the latest comments and this PR is ready to be merged after all checks succeed. @bernalde @emma58 @mrmundt

@mrmundt
Copy link
Contributor

mrmundt commented Aug 22, 2023

@ZedongPeng - the osx doctest failure looks like a spurious one (something took a fraction of a second longer than expected), so feel free to ignore it.

@mrmundt
Copy link
Contributor

mrmundt commented Aug 22, 2023

@ZedongPeng - Jenkins failure is also not your fault. Something is wrong with the machine. I'll go fix it.

@codecov
Copy link

codecov bot commented Aug 22, 2023

Codecov Report

Patch coverage: 62.89% and project coverage change: +0.24% 🎉

Comparison is base (c569b78) 87.84% compared to head (0d9430d) 88.09%.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2887      +/-   ##
==========================================
+ Coverage   87.84%   88.09%   +0.24%     
==========================================
  Files         770      768       -2     
  Lines       89665    89211     -454     
==========================================
- Hits        78764    78587     -177     
+ Misses      10901    10624     -277     
Flag Coverage Δ
linux 85.16% <62.26%> (+0.29%) ⬆️
osx 74.94% <8.17%> (+0.36%) ⬆️
other 85.34% <62.26%> (+0.29%) ⬆️
win 82.40% <62.26%> (+0.28%) ⬆️

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

Files Changed Coverage Δ
pyomo/contrib/mindtpy/algorithm_base_class.py 81.81% <ø> (+0.61%) ⬆️
pyomo/contrib/mindtpy/config_options.py 100.00% <ø> (ø)
pyomo/contrib/mindtpy/cut_generation.py 54.19% <0.00%> (-1.53%) ⬇️
pyomo/contrib/mindtpy/tabu_list.py 25.00% <0.00%> (ø)
...yomo/contrib/mindtpy/global_outer_approximation.py 29.16% <50.00%> (-7.88%) ⬇️
pyomo/contrib/mindtpy/util.py 79.32% <50.00%> (+14.95%) ⬆️
pyomo/contrib/mindtpy/extended_cutting_plane.py 83.09% <70.58%> (-1.52%) ⬇️
pyomo/contrib/mindtpy/single_tree.py 58.58% <74.68%> (+7.64%) ⬆️
pyomo/contrib/mindtpy/feasibility_pump.py 100.00% <100.00%> (ø)
pyomo/contrib/mindtpy/outer_approximation.py 90.32% <100.00%> (-0.31%) ⬇️

... and 6 files with indirect coverage changes

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

@mrmundt mrmundt merged commit 91a31d0 into Pyomo:main Aug 23, 2023
28 of 30 checks passed
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.

6 participants