diff --git a/.github/workflows/asv.yml b/.github/workflows/asv.yml deleted file mode 100644 index 4856306bfd..0000000000 --- a/.github/workflows/asv.yml +++ /dev/null @@ -1,95 +0,0 @@ -# Runner information: -# CPU: Intel(R) Core(TM) i7-6700K CPU @ 4.00GHz -# GPU: NVIDIA GeForce RTX 2060 - -name: asv-benchmarks - -env: - OUTPUT_PATH: ${{ github.workspace }} - ENVHOME: "/home/devito/environments" - -on: - workflow_dispatch: - inputs: - tags: - description: 'Run ASV' - # Trigger the workflow on push to the master branch - push: - branches: - - master - -jobs: - - # Run the asv benchmarks on the self-hosted runner - benchmarks: - name: benchmarks - runs-on: [self-hosted, asv] - - env: - DEVITO_ARCH: "gcc-9" - DEVITO_LANGUAGE: "openmp" - DEVITO_BENCHMARKS: "1" - DEVITO_LOGGING: "PERF" - OMP_NUM_THREADS: "8" - CC: "gcc-9" - CXX: "g++-9" - - steps: - - name: Checkout devito - uses: actions/checkout@v2.3.2 - - - name: Set VIRTUAL_ENV - run: | - echo "VIRTUAL_ENV=$ENVHOME/asv" >> $GITHUB_ENV - echo "PATH=$VIRTUAL_ENV/bin:$PATH" >> $GITHUB_ENV - - - name: Set PATH - run: | - echo "PATH=$VIRTUAL_ENV/bin:$PATH" >> $GITHUB_ENV - - - name: Install dependencies - run: | - pip install --upgrade pip - pip install -e . - pip install --upgrade asv - - - name: Setup asv - run: | - asv machine --config benchmarks/regression/asv.conf.json --machine i7-6700K --os ubuntu-20.10 --arch x86-64 --cpu i7-6700K --num_cpu 8 --ram 16GB - - - name: Run benchmarks - run: | - asv run -v --strict --show-stderr --config benchmarks/regression/asv.conf.json --cpu-affinity 0-7 --machine i7-6700K - - - name: Checkout asv-results branch - uses: actions/checkout@v2.3.2 - with: - ref: asv-results - clean: false - - - name: Commit benchmarks results - run: | - git config --local user.email "action@github.com" - git config --local user.name "GitHub Action" - git add -f benchmarks/regression/.asv/results/ - git status - git commit -m "Commit ASV results" - - - name: Push benchmarks results to the asv-results branch - uses: ad-m/github-push-action@master - with: - branch: asv-results - force: true - github_token: ${{ secrets.GITHUB_TOKEN }} - - - name: Create results (html) - run: | - asv publish --config benchmarks/regression/asv.conf.json - - - name: Deploy results to devitocodes/devito-performance/gh-pages - uses: peaceiris/actions-gh-pages@v2.5.0 - env: - ACTIONS_DEPLOY_KEY: ${{ secrets.ACTIONS_DEPLOY_KEY }} - EXTERNAL_REPOSITORY: devitocodes/devito-performance - PUBLISH_BRANCH: gh-pages - PUBLISH_DIR: ./benchmarks/regression/.asv/html diff --git a/.github/workflows/cancel.yml b/.github/workflows/cancel.yml deleted file mode 100644 index 252d4da389..0000000000 --- a/.github/workflows/cancel.yml +++ /dev/null @@ -1,16 +0,0 @@ -name: Cancel - -on: [push] - -jobs: - cancel: - name: 'Cancel Previous Runs' - runs-on: ubuntu-latest - timeout-minutes: 3 - steps: - - uses: styfle/cancel-workflow-action@0.4.0 - with: - # Ids to cancel core/mpi/gpu/examples/tutorials - # https://api.github.com/repos/devitocodes/devito/actions/workflows - workflow_id: 167582, 203470, 203471, 434862, 501517 - access_token: ${{ github.token }} \ No newline at end of file diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml deleted file mode 100644 index 67bf09c285..0000000000 --- a/.github/workflows/docker-publish.yml +++ /dev/null @@ -1,131 +0,0 @@ -name: Publish docker image - -on: - release: - types: [published] - push: - branches: - - master # Push events on master branch - -jobs: - deploy-docker-cpu: - runs-on: ubuntu-latest - - steps: - - name: Checkout devito - uses: actions/checkout@v2 - - - name: Check event name - run: echo ${{ github.event_name }} - - - name: Set up QEMU - uses: docker/setup-qemu-action@v1.0.2 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v1.1.2 - - - name: Login to DockerHub - uses: docker/login-action@v1 - with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_PASSWORD }} - - - name: CPU image - if: github.event_name == 'push' - uses: docker/build-push-action@v2.4.0 - with: - context: . - file: ./docker/Dockerfile - push: true - tags: devitocodes/devito:cpu-dev - - - name: CPU image release - if: github.event_name == 'release' - uses: docker/build-push-action@v2.4.0 - with: - context: . - file: ./docker/Dockerfile - push: true - tags: | - devitocodes/devito:cpu-latest - devitocodes/devito:cpu-${{ github.event.release.tag_name }} - - deploy-docker-gpu: - runs-on: [self-hosted, gpu, docker] - - steps: - - name: Checkout devito - uses: actions/checkout@v2 - - - name: Check event name - run: echo ${{ github.event_name }} - - - name: Set up QEMU - uses: docker/setup-qemu-action@v1.0.2 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v1.1.2 - - - name: Login to DockerHub - uses: docker/login-action@v1 - with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_PASSWORD }} - - - name: GPU image - if: github.event_name == 'push' - uses: docker/build-push-action@v2.4.0 - with: - context: . - file: ./docker/Dockerfile.nvidia - push: true - tags: devitocodes/devito:gpu-dev - - - name: GPU image release - if: github.event_name == 'release' - uses: docker/build-push-action@v2.4.0 - with: - context: . - file: ./docker/Dockerfile.nvidia - push: true - tags: | - devitocodes/devito:gpu-latest - devitocodes/devito:gpu-${{ github.event.release.tag_name }} - - # Comment out 'cpu-latest' until next release - test-cpu-image: - needs: deploy-docker-cpu - runs-on: ubuntu-latest - - strategy: - fail-fast: false - matrix: - #im-name: [cpu-dev, cpu-latest] - im-name: [cpu-dev] - - steps: - - name: Run simple test - run: | - docker pull 'devitocodes/devito:${{ matrix.im-name }}' - docker run --rm --name testrun 'devitocodes/devito:${{ matrix.im-name }}' pytest tests/test_operator.py - - test-gpu-image: - needs: deploy-docker-gpu - runs-on: [self-hosted, gpu, docker] - - strategy: - fail-fast: false - matrix: - #im-name: [gpu-dev, gpu-latest] - im-name: [gpu-dev] - - steps: - - name: Run simple test - run: | - docker pull 'devitocodes/devito:${{ matrix.im-name }}' - docker run --gpus all --rm --name testrun 'devitocodes/devito:${{ matrix.im-name }}' pytest tests/test_gpu_openacc.py - - # NOTE: Suitable for the time being but will need to modify when we switch runners - - name: Clean - run: | - docker system prune -a -f diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml deleted file mode 100644 index cd4055e5bc..0000000000 --- a/.github/workflows/documentation.yml +++ /dev/null @@ -1,34 +0,0 @@ -name: Documentation - -on: - push: - branches: - - master # Push events on master branch - -jobs: - build: - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - with: - python-version: '3.x' - - name: Install Sphinx - run: | - python -m pip install --upgrade pip - pip install sphinx sphinx_rtd_theme - pip install -e . - - - name: Generate documentation - working-directory: docs - run: make html - - - name: Deploy - uses: peaceiris/actions-gh-pages@v2 - env: - PERSONAL_TOKEN: ${{ secrets.PERSONAL_TOKEN }} - PUBLISH_BRANCH: gh-pages - PUBLISH_DIR: ./docs/_build/html diff --git a/.github/workflows/examples-mpi.yml b/.github/workflows/examples-mpi.yml deleted file mode 100644 index fea29345d9..0000000000 --- a/.github/workflows/examples-mpi.yml +++ /dev/null @@ -1,64 +0,0 @@ -# Runner information: -# CPU: Intel(R) Xeon(R) CPU E5-2640 0 @ 2.50GHz (24 cores) - -name: Examples-mpi - -env: - OUTPUT_PATH: ${{ github.workspace }} - ENVHOME: "/home/devito/environments" - -on: - # Trigger the workflow on push or pull request, - # but only for the master branch - push: - branches: - - master - pull_request: - branches: - - master - -jobs: - build: - name: Examples with mpi - runs-on: ["self-hosted", "mpi", "examples"] - - env: - DEVITO_MPI: "1" - DEVITO_LANGUAGE: "openmp" - OMP_NUM_THREADS: "2" - DEVITO_ARCH: "gcc" - CC: "gcc" - CXX: "g++" - - steps: - - name: Checkout devito - uses: actions/checkout@v2.3.2 - - - name: Set environment - run: | - source $ENVHOME/devito-cpu-mpi/bin/activate - echo "PATH=$PATH" >> $GITHUB_ENV - echo "LD_LIBRARY_PATH=$LD_LIBRARY_PATH" >> $GITHUB_ENV - - - name: Install dependencies - run: | - pip install --upgrade pip - pip install -e . - - - name: Test mpi notebooks - run : | - # Currently not tested due to issue #859 - # ipcluster start --profile=mpi -n 4 --daemon - # py.test --nbval examples/mpi - # ipcluster stop --profile=mpi - - - name: Test seismic examples - run: | - mpirun -n 4 pytest examples/seismic/tti/tti_example.py - mpirun -n 4 pytest examples/seismic/elastic/elastic_example.py - mpirun -n 4 pytest examples/seismic/viscoacoustic/viscoacoustic_example.py - mpirun -n 4 pytest examples/seismic/viscoelastic/viscoelastic_example.py - - - name: Test fwi examples with mpi - run: | - mpirun -n 4 python examples/seismic/inversion/fwi.py diff --git a/.github/workflows/examples.yml b/.github/workflows/examples.yml deleted file mode 100644 index cc9e0a24e5..0000000000 --- a/.github/workflows/examples.yml +++ /dev/null @@ -1,89 +0,0 @@ -name: Examples - -on: - # Trigger the workflow on push or pull request, - # but only for the master branch - push: - branches: - - master - pull_request: - branches: - - master - -jobs: - tutorials: - name: Examples with conda install - runs-on: ubuntu-latest - - defaults: - # Default for conda env - run: - shell: bash -l {0} - - env: - DEVITO_ARCH: gcc - DEVITO_LANGUAGE: "openmp" - PYTHON_VERSION: "3.7" - - strategy: - # Prevent all build to stop if a single one fails - fail-fast: false - - steps: - - name: Checkout devito - uses: actions/checkout@v2 - - - name: Setup conda - uses: conda-incubator/setup-miniconda@v2 - with: - activate-environment: devito - environment-file: environment-dev.yml - auto-activate-base: false - - - name: Install dependencies - run: | - pip install -e . - pip install matplotlib - - - name: Tests in examples - run: py.test --cov --cov-config=.coveragerc --cov-report=xml examples/ - - - name: Seismic acoustic examples - run: | - python examples/seismic/acoustic/acoustic_example.py --full - python examples/seismic/acoustic/acoustic_example.py --full --checkpointing - python examples/seismic/acoustic/acoustic_example.py --constant --full - python examples/seismic/acoustic/acoustic_example.py --fs - python examples/seismic/inversion/fwi.py - python examples/seismic/self_adjoint/example_iso.py - python examples/seismic/viscoacoustic/viscoacoustic_example.py - python examples/seismic/viscoacoustic/viscoacoustic_example.py -k ren - python examples/seismic/viscoacoustic/viscoacoustic_example.py -k deng_mcmechan - - - name: Seismic tti examples - run: | - python examples/seismic/tti/tti_example.py -a basic - python examples/seismic/tti/tti_example.py -a basic --noazimuth - python examples/seismic/tti/tti_example.py -k staggered - python examples/seismic/tti/tti_example.py --full -so 12 - - - name: Seismic elastic examples - run: | - python examples/seismic/elastic/elastic_example.py - python examples/seismic/viscoelastic/viscoelastic_example.py - - - name: Linear algebra example - run: | - python examples/misc/linalg.py mat-vec mat-mat mat-mat-sum transpose-mat-vec - python examples/misc/linalg.py mat-vec -o mat-mat -o mat-mat-sum -o transpose-mat-vec -o - - - name: CFD examples - run: | - python examples/cfd/example_diffusion.py - - - name: Upload coverage to Codecov - if: matrix.name != 'pytest-docker-py36-gcc-omp' - uses: codecov/codecov-action@v1.0.6 - with: - token: ${{ secrets.CODECOV_TOKEN }} - name: ${{ matrix.name }} diff --git a/.github/workflows/flake8.yml b/.github/workflows/flake8.yml deleted file mode 100644 index 72e7805a93..0000000000 --- a/.github/workflows/flake8.yml +++ /dev/null @@ -1,30 +0,0 @@ -name: Flake8 - -on: - # Trigger the workflow on push or pull request, - # but only for the master branch - push: - branches: - - master - pull_request: - branches: - - master - -jobs: - flake8: - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v1 - - name: Set up Python 3.7 - uses: actions/setup-python@v1 - with: - python-version: 3.7 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install flake8 - - name: Lint with flake8 - run: | - flake8 --builtins=ArgumentError . diff --git a/.github/workflows/pytest-core-mpi.yml b/.github/workflows/pytest-core-mpi.yml deleted file mode 100644 index 202b9f9d19..0000000000 --- a/.github/workflows/pytest-core-mpi.yml +++ /dev/null @@ -1,43 +0,0 @@ -name: CI-mpi - -on: - # Trigger the workflow on push or pull request, - # but only for the master branch - push: - branches: - - master - pull_request: - branches: - - master - -jobs: - build: - name: pytest-mpi - runs-on: ubuntu-20.04 - - env: - DEVITO_LANGUAGE: "openmp" - DEVITO_ARCH: "gcc-9" - CC: "gcc-9" - CXX: "g++-9" - - steps: - - name: Checkout devito - uses: actions/checkout@v2 - - - name: Install dependencies - run: | - sudo apt-get update && sudo apt install mpich -y - pip3 install --upgrade pip - pip3 install -r requirements-mpi.txt - pip3 install -e .[extras] - - - name: Test with pytest - run: | - python3 -m pytest --cov --cov-config=.coveragerc --cov-report=xml -m parallel tests/ - - - name: Upload coverage to Codecov - uses: codecov/codecov-action@v1.0.15 - with: - token: ${{ secrets.CODECOV_TOKEN }} - name: pytest-mpi diff --git a/.github/workflows/pytest-gpu.yml b/.github/workflows/pytest-gpu.yml deleted file mode 100644 index 0c41ee49d5..0000000000 --- a/.github/workflows/pytest-gpu.yml +++ /dev/null @@ -1,119 +0,0 @@ -# Runner information: -# OpenACC on NVidia runs on `sarlaac` -# OpenMP on NVidia runs on `kimogila` - -name: CI-gpu - -env: - OUTPUT_PATH: ${{ github.workspace }} - RESOURCE_GROUP: CI-gpu - -on: - # Trigger the workflow on push or pull request, - # but only for the master branch - push: - branches: - - master - pull_request: - branches: - - master - # Push-button activation - workflow_dispatch: - inputs: - tags: - description: 'Run GPU tests' - -jobs: - - build: - name: ${{ matrix.name }} - runs-on: ${{ matrix.tags }} - - env: - DEVITO_ARCH: ${{ matrix.arch }} - DEVITO_PLATFORM: ${{ matrix.platform }} - DEVITO_LANGUAGE: ${{ matrix.language }} - OMPI_CC: ${{ matrix.arch }} - - strategy: - # Prevent all builds from terminating if one fails - fail-fast: false - - matrix: - name: [ - # NOTE: We can re-instate this as a 'failing' build - # as soon as the hardware is ready - pytest-gpu-omp, - pytest-gpu-acc - # pytest-gpu-aomp - ] - include: - - name: pytest-gpu-omp - test_file: "tests/test_gpu_openmp.py" - env_file: "devito-ci-nvidia-openmp.env" - test_drive_cmd: "nvidia-smi" - arch: "clang" - platform: "nvidiaX" - language: "openmp" - tags: ["self-hosted", "gpu", "openmp"] - - - name: pytest-gpu-acc - test_file: "tests/test_gpu_openacc.py" - env_file: "devito-ci-nvidia-openacc.env" - test_drive_cmd: "nvidia-smi" - arch: "nvcc" - platform: "nvidiaX" - language: "openacc" - tags: ["self-hosted", "gpu", "openacc"] - - # - name: pytest-gpu-aomp - # test_file: "tests_gpu_aomp.py" - # env_file: "devito-ci-amd-openmp.py" - # test_drive_cmd: "TODO" - # arch: "aomp" - # platform: "amdgpuX" - # language: "openmp" - # tags: ["self-hosted", "gpu", "aomp"] - - steps: - - name: Checkout devito - uses: actions/checkout@v1 - - - name: Set environment - run: | - source $HOME/${{ matrix.env_file }} - echo "PATH=$PATH" >> $GITHUB_ENV - echo "LD_LIBRARY_PATH=$LD_LIBRARY_PATH" >> $GITHUB_ENV - - - name: Install dependencies - run: | - pip3 install --upgrade pip - pip3 install -e .[extras] - - - name: Test with pytest - run: | - ${{ matrix.test_drive_cmd }} - pytest --cov --cov-config=.coveragerc --cov-report=xml tests/test_adjoint.py tests/test_gpu_common.py - pytest --cov --cov-config=.coveragerc --cov-report=xml ${{ matrix.test_file }} - - - name: Test examples - run: | - pytest examples/seismic/acoustic/acoustic_example.py - pytest examples/seismic/elastic/elastic_example.py - pytest examples/seismic/tti/tti_example.py - pytest examples/seismic/viscoacoustic/viscoacoustic_example.py - pytest examples/seismic/viscoelastic/viscoelastic_example.py - - - name: Test examples with MPI - run: | - DEVITO_MPI=1 mpirun -n 2 pytest examples/seismic/acoustic/acoustic_example.py - DEVITO_MPI=1 mpirun -n 2 pytest examples/seismic/elastic/elastic_example.py - DEVITO_MPI=1 mpirun -n 2 pytest examples/seismic/tti/tti_example.py - DEVITO_MPI=1 mpirun -n 2 pytest examples/seismic/viscoacoustic/viscoacoustic_example.py - DEVITO_MPI=1 mpirun -n 2 pytest examples/seismic/viscoelastic/viscoelastic_example.py - - - name: Upload coverage to Codecov - uses: codecov/codecov-action@v1.0.6 - with: - token: ${{ secrets.CODECOV_TOKEN }} - name: ${{ matrix.name }} diff --git a/.github/workflows/pythonpublish.yml b/.github/workflows/pythonpublish.yml deleted file mode 100644 index 6ae0f32795..0000000000 --- a/.github/workflows/pythonpublish.yml +++ /dev/null @@ -1,26 +0,0 @@ -name: Upload to PyPI - -on: - release: - types: [published] - -jobs: - deploy: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - with: - python-version: '3.x' - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install setuptools wheel twine - - name: Build and publish - env: - TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }} - TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} - run: | - python setup.py sdist bdist_wheel - twine upload dist/* diff --git a/.github/workflows/release-notes.yml b/.github/workflows/release-notes.yml deleted file mode 100644 index 2c30bcdb18..0000000000 --- a/.github/workflows/release-notes.yml +++ /dev/null @@ -1,16 +0,0 @@ -name: Release Drafter - -on: - push: - # branches to consider in the event; optional, defaults to all - branches: - - master - -jobs: - update_release_draft: - runs-on: ubuntu-latest - steps: - # Drafts your next Release notes as Pull Requests are merged into "master" - - uses: release-drafter/release-drafter@v5 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/tutorials.yml b/.github/workflows/tutorials.yml deleted file mode 100644 index 721be93ab7..0000000000 --- a/.github/workflows/tutorials.yml +++ /dev/null @@ -1,139 +0,0 @@ -name: Jupyter Notebooks - -on: - # Trigger the workflow on push or pull request, - # but only for the master branch - push: - branches: - - master - pull_request: - branches: - - master - -jobs: - tutorials: - name: ${{ matrix.name }} - runs-on: ${{ matrix.os }} - - env: - DEVITO_ARCH: "${{ matrix.compiler }}" - DEVITO_LANGUAGE: ${{ matrix.language }} - PYTHON_VERSION: "3.7" - - strategy: - # Prevent all build to stop if a single one fails - fail-fast: false - matrix: - name: [ - tutos-ubuntu-gcc-py37, - tutos-osx-gcc-py37, - tutos-osx-clang-py37, - tutos-docker-gcc-py36 - ] - - include: - - name: tutos-ubuntu-gcc-py37 - os: ubuntu-16.04 - compiler: gcc - language: "openmp" - - - name: tutos-osx-gcc-py37 - os: macos-latest - compiler: gcc-9 - language: "openmp" - - - name: tutos-osx-clang-py37 - os: macos-latest - compiler: clang - language: "C" - - - name: tutos-docker-gcc-py36 - os: ubuntu-latest - compiler: gcc - language: "openmp" - - steps: - - name: Checkout devito - uses: actions/checkout@v1 - - - name: Set up Python 3.7 - if: matrix.name != 'tutos-docker-gcc-py36' - uses: actions/setup-python@v1 - with: - python-version: 3.7 - - - name: Install compilers for OSX - if: runner.os == 'macOS' - run: | - if [ "${{ matrix.compiler }}" = "gcc-9" ]; then - brew install gcc@9 - else - sudo xcode-select -s /Applications/Xcode_12.2.app/Contents/Developer - fi - - - name: Build docker image - if: matrix.name == 'tutos-docker-gcc-py36' - run: | - docker build . --file docker/Dockerfile --tag devito_img - - - name: Set run prefix - run: | - if [ "${{ matrix.name }}" == 'tutos-docker-gcc-py36' ]; then - echo "::set-output name=RUN_CMD::docker run --rm --name testrun devito_img" - else - echo "::set-output name=RUN_CMD::" - fi - id: set-run - - - name: Install dependencies - if: matrix.name != 'tutos-docker-gcc-py36' - run: | - python -m pip install --upgrade pip - pip install -e . - pip install matplotlib blosc - - - name: Seismic notebooks - run: | - ${{ steps.set-run.outputs.RUN_CMD }} py.test --nbval --cov . --cov-config=.coveragerc --cov-report=xml:seis_coverage.xml -k 'not dask' examples/seismic/tutorials/ # Horrible, but we're still at a loss - ${{ steps.set-run.outputs.RUN_CMD }} py.test --nbval --cov . --cov-config=.coveragerc --cov-report=xml:acc_coverage.xml examples/seismic/acoustic/accuracy.ipynb - - - name: Dask notebooks - if: runner.os != 'macOS' - run: | - ${{ steps.set-run.outputs.RUN_CMD }} py.test --nbval --cov . --cov-config=.coveragerc --cov-report=xml:seis_coverage.xml examples/seismic/tutorials/*dask*.ipynb - - - name: Self-adjoint notebooks - run: | - ${{ steps.set-run.outputs.RUN_CMD }} py.test --nbval --cov . --cov-config=.coveragerc --cov-report=xml:sa_coverage.xml examples/seismic/self_adjoint/ - - - name: CFD notebooks - run: | - ${{ steps.set-run.outputs.RUN_CMD }} py.test --nbval --cov . --cov-config=.coveragerc --cov-report=xml:cfd_coverage.xml examples/cfd - - - name: User api notebooks - run: | - ${{ steps.set-run.outputs.RUN_CMD }} py.test --nbval --cov . --cov-config=.coveragerc --cov-report=xml:api_coverage.xml examples/userapi - - - name: Compiler notebooks - run: | - ${{ steps.set-run.outputs.RUN_CMD }} py.test --nbval --cov . --cov-config=.coveragerc --cov-report=xml:comp_coverage.xml examples/compiler - - - name: Finance notebooks - run: | - ${{ steps.set-run.outputs.RUN_CMD }} py.test --nbval --cov . --cov-config=.coveragerc --cov-report=xml:comp_coverage.xml examples/finance - - - name: Performance notebooks - run: | - ${{ steps.set-run.outputs.RUN_CMD }} py.test --nbval --cov . --cov-config=.coveragerc --cov-report=xml:comp_coverage.xml examples/performance - - - name: ABC Notebooks - run: | - ${{ steps.set-run.outputs.RUN_CMD }} py.test --nbval --cov . --cov-config=.coveragerc --cov-report=xml:comp_coverage.xml examples/seismic/abc_methods - - - name: Upload coverage to Codecov - if: matrix.name != 'tutos-docker-gcc-py36' - uses: codecov/codecov-action@v1.0.6 - with: - token: ${{ secrets.CODECOV_TOKEN }} - name: ${{ matrix.name }} - file: ./*_coverage.xml diff --git a/devito/operator/operator.py b/devito/operator/operator.py index 3132be38a3..3155464a10 100644 --- a/devito/operator/operator.py +++ b/devito/operator/operator.py @@ -478,7 +478,7 @@ def _prepare_arguments(self, **kwargs): p._arg_check(args, self._dspace[p]) for d in self.dimensions: if d.is_Derived: - d._arg_check(args, self._dspace[p]) + d._arg_check(args, self._dspace[d]) # BUG? # Turn arguments into a format suitable for the generated code # E.g., instead of NumPy arrays for Functions, the generated code expects diff --git a/devito/types/dense.py b/devito/types/dense.py index affa8cebe6..45b0873a53 100644 --- a/devito/types/dense.py +++ b/devito/types/dense.py @@ -860,7 +860,11 @@ def _arg_check(self, args, intervals): warning("Data type %s of runtime value `%s` does not match the " "Function data type %s" % (key.dtype, self.name, self.dtype)) for i, s in zip(self.dimensions, key.shape): - i._arg_check(args, s, intervals[i]) + if i not in intervals and i.is_Sub: + interval = intervals[i.parent] + else: + interval = intervals[i] + i._arg_check(args, s, interval) def _arg_as_ctype(self, args, alias=None): key = alias or self diff --git a/devito/types/dimension.py b/devito/types/dimension.py index 06e6a11869..6bfe78c5ac 100644 --- a/devito/types/dimension.py +++ b/devito/types/dimension.py @@ -11,6 +11,8 @@ from devito.types.args import ArgProvider from devito.types.basic import Symbol, DataSymbol, Scalar +import inspect + __all__ = ['Dimension', 'SpaceDimension', 'TimeDimension', 'DefaultDimension', 'CustomDimension', 'SteppingDimension', 'SubDimension', 'ConditionalDimension', 'dimensions', 'ModuloDimension', 'IncrDimension'] @@ -672,6 +674,20 @@ def _arg_values(self, args, interval, grid, **kwargs): ['symbolic_min', 'symbolic_max', 'thickness', 'local'] _pickle_kwargs = [] + def _arg_check(self, *args): + if len(args) == 2: + # Comes from Operator._prepare_arguments + dargs, interval = args + else: + # Comes from DiscreteFunction._arg_check + dargs, size, interval = args + if not interval.is_Null: + test0 = self._interval.subs(dargs).start + interval.lower < 0 + test1 = self._interval.subs(dargs).end + interval.upper > size + if test0 or test1: + raise ValueError(' OOB access\n') + return + class ConditionalDimension(DerivedDimension): diff --git a/tests/test_derivatives.py b/tests/test_derivatives.py index 08feb3a07e..4963cb9545 100644 --- a/tests/test_derivatives.py +++ b/tests/test_derivatives.py @@ -3,7 +3,7 @@ from sympy import simplify, diff, Float from devito import (Grid, Function, TimeFunction, Eq, Operator, NODE, cos, sin, - ConditionalDimension, left, right, centered, div, grad) + SubDimension, ConditionalDimension, left, right, centered, div, grad) from devito.finite_differences import Derivative, Differentiable from devito.finite_differences.differentiable import EvalDerivative from devito.symbolics import indexify, retrieve_indexed @@ -488,3 +488,98 @@ def test_shifted_grad(self, shift, ndim): x0 = (None if shift is None else d + shift[i] * d.spacing if type(shift) is tuple else d + shift * d.spacing) assert gi == getattr(f, 'd%s' % d.name)(x0=x0).evaluate + + @pytest.mark.parametrize('exprs, error,', [ + ### Dimensions + + # # OOB access avoided by iteration space shrinking + (['Eq(so2.forward, so2.dx.dx.dx)'],None), + (['Eq(so2.forward, (so2+so0).dx2 )'],None), + (['Eq(so2.forward, so2.biharmonic(1/so0) )'],None), + (['Eq(tk0so0[t+1,x,y], tk0so0[t,x-1,y] + tk0so0[t,x+1,y] )'],None), + + ### SubDimensions (Thickness == 0) + + # Indices within the halo + # (['Eq(so0[t+1,xm0,y], so0[t,xm0,y] + so0[t,xm0,y] )'],None), + # (['Eq(so1[t+1,xm0,y], so1[t,xm0-1,y] + so1[t,xm0+1,y] )'],None), + # (['Eq(so2[t+1,xm0,y], so2[t,xm0-2,y] + so2[t,xm0+2,y] )'],None), + + # # OOB indices + # (['Eq(so0[t+1,xm0,y], so0[t,xm0-1,y] + so0[t,xm0+1,y] )'],ValueError), + # (['Eq(so1[t+1,xm0,y], so1[t,xm0-2,y] + so1[t,xm0+2,y] )'],ValueError), + # (['Eq(so2[t+1,xm0,y], so2[t,xm0-3,y] + so2[t,xm0+3,y] )'],ValueError), + + (['Eq(tk0so2.forward, (tk0so2+tk0so0).dx2 )'],ValueError), + (['Eq(tk0so2.forward, tk0so2.dx.dx.dx.dx)'],ValueError), + + ### SubDimensions (Thickness == 1) + + # # Indices within the halo + subdimension offset + # (['Eq(so0[t+1,xm1,y], so0[t,xm1-1,y] + so0[t,xm1+1,y] )'],None), + # (['Eq(so1[t+1,xm1,y], so1[t,xm1-2,y] + so1[t,xm1+2,y] )'],None), + # (['Eq(so2[t+1,xm1,y], so2[t,xm1-3,y] + so2[t,xm1+3,y] )'],None), + + # (['Eq(so0[t+1,xl1,y], so0[t,xl1,y] + so0[t,xl1+99,y] )'],None), + # (['Eq(so1[t+1,xl1,y], so1[t,xl1-1,y] + so1[t,xl1+100,y] )'],None), + # (['Eq(so2[t+1,xl1,y], so2[t,xl1-2,y] + so2[t,xl1+101,y] )'],None), + + # (['Eq(so0[t+1,xr1,y], so0[t,xr1-99,y] + so0[t,xr1,y] )'],None), + # (['Eq(so1[t+1,xr1,y], so1[t,xr1-100,y] + so1[t,xr1+1,y] )'],None), + # (['Eq(so2[t+1,xr1,y], so2[t,xr1-101,y] + so2[t,xr1+2,y] )'],None), + + (['Eq(tk1so2.forward, tk1so2.dx.dx.dx.dx)'],None), + (['Eq(tk1so2.forward, (tk1so2+tk1so0).dx2 )'],None), + + # # OOB indices + # (['Eq(so0[t+1,xm1,y], so0[t,xm1-2,y] + so0[t,xm1+2,y] )'],ValueError), + # (['Eq(so1[t+1,xm1,y], so1[t,xm1-3,y] + so1[t,xm1+3,y] )'],ValueError), + # (['Eq(so2[t+1,xm1,y], so2[t,xm1-4,y] + so2[t,xm1+4,y] )'],ValueError), + + # (['Eq(so0[t+1,xl1,y], so0[t,xl1-1,y] + so0[t,xl1+100,y] )'],ValueError), + # (['Eq(so1[t+1,xl1,y], so1[t,xl1-2,y] + so1[t,xl1+101,y] )'],ValueError), + # (['Eq(so2[t+1,xl1,y], so2[t,xl1-3,y] + so2[t,xl1+102,y] )'],ValueError), + + # (['Eq(so0[t+1,xr1,y], so0[t,xr1-100,y] + so0[t,xr1+1,y] )'],ValueError), + # (['Eq(so1[t+1,xr1,y], so1[t,xr1-101,y] + so1[t,xr1+2,y] )'],ValueError), + # (['Eq(so2[t+1,xr1,y], so2[t,xr1-102,y] + so2[t,xr1+3,y] )'],ValueError), + ]) + def test_oobs(self, exprs, error): + + grid = Grid(tuple([100]*2)) + x , y = grid.dimensions + t = grid.stepping_dim + + xm0 = SubDimension.middle(name='xm0', parent=x, thickness_left=0, thickness_right=0) + xm1 = SubDimension.middle(name='xm1', parent=x, thickness_left=1, thickness_right=1) + + xl0 = SubDimension.left(name='xl0', parent=x, thickness=0) + xl1 = SubDimension.left(name='xl1', parent=x, thickness=1) + + xr0 = SubDimension.right(name='xr0', parent=x, thickness=0) + xr1 = SubDimension.right(name='xr1', parent=x, thickness=1) + + so0 = TimeFunction(name="so0", grid=grid, time_order=1, space_order=0) + so1 = TimeFunction(name="so1", grid=grid, time_order=1, space_order=1) + so2 = TimeFunction(name="so2", grid=grid, time_order=1, space_order=2) + + tk0so0 = TimeFunction(name="tk0so0", grid=grid, time_order=1, space_order=0, dimensions=(t,xm0,y)) + tk0so1 = TimeFunction(name="tk0so1", grid=grid, time_order=1, space_order=1, dimensions=(t,xm0,y)) + tk0so2 = TimeFunction(name="tk0so2", grid=grid, time_order=1, space_order=2, dimensions=(t,xm0,y)) + + tk1so0 = TimeFunction(name="tk1so0", grid=grid, time_order=1, space_order=0, dimensions=(t,xm1,y)) + tk1so1 = TimeFunction(name="tk1so1", grid=grid, time_order=1, space_order=1, dimensions=(t,xm1,y)) + tk1so2 = TimeFunction(name="tk1so2", grid=grid, time_order=1, space_order=2, dimensions=(t,xm1,y)) + + # List comprehension would need explicit locals/globals mappings to eval + for i, e in enumerate(list(exprs)): + exprs[i] = eval(e) + try: + op = Operator(exprs) + op.apply(time_M=6) + except Exception as e: + if error is None or not isinstance(e, error): + assert False, "Not expected: %s %s" % (type(e),e) + else: + if error is not None: + assert False, "Should raise an %s exception" % error