From 74ef086977e2b347148a417aee8a008a2b0d3f32 Mon Sep 17 00:00:00 2001 From: swryan Date: Tue, 15 Apr 2025 12:46:00 -0400 Subject: [PATCH 1/2] mv setup to pyproject.toml; update readme; add test conditionals --- .github/workflows/CADRE_test_workflow.yml | 16 +++++-- CADRE/__init__.py | 1 + CADRE/test/test_mdp.py | 6 ++- README.md | 42 +++++++++++++---- benchmark/benchmark_derivs_full_par.py | 6 +++ benchmark/benchmark_mppt.py | 2 + examples/mppt.py | 8 +++- pyproject.toml | 57 +++++++++++++++++++++++ setup.py | 30 ------------ 9 files changed, 121 insertions(+), 47 deletions(-) create mode 100644 pyproject.toml delete mode 100644 setup.py diff --git a/.github/workflows/CADRE_test_workflow.yml b/.github/workflows/CADRE_test_workflow.yml index 70c4aca..6b9aad2 100644 --- a/.github/workflows/CADRE_test_workflow.yml +++ b/.github/workflows/CADRE_test_workflow.yml @@ -51,11 +51,17 @@ jobs: python -m pip install --upgrade pip - python -m pip install six parameterized - python -m pip install openmdao[test] - python -m pip install . + python -m pip install .[all] - pip install git+https://github.com/OpenMDAO/MBI + - name: Install pyoptsparse + run: | + conda install -c conda-forge pyoptsparse -q -y + if [[ "${{ secrets.SNOPT_LOCATION_77 }}" ]]; then + echo " > Secure copying SNOPT 7.7 over SSH" + mkdir SNOPT + scp -qr ${{ secrets.SNOPT_LOCATION_77 }} SNOPT + build_pyoptsparse -v -s SNOPT/src + fi - name: Install PETSc run: | @@ -116,4 +122,4 @@ jobs: - uses: coverallsapp/github-action@master with: github-token: ${{ secrets.GITHUB_TOKEN }} - parallel-finished: true \ No newline at end of file + parallel-finished: true diff --git a/CADRE/__init__.py b/CADRE/__init__.py index e69de29..b650ceb 100644 --- a/CADRE/__init__.py +++ b/CADRE/__init__.py @@ -0,0 +1 @@ +__version__ = '0.2' diff --git a/CADRE/test/test_mdp.py b/CADRE/test/test_mdp.py index e5bd96f..21bf946 100644 --- a/CADRE/test/test_mdp.py +++ b/CADRE/test/test_mdp.py @@ -17,6 +17,10 @@ from openmdao import __version__ as om_version from openmdao.api import Problem, PETScKrylov from openmdao.utils.mpi import MPI +try: + from openmdao.vectors.petsc_vector import PETScVector +except ImportError: + PETScVector = None from CADRE.CADRE_mdp import CADRE_MDP_Group @@ -24,7 +28,7 @@ # set verbose to True for debugging verbose = False - +@unittest.skipUnless(MPI and PETScVector, "MPI and PETSc are required.") class TestCADRE(unittest.TestCase): N_PROCS = 2 diff --git a/README.md b/README.md index 2b33278..b41803a 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,8 @@ CADRE CubeSat design problem This is an implementation of the CADRE CubeSat problem for OpenMDAO 3.x. -It is no longer in active development. +> [!NOTE] +> CADRE is an interesting optimization problem, but this code should not be used as an example of how to use OpenMDAO. This problem was implemented in the early days of OpenMDAO and has not been in active development for a long time, so it doesn't reflect the proper use of the current OpenMDAO API. Instructions for the latest development version: @@ -14,18 +15,39 @@ Instructions for the latest development version: `cd CADRE` - `pip install -e .` + `pip install -e .[all]` -You will also need MBI: +This will install CADRE with most of the required dependencies for testing, including [MBI][5]. - `pip install git+https://github.com/OpenMDAO/MBI` +Some examples use the [pyOptSparse][6] package with the [SNOPT][7] optimizer. +These will require that you have SNOPT, which you may be able to get [here][8]. +Once you have SNOPT, you can follow the instructions [here][9] or use the [build_pyoptsparse][10] script to install it for use with OpenMDAO. e.g. -And for parallel execution you will need petsc4py: + `pip install git+https://github.com/OpenMDAO/build_pyoptsparse` - `pip install petsc4py` + `build_pyoptsparse -s /path/to/SNOPT/src` -[1]: https://github.com/OpenMDAO/CADRE/actions/workflows/CADRE_test_workflow.yml/badge.svg "Github Actions Badge" -[2]: https://github.com/OpenMDAO/CADRE/actions "Github Actions" +For parallel execution you will also need MPI and [PETSc4py][11]: -[3]: https://coveralls.io/repos/github/OpenMDAO/CADRE/badge.svg?branch=master "Coverage Badge" -[4]: https://coveralls.io/github/OpenMDAO/CADRE?branch=master "CADRE @Coveralls" + `pip install mpi4py petsc4py` +or + `conda install mpi4py petsc4py` + + + +[1]: https://github.com/OpenMDAO/CADRE/actions/workflows/CADRE_test_workflow.yml/badge.svg "Github Actions Badge" +[2]: https://github.com/OpenMDAO/CADRE/actions "Github Actions" + +[3]: https://coveralls.io/repos/github/OpenMDAO/CADRE/badge.svg?branch=master "Coverage Badge" +[4]: https://coveralls.io/github/OpenMDAO/CADRE?branch=master "CADRE @Coveralls" + +[5]: https://github.com/OpenMDAO/MBI "MBI" + +[6]: https://mdolab-pyoptsparse.readthedocs-hosted.com/en/latest/ "pyOptSparse" +[7]: https://ccom.ucsd.edu/~optimizers/solvers/snopt/ "SNOPT" +[8]: https://ccom.ucsd.edu/~optimizers/downloads/request/academic/ "UCSD" +[9]: https://mdolab-pyoptsparse.readthedocs-hosted.com/en/latest/optimizers/SNOPT.html "MDO Lab" +[10]: https://github.com/OpenMDAO/build_pyoptsparse "build_pyoptsparse" + + +[11]: https://petsc.org/release/petsc4py/ "PETSc4py" diff --git a/benchmark/benchmark_derivs_full_par.py b/benchmark/benchmark_derivs_full_par.py index 578cbdf..0bdbb49 100644 --- a/benchmark/benchmark_derivs_full_par.py +++ b/benchmark/benchmark_derivs_full_par.py @@ -12,10 +12,16 @@ from openmdao import __version__ as om_version from openmdao.api import Problem, LinearBlockGS from openmdao.utils.assert_utils import assert_near_equal +from openmdao.utils.mpi import MPI +try: + from openmdao.vectors.petsc_vector import PETScVector +except ImportError: + PETScVector = None from CADRE.CADRE_mdp import CADRE_MDP_Group +@unittest.skipUnless(MPI and PETScVector, "MPI and PETSc are required.") class BenchmarkDerivsParallel(unittest.TestCase): N_PROCS = 6 diff --git a/benchmark/benchmark_mppt.py b/benchmark/benchmark_mppt.py index 0873579..2f452eb 100644 --- a/benchmark/benchmark_mppt.py +++ b/benchmark/benchmark_mppt.py @@ -12,6 +12,7 @@ from openmdao.api import Problem, Group, ParallelGroup, IndepVarComp, pyOptSparseDriver from openmdao.utils.assert_utils import assert_near_equal +from openmdao.utils.testing_utils import require_pyoptsparse from CADRE.power import Power_SolarPower, Power_CellVoltage from CADRE.parameters import BsplineParameters @@ -120,6 +121,7 @@ class BenchmarkMPPT(unittest.TestCase): N_PROCS = 2 + @require_pyoptsparse('SNOPT') def benchmark_mppt(self): model = MPPT_MDP() diff --git a/examples/mppt.py b/examples/mppt.py index 1885184..df01672 100644 --- a/examples/mppt.py +++ b/examples/mppt.py @@ -9,6 +9,12 @@ import numpy as np from openmdao.api import Problem, Group, ParallelGroup, IndepVarComp + +from openmdao.utils.general_utils import set_pyoptsparse_opt +try: + OPT, OPTIMIZER = set_pyoptsparse_opt('SNOPT', fallback=False) +except: + raise RuntimeError("This example requires pyOptSparse with SNOPT.") from openmdao.drivers.pyoptsparse_driver import pyOptSparseDriver from CADRE.power import Power_SolarPower, Power_CellVoltage @@ -120,7 +126,7 @@ def setup(self): # create problem and add optimizer prob = Problem(model) - prob.driver = pyOptSparseDriver(optimizer='SNOPT') + prob.driver = pyOptSparseDriver(optimizer=OPTIMIZER) prob.driver.opt_settings = { 'Major optimality tolerance': 1e-3, 'Major feasibility tolerance': 1.0e-5, diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..2efc2b5 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,57 @@ +[build-system] +requires = ["hatchling", "numpy>=2.0"] +build-backend = "hatchling.build" + +[project] +name = "CADRE" +dynamic = ["version"] +description = "Implementation of the CADRE CubeSat design problem for OpenMDAO 2.x" +readme = "README.md" +license = "Apache-2.0" +authors = [ + { name = "Kenneth T. Moore", email = "kenneth.t.moore-1@nasa.gov" }, +] +maintainers = [ + { name = "Kenneth T. Moore", email = "kenneth.t.moore-1@nasa.gov" }, +] +keywords = [ + "CADRE", + "openmdao", +] +classifiers = [ + "Intended Audience :: Science/Research", + "Topic :: Scientific/Engineering", +] + +dependencies = [ + "numpy<2.0", + "openmdao>=2.3", + "six", +] + +[tool.hatch.metadata] +allow-direct-references = true + +[project.optional-dependencies] +all = [ + "CADRE[MBI,test]", +] +MBI = [ + "MBI@git+https://github.com/OpenMDAO/MBI", +] +test = [ + "parameterized", + "testflo", +] + +[project.urls] +Download = "http://github.com/OpenMDAO/CADRE.git" +Homepage = "http://github.com/OpenMDAO/CADRE.git" + +[tool.hatch.version] +path = "CADRE/__init__.py" + +[tool.hatch.build.targets.sdist] +include = [ + "/CADRE", +] diff --git a/setup.py b/setup.py deleted file mode 100644 index ebb565f..0000000 --- a/setup.py +++ /dev/null @@ -1,30 +0,0 @@ -# -# CADRE setup -# - -from setuptools import setup - -kwargs = { - 'name': 'CADRE', - 'description': 'Implementation of the CADRE CubeSat design problem for OpenMDAO 2.x', - 'license': 'Apache 2.0', - 'author': 'Kenneth T. Moore', - 'author_email': 'kenneth.t.moore-1@nasa.gov', - 'maintainer': 'Kenneth T. Moore', - 'maintainer_email': 'kenneth.t.moore-1@nasa.gov', - 'classifiers': [ - 'Intended Audience :: Science/Research', - 'Topic :: Scientific/Engineering' - ], - 'keywords': ['openmdao', 'CADRE'], - 'url': 'http://github.com/OpenMDAO/CADRE.git', - 'download_url': 'http://github.com/OpenMDAO/CADRE.git', - 'install_requires': ['openmdao>=2.3'], - 'packages': ['CADRE', 'CADRE.test'], - 'package_data': {'CADRE': ['data/*.pkl', 'test/*.pkl']}, - 'include_package_data': True, - 'version': '0.2', - 'zip_safe': False -} - -setup(**kwargs) From 142e705d5a48c38edd5974e6a5177d3c641ef49d Mon Sep 17 00:00:00 2001 From: swryan Date: Tue, 15 Apr 2025 12:50:32 -0400 Subject: [PATCH 2/2] add MPI vars to test workflow --- .github/workflows/CADRE_test_workflow.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/CADRE_test_workflow.yml b/.github/workflows/CADRE_test_workflow.yml index 6b9aad2..2b84d38 100644 --- a/.github/workflows/CADRE_test_workflow.yml +++ b/.github/workflows/CADRE_test_workflow.yml @@ -70,7 +70,9 @@ jobs: echo "=============================================================" echo "Check MPI and PETSc installation" echo "=============================================================" + export PRTE_MCA_rmaps_default_mapping_policy=:oversubscribe export OMPI_MCA_rmaps_base_oversubscribe=1 + export OMPI_MCA_btl=^openib echo "-----------------------" echo "Quick test of mpi4py:" mpirun -n 3 python -c "from mpi4py import MPI; print(f'Rank: {MPI.COMM_WORLD.rank}')" @@ -82,7 +84,9 @@ jobs: print(x.getArray())" echo "-----------------------" + echo "export PRTE_MCA_rmaps_default_mapping_policy=:oversubscribe" >> $GITHUB_ENV echo "OMPI_MCA_rmaps_base_oversubscribe=1" >> $GITHUB_ENV + echo "OMPI_MCA_btl=^openib" >> $GITHUB_ENV echo "Workaround for intermittent failures with OMPI https://github.com/open-mpi/ompi/issues/7393" echo "TMPDIR=/tmp" >> $GITHUB_ENV