[MPI3 Fortran] [Fwd: add TYPE(*) and DIMENSION(..) to Fortran]
Jeff Squyres
jsquyres at cisco.com
Fri Sep 5 12:48:04 CDT 2008
Great! Note a few changes, though; MPI functions in C [almost] all
return int. So we can't use the BIND(C) stuff, unfortunately -- it
was felt that making all MPI invocations be FUNCTIONS would be
unnatural for Fortran programmers. So it'll really be something like
this (note that MPI_xxx returns "int" in C and we pass an additional
"ierr" c_int integer argument in Fortran):
In C: int MPI_xxx (void * buffer, int n);
In the Fortran MPI module:
interface MPI_xxx
subroutine MPI_xxx (buffer, n, ierr) bind(c,name="MPI_xxx_fortran")
type(*),dimension(*) :: buffer
integer(c_int),value :: n, ierr
end subroutine MPI_xxx
end interface MPI_xxx
And then then MPI will still have to have a "wrapper" function (in C
or Fortran; whatever they want) to call the back-end/"real" MPI C
function.
On Sep 4, 2008, at 5:29 PM, Hubert Ritzdorf wrote:
> Hi,
>
> attached the accepted proposal by Bill Long which was provided by
> Matthijs van Waveren.
>
> Best regards
>
> Hubert
>
> From: Matthijs van Waveren <m_van_waveren at yahoo.fr>
> Date: September 4, 2008 4:57:50 PM IST
> To: ritzdorf at it.neclab.eu
> Subject: add TYPE(*) and DIMENSION(..) to Fortran
>
>
> To: J3 08-271
> From: Bill Long
> Subject: Adding TYPE(*) and DIMENSION(..) to the TR
> Date: 14 Aug 2008
> References: J3/08-007r2
>
>
> Proposal to add TYPE(*) and DIMENSION(..) to Fortran.
>
> The desire for a simple mechanism to interoperate with C objects
> declared as (void *) has lead to several proposed modifications to
> Fortran. One of the most direct solutions is to provide as essentially
> equivalent declaration in Fortran and limit its associated
> semantics. The form of the declaration proposed is TYPE(*) which
> extends the already existing TYPE(...) syntax, and borrows the
> "assumed" semantics associated with the use of * in declarations. In
> keeping with the rest of the TR, the idea
> is expanded to include
> assumed-shape, allocatable, and pointer variables. With those
> additions, a mechanism to ignore the rank is also needed.
>
>
> Syntax changes:
> ---------------
>
> At [49:R403]:
>
> Add "<<or>> TYPE (*)" to the options for <declaration-type-spec>.
>
> At [92:515]:
>
> Add "<<or>> <assumed-rank-spec>"
>
> After [94:5.3.8.6] in a new subclause named "Assumed-rank array"
> include a syntax rule:
>
> "R522a <assumed-rank-spec> <<is>> .."
>
> Semantics for assumed-type variables:
> -------------------------------------
>
> An <assumed-type> variable is a variable declared with TYPE (*). These
> constraints apply to assumed-type variables:
>
> C1) An <assumed-type> variable shall be a dummy variable.
>
> C2) An <assumed-type> variable shall not have the CODIMENSION,
> EXTERNAL, INTRINSIC, or VALUE
> attribute.
>
> Note: The ALLOCATABLE, ASYNCHRONOUS, CONTIGUOUS, DIMENSION, INTENT,
> OPTIONAL, POINTER, TARGET, and VOLATILE attributes are allowed.
>
> C3) An assumed-type variable may appear only as a dummy argument, an
> actual argument associated with a dummy argument that is assumed-type,
> or the first argument to these intrinsic and intrinsic module
> functions: ALLOCATED, ASSOCIATED, IS_CONTIGUOUS, LBOUND, PRESENT,
> SHAPE, SIZE, UBOUND, or C_LOC.
>
> Additional rules governing variables declared TYPE(*):
>
> An explicit interface is required for a procedure that has an
> assumed-type dummy argument.
>
> In the association of actual and dummy arguments, an assumed-type
> dummy
> argument is type and kind compatible with any actual data argument.
>
> In resolving a generic interface, corresponding dummy arguments may
> include a dummy argument of TYPE (*). Such a dummy is not
> distinguishable
> from other dummies based on
> type. That is, the other specifics in the
> generic must be distinguished based on the rank of this dummy or
> based on other arguments.
>
> A BIND(C) interface may specify dummy arguments that are
> assumed-type. If the dummy argument is a scalar, an explicit-shape
> array, or an assumed-size array, the corresponding formal argument in
> the C prototype shall be a void pointer (void *). If the dummy
> argument has the ALLOCATABLE or POINTER attributes, or is
> assumed-shape or assumed-rank, the actual argument is passed as a
> descriptor, as specified elsewhere in the TR.
>
>
> Semantics for assumed-rank variables:
> -------------------------------------
>
> An <assumed-rank> variable is a variable declared with an
> <assumed-rank-spec>. These constraints apply:
>
> C4) An <assumed-rank> variable shall be a dummy variable.
>
> C5) An <assumed-rank> variable shall not have the CODIMENSION,
> EXTERNAL,
> INTRINSIC, or VALUE attribute.
>
> Note: The ALLOCATABLE, ASYNCHRONOUS, CONTIGUOUS, DIMENSION, INTENT,
> OPTIONAL, POINTER, TARGET, and VOLATILE attributes are allowed.
>
> C6) An assumed-rank variable may appear only as a dummy argument, an
> actual argument associated with a dummy argument that is assumed-rank,
> the argument of the C_LOC intrinsic function in the ISO_C_BINDING
> module, or the first argument in a reference to the intrinsic inquiry
> functions except LCOBOUND, UCOBOUND, and IMAGE_INDEX. A new inquiry
> intrinsic RANK is added to inquire about the rank of an array.
>
> Additional rules governing assumed-rank variables:
>
> An explicit interface is required for a procedure that has an
> assumed-rank dummy argument.
>
> In the association of actual and dummy arguments, an assumed-rank
> dummy argument is rank compatible with any actual array argument, or
> an actual scalar argument. If the actual argument is
> scalar, the dummy
> argument has rank zero and the shape and bounds are arrays of zero
> size. If the actual argument is an array, the bounds of the dummy
> argument are assumed from the actual argument. In other respects, the
> rules for assumed-rank dummy arguments are similar to those for
> assumed-shape arrays.
>
> In resolving a generic interface, corresponding dummy arguments may
> include an assumed-rank dummy argument. Disambiguation must rely
> on the type of the argument or on other arguments.
>
> A BIND(C) interface may specify dummy arguments that are
> assumed-rank. If the dummy argument is assumed-rank, the actual
> argument is passed as a descriptor, as specified elsewhere in the TR.
>
> Specification for a RANK inquiry function.
> ------------------------------------------
>
> In Table 13.1:
>
> RANK (ARRAY) I Rank of an array.
>
> Following the RANGE intrinsic in 13.7:
>
> 13.7.136a
> RANK (ARRAY)
>
> Description: Rank of an array.
>
> Class: Inquiry function.
>
> Argument: ARRAY shall be an array of any type.
>
> Result Characteristics: Default integer scalar.
>
> Result value: The result is the rank of ARRAY.
>
> Example: For an array X declared REAL :: X(:,:,:), RANK(X) is 3.
>
> -------------------
>
> Example of TYPE (*) for an abstracted MPI routine with two
> arguments. The first argument is a data buffer of type (void *) and
> the second is an integer indicating the size of the buffer. The
> generic interface allows for both 4 and 8 byte integers, as a solution
> to the "-i8" compiler switch problem.
>
> In C: void MPI_xxx ( void * buffer, int n);
>
> In the Fortran MPI module:
>
> interface MPI_xxx
> subroutine MPI_xxx (buffer, n) bind(c,name="MPI_xxx")
> type(*),dimension(*) :: buffer
> integer(c_int),value :: n
> end subroutine MPI_xxx
> module procedure
> MPI_xxx_i8
> end interface MPI_xxx
>
> ...
>
> subroutine MPI_xxx_i8 (buffer, n)
> type(*),dimension(*) :: buffer
> integer(8) :: n
> call MPI_xxx(buffer, int(n,c_int))
> end subroutine MPI_xxx_i8
>
> -----------------------
> Example of assumed-type and assumed-rank for an abstracted
> MPI_send routine.
>
> In C: void MPI_send ( void * buffer, int n);
> void MPI_send_new ( void * buffer_desc);
>
> In the Fortran MPI module:
>
> interface MPI_send
> subroutine MPI_send_old (buffer, n) bind(c,name="MPI_send")
> type(*), dimension(*) :: buffer ! Passed by simple address
> integer(c_int),value :: n
> end subroutine
> subroutine MPI_send_new (buffer) bind(c,name="MPI_send_new")
> type(*), dimension(..), contiguous :: buffer
> ! Passed by descriptor including the shape and type
> end subroutine
> end interface
>
> real :: x(100), y(10,10)
>
> ! These will invoke
> MPI_send_old
> call MPI_send(x,size(x)) ! Passed by address
> call MPI_send(y,size(y)) ! Sequence association
> call MPI_send(y(:,1),size(y,dim=1)) ! Pass first column of y
> call MPI_send(y(1,5),size(y,dim=1)) ! Pass fifth column of y
>
> ! These will invoke MPI_send_new
> call MPI_send(x) ! Pass a rank-1 descriptor
> call MPI_send(y) ! Pass a rank-0 descriptor
> call MPI_send(y(:,1)) ! Passed by descriptor without copy
> call MPI_send(y(1,5)) ! Illegal: No sequence association
>
> --------------------
>
> It is possible to "cast" a TYPE (*) object to a usable type, exactly
> as is done for void * objects in C. For example, this code fragment
> casts a block of memory to be used as an intger array.
>
>
> subroutine process(block, nbytes)
> type(*), target :: block(*)
> integer, intent(in) :: nbytes ! Number of bytes in block(*)
>
> integer :: nelems
> integer, pointer :: usable(:)
>
>
> nelems=nbytes/(bit_size(usable)/8)
> call c_f_pointer (c_loc(block), usable, [nelems] )
> usable=0 ! Instead of the illegal block=0
> end subroutine
>
>
> --------------------
> Assumed-rank variables are not restricted to be assumed-type.
> For example, many of the procedures in Clause 14 could be written
> using an assumed-rank dummy argument instead of writing 16 separate
> specific routines for each possible rank.
>
> An example of an assumed-rank dummy argument for the specific
> procedures for a Clause 14 function.
>
> interface ieee_support_divide
> module procedure ieee_support_divide_noarg
> module procedure ieee_support_divide_onearg_r4
> module procedure ieee_support_divide_onearg_r8
> module procedure ieee_support_divide_onearg_r4_scalar
> module procedure ieee_support_divide_onearg_r8_scalar
> end interface ieee_support_divide
>
> ...
>
> logical function ieee_support_divide_noarg
> ()
> ieee_support_divide_noarg = .true.
> end function ieee_support_divide_onearg_r4
>
> logical function ieee_support_divide_onearg_r4 (x)
> real(4),dimension(::) :: x
> ieee_support_divide_onearg_r4 = .true.
> end function ieee_support_divide_onearg_r4
>
> logical function ieee_support_divide_onearg_r8 (x)
> real(8),dimension(::) :: x
> ieee_support_divide_onearg_r8 = .true.
> end function ieee_support_divide_onearg_r8
>
> logical function ieee_support_divide_onearg_r4_scalar (x)
> real(4) :: x
> ieee_support_divide_onearg_r4_scalar = .true.
> end function ieee_support_divide_onearg_r4_scalar
>
> logical function ieee_support_divide_onearg_r8_scalar (x)
> real(8) :: x
> ieee_support_divide_onearg_r8_scalar = .true.
> end function ieee_support_divide_onearg_r8_scalar
>
>
> _______________________________________________
> mpi3-fortran mailing list
> mpi3-fortran at lists.mpi-forum.org
> http://lists.mpi-forum.org/mailman/listinfo.cgi/mpi3-fortran
--
Jeff Squyres
Cisco Systems
More information about the mpiwg-fortran
mailing list