-
Notifications
You must be signed in to change notification settings - Fork 861
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Generate interfaces for C with bigcount
This adds scripts for generating the C API bindings from template files, while also generating bigcount interfaces for those that require them. The binding script also include initial support for the mpi_f08 Fortran bindings, but doesn't yet make any changes to fortran/use-mpi-f08 Python >=3.6 is required for running these scripts, which is only necessary when the binding files have not already been generated. Users of the distribution tarball should not need to generate these files and thus should not require Python. Co-authored-by: mphinney1100 <[email protected]> Co-authored-by: Howard Pritchard <[email protected]> Signed-off-by: Jake Tronge <[email protected]>
- Loading branch information
1 parent
c3bebd8
commit 1ae5439
Showing
859 changed files
with
39,430 additions
and
38,549 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
dnl -*- shell-script -*- | ||
dnl | ||
dnl Copyright (c) 2019 Research Organization for Information Science | ||
dnl and Technology (RIST). All rights reserved. | ||
dnl $COPYRIGHT$ | ||
dnl | ||
dnl Additional copyrights may follow | ||
dnl | ||
dnl $HEADER$ | ||
dnl | ||
|
||
# Check whether or not the C compiler supports ISO_Fortran_binding.h | ||
# Also check whether C and Fortran compiler interoperate. | ||
# | ||
# OMPI_FORTRAN_CHECK_TS([action if found], [action if not found]) | ||
# ---------------------------------------------------- | ||
AC_DEFUN([OMPI_FORTRAN_CHECK_TS],[ | ||
AS_VAR_PUSHDEF([fortran_ts], [ompi_cv_fortran_have_ts]) | ||
|
||
AC_CHECK_HEADERS([ISO_Fortran_binding.h], | ||
[AC_CACHE_CHECK([if Fortran and C compilers support ISO_Fortran_binding.h], fortran_ts, | ||
[mkdir conftest.$$ | ||
cd conftest.$$ | ||
|
||
# Try to compile the C bindings | ||
cat > conftest_c.c << EOF | ||
#include <ISO_Fortran_binding.h> | ||
|
||
int is_contiguous_c(CFI_cdesc_t* x) { | ||
return CFI_is_contiguous(x); | ||
} | ||
EOF | ||
OPAL_LOG_COMMAND([$CC $CCFLAGS -c conftest_c.c], | ||
[cat > conftest.f90 << EOF | ||
module MOD_IS_CONTIGUOUS | ||
|
||
interface | ||
|
||
function is_contiguous(buf) BIND(C, name="is_contiguous_c") | ||
implicit none | ||
type(*), dimension(..) :: buf | ||
integer :: is_contiguous | ||
end function is_contiguous | ||
|
||
end interface | ||
|
||
end module | ||
|
||
program test_is_contiguous | ||
use MOD_IS_CONTIGUOUS | ||
implicit none | ||
integer :: a0, a1(2), a2(2,2), a3(2,2,2) | ||
write (*,*) is_contiguous(a0) | ||
write (*,*) is_contiguous(a1) | ||
write (*,*) is_contiguous(a2) | ||
write (*,*) is_contiguous(a3) | ||
end program | ||
EOF | ||
OPAL_LOG_COMMAND([$FC $FCFLAGS $FCFLAGS_f90 -o conftest conftest.f90 conftest_c.o $LDFLAGS $LIBS], | ||
[AS_VAR_SET(fortran_ts, yes)], | ||
[AS_VAR_SET(fortran_ts, no)])], | ||
[AS_VAR_SET(fortran_ts, no)]) | ||
cd .. | ||
rm -rf conftest.$$])], | ||
[AS_VAR_SET(fortran_ts, no)]) | ||
|
||
AS_VAR_IF(fortran_ts, [yes], [$1], [$2]) | ||
AS_VAR_POPDEF([fortran_ts])dnl | ||
]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
C and Fortran Bindings | ||
====================== | ||
|
||
The C and Fortran (mpi_f08) bindings are generated from Python code in | ||
``ompi/mpi/bindings``. The C code is generated based on a template file for | ||
each function, with a header and a body containing error-checking and | ||
conversion code; the mpi_f08 Fortran bindings are generated from a single | ||
file ``ompi/mpi/fortran/use-mpi-f08/interface.in``. | ||
|
||
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. | ||
|
||
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: | ||
|
||
.. code-block:: c | ||
#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: | ||
|
||
.. code-block:: c | ||
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. | ||
|
||
Fortran Bindings | ||
---------------- | ||
|
||
To add a new Fortran binding, or update an existing one, one will need to | ||
modify the ``ompi/mpi/fortran/use-mpi-f08/interface.json`` file; this JSON file | ||
contains a list of prototype objects, including information about their name | ||
and each parameter passed. Below is an example for ``MPI_Waitall``: | ||
|
||
.. code-block:: | ||
{ | ||
"name": "waitall", | ||
"parameters": [ | ||
{ | ||
"type": "SHORTCUT_COUNT", | ||
"name": "count" | ||
}, | ||
{ | ||
"type": "REQUEST_ARRAY", | ||
"name": "array_of_requests", | ||
"dep_params": { | ||
"count": "count" | ||
} | ||
}, | ||
{ | ||
"type": "STATUS_ARRAY", | ||
"name": "array_of_statuses", | ||
"dep_params": { | ||
"count": "count" | ||
} | ||
} | ||
] | ||
} | ||
This object includes two properties: the ``name`` property holding the | ||
subroutine name, converted to lowercase and the ``mpi_`` prefix removed; and | ||
the ``parameters`` property describing all parameters, their types and | ||
dependencies. Some parameters may depend on other types and this is listed in | ||
the ``dep_params`` field. An example of this can be seen with | ||
``array_of_requests`` above, in which ``dep_params`` holds a key-value pair | ||
``"count": "count"``, where the key ``count`` corresponds to a key required by | ||
the ``REQUEST_ARRAY`` type and the value ``count`` to the name of another | ||
parameter. These parameter dependencies are specific to the types used and are | ||
validated by the binding scripts. | ||
|
||
The Fortran binding code not only generates Fortran, but also additional | ||
wrapping C code that calls into the C bindings, making conversions and checking | ||
for Fortran-specific error conditions as necessary. The following files will be | ||
generated by the script: | ||
|
||
* ``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/base/api_f08_ts_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. Two | ||
different C files are generated: ``api_f08_ts_generated.c`` contains support | ||
for compilers with TS 29113 support, allowing the use of ``CFI_cdesc_t`` types | ||
(see `Fortran 2018`_ for more details); and ``api_f08_generated.c`` for | ||
compilers without TS 29113 support. 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``. | ||
|
||
.. _Fortran 2018: https://fortranwiki.org/fortran/show/Fortran+2018 | ||
|
||
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. | ||
|
||
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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,3 +22,4 @@ probably don't need to read this section. | |
gnu-autotools | ||
sphinx | ||
rst-for-markdown-expats.rst | ||
bindings |
Oops, something went wrong.