# vim: set ft=c: MPI_T_category_changed: .desc: Get the timestamp indicating the last change to the categories /* Notes: If two subsequent calls to this routine return the same timestamp, it is guaranteed that the category information has not changed between the two calls. If the timestamp retrieved from the second call is higher, then some categories have been added or expanded. */ { *update_number = cat_stamp; } MPI_T_category_get_categories: .desc: Get sub-categories in a category { -- error_check -- indices if (len != 0) { MPIT_ERRTEST_ARGNULL(indices); } } { -- early_return -- if (len == 0) { goto fn_exit; } } MPI_T_category_get_cvars: .desc: Get control variables in a category { -- error_check -- indices if (len != 0) { MPIT_ERRTEST_ARGNULL(indices); } } { -- early_return -- if (len == 0) { goto fn_exit; } } MPI_T_category_get_index: .desc: Get the index of a category .error: MPI_T_ERR_INVALID_NAME { name2index_hash_t *hash_entry; /* Do hash lookup by the name */ HASH_FIND_STR(cat_hash, name, hash_entry); if (hash_entry != NULL) { *cat_index = hash_entry->idx; } else { mpi_errno = MPI_T_ERR_INVALID_NAME; goto fn_fail; } } MPI_T_category_get_info: .desc: Get the information about a category .skip: validate-ANY .error: MPI_T_ERR_INVALID_INDEX { -- error_check -- MPIT_ERRTEST_CAT_INDEX(cat_index); } { cat_table_entry_t *cat; cat = (cat_table_entry_t *) utarray_eltptr(cat_table, cat_index); MPIR_T_strncpy(name, cat->name, name_len); MPIR_T_strncpy(desc, cat->desc, desc_len); if (num_cvars != NULL) *num_cvars = utarray_len(cat->cvar_indices); if (num_pvars != NULL) *num_pvars = utarray_len(cat->pvar_indices); if (num_categories != NULL) *num_categories = utarray_len(cat->subcat_indices); } MPI_T_category_get_num: .desc: Get the number of categories { *num_cat = utarray_len(cat_table); } MPI_T_category_get_pvars: .desc: Get performance variables in a category .error: MPI_T_ERR_INVALID { -- error_check -- indices if (len != 0) { MPIT_ERRTEST_ARGNULL(indices); } } { -- early_return -- if (len == 0) { goto fn_exit; } } MPI_T_cvar_get_index: .desc: Get the index of a control variable .error: MPI_T_ERR_INVALID_NAME { name2index_hash_t *hash_entry; /* Do hash lookup by the name */ HASH_FIND_STR(cvar_hash, name, hash_entry); if (hash_entry != NULL) { *cvar_index = hash_entry->idx; } else { mpi_errno = MPI_T_ERR_INVALID_NAME; goto fn_fail; } } MPI_T_cvar_get_info: .desc: Get the information about a control variable .skip: validate-ANY .error: MPI_T_ERR_INVALID_INDEX { -- error_check -- MPIT_ERRTEST_CVAR_INDEX(cvar_index); } { cvar_table_entry_t *cvar; cvar = (cvar_table_entry_t *) utarray_eltptr(cvar_table, cvar_index); MPIR_T_strncpy(name, cvar->name, name_len); MPIR_T_strncpy(desc, cvar->desc, desc_len); if (verbosity != NULL) *verbosity = cvar->verbosity; if (datatype != NULL) *datatype = cvar->datatype; if (enumtype != NULL) *enumtype = cvar->enumtype; if (bind!= NULL) *bind= cvar->bind; if (scope != NULL) *scope = cvar->scope; } MPI_T_cvar_get_num: .desc: Get the number of control variables { *num_cvar = utarray_len(cvar_table); } MPI_T_cvar_handle_alloc: .desc: Allocate a handle for a control variable .skip: validate-TOOL_MPI_OBJ .error: MPI_T_ERR_OUT_OF_HANDLES MPI_T_cvar_handle_free: .desc: Free an existing handle for a control variable { MPIR_T_cvar_handle_t *hnd; hnd = *handle; MPL_free(hnd); *handle = MPI_T_CVAR_HANDLE_NULL; } MPI_T_cvar_read: .desc: Read the value of a control variable MPI_T_cvar_write: .desc: Write a control variable .error: MPI_T_ERR_CVAR_SET_NEVER, MPI_T_ERR_CVAR_SET_NOT_NOW { -- error_check -- MPIR_T_cvar_handle_t *hnd = handle; if (hnd->scope == MPI_T_SCOPE_CONSTANT) { mpi_errno = MPI_T_ERR_CVAR_SET_NEVER; goto fn_fail; } else if (hnd->scope == MPI_T_SCOPE_READONLY) { mpi_errno = MPI_T_ERR_CVAR_SET_NOT_NOW; goto fn_fail; } } MPI_T_enum_get_info: .desc: Get the information about an enumeration .skip: validate-STRING, validate-STRING_LENGTH { *num = utarray_len(enumtype->items); MPIR_T_strncpy(name, enumtype->name, name_len); } MPI_T_enum_get_item: .desc: Get the information about an item in an enumeration { enum_item_t *item; item = (enum_item_t *) utarray_eltptr(enumtype->items, indx); *value = item->value; MPIR_T_strncpy(name, item->name, name_len); } MPI_T_finalize: .desc: Finalize the MPI tool information interface .skip: global_cs .seealso: MPI_T_init_thread .error: MPI_T_ERR_NOT_INITIALIZED /* Notes: This routine may be called as often as the corresponding MPI_T_init_thread() routine up to the current point of execution. Calling it more times returns a corresponding error code. As long as the number of calls to MPI_T_finalize() is smaller than the number of calls to MPI_T_init_thread() up to the current point of execution, the MPI tool information interface remains initialized and calls to its routines are permissible. Further, additional calls to MPI_T_init_thread() after one or more calls to MPI_T_finalize() are permissible. Once MPI_T_finalize() is called the same number of times as the routine MPI_T_init_thread() up to the current point of execution, the MPI tool information interface is no longer initialized. The interface can be reinitialized by subsequent calls to MPI_T_init_thread(). At the end of the program execution, unless MPI_Abort() is called, an application must have called MPI_T_init_thread() and MPI_T_finalize() an equal number of times. */ { --MPIR_T_init_balance; if (MPIR_T_init_balance < 0) { mpi_errno = MPI_T_ERR_NOT_INITIALIZED; goto fn_fail; } if (MPIR_T_init_balance == 0) { MPIR_T_THREAD_CS_FINALIZE(); MPIR_T_env_finalize(); } } MPI_T_init_thread: .desc: Initialize the MPI_T execution environment .skip: global_cs, initcheck .seealso: MPI_T_finalize /* Notes: The valid values for the level of thread support are: + MPI_THREAD_SINGLE - Only one thread will execute. . MPI_THREAD_FUNNELED - The process may be multi-threaded, but only the main thread will make MPI_T calls (all MPI_T calls are funneled to the main thread). . MPI_THREAD_SERIALIZED - The process may be multi-threaded, and multiple threads may make MPI_T calls, but only one at a time: MPI_T calls are not made concurrently from two distinct threads (all MPI_T calls are serialized). - MPI_THREAD_MULTIPLE - Multiple threads may call MPI_T, with no restrictions. */ { -- error_check -- required CHECKENUM: required, thread_level, MPI_THREAD_SINGLE MPI_THREAD_FUNNELED MPI_THREAD_SERIALIZED MPI_THREAD_MULTIPLE } { #if defined MPICH_IS_THREADED MPIR_T_is_threaded = (required == MPI_THREAD_MULTIPLE); #endif /* MPICH_IS_THREADED */ if (provided != NULL) { /* This must be min(required,MPICH_THREAD_LEVEL) if runtime * control of thread level is available */ *provided = (MPICH_THREAD_LEVEL < required) ? MPICH_THREAD_LEVEL : required; } ++MPIR_T_init_balance; if (MPIR_T_init_balance == 1) { MPIR_T_THREAD_CS_INIT(); mpi_errno = MPIR_T_env_init(); if (mpi_errno) { goto fn_fail; } } } MPI_T_pvar_get_index: .desc: Get the index of a performance variable .error: MPI_T_ERR_INVALID_NAME { int seq = var_class - MPIR_T_PVAR_CLASS_FIRST; name2index_hash_t *hash_entry; /* Do hash lookup by the name */ HASH_FIND_STR(pvar_hashs[seq], name, hash_entry); if (hash_entry != NULL) { *pvar_index = hash_entry->idx; } else { mpi_errno = MPI_T_ERR_INVALID_NAME; goto fn_fail; } } MPI_T_pvar_get_info: .desc: Get the information about a performance variable .skip: validate-ANY .error: MPI_T_ERR_INVALID_INDEX { -- error_check -- MPIT_ERRTEST_CVAR_INDEX(pvar_index); } { pvar_table_entry_t *entry; entry = (pvar_table_entry_t *) utarray_eltptr(pvar_table, pvar_index); if (!entry->active) { mpi_errno = MPI_T_ERR_INVALID_INDEX; goto fn_fail; } pvar_table_entry_t *info; info = (pvar_table_entry_t *) utarray_eltptr(pvar_table, pvar_index); MPIR_T_strncpy(name, info->name, name_len); MPIR_T_strncpy(desc, info->desc, desc_len); if (verbosity != NULL) *verbosity = info->verbosity; if (var_class != NULL) *var_class = info->varclass; if (datatype != NULL) *datatype = info->datatype; if (enumtype != NULL) *enumtype = info->enumtype; if (bind != NULL) *bind = info->bind; if (readonly != NULL) *readonly = info->flags & MPIR_T_PVAR_FLAG_READONLY; if (continuous != NULL) *continuous = info->flags & MPIR_T_PVAR_FLAG_CONTINUOUS; if (atomic != NULL) *atomic = info->flags & MPIR_T_PVAR_FLAG_ATOMIC; } MPI_T_pvar_get_num: .desc: Get the number of performance variables { *num_pvar = utarray_len(pvar_table); } MPI_T_pvar_handle_alloc: .desc: Allocate a handle for a performance variable .skip: validate-TOOL_MPI_OBJ .error: MPI_T_ERR_INVALID_INDEX, MPI_T_ERR_OUT_OF_HANDLES { -- error_check -- pvar_index pvar_table_entry_t *entry; entry = (pvar_table_entry_t *) utarray_eltptr(pvar_table, pvar_index); if (!entry->active) { mpi_errno = MPI_T_ERR_INVALID_INDEX; goto fn_fail; } } MPI_T_pvar_handle_free: .desc: Free an existing handle for a performance variable MPI_T_pvar_read: .desc: Read the value of a performance variable /* Notes: The MPI_T_pvar_read() call queries the value of the performance variable with the handle "handle" in the session identified by the parameter session and stores the result in the buffer identified by the parameter buf. The user is responsible to ensure that the buffer is of the appropriate size to hold the entire value of the performance variable (based on the datatype and count returned by the corresponding previous calls to MPI_T_pvar_get_info() and MPI_T_pvar_handle_alloc(), respectively). The constant MPI_T_PVAR_ALL_HANDLES cannot be used as an argument for the function MPI_T_pvar_read(). */ MPI_T_pvar_readreset: .desc: Read the value of a performance variable and then reset it .error: MPI_T_ERR_INVALID_HANDLE, MPI_T_ERR_PVAR_NO_ATOMIC { -- error_check -- if (handle == MPI_T_PVAR_ALL_HANDLES || session != handle->session || !MPIR_T_pvar_is_oncestarted(handle)) { mpi_errno = MPI_T_ERR_INVALID_HANDLE; goto fn_fail; } if (!MPIR_T_pvar_is_atomic(handle)) { mpi_errno = MPI_T_ERR_PVAR_NO_ATOMIC; goto fn_fail; } } MPI_T_pvar_reset: .desc: Reset a performance variable .error: MPI_T_ERR_INVALID_HANDLE, MPI_T_ERR_PVAR_NO_WRITE /* Notes: The MPI_T_pvar_reset() call sets the performance variable with the handle identified by the parameter handle to its starting value. If it is not possible to change the variable, the function returns MPI_T_ERR_PVAR_NO_WRITE. If the constant MPI_T_PVAR_ALL_HANDLES is passed in handle, the MPI implementation attempts to reset all variables within the session identified by the parameter session for which handles have been allocated. In this case, the routine returns MPI_SUCCESS if all variables are reset successfully, otherwise MPI_T_ERR_PVAR_NO_WRITE is returned. Readonly variables are ignored when MPI_T_PVAR_ALL_HANDLES is specified. */ { MPIR_T_pvar_handle_t *hnd; /* If handle is MPI_T_PVAR_ALL_HANDLES, dispatch the call. * Otherwise, do correctness check, then go to impl. */ if (handle == MPI_T_PVAR_ALL_HANDLES) { DL_FOREACH(session->hlist, hnd) { if (!MPIR_T_pvar_is_readonly(hnd)) { mpi_errno = MPIR_T_pvar_reset_impl(session, hnd); if (mpi_errno != MPI_SUCCESS) goto fn_fail; } } } else { if (handle->session != session) { mpi_errno = MPI_T_ERR_INVALID_HANDLE; goto fn_fail; } if (MPIR_T_pvar_is_readonly(handle)) { mpi_errno = MPI_T_ERR_PVAR_NO_WRITE; goto fn_fail; } mpi_errno = MPIR_T_pvar_reset_impl(session, handle); if (mpi_errno != MPI_SUCCESS) goto fn_fail; } } MPI_T_pvar_session_create: .desc: Create a new session for accessing performance variables .error: MPI_T_ERR_OUT_OF_SESSIONS MPI_T_pvar_session_free: .desc: Free an existing performance variable session /* Notes: Calls to the MPI tool information interface can no longer be made within the context of a session after it is freed. On a successful return, MPI sets the session identifier to MPI_T_PVAR_SESSION_NULL. */ MPI_T_pvar_start: .desc: Start a performance variable .error: MPI_T_ERR_INVALID_HANDLE, MPI_T_ERR_PVAR_NO_STARTSTOP /* Notes: If the constant MPI_T_PVAR_ALL_HANDLES is passed in handle, the MPI implementation attempts to start all variables within the session identified by the parameter session for which handles have been allocated. In this case, the routine returns MPI_SUCCESS if all variables are started successfully, otherwise MPI_T_ERR_PVAR_NO_STARTSTOP is returned. Continuous variables and variables that are already started are ignored when MPI_T_PVAR_ALL_HANDLES is specified. */ { if (handle == MPI_T_PVAR_ALL_HANDLES) { MPIR_T_pvar_handle_t *hnd; DL_FOREACH(session->hlist, hnd) { if (!MPIR_T_pvar_is_continuous(hnd) && !MPIR_T_pvar_is_started(hnd)) mpi_errno = MPIR_T_pvar_start_impl(session, hnd); } } else { if (handle->session != session) { mpi_errno = MPI_T_ERR_INVALID_HANDLE; goto fn_fail; } if (MPIR_T_pvar_is_continuous(handle)) { mpi_errno = MPI_T_ERR_PVAR_NO_STARTSTOP; goto fn_fail; } if (!MPIR_T_pvar_is_started(handle)) { mpi_errno = MPIR_T_pvar_start_impl(session, handle); if (mpi_errno != MPI_SUCCESS) goto fn_fail; } } } MPI_T_pvar_stop: .desc: Stop a performance variable .error: MPI_T_ERR_INVALID_HANDLE, MPI_T_ERR_PVAR_NO_STARTSTOP /* Notes: This functions stops the performance variable with the handle identified by the parameter handle in the session identified by the parameter session. If the constant MPI_T_PVAR_ALL_HANDLES is passed in handle, the MPI implementation attempts to stop all variables within the session identified by the parameter session for which handles have been allocated. In this case, the routine returns MPI_SUCCESS if all variables are stopped successfully, otherwise MPI_T_ERR_PVAR_NO_STARTSTOP is returned. Continuous variables and variables that are already stopped are ignored when MPI_T_PVAR_ALL_HANDLES is specified. */ { /* If handle is MPI_T_PVAR_ALL_HANDLES, dispatch the call. * Otherwise, do correctness check, then go to impl. */ if (handle == MPI_T_PVAR_ALL_HANDLES) { MPIR_T_pvar_handle_t *hnd; DL_FOREACH(session->hlist, hnd) { if (!MPIR_T_pvar_is_continuous(hnd) && MPIR_T_pvar_is_started(hnd)) { mpi_errno = MPIR_T_pvar_stop_impl(session, hnd); if (mpi_errno != MPI_SUCCESS) goto fn_fail; } } } else { if (handle->session != session) { mpi_errno = MPI_T_ERR_INVALID_HANDLE; goto fn_fail; } if (MPIR_T_pvar_is_continuous(handle)) { mpi_errno = MPI_T_ERR_PVAR_NO_STARTSTOP; goto fn_fail; } if (MPIR_T_pvar_is_started(handle)) { mpi_errno = MPIR_T_pvar_stop_impl(session, handle); if (mpi_errno != MPI_SUCCESS) goto fn_fail; } } } MPI_T_pvar_write: .desc: Write a performance variable .error: MPI_T_ERR_PVAR_NO_WRITE /* Notes: The MPI_T_pvar_write() call attempts to write the value of the performance variable with the handle identified by the parameter handle in the session identified by the parameter session. The value to be written is passed 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 performance variable (based on the datatype and count returned by the corresponding previous calls to MPI_T_pvar_get_info() and MPI_T_pvar_handle_alloc(), respectively). The constant MPI_T_PVAR_ALL_HANDLES cannot be used as an argument for the function MPI_T_pvar_write(). */ { -- error_check -- if (MPIR_T_pvar_is_readonly(handle)) { mpi_errno = MPI_T_ERR_PVAR_NO_WRITE; goto fn_fail; } } MPI_T_category_get_num_events: .desc: Returns the number of event types contained in the queried category. .error: MPI_T_ERR_INVALID_INDEX MPI_T_category_get_events: .desc: Query which event types are contained in a particular category. .error: MPI_T_ERR_INVALID_INDEX MPI_T_source_get_num: .desc: Query the number of event sources MPI_T_source_get_info: .desc: Returns additional information on the source identified by the source_index argument .skip: validate-INFO, validate-SOURCE_INDEX .error: MPI_T_ERR_INVALID_INDEX MPI_T_source_get_timestamp: .desc: Returns a current timestamp from the source identified by the source_index argument .skip: validate-SOURCE_INDEX .error: MPI_T_ERR_INVALID_INDEX, MPI_T_ERR_NOT_SUPPORTED MPI_T_event_get_num: .desc: Query the number of event types MPI_T_event_get_info: .desc: Returns additional information about a specific event type .skip: validate-STRING, validate-DATATYPE, validate-DISPLACEMENT_NNI, validate-ARRAY_LENGTH_NNI, validate-INFO, validate-EVENT_INDEX .error: MPI_T_ERR_INVALID_INDEX MPI_T_event_get_index: .desc: Returns the index of an event type identified by a known event type name .error: MPI_T_ERR_INVALID_NAME MPI_T_event_handle_alloc: .desc: Creates a registration handle for the event type identified by event_index .skip: validate-TOOL_MPI_OBJ, validate-EVENT_INDEX .error: MPI_T_ERR_INVALID_INDEX MPI_T_event_handle_set_info: .desc: Updates the hints of the event-registration handle associated with event_registration MPI_T_event_handle_get_info: .desc: Returns a new info object containing the hints of the event-registration handle associated with event_registration MPI_T_event_register_callback: .desc: Associates a user-defined function with an allocated event-registration handle .skip: validate-CALLBACK_SAFETY, validate-EVENT_CB_FUNCTION MPI_T_event_callback_set_info: .desc: Updates the hints of the callback function registered for the callback safety level specified by cb_safety of the event-registration handle associated with event_registration .skip: validate-CALLBACK_SAFETY MPI_T_event_callback_get_info: .desc: Returns a new info object containing the hints of the callback function registered for the callback safety level specified by cb_safety of the event-registration handle associated with event_registration. .skip: validate-CALLBACK_SAFETY MPI_T_event_handle_free: .desc: Initiates deallocation of the event-registration handle specified by event_registration .skip: validate-EVENT_FREE_CB_FUNCTION MPI_T_event_set_dropped_handler: .desc: Registers a function to be called when event information is dropped for the registration handle specified in event_registration .skip: validate-EVENT_DROP_CB_FUNCTION MPI_T_event_read: .desc: Copy one element of event data to a user-specified buffer MPI_T_event_copy: .desc: Copy event data as a whole into a user-specified buffer MPI_T_event_get_timestamp: .desc: Returns the timestamp of when the event was initially observed by the implementation MPI_T_event_get_source: .desc: Returns the index of the source of the event instance