1
1

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.
Этот коммит содержится в:
Nathan Hjelm 2013-07-16 16:02:13 +00:00
родитель 5f520e241b
Коммит d446675526
32 изменённых файлов: 2872 добавлений и 814 удалений

Просмотреть файл

@ -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 Обычный файл
Просмотреть файл

@ -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(&registered_pvars, opal_pointer_array_t);
opal_pointer_array_init(&registered_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(&registered_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 (&registered_pvars, i);
if (pvar) {
OBJ_RELEASE(pvar);
}
}
OBJ_DESTRUCT(&registered_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 (&registered_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 (&registered_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 Обычный файл
Просмотреть файл

@ -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 Обычный файл
Просмотреть файл

@ -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, &param_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, &param_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 Обычный файл
Просмотреть файл

@ -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);