diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml index 5f6dfe7e..b33b4ae2 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/testing.yml @@ -15,20 +15,53 @@ env: CLAW: ${{ github.workspace }} jobs: - build: - runs-on: ubuntu-latest + tests: + name: > + ${{ matrix.os }} - py ${{ matrix.python-version }} - ${{ matrix.toolchain.compiler }} ${{ matrix.build }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false # Probably want to turn this off for a large matrix + matrix: + os: [ubuntu-latest, macos-latest] + python-version: ["3.12"] + build: [debug, opt] + toolchain: + - {compiler: gcc, version: 14} + - {compiler: gcc, version: 15} + # - {compiler: intel, version: '2025.0'} + # - {compiler: intel-classic, version: '2021.10'} + # - {compiler: nvidia-hpc, version: '25.1'} # does not build python + # - {compiler: lfortran, version: '0.45.0'} # lfortran not yet supported + # - {compiler: flang, version: '20.1.0'} # flang not yet supported + # include: + # - os: ubuntu-latest + # python-version: 3.10 + # build: opt + # toolchain: {compiler: gcc, version: 14} + exclude: + - os: ubuntu-latest + toolchain: {compiler: gcc, version: 15} + - os: macos-latest + toolchain: {compiler: gcc, version: 14} + steps: - - name: Set up Python 3.10 + - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v5 with: - python-version: "3.10" - - name: Install dependencies - run: | - sudo apt-get update - sudo apt-get install gfortran + python-version: ${{ matrix.python-version }} + + - name: Set up compilers + uses: fortran-lang/setup-fortran@v1 + id: setup-fortran + with: + compiler: ${{ matrix.toolchain.compiler }} + version: ${{ matrix.toolchain.version }} + - name: Install python dependencies + run: | python -m pip install --upgrade pip - pip install 'numpy<2.0' + # pip install 'numpy<2.0' + pip install numpy pip install matplotlib #Some imports require matplotlib pip install scipy #To not skip tests pip install flake8 meson-python ninja pytest coveralls @@ -44,21 +77,77 @@ jobs: uses: actions/checkout@v4.1.5 with: path: pyclaw - + - name: Install clawpack run: | - cd ${CLAW} + if [ "${{ matrix.toolchain.compiler }}" = "gcc" ]; then + if [ "${{ matrix.build }}" = "debug" ]; then + export FFLAGS="-O0 -g -fcheck=all -fbacktrace -fbounds-check -ffpe-trap=invalid,zero,overflow -finit-real=nan -finit-integer=nan -Wall -Wunderflow -Wextra -Wconversion -Wuninitialized -Warray-bounds -Wshadow -Wno-unused-function -Wno-unused-variable -Wno-unused-parameter -Wno-unused-label -Wno-unused-but-set-variable" + export CFLAGS="" + elif [ "${{ matrix.build }}" = "opt" ]; then + # export FFLAGS="-O1 -funroll-loops -finline-functions -ftree-vectorize -fstack-protector-strong -flto -march=native" + export FFLAGS="" + export CFLAGS="" + else + echo "Unknown build type: ${{ matrix.build }}" + exit 1 + fi + elif [ "${{ matrix.toolchain.compiler }}" = "intel" ] || [ "${{ matrix.toolchain.compiler }}" = "intel-classic" ]; then + if [ "${{ matrix.build }}" = "debug" ]; then + export FFLAGS="" + export CFLAGS="" + elif [ "${{ matrix.build }}" = "opt" ]; then + export FFLAGS="" + export CFLAGS="" + else + echo "Unknown build type: ${{ matrix.build }}" + exit 1 + fi + else + echo "Unknown compiler: ${{ matrix.toolchain.compiler }}" + exit 1 + fi + echo "Using `$FC --version`" + echo "FFLAGS: $FFLAGS" + echo "CFLAGS: $CFLAGS" + cd ${{ env.CLAW }} pip install --no-build-isolation --editable . + - name: Lint with flake8 + if: ${{ matrix.build == 'debug' }} + run: | + cd ${{ env.CLAW }}/pyclaw + # stop the build if there are Python syntax errors or undefined names + flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics --exclude "development","src/pyclaw/fileio/netcdf.py" + # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide + flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics + - name: Test with pytest run: | - cd ${CLAW}/pyclaw - coverage run --source=src -m pytest --ignore=development -k "not test_shallow_sphere" + cd ${{ env.CLAW }}/pyclaw + coverage run --source=src -m pytest -vv -s --showlocals --ignore=development -k "not test_shallow_sphere" --junitxml=test-report.xml - - name: Upload to Coveralls + - name: Process test results + uses: test-summary/action@v2.4 + if: always() + with: + paths: ${{ env.CLAW }}/pyclaw/test-report.xml + output: ${{ env.CLAW }}/pyclaw/test-summary.md + show: "all" + + - name: Upload test results + # if: failure() if: always() + uses: actions/upload-artifact@v4 + with: + name: ${{ matrix.os }}-py${{ matrix.python-version }}-${{ matrix.toolchain.compiler }}-${{ matrix.build }} + path: ${{ env.CLAW }}/pyclaw/test-summary.md + if-no-files-found: ignore + + - name: Upload to Coveralls + if: ${{ matrix.os == 'ubuntu-latest' && matrix.toolchain.compiler == 'gcc' && matrix.build == 'opt' && matrix.python-version == '3.12' }} run: | - cd ${CLAW}/pyclaw + cd ${{ env.CLAW }}/pyclaw ls -l .coverage coveralls env: diff --git a/cleanup_examples.py b/cleanup_examples.py index 483a592f..d9627d89 100755 --- a/cleanup_examples.py +++ b/cleanup_examples.py @@ -4,16 +4,17 @@ Cleans up by deleting object files, executable, and _output directory. """ -import os,sys,glob +import os +import sys import shutil if __name__ == "__main__": examples_dir = os.path.abspath('./examples') - print "Will remove all _output, _plots, and build directories from ",examples_dir - ans = raw_input("Ok? ") + print(f"Will remove all _output, _plots, and build directories from {examples_dir}") + ans = input("Ok? ") if ans.lower() not in ['y','yes']: - print "Aborting." + print("Aborting.") sys.exit() os.chdir(examples_dir) @@ -21,15 +22,14 @@ for (dirpath, subdirs, files) in os.walk('.'): currentdir = os.path.abspath(os.getcwd()) os.chdir(os.path.abspath(dirpath)) - - print 'In directory ',dirpath - + + print(f'In directory {dirpath}') + if os.path.isdir('_output'): shutil.rmtree('./_output') if os.path.isdir('_plots'): shutil.rmtree('./_plots') if os.path.isdir('build'): shutil.rmtree('./build') - - os.chdir(currentdir) + os.chdir(currentdir) diff --git a/examples/compare_solvers.py b/examples/compare_solvers.py index de0902b1..1d40d761 100755 --- a/examples/compare_solvers.py +++ b/examples/compare_solvers.py @@ -160,12 +160,12 @@ def compare_2D(nx=(250,250)): import sys vis = True - + if vis: compare_solvers.outdir='./_output' else: compare_solvers.outdir = None - + if len(sys.argv) > 1: nx_1D = int(sys.argv[1]) else: @@ -173,7 +173,7 @@ def compare_2D(nx=(250,250)): if len(sys.argv) > 2: # '(2,2)' -> (2,2) - nx_2D = tuple(int(i) for i in argv.split(',')) + nx_2D = tuple(int(i) for i in sys.argv.split(',')) else: nx_2D = 100,100 diff --git a/fvmbook/chap22/inclusion/inclusion.py b/fvmbook/chap22/inclusion/inclusion.py index bb3489be..0777bd1b 100644 --- a/fvmbook/chap22/inclusion/inclusion.py +++ b/fvmbook/chap22/inclusion/inclusion.py @@ -4,7 +4,7 @@ Variable-coefficient elasticity example. """ import numpy as np -from six.moves import range + t0wall = 0.025 tperiod = 0.05 @@ -13,7 +13,7 @@ def moving_wall_bc(state,dim,t,qbc,auxbc,num_ghost): if t