6.1.13. Decoding a Datatype

PreviousUpNext
Up: Derived Datatypes Next: Examples Previous: Correct Use of Addresses

MPI datatype objects allow users to specify an arbitrary layout of data in memory. There are several cases where accessing the layout information in opaque datatype objects would be useful. The opaque datatype object has found a number of uses outside MPI. Furthermore, a number of tools wish to display internal information about a datatype. To achieve this, datatype decoding procedures are provided. The two procedures in this section are used together to decode datatypes to recreate the calling sequence used in their initial definition. These can be used to allow a user to determine the type map and type signature of a datatype.

MPI_TYPE_GET_ENVELOPE(datatype, num_integers, num_addresses, num_large_counts, num_datatypes, combiner)
IN datatypedatatype to decode (handle)
OUT num_integersnumber of input integers used in call constructing combiner (non-negative integer)
OUT num_addressesnumber of input addresses used in call constructing combiner (non-negative integer)
OUT num_large_countsnumber of input large counts used in call constructing combiner (non-negative integer, only present for large count variants)
OUT num_datatypesnumber of input datatypes used in call constructing combiner (non-negative integer)
OUT combinercombiner (state)
C binding
int MPI_Type_get_envelope(MPI_Datatype datatype, int *num_integers, int *num_addresses, int *num_datatypes, int *combiner)
int MPI_Type_get_envelope_c(MPI_Datatype datatype, MPI_Count *num_integers, MPI_Count *num_addresses, MPI_Count *num_large_counts, MPI_Count *num_datatypes, int *combiner)
Fortran 2008 binding
MPI_Type_get_envelope(datatype, num_integers, num_addresses, num_datatypes, combiner, ierror)

TYPE(MPI_Datatype), INTENT(IN) :: datatype
INTEGER, INTENT(OUT) :: num_integers, num_addresses, num_datatypes, combiner
INTEGER, OPTIONAL, INTENT(OUT) :: ierror
MPI_Type_get_envelope(datatype, num_integers, num_addresses, num_large_counts, num_datatypes, combiner, ierror) !(_c)

TYPE(MPI_Datatype), INTENT(IN) :: datatype
INTEGER(KIND=MPI_COUNT_KIND), INTENT(OUT) :: num_integers, num_addresses, num_large_counts, num_datatypes
INTEGER, INTENT(OUT) :: combiner
INTEGER, OPTIONAL, INTENT(OUT) :: ierror
Fortran binding
MPI_TYPE_GET_ENVELOPE(DATATYPE, NUM_INTEGERS, NUM_ADDRESSES, NUM_DATATYPES, COMBINER, IERROR)

INTEGER DATATYPE, NUM_INTEGERS, NUM_ADDRESSES, NUM_DATATYPES, COMBINER, IERROR

For the given datatype, MPI_TYPE_GET_ENVELOPE returns information on the number and type of input arguments used in the call that created the datatype. The number-of-arguments values returned can be used to provide sufficiently large arrays in the decoding routine MPI_TYPE_GET_CONTENTS. This call and the meaning of the returned values is described below. The combiner reflects the MPI datatype constructor call that was used in creating datatype.


Rationale.

By requiring that the combiner reflect the constructor used in the creation of the datatype, the decoded information can be used to effectively recreate the calling sequence used in the original creation. This is the most useful information and was felt to be reasonable even though it constrains implementations to remember the original constructor sequence even if the internal representation is different.

The decoded information keeps track of datatype duplications. This is important as one needs to distinguish between a predefined datatype and a dup of a predefined datatype. The former is a constant object that cannot be freed, while the latter is a derived datatype that can be freed. ( End of rationale.)
The list of values that can be returned from MPI_TYPE_GET_ENVELOPE in combiner (on the left) and the call associated with them (on the right) are as follows:

Image file

If combiner is MPI_COMBINER_NAMED then datatype is a named predefined datatype.

If the MPI_TYPE_GET_ENVELOPE variant without num_large_counts is invoked with a datatype that requires an output value of num_large_counts >0, then an error of class MPI_ERR_TYPE is raised.


Rationale.

The large count variant of this MPI procedure was added in MPI-4. It contains a new num_large_counts parameter. The other variant---the variant that existed before MPI-4---was not changed in order to preserve backwards compatibility. ( End of rationale.)
The actual arguments used in the creation call for a datatype can be obtained using MPI_TYPE_GET_CONTENTS.

MPI_TYPE_GET_ENVELOPE and MPI_TYPE_GET_CONTENTS also support large count types in separate additional MPI procedures in C (suffixed with the ``_c'') and interface polymorphism in Fortran when using USE mpi_f08.

MPI_TYPE_GET_CONTENTS(datatype, max_integers, max_addresses, max_large_counts, max_datatypes, array_of_integers, array_of_addresses, array_of_large_counts, array_of_datatypes)
IN datatypedatatype to decode (handle)
IN max_integersnumber of elements in array_of_integers (non-negative integer)
IN max_addressesnumber of elements in array_of_addresses (non-negative integer)
IN max_large_countsnumber of elements in array_of_large_counts (non-negative integer, only present for large count variants)
IN max_datatypesnumber of elements in array_of_datatypes (non-negative integer)
OUT array_of_integerscontains integer arguments used in constructing datatype (array of integers)
OUT array_of_addressescontains address arguments used in constructing datatype (array of integers)
OUT array_of_large_countscontains large count arguments used in constructing datatype (array of integers, only present for large count variants)
OUT array_of_datatypescontains datatype arguments used in constructing datatype (array of handles)
C binding
int MPI_Type_get_contents(MPI_Datatype datatype, int max_integers, int max_addresses, int max_datatypes, int array_of_integers[], MPI_Aint array_of_addresses[], MPI_Datatype array_of_datatypes[])
int MPI_Type_get_contents_c(MPI_Datatype datatype, MPI_Count max_integers, MPI_Count max_addresses, MPI_Count max_large_counts, MPI_Count max_datatypes, int array_of_integers[], MPI_Aint array_of_addresses[], MPI_Count array_of_large_counts[], MPI_Datatype array_of_datatypes[])
Fortran 2008 binding
MPI_Type_get_contents(datatype, max_integers, max_addresses, max_datatypes, array_of_integers, array_of_addresses, array_of_datatypes, ierror)

TYPE(MPI_Datatype), INTENT(IN) :: datatype
INTEGER, INTENT(IN) :: max_integers, max_addresses, max_datatypes
INTEGER, INTENT(OUT) :: array_of_integers(max_integers)
INTEGER(KIND=MPI_ADDRESS_KIND), INTENT(OUT) :: array_of_addresses(max_addresses)
TYPE(MPI_Datatype), INTENT(OUT) :: array_of_datatypes(max_datatypes)
INTEGER, OPTIONAL, INTENT(OUT) :: ierror
MPI_Type_get_contents(datatype, max_integers, max_addresses, max_large_counts, max_datatypes, array_of_integers, array_of_addresses, array_of_large_counts, array_of_datatypes, ierror) !(_c)

TYPE(MPI_Datatype), INTENT(IN) :: datatype
INTEGER(KIND=MPI_COUNT_KIND), INTENT(IN) :: max_integers, max_addresses, max_large_counts, max_datatypes
INTEGER, INTENT(OUT) :: array_of_integers(max_integers)
INTEGER(KIND=MPI_ADDRESS_KIND), INTENT(OUT) :: array_of_addresses(max_addresses)
INTEGER(KIND=MPI_COUNT_KIND), INTENT(OUT) :: array_of_large_counts(max_large_counts)
TYPE(MPI_Datatype), INTENT(OUT) :: array_of_datatypes(max_datatypes)
INTEGER, OPTIONAL, INTENT(OUT) :: ierror
Fortran binding
MPI_TYPE_GET_CONTENTS(DATATYPE, MAX_INTEGERS, MAX_ADDRESSES, MAX_DATATYPES, ARRAY_OF_INTEGERS, ARRAY_OF_ADDRESSES, ARRAY_OF_DATATYPES, IERROR)

INTEGER DATATYPE, MAX_INTEGERS, MAX_ADDRESSES, MAX_DATATYPES, ARRAY_OF_INTEGERS(*), ARRAY_OF_DATATYPES(*), IERROR
INTEGER(KIND=MPI_ADDRESS_KIND) ARRAY_OF_ADDRESSES(*)

datatype must be a predefined unnamed or a derived datatype; the call is erroneous if datatype is a predefined named datatype.

The values given for max_integers, max_addresses, max_large_counts, and max_datatypes must be at least as large as the value returned in num_integers, num_addresses, num_large_counts, and num_datatypes, respectively, in the call MPI_TYPE_GET_ENVELOPE for the same datatype argument.


Rationale.

The arguments max_integers, max_addresses, max_large_counts, and max_datatypes allow for error checking in the call. ( End of rationale.)
If the MPI_TYPE_GET_CONTENTS variant without max_large_counts is invoked with a datatype that requires >0 values in array_of_large_counts, then an error of class MPI_ERR_TYPE is raised.


Rationale.

The large count variant of this MPI procedure was added in MPI-4. It contains new max_large_counts and array_of_large_counts parameters. The other variant---the variant that existed before MPI-4---was not changed in order to preserve backwards compatibility. ( End of rationale.)
The datatypes returned in array_of_datatypes are handles to datatype objects that are equivalent to the datatypes used in the original construction call. If these were derived datatypes, then the returned datatypes are new datatype objects, and the user is responsible for freeing these datatypes with MPI_TYPE_FREE. If these were predefined datatypes, then the returned datatype is equal to that (constant) predefined datatype and cannot be freed.

The committed state of returned derived datatypes is undefined, i.e., the datatypes may or may not be committed. Furthermore, the content of attributes of returned datatypes is undefined.

Note that MPI_TYPE_GET_CONTENTS can be invoked with a datatype argument that was constructed using MPI_TYPE_CREATE_F90_REAL, MPI_TYPE_CREATE_F90_INTEGER, or MPI_TYPE_CREATE_F90_COMPLEX (an unnamed predefined datatype). In such a case, an empty array_of_datatypes is returned.


Rationale.

The definition of datatype equivalence implies that equivalent predefined datatypes are equal. By requiring the same handle for named predefined datatypes, it is possible to use the == or .EQ. comparison operator to determine the datatype involved. ( End of rationale.)

Advice to implementors.

The datatypes returned in array_of_datatypes must appear to the user as if each is an equivalent copy of the datatype used in the type constructor call. Whether this is done by creating a new datatype or via another mechanism such as a reference count mechanism is up to the implementation as long as the semantics are preserved. ( End of advice to implementors.)

Rationale.

The committed state and attributes of the returned datatype is deliberately left vague. The datatype used in the original construction may have been modified since its use in the constructor call. Attributes can be added, removed, or modified as well as having the datatype committed. The semantics given allow for a reference count implementation without having to track these changes. ( End of rationale.)
In the deprecated datatype constructor calls, the address arguments in Fortran are of type INTEGER. In the preferred calls, the address arguments are of type INTEGER(KIND=MPI_ADDRESS_KIND) . The call MPI_TYPE_GET_CONTENTS returns all addresses in an argument of type INTEGER(KIND=MPI_ADDRESS_KIND) . This is true even if the deprecated calls were used. Thus, the location of values returned can be thought of as being returned by the C bindings. It can also be determined by examining the preferred calls for datatype constructors for the deprecated calls that involve addresses.


Rationale.

By having all address arguments returned in the array_of_addresses argument, the result from a C and Fortran decoding of a datatype gives the result in the same argument. It is assumed that an integer of type INTEGER(KIND=MPI_ADDRESS_KIND) will be at least as large as the INTEGER argument used in datatype construction with the old MPI-1 calls so no loss of information will occur. ( End of rationale.)
The following defines what values are placed in each entry of the returned arrays depending on the datatype constructor used for datatype. It also specifies the size of the arrays needed, which is the values returned by MPI_TYPE_GET_ENVELOPE. In Fortran, the following calls were made:

Image file

or in C the analogous calls of:

Image file

The following describes the values of the arguments for each combiner. The lower case name of arguments is used. Also, the descriptions below refer to MPI datatypes created by procedures without large count arguments.

[style=unboxed,leftmargin=0cm]

MPI_COMBINER_NAMED
the datatype represent a predefined type and therefore it is erroneous to call MPI_TYPE_GET_CONTENTS.

MPI_COMBINER_DUP
ni = 0, na = 0, nd = 1, and

Constructor argument C Fortran location
oldtype d[0] D(1)

MPI_COMBINER_CONTIGUOUS
ni = 1, na = 0, nd = 1, and

Constructor argument C Fortran location
count i[0] I(1)
oldtype d[0] D(1)

MPI_COMBINER_VECTOR
ni = 3, na = 0, nd = 1, and

Constructor argument C Fortran location
count i[0] I(1)
blocklength i[1] I(2)
stride i[2] I(3)
oldtype d[0] D(1)

MPI_COMBINER_HVECTOR
ni = 2, na = 1, nd = 1, and

Constructor argument C Fortran location
count i[0] I(1)
blocklength i[1] I(2)
stride a[0] A(1)
oldtype d[0] D(1)

MPI_COMBINER_INDEXED
ni = 2*count+1, na = 0, nd = 1, and

Constructor argument C Fortran location
count i[0] I(1)
array_of_blocklengths i[1] to i[i[0]] I(2) to I(I(1)+1)
array_of_displacements i[i[0]+1] to i[2*i[0]] I(I(1)+2) to I(2*I(1)+1)
oldtype d[0] D(1)

MPI_COMBINER_HINDEXED
ni = count+1, na = count, nd = 1, and

Constructor argument C Fortran location
count i[0] I(1)
array_of_blocklengths i[1] to i[i[0]] I(2) to I(I(1)+1)
array_of_displacements a[0] to a[i[0]-1] A(1) to A(I(1))
oldtype d[0] D(1)

MPI_COMBINER_INDEXED_BLOCK
ni = count+2, na = 0, nd = 1, and

Constructor argument C Fortran location
count i[0] I(1)
blocklength i[1] I(2)
array_of_displacements i[2] to i[i[0]+1] I(3) to I(I(1)+2)
oldtype d[0] D(1)

MPI_COMBINER_HINDEXED_BLOCK
ni = 2, na = count, nd = 1, and

Constructor argument C Fortran location
count i[0] I(1)
blocklength i[1] I(2)
array_of_displacements a[0] to a[i[0]-1] A(1) to A(I(1))
oldtype d[0] D(1)

MPI_COMBINER_STRUCT
ni = count+1, na = count, nd = count, and

Constructor argument C Fortran location
count i[0] I(1)
array_of_blocklengths i[1] to i[i[0]] I(2) to I(I(1)+1)
array_of_displacements a[0] to a[i[0]-1] A(1) to A(I(1))
array_of_types d[0] to d[i[0]-1] D(1) to D(I(1))

MPI_COMBINER_SUBARRAY
ni = 3*ndims+2, na = 0, nd = 1, and

Constructor argument C Fortran location
ndims i[0] I(1)
array_of_sizes i[1] to i[i[0]] I(2) to I(I(1)+1)
array_of_subsizes i[i[0]+1] to i[2*i[0]] I(I(1)+2) to I(2*I(1)+1)
array_of_starts i[2*i[0]+1] to i[3*i[0]] I(2*I(1)+2) to I(3*I(1)+1)
order i[3*i[0]+1] I(3*I(1)+2]
oldtype d[0] D(1)

MPI_COMBINER_DARRAY
ni = 4*ndims+4, na = 0, nd = 1, and

Constructor argument C Fortran location
size i[0] I(1)
rank i[1] I(2)
ndims i[2] I(3)
array_of_gsizes i[3] to i[i[2]+2] I(4) to I(I(3)+3)
array_of_distribs i[i[2]+3] to i[2*i[2]+2] I(I(3)+4) to I(2*I(3)+3)
array_of_dargs i[2*i[2]+3] to i[3*i[2]+2] I(2*I(3)+4) to I(3*I(3)+3)
array_of_psizes i[3*i[2]+3] to i[4*i[2]+2] I(3*I(3)+4) to I(4*I(3)+3)
order i[4*i[2]+3] I(4*I(3)+4)
oldtype d[0] D(1)

MPI_COMBINER_F90_REAL
ni = 2, na = 0, nd = 0, and

Constructor argument C Fortran location
p i[0] I(1)
r i[1] I(2)

MPI_COMBINER_F90_COMPLEX
ni = 2, na = 0, nd = 0, and

Constructor argument C Fortran location
p i[0] I(1)
r i[1] I(2)

MPI_COMBINER_F90_INTEGER
ni = 1, na = 0, nd = 0, and

Constructor argument C Fortran location
r i[0] I(1)

MPI_COMBINER_RESIZED
ni = 0, na = 2, nd = 1, and

Constructor argument C Fortran location
lb a[0] A(1)
extent a[1] A(2)
oldtype d[0] D(1)

MPI_COMBINER_VALUE_INDEX
ni = 0, na = 0, nd = 2, and

Constructor argument C Fortran location
value_type d[0] D(1)
index_type d[1] D(2)



PreviousUpNext
Up: Derived Datatypes Next: Examples Previous: Correct Use of Addresses


Return to MPI-4.1 Standard Index
Return to MPI Forum Home Page

(Unofficial) MPI-4.1 of November 2, 2023
HTML Generated on November 19, 2023