[MPI3 Fortran] Fortran extra_state argument to MPIattributefunctions
Iain Bason
Iain.Bason at Sun.COM
Thu May 28 08:55:20 CDT 2009
On 05/28/09 04:23, N.M. Maclaren wrote:
> On May 28 2009, Aleksandar Donev wrote:
>> Jeff Squyres wrote:
>>
>>> I guess I should clarify here -- the intent for this parameter is
>>> not to be interoperable with C.
>> I understand, but you were asking about a "neutral" type that can be
>> "cast" into the "right type". The C void* can be used for such
>> things, but Fortran does not have an equivalent, at least not unless
>> you count Fortran 2003 object oriented features (where there are
>> "unlimited polymorphic pointers" which provide a type-safe "castable"
>> generic pointer). This is why using C interoperability is good
>> here---it is legal and does what you want.
>
> While this is true, a reasonable alternative approach (which is what is
> actually done by must current implementations for MPI handles) is to use
> an integer token in Fortran, and have the using routines decode it. That
> isn't exactly an unusual strategy in Fortran, and was common in the many
> compilers written in Fortran 66.
There are two issues here:
1. How best to pass a void* equivalent type to an MPI routine; and
2. How to deal with the aliasing issues that arise due to callback routines.
I believe Nick and Aleksandar have addressed #1, but I don't think they
have addressed
#2. Look at this example program, which uses Cray pointers and LOC to deal
with issue #1:
include 'mpif.h'
implicit none
external copyfunc, delfunc
integer err, kvh, comm
real extra(10)
call mpi_init(err)
extra(2:10) = 6
extra(1) = 5
call mpi_comm_create_keyval(copyfunc, delfunc, kvh, loc(extra),
+ err)
call mpi_comm_set_attr(mpi_comm_world, kvh, 1, err)
call mpi_comm_dup(mpi_comm_world, comm, err)
extra = 7
call mpi_comm_free(comm, err)
call mpi_finalize(err)
end
subroutine copyfunc(oldcomm, kv, extra, val_in, val_out, flag,
+ ierror)
include 'mpif.h'
implicit none
integer oldcomm, kv, ierror
integer(kind=mpi_address_kind) val_in, val_out
real extra_val(10)
pointer (extra, extra_val)
logical flag
print *, extra_val
flag = 1
val_out = val_in
ierror = mpi_success
end subroutine
subroutine delfunc(oldcomm, kv, val, extra, ierror)
include 'mpif.h'
implicit none
integer oldcomm, kv, ierror
integer(kind=mpi_address_kind) val
real extra_val(10)
pointer (extra, extra_val)
print *, extra_val
ierror = mpi_success
end subroutine
Now copyfunc is called from the MPI library during evaluation of the
call to mpi_comm_dup, while delfunc is called during the evaluation
of the call to mpi_comm_free. Those routines are accessing extra, which
is a local variable in the main program. The program has passed the
address of extra to mpi_comm_create_keyval, but not to mpi_comm_dup
or mpi_comm_free.
A compiler may choose to delete "extra = 7" as dead code, or to move
the assignment before the call to mpi_comm_dup or after the call to
mpi_comm_free. Or the compiler may decide that use of "loc(extra)"
means that extra may be accessed or modified by any call, and thus
be conservative about its optimizations. The standard doesn't provide
any guidance, since LOC and Cray pointers are outside the standard.
Is there a standard-conformant way to indicate that extra may be accessed
or modified during the calls to mpi_comm_dup and mpi_comm_free?
Iain
More information about the mpiwg-fortran
mailing list