[MPI3 Fortran] Proposing changes to Fortran 2008
Hello, I am just joining this group so forgive me for not having the full background. I am a member of the J3 committee and in discussions with Craig we think it would be great if this group comes up with a specific proposal on changes needed to the Fortran standard to construct a nice interface to MPI. Sorry for the long missive. The main issue is the handling of the void* arguments and avoiding the issues with type-kind-rank (TKR) matching between actuals and dummies. The first step in any proposal to J3 is to argue that what was already put in Fortran 2003 with C Interop is insufficient. Here is my argument, but other things can be added. The mechanism for passing void* pointers is scalar arguments of type C_PTR. At the call site, C_LOC is used to get the address: CALL MPI_Send(C_LOC(buffer)...) The issues with this are: 1) buffer must have the TARGET attribute, affecting performance and existing codes 2) one must add C_LOC at every call site, thus affecting existing codes. Number 1 is very serious, IMO. It cannot be relaxed without compromising the standard's internal consistency. So a new mechanism is needed. A possible solution is something like: interface subroutine mpi_send(buffer...) bind(c) type(c_void), dimension(*) :: buffer end subroutine end interface or interface subroutine mpi_send(buffer,N,...) bind(c) integer :: N type(c_void), dimension(N) :: buffer end subroutine end interface The actual must be of interoperable type. The argument association rules are the same as for "normal" arrays (for example, in the first case the association is with all of the elements of the actual, in the second with the first N elements, the actual can be of higher rank, etc.). In particular, if the actual is not contiguous, a contiguous copy will be made at the call site. The corresponding C routine must have a void* argument. The important thing here, which will be objected to in J3, is that such a type(c_void) argument can only appear in bind(c) interfaces for an assumed-size or explicit-shape array (we can discuss extensions to assumed-shape arrays later...we are working on a TR for that). One cannot write an actual Fortran routine that has a dummy with no type since it is ill-defined what that means in Fortran. This is not the case with existing Fortran---interfaces merely repeat what can be written in Fortran and any BIND(C) routine may be written in either C or Fortran. Bill Long has proposed that the syntax BIND(C,LANG="C99") be used for the new type of interface blocks. For non-blocking sends, a pointer to the actual must be retained. This requires matching TARGET attributes on *both* the dummy and actual: interface subroutine mpi_Isend(buffer...) bind(c) type(c_void), dimension(*), target :: buffer end subroutine end interface integer(c_int), target :: x(100) call mpi_Isend(x...) For the call to actually work as expected, the actual must be contiguous (this is a new defined term in Fortran 2008 with some intrinsics to test is an array is contiguous) and have the target attribute, and must be of interoperable type. This approach would allow one to construct a Fortran interface to MPI that emulates the C interface closely. One more useful thing are TYPEALIASes, which were supposed to be in F2003 but were pulled out at the last minute. I think that things like MPI_Datatype should be type aliases instead of opaque derived types. But this is not that serious. An alternative is to construct a Fortran interface to MPI that actually uses the full power of Fortran, rather then using the (IMHO) very low-level and very annoying to use in practice C interface. For example, a call to MPI_Send includes redundant information about the type and size of the buffer. This info is known to the compiler from the actual argument and can be automatically provided by the compiler thus increasing safety and usability greatly. This is done in Fortran using array descriptors, which contain info about the TKR of the array. My dream interface to MPI_Send would be something like: interface subroutine mpi_send(buffer...) class(*), dimension() :: buffer end subroutine end interface This would pass a descriptor to the C routine, which can then get the TKR info from it and call the low-level MPI routine. This is more for the future. I think getting the simple "no TKR matching" is more focused and important for now. Best, Aleks -- Aleksandar Donev, Ph.D. Lawrence Postdoctoral Fellow @ LLNL High Performance Computational Materials Science and Chemistry E-mail: [email protected] Phone: (925) 424-6816 Fax: (925) 423-0785 Address: P.O.Box 808, L-367, Livermore, CA 94551-9900 Web: http://cherrypit.princeton.edu/donev
participants (1)
-
Aleksandar Donev