[MPI3 Fortran] Proposing changes to Fortran 2008

Aleksandar Donev donev1 at llnl.gov
Wed Mar 12 16:24:30 CDT 2008


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:

subroutine mpi_send(buffer...) bind(c)
    type(c_void), dimension(*) :: buffer
end subroutine
end 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* 

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:

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:

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.


Aleksandar Donev, Ph.D.
Lawrence Postdoctoral Fellow @ LLNL
High Performance Computational Materials Science and Chemistry
E-mail: donev1 at llnl.gov
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

More information about the mpiwg-fortran mailing list