/*@C MPI_Attr_get - Retrieves attribute value by key Input Parameters: + comm - communicator to which attribute is attached (handle) - keyval - key value (integer) Output Parameters: + attr_value - attribute value, unless 'flag' = false - flag - true if an attribute value was extracted; false if no attribute is associated with the key Notes: Attributes must be extracted from the same language as they were inserted in with 'MPI_ATTR_PUT'. The notes for C and Fortran below explain why. Notes for C: Even though the 'attr_value' arguement is declared as 'void *', it is really the address of a void pointer. See the rationale in the standard for more details. .N fortran The 'attr_value' in Fortran is a pointer to a Fortran integer, not a pointer to a 'void *'. .N Errors .N MPI_SUCCESS .N MPI_ERR_COMM .N MPI_ERR_KEYVAL @*/ int MPI_Attr_get ( MPI_Comm comm, int keyval, void *attr_value, int *flag ) { MPIR_HBT_node *attr; int mpi_errno = MPI_SUCCESS; struct MPIR_COMMUNICATOR *comm_ptr; static char myname[] = "MPI_ATTR_GET"; TR_PUSH(myname); comm_ptr = MPIR_GET_COMM_PTR(comm); MPIR_TEST_MPI_COMM(comm,comm_ptr,comm_ptr,myname); if ( ( (keyval == MPI_KEYVAL_INVALID) && (mpi_errno = MPI_ERR_OTHER) ) ) return MPIR_ERROR(comm_ptr, mpi_errno, myname); MPIR_HBT_lookup(comm_ptr->attr_cache, keyval, &attr); if ( attr == (MPIR_HBT_node *)0 ) { (*flag) = 0; (*(void **)attr_value) = (void *)0; } else { (*flag) = 1; /* Device may want to update attribute */ MPID_ATTR_GET(comm_ptr,keyval,&attr->value); (*(void **)attr_value) = attr->value; } TR_POP; return(mpi_errno); }
/*@ MPI_Attr_delete - Deletes attribute value associated with a key Input Parameters: + comm - communicator to which attribute is attached (handle) - keyval - The key value of the deleted attribute (integer) .N fortran .N Errors .N MPI_ERR_COMM .N MPI_ERR_PERM_KEY @*/ EXPORT_MPI_API int MPI_Attr_delete ( MPI_Comm comm, int keyval ) { MPIR_HBT_node *attr; MPIR_Attr_key *attr_key; int mpi_errno = MPI_SUCCESS; struct MPIR_COMMUNICATOR *comm_ptr; static char myname[] = "MPI_ATTR_DELETE"; TR_PUSH(myname); comm_ptr = MPIR_GET_COMM_PTR(comm); MPIR_TEST_MPI_COMM(comm,comm_ptr,comm_ptr,myname); if ( ( (keyval == MPI_KEYVAL_INVALID) && (mpi_errno = MPI_ERR_OTHER) ) ) return MPIR_ERROR(comm_ptr, mpi_errno, myname); attr_key = MPIR_GET_KEYVAL_PTR( keyval ); MPIR_TEST_MPI_KEYVAL(keyval,attr_key,comm_ptr,myname); if (comm == MPI_COMM_WORLD && attr_key->permanent) return MPIR_ERROR( comm_ptr, MPIR_ERRCLASS_TO_CODE(MPI_ERR_ARG,MPIR_ERR_PERM_KEY),myname ); MPIR_HBT_lookup(comm_ptr->attr_cache, keyval, &attr); if (attr != (MPIR_HBT_node *)0) { if ( attr_key->delete_fn.c_delete_fn ) { if (attr_key->FortranCalling) { MPI_Aint invall = (MPI_Aint)attr->value; int inval = (int)invall; (*attr_key->delete_fn.f77_delete_fn)(comm, &keyval, &inval, attr_key->extra_state, &mpi_errno ); attr->value = (void *)(MPI_Aint)inval; } else mpi_errno = (*attr_key->delete_fn.c_delete_fn)(comm, keyval, attr->value, attr_key->extra_state ); if (mpi_errno) return MPIR_ERROR( comm_ptr, mpi_errno, myname ); } MPIR_HBT_delete(comm_ptr->attr_cache, keyval, &attr); /* We will now have one less reference to keyval */ MPIR_REF_DECR(attr_key); if ( attr != (MPIR_HBT_node *)0 ) (void) MPIR_HBT_free_node ( attr ); } else { mpi_errno = MPIR_Err_setmsg( MPI_ERR_ARG, MPIR_ERR_NOKEY, myname, "Key not in communicator", "Key %d not in communicator", keyval ); return MPIR_ERROR( comm_ptr, mpi_errno, myname ); /* "Error in MPI_ATTR_DELETE: key not in communicator" ); */ } TR_POP; return(mpi_errno); }
/*@ MPI_Attr_put - Stores attribute value associated with a key Input Parameters: + comm - communicator to which attribute will be attached (handle) . keyval - key value, as returned by 'MPI_KEYVAL_CREATE' (integer) - attribute_val - attribute value Notes: Values of the permanent attributes 'MPI_TAG_UB', 'MPI_HOST', 'MPI_IO', and 'MPI_WTIME_IS_GLOBAL' may not be changed. The type of the attribute value depends on whether C or Fortran is being used. In C, an attribute value is a pointer ('void *'); in Fortran, it is a single integer (`not` a pointer, since Fortran has no pointers and there are systems for which a pointer does not fit in an integer (e.g., any > 32 bit address system that uses 64 bits for Fortran 'DOUBLE PRECISION'). If an attribute is already present, the delete function (specified when the corresponding keyval was created) will be called. .N fortran .N Errors .N MPI_SUCCESS .N MPI_ERR_COMM .N MPI_ERR_KEYVAL .N MPI_ERR_PERM_KEY .seealso MPI_Attr_get, MPI_Keyval_create, MPI_Attr_delete @*/ EXPORT_MPI_API int MPI_Attr_put ( MPI_Comm comm, int keyval, void *attr_value ) { MPIR_HBT_node *attr; MPIR_Attr_key *attr_key; int mpi_errno = MPI_SUCCESS; struct MPIR_COMMUNICATOR *comm_ptr; static char myname[] = "MPI_ATTR_PUT"; TR_PUSH(myname); comm_ptr = MPIR_GET_COMM_PTR(comm); MPIR_TEST_MPI_COMM(comm,comm_ptr,comm_ptr,myname); attr_key = MPIR_GET_KEYVAL_PTR( keyval ); MPIR_TEST_MPI_KEYVAL(keyval,attr_key,comm_ptr,myname); /* Check for valid arguments */ if ( ( (keyval == MPI_KEYVAL_INVALID) && (mpi_errno = MPI_ERR_OTHER) ) ) return MPIR_ERROR( comm_ptr, mpi_errno, myname); if (comm == MPI_COMM_WORLD && attr_key->permanent) return MPIR_ERROR( comm_ptr, MPIR_ERRCLASS_TO_CODE(MPI_ERR_ARG,MPIR_ERR_PERM_KEY),myname ); MPIR_HBT_lookup(comm_ptr->attr_cache, keyval, &attr); if (attr == (MPIR_HBT_node *)0) { (void) MPIR_HBT_new_node ( attr_key, attr_value, &attr ); (void) MPIR_HBT_insert ( comm_ptr->attr_cache, attr ); /* Every update to the attr_key must be counted! */ MPIR_REF_INCR(attr_key); } else { /* This is an unclear part of the standard. Under MPI_KEYVAL_CREATE, it is claimed that ONLY MPI_COMM_FREE and MPI_ATTR_DELETE can cause the delete routine to be called. Under MPI_ATTR_PUT, however, the delete routine IS called. */ if ( attr_key->delete_fn.c_delete_fn ) { if (attr_key->FortranCalling) { MPI_Aint invall = (MPI_Aint)attr->value; int inval = (int)invall; (void) (*attr_key->delete_fn.f77_delete_fn)(comm, &keyval, &inval, attr_key->extra_state, &mpi_errno ); attr->value = (void *)(MPI_Aint)inval; } else mpi_errno = (*attr_key->delete_fn.c_delete_fn)(comm, keyval, attr->value, attr_key->extra_state ); if (mpi_errno) return MPIR_ERROR( comm_ptr, mpi_errno, myname); } attr->value = attr_value; } /* The device may want to know about attributes */ MPID_ATTR_SET(comm_ptr,keyval,attr_value); TR_POP; return (mpi_errno); }