(j3.2006) MPI usage problems in Fortran
Bill Long
longb
Wed Mar 19 14:20:37 EDT 2008
Aleksandar Donev wrote:
> Craig,
>
> You are mixing two things up: Either your buffer is an regular (typed) Fortran
> array and has the ASYNC attribute, *or* it is a "TYPE(C_PTR), VALUE". Don't
> mix the two as it makes no sense. The pointer itself is neither volatile nor
> asynchronous, it is the target of the pointer that is.
>
>
>> 1. VALUE and ASYNCHRONOUS lead to a compile error (is this correct?)
>>
> Yes it is correct, but don't ask me why.
>
Right, it is a constraint violation. And it does make sense. The point
of giving a dummy variable the asynchronous attribute is to make sure
that the physical memory referenced through it is the same memory as is
associated with the corresponding actual argument. That's because an
async I/O operation initiated in the subprogram might not finish before
control is transferred back to the caller, and the I/O libraries need a
stable target in memory for the data transfers throughout the I/O
operation. The VALUE attribute has essentially the opposite effect. It,
at least conceptually, implies that the dummy is associated with a
memory location local to the subprogram that gets its initial value from
the caller, but from that point on is disassociated from the
corresponding actual argument. In particular, any changes made to the
value in the local memory location are thrown away on return.
>
>> 2. buf doesn't have the TARGET attribute
>>
> Definitely a bad idea---you are taking and retaining a pointer to it. It must
> have TARGET.
>
>
>> 3. How long is buf tainted as Bill suggests?
>>
> Ask Bill :-) The standard says nothing that I can understand...
>
The user is responsible for knowing how asynchronous variables are used
and not violating the associated rules. The only thing the compiler can
really know is that a hard WAIT statement (with no ID) will imply that
all the currently asynchronous variables are untainted, since all I/O
operations have completed. But it is free to assume that all the uses
are conforming, and so can assume untainted in most cases.
In many respects, asynchronous is just a restricted/limited form of
volatile. Both imply that the value of a variable might change during
the execution of a statement that has no affect on that variable. The
restriction with asynchronous is that we assume the agent for that value
change is an async I/O operation that was previously started, but might
not have finished. Thus, a WAIT statement can free the variable from the
possibility of invisible change, at least until it is used in another
async I/O statement. The compiler, however, is not required to perform
this sort of flow control analysis. The VOLATILE attribute, on the
other hand, basically taints the variable everywhere in a scoping unit
where it is declared volatile. Typically, you would use volatile only
for a variable that has a very narrow range of uses, all of which you
really want to be unoptimized. Asynchronous, on the other hand, applies
to variables in I/O lists that you would generally want treated in
optimized ways. Since the user can control the code range where the
variable is tainted, and in that region the variable is not supposed to
be used in ways that would depend one the progress of the I/O operation,
the compiler can optimize the use of such variables.
Cheers,
Bill
Cheers,
Bill
> Here is what it should look like:
>
> --------------
> interface
> function MPI_Isend(buf, count, datatype, &
> dest, tag, comm, request)
> BIND(C, name="MPI_Isend") result(err)
> use, intrinsic :: ISO_C_BINDING
> import :: MPI_HANDLE
> implicit none
> type(C_PTR), value :: buf
> ...
> end function MPI_Isend
> end interface
>
> use, intrinsic :: ISO_C_BINDING
> use MPI3
> type(MPI_HANDLE) :: request
> integer, volatile, target :: buf(10)
> integer(C_INT) :: err
>
> err = MPI_Isend(C_LOC(buf), 10, MPI_INTEGER, 1, 1, MPI_COMM_WORLD,
> request)
> ----------------
>
> Note that buf is volatile and target. Maybe asynchronous and target would also
> work, but I think the standard reserves asynchronous for internal Fortran I/O
> use and not for things outside of the standard. I don't think it will make
> any difference---don't compilers treat the two identically?
>
> This will kill optimization of anything done with buf in any program unit
> where it has both the volatile and the target attribute.
>
> Bill and the misguided Note in the standard suggest that maybe this was some
> intended use of asynchronous:
>
> --------------
> interface
> function MPI_Isend(buf, count, datatype, &
> dest, tag, comm, request)
> BIND(C, name="MPI_Isend") result(err)
> use, intrinsic :: ISO_C_BINDING
> import :: MPI_HANDLE
> implicit none
> real(c_double), dimension(*), asynchronous :: buf ! An array
> ...
> end function MPI_Isend
> end interface
>
> use, intrinsic :: ISO_C_BINDING
> use MPI3
> type(MPI_HANDLE) :: request
> integer, target :: buf(10) ! Should/must this have ASYNC attribute???
> integer(C_INT) :: err
>
> err = MPI_Isend(buf, ..., request)
> ----------------
>
> but again I don't think the standard holds water in making this actually make
> sense, yet alone work.
>
> Best,
> Aleks
>
> _______________________________________________
> J3 mailing list
> J3 at j3-fortran.org
> http://j3-fortran.org/mailman/listinfo/j3
>
--
Bill Long longb at cray.com
Fortran Technical Support & voice: 651-605-9024
Bioinformatics Software Development fax: 651-605-9142
Cray Inc., 1340 Mendota Heights Rd., Mendota Heights, MN, 55120
More information about the J3
mailing list