[MPI3 Fortran] MPI buffer arguments - void and call-by-reference

Craig Rasmussen crasmussen at lanl.gov
Tue Feb 17 14:08:57 CST 2009


After the J3 meeting in Las Vegas last week I think we are reaching a  
conclusion on many of the MPI 3 interface issues.  The one remaining  
point of disagreement is whether to use the ASYNCHRONOUS attribute  
(currently it only applies to Fortran IO) or the VOLATILE attribute.   
Since there is so much disagreement on this issue within J3 and WG5  
(this includes disagreements between several influential members on  
the committees and some even switching sides from time to time), I'll  
leave the solution for later.  As for now, I believe that the MPI  
Forum should disregard the J3 paper I send to you earlier, supposedly  
clarifying the asynchronous MPI question.

We do have clarity on another issue, however.  There was substantial  
agreement on the committee for the following interface (I was the lone  
dissenting vote):

interface
     subroutine MPI_Send(buf, ...) BIND(C)
         TYPE(*), DIMENSION(..), INTENT(in) :: buf
         ...
     end subroutine
end interface

This means that actual argument associated with the dummy argument  
buf, can be an array or scalar of any type.  If it is an array, it can  
have any rank.  The major impact to the MPI implementation is that the  
buf argument will be passed by descriptor.  This means that there will  
be no copyin/copyout of the array by the Fortran compiler.  The MPI  
implementation is free to enforce whatever semantics it wishes on the  
buf argument.  In your example below,

    CALL MPI_SEND(rarr(5:30:3),...)

the MPI implementation can get the address of the rarr array and the  
5:30:3 index information.  It can choose to return an error if it  
wishes to enforce that the array is contiguous or it can ignore the  
stride by 3 information and just proceed as if the array was contiguous.

I'm pretty sure this will be the only choice provided in Fortran 2008/ 
Interop TR  and MPI 3.0 timeframe.  Otherwise the MPI Forum can use  
the CLOC() intrinsic in the current 2003 interoperability standard to  
pass void* buffer addresses.

I think using TYPE(*) and DIMENSION(..) is an excellent solution for  
MPI 3.0.  The advantages are:

1. Current user code won't have to change beyond using the MPI3 module.
2. The interface is non-generic and doesn't have the interface  
explosion in the current MPI 90 interfaces.  This interface will even  
accept scalar actuals.
3. The interface is type safe as far as the other (non void*) arguments.
4. The actual argument associated with buf doesn't require the TARGET  
attribute (as the CLOC/C_PTR route does), with the possibly  
substantial performance implications.

Potential downside:

1. There must be a wrapper that calls the MPI C implementation.  We  
had decided on this anyway as we wanted to stick with the SUBROUTINE  
syntax.
2. There will be some minor performance implications as the array  
descriptor must be examined before calling the MPI C implementation.   
The performance hit can be as minor as dereferencing a struct to get  
at the array address to something more substantial if the  
implementation wants to make use of the stride information.

I'm hoping we can look at this in more detail at the next MPI Forum  
meeting and reach agreement on the non-asynchronous interfaces.

We can also discuss MPI_Isend and MPI_Irecv and what to do with them.   
I'm assuming that the use of ASYNCHRONOUS plus TARGET will be  
preferred over VOLATILE.  Since at this point ASYNCHRONOUS really only  
pertains to Fortran IO, MPI Forum could request another name for an  
equivalent attribute, perhaps one that combines the semantics of  
ASYNCHRONOUS and TARGET.

Cheers,
Craig


On Feb 9, 2009, at 3:59 PM, Rolf Rabenseifner wrote:

> This is the second part of my two mails:
>
> B) VOID buffer declaration
> --------------------------
>
> B.1 Current status
>
>    INTEGER :: ibuf
>    CALL MPI_SEND(ibuf,...)
>
>    REAL, DIMENSION(100) :: rarr
>    CALL MPI_SEND(rarr,...)
>    CALL MPI_SEND(rarr(5:30:3),...)
>
>    COMPLEX, DIMENSION(10,20,30) :: carr3dim
>    CALL MPI_SEND(carr3dim,...)
>
>    TYPE buff_type
>     SEQUENCE
>     INTEGER, DIMENSION(3):: i_val
>     DOUBLE PRECISION, DIMENSION(5):: d_val
>    END TYPE buff_type
>    TYPE (buff_type) :: struct
>    CALL MPI_SEND(struct,...)
>
>    TYPE (buff_type), DIMENSION(10,20) :: struct2dim
>    CALL MPI_SEND(struct2dim,...)
>
>    ... ... ... ...
>
>    All this works and the C-writte MPI_SEND receives the address
>    of the first data element of each buffer.
>
>    Currently, there isn't a F90 interface definition
>    (i.e. only F77 style is used)
>
>    MPI has its own interface to handle the data structure behind
>    the starting pointer, the so called MPI datatypes.
>    Such an MPI datatype  need not to describe the whole
>    structure, i.e., there may be differences between the
>    type information that was told the compiler and the MPI datatype
>    information.
>
>
> B.2 Goals
>
>    B.2.1 To allow F90 interfaces that do not break eisting codes
>    B.2.2 To minimize the burden for MPI libraries implementers
>          and Fortran compiler implementers.
>
> B.3 Maybe a simple but efficient solution
>
>    SUBROUTINE MPI_SEND(buf,...
>    VOID :: buf
>    END
>
>    This can be used only in a interface definition for routines
>    that are implemented in C.
>    There is no meaning if one wants to write the routine MPI_SEND
>    in Fortran.
>
>    Meaning of VOID buf:
>    Exactly the same as if implicit (F77) interfaces are used.
>
>    (Not needed for MPI, but a possible extension:
>
>       Instead of VOID, one is using IMPLARG, meaning the
>       same as VOID on the caller side and is also allowed
>       on the soubroutine side.
>       Meaning: Same argument handlich as with implicit interfaces,
>                i.e., handing over the pointer to the data or
>                in cases of noncontiguos subarrays only a pointer to
>                a contiguous copy of the data.
>    )
>
>
> C) Call by reference and not by in-copy-out-copy
> ------------------------------------------------
>
>   It is clear, that F77 interfaces cannot do strided arrays
>   directly with call-by-reference.
>
>   For contiguous arrays and non-arrays, it isn't a problem.
>
>   Fortran compilers are allowed to choose call-by-incopy-and-outcopy
>   instead of call-by-reference.
>
>   Maybe the following additional option may solve the problem:
>
>   SUBROUTINE MPI_SEND(buf,...
>   VOID, CALLBYREFERENCE :: buf
>
>   Meaning: Same as what currently done, i.e., call-by-reference
>   on the caller side, if call-by-reference is possible (i.e.,
>   not for non-contiguous subarrays)
>
>
> Dr. Rolf Rabenseifner . . . . . . . . . .. email rabenseifner at hlrs.de
> High Performance Computing Center (HLRS) . phone ++49(0)711/685-65530
> University of Stuttgart . . . . . . . . .. fax ++49(0)711 / 685-65832
> Head of Dpmt Parallel Computing . . . www.hlrs.de/people/rabenseifner
> Nobelstr. 19, D-70550 Stuttgart, Germany . (Office: Allmandring 30)




More information about the mpiwg-fortran mailing list