Some existing communication libraries provide pack/unpack functions for sending noncontiguous data. In these, the user explicitly packs data into a contiguous buffer before sending it, and unpacks it from a contiguous buffer after receiving it. Derived datatypes, which are described in Section Derived Datatypes , allow one, in most cases, to avoid explicit packing and unpacking. The user specifies the layout of the data to be sent or received, and the communication library directly accesses a noncontiguous buffer. The pack/unpack routines are provided for compatibility with previous libraries. Also, they provide some functionality that is not otherwise available in MPI. For instance, a message can be received in several parts, where the receive operation done on a later part may depend on the content of a former part. Another use is that outgoing messages may be explicitly buffered in user supplied space, thus overriding the system buffering policy. Finally, the availability of pack and unpack operations facilitates the development of additional communication libraries layered on top of MPI.
MPI_PACK(inbuf, incount, datatype, outbuf, outsize, position, comm) | |
IN inbuf | input buffer start (choice) |
IN incount | number of input data items (non-negative integer) |
IN datatype | datatype of each input data item (handle) |
OUT outbuf | output buffer start (choice) |
IN outsize | output buffer size, in bytes (non-negative integer) |
INOUT position | current position in buffer, in bytes (integer) |
IN comm | communicator for packed message (handle) |
int MPI_Pack(void* inbuf, int incount, MPI_Datatype datatype, void *outbuf, int outsize, int *position, MPI_Comm comm)
MPI_PACK(INBUF, INCOUNT, DATATYPE, OUTBUF, OUTSIZE, POSITION, COMM, IERROR)
The input value of position is the first
location in the output buffer to be used for packing. position is
incremented by the size of the packed message, and the output value of
position is the first location in the output buffer
following the locations occupied by the packed message.
The comm argument
is the communicator that will be subsequently used for sending the packed
message.
int MPI_Unpack(void* inbuf, int insize, int *position, void *outbuf, int outcount, MPI_Datatype datatype, MPI_Comm comm)
MPI_UNPACK(INBUF, INSIZE, POSITION, OUTBUF, OUTCOUNT, DATATYPE, COMM, IERROR)
Note the difference between MPI_RECV and MPI_UNPACK: in
MPI_RECV, the count argument specifies the maximum
number of
items that can be received. The actual number of items received is determined
by the length of the incoming message. In MPI_UNPACK, the
count argument specifies the actual number
of items that are unpacked;
the ``size'' of the corresponding message is the increment in
position.
The reason for this change is that the ``incoming message size'' is not
predetermined since the user decides how much to unpack; nor is it easy to
determine
the ``message size'' from the number of items to be unpacked. In fact, in a
heterogeneous system, this number may not be determined a priori.
( End of advice to users.)
Several messages can be successively packed into one packing unit. This
is effected by several successive related calls to MPI_PACK,
where the first
call provides position = 0, and each successive call inputs the value
of position that was output by the previous call, and the same values
for outbuf, outcount and comm. This packing unit
now contains
the equivalent information that would have been stored in a message by one send
call with a send buffer that is the ``concatenation'' of the individual send
buffers.
A packing unit can
be sent using type MPI_PACKED. Any point to point
or collective communication function can be used to move the sequence of bytes
that forms the packing unit from one process to another. This packing unit
can now be
received using any receive operation, with any datatype: the
type matching rules are relaxed for messages sent with type MPI_PACKED.
A message sent with any type (including MPI_PACKED) can be
received using the type MPI_PACKED. Such a message can then be
unpacked by calls to MPI_UNPACK.
A packing unit (or a message created by a regular, ``typed'' send)
can be unpacked into several successive messages. This is
effected by several successive related calls to MPI_UNPACK, where
the first
call provides position = 0, and each successive call inputs the value
of position that was output by the previous call, and the same values
for inbuf, insize and comm.
The concatenation of two packing units is not necessarily a packing unit; nor is
a substring of a packing unit necessarily a packing unit. Thus, one cannot
concatenate two packing units and then unpack the result as one packing
unit; nor can one unpack a substring of a packing unit as a separate
packing unit. Each packing unit, that was created by a related
sequence of pack
calls, or by a regular send,
must be unpacked as a unit, by a sequence of related unpack calls.
The restriction on ``atomic'' packing and unpacking of packing units allows
the implementation to add at the head of packing units additional
information, such as
a description of the sender architecture (to be used for type conversion, in a
heterogeneous environment)
( End of rationale.)
int MPI_Pack_size(int incount, MPI_Datatype datatype, MPI_Comm comm, int *size)
MPI_PACK_SIZE(INCOUNT, DATATYPE, COMM, SIZE, IERROR)
The call returns an upper bound, rather than an exact bound, since the
exact amount of space needed to pack the message may depend on the
context (e.g., first message packed in a packing unit may take more
space).
( End of rationale.)
<type> INBUF(*), OUTBUF(*)
INTEGER INCOUNT, DATATYPE, OUTSIZE, POSITION, COMM, IERROR
{ void MPI::Datatype::Pack(const void* inbuf, int incount, void *outbuf, int outsize, int& position, const MPI::Comm &comm) const (binding deprecated, see Section Deprecated since MPI-2.2
) }
Packs the message in the send buffer specified by inbuf, incount,
datatype into the buffer
space specified by outbuf and
outsize. The
input buffer can
be any communication buffer allowed in MPI_SEND. The output buffer
is a contiguous storage area containing outsize bytes, starting at
the address outbuf (length is counted in bytes, not elements,
as if it were a communication buffer for a message of type MPI_PACKED).
MPI_UNPACK(inbuf, insize, position, outbuf, outcount,
datatype, comm) IN inbuf input buffer start (choice) IN insize size of input buffer, in bytes (non-negative
integer) INOUT position current position in bytes (integer) OUT outbuf output buffer start (choice) IN outcount number of items to be unpacked (integer) IN datatype datatype of each output data item (handle) IN comm communicator for packed message (handle)
<type> INBUF(*), OUTBUF(*)
INTEGER INSIZE, POSITION, OUTCOUNT, DATATYPE, COMM, IERROR
{ void MPI::Datatype::Unpack(const void* inbuf, int insize, void *outbuf, int outcount, int& position, const MPI::Comm& comm) const (binding deprecated, see Section Deprecated since MPI-2.2
) }
Unpacks a message into the receive buffer specified by outbuf,
outcount,
datatype from the buffer
space specified by inbuf and insize. The output buffer can
be any communication buffer allowed in MPI_RECV. The input
buffer is a contiguous storage area containing insize bytes,
starting at address inbuf.
The input value of position is the first location in
the input buffer occupied by the packed message.
position is incremented
by the size of the packed message, so that the output value of
position is the first location in the input buffer
after the locations occupied by the message that was unpacked.
comm is the communicator used to receive the packed message.
Advice to users.
To understand the behavior of pack and unpack, it is convenient to think of the
data part of a message as being the sequence obtained by concatenating the
successive values sent in that message. The pack operation stores this
sequence in the buffer space, as if sending the message to that buffer. The
unpack operation retrieves this sequence from buffer space, as if receiving a
message from that buffer. (It is helpful to think of internal Fortran files or
sscanf in C, for a similar function.)
Rationale.
The following call allows the user to find out how much space is
needed to pack a message and, thus, manage space allocation for
buffers.
MPI_PACK_SIZE(incount, datatype, comm, size) IN incount count argument to packing call (non-negative
integer) IN datatype datatype argument to packing call (handle) IN comm communicator argument to packing call (handle) OUT size upper bound on size of packed message, in bytes (non-negative
integer)
INTEGER INCOUNT, DATATYPE, COMM, SIZE, IERROR
{ int MPI::Datatype::Pack_size(int incount, const MPI::Comm& comm) const (binding deprecated, see Section Deprecated since MPI-2.2
) }
A call to MPI_PACK_SIZE(incount, datatype, comm, size)
returns in size an upper bound on the increment in position
that is effected by a call to MPI_PACK(inbuf, incount, datatype,
outbuf, outcount, position, comm).
Rationale.
Example
An example using MPI_PACK.
Example
An elaborate example.
Example
Each process sends a count, followed by count characters to the root;
the root
concatenates
all characters into one string.
Up: Contents
Next: Canonical MPI_PACK and MPI_UNPACK
Previous: Examples
Return to MPI-2.2 Standard Index
Return to MPI Forum Home Page
(Unofficial) MPI-2.2 of September 4, 2009
HTML Generated on September 10, 2009