MPI Derived Types
Modern programming languages provide data structures that may be called “structs,” or “classes,” or “types.” These data structures permit grouping of different quantities under a single variable name.
MPI also provides a general type that enables programmer-defined datatypes. Unlike arrays, which must be adjacent in memory, MPI derived datatypes may consist of elements in non-contiguous locations in memory.
While more general derived MPI datatypes are available, one of the most commonly used is the MPI_TYPE_VECTOR
. This creates a group of elements of size blocklength separated by a constant interval, called the stride, in memory. Examples would be generating a type for columns in a row-major-oriented language, or rows in a column-major-oriented language.
C++
MPI_Datatype newtype;
MPI_Type_vector(ncount, blocklength, stride, oldtype, newtype);
Fortran
integer newtype
!code
call MPI_TYPE_VECTOR(ncount, blocklength, stride, oldtype, newtype, ierr)
For both C++ and Fortran, ncount
, blocklength
, and stride
must be integers. The oldtype
is a pre-existing type, usually a built-in MPI Type such as MPI_FLOAT or MPI_REAL. For C++ the new type would be declared as an MPI_Datatype
, unless it corresponds to an existing built-in type. For Fortran oldtype
would be an integer if not a built-in type. The newtype
is a name chosen by the programmer.
Python
newtype = oldtype.Create_vector(ncount, blocklength, stride)
A derived type must be committed before it can be used.
MPI_Type_commit(newtype)
Fortran
call MPI_TYPE_COMMIT(newtype,ierr)
Python
newtype.Commit()
To use our newly committed type in an MPI communication function, we must pass it the starting position of the data to be placed into the type.
C++
MPI_Send(&a[0][i],1,newtype,i,MPI_COMM_WORLD);
//We need to pass the first element by reference because an array element
//is not a pointer
Fortran
MPI_Send(a(1)(i),1,newtype,i,MPI_COMM_WORLD,ierr)