next up previous index
Next: Datatype Constructors Up: Message Passing Interface: Advanced Previous: Multiple Completions

Derived Data Types

This stuff is used for polymorphic messages, i.e., messages that are made of compound items comprising various generic data types, e.g., integers, floats, and characters - all in a single data block. Derived data types are also used to transfer data from non-contiguous buffers, e.g., a portion of a matrix. To this effect MPI lets programmers specify mixed and non-contiguous communication buffers, so that objects of various shapes and sizes can be transferred directly without copying.

However, MPI as it is defined and implemented today, has no means of figuring out on its own how such data is laid out in the host language, i.e., C, F77, or F95. This information could, in principle, be obtained by decoding definitions from a symbol table, but no attempt has been made in the MPI definition to incorporate this. Consequently it befalls the programmer to figure this out and then define matching derived MPI datatypes.

Neither does MPI specify how such transfers are to be implemented. It is still possible that an actual MPI implementation would copy all the data to an auxiliary contiguous buffer before transfer. But MPI semantics allow for a direct transfer from non-contiguous memory locations, and for a direct transfer of polymorphic data blocks.

An MPI programmer defines a new derived data type by specifying its map and its signature. This can be done recursively, i.e., an already defined data type can be used in constructing a new map. Furthermore, all MPI data type definitions occur during program execution. Consequently various MPI derived types can be associated with the same name as the program unfolds.

A type map is a sequence of the following form

Typemap = {(type_0, disp_0), ..., (type_{n-1}, disp_{n-1})}
In turn a type signature is the following sequence
Typesig = {type_0, ..., type_{n-1}}

General MPI datatypes can be used in all send and receive operations. Basic data types can be thought of as special cases of general data types, for example:

MPI_INT = {(int, 0)}

The extent of a general datatype is a span from the first to the last byte occupied by entries in the datatype rounded up to satisfy alignment requirements, if any

extent(typemap) = ub(typemap) - lb(typemap)
where ub stands for the upper bound and lb stands for the lower bound, for example:
extent({(double, 0), (char, 8)}) = 16
Here the size is 16 B (16 bytes), rather than 9 B because the data item must be padded to the next word boundary.

In the following we are going to look first at MPI derived data type constructors, then at auxiliary functions that return an address of a variable and an extent, upper and lower bound markers for a defined datatype. Then we'll talk about committing and freeing a datatype and what it means and finally we'll have a look at some examples.

next up previous index
Next: Datatype Constructors Up: Message Passing Interface: Advanced Previous: Multiple Completions
Zdzislaw Meglicki