The routines described in this section of the MPI tool information interface specification focus on the ability to list, query, and possibly set control variables exposed by the MPI implementation. These variables can typically be used by the user to fine tune properties and configuration settings of the MPI implementation. On many systems, such variables can be set using environment variables, although other configuration mechanisms may be available, such as configuration files or central configuration registries. A typical example that is available in several existing MPI implementations is the ability to specify an ``eager limit,'' i.e., an upper bound on the size of messages sent or received using an eager protocol.
An MPI implementation exports a set of N control variables through the MPI tool information interface. If N is zero, then the MPI implementation does not export any control variables, otherwise the provided control variables are indexed from 0 to N-1. This index number is used in subsequent calls to identify the individual variables.
An MPI implementation is allowed to increase the number of control variables during the execution of an MPI application when new variables become available through dynamic loading. However, MPI implementations are not allowed to change the index of a control variable or to delete a variable once it has been added to the set. When a variable becomes inactive, e.g., through dynamic unloading, accessing its value should return a corresponding error code.
Advice to users.
While the MPI tool information interface guarantees that indices or variable properties do not change
during a particular run of an MPI program, it does not provide a similar
guarantee between runs.
( End of advice to users.)
The following function can be used to query the number of control
variables, num_cvar:
MPI_T_CVAR_GET_NUM(num_cvar) | |
OUT num_cvar | returns number of control variables (integer) |
int MPI_T_cvar_get_num(int *num_cvar)
The function MPI_T_CVAR_GET_INFO provides access to additional information for each variable.
MPI_T_CVAR_GET_INFO(cvar_index, name, name_len, verbosity, datatype, enumtype, desc, desc_len, bind, scope) | |
IN cvar_index | index of the control variable to be queried, value between 0 and num_cvar-1 (integer) |
OUT name | buffer to return the string containing the name of the control variable (string) |
INOUT name_len | length of the string and/or buffer for name (integer) |
OUT verbosity | verbosity level of this variable (integer) |
OUT datatype | MPI datatype of the information stored in the control variable (handle) |
OUT enumtype | optional descriptor for enumeration information (handle) |
OUT desc | buffer to return the string containing a description of the control variable (string) |
INOUT desc_len | length of the string and/or buffer for desc (integer) |
OUT bind | type of MPI object to which this variable must be bound (integer) |
OUT scope | scope of when changes to this variable are possible (integer) |
int MPI_T_cvar_get_info(int cvar_index, char *name, int *name_len, int *verbosity, MPI_Datatype *datatype, MPI_T_enum *enumtype, char *desc, int *desc_len, int *bind, int *scope)
After a successful call to MPI_T_CVAR_GET_INFO for a particular variable, subsequent calls to this routine that query information about the same variable must return the same information. An MPI implementation is not allowed to alter any of the returned values.
If any OUT parameter to MPI_T_CVAR_GET_INFO is a NULL pointer, the implementation will ignore the parameter and not return a value for the parameter.
The arguments name and name_len are used to return the name of the control variable as described in Section Convention for Returning Strings .
If completed successfully, the routine is required to return a name of at least length one. The name must be unique with respect to all other names for control variables used by the MPI implementation.
The argument verbosity returns the verbosity level of the variable (see Section Verbosity Levels ).
The argument datatype returns the MPI datatype that is used to represent the control variable.
If the variable is of type MPI_INT, MPI can optionally specify an enumeration for the values represented by this variable and return it in enumtype. In this case, MPI returns an enumeration identifier, which can then be used to gather more information as described in Section Datatype System . Otherwise, enumtype is set to MPI_T_ENUM_NULL. If the datatype is not MPI_INT or the argument enumtype is the null pointer, no enumeration type is returned.
The arguments desc and desc_len are used to return a description of the control variable as described in Section Convention for Returning Strings .
Returning a description is optional. If an MPI implementation does not return a description, the first character for desc must be set to the null character and desc_len must be set to one at the return of this call.
The parameter bind returns the type of the MPI object to which the variable must be bound or the value MPI_T_BIND_NO_OBJECT (see Section Binding MPI Tool Information Interface Variables to MPI Objects ).
The scope of a variable determines whether changing a variable's value is either local to the process or must be done by the user across multiple processes. The latter is further split into variables that require changes in a group of processes and those that require collective changes among all connected processes. Both cases can require all processes either to be set to consistent (but potentially different) values or to equal values on every participating process. The description provided with the variable must contain an explanation about the requirements and/or restrictions for setting the particular variable.
On successful return from MPI_T_CVAR_GET_INFO, the argument scope will be set to one of the constants listed in Table 15 .
If the name of a control variable is equivalent across connected processes, the following OUT parameters must be identical: verbosity, datatype, enumtype, bind, and scope. The returned description must be equivalent.
Scope Constant | Description |
MPI_T_SCOPE_CONSTANT | read-only, value is constant |
MPI_T_SCOPE_READONLY | read-only, cannot be written, but can change |
MPI_T_SCOPE_LOCAL | may be writeable, writing is a local operation |
MPI_T_SCOPE_GROUP | may be writeable, must be done to a group of processes, |
all processes in a group must be set to consistent values | |
MPI_T_SCOPE_GROUP_EQ | may be writeable, must be done to a group of processes, |
all processes in a group must be set to the same value | |
MPI_T_SCOPE_ALL | may be writeable, must be done to all processes, |
all connected processes must be set to consistent values | |
MPI_T_SCOPE_ALL_EQ | may be writeable, must be done to all processes, |
all connected processes must be set to the same value | |
Advice to users.
The scope of a variable only indicates if a variable might be
changeable; it is not a guarantee that it can be changed at any time.
( End of advice to users.)
MPI_T_CVAR_GET_INDEX(name, cvar_index) | |
IN name | name of the control variable (string) |
OUT cvar_index | index of the control variable (integer) |
int MPI_T_cvar_get_index(const char *name, int *cvar_index)
MPI_T_CVAR_GET_INDEX is a function for retrieving the index of a control variable given a known variable name. The name parameter is provided by the caller, and cvar_index is returned by the MPI implementation. The name parameter is a string terminated with a null character.
This routine returns MPI_SUCCESS on success and returns MPI_T_ERR_INVALID_NAME if name does not match the name of any control variable provided by the implementation at the time of the call.
Rationale.
This routine is provided to enable fast retrieval of control variables by a tool,
assuming it knows the name of the variable for which it is looking.
The number of variables exposed by the implementation can change over time,
so it is not possible for the tool to simply iterate over the list of variables
once at initialization. Although using MPI implementation specific variable
names is not portable across MPI implementations, tool developers may choose to
take this route for lower overhead at runtime because the tool will not have to
iterate over the entire set of variables to find a specific one.
( End of rationale.)
Example
The following example shows how the MPI tool information interface can be used to query and to print the names of all available control variables.
#include <stdio.h> #include <stdlib.h> #include <mpi.h> int main(int argc, char *argv[]) { int i, err, num, namelen, bind, verbose, scope; int threadsupport; char name[100]; MPI_Datatype datatype; err=MPI_T_init_thread(MPI_THREAD_SINGLE,&threadsupport); if (err!=MPI_SUCCESS) return err; err=MPI_T_cvar_get_num(&num); if (err!=MPI_SUCCESS) return err; for (i=0; i<num; i++) { namelen=100; err=MPI_T_cvar_get_info(i, name, &namelen, &verbose, &datatype, NULL, NULL, NULL, /*no description */ &bind, &scope); if (err!=MPI_SUCCESS || err!=MPI_T_ERR_INVALID_INDEX) return err; printf("Var %i: %s\n", i, name); } err=MPI_T_finalize(); if (err!=MPI_SUCCESS) return 1; else return 0; }
Before reading or writing the value of a variable, a user must first allocate a handle of type MPI_T_cvar_handle for the variable by binding it to an MPI object (see also Section Binding MPI Tool Information Interface Variables to MPI Objects ).
Rationale.
Handles used in the MPI tool information interface are distinct from handles used in the remaining parts of the MPI standard because they must be usable
before MPI_INIT and after
MPI_FINALIZE. Further, accessing
handles, in particular for performance variables, can be time critical
and having a separate handle space enables optimizations.
( End of rationale.)
MPI_T_CVAR_HANDLE_ALLOC(cvar_index, obj_handle, handle, count) | |
IN cvar_index | index of control variable for which handle is to be allocated (index) |
IN obj_handle | reference to a handle of the MPI object to which this variable is supposed to be bound (pointer) |
OUT handle | allocated handle (handle) |
OUT count | number of elements used to represent this variable (integer) |
int MPI_T_cvar_handle_alloc(int cvar_index, void *obj_handle, MPI_T_cvar_handle *handle, int *count)
This routine binds the control variable specified by the argument index to an MPI object. The object is passed in the argument obj_handle as an address to a local variable that stores the object's handle. The argument obj_handle is ignored if the MPI_T_CVAR_GET_INFO call for this control variable returned MPI_T_BIND_NO_OBJECT in the argument bind. The handle allocated to reference the variable is returned in the argument handle. Upon successful return, count contains the number of elements (of the datatype returned by a previous MPI_T_CVAR_GET_INFO call) used to represent this variable.
Advice to users.
The count can be different based on the MPI object to which the control variable was bound. For example, variables bound to communicators could have a count that matches the size of the communicator.
It is not portable to pass references to predefined MPI object handles,
such as MPI_COMM_WORLD to this routine, since their
implementation depends on the MPI library. Instead, such object handles should
be stored in a local variable and the address of this local variable
should be passed into MPI_T_CVAR_HANDLE_ALLOC.
( End of advice to users.)
The value of cvar_index should
be in the range 0 to num_cvar-1, where num_cvar is the number of available control
variables as determined from a prior call to MPI_T_CVAR_GET_NUM.
The type of the MPI object it references must be consistent with the type
returned in the bind argument in a prior call to MPI_T_CVAR_GET_INFO.
MPI_T_CVAR_HANDLE_FREE(handle) | |
INOUT handle | handle to be freed (handle) |
int MPI_T_cvar_handle_free(MPI_T_cvar_handle *handle)
When a handle is no longer needed, a user of the MPI tool information interface should call MPI_T_CVAR_HANDLE_FREE to free the handle and the associated resources in the MPI implementation. On a successful return, MPI sets the handle to MPI_T_CVAR_HANDLE_NULL.
MPI_T_CVAR_READ(handle, buf) | |
IN handle | handle to the control variable to be read (handle) |
OUT buf | initial address of storage location for variable value (choice) |
int MPI_T_cvar_read(MPI_T_cvar_handle handle, void* buf)
This routine queries the value of a control variable identified by the argument handle and stores the result in the buffer identified by the parameter buf. The user must ensure that the buffer is of the appropriate size to hold the entire value of the control variable (based on the returned datatype and count from prior corresponding calls to MPI_T_CVAR_GET_INFO and MPI_T_CVAR_HANDLE_ALLOC, respectively).
MPI_T_CVAR_WRITE(handle, buf) | |
IN handle | handle to the control variable to be written (handle) |
IN buf | initial address of storage location for variable value (choice) |
int MPI_T_cvar_write(MPI_T_cvar_handle handle, const void* buf)
This routine sets the value of the control variable identified by the argument handle to the data stored in the buffer identified by the parameter buf. The user must ensure that the buffer is of the appropriate size to hold the entire value of the control variable (based on the returned datatype and count from prior corresponding calls to MPI_T_CVAR_GET_INFO and MPI_T_CVAR_HANDLE_ALLOC, respectively).
If the variable has a global scope (as returned by a prior corresponding MPI_T_CVAR_GET_INFO call), any write call to this variable must be issued by the user in all connected (as defined in Section Releasing Connections ) MPI processes. If the variable has group scope, any write call to this variable must be issued by the user in all MPI processes in the group, which must be described by the MPI implementation in the description by the MPI_T_CVAR_GET_INFO.
In both cases, the user must ensure that the writes in all processes are consistent. If the scope is either MPI_T_SCOPE_ALL_EQ or MPI_T_SCOPE_GROUP_EQ this means that the variable in all processes must be set to the same value.
If it is not possible to change the variable at the time the call is made, the function returns either MPI_T_ERR_CVAR_SET_NOT_NOW, if there may be a later time at which the variable could be set, or MPI_T_ERR_CVAR_SET_NEVER, if the variable cannot be set for the remainder of the application's execution.
Example
The following example shows a routine that can be used to query the value with a control variable with a given index. The example assumes that the variable is intended to be bound to an MPI communicator.
int getValue_int_comm(int index, MPI_Comm comm, int *val) { int err,count; MPI_T_cvar_handle handle; /* This example assumes that the variable index */ /* can be bound to a communicator */ err=MPI_T_cvar_handle_alloc(index,&comm,&handle,&count); if (err!=MPI_SUCCESS) return err; /* The following assumes that the variable is */ /* represented by a single integer */ err=MPI_T_cvar_read(handle,val); if (err!=MPI_SUCCESS) return err; err=MPI_T_cvar_handle_free(&handle); return err; }