(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