One can think of message transfer as consisting of the following three phases.
To define type matching more precisely, we need to deal with two issues: matching of types of the host language with types specified in communication operations; and matching of types at sender and receiver.
The types of a send and receive match (phase two) if both operations use identical names. That is, MPI_INTEGER matches MPI_INTEGER, MPI_REAL matches MPI_REAL, and so on. There is one exception to this rule, discussed in Sec. Pack and unpack , the type MPI_PACKED can match any other type.
The type of a variable in a host program matches the type specified in the communication operation if the datatype name used by that operation corresponds to the basic type of the host program variable. For example, an entry with type name MPI_INTEGER matches a Fortran variable of type INTEGER. A table giving this correspondence for Fortran and C appears in Sec. Message data . There are two exceptions to this last rule: an entry with type name MPI_BYTE or MPI_PACKED can be used to match any byte of storage (on a byte-addressable machine), irrespective of the datatype of the variable that contains this byte. The type MPI_PACKED is used to send data that has been explicitly packed, or receive data that will be explicitly unpacked, see Section Pack and unpack . The type MPI_BYTE allows one to transfer the binary value of a byte in memory unchanged.
To summarize, the type matching rules fall into the three categories below.
Sender and receiver specify matching types.CALL MPI_COMM_RANK(comm, rank, ierr) IF(rank.EQ.0) THEN CALL MPI_SEND(a(1), 10, MPI_REAL, 1, tag, comm, ierr) ELSE CALL MPI_RECV(b(1), 15, MPI_REAL, 0, tag, comm, status, ierr) END IFThis code is correct if both a and b are real arrays of
size . (In Fortran, it might be correct to use this code
even if a or b have size < 10: e.g., when a(1) can
be equivalenced to an array with ten reals.)
Sender and receiver do not specify matching types.
CALL MPI_COMM_RANK(comm, rank, ierr) IF(rank.EQ.0) THEN CALL MPI_SEND(a(1), 10, MPI_REAL, 1, tag, comm, ierr) ELSE CALL MPI_RECV(b(1), 40, MPI_BYTE, 0, tag, comm, status, ierr) END IFThis code is erroneous, since sender and receiver do not provide
matching datatype arguments.
Sender and receiver specify communication of untyped values.CALL MPI_COMM_RANK(comm, rank, ierr) IF(rank.EQ.0) THEN CALL MPI_SEND(a(1), 40, MPI_BYTE, 1, tag, comm, ierr) ELSE CALL MPI_RECV(b(1), 60, MPI_BYTE, 0, tag, comm, status, ierr) END IFThis code is correct, irrespective of the type and size of a and
b (unless this results in an out of bound memory access).
If a buffer of type MPI_BYTE is passed as an argument to
MPI_SEND, then MPI will send the data stored at contiguous
locations, starting from the address
indicated by the buf argument. This may have unexpected results when
the data layout is not as a casual user would expect it to be.
For example, some Fortran compilers implement variables of type
CHARACTER
as a structure that contains the character length and a pointer to
the actual string. In such an environment, sending and receiving a Fortran
CHARACTER variable using the MPI_BYTE type will not
have the anticipated result of transferring the character string.
For this reason, the user is advised to use typed communications
whenever possible.
( End of advice to users.)
The type MPI_CHARACTER matches one character of a Fortran variable of type CHARACTER, rather then the entire character string stored in the variable. Fortran variables of type CHARACTER or substrings are transferred as if they were arrays of characters. This is illustrated in the example below.
Transfer of Fortran CHARACTERs.
CHARACTER*10 a CHARACTER*10 bThe last five characters of string b at process 1 are replaced by theCALL MPI_COMM_RANK(comm, rank, ierr) IF(rank.EQ.0) THEN CALL MPI_SEND(a, 5, MPI_CHARACTER, 1, tag, comm, ierr) ELSE CALL MPI_RECV(b(6:10), 5, MPI_CHARACTER, 0, tag, comm, status, ierr) END IF
first five characters of string a at process 0.
The alternative choice would be for MPI_CHARACTER to match a character of arbitrary length. This runs into problems.
A Fortran character variable is a constant length string, with no special termination symbol. There is no fixed convention on how to represent characters, and how to store their length. Some compilers pass a character argument to a routine as a pair of arguments, one holding the address of the string and the other holding the length of string. Consider the case of an MPI communication call that is passed a communication buffer with type defined by a derived datatype (Section Derived datatypes ). If this communicator buffer contains variables of type CHARACTER then the information on their length will not be passed to the MPI routine.
This problem forces us to provide explicit information on character
length with the MPI call. One could add a length parameter to the
type MPI_CHARACTER, but this does not add much convenience and the same
functionality can be achieved by defining a suitable derived datatype.
( End of rationale.)
[] Advice
to implementors.
Some compilers pass Fortran CHARACTER arguments as a structure with a
length and a pointer to the actual string. In such an environment, the MPI
call needs to dereference the pointer in order to reach the string.
( End of advice to implementors.)