next up previous index
Next: Commit and free Up: Derived Data Types Previous: Structures

Data Type Inquiry Functions

To a limited extend MPI assists programmers in writing portable programs, even programs that construct derived data types ``manually'' by providing a range of inquiry functions which can be used to ask about the address of a given location, extent of a given derived data type, its size (this is not the same as an extent), and lower and upper bound markers for a given derived data type. This way a program can be constructed that checks for these things and then compare them with assumptions made in the program. If any inconsistencies are found a program may issue a message and abort, or take a corrective action if possible. These functions can be also used to contruct data types dynamically, thus making the whole procedure more portable.

The first one of these functions is a function that returns an address of an object in$\ldots$ bytes. The bytes are counted from the beginning of the usable memory. There is an MPI constant called MPI_BOTTOM, which marks the beginning of memory. Once you have absolute addresses of various objects, as returned by function MPI_address and MPI_BOTTOM you can give displacements to any of the constructor functions in terms of those addresses - and, the pointer to the buffer, of course, must then be given in terms of MPI_BOTTOM.

The synopsis of function MPI_Address in C is:

MPI_Address(void* location, MPI_Aint *address)
and in Fortran:
mpi_address(location, address, ierror)
<type> location(*)
integer address, ierror
Observe that the address, as returned by a call to MPI_Address is not the same as a pointer. A pointer in C, or in Fortran, or in Pascal contains an address, but it may also contain information about the type of the variable that the pointer points to. Here we are concerned with addresses only, and we want them given to us in bytes.

The following example code shows how you can use MPI_Address to find a distance, in bytes, between the beginning of an array and a particular location in that array. You can then use this information in order to write a more portable program, which would work the same regardless of how much space is taken by a real number (it may be 32-bits or 64-bits depending on the architecture of a machine).

real A(100, 100)
integer i1, i2, diff

call mpi_address(a(1,1), i1, ierror)
call mpi_address(a(10,10), i2, ierror)
diff = i2 - i1

The next function can be used to find the extent of a derived data type. The function is MPI_Type_extent. The extent is also given in bytes. The C language synopsis of this function is:

MPI_Type_extent(MPI_Datatype datatype, MPI_Aint *extent)
and its Fortran interface is:
mpi_type_extent(datatype, extent, ierror)
integer datatype, extent, ierror
The extent is not the same as the size of a given data-type. The extent is a difference between the upper bound marker and the lower bound marker for a given data type. There may be a lot of empty space in between, some padding, etc. All this is included in the extent.

On the other hand the size of a data type is the number of bytes that are going to be transmitted when a process MPI_Sends a message that contains this data type. In this case the padding and the empty space that separate and wrap various components of the data type are not going to be transmitted. Instead MPI is going to take all the real data from its various locations pointed to by the displacements, lengths, and types arrays and send just that. The synopsis of the function that returns the size of a derived data type is:

MPI_Type_size(MPI_Datatype datatype, int *size)
in C and
mpi_type_size(datatype, size, ierror)
integer datatype, size, ierror
in Fortran.

The lower and the upper bounds of any MPI data type, derived or not, can be obtained by calling functions MPI_Type_lb and MPI_Type_ub. Both have a similar synopsis, e.g.,

int MPI_Type_lb(MPI_Datatype datatype, MPI_Aint* displacement)
in C and
mpi_type_ub(datatype, displacement, ierror)
integer datatype, displacement, ierror
in Fortran.

But you can also set the lower and upper bound manually on a newly defined MPI typed. For example, you may wish to pad the type on both sides. Then you would not rely on the system generating the upper and the lower bound, but, instead, you would define your own bounds. This can be done by calling MPI_Type_struct and using predefined pseudo-datatypes MPI_LB and MPI_UB to mark the bounds.

next up previous index
Next: Commit and free Up: Derived Data Types Previous: Structures
Zdzislaw Meglicki