MCA: Per-RFC, add support for performance variables
This commit adds an API for registering and querying performance variables (mca_base_pvar) in the MCA base. The existing MCA variable system API has been updated to reflect the new API: MCA variable groups have performance variables, and new types have been added (double, unsigned long long) to reflect what is required by the MPI_T interface. Additionally, the MCA variable group code has been split into its own set of files: mca_base_var_group.[ch]. Details of the new API can be found in doxygen comments in the header: mca_base_pvar.h. Other changes to the variable system: - Use an opal_hash_table to speed up variable/group lookup. - Clean up code associated with MCA variable types. - Registered performance variables are printed by ompi_info -a. In the future an option should be added to control this behavior. Changes to OMPI: - Added full support for the MPI_T performance variable interface. This commit was SVN r28800.
Этот коммит содержится в:
родитель
5f520e241b
Коммит
d446675526
@ -331,8 +331,8 @@ typedef struct ompi_status_public_t MPI_Status;
|
||||
typedef struct ompi_win_t *MPI_Win;
|
||||
typedef struct mca_base_var_enum_t *MPI_T_enum;
|
||||
typedef struct ompi_mpit_cvar_handle_t *MPI_T_cvar_handle;
|
||||
typedef struct ompi_mpit_pvar_handle_t *MPI_T_pvar_handle;
|
||||
typedef struct ompi_mpit_pvar_session_t *MPI_T_pvar_session;
|
||||
typedef struct mca_base_pvar_handle_t *MPI_T_pvar_handle;
|
||||
typedef struct mca_base_pvar_session_t *MPI_T_pvar_session;
|
||||
|
||||
/*
|
||||
* MPI_Status
|
||||
@ -725,7 +725,7 @@ enum {
|
||||
#if OMPI_PROVIDE_MPI_FILE_INTERFACE
|
||||
#define MPI_FILE_NULL OMPI_PREDEFINED_GLOBAL(MPI_File, ompi_mpi_file_null)
|
||||
#endif
|
||||
#define MPI_T_ENUM_NULL NULL
|
||||
#define MPI_T_ENUM_NULL ((MPI_T_enum) NULL)
|
||||
|
||||
/*
|
||||
* MPI_INFO_ENV handle
|
||||
@ -735,6 +735,12 @@ enum {
|
||||
#define MPI_STATUS_IGNORE ((MPI_Status *) 0)
|
||||
#define MPI_STATUSES_IGNORE ((MPI_Status *) 0)
|
||||
|
||||
/*
|
||||
* Special MPI_T handles
|
||||
*/
|
||||
#define MPI_T_PVAR_ALL_HANDLES ((MPI_T_pvar_handle) -1)
|
||||
#define MPI_T_PVAR_HANDLE_NULL ((MPI_T_pvar_handle) 0)
|
||||
|
||||
/* MPI-2 specifies that the name "MPI_TYPE_NULL_DELETE_FN" (and all
|
||||
related friends) must be accessible in C, C++, and Fortran. This is
|
||||
unworkable if the back-end Fortran compiler uses all caps for its
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
# This Makefile.am does not stand on its own - it is included from ompi/Makefile.am
|
||||
|
||||
headers += mpit/mpit-internal.h
|
||||
headers += mpit/mpit-internal.h mpit/mpit-pvar.h
|
||||
|
||||
libmpi_la_SOURCES += mpit/init_thread.c mpit/finalize.c mpit/cvar_get_num.c \
|
||||
mpit/cvar_get_info.c mpit/cvar_read.c mpit/cvar_write.c \
|
||||
|
@ -33,9 +33,8 @@ int MPI_T_category_get_info(int cat_index, char *name, int *name_len,
|
||||
break;
|
||||
}
|
||||
|
||||
/* XXX -- TODO -- Implement me */
|
||||
if (NULL != num_pvars) {
|
||||
*num_pvars = 0;
|
||||
*num_pvars = opal_value_array_get_size ((opal_value_array_t *) &group->group_pvars);
|
||||
}
|
||||
|
||||
if (NULL != num_cvars) {
|
||||
|
@ -15,10 +15,33 @@ static const char FUNC_NAME[] = "MPI_T_category_get_pvars";
|
||||
|
||||
int MPI_T_category_get_pvars(int cat_index, int len, int indices[])
|
||||
{
|
||||
const mca_base_var_group_t *group;
|
||||
int rc = MPI_SUCCESS;
|
||||
const int *vars;
|
||||
int i, size;
|
||||
|
||||
if (!mpit_is_initialized ()) {
|
||||
return MPI_T_ERR_NOT_INITIALIZED;
|
||||
}
|
||||
/* XXX -- TODO -- add pvar support */
|
||||
|
||||
return MPI_ERR_UNSUPPORTED_OPERATION;
|
||||
mpit_lock ();
|
||||
|
||||
do {
|
||||
rc = mca_base_var_group_get (cat_index, &group);
|
||||
if (0 > rc) {
|
||||
rc = (OPAL_ERR_NOT_FOUND == rc) ? MPI_T_ERR_INVALID_INDEX : MPI_ERR_OTHER;
|
||||
break;
|
||||
}
|
||||
|
||||
size = opal_value_array_get_size((opal_value_array_t *) &group->group_pvars);
|
||||
vars = OPAL_VALUE_ARRAY_GET_BASE(&group->group_pvars, int);
|
||||
|
||||
for (i = 0 ; i < len && i < size ; ++i) {
|
||||
indices[i] = vars[i];
|
||||
}
|
||||
} while (0);
|
||||
|
||||
mpit_unlock ();
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
@ -38,31 +38,9 @@ int MPI_T_cvar_get_info(int cvar_index, char *name, int *name_len, int *verbosit
|
||||
mpit_copy_string (desc, desc_len, var->mbv_description);
|
||||
|
||||
/* find the corresponding mpi type for an mca type */
|
||||
switch (var->mbv_type) {
|
||||
case MCA_BASE_VAR_TYPE_INT:
|
||||
case MCA_BASE_VAR_TYPE_BOOL:
|
||||
*datatype = MPI_INT;
|
||||
rc = ompit_var_type_to_datatype (var->mbv_type, datatype);
|
||||
if (OMPI_SUCCESS != rc) {
|
||||
break;
|
||||
case MCA_BASE_VAR_TYPE_UNSIGNED_INT:
|
||||
*datatype = MPI_UNSIGNED;
|
||||
break;
|
||||
case MCA_BASE_VAR_TYPE_UNSIGNED_LONG_LONG:
|
||||
*datatype = MPI_UNSIGNED_LONG_LONG;
|
||||
break;
|
||||
case MCA_BASE_VAR_TYPE_SIZE_T:
|
||||
if (sizeof(size_t) == sizeof (unsigned long long)) {
|
||||
*datatype = MPI_UNSIGNED_LONG_LONG;
|
||||
} else {
|
||||
*datatype = MPI_UNSIGNED;
|
||||
}
|
||||
case MCA_BASE_VAR_TYPE_STRING:
|
||||
*datatype = MPI_CHAR;
|
||||
break;
|
||||
default:
|
||||
/* Internal error! Did the MCA variable system change? */
|
||||
assert (0);
|
||||
mpit_unlock ();
|
||||
return MPI_ERR_OTHER;
|
||||
}
|
||||
|
||||
if (NULL != enumtype) {
|
||||
|
@ -23,7 +23,7 @@ int MPI_T_cvar_get_num (int *num_cvar) {
|
||||
}
|
||||
|
||||
mpit_lock ();
|
||||
*num_cvar = mca_base_var_group_get_count();
|
||||
*num_cvar = mca_base_var_get_count();
|
||||
mpit_unlock ();
|
||||
|
||||
return MPI_SUCCESS;
|
||||
|
@ -41,6 +41,9 @@ int MPI_T_cvar_read (MPI_T_cvar_handle handle, void *buf)
|
||||
case MCA_BASE_VAR_TYPE_UNSIGNED_INT:
|
||||
((int *) buf)[0] = value->intval;
|
||||
break;
|
||||
case MCA_BASE_VAR_TYPE_UNSIGNED_LONG:
|
||||
((unsigned long *) buf)[0] = value->ulval;
|
||||
break;
|
||||
case MCA_BASE_VAR_TYPE_UNSIGNED_LONG_LONG:
|
||||
((unsigned long long *) buf)[0] = value->ullval;
|
||||
break;
|
||||
@ -50,6 +53,9 @@ int MPI_T_cvar_read (MPI_T_cvar_handle handle, void *buf)
|
||||
case MCA_BASE_VAR_TYPE_BOOL:
|
||||
((int *) buf)[0] = value->boolval;
|
||||
break;
|
||||
case MCA_BASE_VAR_TYPE_DOUBLE:
|
||||
((double *) buf)[0] = value->lfval;
|
||||
break;
|
||||
case MCA_BASE_VAR_TYPE_STRING:
|
||||
if (NULL == value->stringval) {
|
||||
((char *)buf)[0] = '\0';
|
||||
|
@ -15,7 +15,6 @@ static const char FUNC_NAME[] = "MPI_T_cvar_write";
|
||||
|
||||
int MPI_T_cvar_write (MPI_T_cvar_handle handle, const void *buf)
|
||||
{
|
||||
mca_base_var_storage_t value;
|
||||
int rc = MPI_SUCCESS;
|
||||
|
||||
if (!mpit_is_initialized ()) {
|
||||
@ -40,42 +39,11 @@ int MPI_T_cvar_write (MPI_T_cvar_handle handle, const void *buf)
|
||||
break;
|
||||
}
|
||||
|
||||
switch (handle->var->mbv_type) {
|
||||
case MCA_BASE_VAR_TYPE_STRING:
|
||||
value.stringval = (char *) buf;
|
||||
|
||||
break;
|
||||
case MCA_BASE_VAR_TYPE_INT:
|
||||
case MCA_BASE_VAR_TYPE_UNSIGNED_INT:
|
||||
value.intval = ((int *) buf)[0];
|
||||
|
||||
break;
|
||||
case MCA_BASE_VAR_TYPE_BOOL:
|
||||
/* we expose boolean values as integers */
|
||||
value.boolval = !!(((int *) buf)[0]);
|
||||
break;
|
||||
case MCA_BASE_VAR_TYPE_UNSIGNED_LONG_LONG:
|
||||
value.ullval = ((unsigned long long *) buf)[0];
|
||||
break;
|
||||
case MCA_BASE_VAR_TYPE_SIZE_T:
|
||||
if (sizeof(size_t) == sizeof(unsigned long long)) {
|
||||
value.ullval = ((unsigned long long *) buf)[0];
|
||||
} else {
|
||||
value.intval = ((int *) buf)[0];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
rc = MPI_T_ERR_CVAR_SET_NEVER;
|
||||
break;
|
||||
}
|
||||
} while (0);
|
||||
|
||||
if (MPI_SUCCESS == rc) {
|
||||
rc = mca_base_var_set_value(handle->var->mbv_index, &value, sizeof(value), MCA_BASE_VAR_SOURCE_SET, NULL);
|
||||
rc = mca_base_var_set_value(handle->var->mbv_index, buf, sizeof(unsigned long long), MCA_BASE_VAR_SOURCE_SET, NULL);
|
||||
if (OPAL_SUCCESS != rc) {
|
||||
rc = MPI_T_ERR_CVAR_SET_NOT_NOW;
|
||||
}
|
||||
}
|
||||
} while (0);
|
||||
|
||||
mpit_unlock ();
|
||||
|
||||
|
@ -15,7 +15,7 @@ static const char FUNC_NAME[] = "MPI_T_enum_get_info";
|
||||
|
||||
int MPI_T_enum_get_info(MPI_T_enum enumtype, int *num, char *name, int *name_len)
|
||||
{
|
||||
int rc;
|
||||
int rc = MPI_SUCCESS;
|
||||
|
||||
if (!mpit_is_initialized ()) {
|
||||
return MPI_T_ERR_NOT_INITIALIZED;
|
||||
|
@ -39,6 +39,59 @@ void mpit_unlock (void)
|
||||
}
|
||||
}
|
||||
|
||||
int ompit_var_type_to_datatype (mca_base_var_type_t type, MPI_Datatype *datatype)
|
||||
{
|
||||
switch (type) {
|
||||
case MCA_BASE_VAR_TYPE_INT:
|
||||
*datatype = MPI_INT;
|
||||
break;
|
||||
case MCA_BASE_VAR_TYPE_UNSIGNED_INT:
|
||||
*datatype = MPI_UNSIGNED;
|
||||
break;
|
||||
case MCA_BASE_VAR_TYPE_UNSIGNED_LONG:
|
||||
*datatype = MPI_UNSIGNED_LONG;
|
||||
break;
|
||||
case MCA_BASE_VAR_TYPE_UNSIGNED_LONG_LONG:
|
||||
*datatype = MPI_UNSIGNED_LONG_LONG;
|
||||
break;
|
||||
case MCA_BASE_VAR_TYPE_SIZE_T:
|
||||
if (sizeof (size_t) == sizeof (unsigned)) {
|
||||
*datatype = MPI_UNSIGNED;
|
||||
} else if (sizeof (size_t) == sizeof (unsigned long)) {
|
||||
*datatype = MPI_UNSIGNED_LONG;
|
||||
} else if (sizeof (size_t) == sizeof (unsigned long long)) {
|
||||
*datatype = MPI_UNSIGNED_LONG_LONG;
|
||||
} else {
|
||||
/* not supported -- fixme */
|
||||
assert (0);
|
||||
}
|
||||
|
||||
break;
|
||||
case MCA_BASE_VAR_TYPE_STRING:
|
||||
*datatype = MPI_CHAR;
|
||||
break;
|
||||
case MCA_BASE_VAR_TYPE_BOOL:
|
||||
if (sizeof (bool) == sizeof (char)) {
|
||||
*datatype = MPI_CHAR;
|
||||
} else if (sizeof (bool) == sizeof (int)) {
|
||||
*datatype = MPI_INT;
|
||||
} else {
|
||||
/* not supported -- fixme */
|
||||
assert (0);
|
||||
}
|
||||
break;
|
||||
case MCA_BASE_VAR_TYPE_DOUBLE:
|
||||
*datatype = MPI_DOUBLE;
|
||||
break;
|
||||
default:
|
||||
/* not supported -- fixme */
|
||||
assert (0);
|
||||
break;
|
||||
}
|
||||
|
||||
return OMPI_SUCCESS;
|
||||
}
|
||||
|
||||
int MPI_T_init_thread (int required, int *provided)
|
||||
{
|
||||
static volatile int32_t first_init = 1;
|
||||
@ -50,8 +103,7 @@ int MPI_T_init_thread (int required, int *provided)
|
||||
}
|
||||
|
||||
while (!initted) {
|
||||
sched_yield ();
|
||||
usleep (1000);
|
||||
usleep (10);
|
||||
}
|
||||
|
||||
mpit_lock ();
|
||||
@ -68,11 +120,15 @@ int MPI_T_init_thread (int required, int *provided)
|
||||
break;
|
||||
}
|
||||
|
||||
/* register all parameters */
|
||||
rc = ompi_info_register_framework_params (NULL);
|
||||
if (OMPI_SUCCESS != rc) {
|
||||
rc = MPI_ERR_OTHER;
|
||||
break;
|
||||
}
|
||||
|
||||
/* determine the thread level. TODO -- this might
|
||||
be wrong */
|
||||
ompi_mpi_thread_level (required, provided);
|
||||
} while (0);
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2011-2012 Los Alamos National Security, LLC. All rights
|
||||
* Copyright (c) 2011-2013 Los Alamos National Security, LLC. All rights
|
||||
* reserved.
|
||||
* Copyright (c) 2011 UT-Battelle, LLC. All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
@ -15,39 +15,29 @@
|
||||
|
||||
#include "ompi/include/ompi_config.h"
|
||||
#include "opal/mca/base/mca_base_var.h"
|
||||
#include "opal/mca/base/mca_base_pvar.h"
|
||||
#include "ompi/runtime/params.h"
|
||||
#include "ompi/communicator/communicator.h"
|
||||
#include "ompi/constants.h"
|
||||
#include "ompi/datatype/ompi_datatype.h"
|
||||
|
||||
#include "mpi.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#define MPI_T_ENUM_NULL NULL
|
||||
|
||||
typedef struct ompi_mpit_cvar_handle_t {
|
||||
const mca_base_var_t *var;
|
||||
/* XXX -- TODO -- allow binding objects */
|
||||
void *bound_object;
|
||||
} ompi_mpit_cvar_handle_t;
|
||||
|
||||
typedef struct ompi_mpi_pvar_handle_t {
|
||||
int dummy;
|
||||
} ompi_mpi_pvar_handle_t;
|
||||
|
||||
typedef struct ompi_mpi_pvar_session_t {
|
||||
int dummy;
|
||||
} ompi_mpi_pvar_session_t;
|
||||
|
||||
typedef struct ompi_mpit_enum_t {
|
||||
mca_base_var_enum_t *enumerator;
|
||||
} ompi_mpit_enum_t;
|
||||
|
||||
void mpit_lock (void);
|
||||
void mpit_unlock (void);
|
||||
|
||||
extern volatile uint32_t mpit_init_count;
|
||||
|
||||
int ompit_var_type_to_datatype (mca_base_var_type_t type, MPI_Datatype *datatype);
|
||||
|
||||
static inline int mpit_is_initialized (void)
|
||||
{
|
||||
return !!mpit_init_count;
|
||||
|
@ -9,7 +9,7 @@
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
#include "ompi/mpit/mpit-internal.h"
|
||||
#include "mpit-internal.h"
|
||||
|
||||
static const char FUNC_NAME[] = "MPI_T_pvar_get_info";
|
||||
|
||||
@ -18,10 +18,69 @@ int MPI_T_pvar_get_info(int pvar_index, char *name, int *name_len,
|
||||
MPI_T_enum *enumtype, char *desc, int *desc_len, int *bind,
|
||||
int *readonly, int *continuous, int *atomic)
|
||||
{
|
||||
const mca_base_pvar_t *pvar;
|
||||
int ret;
|
||||
|
||||
if (!mpit_is_initialized ()) {
|
||||
return MPI_T_ERR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
/* XXX -- TODO -- Implement me */
|
||||
return MPI_T_ERR_INVALID_INDEX;
|
||||
mpit_lock ();
|
||||
|
||||
do {
|
||||
/* Find the performance variable. mca_base_pvar_get() handles the
|
||||
bounds checking. */
|
||||
ret = mca_base_pvar_get (pvar_index, &pvar);
|
||||
if (OMPI_SUCCESS != ret) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check the variable binding is something sane */
|
||||
if (pvar->bind > MPI_T_BIND_MPI_INFO || pvar->bind < MPI_T_BIND_NO_OBJECT) {
|
||||
/* This variable specified an invalid binding (not an MPI object). */
|
||||
ret = MPI_T_ERR_INVALID_INDEX;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Copy name an description */
|
||||
mpit_copy_string (name, name_len, pvar->name);
|
||||
mpit_copy_string (desc, desc_len, pvar->description);
|
||||
|
||||
if (verbosity) {
|
||||
*verbosity = pvar->verbosity;
|
||||
}
|
||||
|
||||
if (var_class) {
|
||||
*var_class = pvar->var_class;
|
||||
}
|
||||
|
||||
ret = ompit_var_type_to_datatype (pvar->type, datatype);
|
||||
if (OMPI_SUCCESS != ret) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (NULL != enumtype) {
|
||||
*enumtype = pvar->enumerator ? (MPI_T_enum) pvar->enumerator : MPI_T_ENUM_NULL;
|
||||
}
|
||||
|
||||
if (NULL != bind) {
|
||||
*bind = pvar->bind;
|
||||
}
|
||||
|
||||
if (NULL != readonly) {
|
||||
*readonly = mca_base_pvar_is_readonly (pvar);
|
||||
}
|
||||
|
||||
if (NULL != continuous) {
|
||||
*continuous = mca_base_pvar_is_continuous (pvar);
|
||||
}
|
||||
|
||||
if (NULL != atomic) {
|
||||
*atomic = mca_base_pvar_is_atomic (pvar);
|
||||
}
|
||||
} while (0);
|
||||
|
||||
mpit_unlock ();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -9,7 +9,7 @@
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
#include "ompi/mpit/mpit-internal.h"
|
||||
#include "mpit-internal.h"
|
||||
|
||||
static const char FUNC_NAME[] = "MPI_T_pvar_get_num";
|
||||
|
||||
@ -23,9 +23,6 @@ int MPI_T_pvar_get_num(int *num_pvar)
|
||||
return MPI_ERR_ARG;
|
||||
}
|
||||
|
||||
/* XXX -- TODO -- Add pvars */
|
||||
*num_pvar = 0;
|
||||
|
||||
return MPI_SUCCESS;
|
||||
return mca_base_pvar_get_count (num_pvar);
|
||||
}
|
||||
|
||||
|
@ -9,17 +9,49 @@
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
#include "ompi/mpit/mpit-internal.h"
|
||||
#include "mpit-internal.h"
|
||||
|
||||
static const char FUNC_NAME[] = "MPI_T_pvar_handle_alloc";
|
||||
|
||||
int MPI_T_pvar_handle_alloc(MPI_T_pvar_session session, int pvar_index,
|
||||
void *obj_handle, MPI_T_pvar_handle *handle, int *count)
|
||||
{
|
||||
const mca_base_pvar_t *pvar;
|
||||
int ret;
|
||||
|
||||
if (!mpit_is_initialized ()) {
|
||||
return MPI_T_ERR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
/* XXX -- TODO -- Implement me */
|
||||
return MPI_T_ERR_INVALID_INDEX;
|
||||
mpit_lock ();
|
||||
|
||||
do {
|
||||
/* Find the performance variable. mca_base_pvar_get() handles the
|
||||
bounds checking. */
|
||||
ret = mca_base_pvar_get (pvar_index, &pvar);
|
||||
if (OMPI_SUCCESS != ret) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check the variable binding is something sane */
|
||||
if (pvar->bind > MPI_T_BIND_MPI_INFO || pvar->bind < MPI_T_BIND_NO_OBJECT) {
|
||||
/* This variable specified an invalid binding (not an MPI object). */
|
||||
ret = MPI_T_ERR_INVALID_INDEX;
|
||||
break;
|
||||
}
|
||||
|
||||
ret = mca_base_pvar_handle_alloc (session, pvar_index, obj_handle,
|
||||
handle, count);
|
||||
if (OPAL_ERR_OUT_OF_RESOURCE == ret) {
|
||||
ret = MPI_T_ERR_MEMORY;
|
||||
} else if (OPAL_ERR_VALUE_OUT_OF_BOUNDS == ret) {
|
||||
ret = MPI_T_ERR_INVALID_HANDLE;
|
||||
} else if (OPAL_SUCCESS != ret) {
|
||||
ret = MPI_ERR_UNKNOWN;
|
||||
}
|
||||
} while (0);
|
||||
|
||||
mpit_unlock ();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -15,10 +15,33 @@ static const char FUNC_NAME[] = "MPI_T_pvar_handle_free";
|
||||
|
||||
int MPI_T_pvar_handle_free(MPI_T_pvar_session session, MPI_T_pvar_handle *handle)
|
||||
{
|
||||
int ret = MPI_SUCCESS;
|
||||
|
||||
if (!mpit_is_initialized ()) {
|
||||
return MPI_T_ERR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
/* XXX -- TODO -- Implement me */
|
||||
return MPI_T_ERR_INVALID_INDEX;
|
||||
mpit_lock ();
|
||||
|
||||
do {
|
||||
/* Check that this is a valid handle */
|
||||
if (MPI_T_PVAR_HANDLE_NULL == *handle ||
|
||||
MPI_T_PVAR_ALL_HANDLES == *handle) {
|
||||
/* As of MPI 3.0 MPI_T_PVAR_ALL_HANDLES is not a valid handle for
|
||||
MPI_T_pvar_handle_free */
|
||||
ret = MPI_T_ERR_INVALID_HANDLE;
|
||||
break;
|
||||
}
|
||||
|
||||
ret = mca_base_pvar_handle_free (*handle);
|
||||
if (OPAL_SUCCESS != ret) {
|
||||
ret = MPI_ERR_UNKNOWN;
|
||||
}
|
||||
|
||||
*handle = MPI_T_PVAR_HANDLE_NULL;
|
||||
} while (0);
|
||||
|
||||
mpit_unlock ();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -16,10 +16,17 @@ static const char FUNC_NAME[] = "MPI_T_pvar_read";
|
||||
int MPI_T_pvar_read(MPI_T_pvar_session session, MPI_T_pvar_handle handle,
|
||||
void* buf)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!mpit_is_initialized ()) {
|
||||
return MPI_T_ERR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
/* XXX -- TODO -- Implement me */
|
||||
return MPI_T_ERR_INVALID_HANDLE;
|
||||
mpit_lock ();
|
||||
|
||||
ret = mca_base_pvar_handle_read_value (handle, buf);
|
||||
|
||||
mpit_unlock ();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -15,10 +15,28 @@ static const char FUNC_NAME[] = "MPI_T_pvar_reset";
|
||||
|
||||
int MPI_T_pvar_reset(MPI_T_pvar_session session, MPI_T_pvar_handle handle)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!mpit_is_initialized ()) {
|
||||
return MPI_T_ERR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
/* XXX -- TODO -- Implement me */
|
||||
return MPI_T_ERR_INVALID_HANDLE;
|
||||
mpit_lock ();
|
||||
|
||||
if (MPI_T_PVAR_ALL_HANDLES == handle) {
|
||||
OPAL_LIST_FOREACH(handle, &session->handles, mca_base_pvar_handle_t) {
|
||||
/* Per MPI 3.0: ignore read-only variables when resetting all
|
||||
handles. */
|
||||
if (!mca_base_pvar_is_readonly (handle->pvar) &&
|
||||
MPI_SUCCESS != mca_base_pvar_handle_reset (handle)) {
|
||||
ret = MPI_T_ERR_PVAR_NO_WRITE;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ret = mca_base_pvar_handle_reset (handle);
|
||||
}
|
||||
|
||||
mpit_unlock ();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -15,10 +15,23 @@ static const char FUNC_NAME[] = "MPI_T_pvar_session_create";
|
||||
|
||||
int MPI_T_pvar_session_create(MPI_T_pvar_session *session)
|
||||
{
|
||||
int ret = MPI_SUCCESS;
|
||||
|
||||
if (!mpit_is_initialized ()) {
|
||||
return MPI_T_ERR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
/* XXX -- TODO -- Implement me */
|
||||
return MPI_ERR_OTHER;
|
||||
mpit_lock ();
|
||||
|
||||
do {
|
||||
*session = OBJ_NEW(mca_base_pvar_session_t);
|
||||
if (NULL == *session) {
|
||||
ret = MPI_ERR_NO_MEM;
|
||||
break;
|
||||
}
|
||||
} while (0);
|
||||
|
||||
mpit_unlock ();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -19,6 +19,10 @@ int MPI_T_pvar_session_free(MPI_T_pvar_session *session)
|
||||
return MPI_T_ERR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
/* XXX -- TODO -- Implement me */
|
||||
return MPI_ERR_OTHER;
|
||||
if (NULL != *session) {
|
||||
OBJ_RELEASE(*session);
|
||||
*session = NULL;
|
||||
}
|
||||
|
||||
return MPI_SUCCESS;
|
||||
}
|
||||
|
@ -13,12 +13,39 @@
|
||||
|
||||
static const char FUNC_NAME[] = "MPI_T_pvar_start";
|
||||
|
||||
static int pvar_handle_start (mca_base_pvar_handle_t *handle)
|
||||
{
|
||||
if (OPAL_SUCCESS != mca_base_pvar_handle_start (handle)) {
|
||||
return MPI_T_ERR_PVAR_NO_STARTSTOP;
|
||||
}
|
||||
|
||||
return MPI_SUCCESS;
|
||||
}
|
||||
|
||||
int MPI_T_pvar_start(MPI_T_pvar_session session, MPI_T_pvar_handle handle)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!mpit_is_initialized ()) {
|
||||
return MPI_T_ERR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
/* XXX -- TODO -- Implement me */
|
||||
return MPI_T_ERR_INVALID_HANDLE;
|
||||
mpit_lock ();
|
||||
|
||||
if (MPI_T_PVAR_ALL_HANDLES == handle) {
|
||||
OPAL_LIST_FOREACH(handle, &session->handles, mca_base_pvar_handle_t) {
|
||||
/* Per MPI 3.0: ignore continuous and started variables when starting
|
||||
all variable handles. */
|
||||
if (!mca_base_pvar_handle_is_running (handle) &&
|
||||
OMPI_SUCCESS != pvar_handle_start (handle)) {
|
||||
ret = MPI_T_ERR_PVAR_NO_STARTSTOP;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ret = pvar_handle_start (handle);
|
||||
}
|
||||
|
||||
mpit_unlock ();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -13,12 +13,41 @@
|
||||
|
||||
static const char FUNC_NAME[] = "MPI_T_pvar_stop";
|
||||
|
||||
static int pvar_handle_stop (mca_base_pvar_handle_t *handle)
|
||||
{
|
||||
if (OPAL_SUCCESS != mca_base_pvar_handle_stop (handle)) {
|
||||
return MPI_T_ERR_PVAR_NO_STARTSTOP;
|
||||
}
|
||||
|
||||
return MPI_SUCCESS;
|
||||
}
|
||||
|
||||
int MPI_T_pvar_stop(MPI_T_pvar_session session, MPI_T_pvar_handle handle)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!mpit_is_initialized ()) {
|
||||
return MPI_T_ERR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
/* XXX -- TODO -- Implement me */
|
||||
return MPI_T_ERR_INVALID_HANDLE;
|
||||
mpit_lock ();
|
||||
|
||||
if (MPI_T_PVAR_ALL_HANDLES == handle) {
|
||||
OPAL_LIST_FOREACH(handle, &session->handles, mca_base_pvar_handle_t) {
|
||||
/* Per MPI 3.0: ignore continuous and stopped variables when stopping
|
||||
all variable handles. */
|
||||
if (mca_base_pvar_handle_is_running (handle) && !mca_base_pvar_is_continuous (handle->pvar) &&
|
||||
MPI_SUCCESS != pvar_handle_stop (handle)) {
|
||||
/* If we failed to stop any variable we need to return
|
||||
an error. */
|
||||
ret = MPI_T_ERR_PVAR_NO_STARTSTOP;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ret = pvar_handle_stop (handle);
|
||||
}
|
||||
|
||||
mpit_unlock ();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -16,10 +16,17 @@ static const char FUNC_NAME[] = "MPI_T_pvar_write";
|
||||
int MPI_T_pvar_write(MPI_T_pvar_session session, MPI_T_pvar_handle handle,
|
||||
const void* buf)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!mpit_is_initialized ()) {
|
||||
return MPI_T_ERR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
/* XXX -- TODO -- Implement me */
|
||||
return MPI_T_ERR_INVALID_HANDLE;
|
||||
mpit_lock ();
|
||||
|
||||
ret = mca_base_pvar_handle_write_value (handle, buf);
|
||||
|
||||
mpit_unlock ();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -33,7 +33,9 @@ headers = \
|
||||
base.h \
|
||||
mca_base_component_repository.h \
|
||||
mca_base_var.h \
|
||||
mca_base_pvar.h \
|
||||
mca_base_var_enum.h \
|
||||
mca_base_var_group.h \
|
||||
mca_base_vari.h \
|
||||
mca_base_framework.h
|
||||
|
||||
@ -52,7 +54,9 @@ libmca_base_la_SOURCES = \
|
||||
mca_base_list.c \
|
||||
mca_base_open.c \
|
||||
mca_base_var.c \
|
||||
mca_base_pvar.c \
|
||||
mca_base_var_enum.c \
|
||||
mca_base_var_group.c \
|
||||
mca_base_parse_paramfile.c \
|
||||
mca_base_components_register.c \
|
||||
mca_base_framework.c
|
||||
|
@ -76,6 +76,15 @@ INT). This a developer error; your job may abort.
|
||||
|
||||
MCA variable name: %s
|
||||
#
|
||||
[var-name-conflict]
|
||||
A name collision was detected on an MCA variable name. This can happen
|
||||
if two components try to register the same variable with slightly
|
||||
different name components. The conflicting variables are listed below:
|
||||
|
||||
MCA variable name: %s
|
||||
New name: %s %s %s
|
||||
Existing name: %s %s %s
|
||||
#
|
||||
[overridden-param-set]
|
||||
WARNING: A user-supplied value attempted to set a variable that is set
|
||||
in the override variable file (openmpi-mca-params-override.conf).
|
||||
|
944
opal/mca/base/mca_base_pvar.c
Обычный файл
944
opal/mca/base/mca_base_pvar.c
Обычный файл
@ -0,0 +1,944 @@
|
||||
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2013 Los Alamos National Security, LLC. All rights
|
||||
* reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
*
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
#include "opal/mca/base/mca_base_pvar.h"
|
||||
#include "opal/mca/base/mca_base_vari.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
|
||||
#include "opal/class/opal_pointer_array.h"
|
||||
#include "opal/class/opal_hash_table.h"
|
||||
|
||||
static opal_hash_table_t mca_base_pvar_index_hash;
|
||||
static opal_pointer_array_t registered_pvars;
|
||||
static bool mca_base_pvar_initialized = false;
|
||||
static int pvar_count = 0;
|
||||
|
||||
#define min(a,b) ((a) < (b) ? (a) : (b))
|
||||
#define max(a,b) ((a) > (b) ? (a) : (b))
|
||||
|
||||
static int mca_base_pvar_get_internal (int index, mca_base_pvar_t **pvar, bool invalidok);
|
||||
|
||||
/* string representations of class names */
|
||||
static const char *pvar_class_names[] = {
|
||||
"state",
|
||||
"level",
|
||||
"size",
|
||||
"percentage",
|
||||
"high watermark",
|
||||
"low watermark",
|
||||
"counter",
|
||||
"aggregate",
|
||||
"timer",
|
||||
"generic"
|
||||
};
|
||||
|
||||
int mca_base_pvar_init (void)
|
||||
{
|
||||
int ret = OPAL_SUCCESS;
|
||||
|
||||
if (!mca_base_pvar_initialized) {
|
||||
mca_base_pvar_initialized = true;
|
||||
|
||||
OBJ_CONSTRUCT(®istered_pvars, opal_pointer_array_t);
|
||||
opal_pointer_array_init(®istered_pvars, 128, 2048, 128);
|
||||
|
||||
OBJ_CONSTRUCT(&mca_base_pvar_index_hash, opal_hash_table_t);
|
||||
ret = opal_hash_table_init (&mca_base_pvar_index_hash, 1024);
|
||||
if (OPAL_SUCCESS != ret) {
|
||||
mca_base_pvar_initialized = false;
|
||||
OBJ_DESTRUCT(®istered_pvars);
|
||||
OBJ_DESTRUCT(&mca_base_pvar_index_hash);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int mca_base_pvar_find (const char *project, const char *framework, const char *component, const char *name)
|
||||
{
|
||||
char *full_name;
|
||||
int ret, index;
|
||||
|
||||
ret = mca_base_var_generate_full_name4 (NULL, framework, component, name, &full_name);
|
||||
if (OPAL_SUCCESS != ret) {
|
||||
return OPAL_ERROR;
|
||||
}
|
||||
|
||||
ret = mca_base_pvar_find_by_name (full_name, &index);
|
||||
free (full_name);
|
||||
|
||||
/* NTH: should we verify the name components match the returned variable? */
|
||||
|
||||
return (OPAL_SUCCESS != ret) ? ret : index;
|
||||
}
|
||||
|
||||
int mca_base_pvar_find_by_name (const char *full_name, int *index)
|
||||
{
|
||||
void *tmp;
|
||||
int rc;
|
||||
|
||||
rc = opal_hash_table_get_value_ptr (&mca_base_pvar_index_hash, full_name, strlen (full_name),
|
||||
&tmp);
|
||||
if (OPAL_SUCCESS != rc) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
*index = (int)(uintptr_t) tmp;
|
||||
|
||||
return OPAL_SUCCESS;
|
||||
}
|
||||
|
||||
int mca_base_pvar_finalize (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (mca_base_pvar_initialized) {
|
||||
mca_base_pvar_initialized = false;
|
||||
|
||||
for (i = 0 ; i < pvar_count ; ++i) {
|
||||
mca_base_pvar_t *pvar = opal_pointer_array_get_item (®istered_pvars, i);
|
||||
if (pvar) {
|
||||
OBJ_RELEASE(pvar);
|
||||
}
|
||||
}
|
||||
|
||||
OBJ_DESTRUCT(®istered_pvars);
|
||||
OBJ_DESTRUCT(&mca_base_pvar_index_hash);
|
||||
}
|
||||
|
||||
return OPAL_SUCCESS;
|
||||
}
|
||||
|
||||
int mca_base_pvar_get_count (int *count)
|
||||
{
|
||||
*count = pvar_count;
|
||||
return OPAL_SUCCESS;
|
||||
}
|
||||
|
||||
static int mca_base_pvar_default_get_value (const mca_base_pvar_t *pvar, void *value, void *obj_handle)
|
||||
{
|
||||
/* not used */
|
||||
(void) obj_handle;
|
||||
|
||||
memmove (value, pvar->ctx, var_type_sizes[pvar->type]);
|
||||
|
||||
return OPAL_SUCCESS;
|
||||
}
|
||||
|
||||
static int mca_base_pvar_default_set_value (mca_base_pvar_t *pvar, const void *value, void *obj_handle)
|
||||
{
|
||||
/* not used */
|
||||
(void) obj_handle;
|
||||
|
||||
memmove (pvar->ctx, value, var_type_sizes[pvar->type]);
|
||||
|
||||
return OPAL_SUCCESS;
|
||||
}
|
||||
|
||||
static int mca_base_pvar_notify_ignore (mca_base_pvar_t *pvar, mca_base_pvar_event_t event, void *obj_handle, int *count)
|
||||
{
|
||||
/* silence compiler warnings */
|
||||
(void) pvar;
|
||||
(void) obj_handle;
|
||||
|
||||
/* default is only one value */
|
||||
if (MCA_BASE_PVAR_HANDLE_BIND == event) {
|
||||
*count = 1;
|
||||
}
|
||||
|
||||
return OPAL_SUCCESS;
|
||||
}
|
||||
|
||||
int mca_base_pvar_register (const char *project, const char *framework, const char *component, const char *name,
|
||||
const char *description, mca_base_var_info_lvl_t verbosity,
|
||||
int var_class, mca_base_var_type_t type, mca_base_var_enum_t *enumerator,
|
||||
int bind, mca_base_pvar_flag_t flags, mca_base_get_value_fn_t get_value,
|
||||
mca_base_set_value_fn_t set_value, mca_base_notify_fn_t notify, void *ctx)
|
||||
{
|
||||
int ret, group_index;
|
||||
mca_base_pvar_t *pvar;
|
||||
|
||||
/* assert on usage errors */
|
||||
if (!get_value && !ctx) {
|
||||
assert (0);
|
||||
return OPAL_ERR_BAD_PARAM;
|
||||
}
|
||||
|
||||
/* ensure the caller did not set an invalid flag */
|
||||
assert (!(flags & 0x3f));
|
||||
|
||||
flags &= ~MCA_BASE_PVAR_FLAG_INVALID;
|
||||
|
||||
/* check that the datatype matches what is permitted for the variable class */
|
||||
switch (var_class) {
|
||||
case MCA_BASE_PVAR_CLASS_STATE:
|
||||
/* states MUST be integers */
|
||||
if (MCA_BASE_VAR_TYPE_INT != type) {
|
||||
assert (0);
|
||||
return OPAL_ERR_BAD_PARAM;
|
||||
}
|
||||
break;
|
||||
case MCA_BASE_PVAR_CLASS_COUNTER:
|
||||
/* counters can have the any of types in the fall-through except double */
|
||||
if (MCA_BASE_VAR_TYPE_DOUBLE == type) {
|
||||
assert (0);
|
||||
return OPAL_ERR_BAD_PARAM;
|
||||
}
|
||||
/* fall-through */
|
||||
case MCA_BASE_PVAR_CLASS_LEVEL:
|
||||
case MCA_BASE_PVAR_CLASS_SIZE:
|
||||
case MCA_BASE_PVAR_CLASS_HIGHWATERMARK:
|
||||
case MCA_BASE_PVAR_CLASS_LOWWATERMARK:
|
||||
case MCA_BASE_PVAR_CLASS_AGGREGATE:
|
||||
case MCA_BASE_PVAR_CLASS_TIMER:
|
||||
if (MCA_BASE_VAR_TYPE_UNSIGNED_INT != type &&
|
||||
MCA_BASE_VAR_TYPE_UNSIGNED_LONG != type &&
|
||||
MCA_BASE_VAR_TYPE_UNSIGNED_LONG_LONG != type &&
|
||||
MCA_BASE_VAR_TYPE_DOUBLE != type) {
|
||||
assert (0);
|
||||
return OPAL_ERR_BAD_PARAM;
|
||||
}
|
||||
break;
|
||||
case MCA_BASE_PVAR_CLASS_PERCENTAGE:
|
||||
/* percentages must be doubles */
|
||||
if (MCA_BASE_VAR_TYPE_DOUBLE != type) {
|
||||
assert (0);
|
||||
return OPAL_ERR_BAD_PARAM;
|
||||
}
|
||||
break;
|
||||
case MCA_BASE_PVAR_CLASS_GENERIC:
|
||||
/* there are no additional restrictions on the type of generic
|
||||
variables */
|
||||
break;
|
||||
default:
|
||||
assert (0);
|
||||
break;
|
||||
}
|
||||
|
||||
/* update this assert if more MPIT verbosity levels are added */
|
||||
assert (verbosity >= OPAL_INFO_LVL_1 && verbosity <= OPAL_INFO_LVL_9);
|
||||
|
||||
/* check if this variable is already registered */
|
||||
ret = mca_base_pvar_find (project, framework, component, name);
|
||||
if (OPAL_SUCCESS <= ret) {
|
||||
ret = mca_base_pvar_get_internal (ret, &pvar, true);
|
||||
if (OPAL_SUCCESS != ret) {
|
||||
/* inconsistent internal state */
|
||||
assert (0);
|
||||
return OPAL_ERROR;
|
||||
}
|
||||
|
||||
if (pvar->enumerator) {
|
||||
OBJ_RELEASE(pvar->enumerator);
|
||||
}
|
||||
} else {
|
||||
/* find/register an MCA parameter group for this performance variable */
|
||||
group_index = mca_base_var_group_register (project, framework, component, NULL);
|
||||
if (-1 > group_index) {
|
||||
return group_index;
|
||||
}
|
||||
|
||||
/* create a new parameter entry */
|
||||
pvar = OBJ_NEW(mca_base_pvar_t);
|
||||
if (NULL == pvar) {
|
||||
return OPAL_ERR_OUT_OF_RESOURCE;
|
||||
}
|
||||
|
||||
do {
|
||||
/* generate the variable's full name */
|
||||
mca_base_var_generate_full_name4 (NULL, framework, component, name, &pvar->name);
|
||||
if (NULL == pvar->name) {
|
||||
ret = OPAL_ERR_OUT_OF_RESOURCE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (NULL != description) {
|
||||
pvar->description = strdup(description);
|
||||
if (NULL == pvar->description) {
|
||||
ret = OPAL_ERR_OUT_OF_RESOURCE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* add this performance variable to the MCA variable group */
|
||||
ret = mca_base_var_group_add_pvar (group_index, pvar_count);
|
||||
if (0 > ret) {
|
||||
break;
|
||||
}
|
||||
|
||||
ret = opal_pointer_array_add (®istered_pvars, pvar);
|
||||
if (0 > ret) {
|
||||
break;
|
||||
}
|
||||
|
||||
opal_hash_table_set_value_ptr (&mca_base_pvar_index_hash, pvar->name, strlen (pvar->name),
|
||||
(void *)(uintptr_t) pvar->pvar_index);
|
||||
|
||||
pvar_count++;
|
||||
ret = OPAL_SUCCESS;
|
||||
} while (0);
|
||||
|
||||
if (OPAL_SUCCESS != ret) {
|
||||
OBJ_RELEASE(pvar);
|
||||
return ret;
|
||||
}
|
||||
|
||||
pvar->group_index = group_index;
|
||||
}
|
||||
|
||||
pvar->verbosity = verbosity;
|
||||
pvar->var_class = var_class;
|
||||
pvar->type = type;
|
||||
pvar->enumerator = enumerator;
|
||||
if (enumerator) {
|
||||
OBJ_RETAIN(enumerator);
|
||||
}
|
||||
|
||||
pvar->bind = bind;
|
||||
pvar->flags = flags;
|
||||
|
||||
pvar->get_value = get_value ? get_value : mca_base_pvar_default_get_value;
|
||||
pvar->notify = notify ? notify : mca_base_pvar_notify_ignore;
|
||||
|
||||
if (!(flags & MCA_BASE_PVAR_FLAG_READONLY)) {
|
||||
pvar->set_value = set_value ? set_value : mca_base_pvar_default_set_value;
|
||||
}
|
||||
|
||||
pvar->ctx = ctx;
|
||||
pvar->pvar_index = pvar_count;
|
||||
|
||||
return pvar->pvar_index;
|
||||
}
|
||||
|
||||
int mca_base_component_pvar_register (const mca_base_component_t *component, const char *name,
|
||||
const char *description, mca_base_var_info_lvl_t verbosity,
|
||||
int var_class, mca_base_var_type_t type, mca_base_var_enum_t *enumerator,
|
||||
int bind, mca_base_pvar_flag_t flags, mca_base_get_value_fn_t get_value,
|
||||
mca_base_set_value_fn_t set_value, mca_base_notify_fn_t notify, void *ctx)
|
||||
{
|
||||
/* XXX -- component_update -- We will stash the project name in the component */
|
||||
/* invalidate this variable if the component's group is deregistered */
|
||||
return mca_base_pvar_register(NULL, component->mca_type_name, component->mca_component_name,
|
||||
name, description, verbosity, var_class, type, enumerator, bind,
|
||||
flags | MCA_BASE_PVAR_FLAG_IWG, get_value, set_value, notify, ctx);
|
||||
}
|
||||
|
||||
static int mca_base_pvar_get_internal (int index, mca_base_pvar_t **pvar, bool invalidok)
|
||||
{
|
||||
if (index >= pvar_count) {
|
||||
return OPAL_ERR_VALUE_OUT_OF_BOUNDS;
|
||||
}
|
||||
|
||||
*pvar = opal_pointer_array_get_item (®istered_pvars, index);
|
||||
|
||||
/* variables should never be removed per MPI 3.0 § 14.3.7 */
|
||||
assert (*pvar);
|
||||
|
||||
if (((*pvar)->flags & MCA_BASE_PVAR_FLAG_INVALID) && !invalidok) {
|
||||
*pvar = NULL;
|
||||
return OPAL_ERR_VALUE_OUT_OF_BOUNDS;
|
||||
}
|
||||
|
||||
return OPAL_SUCCESS;
|
||||
}
|
||||
|
||||
int mca_base_pvar_get (int index, const mca_base_pvar_t **pvar)
|
||||
{
|
||||
return mca_base_pvar_get_internal (index, (mca_base_pvar_t **) pvar, false);
|
||||
}
|
||||
|
||||
int mca_base_pvar_mark_invalid (int index)
|
||||
{
|
||||
mca_base_pvar_t *pvar;
|
||||
int ret;
|
||||
|
||||
ret = mca_base_pvar_get_internal (index, &pvar, false);
|
||||
if (OPAL_SUCCESS != ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
pvar->flags |= MCA_BASE_PVAR_FLAG_INVALID;
|
||||
|
||||
return OPAL_SUCCESS;
|
||||
}
|
||||
|
||||
int mca_base_pvar_notify (mca_base_pvar_handle_t *handle, mca_base_pvar_event_t event, int *count)
|
||||
{
|
||||
return handle->pvar->notify (handle->pvar, event, handle->obj_handle, count);
|
||||
}
|
||||
|
||||
int mca_base_pvar_update_all_handles (int index, const void *obj)
|
||||
{
|
||||
mca_base_pvar_handle_t *handle, *next;
|
||||
mca_base_pvar_t *pvar;
|
||||
int ret;
|
||||
|
||||
ret = mca_base_pvar_get_internal (index, &pvar, false);
|
||||
if (OPAL_SUCCESS != ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (0 == opal_list_get_size (&pvar->bound_handles)) {
|
||||
/* nothing to do */
|
||||
return OPAL_SUCCESS;
|
||||
}
|
||||
|
||||
/* TODO -- probably need to add a handle/variable lock */
|
||||
OPAL_LIST_FOREACH_SAFE(handle, next, &pvar->bound_handles, mca_base_pvar_handle_t) {
|
||||
handle = (mca_base_pvar_handle_t *)((char *) handle - offsetof (mca_base_pvar_handle_t, list2));
|
||||
|
||||
if (handle->obj_handle != obj) {
|
||||
continue;
|
||||
}
|
||||
|
||||
(void) mca_base_pvar_handle_update (handle);
|
||||
}
|
||||
|
||||
return OPAL_SUCCESS;
|
||||
}
|
||||
|
||||
int mca_base_pvar_handle_alloc (mca_base_pvar_session_t *session, int index, void *obj_handle,
|
||||
mca_base_pvar_handle_t **handle, int *count)
|
||||
{
|
||||
mca_base_pvar_handle_t *pvar_handle = NULL;
|
||||
size_t datatype_size;
|
||||
mca_base_pvar_t *pvar;
|
||||
int ret;
|
||||
|
||||
do {
|
||||
/* find the requested performance variable */
|
||||
ret = mca_base_pvar_get_internal (index, &pvar, false);
|
||||
if (OPAL_SUCCESS != ret) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (0 == pvar->bind) {
|
||||
/* ignore binding object */
|
||||
obj_handle = NULL;
|
||||
} else if (0 != pvar->bind && NULL == obj_handle) {
|
||||
/* this is an application error. what is the correct error code? */
|
||||
ret = OPAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
/* allocate and initialize the handle */
|
||||
pvar_handle = OBJ_NEW(mca_base_pvar_handle_t);
|
||||
if (NULL == pvar_handle) {
|
||||
ret = OPAL_ERR_OUT_OF_RESOURCE;
|
||||
break;
|
||||
}
|
||||
|
||||
pvar_handle->obj_handle = obj_handle;
|
||||
pvar_handle->pvar = pvar;
|
||||
|
||||
*handle = pvar_handle;
|
||||
|
||||
/* notify the variable that a handle has been bound and determine
|
||||
how many values this handle has. NTH: finding the count should
|
||||
probably be pushed into a separate function. */
|
||||
ret = mca_base_pvar_notify (pvar_handle, MCA_BASE_PVAR_HANDLE_BIND, count);
|
||||
if (0 > ret) {
|
||||
ret = OPAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
pvar_handle->count = *count;
|
||||
|
||||
/* get the size of this datatype since read functions will expect an
|
||||
array of datatype not mca_base_pvar_value_t's. */
|
||||
datatype_size = var_type_sizes[pvar->type];
|
||||
if (0 == datatype_size) {
|
||||
ret = OPAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
if (mca_base_pvar_is_sum (pvar)) {
|
||||
/* for sums (counters, timers, etc) we need to keep track of
|
||||
what the last value of the underlying counter was. this allows
|
||||
us to push the computation of handle values from the event(s)
|
||||
(which could be in a critical path) to pvar read/stop/reset/etc */
|
||||
pvar_handle->last_value = calloc (*count, datatype_size);
|
||||
if (NULL == pvar_handle->last_value) {
|
||||
ret = OPAL_ERR_OUT_OF_RESOURCE;
|
||||
break;
|
||||
}
|
||||
|
||||
pvar_handle->tmp_value = calloc (*count, datatype_size);
|
||||
if (NULL == pvar_handle->tmp_value) {
|
||||
ret = OPAL_ERR_OUT_OF_RESOURCE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* get the current value of the performance variable if this is a
|
||||
continuous sum. if this variable needs to be started first the
|
||||
current value is not relevant. */
|
||||
if (mca_base_pvar_is_continuous (pvar)) {
|
||||
ret = pvar->get_value (pvar, pvar_handle->last_value, pvar_handle->obj_handle);
|
||||
if (OPAL_SUCCESS != ret) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!mca_base_pvar_is_continuous (pvar) || mca_base_pvar_is_sum (pvar)) {
|
||||
/* if a variable is not continuous we will need to keep track of its last value
|
||||
to support start->stop->read correctly. use calloc to initialize the current
|
||||
value to 0. */
|
||||
pvar_handle->current_value = calloc (*count, datatype_size);
|
||||
if (NULL == pvar_handle->current_value) {
|
||||
ret = OPAL_ERR_OUT_OF_RESOURCE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pvar_handle->session = session;
|
||||
|
||||
/* the handle is ready. add it to the appropriate lists */
|
||||
opal_list_append (&session->handles, &pvar_handle->super);
|
||||
opal_list_append (&pvar->bound_handles, &pvar_handle->list2);
|
||||
|
||||
if (mca_base_pvar_is_continuous (pvar)) {
|
||||
/* mark this variable as started */
|
||||
pvar_handle->started = true;
|
||||
}
|
||||
|
||||
ret = OPAL_SUCCESS;
|
||||
} while (0);
|
||||
|
||||
if (OPAL_SUCCESS != ret && pvar_handle) {
|
||||
OBJ_RELEASE(pvar_handle);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int mca_base_pvar_handle_free (mca_base_pvar_handle_t *handle)
|
||||
{
|
||||
if (handle->session) {
|
||||
opal_list_remove_item (&handle->session->handles, &handle->super);
|
||||
}
|
||||
|
||||
if (handle->pvar) {
|
||||
opal_list_remove_item (&handle->pvar->bound_handles, &handle->list2);
|
||||
}
|
||||
|
||||
OBJ_RELEASE(handle);
|
||||
|
||||
return OPAL_SUCCESS;
|
||||
}
|
||||
|
||||
int mca_base_pvar_handle_update (mca_base_pvar_handle_t *handle)
|
||||
{
|
||||
int i, ret;
|
||||
void *tmp;
|
||||
|
||||
if (!mca_base_pvar_handle_is_running (handle)) {
|
||||
return OPAL_SUCCESS;
|
||||
}
|
||||
|
||||
if (mca_base_pvar_is_sum (handle->pvar) || mca_base_pvar_is_watermark (handle->pvar)) {
|
||||
ret = handle->pvar->get_value (handle->pvar, handle->tmp_value, handle->obj_handle);
|
||||
if (OPAL_SUCCESS != ret) {
|
||||
return OPAL_ERROR;
|
||||
}
|
||||
|
||||
if (mca_base_pvar_is_sum (handle->pvar)) {
|
||||
for (i = 0 ; i < handle->count ; ++i) {
|
||||
/* the instance started at 0. need to subract the initial value off the
|
||||
result. */
|
||||
switch (handle->pvar->type) {
|
||||
case MCA_BASE_VAR_TYPE_UNSIGNED_INT:
|
||||
((unsigned *) handle->current_value)[i] += ((unsigned *) handle->tmp_value)[i] -
|
||||
((unsigned *) handle->last_value)[i];
|
||||
break;
|
||||
case MCA_BASE_VAR_TYPE_UNSIGNED_LONG:
|
||||
((unsigned long *) handle->current_value)[i] += ((unsigned long *) handle->tmp_value)[i] -
|
||||
((unsigned long *) handle->last_value)[i];
|
||||
break;
|
||||
case MCA_BASE_VAR_TYPE_UNSIGNED_LONG_LONG:
|
||||
((unsigned long long *) handle->current_value)[i] += ((unsigned long long *) handle->tmp_value)[i] -
|
||||
((unsigned long long *) handle->last_value)[i];
|
||||
break;
|
||||
case MCA_BASE_VAR_TYPE_DOUBLE:
|
||||
((double *) handle->current_value)[i] += ((double *) handle->tmp_value)[i] -
|
||||
((double *) handle->last_value)[i];
|
||||
break;
|
||||
default:
|
||||
/* shouldn't happen */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
tmp = handle->tmp_value;
|
||||
handle->tmp_value = handle->last_value;
|
||||
handle->last_value = tmp;
|
||||
} else {
|
||||
for (i = 0 ; i < handle->count ; ++i) {
|
||||
if (MCA_BASE_PVAR_CLASS_LOWWATERMARK == handle->pvar->var_class) {
|
||||
switch (handle->pvar->type) {
|
||||
case MCA_BASE_VAR_TYPE_UNSIGNED_INT:
|
||||
((unsigned *) handle->current_value)[i] = min(((unsigned *) handle->tmp_value)[i],
|
||||
((unsigned *) handle->current_value)[i]);
|
||||
break;
|
||||
case MCA_BASE_VAR_TYPE_UNSIGNED_LONG:
|
||||
((unsigned long *) handle->current_value)[i] = min(((unsigned long *) handle->tmp_value)[i],
|
||||
((unsigned long *) handle->current_value)[i]);
|
||||
break;
|
||||
case MCA_BASE_VAR_TYPE_UNSIGNED_LONG_LONG:
|
||||
((unsigned long long *) handle->current_value)[i] = min(((unsigned long long *) handle->tmp_value)[i],
|
||||
((unsigned long long *) handle->current_value)[i]);
|
||||
break;
|
||||
case MCA_BASE_VAR_TYPE_DOUBLE:
|
||||
((double *) handle->current_value)[i] = min(((double *) handle->tmp_value)[i],
|
||||
((double *) handle->current_value)[i]);
|
||||
break;
|
||||
default:
|
||||
/* shouldn't happen */
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (handle->pvar->type) {
|
||||
case MCA_BASE_VAR_TYPE_UNSIGNED_INT:
|
||||
((unsigned *) handle->current_value)[i] = max(((unsigned *) handle->tmp_value)[i],
|
||||
((unsigned *) handle->current_value)[i]);
|
||||
break;
|
||||
case MCA_BASE_VAR_TYPE_UNSIGNED_LONG:
|
||||
((unsigned long *) handle->current_value)[i] = max(((unsigned long *) handle->tmp_value)[i],
|
||||
((unsigned long *) handle->current_value)[i]);
|
||||
break;
|
||||
case MCA_BASE_VAR_TYPE_UNSIGNED_LONG_LONG:
|
||||
((unsigned long long *) handle->current_value)[i] = max(((unsigned long long *) handle->tmp_value)[i],
|
||||
((unsigned long long *) handle->current_value)[i]);
|
||||
break;
|
||||
case MCA_BASE_VAR_TYPE_DOUBLE:
|
||||
((double *) handle->current_value)[i] = max(((double *) handle->tmp_value)[i],
|
||||
((double *) handle->current_value)[i]);
|
||||
break;
|
||||
default:
|
||||
/* shouldn't happen */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (!mca_base_pvar_is_continuous (handle->pvar)) {
|
||||
/* cache the current value */
|
||||
ret = handle->pvar->get_value (handle->pvar, handle->current_value, handle->obj_handle);
|
||||
if (OPAL_SUCCESS != ret) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* XXX -- TODO -- For watermarks this function will have to be invoked for each handle whenever the underlying value is updated. */
|
||||
|
||||
return OPAL_SUCCESS;
|
||||
}
|
||||
|
||||
int mca_base_pvar_handle_read_value (mca_base_pvar_handle_t *handle, void *value)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* ensure this handle's value is up to date. */
|
||||
ret = mca_base_pvar_handle_update (handle);
|
||||
if (OPAL_SUCCESS != ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (mca_base_pvar_is_sum (handle->pvar) || mca_base_pvar_is_watermark (handle->pvar) ||
|
||||
!mca_base_pvar_handle_is_running (handle)) {
|
||||
/* read the value cached in the handle. */
|
||||
memmove (value, handle->current_value, handle->count * var_type_sizes[handle->pvar->type]);
|
||||
} else {
|
||||
/* read the value directly from the variable. */
|
||||
ret = handle->pvar->get_value (handle->pvar, value, handle->obj_handle);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int mca_base_pvar_handle_write_value (mca_base_pvar_handle_t *handle, const void *value)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (mca_base_pvar_is_readonly (handle->pvar)) {
|
||||
return OPAL_ERR_PERM;
|
||||
}
|
||||
|
||||
/* TODO -- actually write the variable. this will likely require a pvar lock */
|
||||
|
||||
ret = mca_base_pvar_handle_update (handle);
|
||||
if (OPAL_SUCCESS != ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
memmove (handle->current_value, value, handle->count * var_type_sizes[handle->pvar->type]);
|
||||
|
||||
return OPAL_SUCCESS;
|
||||
}
|
||||
|
||||
int mca_base_pvar_handle_start (mca_base_pvar_handle_t *handle)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Can't start a continuous or an already started variable */
|
||||
if ((handle->pvar->flags & MCA_BASE_PVAR_FLAG_CONTINUOUS) ||
|
||||
handle->started) {
|
||||
return OPAL_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
/* Notify the variable that a handle has started */
|
||||
ret = mca_base_pvar_notify (handle, MCA_BASE_PVAR_HANDLE_START, NULL);
|
||||
if (OPAL_SUCCESS != ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
handle->started = true;
|
||||
|
||||
if (mca_base_pvar_is_sum (handle->pvar)) {
|
||||
/* Keep track of the counter value from when this counter started. */
|
||||
ret = handle->pvar->get_value (handle->pvar, handle->last_value, handle->obj_handle);
|
||||
if (OPAL_SUCCESS != ret) {
|
||||
return ret;
|
||||
}
|
||||
} else if (mca_base_pvar_is_watermark (handle->pvar)) {
|
||||
/* Find the current watermark. is this correct in the case where a watermark is started, stopped,
|
||||
then restarted? Probably will need to add a check. */
|
||||
ret = handle->pvar->get_value (handle->pvar, handle->current_value, handle->obj_handle);
|
||||
if (OPAL_SUCCESS != ret) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return OPAL_SUCCESS;
|
||||
}
|
||||
|
||||
int mca_base_pvar_handle_stop (mca_base_pvar_handle_t *handle)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Can't stop a continuous or an already stopped variable */
|
||||
if (!mca_base_pvar_handle_is_running (handle) || mca_base_pvar_is_continuous (handle->pvar)) {
|
||||
return OPAL_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
ret = mca_base_pvar_handle_update (handle);
|
||||
if (OPAL_SUCCESS != ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Notify the variable that a handle has stopped */
|
||||
(void) mca_base_pvar_notify (handle, MCA_BASE_PVAR_HANDLE_STOP, NULL);
|
||||
|
||||
/* Handle is stopped */
|
||||
handle->started = false;
|
||||
|
||||
return OPAL_SUCCESS;
|
||||
}
|
||||
|
||||
int mca_base_pvar_handle_reset (mca_base_pvar_handle_t *handle)
|
||||
{
|
||||
int ret = OPAL_SUCCESS;
|
||||
|
||||
/* reset this handle to a state analagous to when it was created */
|
||||
if (mca_base_pvar_is_sum (handle->pvar)) {
|
||||
/* reset the running sum to 0 */
|
||||
memset (handle->current_value, 0, handle->count * var_type_sizes[handle->pvar->type]);
|
||||
|
||||
if (mca_base_pvar_handle_is_running (handle)) {
|
||||
ret = handle->pvar->get_value (handle->pvar, handle->last_value, handle->obj_handle);
|
||||
}
|
||||
} else if (mca_base_pvar_handle_is_running (handle) && mca_base_pvar_is_watermark (handle->pvar)) {
|
||||
/* watermarks should get set to the current value if runnning. */
|
||||
|
||||
ret = handle->pvar->get_value (handle->pvar, handle->current_value, handle->obj_handle);
|
||||
} else if (mca_base_pvar_is_readonly (handle->pvar)) {
|
||||
return OPAL_ERR_PERM;
|
||||
}
|
||||
/* NTH: TODO -- Actually write the value for variable of other types */
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int mca_base_pvar_dump(int index, char ***out, mca_base_var_dump_type_t output_type)
|
||||
{
|
||||
const char *framework, *component, *full_name;
|
||||
mca_base_var_group_t *group;
|
||||
int line = 0, line_count, i;
|
||||
const mca_base_pvar_t *pvar;
|
||||
int ret, enum_count;
|
||||
char *tmp;
|
||||
|
||||
ret = mca_base_pvar_get (index, &pvar);
|
||||
if (OPAL_SUCCESS != ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = mca_base_var_group_get_internal (pvar->group_index, &group, true);
|
||||
if (OPAL_SUCCESS != ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
framework = group->group_framework;
|
||||
component = group->group_component ? group->group_component : "base";
|
||||
full_name = pvar->name;
|
||||
|
||||
if (NULL != pvar->enumerator) {
|
||||
(void) pvar->enumerator->get_count(pvar->enumerator, &enum_count);
|
||||
}
|
||||
|
||||
if (MCA_BASE_VAR_DUMP_PARSABLE == output_type) {
|
||||
line_count = 5 + !!(pvar->description) + enum_count;
|
||||
|
||||
*out = (char **) calloc (line_count + 1, sizeof (char *));
|
||||
if (NULL == *out) {
|
||||
return OPAL_ERR_OUT_OF_RESOURCE;
|
||||
}
|
||||
|
||||
/* build the message*/
|
||||
asprintf(&tmp, "mca:%s:%s:pvar:%s:", framework, component,
|
||||
full_name);
|
||||
|
||||
asprintf(out[0] + line++, "%sclass:%s", tmp, pvar_class_names[pvar->var_class]);
|
||||
asprintf(out[0] + line++, "%sread-only:%s", tmp, mca_base_pvar_is_readonly(pvar) ? "true" : "false");
|
||||
asprintf(out[0] + line++, "%scontinuous:%s", tmp, mca_base_pvar_is_continuous(pvar) ? "true" : "false");
|
||||
asprintf(out[0] + line++, "%satomic:%s", tmp, mca_base_pvar_is_atomic(pvar) ? "true" : "false");
|
||||
|
||||
/* if it has a help message, output the help message */
|
||||
if (pvar->description) {
|
||||
asprintf(out[0] + line++, "%shelp:%s", tmp, pvar->description);
|
||||
}
|
||||
|
||||
if (NULL != pvar->enumerator) {
|
||||
for (i = 0 ; i < enum_count ; ++i) {
|
||||
const char *enum_string = NULL;
|
||||
int enum_value;
|
||||
|
||||
ret = pvar->enumerator->get_value(pvar->enumerator, i, &enum_value,
|
||||
&enum_string);
|
||||
if (OPAL_SUCCESS != ret) {
|
||||
continue;
|
||||
}
|
||||
|
||||
asprintf(out[0] + line++, "%senumerator:value:%d:%s", tmp, enum_value, enum_string);
|
||||
}
|
||||
}
|
||||
|
||||
asprintf(out[0] + line++, "%stype:%s", tmp, var_type_names[pvar->type]);
|
||||
} else {
|
||||
/* there will be at most three lines in the pretty print case */
|
||||
*out = (char **) calloc (3, sizeof (char *));
|
||||
if (NULL == *out) {
|
||||
return OPAL_ERR_OUT_OF_RESOURCE;
|
||||
}
|
||||
|
||||
asprintf (out[0] + line++, "performance \"%s\" (type: %s, class: %s)", full_name,
|
||||
var_type_names[pvar->type], pvar_class_names[pvar->var_class]);
|
||||
|
||||
if (pvar->description) {
|
||||
asprintf(out[0] + line++, "%s", pvar->description);
|
||||
}
|
||||
|
||||
if (NULL != pvar->enumerator) {
|
||||
char *values;
|
||||
|
||||
ret = pvar->enumerator->dump(pvar->enumerator, &values);
|
||||
if (OPAL_SUCCESS == ret) {
|
||||
asprintf (out[0] + line++, "Values: %s", values);
|
||||
free (values);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return OPAL_SUCCESS;
|
||||
}
|
||||
|
||||
/* mca_base_pvar_t class */
|
||||
static void mca_base_pvar_contructor (mca_base_pvar_t *pvar)
|
||||
{
|
||||
memset ((char *) pvar + sizeof (pvar->super), 0, sizeof (*pvar) - sizeof (pvar->super));
|
||||
OBJ_CONSTRUCT(&pvar->bound_handles, opal_list_t);
|
||||
}
|
||||
|
||||
static void mca_base_pvar_destructor (mca_base_pvar_t *pvar)
|
||||
{
|
||||
if (pvar->name) {
|
||||
free (pvar->name);
|
||||
}
|
||||
|
||||
if (pvar->description) {
|
||||
free (pvar->description);
|
||||
}
|
||||
|
||||
if (NULL != pvar->enumerator) {
|
||||
OBJ_RELEASE(pvar->enumerator);
|
||||
}
|
||||
|
||||
OBJ_DESTRUCT(&pvar->bound_handles);
|
||||
}
|
||||
|
||||
OBJ_CLASS_INSTANCE(mca_base_pvar_t, opal_object_t, mca_base_pvar_contructor, mca_base_pvar_destructor);
|
||||
|
||||
/* mca_base_pvar_session_t class */
|
||||
static void ompi_mpi_pvar_session_constructor (mca_base_pvar_session_t *session)
|
||||
{
|
||||
OBJ_CONSTRUCT(&session->handles, opal_list_t);
|
||||
}
|
||||
|
||||
static void ompi_mpi_pvar_session_destructor (mca_base_pvar_session_t *session)
|
||||
{
|
||||
mca_base_pvar_handle_t *handle, *next;
|
||||
|
||||
/* it is likely a user error if there are any allocated handles when the session
|
||||
is freed. clean it up anyway. */
|
||||
OPAL_LIST_FOREACH_SAFE(handle, next, &session->handles, mca_base_pvar_handle_t) {
|
||||
OBJ_DESTRUCT(handle);
|
||||
}
|
||||
|
||||
OBJ_DESTRUCT(&session->handles);
|
||||
}
|
||||
|
||||
OBJ_CLASS_INSTANCE(mca_base_pvar_session_t, opal_object_t, ompi_mpi_pvar_session_constructor,
|
||||
ompi_mpi_pvar_session_destructor);
|
||||
|
||||
/* mca_base_pvar_handle_t class */
|
||||
static void mca_base_pvar_handle_constructor (mca_base_pvar_handle_t *handle)
|
||||
{
|
||||
memset ((char *) handle + sizeof (handle->super), 0, sizeof (*handle) - sizeof (handle->super));
|
||||
|
||||
OBJ_CONSTRUCT(&handle->list2, opal_list_item_t);
|
||||
}
|
||||
|
||||
static void mca_base_pvar_handle_destructor (mca_base_pvar_handle_t *handle)
|
||||
{
|
||||
if (handle->pvar) {
|
||||
(void) mca_base_pvar_notify (handle, MCA_BASE_PVAR_HANDLE_UNBIND, NULL);
|
||||
}
|
||||
|
||||
if (NULL != handle->last_value) {
|
||||
free (handle->last_value);
|
||||
}
|
||||
|
||||
if (NULL != handle->current_value) {
|
||||
free (handle->current_value);
|
||||
}
|
||||
|
||||
if (NULL != handle->tmp_value) {
|
||||
free (handle->tmp_value);
|
||||
}
|
||||
|
||||
OBJ_DESTRUCT(&handle->list2);
|
||||
}
|
||||
|
||||
OBJ_CLASS_INSTANCE(mca_base_pvar_handle_t, opal_list_item_t, mca_base_pvar_handle_constructor,
|
||||
mca_base_pvar_handle_destructor);
|
530
opal/mca/base/mca_base_pvar.h
Обычный файл
530
opal/mca/base/mca_base_pvar.h
Обычный файл
@ -0,0 +1,530 @@
|
||||
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2013 Los Alamos National Security, LLC. All rights
|
||||
* reserved.
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
*
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
#if !defined(OMPI_MPIT_PVAR_H)
|
||||
#define OMPI_MPIT_PVAR_H
|
||||
|
||||
#include "opal/mca/base/mca_base_var.h"
|
||||
|
||||
typedef enum {
|
||||
/** This variable should be marked as invalid when the containing
|
||||
group is deregistered. Equivalent to MCA_BASE_VAR_FLAG_DWG. */
|
||||
MCA_BASE_PVAR_FLAG_IWG = 0x040,
|
||||
/** This variable can not be written. Will be ignored for counter,
|
||||
timer, and aggregate variables. These variable handles will be
|
||||
updated relative to the value reported by the get_value()
|
||||
function provided at registration time. */
|
||||
MCA_BASE_PVAR_FLAG_READONLY = 0x080,
|
||||
/** This variable runs continuously after being bound to a handle. */
|
||||
MCA_BASE_PVAR_FLAG_CONTINUOUS = 0x100,
|
||||
/** This variable can be updated atomically. This flag is ignored
|
||||
by mca_base_pvar_register() at this time. */
|
||||
MCA_BASE_PVAR_FLAG_ATOMIC = 0x200,
|
||||
/** This variable has been marked as invalid. This flag is ignored
|
||||
by mca_base_pvar_register(). */
|
||||
MCA_BASE_PVAR_FLAG_INVALID = 0x400,
|
||||
} mca_base_pvar_flag_t;
|
||||
|
||||
typedef enum {
|
||||
/** A handle has been created an bound to this variable. The
|
||||
return value must be the number of values associated with
|
||||
the bound object or an OMPI error. For example, if the variable
|
||||
is the number of messages sent to each peer in a communicator then the
|
||||
return value should be the size of the bound communicator. */
|
||||
MCA_BASE_PVAR_HANDLE_BIND,
|
||||
/** A handle associated with this variable has been started. It is
|
||||
recommended that any computation that might affect perfomance
|
||||
only be performed when a bound handle has been started. */
|
||||
MCA_BASE_PVAR_HANDLE_START,
|
||||
/** A handle associated with this variable has been stopped */
|
||||
MCA_BASE_PVAR_HANDLE_STOP,
|
||||
/** A handle associated with this variable has been freed */
|
||||
MCA_BASE_PVAR_HANDLE_UNBIND
|
||||
} mca_base_pvar_event_t;
|
||||
|
||||
enum {
|
||||
/** Variable represents a state */
|
||||
MCA_BASE_PVAR_CLASS_STATE,
|
||||
/** Variable represents a the utilization level of a resource */
|
||||
MCA_BASE_PVAR_CLASS_LEVEL,
|
||||
/** Variable represents the fixed size of a resource */
|
||||
MCA_BASE_PVAR_CLASS_SIZE,
|
||||
/** Variable represents the utilization level of a resource.
|
||||
Valid type: double */
|
||||
MCA_BASE_PVAR_CLASS_PERCENTAGE,
|
||||
/** Variable describes the high-watermark of the utilization
|
||||
of a resource */
|
||||
MCA_BASE_PVAR_CLASS_HIGHWATERMARK,
|
||||
/** Variable describes the low-watermark of the utilization
|
||||
of a resource */
|
||||
MCA_BASE_PVAR_CLASS_LOWWATERMARK,
|
||||
/** Variable counts the number of occurences of a specific event */
|
||||
MCA_BASE_PVAR_CLASS_COUNTER,
|
||||
/** Variable represents a sum of arguments processed during a
|
||||
specific event */
|
||||
MCA_BASE_PVAR_CLASS_AGGREGATE,
|
||||
/** Variable represents the aggregated time that is spent
|
||||
executing an specific event */
|
||||
MCA_BASE_PVAR_CLASS_TIMER,
|
||||
/** Variable doesn't fit any other class */
|
||||
MCA_BASE_PVAR_CLASS_GENERIC
|
||||
};
|
||||
|
||||
/* Reserved bindings. OMPI will ignore any other binding type */
|
||||
enum {
|
||||
MCA_BASE_VAR_BIND_NO_OBJECT,
|
||||
MCA_BASE_VAR_BIND_MPI_COMM,
|
||||
MCA_BASE_VAR_BIND_MPI_DATATYPE,
|
||||
MCA_BASE_VAR_BIND_MPI_ERRHANDLER,
|
||||
MCA_BASE_VAR_BIND_MPI_FILE,
|
||||
MCA_BASE_VAR_BIND_MPI_GROUP,
|
||||
MCA_BASE_VAR_BIND_MPI_OP,
|
||||
MCA_BASE_VAR_BIND_MPI_REQUEST,
|
||||
MCA_BASE_VAR_BIND_MPI_WIN,
|
||||
MCA_BASE_VAR_BIND_MPI_MESSAGE,
|
||||
MCA_BASE_VAR_BIND_MPI_INFO,
|
||||
MCA_BASE_VAR_BIND_FIRST_AVAILABLE,
|
||||
};
|
||||
|
||||
struct mca_base_pvar_t;
|
||||
|
||||
/**
|
||||
* Function to retrieve the current value of a variable.
|
||||
*
|
||||
* @param[in] pvar Performance variable to get the value of.
|
||||
* @param[out] value Current value of the variable.
|
||||
* @param[in] obj Bound object
|
||||
*
|
||||
* This function will be called to get the current value of a variable. The value
|
||||
* pointer will be large enough to hold the datatype and count specified when this
|
||||
* variable was created and bound.
|
||||
*/
|
||||
typedef int (*mca_base_get_value_fn_t) (const struct mca_base_pvar_t *pvar, void *value, void *obj);
|
||||
|
||||
/**
|
||||
* Function to set the current value of a variable.
|
||||
*
|
||||
* @param[in] pvar Performance variable to set the value of.
|
||||
* @param[in] value Value to write.
|
||||
* @param[in] obj Bound object.
|
||||
*
|
||||
* This function will be called to set the current value of a variable. The value
|
||||
* pointer will be large enough to hold the datatype and count specified when this
|
||||
* variable was created and bound. Read-only variables are not expected to provide
|
||||
* this function.
|
||||
*/
|
||||
typedef int (*mca_base_set_value_fn_t) (struct mca_base_pvar_t *pvar, const void *value, void *obj);
|
||||
|
||||
/**
|
||||
* Function to notify of a pvar handle event.
|
||||
*
|
||||
* @param[in] pvar Performance variable the handle is assocaited with
|
||||
* @param[in] event Event that has occurred. See mca_base_pvar_event_t.
|
||||
* @param[in] obj Bound object
|
||||
* @param[out] count Value count for this object (on MCA_BASE_PVAR_HANDLE_BIND)
|
||||
*
|
||||
* Depending on the event this functions is expected to:
|
||||
* On MCA_BASE_PVAR_HANDLE_BIND: depending on the bound object returns the number of values
|
||||
* needed for get_value().
|
||||
* On MCA_BASE_PVAR_HANDLE_START: enable the performance variable.
|
||||
* On MCA_BASE_PVAR_HANDLE_STOP: XXX -- TODO -- finish me
|
||||
*/
|
||||
typedef int (*mca_base_notify_fn_t) (struct mca_base_pvar_t *pvar, mca_base_pvar_event_t event, void *obj, int *count);
|
||||
|
||||
/**
|
||||
* Structure representing an OMPI performance variable.
|
||||
*/
|
||||
typedef struct mca_base_pvar_t {
|
||||
/** Make this an opal object */
|
||||
opal_object_t super;
|
||||
|
||||
/** Variable index */
|
||||
int pvar_index;
|
||||
|
||||
/** Full name of the variable: form is framework_component_name */
|
||||
char *full_name;
|
||||
|
||||
/** Short name of the variable */
|
||||
char *name;
|
||||
|
||||
/** Description of this performance variable */
|
||||
char *description;
|
||||
|
||||
/** MCA variable group this variable is associated with */
|
||||
int group_index;
|
||||
|
||||
/** Verbosity level of this variable */
|
||||
mca_base_var_info_lvl_t verbosity;
|
||||
|
||||
/** Variable class. See mpi.h.in MPIT pvar classes */
|
||||
int var_class;
|
||||
|
||||
/** MPI datatype of the information stored in the performance variable */
|
||||
mca_base_var_type_t type;
|
||||
|
||||
/** Enumerator for integer values */
|
||||
mca_base_var_enum_t *enumerator;
|
||||
|
||||
/** Type of object to which this variable must be bound or MCA_BASE_VAR_BIND_NULL */
|
||||
int bind;
|
||||
|
||||
/** Flags for this variable */
|
||||
mca_base_pvar_flag_t flags;
|
||||
|
||||
/** Get the current value of this variable */
|
||||
mca_base_get_value_fn_t get_value;
|
||||
|
||||
/** Set the current value of this variable. Only valid for read-write variables. */
|
||||
mca_base_set_value_fn_t set_value;
|
||||
|
||||
/** Notify the creator of this variable of a change */
|
||||
mca_base_notify_fn_t notify;
|
||||
|
||||
/** Context of this variable */
|
||||
void *ctx;
|
||||
|
||||
/** List of bound pvar handles. NOTE: The items in this list are
|
||||
offsetof(mca_base_pvar_handle_t, list2) into a pvar handle. */
|
||||
opal_list_t bound_handles;
|
||||
} mca_base_pvar_t;
|
||||
OBJ_CLASS_DECLARATION(mca_base_pvar_t);
|
||||
|
||||
/**
|
||||
* Performance variable session
|
||||
*/
|
||||
typedef struct mca_base_pvar_session_t {
|
||||
/** Make this an opal object */
|
||||
opal_object_t super;
|
||||
|
||||
/** List of all handles in the session */
|
||||
opal_list_t handles;
|
||||
} mca_base_pvar_session_t;
|
||||
OBJ_CLASS_DECLARATION(mca_base_pvar_session_t);
|
||||
|
||||
/**
|
||||
* Performance variable handle
|
||||
*
|
||||
* Handles are used to bind performance variables to objects, read, write, and
|
||||
* reset values.
|
||||
*/
|
||||
typedef struct mca_base_pvar_handle_t {
|
||||
/** List item in pvar session */
|
||||
opal_list_item_t super;
|
||||
|
||||
/** XXX -- use me -- add this list item to the associated variable */
|
||||
opal_list_item_t list2;
|
||||
|
||||
/** session this handle is associated with */
|
||||
mca_base_pvar_session_t *session;
|
||||
|
||||
/** performance variable this handle is associated with */
|
||||
mca_base_pvar_t *pvar;
|
||||
|
||||
/** MPI object handle */
|
||||
void *obj_handle;
|
||||
|
||||
/** Number of values for this handle */
|
||||
int count;
|
||||
|
||||
/** Last value read from the variable */
|
||||
void *last_value;
|
||||
|
||||
/** Current sum for counters and timers */
|
||||
void *current_value;
|
||||
|
||||
/** Temporary buffer for counters. Used to calculate deltas between
|
||||
the last value and the current value. */
|
||||
void *tmp_value;
|
||||
|
||||
/** Has this handle been started (or is continuous) */
|
||||
bool started;
|
||||
} mca_base_pvar_handle_t;
|
||||
OBJ_CLASS_DECLARATION(mca_base_pvar_handle_t);
|
||||
|
||||
/**
|
||||
* Return the number or registered performance variables.
|
||||
*
|
||||
* @param[out] count Number of registered performance variables.
|
||||
*
|
||||
* This function can be called before mca_base_pvar_init() and after
|
||||
* mca_base_pvar_finalize().
|
||||
*/
|
||||
OPAL_DECLSPEC int mca_base_pvar_get_count (int *count);
|
||||
|
||||
/**
|
||||
* Register a performance variable
|
||||
*
|
||||
* @param[in] framework Name of registering framework
|
||||
* @param[in] component Name of registering component
|
||||
* @param[in] name Name of performance variable
|
||||
* @param[in] description Description of the performance variable. Verbose
|
||||
* is good!
|
||||
* @param[in] verbosity Opal info verbosity of this variable. Equivalent to
|
||||
* MPI_T verbosity.
|
||||
* @param[in] var_class Class of performance variable. See mpi.h.in MPI_T_PVAR_CLASS_*
|
||||
* @param[in] type Type of this performance variable
|
||||
* @param[in] enumerator Enumerator for this variable. Will be OBJ_RETAIN'd.
|
||||
* @param[in] bind Object type this variable should be bound to. See mpi.h.in
|
||||
* MPI_T_BIND_*
|
||||
* @param[in] flags Flags for this variable. See mca_base_pvar_flag_t for acceptable
|
||||
* flags.
|
||||
* @param[in] get_value Function for reading the value of this variable. If this function
|
||||
* is NULL a default function that reads 1 value from ctx will be used.
|
||||
* See mca_base_get_value_fn_t.
|
||||
* @param[in] set_value Function for writing the value of this variable. This pointer is
|
||||
* ignored if the \flags includes \MCA_BASE_PVAR_FLAG_READONLY. If this
|
||||
* function is NULL a default function that writes 1 value from ctx will
|
||||
* be used. See mca_base_set_value_fn_t.
|
||||
* @param[in] notify Function for notifying about variable handle events. If this function
|
||||
* is NULL then a default function that ignores all events will be used.
|
||||
* See mca_base_notify_fn_t.
|
||||
* @param[in] ctx Context for this variable. Will be stored in the resulting variable
|
||||
* for future use.
|
||||
*
|
||||
* @returns index On success returns the index of this variable.
|
||||
* @returns OMPI_ERROR On error.
|
||||
*
|
||||
* Note: if used incorrectly this functions may call abort(). Please see MPI 3.0 14.3 to see
|
||||
* acceptable values for datatype given the class.
|
||||
*/
|
||||
OPAL_DECLSPEC int mca_base_pvar_register (const char *project, const char *framework, const char *component, const char *name,
|
||||
const char *description, mca_base_var_info_lvl_t verbosity,
|
||||
int var_class, mca_base_var_type_t type, mca_base_var_enum_t *enumerator,
|
||||
int bind, mca_base_pvar_flag_t flags, mca_base_get_value_fn_t get_value,
|
||||
mca_base_set_value_fn_t set_value, mca_base_notify_fn_t notify, void *ctx);
|
||||
|
||||
/**
|
||||
* Convinience function for registering a performance variable associated with a component.
|
||||
* See mca_base_pvar_register().
|
||||
*/
|
||||
OPAL_DECLSPEC int mca_base_component_pvar_register (const mca_base_component_t *component, const char *name,
|
||||
const char *description, mca_base_var_info_lvl_t verbosity, int var_class,
|
||||
mca_base_var_type_t type, mca_base_var_enum_t *enumerator, int bind,
|
||||
mca_base_pvar_flag_t flags, mca_base_get_value_fn_t get_value,
|
||||
mca_base_set_value_fn_t set_value, mca_base_notify_fn_t notify, void *ctx);
|
||||
|
||||
|
||||
/**
|
||||
* Find the index for an MCA performance variable based on its names.
|
||||
*
|
||||
* @param project Name of the project
|
||||
* @param type Name of the type containing the variable.
|
||||
* @param component Name of the component containing the variable.
|
||||
* @param param Name of the variable.
|
||||
*
|
||||
* @retval OPAL_ERROR If the variable was not found.
|
||||
* @retval index If the variable was found.
|
||||
*
|
||||
* It is not always convenient to widely propagate a variable's index
|
||||
* value, or it may be necessary to look up the variable from a
|
||||
* different component. This function can be used to look up the index
|
||||
* of any registered variable. The returned index can be used with
|
||||
* mca_base_pvar_get(), mca_base_pvar_handle_alloc(), and
|
||||
* mca_base_pvar_dump().
|
||||
*/
|
||||
OPAL_DECLSPEC int mca_base_pvar_find (const char *project, const char *framework, const char *component, const char *name);
|
||||
|
||||
/**
|
||||
* Find the index for a performance variable based on its full name
|
||||
*
|
||||
* @param full_name [in] Full name of the variable
|
||||
* @param index [out] Index of the variable
|
||||
*
|
||||
* See mca_base_pvar_find().
|
||||
*/
|
||||
OPAL_DECLSPEC int mca_base_pvar_find_by_name (const char *full_name, int *index);
|
||||
|
||||
/**
|
||||
* Update the handles associated with the specified performance variable and MPI object
|
||||
*
|
||||
* @param[in] index Index of the performance variable
|
||||
* @param[in] value New value of the variable.
|
||||
* @param[in] obj Object updated handles should be bound to.
|
||||
*
|
||||
* This function will obtain and hold the mpit big lock until all handles are updated. It
|
||||
* is recommended this function not be called from within any critical code path. Calling
|
||||
* this function should only be necessary to update watermarks.
|
||||
*/
|
||||
OPAL_DECLSPEC int mca_base_pvar_update_all_handles (int index, const void *obj);
|
||||
|
||||
/**
|
||||
* Get the variable at an index
|
||||
*
|
||||
* @param[in] index Index of variable to get.
|
||||
* @param[out] pvar Performance variable from index on success.
|
||||
*
|
||||
* @returns OMPI_SUCCESS on success
|
||||
* @returns OMPI_ERR_VALUE_OUT_OF_BOUNDS on if index is out of range
|
||||
*/
|
||||
OPAL_DECLSPEC int mca_base_pvar_get (int index, const mca_base_pvar_t **pvar);
|
||||
|
||||
/**
|
||||
* Dump strings describing the performance variable at an index
|
||||
*
|
||||
* @param[in] index Variable index
|
||||
* @param[out] out Array of strings representing this variable
|
||||
* @param[in] output_type Type of output desired
|
||||
*
|
||||
* This function returns an array of strings describing the variable. All strings
|
||||
* and the array must be freed by the caller. The \output_type may be either
|
||||
* MCA_BASE_VAR_DUMP_READABLE or MCA_BASE_VAR_DUMP_PARSABLE.
|
||||
*/
|
||||
OPAL_DECLSPEC int mca_base_pvar_dump(int index, char ***out, mca_base_var_dump_type_t output_type);
|
||||
|
||||
/**
|
||||
* Mark a performance variable as invalid
|
||||
*
|
||||
* @param[in] index Variable index
|
||||
*
|
||||
* A performance variable that has been marked as invalid will not be available. To
|
||||
* restore a performance variable it has to be re-registered using mca_base_pvar_register().
|
||||
*/
|
||||
int mca_base_pvar_mark_invalid (int index);
|
||||
|
||||
/**
|
||||
* Convienience functions for performance variables
|
||||
*/
|
||||
static inline bool mca_base_pvar_is_sum (const mca_base_pvar_t *pvar)
|
||||
{
|
||||
return (MCA_BASE_PVAR_CLASS_COUNTER == pvar->var_class ||
|
||||
MCA_BASE_PVAR_CLASS_TIMER == pvar->var_class ||
|
||||
MCA_BASE_PVAR_CLASS_AGGREGATE == pvar->var_class);
|
||||
}
|
||||
|
||||
static inline bool mca_base_pvar_is_watermark (const mca_base_pvar_t *pvar)
|
||||
{
|
||||
return (MCA_BASE_PVAR_CLASS_HIGHWATERMARK == pvar->var_class ||
|
||||
MCA_BASE_PVAR_CLASS_LOWWATERMARK == pvar->var_class);
|
||||
}
|
||||
|
||||
static inline bool mca_base_pvar_is_readonly (const mca_base_pvar_t *pvar)
|
||||
{
|
||||
return !!(pvar->flags & MCA_BASE_PVAR_FLAG_READONLY);
|
||||
}
|
||||
|
||||
static inline bool mca_base_pvar_is_continuous (const mca_base_pvar_t *pvar)
|
||||
{
|
||||
return !!(pvar->flags & MCA_BASE_PVAR_FLAG_CONTINUOUS);
|
||||
}
|
||||
|
||||
static inline bool mca_base_pvar_is_atomic (const mca_base_pvar_t *pvar)
|
||||
{
|
||||
return !!(pvar->flags & MCA_BASE_PVAR_FLAG_ATOMIC);
|
||||
}
|
||||
|
||||
/* Handle functions */
|
||||
|
||||
/**
|
||||
* Bind a new handle and object to a performance variable
|
||||
*
|
||||
* @param[in] session Valid pvar session
|
||||
* @param[in] index Variable index
|
||||
* @param[in] obj_handle Object handle
|
||||
* @param[out] handle New handle
|
||||
* @param[out] count Number of values associated with this object
|
||||
*
|
||||
* This function allocates a new performance variable handle and binds it
|
||||
* to \obj_handle (if the variable binding is 0 the object is ignored). On
|
||||
* success a new handle is returned in \handle and the number of values i
|
||||
* returned in \count. Calls to read/write must provide buffers that will
|
||||
* hold \count values of the type of the performance variable specified by
|
||||
* \index.
|
||||
*/
|
||||
OPAL_DECLSPEC int mca_base_pvar_handle_alloc (mca_base_pvar_session_t *session, int index, void *obj_handle,
|
||||
mca_base_pvar_handle_t **handle, int *count);
|
||||
|
||||
/**
|
||||
* Free an allocated performance variable handle
|
||||
*
|
||||
* @param[in] handle Handle to free
|
||||
*
|
||||
* After calling this function the performance variable will no longer be valid.
|
||||
*/
|
||||
OPAL_DECLSPEC int mca_base_pvar_handle_free (mca_base_pvar_handle_t *handle);
|
||||
|
||||
/**
|
||||
* Update a performance variable handle.
|
||||
*
|
||||
* @param[in] handle Handle to update
|
||||
*
|
||||
* The new value of the handle will depend on the class of performance variable.
|
||||
* For counters and timers the new value will be the current handle value plus the
|
||||
* difference between the last and the current variable value. For high/low watermarks
|
||||
* the new value will be the greater/lesser of the current handle value and the
|
||||
* current variable value. This call does not update other types of handles.
|
||||
*/
|
||||
OPAL_DECLSPEC int mca_base_pvar_handle_update (mca_base_pvar_handle_t *handle);
|
||||
|
||||
/**
|
||||
* Read the current value of a handle
|
||||
*
|
||||
* @param[in] handle Handle to read from
|
||||
* @param[out] value Buffer to store the current value in
|
||||
*
|
||||
* Read the current value of the handle or variable (depending on the variable class)
|
||||
* and return it in the buffer specified by value. The buffer must be large enough to
|
||||
* hold the correct number and type of this handle's value (see mca_base_pvar_handle_update()).
|
||||
*/
|
||||
OPAL_DECLSPEC int mca_base_pvar_handle_read_value (mca_base_pvar_handle_t *handle, void *value);
|
||||
|
||||
/**
|
||||
* Write a value to a read-write handle
|
||||
*
|
||||
* @param[in] handle Handle to update
|
||||
* @param[in] value Value to write
|
||||
*
|
||||
* If the underlying variable is read-only this function will fail with OPAL_ERR_PERM.
|
||||
*/
|
||||
OPAL_DECLSPEC int mca_base_pvar_handle_write_value (mca_base_pvar_handle_t *handle, const void *value);
|
||||
|
||||
/**
|
||||
* Convienience function for sending notification of a handle change
|
||||
*
|
||||
* @param[in] handle Handle event occurred on
|
||||
* @param[in] event Event that occurred
|
||||
* @param[out] count Value count returned when binding a handle
|
||||
*/
|
||||
OPAL_DECLSPEC int mca_base_pvar_notify (mca_base_pvar_handle_t *handle, mca_base_pvar_event_t event, int *count);
|
||||
|
||||
/**
|
||||
* Start a performance variable handle
|
||||
*
|
||||
* @param[in] handle Handle to start
|
||||
*
|
||||
* @returns OPAL_SUCCESS on success
|
||||
* @returns OPAL_ERR_NOT_SUPPORTED if the handle could not be started
|
||||
*/
|
||||
OPAL_DECLSPEC int mca_base_pvar_handle_start (mca_base_pvar_handle_t *handle);
|
||||
|
||||
/**
|
||||
* Stop a performance variable handle
|
||||
*
|
||||
* @param[in] handle Handle to stop (must be started)
|
||||
*
|
||||
* @return OPAL_SUCCESS on success
|
||||
* @returns OPAL_ERR_NOT_SUPPORTED if the handle could not be started
|
||||
*/
|
||||
OPAL_DECLSPEC int mca_base_pvar_handle_stop (mca_base_pvar_handle_t *handle);
|
||||
|
||||
/**
|
||||
* Reset a performance variable handle
|
||||
*
|
||||
* @param[in] handle Handle to reset
|
||||
*
|
||||
* Reset the handle to a value equivalent to when the handle was first allocated.
|
||||
*/
|
||||
OPAL_DECLSPEC int mca_base_pvar_handle_reset (mca_base_pvar_handle_t *handle);
|
||||
|
||||
static inline bool mca_base_pvar_handle_is_running (mca_base_pvar_handle_t *handle)
|
||||
{
|
||||
return handle->started || !!(handle->pvar->flags & MCA_BASE_PVAR_FLAG_CONTINUOUS);
|
||||
}
|
||||
|
||||
#endif
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
@ -64,6 +64,7 @@
|
||||
#include "opal/class/opal_list.h"
|
||||
#include "opal/class/opal_value_array.h"
|
||||
#include "opal/mca/base/mca_base_var_enum.h"
|
||||
#include "opal/mca/base/mca_base_var_group.h"
|
||||
#include "opal/mca/base/mca_base_framework.h"
|
||||
#include "opal/mca/mca.h"
|
||||
|
||||
@ -75,6 +76,8 @@ typedef enum {
|
||||
MCA_BASE_VAR_TYPE_INT,
|
||||
/** The variable is of type unsigned int */
|
||||
MCA_BASE_VAR_TYPE_UNSIGNED_INT,
|
||||
/** The variable is of type unsigned long */
|
||||
MCA_BASE_VAR_TYPE_UNSIGNED_LONG,
|
||||
/** The variable is of type unsigned long long */
|
||||
MCA_BASE_VAR_TYPE_UNSIGNED_LONG_LONG,
|
||||
/** The variable is of type size_t */
|
||||
@ -83,6 +86,8 @@ typedef enum {
|
||||
MCA_BASE_VAR_TYPE_STRING,
|
||||
/** The variable is of type bool */
|
||||
MCA_BASE_VAR_TYPE_BOOL,
|
||||
/** The variable is of type double */
|
||||
MCA_BASE_VAR_TYPE_DOUBLE,
|
||||
/** Maximum variable type. */
|
||||
MCA_BASE_VAR_TYPE_MAX
|
||||
} mca_base_var_type_t;
|
||||
@ -184,18 +189,22 @@ typedef enum {
|
||||
* Types for MCA parameters.
|
||||
*/
|
||||
typedef union {
|
||||
/** Integer value */
|
||||
/** integer value */
|
||||
int intval;
|
||||
/** Unsigned int value */
|
||||
/** unsigned int value */
|
||||
unsigned int uintval;
|
||||
/** String value */
|
||||
/** string value */
|
||||
char *stringval;
|
||||
/** Boolean value */
|
||||
/** boolean value */
|
||||
bool boolval;
|
||||
/** unsigned long value */
|
||||
unsigned long ulval;
|
||||
/** unsigned long long value */
|
||||
unsigned long long ullval;
|
||||
/** size_t value */
|
||||
size_t sizetval;
|
||||
/** double value */
|
||||
double lfval;
|
||||
} mca_base_var_storage_t;
|
||||
|
||||
|
||||
@ -268,34 +277,6 @@ struct mca_base_var_t {
|
||||
*/
|
||||
typedef struct mca_base_var_t mca_base_var_t;
|
||||
|
||||
struct mca_base_var_group_t {
|
||||
opal_list_item_t super;
|
||||
|
||||
/** Index of group */
|
||||
int group_index;
|
||||
|
||||
/** Group is valid (registered) */
|
||||
bool group_isvalid;
|
||||
|
||||
/** Group name */
|
||||
char *group_full_name;
|
||||
|
||||
char *group_project;
|
||||
char *group_framework;
|
||||
char *group_component;
|
||||
|
||||
/** Group help message (description) */
|
||||
char *group_description;
|
||||
|
||||
/** Integer value array of subgroup indices */
|
||||
opal_value_array_t group_subgroups;
|
||||
|
||||
/** Integer array of group variables */
|
||||
opal_value_array_t group_vars;
|
||||
};
|
||||
|
||||
typedef struct mca_base_var_group_t mca_base_var_group_t;
|
||||
|
||||
/*
|
||||
* Global functions for MCA
|
||||
*/
|
||||
@ -307,12 +288,6 @@ BEGIN_C_DECLS
|
||||
*/
|
||||
OPAL_DECLSPEC OBJ_CLASS_DECLARATION(mca_base_var_t);
|
||||
|
||||
|
||||
/**
|
||||
* Object declaration for mca_base_var_group_t
|
||||
*/
|
||||
OPAL_DECLSPEC OBJ_CLASS_DECLARATION(mca_base_var_group_t);
|
||||
|
||||
/**
|
||||
* Initialize the MCA variable system.
|
||||
*
|
||||
@ -324,104 +299,6 @@ OPAL_DECLSPEC OBJ_CLASS_DECLARATION(mca_base_var_group_t);
|
||||
*/
|
||||
OPAL_DECLSPEC int mca_base_var_init(void);
|
||||
|
||||
/**
|
||||
* Register an MCA variable group
|
||||
*
|
||||
* @param[in] project_name Project name for this group.
|
||||
* @param[in] framework_name Framework name for this group.
|
||||
* @param[in] component_name Component name for this group.
|
||||
* @param[in] descrition Description of this group.
|
||||
*
|
||||
* @retval index Unique group index
|
||||
* @return opal error code on Error
|
||||
*
|
||||
* Create an MCA variable group. If the group already exists
|
||||
* this call is equivalent to mca_base_ver_find_group().
|
||||
*/
|
||||
OPAL_DECLSPEC int mca_base_var_group_register(const char *project_name,
|
||||
const char *framework_name,
|
||||
const char *component_name,
|
||||
const char *description);
|
||||
|
||||
/**
|
||||
* Register an MCA variable group for a component
|
||||
*
|
||||
* @param[in] component [in] Pointer to the component for which the
|
||||
* group is being registered.
|
||||
* @param[in] description Description of this group.
|
||||
*
|
||||
* @retval index Unique group index
|
||||
* @return opal error code on Error
|
||||
*/
|
||||
OPAL_DECLSPEC int mca_base_var_group_component_register (const mca_base_component_t *component,
|
||||
const char *description);
|
||||
|
||||
/**
|
||||
* Deregister an MCA param group
|
||||
*
|
||||
* @param group_index [in] Group index from mca_base_var_group_register (),
|
||||
* mca_base_var_group_find().
|
||||
*
|
||||
* This call deregisters all associated variables and subgroups.
|
||||
*/
|
||||
OPAL_DECLSPEC int mca_base_var_group_deregister (int group_index);
|
||||
|
||||
/**
|
||||
* Find an MCA group
|
||||
*
|
||||
* @param project_name [in] Project name
|
||||
* @param framework_name [in] Type name
|
||||
* @param component_name [in] Component name
|
||||
*/
|
||||
OPAL_DECLSPEC int mca_base_var_group_find (const char *project_name,
|
||||
const char *framework_name,
|
||||
const char *component_name);
|
||||
|
||||
/**
|
||||
* Dump info from a group
|
||||
*
|
||||
* @param[in] group_index Group index
|
||||
* @param[out] group Storage for the group object pointer.
|
||||
*
|
||||
* @retval OPAL_ERR_NOT_FOUND If the group specified by group_index does not exist.
|
||||
* @retval OPAL_ERR_OUT_OF_RESOURCE If memory allocation fails.
|
||||
* @retval OPAL_SUCCESS If the group is dumped successfully.
|
||||
*
|
||||
* The returned pointer belongs to the MCA variable system. Do not modify/release/retain
|
||||
* the pointer.
|
||||
*/
|
||||
OPAL_DECLSPEC int mca_base_var_group_get (const int group_index,
|
||||
const mca_base_var_group_t **group);
|
||||
|
||||
/**
|
||||
* Set/unset a flags for all variables in a group.
|
||||
*
|
||||
* @param[in] group_index Index of group
|
||||
* @param[in] flag Flag(s) to set or unset.
|
||||
* @param[in] set Boolean indicating whether to set flag(s).
|
||||
*
|
||||
* Set a flag for every variable in a group. See mca_base_var_set_flag() for more info.
|
||||
*/
|
||||
OPAL_DECLSPEC int mca_base_var_group_set_var_flag (const int group_index,
|
||||
mca_base_var_flag_t flags,
|
||||
bool set);
|
||||
|
||||
/**
|
||||
* Get the number of registered MCA groups
|
||||
*
|
||||
* @retval count Number of registered MCA groups
|
||||
*/
|
||||
OPAL_DECLSPEC int mca_base_var_group_get_count (void);
|
||||
|
||||
/**
|
||||
* Get a relative timestamp for the MCA group system
|
||||
*
|
||||
* @retval stamp
|
||||
*
|
||||
* This value will change if groups or variables are either added or removed.
|
||||
*/
|
||||
OPAL_DECLSPEC int mca_base_var_group_get_stamp (void);
|
||||
|
||||
/**
|
||||
* Register an MCA variable
|
||||
*
|
||||
@ -542,7 +419,6 @@ OPAL_DECLSPEC int mca_base_framework_var_register (const mca_base_framework_t *f
|
||||
mca_base_var_info_lvl_t info_level,
|
||||
mca_base_var_scope_t scope, void *storage);
|
||||
|
||||
|
||||
/**
|
||||
* Register a synonym name for an MCA variable.
|
||||
*
|
||||
@ -644,7 +520,7 @@ OPAL_DECLSPEC int mca_base_var_get_value (int index, const void *value,
|
||||
* a synonym the variable the synonym represents) if the value is
|
||||
* settable.
|
||||
*/
|
||||
OPAL_DECLSPEC int mca_base_var_set_value (int index, void *value, size_t size,
|
||||
OPAL_DECLSPEC int mca_base_var_set_value (int index, const void *value, size_t size,
|
||||
mca_base_var_source_t source,
|
||||
const char *source_file);
|
||||
|
||||
@ -667,26 +543,35 @@ OPAL_DECLSPEC int mca_base_var_env_name(const char *param_name,
|
||||
/**
|
||||
* Find the index for an MCA variable based on its names.
|
||||
*
|
||||
* @param type Name of the type containing the variable.
|
||||
* @param component Name of the component containing the variable.
|
||||
* @param param Name of the variable.
|
||||
* @param project_name Name of the project
|
||||
* @param type_name Name of the type containing the variable.
|
||||
* @param component_name Name of the component containing the variable.
|
||||
* @param param_name Name of the variable.
|
||||
*
|
||||
* @retval OPAL_ERROR If the variable was not found.
|
||||
* @retval index If the variable was found.
|
||||
*
|
||||
* It is not always convenient to widely propagate a variable's index
|
||||
* value, or it may be necessary to look up the variable from a
|
||||
* different component -- where it is not possible to have the return
|
||||
* value from mca_base_var_reg_int() or mca_base_var_reg_string().
|
||||
* This function can be used to look up the index of any registered
|
||||
* variable. The returned index can be used with
|
||||
* mca_base_var_lookup_int() and mca_base_var_lookup_string().
|
||||
* different component. This function can be used to look up the index
|
||||
* of any registered variable. The returned index can be used with
|
||||
* mca_base_var_get() and mca_base_var_get_value().
|
||||
*/
|
||||
OPAL_DECLSPEC int mca_base_var_find (const char *project_name,
|
||||
const char *type_name,
|
||||
const char *component_name,
|
||||
const char *param_name);
|
||||
|
||||
/**
|
||||
* Find the index for a variable based on its full name
|
||||
*
|
||||
* @param full_name [in] Full name of the variable
|
||||
* @param index [out] Index of the variable
|
||||
*
|
||||
* See mca_base_var_find().
|
||||
*/
|
||||
OPAL_DECLSPEC int mca_base_var_find_by_name (const char *full_name, int *index);
|
||||
|
||||
/**
|
||||
* Check that two MCA variables were not both set to non-default
|
||||
* values.
|
||||
@ -801,20 +686,23 @@ OPAL_DECLSPEC int mca_base_var_build_env(char ***env, int *num_env,
|
||||
OPAL_DECLSPEC int mca_base_var_finalize(void);
|
||||
|
||||
typedef enum {
|
||||
/* Dump human-readable strings */
|
||||
MCA_BASE_VAR_DUMP_READABLE = 0,
|
||||
/* Dump easily parsable strings */
|
||||
MCA_BASE_VAR_DUMP_PARSABLE = 1,
|
||||
/* Dump simple name=value string */
|
||||
MCA_BASE_VAR_DUMP_SIMPLE = 2,
|
||||
} mca_base_var_dump_type_t;
|
||||
|
||||
/**
|
||||
* Dump strings for variable at index.
|
||||
* Dump strings describing the MCA variable at an index.
|
||||
*
|
||||
* @param[in] index Variable index
|
||||
* @param[out] out Array of strings representing this variable
|
||||
* @param[in] flags Flags indication how to output variable
|
||||
* @param[in] index Variable index
|
||||
* @param[out] out Array of strings describing this variable
|
||||
* @param[in] output_type Type of output desired
|
||||
*
|
||||
* This functions returns an array strings for the variable. All strings and the array
|
||||
* need to be freed by the caller.
|
||||
* This function returns an array of strings describing the variable. All strings
|
||||
* and the array must be freed by the caller.
|
||||
*/
|
||||
OPAL_DECLSPEC int mca_base_var_dump(int index, char ***out, mca_base_var_dump_type_t output_type);
|
||||
|
||||
|
497
opal/mca/base/mca_base_var_group.c
Обычный файл
497
opal/mca/base/mca_base_var_group.c
Обычный файл
@ -0,0 +1,497 @@
|
||||
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2004-2008 The Trustees of Indiana University and Indiana
|
||||
* University Research and Technology
|
||||
* Corporation. All rights reserved.
|
||||
* Copyright (c) 2004-2012 The University of Tennessee and The University
|
||||
* of Tennessee Research Foundation. All rights
|
||||
* reserved.
|
||||
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
* University of Stuttgart. All rights reserved.
|
||||
* Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 2008-2013 Cisco Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2012-2013 Los Alamos National Security, LLC. All rights
|
||||
* reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
*
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
#include "opal_config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_PARAM_H
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
|
||||
#include "opal/include/opal_stdint.h"
|
||||
#include "opal/util/show_help.h"
|
||||
#include "opal/mca/mca.h"
|
||||
#include "opal/mca/base/mca_base_vari.h"
|
||||
#include "opal/mca/base/mca_base_pvar.h"
|
||||
#include "opal/constants.h"
|
||||
#include "opal/util/output.h"
|
||||
#include "opal/util/opal_environ.h"
|
||||
#include "opal/runtime/opal.h"
|
||||
|
||||
static opal_pointer_array_t mca_base_var_groups;
|
||||
static opal_hash_table_t mca_base_var_group_index_hash;
|
||||
static int mca_base_var_group_count = 0;
|
||||
static int mca_base_var_groups_timestamp = 0;
|
||||
static bool mca_base_var_group_initialized = false;
|
||||
|
||||
static void mca_base_var_group_constructor (mca_base_var_group_t *group);
|
||||
static void mca_base_var_group_destructor (mca_base_var_group_t *group);
|
||||
OBJ_CLASS_INSTANCE(mca_base_var_group_t, opal_object_t,
|
||||
mca_base_var_group_constructor,
|
||||
mca_base_var_group_destructor);
|
||||
|
||||
int mca_base_var_group_init (void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!mca_base_var_group_initialized) {
|
||||
OBJ_CONSTRUCT(&mca_base_var_groups, opal_pointer_array_t);
|
||||
|
||||
/* These values are arbitrary */
|
||||
ret = opal_pointer_array_init (&mca_base_var_groups, 128, 16384, 128);
|
||||
if (OPAL_SUCCESS != ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
OBJ_CONSTRUCT(&mca_base_var_group_index_hash, opal_hash_table_t);
|
||||
ret = opal_hash_table_init (&mca_base_var_group_index_hash, 256);
|
||||
if (OPAL_SUCCESS != ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
mca_base_var_group_initialized = true;
|
||||
mca_base_var_group_count = 0;
|
||||
}
|
||||
|
||||
return OPAL_SUCCESS;
|
||||
}
|
||||
|
||||
int mca_base_var_group_finalize (void)
|
||||
{
|
||||
opal_object_t *object;
|
||||
int size, i;
|
||||
|
||||
if (mca_base_var_group_initialized) {
|
||||
size = opal_pointer_array_get_size(&mca_base_var_groups);
|
||||
for (i = 0 ; i < size ; ++i) {
|
||||
object = opal_pointer_array_get_item (&mca_base_var_groups, i);
|
||||
if (NULL != object) {
|
||||
OBJ_RELEASE(object);
|
||||
}
|
||||
}
|
||||
OBJ_DESTRUCT(&mca_base_var_groups);
|
||||
OBJ_DESTRUCT(&mca_base_var_group_index_hash);
|
||||
mca_base_var_group_count = 0;
|
||||
mca_base_var_group_initialized = false;
|
||||
}
|
||||
|
||||
return OPAL_SUCCESS;
|
||||
}
|
||||
|
||||
int mca_base_var_group_get_internal (const int group_index, mca_base_var_group_t **group, bool invalidok)
|
||||
{
|
||||
if (group_index < 0) {
|
||||
return OPAL_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
*group = (mca_base_var_group_t *) opal_pointer_array_get_item (&mca_base_var_groups,
|
||||
group_index);
|
||||
if (NULL == *group || (!invalidok && !(*group)->group_isvalid)) {
|
||||
*group = NULL;
|
||||
return OPAL_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
return OPAL_SUCCESS;
|
||||
}
|
||||
|
||||
static int group_find_by_name (const char *full_name, int *index, bool invalidok)
|
||||
{
|
||||
mca_base_var_group_t *group;
|
||||
void *tmp;
|
||||
int rc;
|
||||
|
||||
rc = opal_hash_table_get_value_ptr (&mca_base_var_group_index_hash, full_name,
|
||||
strlen (full_name), &tmp);
|
||||
if (OPAL_SUCCESS != rc) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = mca_base_var_group_get_internal ((int)(uintptr_t) tmp, &group, false);
|
||||
if (OPAL_SUCCESS != rc) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (invalidok || group->group_isvalid) {
|
||||
*index = (int)(uintptr_t) tmp;
|
||||
return OPAL_SUCCESS;
|
||||
}
|
||||
|
||||
return OPAL_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
static int group_find (const char *project_name, const char *framework_name,
|
||||
const char *component_name, bool invalidok)
|
||||
{
|
||||
char *full_name;
|
||||
int ret, index;
|
||||
|
||||
if (!mca_base_var_initialized) {
|
||||
return OPAL_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
/* TODO -- deal with the project name correctly (including the wildcard '*') */
|
||||
project_name = NULL;
|
||||
|
||||
ret = mca_base_var_generate_full_name4(project_name, framework_name, component_name,
|
||||
NULL, &full_name);
|
||||
if (OPAL_SUCCESS != ret) {
|
||||
return OPAL_ERROR;
|
||||
}
|
||||
|
||||
ret = group_find_by_name(full_name, &index, invalidok);
|
||||
free (full_name);
|
||||
|
||||
return (0 > ret) ? ret : index;
|
||||
}
|
||||
|
||||
static int group_register (const char *project_name, const char *framework_name,
|
||||
const char *component_name, const char *description)
|
||||
{
|
||||
mca_base_var_group_t *group;
|
||||
int group_id, parent_id = -1;
|
||||
int ret;
|
||||
|
||||
if (NULL == project_name && NULL == framework_name && NULL == component_name) {
|
||||
/* don't create a group with no name (maybe we should create a generic group?) */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* XXX -- remove this once the project name is available in the component structure */
|
||||
if (framework_name || component_name) {
|
||||
project_name = NULL;
|
||||
}
|
||||
|
||||
group_id = group_find (project_name, framework_name, component_name, true);
|
||||
if (0 <= group_id) {
|
||||
(void) mca_base_var_group_get_internal (group_id, &group, true);
|
||||
group->group_isvalid = true;
|
||||
mca_base_var_groups_timestamp++;
|
||||
|
||||
/* group already exists. return it's index */
|
||||
return group_id;
|
||||
}
|
||||
|
||||
group = OBJ_NEW(mca_base_var_group_t);
|
||||
|
||||
group->group_isvalid = true;
|
||||
|
||||
if (NULL != project_name) {
|
||||
group->group_project = strdup (project_name);
|
||||
if (NULL == group->group_project) {
|
||||
OBJ_RELEASE(group);
|
||||
return OPAL_ERR_OUT_OF_RESOURCE;
|
||||
}
|
||||
}
|
||||
if (NULL != framework_name) {
|
||||
group->group_framework = strdup (framework_name);
|
||||
if (NULL == group->group_framework) {
|
||||
OBJ_RELEASE(group);
|
||||
return OPAL_ERR_OUT_OF_RESOURCE;
|
||||
}
|
||||
}
|
||||
if (NULL != component_name) {
|
||||
group->group_component = strdup (component_name);
|
||||
if (NULL == group->group_component) {
|
||||
OBJ_RELEASE(group);
|
||||
return OPAL_ERR_OUT_OF_RESOURCE;
|
||||
}
|
||||
}
|
||||
if (NULL != description) {
|
||||
group->group_description = strdup (description);
|
||||
if (NULL == group->group_description) {
|
||||
OBJ_RELEASE(group);
|
||||
return OPAL_ERR_OUT_OF_RESOURCE;
|
||||
}
|
||||
}
|
||||
|
||||
if (NULL != framework_name && NULL != component_name) {
|
||||
if (component_name) {
|
||||
parent_id = group_register (project_name, framework_name, NULL, NULL);
|
||||
} else if (framework_name && project_name) {
|
||||
parent_id = group_register (project_name, NULL, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/* avoid groups of the form opal_opal, ompi_ompi, etc */
|
||||
if (NULL != project_name && NULL != framework_name &&
|
||||
(0 == strcmp (project_name, framework_name))) {
|
||||
project_name = NULL;
|
||||
}
|
||||
|
||||
/* build the group name */
|
||||
ret = mca_base_var_generate_full_name4 (NULL, project_name, framework_name, component_name,
|
||||
&group->group_full_name);
|
||||
if (OPAL_SUCCESS != ret) {
|
||||
OBJ_RELEASE(group);
|
||||
return ret;
|
||||
}
|
||||
|
||||
group_id = opal_pointer_array_add (&mca_base_var_groups, group);
|
||||
if (0 > group_id) {
|
||||
OBJ_RELEASE(group);
|
||||
return OPAL_ERROR;
|
||||
}
|
||||
|
||||
opal_hash_table_set_value_ptr (&mca_base_var_group_index_hash, group->group_full_name,
|
||||
strlen (group->group_full_name), (void *)(uintptr_t) group_id);
|
||||
|
||||
mca_base_var_group_count++;
|
||||
mca_base_var_groups_timestamp++;
|
||||
|
||||
if (0 <= parent_id) {
|
||||
mca_base_var_group_t *parent_group;
|
||||
|
||||
(void) mca_base_var_group_get_internal(parent_id, &parent_group, false);
|
||||
opal_value_array_append_item (&parent_group->group_subgroups, &group_id);
|
||||
}
|
||||
|
||||
return group_id;
|
||||
}
|
||||
|
||||
int mca_base_var_group_register (const char *project_name, const char *framework_name,
|
||||
const char *component_name, const char *description)
|
||||
{
|
||||
return group_register (project_name, framework_name, component_name, description);
|
||||
}
|
||||
|
||||
int mca_base_var_group_component_register (const mca_base_component_t *component,
|
||||
const char *description)
|
||||
{
|
||||
/* 1.7 components do not store the project */
|
||||
return group_register (NULL, component->mca_type_name,
|
||||
component->mca_component_name, description);
|
||||
}
|
||||
|
||||
|
||||
int mca_base_var_group_deregister (int group_index)
|
||||
{
|
||||
mca_base_var_group_t *group;
|
||||
int size, i, ret;
|
||||
int *params, *subgroups;
|
||||
|
||||
ret = mca_base_var_group_get_internal (group_index, &group, false);
|
||||
if (OPAL_SUCCESS != ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
group->group_isvalid = false;
|
||||
|
||||
/* deregister all associated mca parameters */
|
||||
size = opal_value_array_get_size(&group->group_vars);
|
||||
params = OPAL_VALUE_ARRAY_GET_BASE(&group->group_vars, int);
|
||||
|
||||
for (i = 0 ; i < size ; ++i) {
|
||||
const mca_base_var_t *var;
|
||||
|
||||
ret = mca_base_var_get (params[i], &var);
|
||||
if (OPAL_SUCCESS != ret || !(var->mbv_flags & MCA_BASE_VAR_FLAG_DWG)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
(void) mca_base_var_deregister (params[i]);
|
||||
}
|
||||
OBJ_DESTRUCT(&group->group_vars);
|
||||
OBJ_CONSTRUCT(&group->group_vars, opal_value_array_t);
|
||||
|
||||
/* invalidate all associated mca performance variables */
|
||||
size = opal_value_array_get_size(&group->group_pvars);
|
||||
params = OPAL_VALUE_ARRAY_GET_BASE(&group->group_pvars, int);
|
||||
|
||||
for (i = 0 ; i < size ; ++i) {
|
||||
const mca_base_pvar_t *var;
|
||||
|
||||
ret = mca_base_pvar_get (params[i], &var);
|
||||
if (OPAL_SUCCESS != ret || !(var->flags & MCA_BASE_PVAR_FLAG_IWG)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
(void) mca_base_pvar_mark_invalid (params[i]);
|
||||
}
|
||||
OBJ_DESTRUCT(&group->group_pvars);
|
||||
OBJ_CONSTRUCT(&group->group_pvars, opal_value_array_t);
|
||||
|
||||
size = opal_value_array_get_size(&group->group_subgroups);
|
||||
subgroups = OPAL_VALUE_ARRAY_GET_BASE(&group->group_subgroups, int);
|
||||
for (i = 0 ; i < size ; ++i) {
|
||||
(void) mca_base_var_group_deregister (subgroups[i]);
|
||||
}
|
||||
OBJ_DESTRUCT(&group->group_subgroups);
|
||||
OBJ_CONSTRUCT(&group->group_subgroups, opal_value_array_t);
|
||||
|
||||
mca_base_var_groups_timestamp++;
|
||||
|
||||
return OPAL_SUCCESS;
|
||||
}
|
||||
|
||||
int mca_base_var_group_find (const char *project_name,
|
||||
const char *framework_name,
|
||||
const char *component_name)
|
||||
{
|
||||
return group_find (project_name, framework_name, component_name, false);
|
||||
}
|
||||
|
||||
int mca_base_var_group_find_by_name (const char *full_name, int *index)
|
||||
{
|
||||
return group_find_by_name (full_name, index, false);
|
||||
}
|
||||
|
||||
int mca_base_var_group_add_var (const int group_index, const int param_index)
|
||||
{
|
||||
mca_base_var_group_t *group;
|
||||
int size, i, ret;
|
||||
int *params;
|
||||
|
||||
ret = mca_base_var_group_get_internal (group_index, &group, false);
|
||||
if (OPAL_SUCCESS != ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
size = opal_value_array_get_size(&group->group_vars);
|
||||
params = OPAL_VALUE_ARRAY_GET_BASE(&group->group_vars, int);
|
||||
for (i = 0 ; i < size ; ++i) {
|
||||
if (params[i] == param_index) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
if (OPAL_SUCCESS !=
|
||||
(ret = opal_value_array_append_item (&group->group_vars, ¶m_index))) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
mca_base_var_groups_timestamp++;
|
||||
|
||||
/* return the group index */
|
||||
return (int) opal_value_array_get_size (&group->group_vars) - 1;
|
||||
}
|
||||
|
||||
int mca_base_var_group_add_pvar (const int group_index, const int param_index)
|
||||
{
|
||||
mca_base_var_group_t *group;
|
||||
int size, i, ret;
|
||||
int *params;
|
||||
|
||||
ret = mca_base_var_group_get_internal (group_index, &group, false);
|
||||
if (OPAL_SUCCESS != ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
size = opal_value_array_get_size(&group->group_pvars);
|
||||
params = OPAL_VALUE_ARRAY_GET_BASE(&group->group_pvars, int);
|
||||
for (i = 0 ; i < size ; ++i) {
|
||||
if (params[i] == param_index) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
if (OPAL_SUCCESS !=
|
||||
(ret = opal_value_array_append_item (&group->group_pvars, ¶m_index))) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
mca_base_var_groups_timestamp++;
|
||||
|
||||
/* return the group index */
|
||||
return (int) opal_value_array_get_size (&group->group_pvars) - 1;
|
||||
}
|
||||
|
||||
int mca_base_var_group_get (const int group_index, const mca_base_var_group_t **group)
|
||||
{
|
||||
return mca_base_var_group_get_internal (group_index, (mca_base_var_group_t **) group, false);
|
||||
}
|
||||
|
||||
int mca_base_var_group_set_var_flag (const int group_index, int flags, bool set)
|
||||
{
|
||||
mca_base_var_group_t *group;
|
||||
int size, i, ret;
|
||||
int *vars;
|
||||
|
||||
ret = mca_base_var_group_get_internal (group_index, &group, false);
|
||||
if (OPAL_SUCCESS != ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* set the flag on each valid variable */
|
||||
size = opal_value_array_get_size(&group->group_vars);
|
||||
vars = OPAL_VALUE_ARRAY_GET_BASE(&group->group_vars, int);
|
||||
|
||||
for (i = 0 ; i < size ; ++i) {
|
||||
if (0 <= vars[i]) {
|
||||
(void) mca_base_var_set_flag (vars[i], flags, set);
|
||||
}
|
||||
}
|
||||
|
||||
return OPAL_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static void mca_base_var_group_constructor (mca_base_var_group_t *group)
|
||||
{
|
||||
memset ((char *) group + sizeof (group->super), 0, sizeof (*group) - sizeof (group->super));
|
||||
|
||||
OBJ_CONSTRUCT(&group->group_subgroups, opal_value_array_t);
|
||||
opal_value_array_init (&group->group_subgroups, sizeof (int));
|
||||
|
||||
OBJ_CONSTRUCT(&group->group_vars, opal_value_array_t);
|
||||
opal_value_array_init (&group->group_vars, sizeof (int));
|
||||
|
||||
OBJ_CONSTRUCT(&group->group_pvars, opal_value_array_t);
|
||||
opal_value_array_init (&group->group_pvars, sizeof (int));
|
||||
}
|
||||
|
||||
static void mca_base_var_group_destructor (mca_base_var_group_t *group)
|
||||
{
|
||||
free (group->group_full_name);
|
||||
group->group_full_name = NULL;
|
||||
|
||||
free (group->group_description);
|
||||
group->group_description = NULL;
|
||||
|
||||
free (group->group_project);
|
||||
group->group_project = NULL;
|
||||
|
||||
free (group->group_framework);
|
||||
group->group_framework = NULL;
|
||||
|
||||
free (group->group_component);
|
||||
group->group_component = NULL;
|
||||
|
||||
OBJ_DESTRUCT(&group->group_subgroups);
|
||||
OBJ_DESTRUCT(&group->group_vars);
|
||||
OBJ_DESTRUCT(&group->group_pvars);
|
||||
}
|
||||
|
||||
int mca_base_var_group_get_count (void)
|
||||
{
|
||||
return mca_base_var_group_count;
|
||||
}
|
||||
|
||||
int mca_base_var_group_get_stamp (void)
|
||||
{
|
||||
return mca_base_var_groups_timestamp;
|
||||
}
|
174
opal/mca/base/mca_base_var_group.h
Обычный файл
174
opal/mca/base/mca_base_var_group.h
Обычный файл
@ -0,0 +1,174 @@
|
||||
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana
|
||||
* University Research and Technology
|
||||
* Corporation. All rights reserved.
|
||||
* Copyright (c) 2004-2006 The University of Tennessee and The University
|
||||
* of Tennessee Research Foundation. All rights
|
||||
* reserved.
|
||||
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
* University of Stuttgart. All rights reserved.
|
||||
* Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 2008-2011 Cisco Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2012-2013 Los Alamos National Security, LLC. All rights
|
||||
* reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
*
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
#ifndef OPAL_MCA_BASE_VAR_GROUP_H
|
||||
#define OPAL_MCA_BASE_VAR_GROUP_H
|
||||
|
||||
#include "opal/mca/mca.h"
|
||||
|
||||
struct mca_base_var_group_t {
|
||||
opal_list_item_t super;
|
||||
|
||||
/** Index of group */
|
||||
int group_index;
|
||||
|
||||
/** Group is valid (registered) */
|
||||
bool group_isvalid;
|
||||
|
||||
/** Group name */
|
||||
char *group_full_name;
|
||||
|
||||
char *group_project;
|
||||
char *group_framework;
|
||||
char *group_component;
|
||||
|
||||
/** Group help message (description) */
|
||||
char *group_description;
|
||||
|
||||
/** Integer value array of subgroup indices */
|
||||
opal_value_array_t group_subgroups;
|
||||
|
||||
/** Integer array of group variables */
|
||||
opal_value_array_t group_vars;
|
||||
|
||||
/** Integer array of group performance variables */
|
||||
opal_value_array_t group_pvars;
|
||||
};
|
||||
|
||||
typedef struct mca_base_var_group_t mca_base_var_group_t;
|
||||
|
||||
/**
|
||||
* Object declaration for mca_base_var_group_t
|
||||
*/
|
||||
OPAL_DECLSPEC OBJ_CLASS_DECLARATION(mca_base_var_group_t);
|
||||
|
||||
/**
|
||||
* Register an MCA variable group
|
||||
*
|
||||
* @param[in] project_name Project name for this group.
|
||||
* @param[in] framework_name Framework name for this group.
|
||||
* @param[in] component_name Component name for this group.
|
||||
* @param[in] descrition Description of this group.
|
||||
*
|
||||
* @retval index Unique group index
|
||||
* @return opal error code on Error
|
||||
*
|
||||
* Create an MCA variable group. If the group already exists
|
||||
* this call is equivalent to mca_base_ver_find_group().
|
||||
*/
|
||||
OPAL_DECLSPEC int mca_base_var_group_register(const char *project_name,
|
||||
const char *framework_name,
|
||||
const char *component_name,
|
||||
const char *description);
|
||||
|
||||
/**
|
||||
* Register an MCA variable group for a component
|
||||
*
|
||||
* @param[in] component [in] Pointer to the component for which the
|
||||
* group is being registered.
|
||||
* @param[in] description Description of this group.
|
||||
*
|
||||
* @retval index Unique group index
|
||||
* @return opal error code on Error
|
||||
*/
|
||||
OPAL_DECLSPEC int mca_base_var_group_component_register (const mca_base_component_t *component,
|
||||
const char *description);
|
||||
|
||||
/**
|
||||
* Deregister an MCA param group
|
||||
*
|
||||
* @param group_index [in] Group index from mca_base_var_group_register (),
|
||||
* mca_base_var_group_find().
|
||||
*
|
||||
* This call deregisters all associated variables and subgroups.
|
||||
*/
|
||||
OPAL_DECLSPEC int mca_base_var_group_deregister (int group_index);
|
||||
|
||||
/**
|
||||
* Find an MCA group
|
||||
*
|
||||
* @param[in] project_name Project name
|
||||
* @param[in] framework_name Framework name
|
||||
* @param[in] component_name Component name
|
||||
*
|
||||
* @returns OPAL_SUCCESS if found
|
||||
* @returns OPAL_ERR_NOT_FOUND if not found
|
||||
*/
|
||||
OPAL_DECLSPEC int mca_base_var_group_find (const char *project_name,
|
||||
const char *framework_name,
|
||||
const char *component_name);
|
||||
|
||||
/**
|
||||
* Find an MCA group by its full name
|
||||
*
|
||||
* @param[in] full_name Full name of MCA variable group. Ex: shmem_mmap
|
||||
* @param[out] index Index of group if found
|
||||
*
|
||||
* @returns OPAL_SUCCESS if found
|
||||
* @returns OPAL_ERR_NOT_FOUND if not found
|
||||
*/
|
||||
OPAL_DECLSPEC int mca_base_var_group_find_by_name (const char *full_name, int *index);
|
||||
|
||||
/**
|
||||
* Get the group at a specified index
|
||||
*
|
||||
* @param[in] group_index Group index
|
||||
* @param[out] group Storage for the group object pointer.
|
||||
*
|
||||
* @retval OPAL_ERR_NOT_FOUND If the group specified by group_index does not exist.
|
||||
* @retval OPAL_SUCCESS If the group is found
|
||||
*
|
||||
* The returned pointer belongs to the MCA variable system. Do not modify/release/retain
|
||||
* the pointer.
|
||||
*/
|
||||
OPAL_DECLSPEC int mca_base_var_group_get (const int group_index,
|
||||
const mca_base_var_group_t **group);
|
||||
|
||||
/**
|
||||
* Set/unset a flags for all variables in a group.
|
||||
*
|
||||
* @param[in] group_index Index of group
|
||||
* @param[in] flag Flag(s) to set or unset.
|
||||
* @param[in] set Boolean indicating whether to set flag(s).
|
||||
*
|
||||
* Set a flag for every variable in a group. See mca_base_var_set_flag() for more info.
|
||||
*/
|
||||
OPAL_DECLSPEC int mca_base_var_group_set_var_flag (const int group_index, int flags,
|
||||
bool set);
|
||||
|
||||
/**
|
||||
* Get the number of registered MCA groups
|
||||
*
|
||||
* @retval count Number of registered MCA groups
|
||||
*/
|
||||
OPAL_DECLSPEC int mca_base_var_group_get_count (void);
|
||||
|
||||
/**
|
||||
* Get a relative timestamp for the MCA group system
|
||||
*
|
||||
* @retval stamp
|
||||
*
|
||||
* This value will change if groups or variables are either added or removed.
|
||||
*/
|
||||
OPAL_DECLSPEC int mca_base_var_group_get_stamp (void);
|
||||
|
||||
#endif /* OPAL_MCA_BASE_VAR_GROUP_H */
|
@ -11,7 +11,7 @@
|
||||
* Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 2008 Cisco Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2012 Los Alamos National Security, LLC. All rights
|
||||
* Copyright (c) 2012-2013 Los Alamos National Security, LLC. All rights
|
||||
* reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
@ -23,8 +23,8 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* This is the private declarations for the MCA parameter system.
|
||||
* This file is internal to the MCA parameter system and should not
|
||||
* This is the private declarations for the MCA variable system.
|
||||
* This file is internal to the MCA variable system and should not
|
||||
* need to be used by any other elements in Open MPI except the
|
||||
* special case of the ompi_info command.
|
||||
*
|
||||
@ -41,7 +41,10 @@
|
||||
#include "opal/class/opal_object.h"
|
||||
#include "opal/class/opal_list.h"
|
||||
#include "opal/class/opal_value_array.h"
|
||||
#include "opal/class/opal_pointer_array.h"
|
||||
#include "opal/class/opal_hash_table.h"
|
||||
#include "opal/mca/base/mca_base_var.h"
|
||||
#include "opal/mca/base/mca_base_pvar.h"
|
||||
|
||||
BEGIN_C_DECLS
|
||||
|
||||
@ -66,6 +69,9 @@ typedef enum {
|
||||
#define VAR_IS_SETTABLE(var) (!!((var).mbv_flags & MCA_BASE_VAR_FLAG_SETTABLE))
|
||||
#define VAR_IS_DEPRECATED(var) (!!((var).mbv_flags & MCA_BASE_VAR_FLAG_DEPRECATED))
|
||||
|
||||
extern const char *var_type_names[];
|
||||
extern const size_t var_type_sizes[];
|
||||
extern bool mca_base_var_initialized;
|
||||
|
||||
/**
|
||||
* \internal
|
||||
@ -83,6 +89,7 @@ struct mca_base_var_file_value_t {
|
||||
/** File it came from */
|
||||
char *mbvfv_file;
|
||||
};
|
||||
|
||||
/**
|
||||
* \internal
|
||||
*
|
||||
@ -95,6 +102,16 @@ typedef struct mca_base_var_file_value_t mca_base_var_file_value_t;
|
||||
*/
|
||||
OPAL_DECLSPEC OBJ_CLASS_DECLARATION(mca_base_var_file_value_t);
|
||||
|
||||
/**
|
||||
* \internal
|
||||
*
|
||||
* Get a group
|
||||
*
|
||||
* @param[in] group_index Group index
|
||||
* @param[out] group Returned group if it exists
|
||||
* @param[in] invalidok Return group even if it has been deregistered
|
||||
*/
|
||||
OPAL_DECLSPEC int mca_base_var_group_get_internal (const int group_index, mca_base_var_group_t **group, bool invalidok);
|
||||
|
||||
/**
|
||||
* \internal
|
||||
@ -103,6 +120,45 @@ OPAL_DECLSPEC OBJ_CLASS_DECLARATION(mca_base_var_file_value_t);
|
||||
*/
|
||||
OPAL_DECLSPEC int mca_base_parse_paramfile(const char *paramfile, opal_list_t *list);
|
||||
|
||||
/**
|
||||
* \internal
|
||||
*
|
||||
* Add a variable to a group
|
||||
*/
|
||||
OPAL_DECLSPEC int mca_base_var_group_add_var (const int group_index, const int param_index);
|
||||
|
||||
/**
|
||||
* \internal
|
||||
*
|
||||
* Add a performance variable to a group
|
||||
*/
|
||||
OPAL_DECLSPEC int mca_base_var_group_add_pvar (const int group_index, const int param_index);
|
||||
|
||||
/**
|
||||
* \internal
|
||||
*
|
||||
* Generate a full name with _ between all of the non-NULL arguments
|
||||
*/
|
||||
OPAL_DECLSPEC int mca_base_var_generate_full_name4 (const char *project, const char *framework,
|
||||
const char *component, const char *variable,
|
||||
char **full_name);
|
||||
|
||||
/**
|
||||
* \internal
|
||||
*
|
||||
* Initialize/finalize MCA variable groups
|
||||
*/
|
||||
OPAL_DECLSPEC int mca_base_var_group_init (void);
|
||||
OPAL_DECLSPEC int mca_base_var_group_finalize (void);
|
||||
|
||||
/**
|
||||
* \internal
|
||||
*
|
||||
* Initialize MCA performance variables
|
||||
*/
|
||||
OPAL_DECLSPEC int mca_base_pvar_init (void);
|
||||
OPAL_DECLSPEC int mca_base_pvar_finalize (void);
|
||||
|
||||
END_C_DECLS
|
||||
|
||||
#endif /* OPAL_MCA_BASE_VAR_INTERNAL_H */
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include "opal/util/show_help.h"
|
||||
#include "opal/runtime/opal.h"
|
||||
#include "opal/dss/dss.h"
|
||||
#include "opal/mca/base/mca_base_pvar.h"
|
||||
|
||||
#include "opal/include/opal/frameworks.h"
|
||||
|
||||
@ -554,6 +555,30 @@ static void opal_info_show_mca_group_params(const mca_base_var_group_t *group, m
|
||||
free(strings);
|
||||
}
|
||||
|
||||
variables = OPAL_VALUE_ARRAY_GET_BASE(&group->group_pvars, const int);
|
||||
count = opal_value_array_get_size((opal_value_array_t *)&group->group_pvars);
|
||||
|
||||
for (i = 0 ; i < count ; ++i) {
|
||||
ret = mca_base_pvar_dump (variables[i], &strings, !opal_info_pretty ? MCA_BASE_VAR_DUMP_PARSABLE : MCA_BASE_VAR_DUMP_READABLE);
|
||||
if (OPAL_SUCCESS != ret) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (j = 0 ; strings[j] ; ++j) {
|
||||
if (0 == j && opal_info_pretty) {
|
||||
char *message;
|
||||
|
||||
asprintf (&message, "MCA %s", group->group_framework);
|
||||
opal_info_out(message, message, strings[j]);
|
||||
free(message);
|
||||
} else {
|
||||
opal_info_out("", "", strings[j]);
|
||||
}
|
||||
free(strings[j]);
|
||||
}
|
||||
free(strings);
|
||||
}
|
||||
|
||||
groups = OPAL_VALUE_ARRAY_GET_BASE(&group->group_subgroups, const int);
|
||||
count = opal_value_array_get_size((opal_value_array_t *)&group->group_subgroups);
|
||||
|
||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user