77. Address and Size Functions

PreviousUpNext
Up: Derived Datatypes Next: Lower-Bound and Upper-Bound Markers Previous: Distributed Array Datatype Constructor

The displacements in a general datatype are relative to some initial buffer address. Absolute addresses can be substituted for these displacements: we treat them as displacements relative to ``address zero,'' the start of the address space. This initial address zero is indicated by the constant MPI_BOTTOM. Thus, a datatype can specify the absolute address of the entries in the communication buffer, in which case the buf argument is passed the value MPI_BOTTOM. Note that in Fortran MPI_BOTTOM is not usable for initialization or assignment, see Section Named Constants .

The address of a location in memory can be found by invoking the function MPI_GET_ADDRESS. The relative displacement between two absolute addresses can be calculated with the function MPI_AINT_DIFF. A new absolute address as sum of an absolute base address and a relative displacement can be calculated with the function MPI_AINT_ADD. To ensure portability, arithmetic on absolute addresses should not be performed with the intrinsic operators ``-'' and ``+''. See also Sections Absolute Addresses and Relative Address Displacements and Correct Use of Addresses on pages Absolute Addresses and Relative Address Displacements and Correct Use of Addresses .


Rationale.

Address sized integer values, i.e., MPI_Aint or INTEGER(KIND=MPI_ADDRESS_KIND) values, are signed integers, while absolute addresses are unsigned quantities. Direct arithmetic on addresses stored in address sized signed variables can cause overflows, resulting in undefined behavior. ( End of rationale.)

MPI_GET_ADDRESS(location, address)
IN locationlocation in caller memory (choice)
OUT addressaddress of location (integer)

int MPI_Get_address(const void *location, MPI_Aint *address)

MPI_Get_address(location, address, ierror)
TYPE(*), DIMENSION(..), ASYNCHRONOUS :: location
INTEGER(KIND=MPI_ADDRESS_KIND), INTENT(OUT) :: address
INTEGER, OPTIONAL, INTENT(OUT) :: ierror
MPI_GET_ADDRESS(LOCATION, ADDRESS, IERROR)
<type> LOCATION(*)
INTEGER IERROR
INTEGER(KIND=MPI_ADDRESS_KIND) ADDRESS

Returns the (byte) address of location.


Rationale.

In the mpi_f08 module, the location argument is not defined with INTENT(IN) because existing applications may use MPI_GET_ADDRESS as a substitute for MPI_F_SYNC_REG that was not defined before MPI-3.0. ( End of rationale.)

Example Using MPI_GET_ADDRESS for an array.


   REAL A(100,100) 
   INTEGER(KIND=MPI_ADDRESS_KIND) I1, I2, DIFF 
   CALL MPI_GET_ADDRESS(A(1,1), I1, IERROR) 
   CALL MPI_GET_ADDRESS(A(10,10), I2, IERROR) 
   DIFF = MPI_AINT_DIFF(I2, I1) 
! The value of DIFF is 909*sizeofreal; the values of I1 and I2 are 
! implementation dependent. 


Advice to users.

C users may be tempted to avoid the usage of MPI_GET_ADDRESS and rely on the availability of the address operator &. Note, however, that & cast-expression is a pointer, not an address. ISO C does not require that the value of a pointer (or the pointer cast to int) be the absolute address of the object pointed at --- although this is commonly the case. Furthermore, referencing may not have a unique definition on machines with a segmented address space. The use of MPI_GET_ADDRESS to ``reference'' C variables guarantees portability to such machines as well. ( End of advice to users.)

Advice to users.

To prevent problems with the argument copying and register optimization done by Fortran compilers, please note the hints in Sections Problems With Fortran Bindings for MPI --Comparison with C . ( End of advice to users.)
To ensure portability, arithmetic on MPI addresses must be performed using the MPI_AINT_ADD and MPI_AINT_DIFF functions.

MPI_AINT_ADD(base, disp)
IN basebase address (integer)
IN dispdisplacement (integer)

MPI_Aint MPI_Aint_add(MPI_Aint base, MPI_Aint disp)

INTEGER(KIND=MPI_ADDRESS_KIND) MPI_Aint_add(base, disp)
INTEGER(KIND=MPI_ADDRESS_KIND), INTENT(IN) :: base, disp
INTEGER(KIND=MPI_ADDRESS_KIND) MPI_AINT_ADD(BASE, DISP)
INTEGER(KIND=MPI_ADDRESS_KIND) BASE, DISP

MPI_AINT_ADD produces a new MPI_Aint value that is equivalent to the sum of the base and disp arguments, where base represents a base address returned by a call to MPI_GET_ADDRESS and disp represents a signed integer displacement. The resulting address is valid only at the process that generated base, and it must correspond to a location in the same object referenced by base, as described in Section Correct Use of Addresses . The addition is performed in a manner that results in the correct MPI_Aint representation of the output address, as if the process that originally produced base had called:

MPI_Get_address((char *) base + disp, &result); 
MPI_AINT_DIFF(addr1, addr2)
IN addr1minuend address (integer)
IN addr2subtrahend address (integer)

MPI_Aint MPI_Aint_diff(MPI_Aint addr1, MPI_Aint addr2)

INTEGER(KIND=MPI_ADDRESS_KIND) MPI_Aint_diff(addr1, addr2)
INTEGER(KIND=MPI_ADDRESS_KIND), INTENT(IN) :: addr1, addr2
INTEGER(KIND=MPI_ADDRESS_KIND) MPI_AINT_DIFF(ADDR1, ADDR2)
INTEGER(KIND=MPI_ADDRESS_KIND) ADDR1, ADDR2

MPI_AINT_DIFF produces a new MPI_Aint value that is equivalent to the difference between addr1 and addr2 arguments, where addr1 and addr2 represent addresses returned by calls to MPI_GET_ADDRESS. The resulting address is valid only at the process that generated addr1 and addr2, and addr1 and addr2 must correspond to locations in the same object in the same process, as described in Section Correct Use of Addresses . The difference is calculated in a manner that results in the signed difference from addr1 to addr2, as if the process that originally produced the addresses had called (char *) addr1 - (char *) addr2 on the addresses initially passed to MPI_GET_ADDRESS.

The following auxiliary functions provide useful information on derived datatypes.

MPI_TYPE_SIZE(datatype, size)
IN datatypedatatype (handle)
OUT sizedatatype size (integer)

int MPI_Type_size(MPI_Datatype datatype, int *size)

MPI_Type_size(datatype, size, ierror)
TYPE(MPI_Datatype), INTENT(IN) :: datatype
INTEGER, INTENT(OUT) :: size
INTEGER, OPTIONAL, INTENT(OUT) :: ierror
MPI_TYPE_SIZE(DATATYPE, SIZE, IERROR)
INTEGER DATATYPE, SIZE, IERROR

MPI_TYPE_SIZE_X(datatype, size)
IN datatypedatatype (handle)
OUT sizedatatype size (integer)

int MPI_Type_size_x(MPI_Datatype datatype, MPI_Count *size)

MPI_Type_size_x(datatype, size, ierror)
TYPE(MPI_Datatype), INTENT(IN) :: datatype
INTEGER(KIND=MPI_COUNT_KIND), INTENT(OUT) :: size
INTEGER, OPTIONAL, INTENT(OUT) :: ierror
MPI_TYPE_SIZE_X(DATATYPE, SIZE, IERROR)
INTEGER DATATYPE, IERROR
INTEGER(KIND=MPI_COUNT_KIND) SIZE

MPI_TYPE_SIZE and MPI_TYPE_SIZE_X set the value of size to the total size, in bytes, of the entries in the type signature associated with datatype; i.e., the total size of the data in a message that would be created with this datatype. Entries that occur multiple times in the datatype are counted with their multiplicity. For both functions, if the OUT parameter cannot express the value to be returned (e.g., if the parameter is too small to hold the output value), it is set to MPI_UNDEFINED.


PreviousUpNext
Up: Derived Datatypes Next: Lower-Bound and Upper-Bound Markers Previous: Distributed Array Datatype Constructor


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

(Unofficial) MPI-3.1 of June 4, 2015
HTML Generated on June 4, 2015