.. -*- rest -*- ////////////////////////////////////////////////////////////////////// F2PY Users Guide and Reference Manual ////////////////////////////////////////////////////////////////////// :Author: Pearu Peterson :Contact: pearu@cens.ioc.ee :Web site: http://cens.ioc.ee/projects/f2py2e/ :Date: $Date: 2005/04/02 10:03:26 $ :Revision: $Revision: 1.27 $ .. section-numbering:: .. Contents:: ================ Introduction ================ The purpose of the F2PY_ --*Fortran to Python interface generator*-- project is to provide a connection between Python and Fortran languages. F2PY is a Python_ package (with a command line tool ``f2py`` and a module ``f2py2e``) that facilitates creating/building Python C/API extension modules that make it possible * to call Fortran 77/90/95 external subroutines and Fortran 90/95 module subroutines as well as C functions; * to access Fortran 77 ``COMMON`` blocks and Fortran 90/95 module data, including allocatable arrays from Python. See F2PY_ web site for more information and installation instructions. ====================================== Three ways to wrap - getting started ====================================== Wrapping Fortran or C functions to Python using F2PY consists of the following steps: * Creating the so-called signature file that contains descriptions of wrappers to Fortran or C functions, also called as signatures of the functions. In the case of Fortran routines, F2PY can create initial signature file by scanning Fortran source codes and catching all relevant information needed to create wrapper functions. * Optionally, F2PY created signature files can be edited to optimize wrappers functions, make them "smarter" and more "Pythonic". * F2PY reads a signature file and writes a Python C/API module containing Fortran/C/Python bindings. * F2PY compiles all sources and builds an extension module containing the wrappers. In building extension modules, F2PY uses ``numpy_distutils`` that supports a number of Fortran 77/90/95 compilers, including Gnu, Intel, Sun Fortre, SGI MIPSpro, Absoft, NAG, Compaq etc. compilers. Depending on a particular situation, these steps can be carried out either by just in one command or step-by-step, some steps can be ommited or combined with others. Below I'll describe three typical approaches of using F2PY. The following `example Fortran 77 code`__ will be used for illustration: .. include:: fib1.f :literal: __ fib1.f The quick way ============== The quickest way to wrap the Fortran subroutine ``FIB`` to Python is to run :: f2py -c fib1.f -m fib1 This command builds (see ``-c`` flag, execute ``f2py`` without arguments to see the explanation of command line options) an extension module ``fib1.so`` (see ``-m`` flag) to the current directory. Now, in Python the Fortran subroutine ``FIB`` is accessible via ``fib1.fib``:: >>> import Numeric >>> import fib1 >>> print fib1.fib.__doc__ fib - Function signature: fib(a,[n]) Required arguments: a : input rank-1 array('d') with bounds (n) Optional arguments: n := len(a) input int >>> a=Numeric.zeros(8,'d') >>> fib1.fib(a) >>> print a [ 0. 1. 1. 2. 3. 5. 8. 13.] .. topic:: Comments * Note that F2PY found that the second argument ``n`` is the dimension of the first array argument ``a``. Since by default all arguments are input-only arguments, F2PY concludes that ``n`` can be optional with the default value ``len(a)``. * One can use different values for optional ``n``:: >>> a1=Numeric.zeros(8,'d') >>> fib1.fib(a1,6) >>> print a1 [ 0. 1. 1. 2. 3. 5. 0. 0.] but an exception is raised when it is incompatible with the input array ``a``:: >>> fib1.fib(a,10) fib:n=10 Traceback (most recent call last): File "", line 1, in ? fib.error: (len(a)>=n) failed for 1st keyword n >>> This demonstrates one of the useful features in F2PY, that it, F2PY implements basic compatibility checks between related arguments in order to avoid any unexpected crashes. * When a Numeric array, that is Fortran contiguous and has a typecode corresponding to presumed Fortran type, is used as an input array argument, then its C pointer is directly passed to Fortran. Otherwise F2PY makes a contiguous copy (with a proper typecode) of the input array and passes C pointer of the copy to Fortran subroutine. As a result, any possible changes to the (copy of) input array have no effect to the original argument, as demonstrated below:: >>> a=Numeric.ones(8,'i') >>> fib1.fib(a) >>> print a [1 1 1 1 1 1 1 1] Clearly, this is not an expected behaviour. The fact that the above example worked with ``typecode='d'`` is considered accidental. F2PY provides ``intent(inplace)`` attribute that would modify the attributes of an input array so that any changes made by Fortran routine will be effective also in input argument. For example, if one specifies ``intent(inplace) a`` (see below, how), then the example above would read: >>> a=Numeric.ones(8,'i') >>> fib1.fib(a) >>> print a [ 0. 1. 1. 2. 3. 5. 8. 13.] However, the recommended way to get changes made by Fortran subroutine back to python is to use ``intent(out)`` attribute. It is more efficient and a cleaner solution. * The usage of ``fib1.fib`` in Python is very similar to using ``FIB`` in Fortran. However, using *in situ* output arguments in Python indicates a poor style as there is no safety mechanism in Python with respect to wrong argument types. When using Fortran or C, compilers naturally discover any type mismatches during compile time but in Python the types must be checked in runtime. So, using *in situ* output arguments in Python may cause difficult to find bugs, not to mention that the codes will be less readable when all required type checks are implemented. Though the demonstrated way of wrapping Fortran routines to Python is very straightforward, it has several drawbacks (see the comments above). These drawbacks are due to the fact that there is no way that F2PY can determine what is the acctual intention of one or the other argument, is it input or output argument, or both, or something else. So, F2PY conservatively assumes that all arguments are input arguments by default. However, there are ways (see below) how to "teach" F2PY about the true intentions (among other things) of function arguments; and then F2PY is able to generate more Pythonic (more explicit, easier to use, and less error prone) wrappers to Fortran functions. The smart way ============== Let's apply the steps of wrapping Fortran functions to Python one by one. * First, we create a signature file from ``fib1.f`` by running :: f2py fib1.f -m fib2 -h fib1.pyf The signature file is saved to ``fib1.pyf`` (see ``-h`` flag) and its contents is shown below. .. include:: fib1.pyf :literal: * Next, we'll teach F2PY that the argument ``n`` is a input argument (use ``intent(in)`` attribute) and that the result, i.e. the contents of ``a`` after calling Fortran function ``FIB``, should be returned to Python (use ``intent(out)`` attribute). In addition, an array ``a`` should be created dynamically using the size given by the input argument ``n`` (use ``depend(n)`` attribute to indicate dependence relation). The content of a modified version of ``fib1.pyf`` (saved as ``fib2.pyf``) is as follows: .. include:: fib2.pyf :literal: * And finally, we build the extension module by running :: f2py -c fib2.pyf fib1.f In Python:: >>> import fib2 >>> print fib2.fib.__doc__ fib - Function signature: a = fib(n) Required arguments: n : input int Return objects: a : rank-1 array('d') with bounds (n) >>> print fib2.fib(8) [ 0. 1. 1. 2. 3. 5. 8. 13.] .. topic:: Comments * Clearly, the signature of ``fib2.fib`` now corresponds to the intention of Fortran subroutine ``FIB`` more closely: given the number ``n``, ``fib2.fib`` returns the first ``n`` Fibonacci numbers as a Numeric array. Also, the new Python signature ``fib2.fib`` rules out any surprises that we experienced with ``fib1.fib``. * Note that by default using single ``intent(out)`` also implies ``intent(hide)``. Argument that has ``intent(hide)`` attribute specified, will not be listed in the argument list of a wrapper function. The quick and smart way ======================== The "smart way" of wrapping Fortran functions, as explained above, is suitable for wrapping (e.g. third party) Fortran codes for which modifications to their source codes are not desirable nor even possible. However, if editing Fortran codes is acceptable, then the generation of an intermediate signature file can be skipped in most cases. Namely, F2PY specific attributes can be inserted directly to Fortran source codes using the so-called F2PY directive. A F2PY directive defines special comment lines (starting with ``Cf2py``, for example) which are ignored by Fortran compilers but F2PY interprets them as normal lines. Here is shown a `modified version of the example Fortran code`__, saved as ``fib3.f``: .. include:: fib3.f :literal: __ fib3.f Building the extension module can be now carried out in one command:: f2py -c -m fib3 fib3.f Notice that the resulting wrapper to ``FIB`` is as "smart" as in previous case:: >>> import fib3 >>> print fib3.fib.__doc__ fib - Function signature: a = fib(n) Required arguments: n : input int Return objects: a : rank-1 array('d') with bounds (n) >>> print fib3.fib(8) [ 0. 1. 1. 2. 3. 5. 8. 13.] ================== Signature file ================== The syntax specification for signature files (.pyf files) is borrowed from the Fortran 90/95 language specification. Almost all Fortran 90/95 standard constructs are understood, both in free and fixed format (recall that Fortran 77 is a subset of Fortran 90/95). F2PY introduces also some extensions to Fortran 90/95 language specification that help designing Fortran to Python interface, make it more "Pythonic". Signature files may contain arbitrary Fortran code (so that Fortran codes can be considered as signature files). F2PY silently ignores Fortran constructs that are irrelevant for creating the interface. However, this includes also syntax errors. So, be careful not making ones;-). In general, the contents of signature files is case-sensitive. When scanning Fortran codes and writing a signature file, F2PY lowers all cases automatically except in multi-line blocks or when ``--no-lower`` option is used. The syntax of signature files is overvied below. Python module block ===================== A signature file may contain one (recommended) or more ``python module`` blocks. ``python module`` block describes the contents of a Python/C extension module ``module.c`` that F2PY generates. Exception: if ```` contains a substring ``__user__``, then the corresponding ``python module`` block describes the signatures of so-called call-back functions (see `Call-back arguments`_). A ``python module`` block has the following structure:: python module []... [ interface end [interface] ]... [ interface module [] [] end [module []] end [interface] ]... end [python module []] Here brackets ``[]`` indicate a optional part, dots ``...`` indicate one or more of a previous part. So, ``[]...`` reads zero or more of a previous part. Fortran/C routine signatures ============================= The signature of a Fortran routine has the following structure:: [] function | subroutine \ [ ( [] ) ] [ result ( ) ] [] [] [] [] [] end [ function | subroutine [] ] From a Fortran routine signature F2PY generates a Python/C extension function that has the following signature:: def ([,]): ... return The signature of a Fortran block data has the following structure:: block data [ ] [] [] [] [] [] end [ block data [] ] Type declarations ------------------- The definition of the ```` part is :: [ [] :: ] where :: := byte | character [] | complex [] | real [] | double complex | double precision | integer [] | logical [] := * | ( [len=] [ , [kind=] ] ) | ( kind= [ , len= ] ) := * | ( [kind=] ) := [ [ * ] [ ( ) ] | [ ( ) ] * ] | [ / / | = ] \ [ , ] and + ```` is a comma separated list of attributes_; + ```` is a comma separated list of dimension bounds; + ```` is a `C expression`__. + ```` may be negative integer for ``integer`` type specifications. In such cases ``integer*`` represents unsigned C integers. __ `C expressions`_ If an argument has no ````, its type is determined by applying ``implicit`` rules to its name. Statements ------------ Attribute statements: The ```` is ```` without ````. In addition, in an attribute statement one cannot use other attributes, also ```` can be only a list of names. Use statements: The definition of the ```` part is :: use [ , | , ONLY : ] where :: := => [ , ] Currently F2PY uses ``use`` statement only for linking call-back modules and ``external`` arguments (call-back functions), see `Call-back arguments`_. Common block statements: The definition of the ```` part is :: common / / where :: := [ ( ) ] [ , ] One ``python module`` block should not contain two or more ``common`` blocks with the same name. Otherwise, the latter ones are ignored. The types of variables in ```` are defined using ````. Note that the corresponding ```` may contain array specifications; then you don't need to specify these in ````. Other statements: The ```` part refers to any other Fortran language constructs that are not described above. F2PY ignores most of them except + ``call`` statements and function calls of ``external`` arguments (`more details`__?); __ external_ + ``include`` statements :: include '' include "" If a file ```` does not exist, the ``include`` statement is ignored. Otherwise, the file ```` is included to a signature file. ``include`` statements can be used in any part of a signature file, also outside the Fortran/C routine signature blocks. + ``implicit`` statements :: implicit none implicit where :: := ( ) Implicit rules are used to deterimine the type specification of a variable (from the first-letter of its name) if the variable is not defined using ````. Default implicit rule is given by :: implicit real (a-h,o-z,$_), integer (i-m) + ``entry`` statements :: entry [([])] F2PY generates wrappers to all entry names using the signature of the routine block. Tip: ``entry`` statement can be used to describe the signature of an arbitrary routine allowing F2PY to generate a number of wrappers from only one routine block signature. There are few restrictions while doing this: ``fortranname`` cannot be used, ``callstatement`` and ``callprotoargument`` can be used only if they are valid for all entry routines, etc. In addition, F2PY introduces the following statements: + ``threadsafe`` Use ``Py_BEGIN_ALLOW_THREADS .. Py_END_ALLOW_THREADS`` block around the call to Fortran/C function. + ``callstatement `` Replace F2PY generated call statement to Fortran/C function with ````. The wrapped Fortran/C function is available as ``(*f2py_func)``. To raise an exception, set ``f2py_success = 0`` in ````. + ``callprotoargument `` When ``callstatement`` statement is used then F2PY may not generate proper prototypes for Fortran/C functions (because ```` may contain any function calls and F2PY has no way to determine what should be the proper prototype). With this statement you can explicitely specify the arguments of the corresponding prototype:: extern FUNC_F(,)(); + ``fortranname []`` You can use arbitrary ```` for a given Fortran/C function. Then you have to specify ```` with this statement. If ``fortranname`` statement is used without ```` then a dummy wrapper is generated. + ``usercode `` When used inside ``python module`` block, then given C code will be inserted to generated C/API source just before wrapper function definitions. Here you can define arbitrary C functions to be used in initialization of optional arguments, for example. If ``usercode`` is used twise inside ``python module`` block then the second multi-line block is inserted after the definition of external routines. When used inside ````, then given C code will be inserted to the corresponding wrapper function just after declaring variables but before any C statements. So, ``usercode`` follow-up can contain both declarations and C statements. When used inside the first ``interface`` block, then given C code will be inserted at the end of the initialization function of the extension module. Here you can modify extension modules dictionary. For example, for defining additional variables etc. + ``pymethoddef `` Multiline block will be inserted to the definition of module methods ``PyMethodDef``-array. It must be a comma-separated list of C arrays (see `Extending and Embedding`__ Python documentation for details). ``pymethoddef`` statement can be used only inside ``python module`` block. __ http://www.python.org/doc/current/ext/ext.html Attributes ------------ The following attributes are used by F2PY: ``optional`` The corresponding argument is moved to the end of ```` list. A default value for an optional argument can be specified ````, see ``entitydecl`` definition. Note that the default value must be given as a valid C expression. Note that whenever ```` is used, ``optional`` attribute is set automatically by F2PY. For an optional array argument, all its dimensions must be bounded. ``required`` The corresponding argument is considered as a required one. This is default. You need to specify ``required`` only if there is a need to disable automatic ``optional`` setting when ```` is used. If Python ``None`` object is used as an required argument, the argument is treated as optional. That is, in the case of array argument, the memory is allocated. And if ```` is given, the corresponding initialization is carried out. ``dimension()`` The corresponding variable is considered as an array with given dimensions in ````. ``intent()`` This specifies the "intention" of the corresponding argument. ```` is a comma separated list of the following keys: + ``in`` The argument is considered as an input-only argument. It means that the value of the argument is passed to Fortran/C function and that function is expected not to change the value of an argument. + ``inout`` The argument is considered as an input/output or *in situ* output argument. ``intent(inout)`` arguments can be only "contiguous" Numeric arrays with proper type and size. Here "contiguous" can be either in Fortran or C sense. The latter one coincides with the contiguous concept used in Numeric and is effective only if ``intent(c)`` is used. Fortran-contiguousness is assumed by default. Using ``intent(inout)`` is generally not recommended, use ``intent(in,out)`` instead. See also ``intent(inplace)`` attribute. + ``inplace`` The argument is considered as an input/output or *in situ* output argument. ``intent(inplace)`` arguments must be Numeric arrays with proper size. If the type of an array is not "proper" or the array is non-contiguous then the array will be changed in-place to fix the type and make it contiguous. Using ``intent(inplace)`` is generally not recommended either. For example, when slices have been taken from an ``intent(inplace)`` argument then after in-place changes, slices data pointers may point to unallocated memory area. + ``out`` The argument is considered as an return variable. It is appended to the ```` list. Using ``intent(out)`` sets ``intent(hide)`` automatically, unless also ``intent(in)`` or ``intent(inout)`` were used. By default, returned multidimensional arrays are Fortran-contiguous. If ``intent(c)`` is used, then returned multi-dimensional arrays are C-contiguous. + ``hide`` The argument is removed from the list of required or optional arguments. Typically ``intent(hide)`` is used with ``intent(out)`` or when ```` completely determines the value of the argument like in the following example:: integer intent(hide),depend(a) :: n = len(a) real intent(in),dimension(n) :: a + ``c`` The argument is treated as a C scalar or C array argument. In the case of a scalar argument, its value is passed to C function as a C scalar argument (recall that Fortran scalar arguments are actually C pointer arguments). In the case of an array argument, the wrapper function is assumed to treat multi-dimensional arrays as C-contiguous arrays. There is no need to use ``intent(c)`` for one-dimensional arrays, no matter if the wrapped function is either a Fortran or a C function. This is because the concepts of Fortran- and C-contiguousness overlap in one-dimensional cases. If ``intent(c)`` is used as an statement but without entity declaration list, then F2PY adds ``intent(c)`` attibute to all arguments. Also, when wrapping C functions, one must use ``intent(c)`` attribute for ```` in order to disable Fortran specific ``F_FUNC(..,..)`` macros. + ``cache`` The argument is treated as a junk of memory. No Fortran nor C contiguousness checks are carried out. Using ``intent(cache)`` makes sense only for array arguments, also in connection with ``intent(hide)`` or ``optional`` attributes. + ``copy`` Ensure that the original contents of ``intent(in)`` argument is preserved. Typically used in connection with ``intent(in,out)`` attribute. F2PY creates an optional argument ``overwrite_`` with the default value ``0``. + ``overwrite`` The original contents of the ``intent(in)`` argument may be altered by the Fortran/C function. F2PY creates an optional argument ``overwrite_`` with the default value ``1``. + ``out=`` Replace the return name with ```` in the ``__doc__`` string of a wrapper function. + ``callback`` Construct an external function suitable for calling Python function from Fortran. ``intent(callback)`` must be specified before the corresponding ``external`` statement. If 'argument' is not in argument list then it will be added to Python wrapper but only initializing external function. Use ``intent(callback)`` in situations where a Fortran/C code assumes that a user implements a function with given prototype and links it to an executable. Don't use ``intent(callback)`` if function appears in the argument list of a Fortran routine. With ``intent(hide)`` or ``optional`` attributes specified and using a wrapper function without specifying the callback argument in argument list then call-back function is looked in the namespace of F2PY generated extension module where it can be set as a module attribute by a user. + ``aux`` Define auxiliary C variable in F2PY generated wrapper function. Useful to save parameter values so that they can be accessed in initialization expression of other variables. Note that ``intent(aux)`` silently implies ``intent(c)``. The following rules apply: + If no ``intent(in | inout | out | hide)`` is specified, ``intent(in)`` is assumed. + ``intent(in,inout)`` is ``intent(in)``. + ``intent(in,hide)`` or ``intent(inout,hide)`` is ``intent(hide)``. + ``intent(out)`` is ``intent(out,hide)`` unless ``intent(in)`` or ``intent(inout)`` is specified. + If ``intent(copy)`` or ``intent(overwrite)`` is used, then an additional optional argument is introduced with a name ``overwrite_`` and a default value 0 or 1, respectively. + ``intent(inout,inplace)`` is ``intent(inplace)``. + ``intent(in,inplace)`` is ``intent(inplace)``. + ``intent(hide)`` disables ``optional`` and ``required``. ``check([])`` Perform consistency check of arguments by evaluating ````; if ```` returns 0, an exception is raised. If ``check(..)`` is not used then F2PY generates few standard checks (e.g. in a case of an array argument, check for the proper shape and size) automatically. Use ``check()`` to disable checks generated by F2PY. ``depend([])`` This declares that the corresponding argument depends on the values of variables in the list ````. For example, ```` may use the values of other arguments. Using information given by ``depend(..)`` attributes, F2PY ensures that arguments are initialized in a proper order. If ``depend(..)`` attribute is not used then F2PY determines dependence relations automatically. Use ``depend()`` to disable dependence relations generated by F2PY. When you edit dependence relations that were initially generated by F2PY, be careful not to break the dependence relations of other relevant variables. Another thing to watch out is cyclic dependencies. F2PY is able to detect cyclic dependencies when constructing wrappers and it complains if any are found. ``allocatable`` The corresponding variable is Fortran 90 allocatable array defined as Fortran 90 module data. .. _external: ``external`` The corresponding argument is a function provided by user. The signature of this so-called call-back function can be defined - in ``__user__`` module block, - or by demonstrative (or real, if the signature file is a real Fortran code) call in the ```` block. For example, F2PY generates from :: external cb_sub, cb_fun integer n real a(n),r call cb_sub(a,n) r = cb_fun(4) the following call-back signatures:: subroutine cb_sub(a,n) real dimension(n) :: a integer optional,check(len(a)>=n),depend(a) :: n=len(a) end subroutine cb_sub function cb_fun(e_4_e) result (r) integer :: e_4_e real :: r end function cb_fun The corresponding user-provided Python function are then:: def cb_sub(a,[n]): ... return def cb_fun(e_4_e): ... return r See also ``intent(callback)`` attribute. ``parameter`` The corresponding variable is a parameter and it must have a fixed value. F2PY replaces all parameter occurrences by their corresponding values. Extensions ============ F2PY directives ----------------- The so-called F2PY directives allow using F2PY signature file constructs also in Fortran 77/90 source codes. With this feature you can skip (almost) completely intermediate signature file generations and apply F2PY directly to Fortran source codes. F2PY directive has the following form:: f2py ... where allowed comment characters for fixed and free format Fortran codes are ``cC*!#`` and ``!``, respectively. Everything that follows ``f2py`` is ignored by a compiler but read by F2PY as a normal Fortran (non-comment) line: When F2PY finds a line with F2PY directive, the directive is first replaced by 5 spaces and then the line is reread. For fixed format Fortran codes, ```` must be at the first column of a file, of course. For free format Fortran codes, F2PY directives can appear anywhere in a file. C expressions -------------- C expressions are used in the following parts of signature files: * ```` of variable initialization; * ```` of the ``check`` attribute; * `` of the ``dimension`` attribute; * ``callstatement`` statement, here also a C multi-line block can be used. A C expression may contain: * standard C constructs; * functions from ``math.h`` and ``Python.h``; * variables from the argument list, presumably initialized before according to given dependence relations; * the following CPP macros: ``rank()`` Returns the rank of an array ````. ``shape(,)`` Returns the ````-th dimension of an array ````. ``len()`` Returns the lenght of an array ````. ``size()`` Returns the size of an array ````. ``slen()`` Returns the length of a string ````. For initializing an array ````, F2PY generates a loop over all indices and dimensions that executes the following pseudo-statement:: (_i[0],_i[1],...) = ; where ``_i[]`` refers to the ````-th index value and that runs from ``0`` to ``shape(,)-1``. For example, a function ``myrange(n)`` generated from the following signature :: subroutine myrange(a,n) fortranname ! myrange is a dummy wrapper integer intent(in) :: n real*8 intent(c,out),dimension(n),depend(n) :: a = _i[0] end subroutine myrange is equivalent to ``Numeric.arange(n,typecode='d')``. .. topic:: Warning! F2PY may lower cases also in C expressions when scanning Fortran codes (see ``--[no]-lower`` option). Multi-line blocks ------------------ A multi-line block starts with ``'''`` (triple single-quotes) and ends with ``'''`` in some *strictly* subsequent line. Multi-line blocks can be used only within .pyf files. The contents of a multi-line block can be arbitrary (except that it cannot contain ``'''``) and no transformations (e.g. lowering cases) are applied to it. Currently, multi-line blocks can be used in the following constructs: + as a C expression of the ``callstatement`` statement; + as a C type specification of the ``callprotoargument`` statement; + as a C code block of the ``usercode`` statement; + as a list of C arrays of the ``pymethoddef`` statement; + as documentation string. ================================== Using F2PY bindings in Python ================================== All wrappers (to Fortran/C routines or to common blocks or to Fortran 90 module data) generated by F2PY are exposed to Python as ``fortran`` type objects. Routine wrappers are callable ``fortran`` type objects while wrappers to Fortran data have attributes referring to data objects. All ``fortran`` type object have attribute ``_cpointer`` that contains CObject referring to the C pointer of the corresponding Fortran/C function or variable in C level. Such CObjects can be used as an callback argument of F2PY generated functions to bypass Python C/API layer of calling Python functions from Fortran or C when the computational part of such functions is implemented in C or Fortran and wrapped with F2PY (or any other tool capable of providing CObject of a function). .. topic:: Example Consider a `Fortran 77 file`__ ``ftype.f``: .. include:: ftype.f :literal: and build a wrapper using:: f2py -c ftype.f -m ftype __ ftype.f In Python: .. include:: ftype_session.dat :literal: Scalar arguments ================= In general, a scalar argument of a F2PY generated wrapper function can be ordinary Python scalar (integer, float, complex number) as well as an arbitrary sequence object (list, tuple, array, string) of scalars. In the latter case, the first element of the sequence object is passed to Fortran routine as a scalar argument. Note that when type-casting is required and there is possible loss of information (e.g. when type-casting float to integer or complex to float), F2PY does not raise any exception. In complex to real type-casting only the real part of a complex number is used. ``intent(inout)`` scalar arguments are assumed to be array objects in order to *in situ* changes to be effective. It is recommended to use arrays with proper type but also other types work. .. topic:: Example Consider the following `Fortran 77 code`__: .. include:: scalar.f :literal: and wrap it using ``f2py -c -m scalar scalar.f``. __ scalar.f In Python: .. include:: scalar_session.dat :literal: String arguments ================= F2PY generated wrapper functions accept (almost) any Python object as a string argument, ``str`` is applied for non-string objects. Exceptions are Numeric arrays that must have type code ``'c'`` or ``'1'`` when used as string arguments. A string can have arbitrary length when using it as a string argument to F2PY generated wrapper function. If the length is greater than expected, the string is truncated. If the length is smaller that expected, additional memory is allocated and filled with ``\0``. Because Python strings are immutable, an ``intent(inout)`` argument expects an array version of a string in order to *in situ* changes to be effective. .. topic:: Example Consider the following `Fortran 77 code`__: .. include:: string.f :literal: and wrap it using ``f2py -c -m mystring string.f``. __ string.f Python session: .. include:: string_session.dat :literal: Array arguments ================ In general, array arguments of F2PY generated wrapper functions accept arbitrary sequences that can be transformed to Numeric array objects. An exception is ``intent(inout)`` array arguments that always must be proper-contiguous and have proper type, otherwise an exception is raised. Another exception is ``intent(inplace)`` array arguments that attributes will be changed in-situ if the argument has different type than expected (see ``intent(inplace)`` attribute for more information). In general, if a Numeric array is proper-contiguous and has a proper type then it is directly passed to wrapped Fortran/C function. Otherwise, an element-wise copy of an input array is made and the copy, being proper-contiguous and with proper type, is used as an array argument. There are two types of proper-contiguous Numeric arrays: * Fortran-contiguous arrays when data is stored column-wise, i.e. indexing of data as stored in memory starts from the lowest dimension; * C-contiguous or simply contiguous arrays when data is stored row-wise, i.e. indexing of data as stored in memory starts from the highest dimension. For one-dimensional arrays these notions coincide. For example, an 2x2 array ``A`` is Fortran-contiguous if its elements are stored in memory in the following order:: A[0,0] A[1,0] A[0,1] A[1,1] and C-contiguous if the order is as follows:: A[0,0] A[0,1] A[1,0] A[1,1] To test whether an array is C-contiguous, use ``.iscontiguous()`` method of Numeric arrays. To test for Fortran-contiguousness, all F2PY generated extension modules provide a function ``has_column_major_storage()``. This function is equivalent to ``Numeric.transpose().iscontiguous()`` but more efficient. Usually there is no need to worry about how the arrays are stored in memory and whether the wrapped functions, being either Fortran or C functions, assume one or another storage order. F2PY automatically ensures that wrapped functions get arguments with proper storage order; the corresponding algorithm is designed to make copies of arrays only when absolutely necessary. However, when dealing with very large multi-dimensional input arrays with sizes close to the size of the physical memory in your computer, then a care must be taken to use always proper-contiguous and proper type arguments. To transform input arrays to column major storage order before passing them to Fortran routines, use a function ``as_column_major_storage()`` that is provided by all F2PY generated extension modules. .. topic:: Example Consider `Fortran 77 code`__: .. include:: array.f :literal: and wrap it using ``f2py -c -m arr array.f -DF2PY_REPORT_ON_ARRAY_COPY=1``. __ array.f In Python: .. include:: array_session.dat :literal: Call-back arguments ==================== F2PY supports calling Python functions from Fortran or C codes. .. topic:: Example Consider the following `Fortran 77 code`__ .. include:: callback.f :literal: and wrap it using ``f2py -c -m callback callback.f``. __ callback.f In Python: .. include:: callback_session.dat :literal: In the above example F2PY was able to guess accurately the signature of a call-back function. However, sometimes F2PY cannot establish the signature as one would wish and then the signature of a call-back function must be modified in the signature file manually. Namely, signature files may contain special modules (the names of such modules contain a substring ``__user__``) that collect various signatures of call-back functions. Callback arguments in routine signatures have attribute ``external`` (see also ``intent(callback)`` attribute). To relate a callback argument and its signature in ``__user__`` module block, use ``use`` statement as illustrated below. The same signature of a callback argument can be referred in different routine signatures. .. topic:: Example We use the same `Fortran 77 code`__ as in previous example but now we'll pretend that F2PY was not able to guess the signatures of call-back arguments correctly. First, we create an initial signature file ``callback2.pyf`` using F2PY:: f2py -m callback2 -h callback2.pyf callback.f Then modify it as follows .. include:: callback2.pyf :literal: Finally, build the extension module using:: f2py -c callback2.pyf callback.f An example Python session would be identical to the previous example except that argument names would differ. __ callback.f Sometimes a Fortran package may require that users provide routines that the package will use. F2PY can construct an interface to such routines so that Python functions could be called from Fortran. .. topic:: Example Consider the following `Fortran 77 subroutine`__ that takes an array and applies a function ``func`` to its elements. .. include:: calculate.f :literal: __ calculate.f It is expected that function ``func`` has been defined externally. In order to use a Python function as ``func``, it must have an attribute ``intent(callback)`` (it must be specified before the ``external`` statement). Finally, build an extension module using:: f2py -c -m foo calculate.f In Python: .. include:: calculate_session.dat :literal: The function is included as an argument to the python function call to the FORTRAN subroutine eventhough it was NOT in the FORTRAN subroutine argument list. The "external" refers to the C function generated by f2py, not the python function itself. The python function must be supplied to the C function. The callback function may also be explicitly set in the module. Then it is not necessary to pass the function in the argument list to the FORTRAN function. This may be desired if the FORTRAN function calling the python callback function is itself called by another FORTRAN function. .. topic:: Example Consider the following `Fortran 77 subroutine`__. .. include:: extcallback.f :literal: __ extcallback.f and wrap it using ``f2py -c -m pfromf extcallback.f``. In Python: .. include:: extcallback_session.dat :literal: Resolving arguments to call-back functions ------------------------------------------ F2PY generated interface is very flexible with respect to call-back arguments. For each call-back argument an additional optional argument ``_extra_args`` is introduced by F2PY. This argument can be used to pass extra arguments to user provided call-back arguments. If a F2PY generated wrapper function expects the following call-back argument:: def fun(a_1,...,a_n): ... return x_1,...,x_k but the following Python function :: def gun(b_1,...,b_m): ... return y_1,...,y_l is provided by an user, and in addition, :: fun_extra_args = (e_1,...,e_p) is used, then the following rules are applied when a Fortran or C function calls the call-back argument ``gun``: * If ``p==0`` then ``gun(a_1,...,a_q)`` is called, here ``q=min(m,n)``. * If ``n+p<=m`` then ``gun(a_1,...,a_n,e_1,...,e_p)`` is called. * If ``p<=mm`` then ``gun(e_1,...,e_m)`` is called. * If ``n+p`` is less than the number of required arguments to ``gun`` then an exception is raised. The function ``gun`` may return any number of objects as a tuple. Then following rules are applied: * If ``kl``, then only ``x_1,...,x_l`` are set. Common blocks ============== F2PY generates wrappers to ``common`` blocks defined in a routine signature block. Common blocks are visible by all Fortran codes linked with the current extension module, but not to other extension modules (this restriction is due to how Python imports shared libraries). In Python, the F2PY wrappers to ``common`` blocks are ``fortran`` type objects that have (dynamic) attributes related to data members of common blocks. When accessed, these attributes return as Numeric array objects (multi-dimensional arrays are Fortran-contiguous) that directly link to data members in common blocks. Data members can be changed by direct assignment or by in-place changes to the corresponding array objects. .. topic:: Example Consider the following `Fortran 77 code`__ .. include:: common.f :literal: and wrap it using ``f2py -c -m common common.f``. __ common.f In Python: .. include:: common_session.dat :literal: Fortran 90 module data ======================= The F2PY interface to Fortran 90 module data is similar to Fortran 77 common blocks. .. topic:: Example Consider the following `Fortran 90 code`__ .. include:: moddata.f90 :literal: and wrap it using ``f2py -c -m moddata moddata.f90``. __ moddata.f90 In Python: .. include:: moddata_session.dat :literal: Allocatable arrays ------------------- F2PY has basic support for Fortran 90 module allocatable arrays. .. topic:: Example Consider the following `Fortran 90 code`__ .. include:: allocarr.f90 :literal: and wrap it using ``f2py -c -m allocarr allocarr.f90``. __ allocarr.f90 In Python: .. include:: allocarr_session.dat :literal: =========== Using F2PY =========== F2PY can be used either as a command line tool ``f2py`` or as a Python module ``f2py2e``. Command ``f2py`` ================= When used as a command line tool, ``f2py`` has three major modes, distinguished by the usage of ``-c`` and ``-h`` switches: 1. To scan Fortran sources and generate a signature file, use :: f2py -h \ [[ only: : ] \ [ skip: : ]]... \ [ ...] Note that a Fortran source file can contain many routines, and not necessarily all routines are needed to be used from Python. So, you can either specify which routines should be wrapped (in ``only: .. :`` part) or which routines F2PY should ignored (in ``skip: .. :`` part). If ```` is specified as ``stdout`` then signatures are send to standard output instead of a file. Among other options (see below), the following options can be used in this mode: ``--overwrite-signature`` Overwrite existing signature file. 2. To construct an extension module, use :: f2py \ [[ only: : ] \ [ skip: : ]]... \ [ ...] The constructed extension module is saved as ``module.c`` to the current directory. Here ```` may also contain signature files. Among other options (see below), the following options can be used in this mode: ``--debug-capi`` Add debugging hooks to the extension module. When using this extension module, various information about the wrapper is printed to standard output, for example, the values of variables, the steps taken, etc. ``-include''`` Add a CPP ``#include`` statement to the extension module source. ```` should be given in one of the following forms:: "filename.ext" The include statement is inserted just before the wrapper functions. This feature enables using arbitrary C functions (defined in ````) in F2PY generated wrappers. This option is deprecated. Use ``usercode`` statement to specify C codelets directly in signature filess ``--[no-]wrap-functions`` Create Fortran subroutine wrappers to Fortran functions. ``--wrap-functions`` is default because it ensures maximum portability and compiler independence. ``--include-paths ::..`` Search include files from given directories. ``--help-link []`` List system resources found by ``numpy_distutils/system_info.py``. For example, try ``f2py --help-link lapack_opt``. 3. To build an extension module, use :: f2py -c \ [[ only: : ] \ [ skip: : ]]... \ [ ] [ <.o, .a, .so files> ] If ```` contains a signature file, then a source for an extension module is constructed, all Fortran and C sources are compiled, and finally all object and library files are linked to the extension module ``.so`` which is saved into the current directory. If ```` does not contain a signature file, then an extension module is constructed by scanning all Fortran source codes for routine signatures. Among other options (see below) and options described in previous mode, the following options can be used in this mode: ``--help-fcompiler`` List available Fortran compilers. ``--help-compiler`` [depreciated] List available Fortran compilers. ``--fcompiler=`` Specify Fortran compiler type by vendor. ``--f77exec=`` Specify the path to F77 compiler ``--fcompiler-exec=`` [depreciated] Specify the path to F77 compiler ``--f90exec=`` Specify the path to F90 compiler ``--f90compiler-exec=`` [depreciated] Specify the path to F90 compiler ``--f77flags=`` Specify F77 compiler flags ``--f90flags=`` Specify F90 compiler flags ``--opt=`` Specify optimization flags ``--arch=`` Specify architecture specific optimization flags ``--noopt`` Compile without optimization ``--noarch`` Compile without arch-dependent optimization ``--debug`` Compile with debugging information ``-l`` Use the library ```` when linking. ``-D[=]`` Define macro ```` as ````. ``-U`` Define macro ```` ``-I`` Append directory ```` to the list of directories searched for include files. ``-L`` Add directory ```` to the list of directories to be searched for ``-l``. ``link-`` Link extension module with as defined by ``numpy_distutils/system_info.py``. E.g. to link with optimized LAPACK libraries (vecLib on MacOSX, ATLAS elsewhere), use ``--link-lapack_opt``. See also ``--help-link`` switch. When building an extension module, a combination of the following macros may be required for non-gcc Fortran compilers:: -DPREPEND_FORTRAN -DNO_APPEND_FORTRAN -DUPPERCASE_FORTRAN To test the performance of F2PY generated interfaces, use ``-DF2PY_REPORT_ATEXIT``. Then a report of various timings is printed out at the exit of Python. This feature may not work on all platforms, currently only Linux platform is supported. To see whether F2PY generated interface performs copies of array arguments, use ``-DF2PY_REPORT_ON_ARRAY_COPY=``. When the size of an array argument is larger than ````, a message about the coping is sent to ``stderr``. Other options: ``-m `` Name of an extension module. Default is ``untitled``. Don't use this option if a signature file (*.pyf) is used. ``--[no-]lower`` Do [not] lower the cases in ````. By default, ``--lower`` is assumed with ``-h`` switch, and ``--no-lower`` without the ``-h`` switch. ``--build-dir `` All F2PY generated files are created in ````. Default is ``tempfile.mktemp()``. ``--quiet`` Run quietly. ``--verbose`` Run with extra verbosity. ``-v`` Print f2py version ID and exit. Execute ``f2py`` without any options to get an up-to-date list of available options. Python module ``f2py2e`` ========================= .. topic:: Warning The current Python interface to ``f2py2e`` module is not mature and may change in future depending on users needs. The following functions are provided by the ``f2py2e`` module: ``run_main()`` Equivalent to running:: f2py where ``=string.join(,' ')``, but in Python. Unless ``-h`` is used, this function returns a dictionary containing information on generated modules and their dependencies on source files. For example, the command ``f2py -m scalar scalar.f`` can be executed from Python as follows .. include:: run_main_session.dat :literal: You cannot build extension modules with this function, that is, using ``-c`` is not allowed. Use ``compile`` command instead, see below. ``compile(source, modulename='untitled', extra_args='', verbose=1, source_fn=None)`` Build extension module from Fortran 77 source string ``source``. Return 0 if successful. Note that this function actually calls ``f2py -c ..`` from shell to ensure safety of the current Python process. For example, .. include:: compile_session.dat :literal: ========================== Using ``numpy_distutils`` ========================== ``numpy_distutils`` is part of the SciPy_ project and aims to extend standard Python ``distutils`` to deal with Fortran sources and F2PY signature files, e.g. compile Fortran sources, call F2PY to construct extension modules, etc. .. topic:: Example Consider the following `setup file`__: .. include:: setup_example.py :literal: Running :: python setup_example.py build will build two extension modules ``scalar`` and ``fib2`` to the build directory. __ setup_example.py ``numpy_distutils`` extends ``distutils`` with the following features: * ``Extension`` class argument ``sources`` may contain Fortran source files. In addition, the list ``sources`` may contain at most one F2PY signature file, and then the name of an Extension module must match with the ```` used in signature file. It is assumed that an F2PY signature file contains exactly one ``python module`` block. If ``sources`` does not contain a signature files, then F2PY is used to scan Fortran source files for routine signatures to construct the wrappers to Fortran codes. Additional options to F2PY process can be given using ``Extension`` class argument ``f2py_options``. ``numpy_distutils`` 0.2.2 and up ================================ * The following new ``distutils`` commands are defined: ``build_src`` to construct Fortran wrapper extension modules, among many other things. ``config_fc`` to change Fortran compiler options as well as ``build_ext`` and ``build_clib`` commands are enhanced to support Fortran sources. Run :: python config_fc build_src build_ext --help to see available options for these commands. * When building Python packages containing Fortran sources, then one can choose different Fortran compilers by using ``build_ext`` command option ``--fcompiler=``. Here ```` can be one of the following names:: absoft sun mips intel intelv intele intelev nag compaq compaqv gnu vast pg hpux See ``numpy_distutils/fcompiler.py`` for up-to-date list of supported compilers or run :: f2py -c --help-fcompiler ``numpy_distutils`` pre 0.2.2 ============================= * The following new ``distutils`` commands are defined: ``build_flib`` to build f77/f90 libraries used by Python extensions; ``run_f2py`` to construct Fortran wrapper extension modules. Run :: python build_flib run_f2py --help to see available options for these commands. * When building Python packages containing Fortran sources, then one can choose different Fortran compilers either by using ``build_flib`` command option ``--fcompiler=`` or by defining environment variable ``FC_VENDOR=``. Here ```` can be one of the following names:: Absoft Sun SGI Intel Itanium NAG Compaq Digital Gnu VAST PG See ``numpy_distutils/command/build_flib.py`` for up-to-date list of supported compilers. ====================== Extended F2PY usages ====================== Adding self-written functions to F2PY generated modules ======================================================= Self-written Python C/API functions can be defined inside signature files using ``usercode`` and ``pymethoddef`` statements (they must be used inside the ``python module`` block). For example, the following signature file ``spam.pyf`` .. include:: spam.pyf :literal: wraps the C library function ``system()``:: f2py -c spam.pyf In Python: .. include:: spam_session.dat :literal: Modifying the dictionary of a F2PY generated module =================================================== The following example illustrates how to add an user-defined variables to a F2PY generated extension module. Given the following signature file .. include:: var.pyf :literal: compile it as ``f2py -c var.pyf``. Notice that the second ``usercode`` statement must be defined inside an ``interface`` block and where the module dictionary is available through the variable ``d`` (see ``f2py var.pyf``-generated ``varmodule.c`` for additional details). In Python: .. include:: var_session.dat :literal: .. References ========== .. _F2PY: http://cens.ioc.ee/projects/f2py2e/ .. _Python: http://www.python.org/ .. _NumPy: http://www.numpy.org/ .. _SciPy: http://www.numpy.org/