MPI is a language-independent specification with separate language bindings. The MPI-1.1 standard specifies a C and a Fortran 77 binding. Since these bindings are quite similar, we decided to implement MPI in C, with the Fortran implementation simply calling the C routines. This strategy requires some care, however, because some C routines take arguments by value while all Fortran routines take arguments by reference. In addition, the MPICH implementation uses pointers for the MPI opaque objects (such as MPI_Request and MPI_Comm); Fortran has no native pointer datatype, and the MPI standard uses the Fortran INTEGER type for these objects. Rather than manually create each interface routine, we used a program that had been developed at Argonne for just this purpose.
The program, bfort [21], reads the C source file and uses structured comments to identify routines for which to generate interfaces. Special options allow it to handle opaque types, choose how to handle C pointers, and provide name mapping. In many cases, this was all that was necessary to create the Fortran interfaces. In cases where routine-specific code was needed (for example, in MPI_Waitsome where zero-origin indexing is used in C and one-origin is used in Fortran), the automatically generated code was a good base to use for the custom code. Using the automatic tool also simplifies updating all of the interfaces when a system with a previously unknown Fortran-C interface is encountered. This situation arose the first time we ported MPICH to a system that used the program f2c [14] as a way to provide a Fortran compiler; f2c generates unusual external names for Fortran routine names. We needed only to rerun bfort to update the Fortran interfaces. This interface handles the issues of pointer conversions between C and Fortran (see Section 64-bit Issues ) as well as the mapping of Fortran external names to C external names. The determination of the name format (e.g., whether Fortran externals are upper or lower case and whether they have underscore characters appended to them) is handled by our configure program, which compiles a test program with the user's selected Fortran compiler and extracts the external name from the generated object file. This allows us to handle different Fortran compilers and options on the same platform.