Thursday, July 2, 2020

Calling Fortran from Clojure

Calling compiled/native code from hosted/dynamic languages is always fun. Why not call Fortran from Clojure?

It turns out that Project Panama (used to call C from Java) makes this easy. But wait! Didn't you say calling Fortran from Clojure instead of C from Java? Yes, I did. Again, it turns out that calling Java from Clojure is easy, and making Fortran C-callable is also easy.

Check out my tiny clojure-fortran demo.

I think it would be interesting to get some kind of interop between the C structs (as in `ISO_Fortran_binding.h`) that describe Fortran arrays and Clojure.

Enjoy! Also, happy Canada day! Let's keep working toward a better world... who knows, maybe along the way you'll have to call Fortran from Clojure (but probably not).

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.

Friday, January 6, 2012

Casting complex arrays in Fortran to (flat) real arrays.

Sometimes I find the need to cast complex F90 arrays to (flat) real arrays in Fortran. (By 'cast' I mean: without allocating a new array.) To make life a bit easier, I wrote a Python script to generate an F90 module with a single interface that can cast various complex arrays with different shapes.

The code is here, with an example: fcast.py

Enjoy!