The ability to call Fortran code from Python has been and still is essential to several scientific packages, including the widely used SciPy library. One widely used tool to make the Fortran code accessible to Python is the f2py library that is bundled with NumPy.
Here, I review how one can write portable and easy to compile Fortran routines.
Solution
f2py is a really powerful tool and its features include the ability to pass Python-defined
callbacks to Fortran routines. I have found however that configuring a proper build chain
with f2py is a bit annoying. Well, building Fortran sources from a setup.py
file is not
that easy.
An alternative is to use the "recent" (i.e. 2003) interoperability features of Fortran and provide your code as a library. In short, here's why you could want to use them:
- Definition of common types that is accessible from Fortran: a
real(c_double)
in Fortran is adouble
in C, aninteger(c_int)
is anint
in C, etc. - It is possible to declare a subroutine with the
bind(c)
so that the calling convention and the routine name is well defined. It is possible to customize the name withbind(c, name='public_function')
. - It is possible use "pass by value" arguments with the
value
attribute. - The library is compiled without using distutils.
A consequent drawback of this approach is that there is no automated binding
generator. Following the suggestion on
fortran90.org, I wrote
manually a Fortran wrapper that has uses bind(c)
and interoperable datatypes and then a
Cython wrapper that would make it available to Python. I made this choice so that the
initial Fortran file is completely unmodified and so remains "binding agnostic".
There is a Fortran
module,
a Fortran
wrapper,
and a Cython
wrapper.
The end result will be a Fortran shared library (here, libbrownian.so
) and a Python module
brownian_wrapper.so
.
The immense benefit is that compiling this is very easy. The main line to obtain
libbrownian.so
is gcc -shared -o libbrownian.so *.o -lgfortran
. Then, the
setup.py
file is standard. You have to declare the use of the libraries brownian
and gfortran
(the latter part depends on your compiler, still).
You system might complain about not finding libbrownian.so
here, as I did not copy it
along. If that is the case, adjust your $LD_LIBRARY_PATH
.
Wrap up
There is now an alternative method to access Fortran code from Python and my idea is simply to compile the Fortran part as a library to avoid distutils complexity for dealing with Fortran. This approach requires more work but should be more portable and relies on standard tools: the Fortran interoperability features and Cython.
I tested the code with Intel Fortran too with success.
Comments !
Comments are temporarily disabled.