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

Solver Refactor Part 2: Reduce Duplication & Restructure for Future Redesign #3447

Closed
wants to merge 42 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
4acc2ab
port highs interface to contrib.solver
michaelbynum May 14, 2024
52aa177
run black
michaelbynum May 14, 2024
8be2f94
bug in highs interface
michaelbynum May 30, 2024
5f3a9aa
Merge remote-tracking branch 'main_fork/main' into solvers
michaelbynum May 30, 2024
65033c4
Merge branch 'main' into solvers
mrmundt Jun 11, 2024
a56b35a
Refactoring: cleaning up code; fixing bug in LegacySolutionStatus
mrmundt Jun 11, 2024
0a961b3
Fix doctests
mrmundt Jun 11, 2024
c40fbb0
Merge branch 'main' into solvers
blnicho Jul 8, 2024
01eab67
Merge branch 'main' of github.com:Pyomo/pyomo into solvers
mrmundt Jul 23, 2024
a8ad1d6
Correct BARON URL
mrmundt Jul 23, 2024
d63c052
Minor refactoring: fixing pylint W/E's
mrmundt Jul 23, 2024
33db05a
Attempt to fix broken tests
mrmundt Jul 23, 2024
6b46ecd
Run black on gurobi
mrmundt Jul 23, 2024
7d1f6cf
Reset gurobi.py to previous version
mrmundt Jul 23, 2024
f09f352
Correctly apply pylint recommendations
mrmundt Jul 24, 2024
3ce57a7
Apply black
mrmundt Jul 24, 2024
71856fe
Minor formatting changes
mrmundt Jul 24, 2024
2c09ad8
Merge branch 'main' of github.com:Pyomo/pyomo into solvers
mrmundt Jul 30, 2024
f827498
Refactor: Standardize error messages
mrmundt Jul 30, 2024
4dfc14c
Merge remote-tracking branch 'michaelbynum/solvers' into solvers_backup
michaelbynum Aug 19, 2024
891efc0
fix highs output buffering
michaelbynum Aug 19, 2024
e8aeacd
Refactor of persistent solver to mixin
mrmundt Sep 4, 2024
85935f5
Merge main
mrmundt Sep 4, 2024
285f73f
Merge branch 'solvers' of github.com:michaelbynum/pyomo into solvers
mrmundt Sep 4, 2024
616c00e
Apply black
mrmundt Sep 4, 2024
b87f1c8
Typos
mrmundt Sep 4, 2024
52d1216
Attempt intentional initialization of Mixin class
mrmundt Sep 4, 2024
3045ad2
Merge branch 'main' into solvers
mrmundt Dec 2, 2024
83d156b
Merge branch 'Pyomo:main' into solvers
mrmundt Dec 16, 2024
ba4c1c1
REFACTOR (note: test_base will be broken)
mrmundt Dec 16, 2024
e98299c
Apply black
mrmundt Dec 16, 2024
00dbe64
Resolve gurobi failures
mrmundt Dec 16, 2024
14b1b8a
Missed availability change
mrmundt Dec 16, 2024
66b5b24
Apply black
mrmundt Dec 16, 2024
15db95f
Fix base tests; rename gurobi to gurobi_persistent
mrmundt Dec 16, 2024
5dacecd
Apply black
mrmundt Dec 16, 2024
1bb8f06
Rename solution to solution_loader
mrmundt Dec 16, 2024
ae8a685
Missed solution -> solution_loader change
mrmundt Dec 16, 2024
c5d2cbc
Reduce duplicate code
mrmundt Dec 16, 2024
ecdf0a5
Apply black
mrmundt Dec 16, 2024
bd9756d
Typo
mrmundt Dec 16, 2024
a08ca2c
Fix documentation
mrmundt Dec 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 27 additions & 29 deletions doc/OnlineDocs/explanation/experimental/solvers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,14 @@ with existing interfaces).
:header-rows: 1

* - Solver
- Name registered in the |br| ``pyomo.contrib.solver.factory.SolverFactory``
- Name registered in the |br| ``pyomo.contrib.solver.common.factory.SolverFactory``
- Name registered in the |br| ``pyomo.opt.base.solvers.LegacySolverFactory``
* - Ipopt
- ``ipopt``
- ``ipopt_v2``
* - Gurobi (persistent)
- ``gurobi``
- ``gurobi_v2``
- ``gurobi_persistent``
- ``gurobi_persistent_v2``
* - Gurobi (direct)
- ``gurobi_direct``
- ``gurobi_direct_v2``
Expand All @@ -64,7 +64,6 @@ be used with other Pyomo tools / capabilities.
:skipif: not ipopt_available

import pyomo.environ as pyo
from pyomo.contrib.solver.util import assert_optimal_termination

model = pyo.ConcreteModel()
model.x = pyo.Var(initialize=1.5)
Expand All @@ -76,13 +75,14 @@ be used with other Pyomo tools / capabilities.
model.obj = pyo.Objective(rule=rosenbrock, sense=pyo.minimize)

status = pyo.SolverFactory('ipopt_v2').solve(model)
assert_optimal_termination(status)
pyo.assert_optimal_termination(status)
model.pprint()

.. testoutput::
:skipif: not ipopt_available
:hide:

...
2 Var Declarations
...
3 Declarations: x y obj
Expand Down Expand Up @@ -114,6 +114,7 @@ future methods of specifying solver options are supported:
:skipif: not ipopt_available
:hide:

...
2 Var Declarations
...
3 Declarations: x y obj
Expand All @@ -128,8 +129,7 @@ Here we use the new interface by importing it directly:

# Direct import
import pyomo.environ as pyo
from pyomo.contrib.solver.util import assert_optimal_termination
from pyomo.contrib.solver.ipopt import Ipopt
from pyomo.contrib.solver.solvers.ipopt import Ipopt

model = pyo.ConcreteModel()
model.x = pyo.Var(initialize=1.5)
Expand All @@ -142,7 +142,7 @@ Here we use the new interface by importing it directly:

opt = Ipopt()
status = opt.solve(model)
assert_optimal_termination(status)
pyo.assert_optimal_termination(status)
# Displays important results information; only available through the new interfaces
status.display()
model.pprint()
Expand All @@ -165,8 +165,7 @@ Here we use the new interface by retrieving it from the new ``SolverFactory``:

# Import through new SolverFactory
import pyomo.environ as pyo
from pyomo.contrib.solver.util import assert_optimal_termination
from pyomo.contrib.solver.factory import SolverFactory
from pyomo.contrib.solver.common.factory import SolverFactory

model = pyo.ConcreteModel()
model.x = pyo.Var(initialize=1.5)
Expand All @@ -179,7 +178,7 @@ Here we use the new interface by retrieving it from the new ``SolverFactory``:

opt = SolverFactory('ipopt')
status = opt.solve(model)
assert_optimal_termination(status)
pyo.assert_optimal_termination(status)
# Displays important results information; only available through the new interfaces
status.display()
model.pprint()
Expand All @@ -204,7 +203,6 @@ replace the existing (legacy) SolverFactory and utilities with the new

# Change default SolverFactory version
import pyomo.environ as pyo
from pyomo.contrib.solver.util import assert_optimal_termination
from pyomo.__future__ import solver_factory_v3

model = pyo.ConcreteModel()
Expand All @@ -217,7 +215,7 @@ replace the existing (legacy) SolverFactory and utilities with the new
model.obj = pyo.Objective(rule=rosenbrock, sense=pyo.minimize)

status = pyo.SolverFactory('ipopt').solve(model)
assert_optimal_termination(status)
pyo.assert_optimal_termination(status)
# Displays important results information; only available through the new interfaces
status.display()
model.pprint()
Expand Down Expand Up @@ -245,13 +243,13 @@ recently incorporated into the redesigned NL writer. For example, you
can control the NL writer in the new ``ipopt`` interface through the
solver's ``writer_config`` configuration option:

.. autoclass:: pyomo.contrib.solver.ipopt.Ipopt
.. autoclass:: pyomo.contrib.solver.solvers.ipopt.Ipopt
:noindex:
:members: solve

.. testcode::

from pyomo.contrib.solver.ipopt import Ipopt
from pyomo.contrib.solver.solvers.ipopt import Ipopt
opt = Ipopt()
opt.config.writer_config.display()

Expand Down Expand Up @@ -281,18 +279,18 @@ Interface Implementation
------------------------

All new interfaces should be built upon one of two classes (currently):
:class:`SolverBase<pyomo.contrib.solver.base.SolverBase>` or
:class:`PersistentSolverBase<pyomo.contrib.solver.base.PersistentSolverBase>`.
:class:`SolverBase<pyomo.contrib.solver.common.base.SolverBase>` or
:class:`PersistentSolverBase<pyomo.contrib.solver.common.base.PersistentSolverBase>`.

All solvers should have the following:

.. autoclass:: pyomo.contrib.solver.base.SolverBase
.. autoclass:: pyomo.contrib.solver.common.base.SolverBase
:noindex:
:members:

Persistent solvers include additional members as well as other configuration options:

.. autoclass:: pyomo.contrib.solver.base.PersistentSolverBase
.. autoclass:: pyomo.contrib.solver.common.base.PersistentSolverBase
:noindex:
:show-inheritance:
:members:
Expand All @@ -301,12 +299,12 @@ Results
-------

Every solver, at the end of a
:meth:`solve<pyomo.contrib.solver.base.SolverBase.solve>` call, will
return a :class:`Results<pyomo.contrib.solver.results.Results>`
:meth:`solve<pyomo.contrib.solver.common.base.SolverBase.solve>` call, will
return a :class:`Results<pyomo.contrib.solver.common.results.Results>`
object. This object is a :py:class:`pyomo.common.config.ConfigDict`,
which can be manipulated similar to a standard ``dict`` in Python.

.. autoclass:: pyomo.contrib.solver.results.Results
.. autoclass:: pyomo.contrib.solver.common.results.Results
:noindex:
:show-inheritance:
:members:
Expand All @@ -318,12 +316,12 @@ Termination Conditions

Pyomo offers a standard set of termination conditions to map to solver
returns. The intent of
:class:`TerminationCondition<pyomo.contrib.solver.results.TerminationCondition>`
:class:`TerminationCondition<pyomo.contrib.solver.common.results.TerminationCondition>`
is to notify the user of why the solver exited. The user is expected
to inspect the :class:`Results<pyomo.contrib.solver.results.Results>`
to inspect the :class:`Results<pyomo.contrib.solver.common.results.Results>`
object or any returned solver messages or logs for more information.

.. autoclass:: pyomo.contrib.solver.results.TerminationCondition
.. autoclass:: pyomo.contrib.solver.common.results.TerminationCondition
:noindex:
:show-inheritance:

Expand All @@ -333,13 +331,13 @@ Solution Status

Pyomo offers a standard set of solution statuses to map to solver
output. The intent of
:class:`SolutionStatus<pyomo.contrib.solver.results.SolutionStatus>`
:class:`SolutionStatus<pyomo.contrib.solver.common.results.SolutionStatus>`
is to notify the user of what the solver returned at a high level. The
user is expected to inspect the
:class:`Results<pyomo.contrib.solver.results.Results>` object or any
:class:`Results<pyomo.contrib.solver.common.results.Results>` object or any
returned solver messages or logs for more information.

.. autoclass:: pyomo.contrib.solver.results.SolutionStatus
.. autoclass:: pyomo.contrib.solver.common.results.SolutionStatus
:noindex:
:show-inheritance:

Expand All @@ -351,7 +349,7 @@ Solutions can be loaded back into a model using a ``SolutionLoader``. A specific
loader should be written for each unique case. Several have already been
implemented. For example, for ``ipopt``:

.. autoclass:: pyomo.contrib.solver.ipopt.IpoptSolutionLoader
.. autoclass:: pyomo.contrib.solver.solvers.ipopt.IpoptSolutionLoader
:noindex:
:members:
:show-inheritance:
Expand Down
10 changes: 10 additions & 0 deletions pyomo/contrib/solver/common/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# ___________________________________________________________________________
#
# Pyomo: Python Optimization Modeling Objects
# Copyright (c) 2008-2024
# National Technology and Engineering Solutions of Sandia, LLC
# Under the terms of Contract DE-NA0003525 with National Technology and
# Engineering Solutions of Sandia, LLC, the U.S. Government retains certain
# rights in this software.
# This software is distributed under the 3-clause BSD License.
# ___________________________________________________________________________
Loading
Loading