13.12. C and Fortran Bindings
The C and Fortran (mpi_f08) bindings are generated from Python code in
ompi/mpi/bindings
. Both the language bindings are generated from
template files for each function. In the C case, each template file corresponds
to a single generated C file, while in the Fortran case there are three major
files generated for all functions.
The Python code depends on special prototype lines used with both the C and Fortran bindings. These “prototypes” are designed to be easy to parse and use specific type constants that can be mapped directly to the expanded language-specific code, error-handling, and conversion code.
13.12.1. C Bindings
This will walk through adding (or converting) a plain-C binding into a templated version controlled by the script.
As an example, for MPI_Send
you might have a C file that looks something
like this:
#include "ompi_config.h"
...other includes...
int MPI_Send(const void *buf, int count, MPI_Datatype datatype, int dest,
int tag, MPI_Comm comm)
{
...internal checks...
return internal_mpi_send(buf, count, datatype, dest, tag, comm);
}
To convert this to a template, you will have to first ensure that only a single
function is defined in the file, removing or abstracting out static functions,
and separating multiple definitions, such as MPI_Send
and MPI_Isend
,
into different files. The template should also not include any macro-processing
that attempts to change the name of the function or parameter types; this code
should be generated by the script, or abstracted into header files that can
work easily with multiple functions.
At this point, the template should look like the example above, with a “header” section, with simple includes or macros, maybe a static global, and the function defintion and nothing else.
The next step is to convert the signature line into the prototype format that
the script expects. For MPI_Send
, this should look something like this:
PROTOTYPE ERROR_CLASS send(BUFFER buf, COUNT count, DATATYPE type, RANK dest,
TAG tag, COMM comm)
Notice how the function name is changed, the MPI_
prefix removed and the
rest converted to lowercase, and also how each parameter is simplified into a
TYPE name
format, where the TYPE
conforms to an allowed list in
ompi/mpi/bindings/ompi_bindings/c_type.py
. For newer functions and types,
you may have to extend the c_type.py
file with a new class showing how to
handle the type.
The final step is to update Makefile.am
, adding the template name, in this
case send.c.in
, to the prototype_sources
variable, and the generated
file name, generated_send.c
, to interface_profile_sources
. The
generated file name must be of the form generated_${basename}.c
, where
${basename}
is the name of the template file stripped of all extensions.
13.12.2. Fortran Bindings
Adding new Fortran bindings follows a similar process to the C version above.
All new interfaces are actually based on a single C-template file following the
same format as the C interface templates. However, the C file generated will
use Fortran-specific arguments, including CFI_*
arguments, when TS 29113 is
enabled, MPI_Fint *
arguments in other cases, and others specific to how
the Fortran MPI types are defined. Most of these files perform Fortran-specific
error handling, Fortran-to-C type conversion, and other necessary steps before
calling the actually C bindings with the proper arguments.
These templates are used not only to generate a C backing file for the Fortran code, but also the Fortran interface definitions and the Fortran subroutines corresponding to the generated C file. These are output in three separate files:
ompi/mpi/fortran/use-mpi-f08/api_f08_generated.F90
ompi/mpi/fortran/use-mpi-f08/base/api_f08_generated.c
ompi/mpi/fortran/use-mpi-f08/mod/mpi-f08-interfaces-generated.h
The Fortran file api_f08_generated.F90
contains all the internal subroutine
definitions, each of which makes a call into corresponding C functions. The
internal subroutine names are mapped to the external interface, including
multiple interfaces for the bigcount version of functions, in
mpi-f08-interfaces-generated.h
. The C file api_f08_generated.c
basically contains a concatenation of all fully expanded C templates.
These files contain preprocessing directives to ensure they can support
compilers with and without TS 29113 support, allowing use of
CFI_cdesc_t
types when available (see Fortran 2018 for more details).
If a new type needs to be added, then one will need to extend
fortran_type.py
in ompi/mpi/bindings/ompi_bindings
with an additional
type class specifying how to handle the type in the above generated files,
including any required key-value attributes for more complicated types. New
types use a Type
base class with functions that can be implemented by
derived classes, each returning expanded Fortran or C code.
13.12.3. Other Considerations
Keep in mind that the generated files will not be deleted with a make clean
or make distclean
; instead use make maintainer-clean
to delete those.