DevitoPRO

Compatibility notes

DevitoPRO requires Devito main.

DevitoPRO sets up Devito as a submodule locked onto the latest main commit which is compatible with DevitoPRO (i.e. passes all DevitoPRO tests). The branch of the submodule can be manually changed as desired, although it should be noted that this is discouraged. There is CI workflow which automatically updates the submodule every time a PR is merged into Devito, if the new update passes all the DevitoPRO tests. If necessary, the status of the submodule can also be updated by hand (typically for changes spanning both Devito and DevitoPRO).

Note: DevitoPRO now checks the commit tag of the installed Devito at both installation and runtime.

  • At installation, DevitoPRO will force re-install Devito if the tag is not the compatible one.
  • At runtime, DevitoPRO will raise an error if the tag is not the compatible one.

You can disable the runtime error by setting DEVITO_BYPASS_VERSION_CHECK=1 in your environment. This will only raise a warning instead of an error. This is useful for development purposes but not recommended for production.

Install from Docker

Virtually identical to Devito. The only difference is that the main Dockerfile here is called Dockerfile.devitopro (instead of Dockerfile.devito).

Install with pip

First install

Installing devitopro as a Python package is also supported. This setup is designed to handle all dependencies for the user, including installing devito at the required version. To install devitopro:

  • First, clone your mirror repository:
git clone --recurse-submodules --depth 1 your-devitopro-mirror

This will clone the repository and all the necessary submodules, currently devito and CvxCompress (CPU compression).

  • Then, install devitopro:
./install-devitopro.sh

DevitoPRO can be installed in editable mode with the ./install-devitopro.sh -e commmand.

Additionally MPI installation can be skipped with the --no-mpi option. This is useful if DevitoPRO is to be installed on a machine without MPI support or in a virtual environment.

./install-devitopro.sh --no-mpi

Finally, if a Python installation other than the default system python3 is to be used, the --python option can be supplied with the path to the desired Python executable. This is useful when installing DevitoPRO in a virtual environment or using different Python versions.

./install-devitopro.sh --python /path/to/python

Note: DevitoPRO is installed in a minimal configuration by default, skipping some dependencies to reduce the install size for production. Additional dependencies only used for testing, plotting, and demos are installed with the ./install-devitopro.sh --extras option.

Updating DevitoPRO

We are continuously improving DevitoPRO and updating the submodule to keep it synchronised with the latest Devito version. To update DevitoPRO, simply pull the latest changes from the repository and reinstall DevitoPRO by calling the install-devitopro.sh script with the same options as the original installation:

./install-devitopro.sh

It is extremely important that you include the git submodule update --init --recursive so that devito is updated to the latest version as well. The pip install path/to/devitopro command will then automatically reinstall devito at the correct version if the required version has changed.

Note: By default, install-devitopro.sh automatically calls git submodule update --init --recursive at pip install. However we recommend doing it on the user side to avoid issues with for example git credentials.

Getting started

  • For learning how to use Devito, a range of tutorials and examples can be found here. We recommend beginning with the README, before progressing to the userapi notebooks which detail aspects of the DSL and, subsequently, the seismic/tutorials notebooks.
  • Tutorials for DevitoPRO-specific features are available at /demos/tutorials in your DevitoPRO repository.
  • API reference
  • Devito FAQs
  • DevitoPRO FAQs: devitopro/FAQ.md

Recipes

Curated solvers for DevitoPRO

Various physics examples available in this repository include:

  • Isotropic Acoustic: Standard acoustic wave propagation. Supports SLS viscosity as well.
  • Isotropic Elastic: Elastic wave propagation using isotropic models.
  • Anisotropic Acoustic: Various variations of the acoustic TTI equation (Fletcher Du Fowler, Zhang, Bube’s self-adjoint)
  • Anisotropic Elastic: Elastic wave propagation using anisotropic models such as TTI (Tilted Transverse Isotropy) and VTI (Vertical Transverse Isotropy).

Usage

To run the examples, navigate to the examples directory and execute the scripts or notebooks as needed. Ensure all dependencies are installed.

CLI

To run the solvers from the command line, use the following command:

python devitopro/recipes/run.py -physics <physics_name> -so <space_order> -d nx ny nz -nt <time_steps> ...

You can get all the available options by running:

python devitopro/recipes/run.py -h

When running on accelerators (GPUs) and/or with the DevitoPRO decoupler (DEVITO_DECOUPLER=1), all model initializations (e.g., vp, vs, etc.) are performed serially on the host to avoid unnecessary data transfers and communication overhead. A utility function, host_config, is available and can be imported with from recipes.utils import host_config for use in external codebases. Note that this function will be moved directly into DevitoPRO in the future.

Additional examples

Elastic Accuracy

This example demonstrates the accuracy of elastic solvers.

  • Script: elastic-accuracy.py
  • Description: The script compares different elastic solvers, including isotropic and anisotropic models, and visualizes their results.
  • Sections:
    • Elas vs Acou: Comparison between elastic and acoustic solvers.
    • AnisoElas vs Elas: Comparison between anisotropic elastic and isotropic elastic solvers.
    • VTI vs TTI: Comparison between vertical transverse isotropy (VTI) and tilted transverse isotropy (TTI) solvers.
    • SSG vs RSG: Stability comparison with respect to theta and vs parameters.

Immersed Boundary for Acoustic Solvers

This notebook demonstrates the use of immersed boundary support for implementing a topographic free surface.

  • Notebook: immersed_boundary.ipynb
  • Description: It showcases how to read the Signed Distance Function (SDF) and implement immersed boundary conditions using the Schism library.
  • Sections:
    • Read the SDF: Explanation of the boundary geometry and material properties continuation through the surface.

Installation

The recipes should not be installed by themselves but should be automatically installed as part of the devitopro installation.

Customizing the imaging condition

The recipes/solver.py module defines the solvers base class and the public interface. All the recipes are subclasses of this class and, regardless of whether you have access to the open or the obfuscated version of the repository, you can always subclass the solver class and define your own imaging condition.

The tests/test_gradient.py::TestCustomization::test_dummy test shows how to subclass the solver class and define a dummy imaging condition. Below, we show a slightly modified fragment of said test:


class AcousticIsotropicDummy(AcousticIsotropic):

    def sensitivity(self, params='m'):
        """
        Define a custom imaging condition for our solver.
        """
        # `m`, `vp`, ...
        params = as_tuple(params)
        assert len(params) == 1
        param = params[0]

        u = self.saved_state['u_save']
        v = self.state['u']

        b, damp = self.model.b, self.model.damp  # noqa

        dm = self.perturbation(param=param)

        eqns = [Eq(dm, u.dx*v.dx)]

        return eqns

In short, to customize the imaging condition, you need to:

  • Subclass a solver class (full list available in recipes/__init__.py).
  • Override the sensitivity method to define your imaging condition.
    • Inside this method you can access the wavefield at the current time step (via self.state) as well as the wavefield snapshots saved during the forward run (via self.saved_state). You may also access the overarching model object (via self.model) as well as the inverted objects (via the params variable).
    • Write the Eq’s defining the imaging condition. For this part, you need to be familiar with the Devito API.
    • Return the list of Eq’s defining the imaging condition.

That’s about it. The only remaining step is to ensure that your custom solver is accessible by the runtime. You can do it either programmatically (as in the test above) or by adding your new class to the recipes_registry dictionary in recipes/__init__.py. If you choose the latter, you can then run your custom solver directly from the CLI, e.g.:

python devitopro/recipes/run.py -physics iso-acoustic-dummy ...

Where iso-acoustic-dummy is the name of your custom solver that you used as a key in the recipes_registry dictionary.

While here we only showed how to customize the imaging condition, you can customize any part of the solver by subclassing the solver class and overriding the relevant methods. The base solver class was designed to be easily extensible and customizable.

Back to top