SkillAgentSearch skills...

JUDI.jl

Julia Devito inversion.

Install / Use

/learn @slimgroup/JUDI.jl

README

The Julia Devito Inversion framework (JUDI)

| Documentation | Build Status | | |:--------------------------------------:|:-----------------------------------------------:|:----------------------------------------------------:| | [![][docs-stable-img]][docs-stable-status] [![][docs-dev-img]][docs-dev-status] | [![][build-img]][build-status] [![][codecov-img]][codecov-status] [![][aqua-img]][aqua-status] | [![][license-img]][license-status] [![][zenodo-img]][zenodo-status] [![][docker-img]][docker-url]|

Overview

[JUDI] is a framework for large-scale seismic modeling and inversion and is designed to enable rapid translations of algorithms to fast and efficient code that scales to industry-size 3D problems. The focus of the package lies on seismic modeling as well as PDE-constrained optimization such as full-waveform inversion (FWI) and imaging (LS-RTM). Wave equations in [JUDI] are solved with [Devito], a Python domain-specific language for automated finite-difference (FD) computations. JUDI's modeling operators can also be used as layers in (convolutional) neural networks to implement physics-augmented deep learning algorithms thanks to its implementation of ChainRules's rrule for the linear operators representing the discre wave equation.

Interact and contribute

We gladly welcome and encourage contributions from the community to improve our software and its usability. Feel free to:

  • Open issues for bugs
  • Start discussions to interact with the developer and ask any questions
  • Open PR for bug fixes and improvements

FAQ

You can find an FAQ with answers to issues at FAQ

Installation and prerequisites

You can find installation instructions in our Wiki at Installation

GPU

[JUDI] supports the computation of the wave equation on GPU via Devito's GPU offloading support.

NOTE: Only the wave equation part will be computed on GPU, the Julia arrays will still be CPU arrays and CUDA.jl is not supported.

Installation

To enable gpu support in JUDI, you will need to install one of Devito's supported offloading compilers. We strongly recommend checking the Wiki for installation steps and to reach out to the Devito community for GPU compiler related issues.

  • [x] nvc/pgcc. This is recommended and the simplest installation. You can install the compiler following Nvidia's installation instruction at HPC-sdk
  • [ ] aompcc. This is the AMD compiler that is necessary for running on AMD GPUs. This installation is not tested with [JUDI] and we recommend to reach out to Devito's team for installation guidelines.
  • [ ] openmp5/clang. This installation requires the compilation from source openmp, clang and llvm to install the latest version of openmp5 enabling gpu offloading. You can find instructions on this installation in Devito's Wiki

Setup

The only required setup for GPU support are the environment variables for [Devito]. For the currently supported nvc+openacc setup these are:

export DEVITO_LANGUAGE=openacc
export DEVITO_ARCH=nvc
export DEVITO_PLATFORM=nvidiaX

Running with Docker

If you do not want to install JUDI, you can run [JUDI] as a docker image. The first possibility is to run the docker container as a Jupyter notebook. [JUDI] provides two docker images for the latest [JUDI] release for Julia versions 1.6 (LTS) and 1.7 (latest stable version). The images names are mloubout/judi:JVER-latest where JVER is the Julia version. This docker images contain pre-installed compilers for CPUs (gcc-10) and Nvidia GPUs (nvc) via the nvidia HPC sdk. The environment is automatically set for [Devito] based on the hardware available.

Note: If you wish to use your gpu, you will need to install nvidia-docker and run docker run --gpus all in order to make the GPUs available at runtime from within the image.

To run [JUDI] via docker execute the following command in your terminal:

docker run -p 8888:8888 mloubout/judi:1.7-latest

This command downloads the image and launches a container. You will see a link that you can copy-paste to your browser to access the notebooks. Alternatively, you can run a bash session, in which you can start a regular interactive Julia session and run the example scripts. Download/start the container as a bash session with:

docker run -it mloubout/judi:1.7-latest /bin/bash

Inside the container, all examples are located in the directory /app/judi/examples/scripts.

Previous versions: As of version v2.6.7 of JUDI, we also ship version-tagged images as mloubout/judi:JVER-ver where ver is the version of [JUDI] wanted, for example the current [JUDI] version with Julia 1.7 is mloubout/judi:1.7-v2.6.7

Development version: Additionally, we provide two images corresponding to the latest development version of [JUDI] (latest state of the master branch). These images are called mloubout/judi:JVER-dev and can be used in a similar way.

Testing

A complete test suite is included with [JUDI] and is tested via GitHub Actions. You can also run the test locally via:

    Julia --project -e 'using Pkg;Pkg.test(coverage=false)'

By default, only the [JUDI] base API will be tested. However, the testing suite supports other modes controlled via the environment variable GROUP such as:

	GROUP=JUDI Julia --project -e 'using Pkg;Pkg.test(coverage=false)'

The supported modes are:

  • JUDI : Only the base API (linear operators, vectors, ...)
  • BASICS: Generic modeling and inversion tests such as out of core behavior
  • ISO_OP : Isotropic acoustic operators
  • ISO_OP_FS : Isotropic acoustic operators with free surface
  • TTI_OP : Transverse tilted isotropic operators
  • TTI_OP_FS : Transverse tilted isotropic operators with free surface
  • filename : you can also provide just a filename (i.e GROUP=test_judiVector.jl) and only this one test file will be run. Single files with TTI or free surface are not currently supported as it relies on Base.ARGS for the setup.

Configure compiler and OpenMP

Devito uses just-in-time compilation for the underlying wave equation solves. The default compiler is intel, but can be changed to any other specified compiler such as gnu. Either run the following command from the command line or add it to your ~/.bashrc file:

export DEVITO_ARCH=gnu

Devito uses shared memory OpenMP parallelism for solving PDEs. OpenMP is disabled by default, but you can enable OpenMP and define the number of threads (per PDE solve) as follows:

export DEVITO_LANGUAGE=openmp  # Enable OpenMP. 
export OMP_NUM_THREADS=4    # Number of OpenMP threads

Full-waveform inversion

[JUDI] is designed to let you set up objective functions that can be passed to standard packages for (gradient-based) optimization. The following example demonstrates how to perform FWI on the 2D Overthrust model using a spectral projected gradient algorithm from the minConf library, which is included in the software. A small test dataset (62 MB) and the model can be downloaded from this FTP server:

run(`wget ftp://slim.gatech.edu/data/SoftwareRelease/WaveformInversion.jl/2DFWI/overthrust_2D.segy`)
run(`wget ftp://slim.gatech.edu/data/SoftwareRelease/WaveformInversion.jl/2DFWI/overthrust_2D_initial_model.h5`)

The first step is to load the velocity model and the observed data into Julia, as well as setting up bound constraints for the inversion, which prevent too high or low velocities in the final result. Furthermore, we define an 8 Hertz Ricker wavelet as the source function:

using PythonPlot, HDF5, SegyIO, JUDI, SlimOptim, Statistics, Random

# Load starting model
n, d, o, m0 = read(h5open("overthrust_2D_initial_model.h5", "r"), "n", "d", "o", "m0")
model0 = Model((n[1], n[2]), (d[1], d[2]), (o[1], o[2]), m0)	# need n, d, o as tuples and m0 as array

# Bound constraints
vmin = ones(Float32, model0.n) .+ 0.3f0
vmax = ones(Float32, model0.n) .+ 5.5f0
mmin = vec((1f0 ./ vmax).^2)	# convert to slowness squared [s^2/km^2]
mmax = vec((1f0 ./ vmin).^2)

# Load segy data
block = segy_read("overthrust_2D.segy")
dobs = judiVector(block)

# Set up wavelet
src_geometry = Geometry(block; key="source", segy_depth_key="SourceDepth")	# read source position geometry
wavelet = ricker_wavelet(src_geometry.t[1], src_geometry.dt[1], 0.008f0)	# 8 Hz wavelet
q = judiVector(src_geometry, wavelet)

For this FWI example, we define an objective function that can be passed to the minConf optimization library, which is included in the Julia Devito software package. We allow a maximum of 20 function evaluations using a spectral-projected gradient (SPG) algorithm. To save computational cost, each function evaluation uses a randomized subset of 20 shot records, instead of all 97 shots:

# Optimization parameters
fevals = 20	# number of function evaluations
batchsize = 20	# number of sources per iteration
fvals = zeros(21)
opt = Options(optimal_checkpointing = false)    # set to true to enable checkpointing

# Objective function for minConf library
count = 0
function objective_function(x)
	model0.m = reshape(x, model0.n);

	# fwi function value and gradient
	i = randperm(dobs.nsrc)[1:batchsize]
	fval, grad = fwi_objective(model0, q[i], dobs[i]; options=opt)
	grad = reshape(grad, model0.n); grad[:, 1:21]
View on GitHub
GitHub Stars126
CategoryDevelopment
Updated22d ago
Forks35

Languages

Julia

Security Score

100/100

Audited on Mar 6, 2026

No findings