F2PY A Tool For Connecting Fortran and Python Prog
F2PY A Tool For Connecting Fortran and Python Prog
net/publication/228524531
CITATIONS READS
200 3,983
1 author:
Pearu Peterson
Quansight
61 PUBLICATIONS 12,493 CITATIONS
SEE PROFILE
Some of the authors of this publication are also working on these related projects:
All content following this page was uploaded by Pearu Peterson on 20 May 2014.
Pearu Peterson
Centre for Nonlinear Studies,
Institute of Cybernetics at Tallinn Technical University,
Akadeemia tee 21, 12918 Tallinn, Estonia
E-mail: [email protected]
Abstract: In this paper we tackle the problem of connecting low-level Fortran programs
to high-level Python programs. The difficulties of mixed language programming between
Fortran and C are resolved in an almost compiler and platform independent way.
We provide a polished software tool F2PY that can (semi-)automatically build interfaces
between the Python and Fortran languages and hence almost completely hide the difficulties
from the target user: a research scientist who develops a computer model using a
high-performance scripting approach.
Reference to this paper should be made as follows: Peterson, P. (2009) ‘F2PY: a tool for
connecting Fortran and Python programs’, Int. J. Computational Science and Engineering,
Vol. 4, No. 4, pp.296–305.
Python supports a very high-level object-oriented • The interface generator tool should take advantage
programming paradigm with many predefined data of the information available in the Fortran source
types and useful modules in the standard library; code and create as Pythonic1 interface as possible.
Python is easy to extend and its programs are highly
• The interfacing solution should be as easy to use
portable. High-quality scientific computational packages
for large Fortran libraries (with thousands of
in Python have emerged within the last ten years
subprograms) as for a simple Fortran procedure
(Oliphant, 2007). For example, NumPy offers most of
(Fortran function or subroutine).
the basic functionality of Matlab, and SciPy provides
a rich user-friendly scientific computing environment A number of tools exist that simplify connecting C/C++
with interfaces to different high-performance software to Fortran for wrapping Fortran (77/90/95/2003)
libraries written in C/C++ and Fortran (LAPACK, for programs to Python like SWIG (Beazley, 2003), SIP,
instance). Boost.Python, Babel, and others. However, not one
The task of creating interfaces between programming of them satisfies the single optimal solution criterion
environments such as Fortran and Python is nontrivial stated above, even in the case of simple Fortran
due to both the complexity of the low-level application procedures. To use these tools one needs, as a minimum,
programming interfaces, that often contain many to create a tool-dependent specification file containing
technical details, and the extra knowledge regarding C/C++ declarations from which wrapper codes can be
mixed-programming techniques between both Fortran generated. When interfacing Fortran code, one needs
and C, and C and Python. Finding a portable and to write pseudo-declarations for Fortran procedures
compiler independent way of accessing some Fortran that describe them as if they are C functions. Such
constructions from C can require a considerable amount an approach requires an extensive knowledge of both
of research and resources. For a scientific programmer, Fortran-C mixed-programming techniques and compiler
the threshold of learning all of the required technical specific issues, especially when interfacing Fortran 90 or
details and resolving different portability issues, is newer subprograms and data collections. For example,
prohibitively high. As a result, the developer often some Fortran 90 compilers have rather poor support
chooses to program everything either in a low-level for mixed-programming with C, thus it is impossible
language or in a high-level language, with a resultant to access Fortran module subprograms from C, see
computational model that is often far from optimal. Section 2.4. Very few scientists have the experience
The aim of developing F2PY was to find an optimal required to create such interfaces in an efficient way using
solution to the Fortran and Python connection problem. these tools.
The design criteria were that the programming solution The following example illustrates the F2PY solution
should be appropriate and easy to use both for a scientist, to the Fortran and Python connection problem: with a
who occasionally needs to use a Fortran subprogram single command we can create Python wrappers to all
from Python, and for a Python package developer, who the 1301 LAPACK functions (the sh> line indicates a
needs to provide flexible and Python friendly interfaces command in a Unix or DOS terminal window, \ is line
to large Fortran libraries. The results of this work will continuation):
be important for scientific programming groups that have sh> f2py -m lapack LAPACK-3.0/SRC/*.f -c \
developed large Fortran libraries over decades and now --link-blas_opt
need to increase both the development productivity of
their products and widen their code base to new users. and have them immediately usable from Python:
The following general design criteria describe the sh> python
optimal software solution: >>> from numpy import array, float64
>>> from lapack import dgesv
• No prior knowledge of mixed-programming >>> # Solve a system of linear equations A*x=b
techniques should be required to create and to use >>> A = array([[1,2], [3,4]])
the interfaces between Python and Fortran >>> b = array([[5], [6]], float64,\
programs. order=’FORTRAN’)
>>> # see dgesv.__doc__ for argument information
• The development of a Fortran library of >>> dgesv(2,1,A,[0,0],b,0)
subprograms and a Python program using that >>> print b # the solution x is stored in b
library, should be independent. That is, neither the [[-4. ]
Fortran nor the Python user need not to be [ 4.5]]
familiar with the other language.
To illustrate how much work F2PY can save a developer,
• Creating robust and immediately usable wrappers note that the source file for LAPACK Fortran-Python
between Fortran and Python programs should be bindings has about 290,000 lines of C code and it takes
automatic and triggered by a single command. about 10 min on a standard 2007 laptop to generate and
However, there should also be an opportunity to to compile all sources. If the same task would be carried
tune the interfaces. out by an average C programmer, it would require about
298 P. Peterson
six years to complete (assuming that the productivity is 2.1 Basic steps to create wrappers
about 25 lines of code per hour (Prechelt, 2000)).
This paper is organised as follows. First, we present Creating a Python wrapper to a Fortran procedure
an overview of the task of wrapping Fortran procedures means creating a Python C/API extension module
to Python. This will also include an original idea of (called as wrapper module) that implements a Python
overcoming the difficult problem of accessing Fortran 90 extension function (written in C, called as wrapper
symbols from C in a compiler independent way. Next we function) which in turn calls the given Fortran
show the use of F2PY as an automatic Fortran-Python procedure. In the wrapper function, before the actual call
wrapper generation tool. Following this is a short to Fortran, Python arguments must be converted to C
tutorial and feature overview, including F2PY usage data structures that are suitable for use as arguments to
strategies, interface peculiarities, and limitations. Finally Fortran procedures. After the call, the wrapper function
conclusions and future work plans will be discussed. must convert the computed results to Python objects,
and finally, return to the Python program. The wrapper
module must be compiled and linked with the Fortran
2 Wrapping Fortran programs to python libraries to form a shared library that can be imported
into Python.
Each of these steps requires some technical
A Python wrapper of a Fortran procedure (a Fortran
knowledge. To produce portable, robust, and easy to use
subroutine or function) is an adaptor-like function
wrappers, one needs to have experience with each of the
(implemented as Python extension function) that
various issues. It turns out that the greatest difficulties
converts Python objects (function arguments) to objects
are due to variability of mixed-programming techniques
that can be used as Fortran procedure arguments, makes
within different Fortran compilers. A tool that automates
the call to the Fortran procedure, and finally, converts
the creation of wrappers, must implement algorithms
the results (changed arguments and return values) to
that are independent of a particular choice of Fortran
Python objects.
compiler. This task is not always as straightforward as
The connection between Fortran and Python is
one would wish, as we shall see in Section 2.4.
achieved via C. While Python and C interoperability is
well defined by the Python/C API then there are two
major issues when creating Python wrappers to Fortran
2.2 Collecting signature information from
procedures: Fortran files
In general, the conversion methods of arguments in The most typical case for enhancing signature
the wrapper function need to know about how different information comes when wrapping Fortran 77
Fortran types may be represented as C objects and the procedures as these contain no information about
size and shape of Fortran procedure arguments in the the intention of arguments: whether the arguments
case of arrays. The size and shape information of array contain just input data, or just results, or both. Such
arguments are usually present as Fortran dimension information can be very difficult or impossible to
specifications in a Fortran procedure. The basic Fortran determine automatically without full program analysis
types such as INTEGER, REAL, etc. can be immediately while the user can often easily provide this additional
mapped to the corresponding C types int, float, etc., information from documentation notes.
respectively. Of course, such a mapping must take into An example of where fixing signature information
account the actual byte sizes of Fortran types that must might be necessary is when wrapping legacy Fortran 77
match the byte sizes of the corresponding C types. code which abuses certain features of the Fortran 77
Note that, compared to Fortran subprograms, standards and compilers. An example is when array
C programs contain typically less of the signature arguments of a Fortran procedure are declared to have
information required to create wrappers automatically size one but the callers may provide arrays with different
(for example, arrays in C are declared as simple pointers sizes to the procedure (the actual sizes are specified
without dimension information). This explains why in other arguments to the procedure). Obviously, no
tools designed to wrap C/C++ libraries to scripting automatic tool can detect such abuses and automatically
languages need additional specification files describing fix them.
the signatures, and why the task of wrapping C programs One of the most common enhancements is to add
to scripting languages cannot be fully automated at the intent information to argument declarations. This may
level that is possible with Fortran subprograms. be achieved either by
2.3 Ways to enhance the signature information • Inserting the information via specially formatted
comment in the Fortran source that can be
The choice of programming idioms used in a computer detected by the scanner.
program depends strongly on the programming • Saving the scanned information to an intermediate
language. For example, in a typical Fortran 77 procedure
specification file where the information can be
computed results are often returned by updating the
content of subroutine arguments (i.e., arguments are modified by user. This modified file can be used to
passed by reference or as addresses): create the wrapper. The given approach is termed
semi-automatic.
subroutine foo (i1, i2, n1, n2, io3, o4,\
m1, m2, o5) The syntax of both the specially formatted comment
integer n1, n2, m1, m2 lines and intermediate specification files should follow the
real i1, i2(n1, n2), io3 syntax of recent Fortran standards to reduce the learning
real o4(m1, m2), o5(m1) curve for users with existing Fortran knowledge. Ideally,
c Input arguments: i1, i2 the scanner should be able to detect the errors when
c Input-output arguments: io3 editing either the Fortran sources or the specification
c Output arguments: o4, o5 files.
...
end
2.4 Mixed language programming using
In Python, however, changing arguments in-place is Fortran and C
considered as poor Python programming style where
output data from a function would, preferably, be Technically, there are no difficulties in generating
returned as (multiple) objects. Note also that dimension extension modules from a set of well-defined signatures.
information is included within array objects and, The generator must ensure that reference counting of
therefore, does not need to be passed via the argument Python objects is done correctly and that the generated
list: code follows C standards to guarantee portability.
The difficult part of generating extension modules lies
def foo(i1, i2, io3):
... in mixed language programming between C and Fortran
return io3, o3, o4, o5 because the techniques for accessing Fortran symbols
from C in a portable way, can be complex.
The above code examples represent so-called function The internet and some Fortran compiler vendors
signatures of Fortran and Python programs, respectively, provide technical documentations about mixed language
in a notation used throughout this paper. programming techniques between C/C++ and Fortran
In general, Fortran procedures contain sufficient 77/90/95, but there exists no standard specification
signature information to automatically generate wrappers. about the techniques that all Fortran compilers
However, situations exist where the signature information would follow (except compilers that follow standard
needs to be changed by either adding more signature Fortran 2003). However, with at least one exception
information or fixing the scanned signature information. (the F compiler), all Fortran compilers (see Section 2.5)
300 P. Peterson
have support for compiling fixed form Fortran sources subroutine bar()
containing standard Fortran 77 code. Moreover, end subroutine bar
the basic methods of mixed language programming end module baz
techniques between Fortran 77 and C seem to be
universal among all Fortran compilers assuming that ! auxiliary fixed format Fortran code
only Fortran subroutines are used – this will be our subroutine finitbar(cinit)
assumption when discussing portable techniques. Recall use baz
that Fortran 77 is a subset of newer Fortran standards extern cinit
! sending bar reference to C:
and the assumption does not put applicability restrictions
call cinit(bar)
to wrapping newer Fortran codes.
end
First, one needs to know how to access Fortran
/* Python C/API code */
symbols from C. Different Fortran compilers map the extern void finitbar_; /* GCC convention,
names of Fortran symbols (the names of procedures, refers to Fortran
common blocks, modules, module data, module finitbar */
procedures, etc.) to the corresponding object names char *bar_ptr; /* will hold reference
differently (name mangling). However, most Fortran to bar */
compilers provide command line switches that can void init_bar(char *bar) { /* initializes
be used to achieve a particular naming convention. bar_ptr */
Such a convention can be used consistently in the *bar_ptr = bar;
wrapper generator. So, in the following we assume that } static PyObject* bar_capi /* wrapper function
when proper compiler switches are used, the name of to bar */
a Fortran symbol (recall that names in Fortran are (PyObject *self, PyObject*args) {
case-insensitive), say FOO, can be accessed from a C (*((void *)bar_ptr))();
program as foo_, that is, all cases are lowered and } void initfoo() { /* initializes
exactly one underscore is appended to the name of extension module */
a Fortran symbol. Note that sometimes the Fortran finitbar_(init_bar); /* initialize bar_ptr */
libraries provided by a system, may have been built using ...
different compiler switches leading to different naming }
convention. For such cases, the wrapper generation tool
The proposed technique is unique because it makes
must provide hooks to adapt default naming conventions
mixing Fortran 90 and C as portable as mixing Fortran
to a particular case.
77 and C codes. The technique can be applied also
Unfortunately, the naming convention introduced
for referencing Fortran common blocks and Fortran 90
above cannot be assumed for all Fortran 90 symbols. For
module data from C.
example, the MIPSPro 7 compilers generate object code
There exist other compiler related issues that the
where Fortran 90 module names contain the $ character.
extension generation tool must take into account:
Such names cannot be accessed from C directly and these
compilers do not provide compile switches to change
• Calling convention of COMPLEX or CHARACTER
that behaviour. Therefore, more complex techniques are
string valued Fortran functions is Fortran compiler
required to access Fortran 90 module symbols from C.
We propose the following original solution to the dependent. The issue can be resolved by generating
above problem: the references to Fortran 90 module the auxiliary wrapper Fortran subroutine that
symbols can be determined at runtime by using special executes the Fortran function call and saves the
wrappers. Basically, the initialisation function initfoo result to extra argument of the wrapper subroutine.
(see the example below) of a Python extension module
• Accessing and manipulating Fortran 90 module
foo calls an auxiliary Fortran subroutine finitbar in
fixed form with a special call-back C function init_bar data ALLOCATABLE arrays requires additional
as an argument. The Fortran subroutine finitbar methods that will support creating, initialising,
that uses Fortran 90 module baz symbols, makes a modifying, deallocating, and reallocating such
call-back to C using the call-back C function init_bar. arrays. These operations are better executed in
The call-back function has the Fortran 90 symbols Fortran code than in C because often Fortran
as arguments. In C, the pointers to these arguments compilers do not provide any information how to
are saved in global C variables that are visible to all access allocatable arrays as C structures (Pletzer
C functions that need to access Fortran 90 symbols. et al., 2008).
This arrangement is best illustrated with the following
example (the code should be read from the end for better • Dealing with Fortran alternative returns that have
understanding of the program flow): no matching paradigm in C.
2.5 Compiling and linking extension modules 3 The F2PY tool for connecting Fortran and
Python programs
In general, the task of compiling and linking the
Python extension modules is best performed using This section describes how the problem of connecting
Python’s standard distutils package that implements Fortran and Python programs in a robust and portable
extension module building support to as many way is solved using the polished tool F2PY (F2PY), that
platforms as Python itself supports. However, to build is currently available as a part of the NumPy package.
extension modules that use Fortran software, we In the following we assume that the following software is
recommended using the numpy.distutils package installed: NumPy 1.1 (or newer), the Python development
(provided by NumPy), which extends the standard package distutils (some systems do not provide
distutils with support for Fortran compilers. it by default when installing Python), a compatible
The main advantage of using numpy.distutils C compiler, and a Fortran compiler supported by
compared to the manual approach of building extension numpy.distutils.
modules, is that numpy.distutils contains support
to a large number of Fortran compilers. In addition, 3.1 A simple example
information about specific compilers (switches for
universal naming conventions, compilation flags for To get acquainted with F2PY, let us consider the
optimised builds, required libraries for linking, etc.) are following simple Fortran 77 function for computing the
being continually updated when new Fortran compiler dot product of two vectors:
versions are released. At present, numpy.distutils c file: dot.f
supports the following list of Fortran compilers: GNU FUNCTION dot(n, x, y)
Fortran 77, GNU Fortran 95, Absoft Corp Fortran, INTEGER n, i
Compaq Fortran, G95 Fortran, Intel/Intel Visual DOUBLE PRECISION dot, x(n), y(n)
Fortran, Lahey/Fujitsu Fortran 95, NAGWare Fortran dot = 0d0
95, Portland Group Fortran, Pacific-Sierra Research DO 10 i = 1, n
Fortran 90, HP Fortran 90, IBM XL Fortran, Sun or dot = dot + x(i) * y(i)
Forte Fortran 95, and MIPSpro Fortran compilers. 10 CONTINUE
END
There may exist cases where building extension
modules manually is still needed, for example, when one In order to call the Fortran function dot from Python,
needs to have better control over how the extension let us create an interface to it by using f2py (F2PY’s
modules and Fortran sources are compiled and linked front-end program). For that we issue the following
together. For improving the portability of such setups, command:
we recommend using the Fortran linker for creating sh> f2py -m foo dot.f -c
extension module shared libraries because this will ensure
that all necessary Fortran libraries are included in the where the option -m foo sets the name of the extension
linking step. Using the system linker requires determining module and the option -c instructs f2py to build the
this information manually which can be tedious because extension module library that can be imported to Python
the information may change even between different (without the -c option f2py would only generate
versions of the same Fortran compiler. sources to the extension module).2
The following sample session demonstrates how to
2.6 Providing new signature information call the Fortran function dot from Python:
to wrapper users sh> python
>>> import foo
In general, the process of generating Python wrapper >>> result = foo.dot([1,2], [3, 4])
functions to Fortran procedures requires the signatures >>> print result
of the original Fortran procedures to be transformed 11.0
to functions with different signatures when viewed from
Note the difference between the signatures of the Fortran
the Python side (see Section 2.3). These transformations function dot(n, x, y) and the corresponding wrapper
may be introduced automatically by the wrapper function dot(x, y):
generation tool or explicitly by the user in order
to make the wrapper functions more natural to use >>> print foo.dot.__doc__
for Python programmers. The wrapper generation tool dot - Function signature:
dot = dot(x,y,[n])
must generate documentation (doc strings) that precisely
Required arguments:
describe how the Fortran input and output arguments
x : input rank-1 array(’d’) with bounds (n)
are treated from the Python side. Typically, a user y : input rank-1 array(’d’) with bounds (n)
must first check the documentation string before entering Optional arguments:
code for calling wrapper functions because the Python n := len(x) input int
signature may differ from the Fortran signature, see Return objects:
Section 3.1 for an example. dot : float
302 P. Peterson
Clearly, the latter is more convenient for the Python Fortran storage order. Otherwise, the interface would
user: the user does not need to provide a value for n create a copy of the input argument b and use the copy
because the wrapper function can determine the value as the corresponding argument to the Fortran function.
automatically from the length of the input vectors x Note that although the computed results are saved to this
and y. This feature often reduces very long Fortran copy array, the copy is not returned to Python because
argument lists to much shorter Python wrapper function of the default input-only assumption.
argument lists. The smart way strategy gives maximum flexibility
to enhance the F2PY wrapper generation process
3.2 Strategies of using F2PY and is appropriate for creating high-quality wrappers
to (legacy) Fortran libraries. Typically, one uses the
F2PY is designed to wrap Fortran codes of various following iterative scheme for producing easily usable
complexity written with different styles of programming. and efficient wrapper modules:
We have worked out the following three basic strategies
of wrapping Fortran procedures to Python: 1 Create an initial wrapper module interface:
• The quick way – let F2PY to do all the work, sh> f2py -m <modulename> <Fortran files>\
that is: -h <modulename>.pyf
• scan signature information from Fortran This command will scan Fortran source files for
sources procedure signatures and save the obtained
signature information to a signature (.pyf) file.
• create interface signatures for Fortran
procedures, modules, and data collections 2 Review the signature file manually: insert arguments
intent information via the intent attribute,
• generate wrapper module sources containing
provide default values to optional arguments, etc.
necessary wrapper functions
3 Build the wrapper module:
• compile C and Fortran source files
• and finally, build the Python wrapper module sh> f2py -c <modulename>.pyf <Fortran files>
that can be immediately used for calling
Fortran procedures from Python. 4 Check the documentation strings of the generated
wrapper functions and test their functionality. In
• The smart way – let the user specify the interface case anything needs to be enhanced, go back to
signature (its initial version can be generated by Step 2.
using F2PY for scanning Fortran sources) and then
let F2PY handle the rest as listed above. The quick and smart way strategy is a combination of
the two strategies described above. Here the additional
• The quick and smart way – let the user specify signature information can be inserted directly to Fortran
extra signature information in Fortran source codes source codes using F2PY directive comments starting
and then let F2PY to do all the work as specified with !f2py that F2PY will process. As a result, one
under point 1. can create high-quality wrapper modules using just one
F2PY command. This approach is suitable when one can
The default strategy in F2PY is the quick way. Examples
add comments to Fortran source codes and has the
of using the quick way strategy were given above;
advantage of keeping all signature information in one
wrapping the LAPACK library in Section 1 and the
place.
dot function in Section 3.1. The advantage of using the
default strategy is that wrappers can be created with
a single command and it provides immediate access to 3.3 Differences between Fortran and Python
the Fortran code from Python. The disadvantage is that signatures
the user must be aware of the possible need to deal
with the differences of the Fortran and C data storage When F2PY generates a wrapper to a Fortran procedure
orders as well as how to prepare arrays in Python so then by default the resulting wrapper function follow
that they are efficiently passed to Fortran and filled with Python conventions to make their usage easier for
computed results. Such issues typically merge because of Python users. This behaviour of F2PY may change the
the lack of argument intent information in Fortran 77 interface of a Fortran procedure when viewed from the
procedures; though this is not a problem with Fortran Python side, and users of F2PY must be aware of this
90 or newer procedures. As a result, F2PY must use (see Section 3.1). Although this is unfortunate from an
the most conservative assumption: all arguments are interface stability point of view, when one takes into
input-only arguments. For example, in our LAPACK account the habits of typical Python users who are not
example, the array b has to have the float64 type (that familiar with Fortran idioms, being Pythonic outweighs
corresponds to Fortran DOUBLE PRECISION type) and possible disadvantages.
F2PY: a tool for connecting Fortran and Python programs 303
By default, F2PY automatically changes the Python. The following rule of thumb can be used to
signatures of Fortran procedures in the following two decide if F2PY is suitable for wrapping a given C
cases: function to Python: if the C function is using Fortran 77
compatible argument types (e.g., not types derived
• When a Fortran procedure argument has an from C struct) then F2PY is suitable for the task.
intent(out) attribute then the wrapper function Note that wrapping a C library cannot be made as
returns the value of the given argument. The
automatic as wrapping a Fortran library because the
argument is also removed from the wrapper
function argument list (in the case of not specifying relation between an array argument and its (integer)
an intent(in) attribute). For example, dimension arguments is not specified by the C code and
the following Fortran 77 subroutine, the array size information must be provided manually.
Many may feel that wrapping C functions with F2PY is
subroutine foo(x, y) significantly simpler than using other tools like SWIG.
!f2py intent(out) x, y See http://www.scipy.org/Cookbook/f2py_and_NumPy
!f2py intent(in) y for an example.
... How F2PY interfaces various Fortran features to
will have the following signature for the Python, are exemplified in the following sections.
corresponding Python wrapper function: A detailed list of F2PY features can be found on the
F2PY homepage and in the documentation.
def foo(y):
... 3.4.1 Array arguments
return x, y
As mentioned before, Fortran uses a different array
Here we have used F2PY directives to illustrate storage order than C. This means that before passing
how to insert argument intent information in Python multi-dimensional arrays (NumPy array objects)
Fortran 77 source code files. to Fortran procedures, the arrays must be transposed.
• When an input array argument to a Fortran In addition to that, when the Python array element
procedure has its dimension specified as an type differs from that expected by a Fortran procedure
argument, then the dimension argument is made (for example, when passing Python integer array to a
optional (and moved to the end of argument list) Fortran real array argument) the array content must
and its default value is set by the wrapper function be copied to a new array with the expected element
using the shape information stored in the type. F2PY automatically performs the transposing and
corresponding Python array argument. See copying operations in one transformation and only then
Section 3.1 for an example. when really needed. Specifically, it is possible to create
Python arrays with proper type and Fortran storage
3.4 Overview of F2PY features order that can be safely passed to Fortran without
copying and transposing. F2PY can detect such array
In general, F2PY can be used to wrap any Fortran 77 arguments and skip the corresponding transformations.
and certain Fortran 90 or newer libraries to Python This feature is very important because copying results
(see F2PY limitations below). The generated wrapper in noticeable overheads, especially when dealing with
modules implement various consistency checks for large arrays and when calling Fortran procedures in a
wrapper functions to avoid program crashes and to give long Python loop. User can enable conditional reporting
useful error messages when checks fail. Using F2PY features when array copies are made (see f2py flag
auto-generated wrapper functions is made easy especially -DF2PY_REPORT_ON_ARRAY_COPY).
for Python users who have no prior knowledge of
Fortran. 3.4.2 External procedures
With some help from the developer of a wrapper
module interface, the robustness and quality of F2PY Fortran procedures may declare EXTERNAL symbols
generated wrapper functions can be easily improved by which are procedures defined elsewhere. These external
providing more information (than normally available procedures can be specified as arguments to a Fortran
from Fortran source codes) about the intentions of procedure or as an object code to be linked with
Fortran procedure arguments. the Fortran program. F2PY supports both ways of
F2PY generated wrapper modules are highly portable specifying external procedures which makes it possible to
and compiler independent. Currently F2PY has support call Python functions from Fortran procedures.
for more than ten major Fortran compilers. F2PY For example, when an external procedure is given as
an argument to a Fortran procedure:
implements the approaches explained in Section 2.4 to
circumvent issues with compiler dependencies. subroutine foo(bar)
Although F2PY was originally designed to simplify external bar
wrapping large Fortran libraries to Python, the tool call bar(...)
can be also used for wrapping certain C libraries to ...
304 P. Peterson
then F2PY automatically creates an interface that allows accessing the allocatable array x and the subroutine foo
Python functions to be passed to Fortran:: in Python looks trivial:
>>> def bar(...): >>> m.foo() # call F90 module m function foo
... >>> m.x = [1, 2, 3] # allocate F90 x and \
>>> foo(bar) initialize with \
where the Python function bar will be called with given given values
arguments from the Fortran subroutine bar via an >>> m.x # returns the content of \
x as array
F2PY generated wrapper function bar. The problem of
>>> m.x = None # deallocate F90 x array
determining the signature of Fortran subroutine fun is
solved by scanning Fortran CALL statements. Here the F2PY generated interface handles the
When the external procedure is not specified in a complicated job of accessing Fortran 90 symbols from
Fortran procedure argument list, for example: C using the method explained in Section 2.4. This
subroutine foo() example is a good illustration of the power of F2PY:
external bar call the tool provides a very convenient and simple Python
bar(...) access to Fortran 90 while behind the scenes it uses
then the F2PY user must specify the intent very complicated but unavoidable technique to ensure
(callback) attribute for the bar symbol that will portability.
instruct F2PY to create the necessary interface and add
an additional argument to the wrapper function. 3.5 Limitations
3.4.3 Common blocks The most important limitation of F2PY is that it can
wrap only a certain subset of Fortran 90 programs.
F2PY automatically generates interfaces to COMMON For example, F2PY does not support wrapping Fortran
blocks defined in Fortran procedures and DATA BLOCK procedures that use arguments defined by the Fortran 90
items. For example, the interface to a common block in TYPE or POINTER constructs.
a Fortran subroutine,
At the time of writing, F2PY considers Fortran
subroutine foo() arrays of character strings as arrays of characters.
integer i This causes some inconvenience when providing NumPy
real x string arrays to F2PY generated wrapper functions. (This
common /data/ i, x(2, 3) restriction is present because the previous array backend
...
package Numeric did not support arrays of strings.)
is exposed to Python via a special object whose The other limitations of F2PY are often due to
attributes contain Python arrays with data referring to limitations of C. For example, Fortran alternative
the corresponding Fortran common block content: returns do not have the corresponding concept in C
>>> data.i = 5 # sets the value of common \ and hence F2PY cannot support alternative returns in a
block item i to 5 consistent manner.
>>> data.x # return the item x as \
writable array
Viewing or changing the content of data attributes in 4 Conclusions and future work
Python is directly related to viewing and changing the
content of Fortran common block data. This paper has provided an overview of issues that
arise from connecting low- and high-level languages,
3.4.4 Fortran 90 module procedures with particular focus on Fortran and Python. The
most difficult problems come from the fact that mixed
F2PY automatically generates interfaces to Fortran 90 language programming between Fortran and C was
module procedures (Fortran 90 module subroutines and not standardised until Fortran 2003 was published, and
functions) and Fortran 90 module data. The interface one needs to use nontrivial programming techniques in
is exposed via a special object that is created for
order to connect the Fortran (starting from Fortran 77)
each Fortran 90 module. In addition, F2PY generates
interfaces to Fortran 90 allocatable arrays that are and Python programs in a reasonably portable way.
able to allocate, initialise, reallocate and deallocate the In addition, one must be able to deal with the differences
Fortran allocatable arrays from Python. For example, of the data storage orders that Fortran and C use for
with the following Fortran 90 module: multi-dimensional arrays.
Examples were given highlighting the use of the
module m
real, allocatable, dimension(:) :: x software tool, F2PY, that solves many of the difficult
contains mixed language programming problems. Strategies were
subroutine foo suggested for dealing with idiomatic language differences
... between Fortran and Python in an efficient and
... convenient way.
F2PY: a tool for connecting Fortran and Python programs 305
In summary, F2PY can be used to (semi-)auto- Oliphant, T.E. (2007) ‘Python for scientific computing’,
matically wrap Fortran 77 and Fortran 90 or newer Computing in Science and Engineering, Vol. 9, No. 3,
programs to Python, with the above mentioned May–June, pp.10–20.
restrictions. In practice, F2PY fulfils all optimal software Ousterhout, J.K. (1998) ‘Scripting: higher level programming
solution criteria stated in Section 1 while special cases for the 21st century’, Computer IEEE, Vol. 31, No. 3,
exist where expert support is needed. F2PY has become March, pp.23–30.
an important tool to speed up Python by migrating Peterson, P., Martins, J.R.R.A. and Alonso, J.J. (2001)
computationally intensive tasks to Fortran. F2PY has ‘Fortran to Python interface generator with an application
to aerospace engineering’, Proceedings of the 9th
also given a new life to many legacy Fortran libraries
International Python Conference, CDROM, Long Beach,
and programs.
California, 19 pages.
There is work in progress to extend F2PY to wrap
Prechelt, L. (2000) ‘An empirical comparison of seven
a wider range of the Fortran 90, 95, and 2003 standard
programming languages’, Computer IEEE, Vol. 33,
features, and most importantly add the Fortran 90 No. 10, pp.23–29.
TYPE support. This may provide a significant impact
Pletzer, A., McCune, D., Muszala, S., Vadlamani, S. and
on Computational Science, as scientists are able to Kruger, S. (2008) ‘Exposing Fortran derived types to
reuse more contemporary high-performance Fortran C and other languages’, Computing in Science and
subprograms in high-level Python programs. Engineering, Vol. 10, No. 4, July–August, pp.86–92.
Wilson, G.V. (2006) ‘Where’s the real bottleneck in scientific
computing’, American Scientist, Sigma Xi, Vol. 94, No. 1,
Acknowledgements pp.5, 6, DOI: 10.1511/2006.1.5.