==================================
Using F2PY bindings in Python
==================================

All wrappers for Fortran/C routines, common blocks, or for 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).

Consider a Fortran 77 file ``ftype.f``:

  .. include:: ftype.f
     :literal:

and build a wrapper using ``f2py -c ftype.f -m ftype``.

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.

Consider the following Fortran 77 code:

  .. include:: scalar.f
     :literal:

and wrap it using ``f2py -c -m scalar 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 Numpy 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.

Consider the following Fortran 77 code:

  .. include:: string.f
     :literal:

and wrap it using ``f2py -c -m mystring 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 Numpy 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 Numpy 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 Numpy 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 Numpy arrays.  To test for Fortran contiguity, all
F2PY generated extension modules provide a function
``has_column_major_storage(<array>)``. This function is equivalent to
``<array>.flags.f_contiguous`` 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 multidimensional 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.

Consider Fortran 77 code:

  .. include:: array.f
     :literal:

and wrap it using ``f2py -c -m arr array.f -DF2PY_REPORT_ON_ARRAY_COPY=1``.

In Python:

  .. include:: array_session.dat
     :literal:

.. _Call-back arguments:

Call-back arguments
====================

F2PY supports calling Python functions from Fortran or C codes.

Consider the following Fortran 77 code:

  .. include:: callback.f
     :literal:

and wrap it using ``f2py -c -m callback 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.

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.

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.

Consider the following `Fortran 77 subroutine`__ that takes an array
and applies a function ``func`` to its elements.

  .. include:: calculate.f
     :literal:

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 even though 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.

Consider the following Fortran 77 subroutine:

  .. include:: extcallback.f
     :literal:

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 Numpy array
objects (multidimensional 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.

Consider the following Fortran 77 code:

  .. include:: common.f
     :literal:

and wrap it using ``f2py -c -m common 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.

Consider the following Fortran 90 code:

  .. include:: moddata.f90
     :literal:

and wrap it using ``f2py -c -m moddata moddata.f90``.

In Python:

  .. include:: moddata_session.dat
     :literal:


Allocatable arrays
-------------------

F2PY has basic support for Fortran 90 module allocatable arrays.

Consider the following Fortran 90 code:

  .. include:: allocarr.f90
     :literal:

and wrap it using ``f2py -c -m allocarr allocarr.f90``.

In Python:

  .. include:: allocarr_session.dat
     :literal:
