diff options
author | Pauli Virtanen <pav@iki.fi> | 2014-01-02 22:41:27 +0200 |
---|---|---|
committer | Pauli Virtanen <pav@iki.fi> | 2014-01-02 22:41:27 +0200 |
commit | 337366c6d512b47e6a702d18a3f3f6240c3fda4a (patch) | |
tree | cf9affed706e98fe8731032c37895ab6c3e39737 /doc/source/f2py/python-usage.rst | |
parent | 5bcfbe92fd7fa5db67ba0fc06a1e63a806c33127 (diff) | |
download | numpy-337366c6d512b47e6a702d18a3f3f6240c3fda4a.tar.gz |
DOC: split up f2py user guide + markup fixes
Diffstat (limited to 'doc/source/f2py/python-usage.rst')
-rw-r--r-- | doc/source/f2py/python-usage.rst | 419 |
1 files changed, 419 insertions, 0 deletions
diff --git a/doc/source/f2py/python-usage.rst b/doc/source/f2py/python-usage.rst new file mode 100644 index 000000000..24ec3f15d --- /dev/null +++ b/doc/source/f2py/python-usage.rst @@ -0,0 +1,419 @@ +================================== +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). + +.. 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. + +.. 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. + +.. 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(<array>)``. This function is equivalent to +``Numeric.transpose(<array>).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(<array>)`` that is provided by all F2PY +generated extension modules. + +.. 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: + +Call-back arguments +==================== + +F2PY supports calling Python functions from Fortran or C codes. + + +.. 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. + +.. 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. + +.. 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. + +.. 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 ``<name>_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<=m<n+p`` then ``gun(a_1,...,a_q,e_1,...,e_p)`` is called, here + ``q=m-p``. +* If ``p>m`` 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 ``k<l``, then ``y_{k+1},...,y_l`` are ignored. +* If ``k>l``, 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. + +.. 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. + +.. 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. + +.. 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: |