Next: Pack and unpack
Up: Point-to-Point Communication
Previous: Null processes
Contents
Derived datatypes
In C or Fortran bindings of MPI, derived datatypes have two roles.
One is to allow messages to contain mixed types (for example they
allow an integer count followed by a sequence of real numbers to be
passed in a single message). The other is to allow noncontiguous data
to be transmitted.
In the Java binding presented here the first role is abandoned.
Any derived type can only include elements of a single basic type.
- Rationale. In the C binding of MPI, for example, the MPI_TYPE_STRUCT
constructor for derived types might be used to describe the physical
layout of a struct containing mixed types. This will not
work in Java, because Java does not expose the low-level layout of its
objects. In C and Fortran another use of MPI_TYPE_STRUCT
involves incorporating offsets computed as differences between absolute
addresses, so that parts of a message can come from separately declared
entities. It might be possible to contrive something analogous in a Java
binding, somehow encoding object references instead of physical
addresses. Such a device is likely to be
cumbersome--even in the C and Fortran the mechanism is not
particularly elegant.
Meanwhile, the effect of either of these applications of
MPI_TYPE_STRUCT can be achieved by using MPI.OBJECT
as the buffer type, and relying on Java object serialization.(End of rationale.)
This leaves description of noncontiguous buffers as the
essential role for derived data types in the Java binding.
Every derived data type constructable in the Java binding has
a uniquely defined base type. This is one of the 9 basic
types enumerated in section A.3.2.
Derived types inherit their base types from their precursors in
a straightforward way.
In the proposed binding a general datatype is an object that
specifies two things
- A base type
- A sequence of integer displacements
In contrast to the C and Fortran bindings the displacements are
in terms of subscripts in the buffer array argument, not
byte displacements.
The base types for the predefined MPI datatypes are
| MPI datatype |
base type |
| MPI.BYTE |
byte |
| MPI.CHAR |
char |
| MPI.SHORT |
short |
| MPI.BOOLEAN |
boolean |
| MPI.INT |
int |
| MPI.LONG |
long |
| MPI.FLOAT |
float |
| MPI.DOUBLE |
double |
| MPI.OBJECT |
Object |
| MPI.LB |
 |
| MPI.UB |
 |
| MPI.PACKED |
byte |
The symbol
is a special undefined value.
The displacement sequence for the predefined types consists of a single zero.
If the displacement sequence of a datatype is
then
- Rationale. This definition of the extent differs from the definition in the C or
Fortran. It is in units of the buffer array index, not in units
of bytes.(End of rationale.)
- Advice to implementors. In a JNI-based wrapper implementation, the return values of the
extent, size, lb and ub inquiries will
have to be suitably scaled from the result obtained from the
corresponding C inquiries.(End of advice to implementors.)
These definitions have to be modified if the type construction involves
MPI.LB, MPI.UB.
Datatype Datatype.contiguous(int count)
| count |
replication count |
| |
|
| returns: |
new datatype |
Construct new datatype representing replication of this datatype into
contiguous locations.
Java binding of the MPI operation MPI_TYPE_CONTIGUOUS.
The base type of the new datatype is the same as the base type of
this type. Assume the displacement sequence of this type is
with extent ex. Then the new datatype has a displacement sequence
with count
n entries defined by:
Datatype Datatype.vector(int count, int blocklength, int stride)
| count |
number of blocks |
| blocklength |
number of elements in each block |
| stride |
number of elements between start of each block |
| |
|
| returns: |
new datatype |
Construct new datatype representing replication of this datatype into
locations that consist of equally spaced blocks.
Java binding of the MPI operation MPI_TYPE_VECTOR.
The base type of the new datatype is the same as the base type of
this type. Assume the displacement sequence of this type is
with extent ex. Let bl be blocklength.
Then the new datatype has a displacement sequence
with count
bl
n entries defined by:
Datatype Datatype.hvector(int count, int blocklength, int stride)
| count |
number of blocks |
| blocklength |
number of elements in each block |
| stride |
number of elements between start of each block |
| |
|
| returns: |
new datatype |
Identical to vector except that the stride is expressed
directly in terms of the buffer index, rather than the units of this type.
Java binding of the MPI operation MPI_TYPE_HVECTOR.
Unlike other language bindings, the value
of stride is not measured in bytes.
The displacement sequence of the new type is:
Datatype Datatype.indexed(int [] arrayOfBlocklengths,
int [] arrayOfDisplacements)
| arrayOfBlocklengths |
number of elements per block |
| arrayOfDisplacements |
displacement of each block in units of old type |
| |
|
| returns: |
new datatype |
Construct new datatype representing replication of this type into
a sequence of blocks where each block can contain a different number
of copies and have a different displacement.
Java binding of the MPI operation MPI_TYPE_INDEXED. The number
of blocks is taken to be size of the arrayOfBlocklengths
argument. The second argument, arrayOfDisplacements, should
be the same size.
The base type of the new datatype is the same as the base type of
this type. Assume the displacement sequence of this type is
with extent ex. Let B be the arrayOfBlocklengths
argument and D be the arrayOfDisplacements argument.
Then the new datatype has a displacement sequence with
entries:
Here, count is the number of blocks.
Datatype Datatype.hindexed(int [] array_of_blocklengths,
int [] array_of_displacements)
| arrayOfBlocklengths |
number of elements per block |
| arrayOfDisplacements |
displacement in buffer for each block |
| |
|
| returns: |
new datatype |
Identical to indexed except that the displacements are expressed
directly in terms of the buffer index, rather than the units of this type.
Java binding of the MPI operation MPI_TYPE_HINDEXED.
Unlike other language bindings, the values
in arrayOfDisplacements are not measured in bytes.
The displacement sequence of the new type is:
static Datatype Datatype.struct(int [] arrayOfBlocklengths,
int [] arrayOfDisplacements,
Datatype [] arrayOfTypes)
| arrayOfBlocklengths |
number of elements per block |
| arrayOfDisplacements |
displacement in buffer for each block |
| arrayOfTypes |
type of elements in each block |
| |
|
| returns: |
new datatype |
The most general type constructor.
Java binding of the MPI operation MPI_TYPE_STRUCT. The number
of blocks is taken to be size of the arrayOfBlocklengths
argument. The second and third arguments, arrayOfDisplacements
and arrayOfTypes, should be the same size.
Unlike other language bindings, the values
in arrayOfDisplacements are not measured in bytes.
All elements of arrayOfTypes with definite base types must have the
same base type: this will be the base type of new datatype.
Let T be the arrayOfTypes argument.
Assume the displacement sequence of the old type
is
with extent
. Let B be the arrayOfBlocklengths
argument and D be the arrayOfDisplacements argument.
Then the new datatype has a displacement sequence with
entries:
Here,
is the number of blocks.
If any elements of arrayOfTypes are MPI.LB or MPI.UB,
the corresponding displacements are omitted in the displacement
sequence. These displacements only affect the computation of
Datatype.lb, Datatype.ub and Datatype.extent,
as explained below.
int Datatype.extent()
Returns the extent of a datatype.
Java binding of the MPI operation MPI_TYPE_EXTENT.
Return value is equal to
int Datatype.size()
Returns the total size of the type.
Java binding of the MPI operation MPI_TYPE_SIZE.
Size is defined as the total number of buffer elements incorporated by
the data type, or equivalently as the length of the displacement
sequence. Unlike other language bindings, the size is not
measured in bytes.
int Datatype.lb()
| returns: |
displacement of lower bound from origin |
Find the lower bound of a datatype.
Java binding of the MPI operation MPI_TYPE_LB.
Assume the displacement sequence of the datatype is
In general the return value of lb is
However, if construction of the derived type involved any basic
components of type MPI.LB, the return value is the least
displacement specified for any of those MPI.LB fields, regardless
of the values appearing in the displacement list proper.
int Datatype.ub()
| returns: |
displacement of upper bound from origin |
Find the upper bound of a datatype.
Java binding of the MPI operation MPI_TYPE_UB.
Assume the displacement sequence of the datatype is
In general the return value of lb is
However, if construction of the derived type involved any basic
components of type MPI.UB, the return value is the largest
displacement specified for any of those MPI.UB fields, regardless
of the values appearing in the displacement list proper.
- Advice to implementors. Meeting the detailed requirements of the MPI standard regarding
handling of MPI.UB and MPI.LB needs some extra care.
A possible implementation is to maintain two separate
``pseudo-displacements'' whose values are undefined unless a MPI.UB (respectively MPI.LB) has appeared somewhere. If
defined, these extra displacements are propagated to derived types
using the same formulae as for true displacements, except that only the
greatest (respectively least) term contributed by any precursor
pseudo-displacement need be retained as the pseudo-displacement
for the new type.(End of advice to implementors.)
void Datatype.commit()
Commit a derived datatype.
Java binding of the MPI operation MPI_TYPE_COMMIT.
void Datatype.finalize()
Destructor. Java binding of the MPI operation MPI_TYPE_FREE.
int Status.getElements(Datatype datatype)
| datatype |
datatype used by receive operation |
| |
|
| returns: |
number of received basic elements |
Retrieve number of basic elements from status.
Java binding of the MPI operation MPI_GET_ELEMENTS.
Next: Pack and unpack
Up: Point-to-Point Communication
Previous: Null processes
Contents
Bryan Carpenter
2002-07-12