Skip to content

Commit

Permalink
updates for NumPy 2.0 testing
Browse files Browse the repository at this point in the history
  • Loading branch information
swryan committed May 20, 2024
1 parent 5eb923f commit 2daf319
Show file tree
Hide file tree
Showing 13 changed files with 181 additions and 93 deletions.
54 changes: 6 additions & 48 deletions .github/scripts/install_latest_deps.sh
Original file line number Diff line number Diff line change
@@ -1,30 +1,11 @@
# this script will populate a conda environment with the latest versions
# (including pre-release versions) of all OpenMDAO dependencies

conda upgrade -c conda-forge --all -y

echo "============================================================="
echo "Upgrade to latest pip"
echo "============================================================="
python -m pip install --upgrade pip

echo "============================================================="
echo "Install latest setuptools"
echo "============================================================="
python -m pip install --upgrade --pre setuptools

echo "============================================================="
echo "Install latest versions of NumPy/SciPy"
echo "============================================================="
python -m pip install --upgrade --pre numpy
python -m pip install --upgrade --pre scipy

# remember versions so we can check them later
NUMPY_VER=`python -c "import numpy; print(numpy.__version__)"`
SCIPY_VER=`python -c "import scipy; print(scipy.__version__)"`
echo "NUMPY_VER=$NUMPY_VER" >> $GITHUB_ENV
echo "SCIPY_VER=$SCIPY_VER" >> $GITHUB_ENV

echo "============================================================="
echo "Install latest versions of 'required' dependencies"
echo "============================================================="
Expand All @@ -46,6 +27,11 @@ echo "Install latest versions of 'doe' dependencies"
echo "============================================================="
python -m pip install --upgrade --pre pyDOE3

echo "============================================================="
echo "Install latest versions of 'jax' dependencies"
echo "============================================================="
python -m pip install --upgrade --pre jax jaxlib

echo "============================================================="
echo "Install latest versions of 'notebooks' dependencies"
echo "============================================================="
Expand All @@ -68,10 +54,7 @@ python -m pip install --upgrade --pre pydocstyle
python -m pip install --upgrade --pre testflo
python -m pip install --upgrade --pre websockets
python -m pip install --upgrade --pre aiounittest
echo "the latest version of playwright (1.38.0) is pinned to"
echo "greenlet 2.0.2 which does not build properly for python 3.12"
echo "https://github.com/microsoft/playwright-python/issues/2096"
python -m pip install --upgrade --pre playwright || echo "Skipping playwright, no GUI testing!"
python -m pip install --upgrade --pre playwright
python -m pip install --upgrade --pre num2words

echo "============================================================="
Expand All @@ -80,31 +63,6 @@ echo "============================================================="
python -m pip install --upgrade --pre pyparsing psutil objgraph pyxdsm
python -m pip install --upgrade --pre jax jaxlib

echo "============================================================="
echo "Install latest PETSc"
echo "============================================================="
conda install mpi4py petsc!=3.21.1 petsc4py -q -y

echo "============================================================="
echo "Check MPI and PETSc installation"
echo "============================================================="
export OMPI_MCA_rmaps_base_oversubscribe=1
export OMPI_MCA_btl=^openib

echo "OMPI_MCA_rmaps_base_oversubscribe=1" >> $GITHUB_ENV
echo "OMPI_MCA_btl=^openib" >> $GITHUB_ENV

echo "-----------------------"
echo "Quick test of mpi4py:"
mpirun -n 3 python -c "from mpi4py import MPI; print(f'Rank: {MPI.COMM_WORLD.rank}')"
echo "-----------------------"
echo "Quick test of petsc4py:"
mpirun -n 3 python -c "import numpy; from mpi4py import MPI; comm = MPI.COMM_WORLD; \
import petsc4py; petsc4py.init(); \
x = petsc4py.PETSc.Vec().createWithArray(numpy.ones(5)*comm.rank, comm=comm); \
print(x.getArray())"
echo "-----------------------"

echo "============================================================="
echo "Display conda environment"
echo "============================================================="
Expand Down
101 changes: 90 additions & 11 deletions .github/workflows/openmdao_latest_workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ on:
type: choice
options:
- ''
- 'Ubuntu Latest'
- 'MacOS Latest'
- 'Ubuntu Latest, NumPy<2'
- 'Ubuntu Latest, NumPy 2 (No PETSc/pyOptSparse)'
- 'MacOS Latest, NumPy<2'
- 'MacOS Latest, NumPy 2 (No PETSc/pyOptSparse)'
required: false
default: ''
debug_enabled:
Expand All @@ -46,20 +48,36 @@ jobs:
matrix:
include:
# test latest versions on ubuntu
- NAME: Ubuntu Latest
# Include PETSc/pyOptSparse, which require NumPy<2
- NAME: Ubuntu Latest, NumPy<2
OS: ubuntu-latest
PY: 3
PETSc: 3
SNOPT: 7.7
NUMPY: '<2'
PETSc: True
PYOPTSPARSE: true
SNOPT: true
BUILD_DOCS: true

# test latest versions on ubuntu
# Exclude PETSc/pyOptSparse, which require NumPy<2
- NAME: Ubuntu Latest, NumPy 2 (No PETSc/pyOptSparse)
OS: ubuntu-latest
PY: 3

# test latest versions on macos
# Include PETSc/pyOptSparse, which require NumPy<2
- NAME: MacOS Latest, NumPy<2
OS: macos-13
PY: 3
NUMPY: '<2'
PETSc: True
PYOPTSPARSE: true

# test latest versions on macos
- NAME: MacOS Latest
# Exclude PETSc/pyOptSparse, which require NumPy<2
- NAME: MacOS Latest, NumPy 2 (No PETSc/pyOptSparse)
OS: macos-13
PY: 3
PETSc: 3
SNOPT: 7.7
BUILD_DOCS: false

runs-on: ${{ matrix.OS }}

Expand Down Expand Up @@ -113,11 +131,57 @@ jobs:
run: |
conda install compilers swig
- name: Install NumPy/SciPy
run: |
echo "============================================================="
echo "Install latest versions of NumPy/SciPy"
echo "============================================================="
python -m pip install --upgrade --pre "numpy${{ matrix.NUMPY }}"
python -m pip install --upgrade --pre scipy
# remember versions so we can check them later
NUMPY_VER=`python -c "import numpy; print(numpy.__version__)"`
SCIPY_VER=`python -c "import scipy; print(scipy.__version__)"`
echo "NUMPY_VER=$NUMPY_VER" >> $GITHUB_ENV
echo "SCIPY_VER=$SCIPY_VER" >> $GITHUB_ENV
- name: Install PETSc
if: ${{ matrix.PETSC }}
run: |
echo "============================================================="
echo "Install latest PETSc"
echo "============================================================="
conda install mpi4py petsc!=3.21.1 petsc4py -q -y
echo "============================================================="
echo "Check MPI and PETSc installation"
echo "============================================================="
export OMPI_MCA_rmaps_base_oversubscribe=1
export OMPI_MCA_btl=^openib
echo "OMPI_MCA_rmaps_base_oversubscribe=1" >> $GITHUB_ENV
echo "OMPI_MCA_btl=^openib" >> $GITHUB_ENV
echo "-----------------------"
echo "Quick test of mpi4py:"
mpirun -n 3 python -c "from mpi4py import MPI; print(f'Rank: {MPI.COMM_WORLD.rank}')"
echo "-----------------------"
echo "Quick test of petsc4py:"
mpirun -n 3 python -c "import numpy; from mpi4py import MPI; comm = MPI.COMM_WORLD; \
import petsc4py; petsc4py.init(); \
x = petsc4py.PETSc.Vec().createWithArray(numpy.ones(5)*comm.rank, comm=comm); \
print(x.getArray())"
echo "-----------------------"
- name: Install latest versions of [all] openmdao dependencies
run: |
source .github/scripts/install_latest_deps.sh
echo "Install latest dev version of testflo for deprecations fix"
pip install git+https://github.com/OpenMDAO/testflo
- name: Install pyOptSparse
if: ${{ matrix.PYOPTSPARSE }}
run: |
echo "============================================================="
echo "Define useful functions"
Expand All @@ -138,13 +202,15 @@ jobs:
echo "============================================================="
python -m pip install git+https://github.com/OpenMDAO/build_pyoptsparse
BRANCH="-b $(latest_version https://github.com/mdolab/pyoptsparse)"
if [[ "${{ secrets.SNOPT_LOCATION_77 }}" ]]; then
if [[ "${{ matrix.SNOPT }}" ]]; then
if [[ "${{ secrets.SNOPT_LOCATION_77 }}" ]]; then
echo " > Secure copying SNOPT 7.7 over SSH"
mkdir SNOPT
scp -qr ${{ secrets.SNOPT_LOCATION_77 }} SNOPT
SNOPT="-s SNOPT/src"
else
else
echo "SNOPT source is not available"
fi
fi
build_pyoptsparse $BRANCH $SNOPT
Expand All @@ -153,8 +219,21 @@ jobs:
echo "============================================================="
echo "Install OpenMDAO"
echo "============================================================="
if [[ "${{ matrix.NUMPY }}" == "" ]]; then
sed -i.bak 's/numpy<2/numpy/g' pyproject.toml
grep numpy pyproject.toml
fi
python -m pip install .
- name: Check NumPy 2.0 Compatibility
run: |
echo "============================================================="
echo "Check OpenMDAO code for NumPy 2.0 compatibility"
echo "See: https://numpy.org/devdocs/numpy_2_0_migration_guide.html"
echo "============================================================="
python -m pip install ruff
ruff check . --select NPY201
- name: Display environment info
id: env_info
if: always()
Expand Down
18 changes: 14 additions & 4 deletions .github/workflows/openmdao_test_workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -203,10 +203,6 @@ jobs:
- name: Checkout code
uses: actions/checkout@v3

- name: Fetch tags
run: |
git fetch --prune --unshallow --tags
- name: Setup conda
uses: conda-incubator/setup-miniconda@v3
with:
Expand Down Expand Up @@ -234,6 +230,15 @@ jobs:
python -m pip install .${{ matrix.OPTIONAL }}
fi
- name: Check NumPy 2.0 Compatibility
run: |
echo "============================================================="
echo "Check OpenMDAO code for NumPy 2.0 compatibility"
echo "See: https://numpy.org/devdocs/numpy_2_0_migration_guide.html"
echo "============================================================="
python -m pip install ruff
ruff check . --select NPY201
- name: Install MacOS-specific dependencies
if: matrix.OS == 'macos-13'
run: |
Expand Down Expand Up @@ -486,6 +491,11 @@ jobs:
echo "============================================================="
conda install -c conda-forge 'openssl=3.0'
echo "============================================================="
echo "Fetch tags to get docs version"
echo "============================================================="
git fetch --prune --unshallow --tags
echo "============================================================="
echo "Publish docs"
echo "============================================================="
Expand Down
2 changes: 1 addition & 1 deletion openmdao/components/interp_util/interp.py
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ def _interpolate(self, xi):
for i, p in enumerate(xi.T):
if np.isnan(p).any():
raise OutOfBoundsError("One of the requested xi contains a NaN",
i, np.NaN, self.grid[i][0], self.grid[i][-1])
i, np.nan, self.grid[i][0], self.grid[i][-1])

eps = 1e-14 * self.grid[i][-1]
if np.any(p < self.grid[i][0] - eps) or np.any(p > self.grid[i][-1] + eps):
Expand Down
2 changes: 1 addition & 1 deletion openmdao/components/interp_util/interp_semi.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ def _interpolate(self, xi):
for i, p in enumerate(xi.T):
if np.isnan(p).any():
raise OutOfBoundsError("One of the requested xi contains a NaN",
i, np.NaN, self.grid[i][0], self.grid[i][-1])
i, np.nan, self.grid[i][0], self.grid[i][-1])

if self._compute_d_dvalues:
# If the table grid or values are component inputs, then we need to create a new table
Expand Down
8 changes: 7 additions & 1 deletion openmdao/components/tests/test_balance_comp.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@
from openmdao.utils.assert_utils import assert_no_warning, assert_check_partials
from openmdao.utils.testing_utils import use_tempdirs, force_check_partials

try:
# The exceptions module is new in NumPy 1.25. Older exceptions remain available
# through the main NumPy namespace for compatibility. (Until NumPy 2.0 release)
from numpy.exceptions import ComplexWarning
except ModuleNotFoundError:
from numpy import ComplexWarning

@use_tempdirs
class TestBalanceComp(unittest.TestCase):
Expand Down Expand Up @@ -408,7 +414,7 @@ def test_complex_step(self):
prob.run_model()

with warnings.catch_warnings():
warnings.filterwarnings(action="error", category=np.ComplexWarning)
warnings.filterwarnings(action="error", category=ComplexWarning)
cpd = force_check_partials(prob, out_stream=None, method='cs')

assert_check_partials(cpd, atol=1e-10, rtol=1e-10)
Expand Down
9 changes: 8 additions & 1 deletion openmdao/components/tests/test_eq_constraint_comp.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@
from openmdao.utils.assert_utils import assert_near_equal, assert_check_partials
from openmdao.utils.testing_utils import force_check_partials

try:
# The exceptions module is new in NumPy 1.25. Older exceptions remain available
# through the main NumPy namespace for compatibility. (Until NumPy 2.0 release)
from numpy.exceptions import ComplexWarning
except ModuleNotFoundError:
from numpy import ComplexWarning


class TestEQConstraintComp(unittest.TestCase):

Expand Down Expand Up @@ -352,7 +359,7 @@ def test_complex_step(self):
prob.run_driver()

with warnings.catch_warnings():
warnings.filterwarnings(action="error", category=np.ComplexWarning)
warnings.filterwarnings(action="error", category=ComplexWarning)
cpd = force_check_partials(prob, out_stream=None, method='cs')

assert_check_partials(cpd, atol=1e-10, rtol=1e-10)
Expand Down
12 changes: 10 additions & 2 deletions openmdao/core/component.py
Original file line number Diff line number Diff line change
Expand Up @@ -1119,8 +1119,16 @@ def declare_partials(self, of, wrt, dependent=True, rows=None, cols=None, val=No
f'will raise an error.')

if rows is not None:
rows = np.array(rows, dtype=INT_DTYPE, copy=False)
cols = np.array(cols, dtype=INT_DTYPE, copy=False)
# If using `np.array(obj, copy=False)` replace it with `np.asarray(obj)`
# to allow a copy when needed (no behavior change in NumPy 1.x).
# For more details, see https://numpy.org/devdocs/numpy_2_0_migration_guide.html
# #adapting-to-changes-in-the-copy-keyword.
if np.__version__[0] == '2':
rows = np.asarray(rows, dtype=INT_DTYPE)
cols = np.asarray(cols, dtype=INT_DTYPE)
else:
rows = np.array(rows, dtype=INT_DTYPE, copy=False)
cols = np.array(cols, dtype=INT_DTYPE, copy=False)

# Check the length of rows and cols to catch this easy mistake and give a
# clear message.
Expand Down
5 changes: 3 additions & 2 deletions openmdao/core/tests/test_coloring.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
from openmdao.utils.mpi import MPI, multi_proc_exception_check
from openmdao.utils.testing_utils import use_tempdirs, set_env_vars
from openmdao.test_suite.tot_jac_builder import TotJacBuilder
from openmdao.utils.general_utils import run_driver
from openmdao.utils.general_utils import run_driver, printoptions

import openmdao.test_suite

Expand Down Expand Up @@ -1328,7 +1328,8 @@ def test_multi_variable_coloring_debug_print_totals(self):

p.setup(check=False)

failed, output = run_driver(p)
with printoptions(legacy='1.21'):
failed, output = run_driver(p)

self.assertFalse(failed, "Optimization failed.")

Expand Down
2 changes: 1 addition & 1 deletion openmdao/core/tests/test_impl_comp.py
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,7 @@ def guess_nonlinear(self, inputs, outputs, resids):
prob['pc.c'] = 3.

# Making sure that guess_nonlinear is called early enough to eradicate this.
prob['comp2.x'] = np.NaN
prob['comp2.x'] = np.nan

prob.run_model()
assert_near_equal(prob['comp2.x'], 3.)
Expand Down
Loading

0 comments on commit 2daf319

Please sign in to comment.