Tuesday, May 21, 2013

Visual debugging in Fortran with ZMQ and Python

I recently stumbled upon a relatively simple way to do in-situ visualisation of a fairly complex Fortran 90 based advection-diffusion-reaction code... being able to quickly insert calls to send solutions to a separate visualisation process and see what my algorithm was doing (wrong) was pretty helpful (and fun!).

The general idea is:

  • Fire up a Python process that spins off two threads:
    1. a GUI (Qt/PySide) thread with some matplotlib plots, and
    2. a ZMQ thread that listens on port 31415 and receives solutions from the F90-MPI beast...
  • Write a thin ZMQ wrapper in C that is callable from F90 through the iso_c_binding module. The C part handles all the ZMQ related stuff (establishing connections and sending messages). The F90 part defines a simple routine called 'dsend' (debug send) that can is called with proper F90 data types (BoxLib multifabs in my case) and calls the C wrapper.

Here is the code: visdebug. Please see comments within for more details and compiling tips.

A few nice things about this approach:

  • Solutions are "pushed" from the F90 code to the visualiser and these pushes can be inserted practically anywhere within the F90 code.
  • The Python visualisation process just sits there between runs of the F90 code without any need for interaction from the user.
  • Communication with ZMQ seems fairly robust and does not interfere with MPI - no need to create new MPI communicators to do visualisation/debugging.
  • The visualizer can be run on a different machine from the F90 code.
I should note that although the code I work with uses MPI parallelism, when debugging I usually run with one MPI process. Having said that, I don't think it would take too much extra logic to have the visualiser reconstruct an entire solution given various pieces of it from multiple MPI processes.

A few drawbacks of this approach:

  • The receive calls in the Python visualizer and the order in which the F90 'dsend' routines are called are fairly coupled. I suppose this could be remedied by making things a bit more general without too much trouble.

Some other notes:

  • If you install Anaconda (thanks Continuum!) you have everything you need: ZMQ (includes and libraries too), pyzmq, matplotlib, PySide, Qt etc.
  • You can also use Traits+Mayavi to do the visualisation instead of PySide+matplotlib (but these aren't in Anaconda).
  • Once upon a time I instrumented a Python code to use the in-situ visualisation routines in VisIt, but didn't get around to trying it with F90.

Feedback/comments/flames welcome.

No comments:

Post a Comment