Skip to content

Commit

Permalink
Merge branch 'main' into add_highs_support
Browse files Browse the repository at this point in the history
  • Loading branch information
blnicho committed May 6, 2024
2 parents 3165c9d + e77be8c commit f776baf
Show file tree
Hide file tree
Showing 178 changed files with 3,361 additions and 2,201 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/test_branches.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ jobs:
python-version: '3.10'
- name: Black Formatting Check
run: |
pip install black
# Note v24.4.1 fails due to a bug in the parser
pip install 'black!=24.4.1'
black . -S -C --check --diff --exclude examples/pyomobook/python-ch/BadIndent.py
- name: Spell Check
uses: crate-ci/typos@master
Expand Down Expand Up @@ -92,7 +93,7 @@ jobs:
skip_doctest: 1
TARGET: linux
PYENV: conda
PACKAGES: mpi4py==3.1.5
PACKAGES: openmpi mpi4py

- os: ubuntu-latest
python: '3.10'
Expand Down Expand Up @@ -263,8 +264,7 @@ jobs:
if test -z "${{matrix.slim}}"; then
python -m pip install --cache-dir cache/pip cplex docplex \
|| echo "WARNING: CPLEX Community Edition is not available"
python -m pip install --cache-dir cache/pip \
-i https://pypi.gurobi.com gurobipy==10.0.3 \
python -m pip install --cache-dir cache/pip gurobipy==10.0.3\
|| echo "WARNING: Gurobi is not available"
python -m pip install --cache-dir cache/pip xpress \
|| echo "WARNING: Xpress Community Edition is not available"
Expand Down
17 changes: 12 additions & 5 deletions .github/workflows/test_pr_and_main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ on:
pull_request:
branches:
- main
types:
- opened
- reopened
- synchronize
- ready_for_review
workflow_dispatch:
inputs:
git-ref:
Expand Down Expand Up @@ -34,6 +39,8 @@ jobs:
lint:
name: lint/style-and-typos
runs-on: ubuntu-latest
if: |
contains(github.event.pull_request.title, '[WIP]') != true && !github.event.pull_request.draft
steps:
- name: Checkout Pyomo source
uses: actions/checkout@v4
Expand All @@ -43,7 +50,8 @@ jobs:
python-version: '3.10'
- name: Black Formatting Check
run: |
pip install black
# Note v24.4.1 fails due to a bug in the parser
pip install 'black!=24.4.1'
black . -S -C --check --diff --exclude examples/pyomobook/python-ch/BadIndent.py
- name: Spell Check
uses: crate-ci/typos@master
Expand Down Expand Up @@ -93,7 +101,7 @@ jobs:
skip_doctest: 1
TARGET: linux
PYENV: conda
PACKAGES: mpi4py==3.1.5
PACKAGES: openmpi mpi4py

- os: ubuntu-latest
python: '3.11'
Expand Down Expand Up @@ -293,8 +301,7 @@ jobs:
if test -z "${{matrix.slim}}"; then
python -m pip install --cache-dir cache/pip cplex docplex \
|| echo "WARNING: CPLEX Community Edition is not available"
python -m pip install --cache-dir cache/pip \
-i https://pypi.gurobi.com gurobipy==10.0.3 \
python -m pip install --cache-dir cache/pip gurobipy==10.0.3 \
|| echo "WARNING: Gurobi is not available"
python -m pip install --cache-dir cache/pip xpress \
|| echo "WARNING: Xpress Community Edition is not available"
Expand Down Expand Up @@ -734,7 +741,7 @@ jobs:
cover:
name: process-coverage-${{ matrix.TARGET }}
needs: build
if: always() # run even if a build job fails
if: success() || failure() # run even if a build job fails, but not if cancelled
runs-on: ${{ matrix.os }}
timeout-minutes: 10
strategy:
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/typos.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ WRONLY = "WRONLY"
Hax = "Hax"
# Big Sur
Sur = "Sur"
# contrib package named mis and the acronym whence the name comes
mis = "mis"
MIS = "MIS"
# Ignore the shorthand ans for answer
ans = "ans"
# Ignore the keyword arange
Expand Down
1 change: 1 addition & 0 deletions doc/OnlineDocs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
'sphinx.ext.todo',
'sphinx_copybutton',
'enum_tools.autoenum',
'sphinx.ext.autosectionlabel',
#'sphinx.ext.githubpages',
]

Expand Down
129 changes: 129 additions & 0 deletions doc/OnlineDocs/contributed_packages/iis.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,135 @@
Infeasibility Diagnostics
!!!!!!!!!!!!!!!!!!!!!!!!!

There are two closely related tools for infeasibility diagnosis:

- :ref:`Infeasible Irreducible System (IIS) Tool`
- :ref:`Minimal Intractable System finder (MIS) Tool`

The first simply provides a conduit for solvers that compute an
infeasible irreducible system (e.g., Cplex, Gurobi, or Xpress). The
second provides similar functionality, but uses the ``mis`` package
contributed to Pyomo.


Infeasible Irreducible System (IIS) Tool
========================================

.. automodule:: pyomo.contrib.iis.iis

.. autofunction:: pyomo.contrib.iis.write_iis

Minimal Intractable System finder (MIS) Tool
============================================

The file ``mis.py`` finds sets of actions that each, independently,
would result in feasibility. The zero-tolerance is whatever the
solver uses, so users may want to post-process output if it is going
to be used for analysis. It also computes a minimal intractable system
(which is not guaranteed to be unique). It was written by Ben Knueven
as part of the watertap project (https://github.com/watertap-org/watertap)
and is therefore governed by a license shown
at the top of ``mis.py``.

The algorithms come from John Chinneck's slides, see: https://www.sce.carleton.ca/faculty/chinneck/docs/CPAIOR07InfeasibilityTutorial.pdf

Solver
------

At the time of this writing, you need to use IPopt even for LPs.

Quick Start
-----------

The file ``trivial_mis.py`` is a tiny example listed at the bottom of
this help file, which references a Pyomo model with the Python variable
`m` and has these lines:

.. code-block:: python
from pyomo.contrib.mis import compute_infeasibility_explanation
ipopt = pyo.SolverFactory("ipopt")
compute_infeasibility_explanation(m, solver=ipopt)
.. Note::
This is done instead of solving the problem.

.. Note::
IDAES users can pass ``get_solver()`` imported from ``ideas.core.solvers``
as the solver.

Interpreting the Output
-----------------------

Assuming the dependencies are installed, running ``trivial_mis.py``
(shown below) will
produce a lot of warnings from IPopt and then meaningful output (using a logger).

Repair Options
^^^^^^^^^^^^^^

This output for the trivial example shows three independent ways that the model could be rendered feasible:


.. code-block:: text
Model Trivial Quad may be infeasible. A feasible solution was found with only the following variable bounds relaxed:
ub of var x[1] by 4.464126126706818e-05
lb of var x[2] by 0.9999553410114216
Another feasible solution was found with only the following variable bounds relaxed:
lb of var x[1] by 0.7071067726864677
ub of var x[2] by 0.41421355687130673
ub of var y by 0.7071067651855212
Another feasible solution was found with only the following inequality constraints, equality constraints, and/or variable bounds relaxed:
constraint: c by 0.9999999861866736
Minimal Intractable System (MIS)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

This output shows a minimal intractable system:


.. code-block:: text
Computed Minimal Intractable System (MIS)!
Constraints / bounds in MIS:
lb of var x[2]
lb of var x[1]
constraint: c
Constraints / bounds in guards for stability
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

This part of the report is for nonlinear programs (NLPs).

When we’re trying to reduce the constraint set, for an NLP there may be constraints that when missing cause the solver
to fail in some catastrophic fashion. In this implementation this is interpreted as failing to get a `results`
object back from the call to `solve`. In these cases we keep the constraint in the problem but it’s in the
set of “guard” constraints – we can’t really be sure they’re a source of infeasibility or not,
just that “bad things” happen when they’re not included.

Perhaps ideally we would put a constraint in the “guard” set if IPopt failed to converge, and only put it in the
MIS if IPopt converged to a point of local infeasibility. However, right now the code generally makes the
assumption that if IPopt fails to converge the subproblem is infeasible, though obviously that is far from the truth.
Hence for difficult NLPs even the “Phase 1” may “fail” – in that when finished the subproblem containing just the
constraints in the elastic filter may be feasible -- because IPopt failed to converge and we assumed that meant the
subproblem was not feasible.

Dealing with NLPs is far from clean, but that doesn’t mean the tool can’t return useful results even when its assumptions are not satisfied.

trivial_mis.py
--------------

.. code-block:: python
import pyomo.environ as pyo
m = pyo.ConcreteModel("Trivial Quad")
m.x = pyo.Var([1,2], bounds=(0,1))
m.y = pyo.Var(bounds=(0, 1))
m.c = pyo.Constraint(expr=m.x[1] * m.x[2] == -1)
m.d = pyo.Constraint(expr=m.x[1] + m.y >= 1)
from pyomo.contrib.mis import compute_infeasibility_explanation
ipopt = pyo.SolverFactory("ipopt")
compute_infeasibility_explanation(m, solver=ipopt)
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
Backward Compatibility
======================

While PyNumero is a third-party contribution to Pyomo, we intend to maintain
the stability of its core functionality. The core functionality of PyNumero
consists of:

1. The ``NLP`` API and ``PyomoNLP`` implementation of this API
2. HSL and MUMPS linear solver interfaces
3. ``BlockVector`` and ``BlockMatrix`` classes
4. CyIpopt and SciPy solver interfaces

Other parts of PyNumero, such as ``ExternalGreyBoxBlock`` and
``ImplicitFunctionSolver``, are experimental and subject to change without notice.
1 change: 1 addition & 0 deletions doc/OnlineDocs/contributed_packages/pynumero/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ PyNumero. For more details, see the API documentation (:ref:`pynumero_api`).
installation.rst
tutorial.rst
api.rst
backward_compatibility.rst


Developers
Expand Down
7 changes: 4 additions & 3 deletions doc/OnlineDocs/contributed_packages/pyros.rst
Original file line number Diff line number Diff line change
Expand Up @@ -903,10 +903,10 @@ Observe that the log contains the following information:
:linenos:
==============================================================================
PyROS: The Pyomo Robust Optimization Solver, v1.2.9.
Pyomo version: 6.7.0
PyROS: The Pyomo Robust Optimization Solver, v1.2.11.
Pyomo version: 6.7.2
Commit hash: unknown
Invoked at UTC 2023-12-16T00:00:00.000000
Invoked at UTC 2024-03-28T00:00:00.000000
Developed by: Natalie M. Isenberg (1), Jason A. F. Sherman (1),
John D. Siirola (2), Chrysanthos E. Gounaris (1)
Expand All @@ -926,6 +926,7 @@ Observe that the log contains the following information:
keepfiles=False
tee=False
load_solution=True
symbolic_solver_labels=False
objective_focus=<ObjectiveType.worst_case: 1>
nominal_uncertain_param_vals=[0.13248000000000001, 4.97, 4.97, 1800]
decision_rule_order=1
Expand Down
13 changes: 10 additions & 3 deletions doc/OnlineDocs/contribution_guide.rst
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ at least 70% coverage of the lines modified in the PR and prefer coverage
closer to 90%. We also require that all tests pass before a PR will be
merged.

.. note::
If you are having issues getting tests to pass on your Pull Request,
please tag any of the core developers to ask for help.

The Pyomo main branch provides a Github Actions workflow (configured
in the ``.github/`` directory) that will test any changes pushed to
a branch with a subset of the complete test harness that includes
Expand All @@ -82,13 +86,16 @@ This will enable the tests to run automatically with each push to your fork.

At any point in the development cycle, a "work in progress" pull request
may be opened by including '[WIP]' at the beginning of the PR
title. This allows your code changes to be tested by the full suite of
Pyomo's automatic
testing infrastructure. Any pull requests marked '[WIP]' will not be
title. Any pull requests marked '[WIP]' or draft will not be
reviewed or merged by the core development team. However, any
'[WIP]' pull request left open for an extended period of time without
active development may be marked 'stale' and closed.

.. note::
Draft and WIP Pull Requests will **NOT** trigger tests. This is an effort to
reduce our CI backlog. Please make use of the provided
branch test suite for evaluating / testing draft functionality.

Python Version Support
++++++++++++++++++++++

Expand Down
7 changes: 7 additions & 0 deletions doc/OnlineDocs/library_reference/common/enums.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

pyomo.common.enums
==================

.. automodule:: pyomo.common.enums
:members:
:member-order: bysource
1 change: 1 addition & 0 deletions doc/OnlineDocs/library_reference/common/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ or rely on any other parts of Pyomo.
config.rst
dependencies.rst
deprecation.rst
enums.rst
errors.rst
fileutils.rst
formatting.rst
Expand Down
2 changes: 1 addition & 1 deletion examples/pyomobook/pyomo-components-ch/obj_declaration.txt
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ Model unknown
None
value
x[Q] + 2*x[R]
1
minimize
6.5
Model unknown

Expand Down
2 changes: 1 addition & 1 deletion pyomo/common/deprecation.py
Original file line number Diff line number Diff line change
Expand Up @@ -542,7 +542,7 @@ def __renamed__warning__(msg):

if new_class is None and '__renamed__new_class__' not in classdict:
if not any(
hasattr(base, '__renamed__new_class__')
hasattr(mro, '__renamed__new_class__')
for mro in itertools.chain.from_iterable(
base.__mro__ for base in renamed_bases
)
Expand Down
Loading

0 comments on commit f776baf

Please sign in to comment.