From b54a396ba4c9b636336397d7228e3c41de12e023 Mon Sep 17 00:00:00 2001 From: Miranda Mundt Date: Fri, 10 Jan 2025 15:48:55 -0700 Subject: [PATCH 01/14] New Year, New Typos --- pyomo/contrib/doe/doe.py | 6 +++--- pyomo/core/base/indexed_component.py | 2 +- pyomo/core/expr/taylor_series.py | 2 +- pyomo/solvers/plugins/solvers/cplex_direct.py | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 5f3151961fb..3a616b714b8 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -1458,7 +1458,7 @@ def compute_FIM_full_factorial( } ) - succeses = 0 + successes = 0 failures = 0 total_points = np.prod( np.array([len(v) for k, v in design_ranges_enum.items()]) @@ -1477,14 +1477,14 @@ def compute_FIM_full_factorial( # Compute FIM with given options try: - curr_point = succeses + failures + 1 + curr_point = successes + failures + 1 # Logging information for each run self.logger.info("This is run %s out of %s.", curr_point, total_points) # Attempt the FIM computation self.compute_FIM(model=model, method=method) - succeses += 1 + successes += 1 # iteration time iter_t = iter_timer.toc(msg=None) diff --git a/pyomo/core/base/indexed_component.py b/pyomo/core/base/indexed_component.py index ee1fe1e0037..4fcbd30d1ff 100644 --- a/pyomo/core/base/indexed_component.py +++ b/pyomo/core/base/indexed_component.py @@ -344,7 +344,7 @@ def _create_objects_for_deepcopy(self, memo, component_list): # For indexed components, we will pre-emptively clone all # component data objects as well (as those are the objects # that will be referenced by things like expressions). It - # is important to only clone "normal" ComponentData obects: + # is important to only clone "normal" ComponentData objects: # so we will want to skip this for all scalar components # (where the _data points back to self) and references # (where the data may be stored outside this block tree and diff --git a/pyomo/core/expr/taylor_series.py b/pyomo/core/expr/taylor_series.py index 2658dd36ff5..7dc24f3ccf4 100644 --- a/pyomo/core/expr/taylor_series.py +++ b/pyomo/core/expr/taylor_series.py @@ -43,7 +43,7 @@ def taylor_series_expansion( The method for differentiation. order: The order of the taylor series expansion If order is not 1, then symbolic differentiation must - be used (differentiation.Modes.reverse_sybolic or + be used (differentiation.Modes.reverse_symbolic or differentiation.Modes.sympy). Returns diff --git a/pyomo/solvers/plugins/solvers/cplex_direct.py b/pyomo/solvers/plugins/solvers/cplex_direct.py index 93d8015514e..40b01f85e30 100644 --- a/pyomo/solvers/plugins/solvers/cplex_direct.py +++ b/pyomo/solvers/plugins/solvers/cplex_direct.py @@ -846,7 +846,7 @@ def _postsolve(self): if extract_slacks: linear_slacks = self._solver_model.solution.get_linear_slacks() - qudratic_slacks = self._solver_model.solution.get_quadratic_slacks() + quadratic_slacks = self._solver_model.solution.get_quadratic_slacks() for i, con_name in enumerate( self._solver_model.linear_constraints.get_names() ): @@ -869,7 +869,7 @@ def _postsolve(self): for i, con_name in enumerate( self._solver_model.quadratic_constraints.get_names() ): - soln_constraints[con_name]["Slack"] = qudratic_slacks[i] + soln_constraints[con_name]["Slack"] = quadratic_slacks[i] elif self._load_solutions: if cpxprob.solution.get_solution_type() > 0: self.load_vars() From 9ed1bdb228b82ddae34bf8fb32430158be67209e Mon Sep 17 00:00:00 2001 From: Miranda Mundt Date: Fri, 10 Jan 2025 15:49:42 -0700 Subject: [PATCH 02/14] Apply black --- pyomo/solvers/plugins/solvers/cplex_direct.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pyomo/solvers/plugins/solvers/cplex_direct.py b/pyomo/solvers/plugins/solvers/cplex_direct.py index 40b01f85e30..b758453df7d 100644 --- a/pyomo/solvers/plugins/solvers/cplex_direct.py +++ b/pyomo/solvers/plugins/solvers/cplex_direct.py @@ -846,7 +846,9 @@ def _postsolve(self): if extract_slacks: linear_slacks = self._solver_model.solution.get_linear_slacks() - quadratic_slacks = self._solver_model.solution.get_quadratic_slacks() + quadratic_slacks = ( + self._solver_model.solution.get_quadratic_slacks() + ) for i, con_name in enumerate( self._solver_model.linear_constraints.get_names() ): From 14f21e6036104072f5c8fe72dcc329484a81f2af Mon Sep 17 00:00:00 2001 From: Miranda Mundt Date: Fri, 10 Jan 2025 15:58:10 -0700 Subject: [PATCH 03/14] Change ubuntu-latest to ubuntu-22.04 --- .github/workflows/release_wheel_creation.yml | 6 ++--- .github/workflows/test_branches.yml | 18 ++++++------- .github/workflows/test_pr_and_main.yml | 28 ++++++++++---------- .github/workflows/url_check.yml | 2 +- 4 files changed, 27 insertions(+), 27 deletions(-) diff --git a/.github/workflows/release_wheel_creation.yml b/.github/workflows/release_wheel_creation.yml index 2637a315878..8b3f862504a 100644 --- a/.github/workflows/release_wheel_creation.yml +++ b/.github/workflows/release_wheel_creation.yml @@ -145,7 +145,7 @@ jobs: pure_python: name: pure_python_wheel - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 strategy: matrix: python-version: ['3.11'] @@ -175,9 +175,9 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest] + os: [ubuntu-22.04] include: - - os: ubuntu-latest + - os: ubuntu-22.04 TARGET: generic_tarball python-version: [3.9] steps: diff --git a/.github/workflows/test_branches.yml b/.github/workflows/test_branches.yml index 3315c5250df..8a66acf8a81 100644 --- a/.github/workflows/test_branches.yml +++ b/.github/workflows/test_branches.yml @@ -30,7 +30,7 @@ env: jobs: lint: name: lint/style-and-typos - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 steps: - name: Checkout Pyomo source uses: actions/checkout@v4 @@ -70,13 +70,13 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest] + os: [ubuntu-22.04] python: ['3.13'] other: [""] category: [""] include: - - os: ubuntu-latest + - os: ubuntu-22.04 python: '3.13' TARGET: linux PYENV: pip @@ -92,7 +92,7 @@ jobs: PYENV: conda PACKAGES: glpk pytest-qt filelock - - os: ubuntu-latest + - os: ubuntu-22.04 python: '3.11' other: /conda skip_doctest: 1 @@ -100,7 +100,7 @@ jobs: PYENV: conda PACKAGES: pytest-qt - - os: ubuntu-latest + - os: ubuntu-22.04 python: '3.10' other: /mpi mpi: 3 @@ -109,7 +109,7 @@ jobs: PYENV: conda PACKAGES: openmpi mpi4py - - os: ubuntu-latest + - os: ubuntu-22.04 python: '3.12' other: /cython setup_options: --with-cython @@ -688,7 +688,7 @@ jobs: bare-python-env: name: linux/3.9/bare-env - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 timeout-minutes: 10 steps: - name: Checkout Pyomo source @@ -735,10 +735,10 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-13, windows-latest] + os: [ubuntu-22.04, macos-13, windows-latest] include: - - os: ubuntu-latest + - os: ubuntu-22.04 TARGET: linux - os: macos-13 TARGET: osx diff --git a/.github/workflows/test_pr_and_main.yml b/.github/workflows/test_pr_and_main.yml index 98ec7fd933b..a04dd4b7a12 100644 --- a/.github/workflows/test_pr_and_main.yml +++ b/.github/workflows/test_pr_and_main.yml @@ -38,7 +38,7 @@ env: jobs: lint: name: lint/style-and-typos - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 if: | contains(github.event.pull_request.title, '[WIP]') != true && !github.event.pull_request.draft steps: @@ -67,13 +67,13 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-latest, windows-latest] + os: [ubuntu-22.04, macos-latest, windows-latest] python: [ 3.9, '3.10', '3.11', '3.12', '3.13' ] other: [""] category: [""] include: - - os: ubuntu-latest + - os: ubuntu-22.04 TARGET: linux PYENV: pip @@ -86,7 +86,7 @@ jobs: PYENV: conda PACKAGES: glpk pytest-qt filelock - - os: ubuntu-latest + - os: ubuntu-22.04 python: '3.11' other: /conda skip_doctest: 1 @@ -94,7 +94,7 @@ jobs: PYENV: conda PACKAGES: pytest-qt - - os: ubuntu-latest + - os: ubuntu-22.04 python: '3.10' other: /mpi mpi: 3 @@ -103,7 +103,7 @@ jobs: PYENV: conda PACKAGES: openmpi mpi4py - - os: ubuntu-latest + - os: ubuntu-22.04 python: '3.12' other: /cython setup_options: --with-cython @@ -119,7 +119,7 @@ jobs: TARGET: win PYENV: pip - - os: ubuntu-latest + - os: ubuntu-22.04 python: '3.11' other: /singletest category: "-m 'neos or importtest'" @@ -127,7 +127,7 @@ jobs: TARGET: linux PYENV: pip - - os: ubuntu-latest + - os: ubuntu-22.04 python: 3.9 other: /slim slim: 1 @@ -135,7 +135,7 @@ jobs: TARGET: linux PYENV: pip - - os: ubuntu-latest + - os: ubuntu-22.04 python: 3.12 other: /numpy2 slim: 1 @@ -144,14 +144,14 @@ jobs: PYENV: pip PACKAGES: "gurobipy dill numpy>2.0 scipy networkx" - - os: ubuntu-latest + - os: ubuntu-22.04 python: '3.10' other: /pyutilib TARGET: linux PYENV: pip PACKAGES: pyutilib - - os: ubuntu-latest + - os: ubuntu-22.04 python: pypy-3.9 skip_doctest: 1 TARGET: linux @@ -723,7 +723,7 @@ jobs: bare-python-env: name: linux/3.9/bare-env needs: lint # the linter job is a prerequisite for PRs - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 timeout-minutes: 10 steps: - name: Checkout Pyomo source @@ -770,10 +770,10 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-13, windows-latest] + os: [ubuntu-22.04, macos-13, windows-latest] include: - - os: ubuntu-latest + - os: ubuntu-22.04 TARGET: linux - os: macos-13 TARGET: osx diff --git a/.github/workflows/url_check.yml b/.github/workflows/url_check.yml index 797574574b4..6b8d3a9e092 100644 --- a/.github/workflows/url_check.yml +++ b/.github/workflows/url_check.yml @@ -11,7 +11,7 @@ on: jobs: url_check: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 steps: - name: Checkout Pyomo source uses: actions/checkout@v4 From 6a0be4939c77ee5729007c20100d03fee1750518 Mon Sep 17 00:00:00 2001 From: Miranda Mundt Date: Fri, 10 Jan 2025 16:37:07 -0700 Subject: [PATCH 04/14] Update ubuntu; update headless action --- .github/workflows/release_wheel_creation.yml | 10 +++---- .github/workflows/test_branches.yml | 20 ++++++------- .github/workflows/test_pr_and_main.yml | 30 ++++++++++---------- .github/workflows/url_check.yml | 2 +- 4 files changed, 31 insertions(+), 31 deletions(-) diff --git a/.github/workflows/release_wheel_creation.yml b/.github/workflows/release_wheel_creation.yml index 8b3f862504a..419921c795d 100644 --- a/.github/workflows/release_wheel_creation.yml +++ b/.github/workflows/release_wheel_creation.yml @@ -27,7 +27,7 @@ jobs: strategy: fail-fast: true matrix: - os: [ubuntu-22.04, windows-latest, macos-latest] + os: [ubuntu-latest, windows-latest, macos-latest] arch: [all] wheel-version: ['cp39*', 'cp310*', 'cp311*', 'cp312*', 'cp313*'] @@ -91,7 +91,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [ubuntu-22.04] + os: [ubuntu-latest] arch: [all] wheel-version: ['cp39*', 'cp310*', 'cp311*', 'cp312*', 'cp313*'] @@ -145,7 +145,7 @@ jobs: pure_python: name: pure_python_wheel - runs-on: ubuntu-22.04 + runs-on: ubuntu-latest strategy: matrix: python-version: ['3.11'] @@ -175,9 +175,9 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-22.04] + os: [ubuntu-latest] include: - - os: ubuntu-22.04 + - os: ubuntu-latest TARGET: generic_tarball python-version: [3.9] steps: diff --git a/.github/workflows/test_branches.yml b/.github/workflows/test_branches.yml index 8a66acf8a81..4e701c85d50 100644 --- a/.github/workflows/test_branches.yml +++ b/.github/workflows/test_branches.yml @@ -30,7 +30,7 @@ env: jobs: lint: name: lint/style-and-typos - runs-on: ubuntu-22.04 + runs-on: ubuntu-latest steps: - name: Checkout Pyomo source uses: actions/checkout@v4 @@ -70,13 +70,13 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-22.04] + os: [ubuntu-latest] python: ['3.13'] other: [""] category: [""] include: - - os: ubuntu-22.04 + - os: ubuntu-latest python: '3.13' TARGET: linux PYENV: pip @@ -92,7 +92,7 @@ jobs: PYENV: conda PACKAGES: glpk pytest-qt filelock - - os: ubuntu-22.04 + - os: ubuntu-latest python: '3.11' other: /conda skip_doctest: 1 @@ -100,7 +100,7 @@ jobs: PYENV: conda PACKAGES: pytest-qt - - os: ubuntu-22.04 + - os: ubuntu-latest python: '3.10' other: /mpi mpi: 3 @@ -109,7 +109,7 @@ jobs: PYENV: conda PACKAGES: openmpi mpi4py - - os: ubuntu-22.04 + - os: ubuntu-latest python: '3.12' other: /cython setup_options: --with-cython @@ -234,7 +234,7 @@ jobs: # have support for OSX. - name: Set up UI testing infrastructure if: ${{ matrix.TARGET != 'osx' }} - uses: pyvista/setup-headless-display-action@v2 + uses: pyvista/setup-headless-display-action@v3 with: qt: true pyvista: false @@ -688,7 +688,7 @@ jobs: bare-python-env: name: linux/3.9/bare-env - runs-on: ubuntu-22.04 + runs-on: ubuntu-latest timeout-minutes: 10 steps: - name: Checkout Pyomo source @@ -735,10 +735,10 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-22.04, macos-13, windows-latest] + os: [ubuntu-latest, macos-13, windows-latest] include: - - os: ubuntu-22.04 + - os: ubuntu-latest TARGET: linux - os: macos-13 TARGET: osx diff --git a/.github/workflows/test_pr_and_main.yml b/.github/workflows/test_pr_and_main.yml index a04dd4b7a12..860927ff7ee 100644 --- a/.github/workflows/test_pr_and_main.yml +++ b/.github/workflows/test_pr_and_main.yml @@ -38,7 +38,7 @@ env: jobs: lint: name: lint/style-and-typos - runs-on: ubuntu-22.04 + runs-on: ubuntu-latest if: | contains(github.event.pull_request.title, '[WIP]') != true && !github.event.pull_request.draft steps: @@ -67,13 +67,13 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-22.04, macos-latest, windows-latest] + os: [ubuntu-latest, macos-latest, windows-latest] python: [ 3.9, '3.10', '3.11', '3.12', '3.13' ] other: [""] category: [""] include: - - os: ubuntu-22.04 + - os: ubuntu-latest TARGET: linux PYENV: pip @@ -86,7 +86,7 @@ jobs: PYENV: conda PACKAGES: glpk pytest-qt filelock - - os: ubuntu-22.04 + - os: ubuntu-latest python: '3.11' other: /conda skip_doctest: 1 @@ -94,7 +94,7 @@ jobs: PYENV: conda PACKAGES: pytest-qt - - os: ubuntu-22.04 + - os: ubuntu-latest python: '3.10' other: /mpi mpi: 3 @@ -103,7 +103,7 @@ jobs: PYENV: conda PACKAGES: openmpi mpi4py - - os: ubuntu-22.04 + - os: ubuntu-latest python: '3.12' other: /cython setup_options: --with-cython @@ -119,7 +119,7 @@ jobs: TARGET: win PYENV: pip - - os: ubuntu-22.04 + - os: ubuntu-latest python: '3.11' other: /singletest category: "-m 'neos or importtest'" @@ -127,7 +127,7 @@ jobs: TARGET: linux PYENV: pip - - os: ubuntu-22.04 + - os: ubuntu-latest python: 3.9 other: /slim slim: 1 @@ -135,7 +135,7 @@ jobs: TARGET: linux PYENV: pip - - os: ubuntu-22.04 + - os: ubuntu-latest python: 3.12 other: /numpy2 slim: 1 @@ -144,14 +144,14 @@ jobs: PYENV: pip PACKAGES: "gurobipy dill numpy>2.0 scipy networkx" - - os: ubuntu-22.04 + - os: ubuntu-latest python: '3.10' other: /pyutilib TARGET: linux PYENV: pip PACKAGES: pyutilib - - os: ubuntu-22.04 + - os: ubuntu-latest python: pypy-3.9 skip_doctest: 1 TARGET: linux @@ -266,7 +266,7 @@ jobs: # have support for OSX. - name: Set up UI testing infrastructure if: ${{ matrix.TARGET != 'osx' }} - uses: pyvista/setup-headless-display-action@v2 + uses: pyvista/setup-headless-display-action@v3 with: qt: true pyvista: false @@ -723,7 +723,7 @@ jobs: bare-python-env: name: linux/3.9/bare-env needs: lint # the linter job is a prerequisite for PRs - runs-on: ubuntu-22.04 + runs-on: ubuntu-latest timeout-minutes: 10 steps: - name: Checkout Pyomo source @@ -770,10 +770,10 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-22.04, macos-13, windows-latest] + os: [ubuntu-latest, macos-13, windows-latest] include: - - os: ubuntu-22.04 + - os: ubuntu-latest TARGET: linux - os: macos-13 TARGET: osx diff --git a/.github/workflows/url_check.yml b/.github/workflows/url_check.yml index 6b8d3a9e092..797574574b4 100644 --- a/.github/workflows/url_check.yml +++ b/.github/workflows/url_check.yml @@ -11,7 +11,7 @@ on: jobs: url_check: - runs-on: ubuntu-22.04 + runs-on: ubuntu-latest steps: - name: Checkout Pyomo source uses: actions/checkout@v4 From 76c59d3c24209536b544b2eaae143851b2e9d02f Mon Sep 17 00:00:00 2001 From: Miranda Mundt Date: Mon, 13 Jan 2025 07:33:41 -0700 Subject: [PATCH 05/14] Fix broken URLs --- doc/OnlineDocs/explanation/analysis/doe/doe.rst | 2 +- pyomo/contrib/simplification/build.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/OnlineDocs/explanation/analysis/doe/doe.rst b/doc/OnlineDocs/explanation/analysis/doe/doe.rst index f80878b67eb..05d9d867e2b 100644 --- a/doc/OnlineDocs/explanation/analysis/doe/doe.rst +++ b/doc/OnlineDocs/explanation/analysis/doe/doe.rst @@ -3,7 +3,7 @@ Pyomo.DoE **Pyomo.DoE** (Pyomo Design of Experiments) is a Python library for model-based design of experiments using science-based models. -Pyomo.DoE was developed by **Jialu Wang** and **Alexander W. Dowling** at the University of Notre Dame as part of the `Carbon Capture Simulation for Industry Impact (CCSI2) `_. +Pyomo.DoE was developed by **Jialu Wang** and **Alexander W. Dowling** at the University of Notre Dame as part of the `Carbon Capture Simulation for Industry Impact (CCSI2) `_. project, funded through the U.S. Department Of Energy Office of Fossil Energy. If you use Pyomo.DoE, please cite: diff --git a/pyomo/contrib/simplification/build.py b/pyomo/contrib/simplification/build.py index b4bec63088a..d7fac9522dc 100644 --- a/pyomo/contrib/simplification/build.py +++ b/pyomo/contrib/simplification/build.py @@ -63,7 +63,7 @@ def build_ginac_library(parallel=None, argv=None, env=None): assert subprocess.run(make_cmd, cwd=cln_dir, env=env).returncode == 0 assert subprocess.run(install_cmd, cwd=cln_dir, env=env).returncode == 0 - url = 'https://www.ginac.de/ginac-1.8.7.tar.bz2' + url = 'https://www.ginac.de/ginac-1.8.8.tar.bz2' ginac_dir = os.path.join(tmpdir, 'ginac') downloader.set_destination_filename(ginac_dir) logger.info( From a625df65fce8de24500d26d09ef8b04cdf9e68a9 Mon Sep 17 00:00:00 2001 From: Miranda Mundt Date: Mon, 13 Jan 2025 07:42:02 -0700 Subject: [PATCH 06/14] Upgrade to pypy-3.10 --- .github/workflows/test_pr_and_main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test_pr_and_main.yml b/.github/workflows/test_pr_and_main.yml index 860927ff7ee..db48844debe 100644 --- a/.github/workflows/test_pr_and_main.yml +++ b/.github/workflows/test_pr_and_main.yml @@ -152,7 +152,7 @@ jobs: PACKAGES: pyutilib - os: ubuntu-latest - python: pypy-3.9 + python: 'pypy-3.10' skip_doctest: 1 TARGET: linux PYENV: pip From 2a50773b62b4145d292ffc0af68a69107251cd5a Mon Sep 17 00:00:00 2001 From: Miranda Mundt Date: Mon, 13 Jan 2025 08:29:45 -0700 Subject: [PATCH 07/14] Introduce PATH forcing --- .github/workflows/test_branches.yml | 28 +++++++++++++++++++++++++- .github/workflows/test_pr_and_main.yml | 28 +++++++++++++++++++++++++- README.md | 2 +- 3 files changed, 55 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test_branches.yml b/.github/workflows/test_branches.yml index 4e701c85d50..09626e781c0 100644 --- a/.github/workflows/test_branches.yml +++ b/.github/workflows/test_branches.yml @@ -428,6 +428,9 @@ jobs: mkdir -p "$DOWNLOAD_DIR" echo "TPL_DIR=$TPL_DIR" >> $GITHUB_ENV echo "DOWNLOAD_DIR=$DOWNLOAD_DIR" >> $GITHUB_ENV + # Create a new PYOMO_PATH variable so we can ensure that we are actually + # getting the right PATH at the end + echo "PYOMO_PATH=$PATH" >> $GITHUB_ENV - name: Install Ipopt if: ${{ ! matrix.slim }} @@ -435,6 +438,8 @@ jobs: IPOPT_DIR=$TPL_DIR/ipopt echo "$IPOPT_DIR" >> $GITHUB_PATH echo "LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$IPOPT_DIR" >> $GITHUB_ENV + NEW_PYOMO_PATH="$IPOPT_DIR:$PYOMO_PATH" + echo "PYOMO_PATH=$NEW_PYOMO_PATH" >> $GITHUB_ENV mkdir -p $IPOPT_DIR IPOPT_TAR=${DOWNLOAD_DIR}/ipopt.tar.gz if test ! -e $IPOPT_TAR; then @@ -511,7 +516,9 @@ jobs: - name: Install GAMS Python bindings if: ${{ ! matrix.slim }} run: | - GAMS_DIR="${env:TPL_DIR}/gams" + GAMS_DIR="$TPL_DIR/gams" + NEW_PYOMO_PATH="$GAMS_DIR:$PYOMO_PATH" + echo "PYOMO_PATH=$NEW_PYOMO_PATH" >> $GITHUB_ENV py_ver=$($PYTHON_EXE -c 'import sys;v="_%s%s" % sys.version_info[:2] \ ;print(v if v != "_27" else "")') if test -e $GAMS_DIR/apifiles/Python/api$py_ver; then @@ -528,6 +535,17 @@ jobs: $BARON_DIR = "${env:TPL_DIR}/baron" echo "$BARON_DIR" | ` Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append + $CURRENT_PYOMO_PATH="${env:PYOMO_PATH}" + # Prepend BARON_DIR with appropriate path separator + if ( "${{matrix.TARGET}}" -eq "win" ) { + $PATH_SEPARATOR = ";" + } else { + $PATH_SEPARATOR = ":" + } + $NEW_PYOMO_PATH = "$BARON_DIR$PATH_SEPARATOR$CURRENT_PYOMO_PATH" + echo "New PYOMO_PATH: $NEW_PYOMO_PATH" + echo "PYOMO_PATH=$NEW_PYOMO_PATH" | ` + Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append $URL = "https://minlp-downloads.nyc3.cdn.digitaloceanspaces.com/xecs/baron/current/" if ( "${{matrix.TARGET}}" -eq "win" ) { $INSTALLER = "${env:DOWNLOAD_DIR}/baron_install.exe" @@ -562,6 +580,8 @@ jobs: run: | GJH_DIR="$TPL_DIR/gjh" echo "${GJH_DIR}" >> $GITHUB_PATH + NEW_PYOMO_PATH="$GJH_DIR:$PYOMO_PATH" + echo "PYOMO_PATH=$NEW_PYOMO_PATH" >> $GITHUB_ENV INSTALL_DIR="${DOWNLOAD_DIR}/gjh" if test ! -e "$INSTALL_DIR/bin"; then mkdir -p "$INSTALL_DIR" @@ -637,6 +657,11 @@ jobs: - name: Report pyomo plugin information run: | + # MRM / Jan 9, 2025: We update the PATH manually to make sure we capture + # the all of our changes. This is necessary because of an + # issue with how the PATH rearranges on Windows. + # Issue: https://github.com/actions/runner-images/issues/11328 + export PATH=$PYOMO_PATH echo "$PATH" pyomo help --solvers || exit 1 pyomo help --transformations || exit 1 @@ -645,6 +670,7 @@ jobs: - name: Run Pyomo tests if: matrix.mpi == 0 run: | + export PATH=$PYOMO_PATH $PYTHON_EXE -m pytest -v \ -W ignore::Warning ${{matrix.category}} \ pyomo `pwd`/pyomo-model-libraries \ diff --git a/.github/workflows/test_pr_and_main.yml b/.github/workflows/test_pr_and_main.yml index db48844debe..f8d7b8f0892 100644 --- a/.github/workflows/test_pr_and_main.yml +++ b/.github/workflows/test_pr_and_main.yml @@ -460,6 +460,9 @@ jobs: mkdir -p "$DOWNLOAD_DIR" echo "TPL_DIR=$TPL_DIR" >> $GITHUB_ENV echo "DOWNLOAD_DIR=$DOWNLOAD_DIR" >> $GITHUB_ENV + # Create a new PYOMO_PATH variable so we can ensure that we are actually + # getting the right PATH at the end + echo "PYOMO_PATH=$PATH" >> $GITHUB_ENV - name: Install Ipopt if: ${{ ! matrix.slim }} @@ -467,6 +470,8 @@ jobs: IPOPT_DIR=$TPL_DIR/ipopt echo "$IPOPT_DIR" >> $GITHUB_PATH echo "LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$IPOPT_DIR" >> $GITHUB_ENV + NEW_PYOMO_PATH="$IPOPT_DIR:$PYOMO_PATH" + echo "PYOMO_PATH=$NEW_PYOMO_PATH" >> $GITHUB_ENV mkdir -p $IPOPT_DIR IPOPT_TAR=${DOWNLOAD_DIR}/ipopt.tar.gz if test ! -e $IPOPT_TAR; then @@ -543,7 +548,9 @@ jobs: - name: Install GAMS Python bindings if: ${{ ! matrix.slim }} run: | - GAMS_DIR="${env:TPL_DIR}/gams" + GAMS_DIR="$TPL_DIR/gams" + NEW_PYOMO_PATH="$GAMS_DIR:$PYOMO_PATH" + echo "PYOMO_PATH=$NEW_PYOMO_PATH" >> $GITHUB_ENV py_ver=$($PYTHON_EXE -c 'import sys;v="_%s%s" % sys.version_info[:2] \ ;print(v if v != "_27" else "")') if test -e $GAMS_DIR/apifiles/Python/api$py_ver; then @@ -560,6 +567,17 @@ jobs: $BARON_DIR = "${env:TPL_DIR}/baron" echo "$BARON_DIR" | ` Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append + $CURRENT_PYOMO_PATH="${env:PYOMO_PATH}" + # Prepend BARON_DIR with appropriate path separator + if ( "${{matrix.TARGET}}" -eq "win" ) { + $PATH_SEPARATOR = ";" + } else { + $PATH_SEPARATOR = ":" + } + $NEW_PYOMO_PATH = "$BARON_DIR$PATH_SEPARATOR$CURRENT_PYOMO_PATH" + echo "New PYOMO_PATH: $NEW_PYOMO_PATH" + echo "PYOMO_PATH=$NEW_PYOMO_PATH" | ` + Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append $URL = "https://minlp-downloads.nyc3.cdn.digitaloceanspaces.com/xecs/baron/current/" if ( "${{matrix.TARGET}}" -eq "win" ) { $INSTALLER = "${env:DOWNLOAD_DIR}/baron_install.exe" @@ -594,6 +612,8 @@ jobs: run: | GJH_DIR="$TPL_DIR/gjh" echo "${GJH_DIR}" >> $GITHUB_PATH + NEW_PYOMO_PATH="$GJH_DIR:$PYOMO_PATH" + echo "PYOMO_PATH=$NEW_PYOMO_PATH" >> $GITHUB_ENV INSTALL_DIR="${DOWNLOAD_DIR}/gjh" if test ! -e "$INSTALL_DIR/bin"; then mkdir -p "$INSTALL_DIR" @@ -670,6 +690,11 @@ jobs: - name: Report pyomo plugin information run: | + # MRM / Jan 9, 2025: We update the PATH manually to make sure we capture + # the all of our changes. This is necessary because of an + # issue with how the PATH rearranges on Windows. + # Issue: https://github.com/actions/runner-images/issues/11328 + export PATH=$PYOMO_PATH echo "$PATH" pyomo help --solvers || exit 1 pyomo help --transformations || exit 1 @@ -678,6 +703,7 @@ jobs: - name: Run Pyomo tests if: matrix.mpi == 0 run: | + export PATH=$PYOMO_PATH $PYTHON_EXE -m pytest -v \ -W ignore::Warning ${{matrix.category}} \ pyomo `pwd`/pyomo-model-libraries \ diff --git a/README.md b/README.md index 1cb773788f2..45ccce5b769 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ Pyomo is available under the BSD License - see the Pyomo is currently tested with the following Python implementations: * CPython: 3.9, 3.10, 3.11, 3.12, 3.13 -* PyPy: 3.9 +* PyPy: 3.10 _Testing and support policy_: From c86149155f868ab9f801639b9359449f1fa8520b Mon Sep 17 00:00:00 2001 From: Miranda Mundt Date: Mon, 13 Jan 2025 09:22:58 -0700 Subject: [PATCH 08/14] Fix PyNumero tests to use TempfileManager --- .../solvers/tests/test_cyipopt_solver.py | 37 ++++--- .../solvers/tests/test_pyomo_ext_cyipopt.py | 104 +++++++++--------- .../examples/tests/test_cyipopt_examples.py | 50 +++++---- .../tests/test_external_grey_box_model.py | 42 +++---- .../tests/test_pyomo_grey_box_nlp.py | 33 +++--- 5 files changed, 135 insertions(+), 131 deletions(-) diff --git a/pyomo/contrib/pynumero/algorithms/solvers/tests/test_cyipopt_solver.py b/pyomo/contrib/pynumero/algorithms/solvers/tests/test_cyipopt_solver.py index 8a35449d94d..9578be510a7 100644 --- a/pyomo/contrib/pynumero/algorithms/solvers/tests/test_cyipopt_solver.py +++ b/pyomo/contrib/pynumero/algorithms/solvers/tests/test_cyipopt_solver.py @@ -11,7 +11,7 @@ import pyomo.common.unittest as unittest import pyomo.environ as pyo -import os +from pyomo.common.tempfiles import TempfileManager from pyomo.contrib.pynumero.dependencies import ( numpy as np, @@ -219,24 +219,25 @@ def test_model1_with_scaling(self): m.scaling_factor[m.d] = 3.0 # scale the inequality constraint m.scaling_factor[m.x[1]] = 4.0 # scale one of the x variables - cynlp = CyIpoptNLP(PyomoNLP(m)) - options = { - 'nlp_scaling_method': 'user-scaling', - 'output_file': '_cyipopt-scaling.log', - 'file_print_level': 10, - 'max_iter': 0, - } - solver = CyIpoptSolver(cynlp, options=options) - x, info = solver.solve() - - with open('_cyipopt-scaling.log', 'r') as fd: - solver_trace = fd.read() - cynlp.close() - os.remove('_cyipopt-scaling.log') - - # check for the following strings in the log and then delete the log + with TempfileManager.new_context() as temp: + cynlp = CyIpoptNLP(PyomoNLP(m)) + logfile = temp.create_tempfile('_cyipopt-scaling.log') + options = { + 'nlp_scaling_method': 'user-scaling', + 'output_file': logfile, + 'file_print_level': 10, + 'max_iter': 0, + } + solver = CyIpoptSolver(cynlp, options=options) + x, info = solver.solve() + cynlp.close() + + with open(logfile, 'r') as fd: + solver_trace = fd.read() + + # check for the following strings in the log self.assertIn('nlp_scaling_method = user-scaling', solver_trace) - self.assertIn('output_file = _cyipopt-scaling.log', solver_trace) + self.assertIn(f"output_file = {logfile}", solver_trace) self.assertIn('objective scaling factor = 1e-06', solver_trace) self.assertIn('x scaling provided', solver_trace) self.assertIn('c scaling provided', solver_trace) diff --git a/pyomo/contrib/pynumero/algorithms/solvers/tests/test_pyomo_ext_cyipopt.py b/pyomo/contrib/pynumero/algorithms/solvers/tests/test_pyomo_ext_cyipopt.py index 0036a6b3623..5cb0fef91ba 100644 --- a/pyomo/contrib/pynumero/algorithms/solvers/tests/test_pyomo_ext_cyipopt.py +++ b/pyomo/contrib/pynumero/algorithms/solvers/tests/test_pyomo_ext_cyipopt.py @@ -9,9 +9,9 @@ # This software is distributed under the 3-clause BSD License. # ___________________________________________________________________________ -import os import pyomo.common.unittest as unittest import pyomo.environ as pyo +from pyomo.common.tempfiles import TempfileManager from pyomo.contrib.pynumero.dependencies import ( numpy as np, @@ -157,33 +157,33 @@ def test_pyomo_external_model_scaling(self): m.scaling_factor[m.F_con] = 8.0 # scale the pyomo constraint m.scaling_factor[m.Pin_con] = 9.0 # scale the pyomo constraint - cyipopt_problem = PyomoExternalCyIpoptProblem( - pyomo_model=m, - ex_input_output_model=PressureDropModel(), - inputs=[m.Pin, m.c1, m.c2, m.F], - outputs=[m.P1, m.P2], - outputs_eqn_scaling=[10.0, 11.0], - nl_file_options={'file_determinism': 2}, - ) - - # solve the problem - options = { - 'hessian_approximation': 'limited-memory', - 'nlp_scaling_method': 'user-scaling', - 'output_file': '_cyipopt-pyomo-ext-scaling.log', - 'file_print_level': 10, - 'max_iter': 0, - } - solver = CyIpoptSolver(cyipopt_problem, options=options) - x, info = solver.solve(tee=False) - - with open('_cyipopt-pyomo-ext-scaling.log', 'r') as fd: - solver_trace = fd.read() - cyipopt_problem.close() - os.remove('_cyipopt-pyomo-ext-scaling.log') + with TempfileManager.new_context() as temp: + cyipopt_problem = PyomoExternalCyIpoptProblem( + pyomo_model=m, + ex_input_output_model=PressureDropModel(), + inputs=[m.Pin, m.c1, m.c2, m.F], + outputs=[m.P1, m.P2], + outputs_eqn_scaling=[10.0, 11.0], + nl_file_options={'file_determinism': 2}, + ) + logfile = temp.create_tempfile('_cyipopt-pyomo-ext-scaling.log') + # solve the problem + options = { + 'hessian_approximation': 'limited-memory', + 'nlp_scaling_method': 'user-scaling', + 'output_file': logfile, + 'file_print_level': 10, + 'max_iter': 0, + } + solver = CyIpoptSolver(cyipopt_problem, options=options) + x, info = solver.solve(tee=False) + cyipopt_problem.close() + + with open(logfile, 'r') as fd: + solver_trace = fd.read() self.assertIn('nlp_scaling_method = user-scaling', solver_trace) - self.assertIn('output_file = _cyipopt-pyomo-ext-scaling.log', solver_trace) + self.assertIn(f"output_file = {logfile}", solver_trace) self.assertIn('objective scaling factor = 0.1', solver_trace) self.assertIn('x scaling provided', solver_trace) self.assertIn('c scaling provided', solver_trace) @@ -232,35 +232,33 @@ def test_pyomo_external_model_ndarray_scaling(self): m.scaling_factor[m.Pin_con] = 9.0 # scale the pyomo constraint # test that this all works with ndarray input as well - cyipopt_problem = PyomoExternalCyIpoptProblem( - pyomo_model=m, - ex_input_output_model=PressureDropModel(), - inputs=[m.Pin, m.c1, m.c2, m.F], - outputs=[m.P1, m.P2], - outputs_eqn_scaling=np.asarray([10.0, 11.0], dtype=np.float64), - nl_file_options={'file_determinism': 2}, - ) - - # solve the problem - options = { - 'hessian_approximation': 'limited-memory', - 'nlp_scaling_method': 'user-scaling', - 'output_file': '_cyipopt-pyomo-ext-scaling-ndarray.log', - 'file_print_level': 10, - 'max_iter': 0, - } - solver = CyIpoptSolver(cyipopt_problem, options=options) - x, info = solver.solve(tee=False) - - with open('_cyipopt-pyomo-ext-scaling-ndarray.log', 'r') as fd: - solver_trace = fd.read() - cyipopt_problem.close() - os.remove('_cyipopt-pyomo-ext-scaling-ndarray.log') + with TempfileManager.new_context() as temp: + cyipopt_problem = PyomoExternalCyIpoptProblem( + pyomo_model=m, + ex_input_output_model=PressureDropModel(), + inputs=[m.Pin, m.c1, m.c2, m.F], + outputs=[m.P1, m.P2], + outputs_eqn_scaling=np.asarray([10.0, 11.0], dtype=np.float64), + nl_file_options={'file_determinism': 2}, + ) + logfile = temp.create_tempfile('_cyipopt-pyomo-ext-scaling-ndarray.log') + # solve the problem + options = { + 'hessian_approximation': 'limited-memory', + 'nlp_scaling_method': 'user-scaling', + 'output_file': logfile, + 'file_print_level': 10, + 'max_iter': 0, + } + solver = CyIpoptSolver(cyipopt_problem, options=options) + x, info = solver.solve(tee=False) + cyipopt_problem.close() + + with open(logfile, 'r') as fd: + solver_trace = fd.read() self.assertIn('nlp_scaling_method = user-scaling', solver_trace) - self.assertIn( - 'output_file = _cyipopt-pyomo-ext-scaling-ndarray.log', solver_trace - ) + self.assertIn(f'output_file = {logfile}', solver_trace) self.assertIn('objective scaling factor = 0.1', solver_trace) self.assertIn('x scaling provided', solver_trace) self.assertIn('c scaling provided', solver_trace) diff --git a/pyomo/contrib/pynumero/examples/tests/test_cyipopt_examples.py b/pyomo/contrib/pynumero/examples/tests/test_cyipopt_examples.py index 2df43c1e797..22f2f4a844b 100644 --- a/pyomo/contrib/pynumero/examples/tests/test_cyipopt_examples.py +++ b/pyomo/contrib/pynumero/examples/tests/test_cyipopt_examples.py @@ -10,14 +10,16 @@ # ___________________________________________________________________________ import os.path +from io import StringIO +import logging + from pyomo.common.fileutils import this_file_dir, import_file +from pyomo.common.tempfiles import TempfileManager import pyomo.common.unittest as unittest import pyomo.environ as pyo from pyomo.common.dependencies import attempt_import from pyomo.common.log import LoggingIntercept from pyomo.opt import TerminationCondition -from io import StringIO -import logging from pyomo.contrib.pynumero.dependencies import ( numpy as np, @@ -87,30 +89,32 @@ def test_external_grey_box_react_example_maximize_cb_outputs_scaling(self): 'maximize_cb_ratio_residuals.py', ) ) - aoptions = { - 'nlp_scaling_method': 'user-scaling', - 'output_file': '_cyipopt-external-greybox-react-scaling.log', - 'file_print_level': 10, - } - m = ex.maximize_cb_ratio_residuals_with_output_scaling( - additional_options=aoptions - ) - self.assertAlmostEqual(pyo.value(m.reactor.inputs['sv']), 1.26541996, places=3) - self.assertAlmostEqual( - pyo.value(m.reactor.inputs['cb']), 1071.7410089, places=2 - ) - self.assertAlmostEqual( - pyo.value(m.reactor.outputs['cb_ratio']), 0.15190409266, places=3 - ) - with open('_cyipopt-external-greybox-react-scaling.log', 'r') as fd: - solver_trace = fd.read() - os.remove('_cyipopt-external-greybox-react-scaling.log') + with TempfileManager.new_context() as temp: + logfile = temp.create_tempfile('_cyipopt-external-greybox-react-scaling.log') + aoptions = { + 'nlp_scaling_method': 'user-scaling', + 'output_file': logfile, + 'file_print_level': 10, + } + m = ex.maximize_cb_ratio_residuals_with_output_scaling( + additional_options=aoptions + ) + self.assertAlmostEqual( + pyo.value(m.reactor.inputs['sv']), 1.26541996, places=3 + ) + self.assertAlmostEqual( + pyo.value(m.reactor.inputs['cb']), 1071.7410089, places=2 + ) + self.assertAlmostEqual( + pyo.value(m.reactor.outputs['cb_ratio']), 0.15190409266, places=3 + ) + + with open(logfile, 'r') as fd: + solver_trace = fd.read() self.assertIn('nlp_scaling_method = user-scaling', solver_trace) - self.assertIn( - 'output_file = _cyipopt-external-greybox-react-scaling.log', solver_trace - ) + self.assertIn(f'output_file = {logfile}', solver_trace) self.assertIn('objective scaling factor = 1', solver_trace) self.assertIn('x scaling provided', solver_trace) self.assertIn('c scaling provided', solver_trace) diff --git a/pyomo/contrib/pynumero/interfaces/tests/test_external_grey_box_model.py b/pyomo/contrib/pynumero/interfaces/tests/test_external_grey_box_model.py index 0fc342c4e40..1ea17b5e223 100644 --- a/pyomo/contrib/pynumero/interfaces/tests/test_external_grey_box_model.py +++ b/pyomo/contrib/pynumero/interfaces/tests/test_external_grey_box_model.py @@ -9,9 +9,9 @@ # This software is distributed under the 3-clause BSD License. # ___________________________________________________________________________ -import os import pyomo.common.unittest as unittest import pyomo.environ as pyo +from pyomo.common.tempfiles import TempfileManager from pyomo.contrib.pynumero.dependencies import ( numpy as np, @@ -31,8 +31,11 @@ from pyomo.contrib.pynumero.algorithms.solvers.cyipopt_solver import cyipopt_available -from ..external_grey_box import ExternalGreyBoxModel, ExternalGreyBoxBlock -from ..pyomo_nlp import PyomoGreyBoxNLP +from pyomo.contrib.pynumero.interfaces.external_grey_box import ( + ExternalGreyBoxModel, + ExternalGreyBoxBlock, +) +from pyomo.contrib.pynumero.interfaces.pyomo_nlp import PyomoGreyBoxNLP from pyomo.contrib.pynumero.interfaces.tests.compare_utils import ( check_vectors_specific_order, check_sparse_matrix_specific_order, @@ -2074,24 +2077,23 @@ def test_external_greybox_solve_scaling(self): m.scaling_factor[m.mu] = 1.9 m.scaling_factor[m.pincon] = 2.2 - solver = pyo.SolverFactory('cyipopt') - solver.config.options = { - 'hessian_approximation': 'limited-memory', - 'nlp_scaling_method': 'user-scaling', - 'output_file': '_cyipopt-external-greybox-scaling.log', - 'file_print_level': 10, - 'max_iter': 0, - } - status = solver.solve(m, tee=False) - - with open('_cyipopt-external-greybox-scaling.log', 'r') as fd: - solver_trace = fd.read() - os.remove('_cyipopt-external-greybox-scaling.log') + with TempfileManager.new_context() as temp: + logfile = temp.create_tempfile('_cyipopt-external-greybox-scaling.log') + solver = pyo.SolverFactory('cyipopt') + solver.config.options = { + 'hessian_approximation': 'limited-memory', + 'nlp_scaling_method': 'user-scaling', + 'output_file': logfile, + 'file_print_level': 10, + 'max_iter': 0, + } + status = solver.solve(m, tee=False) + + with open(logfile, 'r') as fd: + solver_trace = fd.read() self.assertIn('nlp_scaling_method = user-scaling', solver_trace) - self.assertIn( - 'output_file = _cyipopt-external-greybox-scaling.log', solver_trace - ) + self.assertIn(f'output_file = {logfile}', solver_trace) self.assertIn('objective scaling factor = 0.1', solver_trace) self.assertIn('x scaling provided', solver_trace) self.assertIn('c scaling provided', solver_trace) @@ -2149,4 +2151,4 @@ def test_external_greybox_solve_scaling(self): if __name__ == '__main__': - TestPyomoGreyBoxNLP().test_external_greybox_solve(self) + TestPyomoGreyBoxNLP().test_external_greybox_solve() diff --git a/pyomo/contrib/pynumero/interfaces/tests/test_pyomo_grey_box_nlp.py b/pyomo/contrib/pynumero/interfaces/tests/test_pyomo_grey_box_nlp.py index ecadf40e5cf..053c9aba4ea 100644 --- a/pyomo/contrib/pynumero/interfaces/tests/test_pyomo_grey_box_nlp.py +++ b/pyomo/contrib/pynumero/interfaces/tests/test_pyomo_grey_box_nlp.py @@ -9,9 +9,9 @@ # This software is distributed under the 3-clause BSD License. # ___________________________________________________________________________ -import os import pyomo.common.unittest as unittest import pyomo.environ as pyo +from pyomo.common.tempfiles import TempfileManager from pyomo.contrib.pynumero.dependencies import ( numpy as np, @@ -2495,24 +2495,23 @@ def test_external_greybox_solve_scaling(self): m.scaling_factor[m.mu] = 1.9 m.scaling_factor[m.pincon] = 2.2 - solver = pyo.SolverFactory('cyipopt') - solver.config.options = { - 'hessian_approximation': 'limited-memory', - 'nlp_scaling_method': 'user-scaling', - 'output_file': '_cyipopt-external-greybox-scaling.log', - 'file_print_level': 10, - 'max_iter': 0, - } - status = solver.solve(m, tee=False) - - with open('_cyipopt-external-greybox-scaling.log', 'r') as fd: - solver_trace = fd.read() - os.remove('_cyipopt-external-greybox-scaling.log') + with TempfileManager.new_context() as temp: + logfile = temp.create_tempfile('_cyipopt-external-greybox-scaling.log') + solver = pyo.SolverFactory('cyipopt') + solver.config.options = { + 'hessian_approximation': 'limited-memory', + 'nlp_scaling_method': 'user-scaling', + 'output_file': logfile, + 'file_print_level': 10, + 'max_iter': 0, + } + status = solver.solve(m, tee=False) + + with open(logfile, 'r') as fd: + solver_trace = fd.read() self.assertIn('nlp_scaling_method = user-scaling', solver_trace) - self.assertIn( - 'output_file = _cyipopt-external-greybox-scaling.log', solver_trace - ) + self.assertIn(f'output_file = {logfile}', solver_trace) self.assertIn('objective scaling factor = 0.1', solver_trace) self.assertIn('x scaling provided', solver_trace) self.assertIn('c scaling provided', solver_trace) From 3722b42022a6bf7304c2939a0c818bc89a7b2bbc Mon Sep 17 00:00:00 2001 From: Miranda Mundt Date: Mon, 13 Jan 2025 09:24:27 -0700 Subject: [PATCH 09/14] Apply black --- .../contrib/pynumero/examples/tests/test_cyipopt_examples.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pyomo/contrib/pynumero/examples/tests/test_cyipopt_examples.py b/pyomo/contrib/pynumero/examples/tests/test_cyipopt_examples.py index 22f2f4a844b..f735e98b026 100644 --- a/pyomo/contrib/pynumero/examples/tests/test_cyipopt_examples.py +++ b/pyomo/contrib/pynumero/examples/tests/test_cyipopt_examples.py @@ -91,7 +91,9 @@ def test_external_grey_box_react_example_maximize_cb_outputs_scaling(self): ) with TempfileManager.new_context() as temp: - logfile = temp.create_tempfile('_cyipopt-external-greybox-react-scaling.log') + logfile = temp.create_tempfile( + '_cyipopt-external-greybox-react-scaling.log' + ) aoptions = { 'nlp_scaling_method': 'user-scaling', 'output_file': logfile, From dcb610216338f1a0af8469ede58e2b84ef5a6d32 Mon Sep 17 00:00:00 2001 From: John Siirola Date: Tue, 14 Jan 2025 09:41:11 -0700 Subject: [PATCH 10/14] Make sensitivity docs more robust to small solver differences --- .../explanation/analysis/sensitivity_toolbox.rst | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/doc/OnlineDocs/explanation/analysis/sensitivity_toolbox.rst b/doc/OnlineDocs/explanation/analysis/sensitivity_toolbox.rst index 17c0e765541..fbd9b2096b4 100644 --- a/doc/OnlineDocs/explanation/analysis/sensitivity_toolbox.rst +++ b/doc/OnlineDocs/explanation/analysis/sensitivity_toolbox.rst @@ -67,6 +67,16 @@ And finally we call sIPOPT or k_aug: >>> m_sipopt = sensitivity_calculation('sipopt', m, [m.eta1, m.eta2], [m.perturbed_eta1, m.perturbed_eta2], tee=False) >>> m_kaug_dsdp = sensitivity_calculation('k_aug', m, [m.eta1, m.eta2], [m.perturbed_eta1, m.perturbed_eta2], tee=False) +.. testcode:: python + :skipif: not sipopt_available or not k_aug_available or not dot_sens_available + :hide: + + # The x3 result can come back -0.000 depending on the platform or + # solver version; map it so that tests don't fail. + for _m in (m, m_sipopt, m_kaug): + if f'{_m.x3():.3f}' == '-0.000': + _m.x3 = 0. + The first argument specifies the method, either 'sipopt' or 'k_aug'. The second argument is the Pyomo model. The third argument is a list of the original parameters. The fourth argument is a list of the perturbed parameters. It's important that these two lists are the same length and in the same order. First, we can inspect the initial point: @@ -138,7 +148,7 @@ Note that k_aug does not save the solution with the original parameter values. F x2 = 0.667 >>> print("x3 = %0.3f" % x3) - x3 = -0.000 + x3 = 0.000 # *k_aug* # New parameter values: @@ -162,7 +172,7 @@ Note that k_aug does not save the solution with the original parameter values. F x2 = 0.667 >>> print("x3 = %0.3f" % x3) - x3 = -0.000 + x3 = 0.000 Installing sIPOPT and k_aug From 33a3e96faa533b75d1b4ca3bb04238f3cdd2cac7 Mon Sep 17 00:00:00 2001 From: John Siirola Date: Tue, 14 Jan 2025 09:41:49 -0700 Subject: [PATCH 11/14] Avoid setting _default to NOTSET when duplicating ConfigValue objects --- pyomo/common/config.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pyomo/common/config.py b/pyomo/common/config.py index b6ff0ebfee3..ddeac28e521 100644 --- a/pyomo/common/config.py +++ b/pyomo/common/config.py @@ -1840,7 +1840,11 @@ def __call__( assert default is NOTSET else: fields += ('domain',) - kwds['default'] = self.value() if default is NOTSET else default + if default is NOTSET: + default = self.value() + if default is NOTSET: + default = None + kwds['default'] = default assert implicit is NOTSET assert implicit_domain is NOTSET for field in fields: From ff045f86db90f10938c615e23481d113d5cfefde Mon Sep 17 00:00:00 2001 From: John Siirola Date: Tue, 14 Jan 2025 10:42:45 -0700 Subject: [PATCH 12/14] Fix typo --- doc/OnlineDocs/explanation/analysis/sensitivity_toolbox.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/OnlineDocs/explanation/analysis/sensitivity_toolbox.rst b/doc/OnlineDocs/explanation/analysis/sensitivity_toolbox.rst index fbd9b2096b4..8be6db90ead 100644 --- a/doc/OnlineDocs/explanation/analysis/sensitivity_toolbox.rst +++ b/doc/OnlineDocs/explanation/analysis/sensitivity_toolbox.rst @@ -73,7 +73,7 @@ And finally we call sIPOPT or k_aug: # The x3 result can come back -0.000 depending on the platform or # solver version; map it so that tests don't fail. - for _m in (m, m_sipopt, m_kaug): + for _m in (m, m_sipopt, m_kaug_dsdp): if f'{_m.x3():.3f}' == '-0.000': _m.x3 = 0. From 6db771e0386dda7bdb809b8ff4b8f90fdc89b676 Mon Sep 17 00:00:00 2001 From: John Siirola Date: Tue, 14 Jan 2025 11:20:58 -0700 Subject: [PATCH 13/14] Map an additional -0.000 -> 0.000 --- doc/OnlineDocs/explanation/analysis/sensitivity_toolbox.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/OnlineDocs/explanation/analysis/sensitivity_toolbox.rst b/doc/OnlineDocs/explanation/analysis/sensitivity_toolbox.rst index 8be6db90ead..6d3bbea426a 100644 --- a/doc/OnlineDocs/explanation/analysis/sensitivity_toolbox.rst +++ b/doc/OnlineDocs/explanation/analysis/sensitivity_toolbox.rst @@ -76,6 +76,8 @@ And finally we call sIPOPT or k_aug: for _m in (m, m_sipopt, m_kaug_dsdp): if f'{_m.x3():.3f}' == '-0.000': _m.x3 = 0. + if f'{m_sipopt.sens_sol_state_1[m_sipopt.x3]:.3f}' == '-0.000': + m_sipopt.sens_sol_state_1[m_sipopt.x3] = 0. The first argument specifies the method, either 'sipopt' or 'k_aug'. The second argument is the Pyomo model. The third argument is a list of the original parameters. The fourth argument is a list of the perturbed parameters. It's important that these two lists are the same length and in the same order. From 7d673334294d72c7f09a8dc060796147ebaf75d4 Mon Sep 17 00:00:00 2001 From: Miranda Mundt Date: Tue, 14 Jan 2025 12:34:39 -0700 Subject: [PATCH 14/14] Grammar typo --- .github/workflows/test_branches.yml | 4 ++-- .github/workflows/test_pr_and_main.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test_branches.yml b/.github/workflows/test_branches.yml index 09626e781c0..653ef6eba54 100644 --- a/.github/workflows/test_branches.yml +++ b/.github/workflows/test_branches.yml @@ -657,8 +657,8 @@ jobs: - name: Report pyomo plugin information run: | - # MRM / Jan 9, 2025: We update the PATH manually to make sure we capture - # the all of our changes. This is necessary because of an + # MRM / Jan 9, 2025: We update the PATH manually to make sure we + # capture all of our changes. This is necessary because of an # issue with how the PATH rearranges on Windows. # Issue: https://github.com/actions/runner-images/issues/11328 export PATH=$PYOMO_PATH diff --git a/.github/workflows/test_pr_and_main.yml b/.github/workflows/test_pr_and_main.yml index f8d7b8f0892..2506573db4d 100644 --- a/.github/workflows/test_pr_and_main.yml +++ b/.github/workflows/test_pr_and_main.yml @@ -690,8 +690,8 @@ jobs: - name: Report pyomo plugin information run: | - # MRM / Jan 9, 2025: We update the PATH manually to make sure we capture - # the all of our changes. This is necessary because of an + # MRM / Jan 9, 2025: We update the PATH manually to make sure we + # capture all of our changes. This is necessary because of an # issue with how the PATH rearranges on Windows. # Issue: https://github.com/actions/runner-images/issues/11328 export PATH=$PYOMO_PATH