[MPI3 Fortran] Proposing changes to Fortran 2008
Aleksandar Donev
donev1 at llnl.gov
Wed Mar 12 16:24:30 CDT 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: 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