My name is Rini Banerjee, and I am about to start my third year of Joint Mathematics and Computer Science at Imperial College London.
I’ve spent this summer doing a remote research internship on the Devito Project, under the supervision of Prof Paul Kelly and Dr Gerard Gorman. I’ve been working on the Devito Book: a set of Jupyter Notebook tutorials that teach the finite difference method for solving partial differential equations using Devito, based on the textbook “Finite Difference Computing with PDEs - A Modern Software Approach” by H. P. Langtangen and S. Linge.
What is Devito?
Devito is a domain-specific language and code generation framework that automates the finite difference method for solving partial differential equations (PDEs). It can be used as a library in Python to provide a high-level symbolic abstraction for the user, allowing them to input their problem concisely using simple mathematical operators. This makes code extremely readable and intuitive to understand. In addition, Devito turns symbolic Python code into highly optimised C++ code under the hood and, as a result, is much faster than its contemporaries. Its performance and usability give it a significant edge over many existing programs.
Symbolic Computation in Devito
Devito is primarily used to solve inverse problems. In particular, the original motivation for Devito was to create wave propagation kernels to solve PDEs in the context of seismic equations.
Marmousi Full Waveform Inversion (FWI),
Marmousi Full Waveform Inversion (FWI), done using JUDI (from this paper)
Configure CI/CD using GitHub Actions to verify that code examples (both stand alone examples and individual Jupyter notebooks) execute correctly and to deploy the revised Jupyter Book.
Re-implement the existing finite difference coding examples using Devito.
The main aim of this project is to provide an interactive, easy-to-follow online textbook for teaching the finite difference method. It is hoped that by doing these tutorials, students will not only gain a deeper understanding of how the finite difference method works, but also learn how to use Devito as a powerful tool for numerical computation.
Re-engineering the book format
My first task was to take the original book, which was essentially a set of DocOnce files, and convert these files into a form that could be represented as a Jupyter Book. Jupyter Books allow Jupyter Notebooks to be represented as an online book with a table of contents and simple navigation between different notebooks. Thankfully, DocOnce came with a command-line tool for directly converting from DocOnce (.do.txt) files into Jupyter Notebook (.ipynb) files, and so after importing the original textbook into the devito_book repository, I used this tool to generate the Jupyter Notebooks.
Next, I used GitHub Actions to configure CI/CD for the book. This involved setting up a few workflows (.yml files) that do the following:
Test that the code in the completed Jupyter Notebooks is compiling, using pytest and a plugin called nbval (NoteBook VALidation)
Test that the numerical computation is being done correctly in the Jupyter Notebooks, using tests that were written for the original textbook
Re-implementing the existing NumPy solvers using Devito
Once the initial setup for the Devito Book was complete, it was time to get to work on re-implementing the existing finite difference coding examples. These existing examples were written in Python, using the NumPy library, and my task was to change these examples to use Devito instead.
My approach to doing this conversion from NumPy to Devito code involved:
Writing a new function with the same expected behaviour using Devito
Plotting the Devito function’s output against the original NumPy function’s output for the same inputs
Using the original textbook’s verification tests to check that the Devito function was performing as expected
Once I was confident that my Devito solvers were executing correctly for a particular notebook, I would deploy it to GitHub Pages.
The deployed Jupyter Book
Throughout the summer, I worked on notebooks that teach students how to computationally solve wave equations, vibration equations and diffusion equations. I mainly used the Jupyter Notebook interface for working on these notebooks. I also used Visual Studio Code extensively for working on Python files, and later loaded the relevant functions from these files into Jupyter Notebook code cells.
Using Visual Studio Code to write Devito solver functions
During the project, some of the team noticed that there were a lot of dependencies for these notebooks, including visualisation packages such as Bokeh and Mayavi. For users of the book who preferred the more interactive Jupyter Notebook interface, it would require some effort to get the book running quickly if they did not have all of these dependencies already installed. For this reason, we decided to containerise the book using Docker. Running docker-compose up devito_book starts a Jupyter notebook server inside a container and forwards the port to http://localhost:8888 .
Calling all contributors!
Now that I am approaching the end of my summer project, I will be leaving this project to the Devito team so that they can complete what I have been working on for the last 10 weeks.
If you are interested in numerical computation, programming in Python, and/or applied mathematics, and would like to contribute to our open-source textbook, feel free to reach out to us on Slack and check out the devito_book repository on GitHub.
Thank you to everyone on the Devito Project for giving me the opportunity to learn so much this summer in a really friendly and supportive work environment. It’s been great!