


Functions for caching on communicators are:
| MPI_COMM_CREATE_KEYVAL(comm_copy_attr_fn, comm_delete_attr_fn, comm_keyval, extra_state) | |
| IN comm_copy_attr_fn | copy callback function for comm_keyval (function) | 
| IN comm_delete_attr_fn | delete callback function for comm_keyval (function) | 
| OUT comm_keyval | key value for future access (integer) | 
| IN extra_state | extra state for callback functions | 
 
  int MPI_Comm_create_keyval(MPI_Comm_copy_attr_function *comm_copy_attr_fn, MPI_Comm_delete_attr_function *comm_delete_attr_fn, int *comm_keyval, void *extra_state) 
  
 
  MPI_COMM_CREATE_KEYVAL(COMM_COPY_ATTR_FN, COMM_DELETE_ATTR_FN, COMM_KEYVAL, EXTRA_STATE, IERROR)
 EXTERNAL COMM_COPY_ATTR_FN, COMM_DELETE_ATTR_FN
INTEGER COMM_KEYVAL, IERROR
INTEGER(KIND=MPI_ADDRESS_KIND) EXTRA_STATE 
  
 
  
  static int MPI::Comm::Create_keyval(MPI::Comm::Copy_attr_function* comm_copy_attr_fn, MPI::Comm::Delete_attr_function* comm_delete_attr_fn, void* extra_state) 
  
  
  
  
Generates a new attribute key.  Keys are locally unique in a process,  
and opaque to user, though they are explicitly stored in integers.  
Once allocated, the key value can be used to associate attributes  
and access them on any locally defined communicator.  
  
This function replaces  MPI_KEYVAL_CREATE,  
  
whose use is deprecated.  
  
The C binding  
is identical.  The Fortran binding differs in that  
 extra_state is an address-sized integer.  Also, the copy and  
delete callback functions have Fortran bindings that are consistent  
with address-sized attributes.  
  
The C callback functions are:
 
  
  typedef int MPI_Comm_copy_attr_function(MPI_Comm oldcomm, int comm_keyval, void *extra_state, void *attribute_val_in, void *attribute_val_out, int *flag); 
  
and
 
  typedef int MPI_Comm_delete_attr_function(MPI_Comm comm, int comm_keyval, void *attribute_val, void *extra_state); 
  
  
which are the same as the MPI-1.1 calls but with a new name. The old names are deprecated.
The Fortran callback functions are:
 
  SUBROUTINE COMM_COPY_ATTR_FN(OLDCOMM, COMM_KEYVAL, EXTRA_STATE, ATTRIBUTE_VAL_IN, ATTRIBUTE_VAL_OUT, FLAG, IERROR)
 INTEGER OLDCOMM, COMM_KEYVAL, IERROR
INTEGER(KIND=MPI_ADDRESS_KIND) EXTRA_STATE, ATTRIBUTE_VAL_IN,
    ATTRIBUTE_VAL_OUT
LOGICAL FLAG 
  
and
 
  SUBROUTINE COMM_DELETE_ATTR_FN(COMM, COMM_KEYVAL, ATTRIBUTE_VAL, EXTRA_STATE, IERROR)
 INTEGER COMM, COMM_KEYVAL, IERROR
INTEGER(KIND=MPI_ADDRESS_KIND) ATTRIBUTE_VAL, EXTRA_STATE 
  
The C++ callbacks are:
 
  
  typedef int MPI::Comm::Copy_attr_function(const MPI::Comm& oldcomm, int comm_keyval, void* extra_state, void* attribute_val_in, void* attribute_val_out, bool& flag); 
  
and
 
  typedef int MPI::Comm::Delete_attr_function(MPI::Comm& comm, int comm_keyval, void* attribute_val, void* extra_state); 
  
  
  
  
The  comm_copy_attr_fn function is invoked when a communicator is  
duplicated by  MPI_COMM_DUP.   comm_copy_attr_fn should be  
of type  MPI_Comm_copy_attr_function.  
The copy callback function is invoked for each key value in  
 oldcomm in arbitrary order.  Each call  
to the copy callback is made with a key value and its corresponding attribute.  
If it returns  flag = 0, then the  
attribute is deleted in the duplicated communicator.  Otherwise  
( flag = 1),  
  
the new attribute value is set to the value  
returned in  
 attribute_val_out.  
  
The function returns  MPI_SUCCESS on  
success and an error code on failure (in which case  
 MPI_COMM_DUP will fail).  
  
  
The argument  comm_copy_attr_fn may be specified as  
  
 MPI_COMM_NULL_COPY_FN or  
  
 MPI_COMM_DUP_FN  
from either C, C++, or Fortran.  
 MPI_COMM_NULL_COPY_FN  
is a function that does nothing other than returning  flag = 0  
and  MPI_SUCCESS.  
 MPI_COMM_DUP_FN is a simple-minded  
copy function that sets  flag = 1,  
returns the value of  
 attribute_val_in in  attribute_val_out, and  
returns  MPI_SUCCESS.  
These replace the  MPI-1 predefined callbacks  MPI_NULL_COPY_FN  
and  MPI_DUP_FN, whose use is deprecated.  
 
  
  
 
 
 Advice to users.  
Even though both formal arguments attribute_val_in and attribute_val_out are of type void *, their usage differs. The C copy function is passed by MPI in attribute_val_in the value of the attribute, and in attribute_val_out the address of the attribute, so as to allow the function to return the (new) attribute value. The use of type void * for both is to avoid messy type casts.
 
A valid copy function is one that completely duplicates the  
information by making a full duplicate copy of the data structures  
implied by an attribute; another might just make another reference to  
that data structure, while using a reference-count mechanism.  Other  
types of attributes might not copy at all (they might be specific to  
 oldcomm only).  
 ( End of advice to users.) 
 
  
 
 
 Advice  
        to implementors.  
 
A C interface should be assumed for copy and delete functions  
associated with key values created in C; a Fortran calling interface  
should be assumed for key values created in Fortran.  
 ( End of advice to implementors.) 
 
  
  
Analogous to  comm_copy_attr_fn is a callback deletion function, defined  
as follows.  The  comm_delete_attr_fn function is invoked when a communicator is  
deleted by  MPI_COMM_FREE or when a call is made explicitly to  
 MPI_COMM_DELETE_ATTR.    
 comm_delete_attr_fn should be  
of type  MPI_Comm_delete_attr_function.  
  
This function is called by  MPI_COMM_FREE,  
 MPI_COMM_DELETE_ATTR,  
  
and  MPI_COMM_SET_ATTR  
  
to do whatever is needed to remove an attribute.  
  
The function returns  MPI_SUCCESS on  
success and an error code on failure (in which case  
 MPI_COMM_FREE will fail).  
  
  
The argument  comm_delete_attr_fn may be specified as  
  
  
 MPI_COMM_NULL_DELETE_FN from either C, C++, or Fortran.  
 MPI_COMM_NULL_DELETE_FN is a function that does nothing, other  
than returning  MPI_SUCCESS.   MPI_COMM_NULL_DELETE_FN  
replaces  MPI_NULL_DELETE_FN, whose use is deprecated.  
If an attribute copy function or attribute delete function returns other than MPI_SUCCESS, then the call that caused it to be invoked (for example, MPI_COMM_FREE), is erroneous.
The special key value MPI_KEYVAL_INVALID is never returned by MPI_KEYVAL_CREATE. Therefore, it can be used for static initialization of key values.
| MPI_COMM_FREE_KEYVAL(comm_keyval) | |
| INOUT comm_keyval | key value (integer) | 
 
  int MPI_Comm_free_keyval(int *comm_keyval) 
  
 
  MPI_COMM_FREE_KEYVAL(COMM_KEYVAL, IERROR)
 INTEGER COMM_KEYVAL, IERROR 
   
 
  static void MPI::Comm::Free_keyval(int& comm_keyval) 
  
  
Frees an extant attribute key.  
This function sets the value of  keyval to  
 MPI_KEYVAL_INVALID.  
Note that it is not erroneous to free an attribute key  
that is in use, because the actual free does not transpire until after all  
references (in other communicators on the process) to the key have been freed.  
These references need to be explictly freed by the program, either via calls  
to  MPI_COMM_DELETE_ATTR that free one attribute instance, or by calls  
to  MPI_COMM_FREE that free all attribute instances associated with  
the freed communicator.  
This call is identical to the MPI-1 call MPI_KEYVAL_FREE but is needed to match the new communicator-specific creation function. The use of MPI_KEYVAL_FREE is deprecated.
| MPI_COMM_SET_ATTR(comm, comm_keyval, attribute_val) | |
| INOUT comm | communicator from which attribute will be attached (handle) | 
| IN comm_keyval | key value (integer) | 
| IN attribute_val | attribute value | 
 
  int MPI_Comm_set_attr(MPI_Comm comm, int comm_keyval, void *attribute_val) 
  
 
 
  MPI_COMM_SET_ATTR(COMM, COMM_KEYVAL, ATTRIBUTE_VAL, IERROR)
 INTEGER COMM, COMM_KEYVAL, IERROR
INTEGER(KIND=MPI_ADDRESS_KIND) ATTRIBUTE_VAL 
   
 
  void MPI::Comm::Set_attr(int comm_keyval, const void* attribute_val) const 
  
  
  
This function stores the stipulated attribute value  attribute_val  
for subsequent retrieval by  MPI_COMM_GET_ATTR.  
If the value is already present, then the outcome  
is as if  MPI_COMM_DELETE_ATTRwas first called to delete the previous  
value (and the callback function  comm_delete_attr_fn was executed), and a new  
value was next stored.  The call is erroneous if there is no key with value  
 keyval; in particular  
 MPI_KEYVAL_INVALID is an erroneous key value.  
  
The call will fail if the  comm_delete_attr_fn function returned an error code  
other than  MPI_SUCCESS.  
  
  
This function replaces  MPI_ATTR_PUT,  
  
whose use is deprecated.  
  
The C binding  
is identical.  The Fortran binding  
differs in that  attribute_val is an address-sized integer.  
  
| MPI_COMM_GET_ATTR(comm, comm_keyval, attribute_val, flag) | |
| IN comm | communicator to which the attribute is attached (handle) | 
| IN comm_keyval | key value (integer) | 
| OUT attribute_val | attribute value, unless flag = false | 
| OUT flag | false if no attribute is associated with the key (logical) | 
 
  int MPI_Comm_get_attr(MPI_Comm comm, int comm_keyval, void *attribute_val, int *flag) 
  
 
  MPI_COMM_GET_ATTR(COMM, COMM_KEYVAL, ATTRIBUTE_VAL, FLAG, IERROR)
 INTEGER COMM, COMM_KEYVAL, IERROR
INTEGER(KIND=MPI_ADDRESS_KIND) ATTRIBUTE_VAL
LOGICAL FLAG 
    
 
  bool MPI::Comm::Get_attr(int comm_keyval, void* attribute_val) const 
  
  
Retrieves attribute value by key.  
The call is erroneous if there is no key with value  
 keyval.  On the other hand, the call is correct if the key value  
exists, but no attribute is attached on  comm for that key; in such case,  
the call returns  flag = false.  In particular  
 MPI_KEYVAL_INVALID is an erroneous key value.  
 
  
 
 
 Advice to users.  
 
The call to  MPI_Comm_set_attr passes in  attribute_val  
the  value of the attribute; the call to  MPI_Comm_get_attr  
passes in  attribute_val the  address of   
the  
location where the attribute value is to be returned.  
Thus, if the attribute value itself is a pointer of type  void*,   
then the   
actual  attribute_val parameter to  
 MPI_Comm_set_attr will be of type  void* and the actual  
 attribute_val parameter to   
 MPI_Comm_get_attr   
will be of type  void**.  
 ( End of advice to users.) 
 
 
 
 Rationale.  
 
The use of a formal parameter  attribute_val or type  
 void* (rather than  void**) avoids the messy type  
casting that would be needed if the attribute value is declared with a  
type other than  void*.  
 ( End of rationale.) 
 
  
  
This function replaces  MPI_ATTR_GET,  
  
whose use is deprecated.  
  
The C binding is  
identical.  The Fortran binding differs in that  
 attribute_val is an address-sized integer.  
  
| MPI_COMM_DELETE_ATTR(comm, comm_keyval) | |
| INOUT comm | communicator from which the attribute is deleted (handle) | 
| IN comm_keyval | key value (integer) | 
 
  int MPI_Comm_delete_attr(MPI_Comm comm, int comm_keyval) 
  
 
  
  MPI_COMM_DELETE_ATTR(COMM, COMM_KEYVAL, IERROR)
 INTEGER COMM, COMM_KEYVAL, IERROR 
    
  
 
  
  void MPI::Comm::Delete_attr(int comm_keyval) 
  
  
  
Delete attribute from cache by key.  This function invokes the  
attribute delete function  comm_delete_attr_fn  
specified when the  keyval was created.  
  
The call will fail if the  comm_delete_attr_fn function returns an  
error code other than  MPI_SUCCESS.  
  
Whenever a communicator is replicated using the function MPI_COMM_DUP, all call-back copy functions for attributes that are currently set are invoked (in arbitrary order). Whenever a communicator is deleted using the function MPI_COMM_FREE all callback delete functions for attributes that are currently set are invoked. This function is the same as MPI_ATTR_DELETE but is needed to match the new communicator specific functions. The use of MPI_ATTR_DELETE is deprecated.


