Skip to content

Commit 4689b61

Browse files
committed
Add documentation on C/Fortran binding code
Signed-off-by: Jake Tronge <jtronge@lanl.gov>
1 parent a9beb77 commit 4689b61

File tree

2 files changed

+115
-0
lines changed

2 files changed

+115
-0
lines changed

docs/developers/bindings.rst

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
C and Fortran Bindings
2+
======================
3+
4+
The C and Fortran (mpi_f08) bindings are generated from Python code in
5+
``ompi/mpi/bindings``. The C code is generated based on a template file for
6+
each function, with a header and a body containing error-checking and
7+
conversion code; the mpi_f08 Fortran bindings are generated from a single
8+
file ``ompi/mpi/fortran/use-mpi-f08/interface.in``.
9+
10+
The Python code depends on special prototype lines used with both the C and
11+
Fortran bindings. These "prototypes" are designed to be easy to parse and use
12+
specific type constants that can be mapped directly to the expanded
13+
language-specific code, error-handling, and conversion code.
14+
15+
C Bindings
16+
----------
17+
18+
This will walk through adding (or converting) a plain-C binding into a
19+
templated version controlled by the script.
20+
21+
As an example, for ``MPI_Send`` you might have a C file that looks something
22+
like this:
23+
24+
.. code-block:: c
25+
26+
#include "ompi_config.h"
27+
...other includes...
28+
29+
int MPI_Send(const void *buf, int count, MPI_Datatype datatype, int dest,
30+
int tag, MPI_Comm comm)
31+
{
32+
...internal checks...
33+
return internal_mpi_send(buf, count, datatype, dest, tag, comm);
34+
}
35+
36+
To convert this to a template, you will have to first ensure that only a single
37+
function is defined in the file, removing or abstracting out static functions,
38+
and separating multiple definitions, such as ``MPI_Send`` and ``MPI_Isend``,
39+
into different files. The template should also not include any macro-processing
40+
that attempts to change the name of the function or parameter types; this code
41+
should be generated by the script, or abstracted into header files that can
42+
work easily with multiple functions.
43+
44+
At this point, the template should look like the example above, with a "header"
45+
section, with simple includes or macros, maybe a static global, and the
46+
function defintion and nothing else.
47+
48+
The next step is to convert the signature line into the prototype format that
49+
the script expects. For ``MPI_Send``, this should look something like this:
50+
51+
.. code-block:: c
52+
53+
PROTOTYPE ERROR_CLASS send(BUFFER buf, COUNT count, DATATYPE type, RANK dest,
54+
TAG tag, COMM comm)
55+
56+
Notice how the function name is changed, the ``MPI_`` prefix removed and the
57+
rest converted to lowercase, and also how each parameter is simplified into a
58+
``TYPE name`` format, where the ``TYPE`` conforms to an allowed list in
59+
``ompi/mpi/bindings/ompi_bindings/c_type.py``. For newer functions and types,
60+
you may have to extend the ``c_type.py`` file with a new class showing how to
61+
handle the type.
62+
63+
The final step is to update ``Makefile.am``, adding the template name, in this
64+
case ``send.c.in``, to the ``prototype_sources`` variable, and the generated
65+
file name, ``generated_send.c``, to ``interface_profile_sources``. The
66+
generated file name must be of the form ``generated_${basename}.c``, where
67+
``${basename}`` is the name of the template file stripped of all extensions.
68+
69+
Fortran Bindings
70+
----------------
71+
72+
Adding a new Fortran binding may be as simple as adding an additional prototype
73+
to ``ompi/mpi/fortran/use-mpi-f08/interface.in``, as long as all the required
74+
types are already supported by the binding code. Below is an example prototype
75+
for ``MPI_Waitall``:
76+
77+
.. code-block::
78+
79+
.waitall(SHORTCUT_COUNT count, REQUEST_ARRAY array_of_requests[count=count],
80+
STATUS_ARRAY array_of_statuses[count=count])
81+
82+
First, notice that the function name is listed with the ``MPI_`` prefix removed
83+
and in all lowercase along with a ``.`` before the name---this makes it easier
84+
to delimit prototypes across multiple lines. Parameters are listed in a
85+
simplified ``TYPE NAME`` form, with an optional ``[key=value;...]`` attribute
86+
coming after if required for the specific type. This key-value attribute is
87+
used to specify dependencies betwen parameters, where the key is validated by
88+
the type and the value must be the name of another parameter.
89+
90+
The Fortran binding code not only generates Fortran, but also additional
91+
wrapping C code that calls into the C bindings, making conversions and checking
92+
for Fortran-specific error conditions as necessary. The following files will be
93+
generated by the script:
94+
95+
* ``ompi/mpi/fortran/use-mpi-f08/api_f08_generated.F90``
96+
* ``ompi/mpi/fortran/use-mpi-f08/base/api_f08_generated.c``
97+
* ``ompi/mpi/fortran/use-mpi-f08/base/api_f08_ts_generated.c``
98+
* ``ompi/mpi/fortran/use-mpi-f08/mod/mpi-f08-interfaces-generated.h``
99+
100+
The Fortran file ``api_f08_generated.F90`` contains all the internal subroutine
101+
definitions, each of which makes a call into corresponding C functions. Two
102+
different C files are generated: ``api_f08_ts_generated.c`` contains support
103+
for compilers with TS 29113 support, allowing the use of ``CFI_cdesc_t`` types;
104+
and ``api_f08_generated.c`` for compilers without TS 29113 support. The
105+
internal subroutine names are mapped to the external interface, including
106+
multiple interfaces for the bigcount version of functions, in
107+
``mpi-f08-interfaces-generated.h``.
108+
109+
If a new type needs to be added, then one will need to extend
110+
``fortran_type.py`` in ``ompi/mpi/bindings/ompi_bindings`` with an additional
111+
type class specifying how to handle the type in the above generated files,
112+
including any required key-value attributes for more complicated types. New
113+
types use a ``Type`` base class with functions that can be implemented by
114+
derived classes, each returning expanded Fortran or C code.

docs/developers/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,4 @@ probably don't need to read this section.
2222
gnu-autotools
2323
sphinx
2424
rst-for-markdown-expats.rst
25+
bindings

0 commit comments

Comments
 (0)