All MPI communication functions take a
datatype argument. In the
simplest case this will be a primitive type, such as an integer or
floating-point number. An important and powerful generalization results
by allowing user-defined (or ``derived'') types wherever the primitive
types can occur. These are not ``types'' as far as the programming
language is concerned. They are only ``types'' in that MPI is made
aware of them through the use of type-constructor functions, and they
describe the layout, in memory, of sets of primitive types. Through
user-defined types, MPI supports the communication of
complex data structures such as array sections and structures containing
combinations of primitive datatypes. Example shows how
a user-defined datatype is used to send the upper-triangular part
of a matrix, and Figure
diagrams the memory layout
represented by the user-defined datatype.
derived datatype constructor
Figure: A diagram of the memory cells represented by the user-defined
datatype upper. The shaded cells are the locations of the array
that will be sent.
Derived datatypes
are constructed from basic datatypes using the constructors described
in Section . The constructors can
be applied recursively.
A derived datatype is an opaque object that specifies two things:
o A sequence of primitive datatypes and, o A sequence of integer (byte) displacements.The displacements are not required to be positive, distinct, or in increasing order. Therefore, the order of items need not coincide with their order in memory, and an item may appear more than once. We call such a pair of sequences (or sequence of pairs) a type map. The sequence of primitive datatypes (displacements ignored) is the type signature of the datatype. type maptype signature derived datatype, mapderived datatype, signature
Let
be such a type map, where type are primitive types, and disp are displacements. Let
be the associated type signature. This type map, together with a base address buf, specifies a communication buffer: the communication buffer that consists of n entries, where the i-th entry is at address buf + desp and has type type . A message assembled from a single type of this sort will consist of n values, of the types defined by Typesing .
A handle to a derived datatype can appear as an argument in a send or receive operation, instead of a primitive datatype argument. The operation MPI_SEND(buf, 1, datatype,...) will use the send buffer defined by the base address buf and the derived datatype associated with datatype. It will generate a message with the type signature determined by the datatype argument. MPI_RECV(buf, 1, datatype,...) will use the receive buffer defined by the base address buf and the derived datatype associated with datatype.
Derived datatypes can be used in all send and receive operations
including collective. We discuss, in
Section , the case where the second argument
count has value > 1.
The primitive datatypes presented in
Section
are special cases of a derived datatype, and are predefined.
Thus, MPI_INT is a predefined handle to a datatype with type
MPI_INT
map {(int,0)}, with one entry of type int and
displacement zero. The other primitive datatypes are similar.
The extent of a datatype is defined to be the span from the first byte to the last byte occupied by entries in this datatype, rounded up to satisfy alignment requirements. extentderived datatype, extent That is, if
then
extent(Typeman) = ub(Typemap) - lb(Typemap).where j = 0,-----,n-1. lb is the lower bound and ub is the upper bound of the datatype. lower boundderived datatype, lower bound upper boundderived datatype, upper bound If type requires alignment to a byte address that is a multiple of k , then a is the least nonnegative increment needed to round extent(Typemap) to the next multiple of max k . (The definition of extent is expanded in Section
The following functions return information on datatypes.
MPI_TYPE_EXTENT(datatype, extent) IN datatype datatype OUT extent datatype extentMPI_Type_extent(MPI_Datatype datatype, MPI_Aint *extent)
MPI_TYPE_EXTENT(DATATYPE, EXTENT, IERROR)INTEGER DATATYPE, EXTENT, IERROR
MPI_TYPE_EXTENT returns the extent of a datatype. In addition to its use with derived datatypes, it can be used to inquire about the extent of primitive datatypes. For example, MPI_TYPE_EXTENT(MPI_INT, extent) will return in extent the size, in bytes, of an int - the same value that would be returned by the C call sizeof(int).
MPI_Type_size(MPI_Datatype datatype, int *size)
MPI_TYPE_SIZE(DATATYPE, SIZE, IERROR)INTEGER DATATYPE, SIZE, IERROR
MPI_TYPE_SIZE returns the total size, in bytes, of the entries in the type signature associated with datatype; that is, the total size of the data in a message that would be created with this datatype. Entries that occur multiple times in the datatype are counted with their multiplicity. For primitive datatypes, this function returns the same information as MPI_TYPE_EXTENT.