Attribute keys can be allocated in one language and freed in another. Similarly, attribute values can be set in one language and accessed in another. To achieve this, attribute keys will be allocated in an integer range that is valid all languages. The same holds true for system-defined attribute values (such as MPI_TAG_UB, MPI_WTIME_IS_GLOBAL, etc.)
Attribute keys declared in one language are associated with copy and delete functions in that language (the functions provided by the MPI_ {TYPE,COMM,WIN }_CREATE_KEYVAL call). When a communicator is duplicated, for each attribute, the corresponding copy function is called, using the right calling convention for the language of that function; and similarly, for the delete callback function.
Advice
to implementors.
This requires that attributes be tagged either as ``C,'' ``C++'' or
``Fortran,'' and that the language tag be checked in order to use
the right calling convention for the callback function.
( End of advice to implementors.)
The attribute manipulation functions described in
Section Caching
on page Caching
define
attributes arguments to be of type void* in C, and of type
INTEGER, in Fortran. On some systems,
INTEGERs will have 32 bits, while C/C++ pointers will have
64 bits. This is a problem if communicator attributes are used to
move information from a Fortran caller to a C/C++ callee, or
vice-versa.
MPI behaves as if it stores,
internally, address sized attributes. If Fortran INTEGERs
are smaller, then the Fortran function MPI_ATTR_GET will
return the least significant part of the attribute word; the Fortran
function MPI_ATTR_PUT will set the least significant part
of the attribute word, which will be sign extended to the entire word.
(These two functions may be invoked explicitly by user code, or
implicitly, by attribute copying callback functions.)
As for addresses, new functions are provided that manipulate
Fortran address sized attributes, and have the same functionality as the
old
functions in C/C++. These functions are described in
Section Caching
, page Caching
.
Users are encouraged to use these new functions.
MPI supports two types of attributes: address-valued (pointer) attributes,
and integer valued attributes. C and C++
attribute functions put and get address
valued attributes. Fortran attribute functions put and get integer valued
attributes. When an integer valued attribute is accessed from C or C++,
then
MPI_xxx_get_attr
will return the address of (a pointer to) the integer
valued attribute, which is a pointer to
MPI_Aint if the attribute was stored with Fortran
MPI_xxx_SET_ATTR, and a pointer to int if it was
stored with the deprecated Fortran MPI_ATTR_PUT. When an
address valued attribute is accessed from
Fortran, then MPI_xxx_GET_ATTR
will convert the address into an integer and
return the result of this conversion. This conversion is lossless if new
style
attribute functions are used, and an integer of kind
MPI_ADDRESS_KIND
is returned. The conversion may cause truncation if
deprecated
attribute functions are used.
In C, the deprecated routines
MPI_Attr_put and MPI_Attr_get behave identical
to MPI_Comm_set_attr and MPI_Comm_get_attr.
2.2
A. Setting an attribute value in C
A. Setting an attribute value with the (deprecated) Fortran MPI-1 call
The predefined MPI attributes can be integer valued or address valued.
Predefined integer valued attributes, such as MPI_TAG_UB,
behave as if they
were put by a call to the
deprecated Fortran routine MPI_ATTR_PUT,
i.e.,
in Fortran,
MPI_COMM_GET_ATTR(MPI_COMM_WORLD, MPI_TAG_UB, val, flag, ierr)
will return in val
the upper bound for tag value; in C,
MPI_Comm_get_attr(MPI_COMM_WORLD, MPI_TAG_UB, &p, &flag)
will return in p
a pointer to an int containing the upper bound for tag value.
Address valued predefined attributes, such as MPI_WIN_BASE
behave as if
they were put by a C call,
i.e.,
in Fortran,
MPI_WIN_GET_ATTR(win, MPI_WIN_BASE, val, flag, ierror)
will return in val the base address of the window,
converted to an integer. In C,
MPI_Win_get_attr(win, MPI_WIN_BASE, &p, &flag)
will return in p
a pointer to the window base, cast to (void *).
The design is consistent with the behavior
specified
for predefined
attributes, and ensures that no information is lost when attributes are
passed from language to language.
Because the language interoperability for
predefined attributes was defined based on MPI_ATTR_PUT,
this definition is kept for compatibility reasons although the
routine itself is now deprecated.
( End of rationale.)
Implementations should tag attributes either as
(1)
address attributes, (2) as
INTEGER(KIND=MPI_ADDRESS_KIND) attributes or (3) as
INTEGER attributes, according to whether they were set in
(1) C (with MPI_Attr_put or
MPI_Xxx_set_attr), (2) in Fortran with
MPI_XXX_SET_ATTR or (3) with the deprecated Fortran
routine MPI_ATTR_PUT.
Thus, the right choice can be made when the attribute is retrieved.
( End of advice to implementors.)
Example
int set_val = 3;
struct foo set_struct;
/* Set a value that is a pointer to an int */
MPI_Comm_set_attr(MPI_COMM_WORLD, keyval1, &set_val);
/* Set a value that is a pointer to a struct */
MPI_Comm_set_attr(MPI_COMM_WORLD, keyval2, &set_struct);
/* Set an integer value */
MPI_Comm_set_attr(MPI_COMM_WORLD, keyval3, (void *) 17);
B. Reading the attribute value in C
int flag, *get_val;
struct foo *get_struct;
/* Upon successful return, get_val == &set_val
(and therefore *get_val == 3) */
MPI_Comm_get_attr(MPI_COMM_WORLD, keyval1, &get_val, &flag);
/* Upon successful return, get_struct == &set_struct */
MPI_Comm_get_attr(MPI_COMM_WORLD, keyval2, &get_struct, &flag);
/* Upon successful return, get_val == (void*) 17 */
/* i.e., (MPI_Aint) get_val == 17 */
MPI_Comm_get_attr(MPI_COMM_WORLD, keyval3, &get_val, &flag);
C. Reading the attribute value with (deprecated) Fortran MPI-1 calls
LOGICAL FLAG
INTEGER IERR, GET_VAL, GET_STRUCT
! Upon successful return, GET_VAL == &set_val, possibly truncated
CALL MPI_ATTR_GET(MPI_COMM_WORLD, KEYVAL1, GET_VAL, FLAG, IERR)
! Upon successful return, GET_STRUCT == &set_struct, possibly truncated
CALL MPI_ATTR_GET(MPI_COMM_WORLD, KEYVAL2, GET_STRUCT, FLAG, IERR)
! Upon successful return, GET_VAL == 17
CALL MPI_ATTR_GET(MPI_COMM_WORLD, KEYVAL3, GET_VAL, FLAG, IERR)
D. Reading the attribute value with Fortran MPI-2 calls
LOGICAL FLAG
INTEGER IERR
INTEGER (KIND=MPI_ADDRESS_KIND) GET_VAL, GET_STRUCT
! Upon successful return, GET_VAL == &set_val
CALL MPI_COMM_GET_ATTR(MPI_COMM_WORLD, KEYVAL1, GET_VAL, FLAG, IERR)
! Upon successful return, GET_STRUCT == &set_struct
CALL MPI_COMM_GET_ATTR(MPI_COMM_WORLD, KEYVAL2, GET_STRUCT, FLAG, IERR)
! Upon successful return, GET_VAL == 17
CALL MPI_COMM_GET_ATTR(MPI_COMM_WORLD, KEYVAL3, GET_VAL, FLAG, IERR)
Example
INTEGER IERR, VAL
VAL = 7
CALL MPI_ATTR_PUT(MPI_COMM_WORLD, KEYVAL, VAL, IERR)
B. Reading the attribute value in C
int flag;
int *value;
/* Upon successful return, value points to internal MPI storage and
*value == (int) 7 */
MPI_Comm_get_attr(MPI_COMM_WORLD, keyval, &value, &flag);
C. Reading the attribute value with (deprecated) Fortran MPI-1 calls
LOGICAL FLAG
INTEGER IERR, VALUE
! Upon successful return, VALUE == 7
CALL MPI_ATTR_GET(MPI_COMM_WORLD, KEYVAL, VALUE, FLAG, IERR)
D. Reading the attribute value with Fortran MPI-2 calls
LOGICAL FLAG
INTEGER IERR
INTEGER (KIND=MPI_ADDRESS_KIND) VALUE
! Upon successful return, VALUE == 7 (sign extended)
CALL MPI_COMM_GET_ATTR(MPI_COMM_WORLD, KEYVAL, VALUE, FLAG, IERR)
Example
A. Setting an attribute value via a Fortran MPI-2 call
INTEGER IERR
INTEGER(KIND=MPI_ADDRESS_KIND) VALUE1
INTEGER(KIND=MPI_ADDRESS_KIND) VALUE2
VALUE1 = 42
VALUE2 = INT(2, KIND=MPI_ADDRESS_KIND) ** 40
CALL MPI_COMM_SET_ATTR(MPI_COMM_WORLD, KEYVAL1, VALUE1, IERR)
CALL MPI_COMM_SET_ATTR(MPI_COMM_WORLD, KEYVAL2, VALUE2, IERR)
B. Reading the attribute value in C
int flag;
MPI_Aint *value1, *value2;
/* Upon successful return, value1 points to internal MPI storage and
*value1 == 42 */
MPI_Comm_get_attr(MPI_COMM_WORLD, keyval1, &value1, &flag);
/* Upon successful return, value2 points to internal MPI storage and
*value2 == 2^40 */
MPI_Comm_get_attr(MPI_COMM_WORLD, keyval2, &value2, &flag);
C. Reading the attribute value with (deprecated) Fortran MPI-1 calls
LOGICAL FLAG
INTEGER IERR, VALUE1, VALUE2
! Upon successful return, VALUE1 == 42
CALL MPI_ATTR_GET(MPI_COMM_WORLD, KEYVAL1, VALUE1, FLAG, IERR)
! Upon successful return, VALUE2 == 2^40, or 0 if truncation
! needed (i.e., the least significant part of the attribute word)
CALL MPI_ATTR_GET(MPI_COMM_WORLD, KEYVAL2, VALUE2, FLAG, IERR)
D. Reading the attribute value with Fortran MPI-2 calls
LOGICAL FLAG
INTEGER IERR
INTEGER (KIND=MPI_ADDRESS_KIND) VALUE1, VALUE2
! Upon successful return, VALUE1 == 42
CALL MPI_COMM_GET_ATTR(MPI_COMM_WORLD, KEYVAL1, VALUE1, FLAG, IERR)
! Upon successful return, VALUE2 == 2^40
CALL MPI_COMM_GET_ATTR(MPI_COMM_WORLD, KEYVAL2, VALUE2, FLAG, IERR)
Rationale.
Advice
to implementors.
Up: Language Interoperability
Next: Extra State
Previous: Addresses
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