78. Lower-Bound and Upper-Bound Markers

PreviousUpNext
Up: Derived Datatypes Next: Extent and Bounds of Datatypes Previous: Address and Size Functions

It is often convenient to define explicitly the lower bound and upper bound of a type map, and override the definition given on page Lower-Bound and Upper-Bound Markers . This allows one to define a datatype that has ``holes'' at its beginning or its end, or a datatype with entries that extend above the upper bound or below the lower bound. Examples of such usage are provided in Section Examples . Also, the user may want to overide the alignment rules that are used to compute upper bounds and extents. E.g., a C compiler may allow the user to overide default alignment rules for some of the structures within a program. The user has to specify explicitly the bounds of the datatypes that match these structures.

To achieve this, we add two additional conceptual datatypes, lb_marker and ub_marker, that represent the lower bound and upper bound of a datatype. These conceptual datatypes occupy no space (extent(mpiublblb_marker) = extent(mpiublbub_marker) =0) . They do not affect the size or count of a datatype, and do not affect the content of a message created with this datatype. However, they do affect the definition of the extent of a datatype and, therefore, affect the outcome of a replication of this datatype by a datatype constructor.


Example A call to MPI_TYPE_CREATE_RESIZED(MPI_INT, -3, 9, type1) creates a new datatype that has an extent of 9 (from -3 to 5, 5 included), and contains an integer at displacement 0. This is the datatype defined by the typemap {( lb_marker, -3), (int, 0), ( ub_marker, 6)}. If this type is replicated twice by a call to MPI_TYPE_CONTIGUOUS(2, type1, type2) then the newly created type can be described by the typemap {( lb_marker, -3), (int, 0), (int,9), ( ub_marker, 15)}. (An entry of type ub_marker can be deleted if there is another entry of type ub_marker with a higher displacement; an entry of type lb_marker can be deleted if there is another entry of type lb_marker with a lower displacement.)

In general, if Typemap = { (type0 , disp0 ) , ... , (typen-1 , dispn-1) } , then the lower bound of Typemap is defined to be

Image file

Similarly, the upper bound of Typemap is defined to be

Image file

Then

extent(Typemap) = ub(Typemap) - lb(Typemap)

If typei requires alignment to a byte address that is a multiple of ki, then Image file is the least non-negative increment needed to round extent(Typemap) to the next multiple of Image file . In Fortran, it is implementation dependent whether the MPI implementation computes the alignments ki according to the alignments used by the compiler in common blocks, SEQUENCE derived types, BIND(C) derived types, or derived types that are neither SEQUENCE nor BIND(C).

The formal definitions given for the various datatype constructors apply now, with the amended definition of extent.


Rationale.

Before Fortran 2003, MPI_TYPE_CREATE_STRUCT could be applied to Fortran common blocks and SEQUENCE derived types. With Fortran 2003, this list was extended by BIND(C) derived types and MPI implementors have implemented the alignments ki differently, i.e., some based on the alignments used in SEQUENCE derived types, and others according to BIND(C) derived types. ( End of rationale.)

Advice to implementors.

In Fortran, it is generally recommended to use BIND(C) derived types instead of common blocks or SEQUENCE derived types. Therefore it is recommended to calculate the alignments ki based on BIND(C) derived types. ( End of advice to implementors.)

Advice to users.

Structures combining different basic datatypes should be defined so that there will be no gaps based on alignment rules. If such a datatype is used to create an array of structures, users should also avoid an alignment-gap at the end of the structure. In MPI communication, the content of such gaps would not be communicated into the receiver's buffer. For example, such an alignment-gap may occur between an odd number of floats or REALs before a double or DOUBLE PRECISION data. Such gaps may be added explicitly to both the structure and the MPI derived datatype handle because the communication of a contiguous derived datatype may be significantly faster than the communication of one that is non-contiguous because of such alignment-gaps.

Example: Instead of


  TYPE, BIND(C) :: my_data 
    REAL, DIMENSION(3) :: x 
    ! there may be a gap of the size of one REAL 
    ! if the alignment of a DOUBLE PRECISION is  
    ! two times the size of a REAL 
    DOUBLE PRECISION :: p 
  END TYPE 
one should define


  TYPE, BIND(C) :: my_data 
    REAL, DIMENSION(3) :: x 
    REAL :: gap1 
    DOUBLE PRECISION :: p 
  END TYPE 
and also include gap1 in the matching MPI derived datatype. It is required that all processes in a communication add the same gaps, i.e., defined with the same basic datatype. Both the original and the modified structures are portable, but may have different performance implications for the communication and memory accesses during computation on systems with different alignment values.

In principle, a compiler may define an additional alignment rule for structures, e.g., to use at least 4 or 8 byte alignment, although the content may have a maxi ki alignment less than this structure alignment. To maintain portability, users should always resize structure derived datatype handles if used in an array of structures, see the Example in Section Fortran Derived Types . ( End of advice to users.)


PreviousUpNext
Up: Derived Datatypes Next: Extent and Bounds of Datatypes Previous: Address and Size Functions


Return to MPI-3.1 Standard Index
Return to MPI Forum Home Page

(Unofficial) MPI-3.1 of June 4, 2015
HTML Generated on June 4, 2015