2013-07-16 20:02:13 +04:00
|
|
|
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
|
|
|
|
/*
|
2017-07-17 23:06:33 +03:00
|
|
|
* Copyright (c) 2013-2017 Los Alamos National Security, LLC. All rights
|
2013-07-16 20:02:13 +04:00
|
|
|
* reserved.
|
2015-07-25 22:32:00 +03:00
|
|
|
* Copyright (c) 2015 Cisco Systems, Inc. All rights reserved.
|
2015-05-06 18:50:08 +03:00
|
|
|
* Copyright (c) 2015 Bull SAS. All rights reserved.
|
2015-07-25 22:32:00 +03:00
|
|
|
* Copyright (c) 2015 The University of Tennessee and The University
|
|
|
|
* of Tennessee Research Foundation. All rights
|
|
|
|
* reserved.
|
2017-06-30 04:18:46 +03:00
|
|
|
* Copyright (c) 2017 IBM Corporation. All rights reserved.
|
2013-07-16 20:02:13 +04:00
|
|
|
* $COPYRIGHT$
|
|
|
|
*
|
|
|
|
* Additional copyrights may follow
|
|
|
|
*
|
|
|
|
* $HEADER$
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "opal/mca/base/mca_base_pvar.h"
|
|
|
|
#include "opal/mca/base/mca_base_vari.h"
|
|
|
|
|
|
|
|
#include <stddef.h>
|
|
|
|
#include <sys/time.h>
|
|
|
|
#include <sys/resource.h>
|
|
|
|
|
|
|
|
#include "opal/class/opal_pointer_array.h"
|
|
|
|
#include "opal/class/opal_hash_table.h"
|
|
|
|
|
|
|
|
static opal_hash_table_t mca_base_pvar_index_hash;
|
|
|
|
static opal_pointer_array_t registered_pvars;
|
|
|
|
static bool mca_base_pvar_initialized = false;
|
|
|
|
static int pvar_count = 0;
|
|
|
|
|
|
|
|
#define min(a,b) ((a) < (b) ? (a) : (b))
|
|
|
|
#define max(a,b) ((a) > (b) ? (a) : (b))
|
|
|
|
|
|
|
|
static int mca_base_pvar_get_internal (int index, mca_base_pvar_t **pvar, bool invalidok);
|
|
|
|
|
|
|
|
/* string representations of class names */
|
|
|
|
static const char *pvar_class_names[] = {
|
|
|
|
"state",
|
|
|
|
"level",
|
|
|
|
"size",
|
|
|
|
"percentage",
|
|
|
|
"high watermark",
|
|
|
|
"low watermark",
|
|
|
|
"counter",
|
|
|
|
"aggregate",
|
|
|
|
"timer",
|
|
|
|
"generic"
|
|
|
|
};
|
|
|
|
|
|
|
|
int mca_base_pvar_init (void)
|
|
|
|
{
|
|
|
|
int ret = OPAL_SUCCESS;
|
|
|
|
|
|
|
|
if (!mca_base_pvar_initialized) {
|
|
|
|
mca_base_pvar_initialized = true;
|
|
|
|
|
|
|
|
OBJ_CONSTRUCT(®istered_pvars, opal_pointer_array_t);
|
|
|
|
opal_pointer_array_init(®istered_pvars, 128, 2048, 128);
|
|
|
|
|
|
|
|
OBJ_CONSTRUCT(&mca_base_pvar_index_hash, opal_hash_table_t);
|
|
|
|
ret = opal_hash_table_init (&mca_base_pvar_index_hash, 1024);
|
|
|
|
if (OPAL_SUCCESS != ret) {
|
|
|
|
mca_base_pvar_initialized = false;
|
|
|
|
OBJ_DESTRUCT(®istered_pvars);
|
|
|
|
OBJ_DESTRUCT(&mca_base_pvar_index_hash);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
int mca_base_pvar_find (const char *project, const char *framework, const char *component, const char *name)
|
|
|
|
{
|
|
|
|
char *full_name;
|
|
|
|
int ret, index;
|
|
|
|
|
|
|
|
ret = mca_base_var_generate_full_name4 (NULL, framework, component, name, &full_name);
|
|
|
|
if (OPAL_SUCCESS != ret) {
|
|
|
|
return OPAL_ERROR;
|
|
|
|
}
|
|
|
|
|
2015-06-25 01:05:34 +03:00
|
|
|
ret = mca_base_pvar_find_by_name (full_name, MCA_BASE_PVAR_CLASS_ANY, &index);
|
2013-07-16 20:02:13 +04:00
|
|
|
free (full_name);
|
|
|
|
|
|
|
|
/* NTH: should we verify the name components match the returned variable? */
|
|
|
|
|
|
|
|
return (OPAL_SUCCESS != ret) ? ret : index;
|
|
|
|
}
|
|
|
|
|
2015-06-25 01:05:34 +03:00
|
|
|
int mca_base_pvar_find_by_name (const char *full_name, int var_class, int *index)
|
2013-07-16 20:02:13 +04:00
|
|
|
{
|
2015-06-25 01:05:34 +03:00
|
|
|
mca_base_pvar_t *pvar;
|
2013-07-16 20:02:13 +04:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2015-06-25 01:05:34 +03:00
|
|
|
rc = mca_base_pvar_get_internal ((int)(uintptr_t) tmp, &pvar, false);
|
|
|
|
if (OPAL_SUCCESS != rc) {
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (MCA_BASE_PVAR_CLASS_ANY != var_class && pvar->var_class != var_class) {
|
|
|
|
return OPAL_ERR_NOT_FOUND;
|
|
|
|
}
|
|
|
|
|
2013-07-16 20:02:13 +04:00
|
|
|
*index = (int)(uintptr_t) tmp;
|
|
|
|
|
|
|
|
return OPAL_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
int mca_base_pvar_finalize (void)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (mca_base_pvar_initialized) {
|
|
|
|
mca_base_pvar_initialized = false;
|
|
|
|
|
|
|
|
for (i = 0 ; i < pvar_count ; ++i) {
|
|
|
|
mca_base_pvar_t *pvar = opal_pointer_array_get_item (®istered_pvars, i);
|
|
|
|
if (pvar) {
|
|
|
|
OBJ_RELEASE(pvar);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-07 23:42:35 +03:00
|
|
|
pvar_count = 0;
|
|
|
|
|
2013-07-16 20:02:13 +04:00
|
|
|
OBJ_DESTRUCT(®istered_pvars);
|
|
|
|
OBJ_DESTRUCT(&mca_base_pvar_index_hash);
|
|
|
|
}
|
|
|
|
|
|
|
|
return OPAL_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
int mca_base_pvar_get_count (int *count)
|
|
|
|
{
|
|
|
|
*count = pvar_count;
|
|
|
|
return OPAL_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int mca_base_pvar_default_get_value (const mca_base_pvar_t *pvar, void *value, void *obj_handle)
|
|
|
|
{
|
|
|
|
/* not used */
|
|
|
|
(void) obj_handle;
|
|
|
|
|
2017-06-30 04:18:46 +03:00
|
|
|
memmove (value, pvar->ctx, ompi_var_type_sizes[pvar->type]);
|
2013-07-16 20:02:13 +04:00
|
|
|
|
|
|
|
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;
|
|
|
|
|
2017-06-30 04:18:46 +03:00
|
|
|
memmove (pvar->ctx, value, ompi_var_type_sizes[pvar->type]);
|
2013-07-16 20:02:13 +04:00
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
2016-11-15 14:37:52 +03:00
|
|
|
int ret, group_index, pvar_index;
|
2013-07-16 20:02:13 +04:00
|
|
|
mca_base_pvar_t *pvar;
|
|
|
|
|
|
|
|
/* assert on usage errors */
|
|
|
|
if (!get_value && !ctx) {
|
|
|
|
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) {
|
|
|
|
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) {
|
|
|
|
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) {
|
|
|
|
return OPAL_ERR_BAD_PARAM;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case MCA_BASE_PVAR_CLASS_PERCENTAGE:
|
|
|
|
/* percentages must be doubles */
|
|
|
|
if (MCA_BASE_VAR_TYPE_DOUBLE != type) {
|
|
|
|
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:
|
2017-11-03 08:20:34 +03:00
|
|
|
return OPAL_ERR_BAD_PARAM;
|
2013-07-16 20:02:13 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/* 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 */
|
|
|
|
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 */
|
2015-05-21 22:33:31 +03:00
|
|
|
ret = mca_base_var_generate_full_name4 (NULL, framework, component, name, &pvar->name);
|
|
|
|
if (OPAL_SUCCESS != ret) {
|
2013-07-16 20:02:13 +04:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-15 14:37:52 +03:00
|
|
|
pvar_index = opal_pointer_array_add (®istered_pvars, pvar);
|
|
|
|
if (0 > pvar_index) {
|
2013-07-16 20:02:13 +04:00
|
|
|
break;
|
|
|
|
}
|
2016-11-15 14:37:52 +03:00
|
|
|
pvar->pvar_index = pvar_index;
|
2013-07-16 20:02:13 +04:00
|
|
|
|
2016-11-15 14:37:52 +03:00
|
|
|
/* add this performance variable to the MCA variable group */
|
|
|
|
if (0 <= group_index) {
|
|
|
|
ret = mca_base_var_group_add_pvar (group_index, pvar_index);
|
|
|
|
if (0 > ret) {
|
|
|
|
break;
|
|
|
|
}
|
2013-07-16 20:02:13 +04:00
|
|
|
}
|
|
|
|
|
2015-07-25 22:32:00 +03:00
|
|
|
pvar->pvar_index = pvar_count;
|
2013-07-16 20:02:13 +04:00
|
|
|
opal_hash_table_set_value_ptr (&mca_base_pvar_index_hash, pvar->name, strlen (pvar->name),
|
2015-07-25 22:32:00 +03:00
|
|
|
(void *)(uintptr_t) pvar->pvar_index);
|
2013-07-16 20:02:13 +04:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
2015-06-24 06:59:57 +03:00
|
|
|
|
2013-07-16 20:02:13 +04:00
|
|
|
pvar->ctx = ctx;
|
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
/* invalidate this variable if the component's group is deregistered */
|
2017-07-17 23:06:33 +03:00
|
|
|
return mca_base_pvar_register(component->mca_project_name, component->mca_type_name, component->mca_component_name,
|
2013-07-16 20:02:13 +04:00
|
|
|
name, description, verbosity, var_class, type, enumerator, bind,
|
|
|
|
flags | MCA_BASE_PVAR_FLAG_IWG, get_value, set_value, notify, ctx);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int mca_base_pvar_get_internal (int index, mca_base_pvar_t **pvar, bool invalidok)
|
|
|
|
{
|
|
|
|
if (index >= pvar_count) {
|
|
|
|
return OPAL_ERR_VALUE_OUT_OF_BOUNDS;
|
|
|
|
}
|
|
|
|
|
|
|
|
*pvar = opal_pointer_array_get_item (®istered_pvars, index);
|
|
|
|
|
|
|
|
/* variables should never be removed per MPI 3.0 § 14.3.7 */
|
|
|
|
assert (*pvar);
|
|
|
|
|
|
|
|
if (((*pvar)->flags & MCA_BASE_PVAR_FLAG_INVALID) && !invalidok) {
|
|
|
|
*pvar = NULL;
|
|
|
|
return OPAL_ERR_VALUE_OUT_OF_BOUNDS;
|
|
|
|
}
|
|
|
|
|
|
|
|
return OPAL_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
int mca_base_pvar_get (int index, const mca_base_pvar_t **pvar)
|
|
|
|
{
|
|
|
|
return mca_base_pvar_get_internal (index, (mca_base_pvar_t **) pvar, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
int mca_base_pvar_mark_invalid (int index)
|
|
|
|
{
|
|
|
|
mca_base_pvar_t *pvar;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = mca_base_pvar_get_internal (index, &pvar, false);
|
|
|
|
if (OPAL_SUCCESS != ret) {
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
pvar->flags |= MCA_BASE_PVAR_FLAG_INVALID;
|
|
|
|
|
|
|
|
return OPAL_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
int mca_base_pvar_notify (mca_base_pvar_handle_t *handle, mca_base_pvar_event_t event, int *count)
|
|
|
|
{
|
2013-10-24 23:27:06 +04:00
|
|
|
if (mca_base_pvar_is_invalid (handle->pvar)) {
|
|
|
|
return OPAL_ERR_NOT_BOUND;
|
|
|
|
}
|
|
|
|
|
2013-07-16 20:02:13 +04:00
|
|
|
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? */
|
2014-05-01 02:10:30 +04:00
|
|
|
ret = OPAL_ERR_BAD_PARAM;
|
2013-07-16 20:02:13 +04:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2017-11-03 08:20:34 +03:00
|
|
|
pvar_handle->obj_handle = (NULL == obj_handle ? NULL : *(void**)obj_handle);
|
2015-06-24 06:59:57 +03:00
|
|
|
pvar_handle->pvar = pvar;
|
2013-07-16 20:02:13 +04:00
|
|
|
|
|
|
|
*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. */
|
2017-06-30 04:18:46 +03:00
|
|
|
datatype_size = ompi_var_type_sizes[pvar->type];
|
2013-07-16 20:02:13 +04:00
|
|
|
if (0 == datatype_size) {
|
|
|
|
ret = OPAL_ERROR;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2013-10-23 19:47:15 +04:00
|
|
|
if (!mca_base_pvar_is_continuous (pvar) || mca_base_pvar_is_sum (pvar) ||
|
|
|
|
mca_base_pvar_is_watermark (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) {
|
2013-07-16 20:02:13 +04:00
|
|
|
ret = OPAL_ERR_OUT_OF_RESOURCE;
|
|
|
|
break;
|
|
|
|
}
|
2013-08-27 22:19:18 +04:00
|
|
|
}
|
2013-07-16 20:02:13 +04:00
|
|
|
|
2013-10-23 19:47:15 +04:00
|
|
|
if (mca_base_pvar_is_sum (pvar) || mca_base_pvar_is_watermark (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 */
|
2013-07-16 20:02:13 +04:00
|
|
|
pvar_handle->tmp_value = calloc (*count, datatype_size);
|
|
|
|
if (NULL == pvar_handle->tmp_value) {
|
|
|
|
ret = OPAL_ERR_OUT_OF_RESOURCE;
|
|
|
|
break;
|
|
|
|
}
|
2015-06-24 06:59:57 +03:00
|
|
|
|
2013-10-23 19:47:15 +04:00
|
|
|
pvar_handle->last_value = calloc (*count, datatype_size);
|
|
|
|
if (NULL == pvar_handle->last_value) {
|
2013-07-16 20:02:13 +04:00
|
|
|
ret = OPAL_ERR_OUT_OF_RESOURCE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2013-10-23 19:47:15 +04:00
|
|
|
/* get the current value of the performance variable if this is a
|
|
|
|
continuous sum or watermark. if this variable needs to be started first the
|
|
|
|
current value is not relevant. */
|
|
|
|
if (mca_base_pvar_is_continuous (pvar)) {
|
|
|
|
if (mca_base_pvar_is_sum (pvar)) {
|
|
|
|
ret = pvar->get_value (pvar, pvar_handle->last_value, pvar_handle->obj_handle);
|
|
|
|
} else {
|
|
|
|
/* the initial value of a watermark is the current value of the variable */
|
|
|
|
ret = pvar->get_value (pvar, pvar_handle->current_value, pvar_handle->obj_handle);
|
|
|
|
}
|
2013-08-27 22:19:18 +04:00
|
|
|
|
2013-10-23 19:47:15 +04:00
|
|
|
if (OPAL_SUCCESS != ret) {
|
|
|
|
return ret;
|
|
|
|
}
|
2013-08-27 22:19:18 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-07-16 20:02:13 +04:00
|
|
|
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)
|
|
|
|
{
|
|
|
|
OBJ_RELEASE(handle);
|
|
|
|
|
|
|
|
return OPAL_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
int mca_base_pvar_handle_update (mca_base_pvar_handle_t *handle)
|
|
|
|
{
|
|
|
|
int i, ret;
|
|
|
|
void *tmp;
|
|
|
|
|
2013-10-23 19:47:15 +04:00
|
|
|
if (mca_base_pvar_is_invalid (handle->pvar)) {
|
|
|
|
return OPAL_ERR_NOT_BOUND;
|
|
|
|
}
|
|
|
|
|
2013-07-16 20:02:13 +04:00
|
|
|
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;
|
|
|
|
|
2013-10-23 19:47:15 +04:00
|
|
|
if (mca_base_pvar_is_invalid (handle->pvar)) {
|
|
|
|
return OPAL_ERR_NOT_BOUND;
|
|
|
|
}
|
|
|
|
|
2013-07-16 20:02:13 +04:00
|
|
|
/* 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. */
|
2017-06-30 04:18:46 +03:00
|
|
|
memmove (value, handle->current_value, handle->count * ompi_var_type_sizes[handle->pvar->type]);
|
2013-07-16 20:02:13 +04:00
|
|
|
} 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;
|
|
|
|
|
2013-10-23 19:47:15 +04:00
|
|
|
if (mca_base_pvar_is_invalid (handle->pvar)) {
|
|
|
|
return OPAL_ERR_NOT_BOUND;
|
|
|
|
}
|
|
|
|
|
2013-07-16 20:02:13 +04:00
|
|
|
if (mca_base_pvar_is_readonly (handle->pvar)) {
|
|
|
|
return OPAL_ERR_PERM;
|
|
|
|
}
|
|
|
|
|
2015-09-20 13:28:01 +03:00
|
|
|
/* write the value directly from the variable. */
|
|
|
|
ret = handle->pvar->set_value (handle->pvar, value, handle->obj_handle);
|
2013-07-16 20:02:13 +04:00
|
|
|
|
|
|
|
ret = mca_base_pvar_handle_update (handle);
|
|
|
|
if (OPAL_SUCCESS != ret) {
|
|
|
|
return ret;
|
|
|
|
}
|
2015-06-24 06:59:57 +03:00
|
|
|
|
2017-06-30 04:18:46 +03:00
|
|
|
memmove (handle->current_value, value, handle->count * ompi_var_type_sizes[handle->pvar->type]);
|
Topic/monitoring (#3109)
Add a monitoring PML, OSC and IO. They track all data exchanges between processes,
with capability to include or exclude collective traffic. The monitoring infrastructure is
driven using MPI_T, and can be tuned of and on any time o any communicators/files/windows.
Documentations and examples have been added, as well as a shared library that can be
used with LD_PRELOAD and that allows the monitoring of any application.
Signed-off-by: George Bosilca <bosilca@icl.utk.edu>
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* add ability to querry pml monitorinting results with MPI Tools interface
using performance variables "pml_monitoring_messages_count" and
"pml_monitoring_messages_size"
Signed-off-by: George Bosilca <bosilca@icl.utk.edu>
* Fix a convertion problem and add a comment about the lack of component
retain in the new component infrastructure.
Signed-off-by: George Bosilca <bosilca@icl.utk.edu>
* Allow the pvar to be written by invoking the associated callback.
Signed-off-by: George Bosilca <bosilca@icl.utk.edu>
* Various fixes for the monitoring.
Allocate all counting arrays in a single allocation
Don't delay the initialization (do it at the first add_proc as we
know the number of processes in MPI_COMM_WORLD)
Add a choice: with or without MPI_T (default).
Signed-off-by: George Bosilca <bosilca@icl.utk.edu>
* Cleanup for the monitoring module.
Fixed few bugs, and reshape the operations to prepare for
global or communicator-based monitoring. Start integrating
support for MPI_T as well as MCA monitoring.
Signed-off-by: George Bosilca <bosilca@icl.utk.edu>
* Adding documentation about how to use pml_monitoring component.
Document present the use with and without MPI_T.
May not reflect exactly how it works right now, but should reflects
how it should work in the end.
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Change rank into MPI_COMM_WORLD and size(MPI_COMM_WORLD) to global variables in pml_monitoring.c.
Change mca_pml_monitoring_flush() signature so we don't need the size and rank parameters.
Signed-off-by: George Bosilca <bosilca@icl.utk.edu>
* Improve monitoring support (including integration with MPI_T)
Use mca_pml_monitoring_enable to check status state. Set mca_pml_monitoring_current_filename iif parameter is set
Allow 3 modes for pml_monitoring_enable_output: - 1 : stdout; - 2 : stderr; - 3 : filename
Fix test : 1 for differenciated messages, >1 for not differenciated. Fix output.
Add documentation for pml_monitoring_enable_output parameter. Remove useless parameter in example
Set filename only if using mpi tools
Adding missing parameters for fprintf in monitoring_flush (for output in std's cases)
Fix expected output/results for example header
Fix exemple when using MPI_Tools : a null-pointer can't be passed directly. It needs to be a pointer to a null-pointer
Base whether to output or not on message count, in order to print something if only empty messages are exchanged
Add a new example on how to access performance variables from within the code
Allocate arrays regarding value returned by binding
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Add overhead benchmark, with script to use data and create graphs out of the results
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Fix segfault error at end when not loading pml
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Start create common monitoring module. Factorise version numbering
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Fix microbenchmarks script
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Improve readability of code
NULL can't be passed as a PVAR parameter value. It must be a pointer to NULL or an empty string.
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Add osc monitoring component
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Add error checking if running out of memory in osc_monitoring
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Resolve brutal segfault when double freeing filename
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Moving to ompi/mca/common the proper parts of the monitoring system
Using common functions instead of pml specific one. Removing pml ones.
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Add calls to record monitored data from osc. Use common function to translate ranks.
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Fix test_overhead benchmark script distribution
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Fix linking library with mca/common
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Add passive operations in monitoring_test
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Fix from rank calculation. Add more detailed error messages
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Fix alignments. Fix common_monitoring_get_world_rank function. Remove useless trailing new lines
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Fix osc_monitoring mget_message_count function call
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Change common_monitoring function names to respect the naming convention. Move to common_finalize the common parts of finalization. Add some comments.
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Add monitoring common output system
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Add error message when trying to flush to a file, and open fails. Remove erroneous info message when flushing wereas the monitoring is already disabled.
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Consistent output file name (with and without MPI_T).
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Always output to a file when flushing at pvar_stop(flush).
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Update the monitoring documentation.
Complete informations from HowTo. Fix a few mistake and typos.
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Use the world_rank for printf's.
Fix name generation for output files when using MPI_T. Minor changes in benchmarks starting script
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Clean potential previous runs, but keep the results at the end in order to potentially reprocess the data. Add comments.
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Add security check for unique initialization for osc monitoring
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Clean the amout of symbols available outside mca/common/monitoring
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Remove use of __sync_* built-ins. Use opal_atomic_* instead.
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Allocate the hashtable on common/monitoring component initialization. Define symbols to set the values for error/warning/info verbose output. Use opal_atomic instead of built-in function in osc/monitoring template initialization.
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Deleting now useless file : moved to common/monitoring
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Add histogram ditribution of message sizes
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Add histogram array of 2-based log of message sizes. Use simple call to reset/allocate arrays in common_monitoring.c
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Add informations in dumping file. Separate per category (pt2pt/osc/coll (to come)) monitored data
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Add coll component for collectives communications monitoring
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Fix warning messages : use c_name as the magic id is not always defined. Moreover, there was a % missing. Add call to release underlying modules. Add debug info messages. Add warning which may lead to further analysis.
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Fix log10_2 constant initialization. Fix index calculation for histogram array.
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Add debug info messages to follow more easily initialization steps.
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Group all the var/pvar definitions to common_monitoring. Separate initial filename from the current on, to ease its lifetime management. Add verifications to ensure common is initialized once only. Move state variable management to common_monitoring.
monitoring_filter only indicates if filtering is activated.
Fix out of range access in histogram.
List is not used with the struct mca_monitoring_coll_data_t, so heritate only from opal_object_t.
Remove useless dead code.
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Fix invalid memory allocation. Initialize initial_filename to empty string to avoid invalid read in mca_base_var_register.
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Don't install the test scripts.
Signed-off-by: George Bosilca <bosilca@icl.utk.edu>
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Fix missing procs in hashtable. Cache coll monitoring data.
* Add MCA_PML_BASE_FLAG_REQUIRE_WORLD flag to the PML layer.
* Cache monitoring data relative to collectives operations on creation.
* Remove double caching.
* Use same proc name definition for hash table when inserting and
when retrieving.
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Use intermediate variable to avoid invalid write while retrieving ranks in hashtable.
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Add missing release of the last element in flush_all. Add release of the hashtable in finalize.
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Use a linked list instead of a hashtable to keep tracks of communicator data. Add release of the structure at finalize time.
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Set world_rank from hashtable only if found
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Use predefined symbol from opal system to print int
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Move collective monitoring data to a hashtable. Add pvar to access the monitoring_coll_data. Move functions header to a private file only to be used in ompi/mca/common/monitoring
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Fix pvar registration. Use OMPI_ERROR isntead of -1 as returned error value. Fix releasing of coll_data_t objects. Affect value only if data is found in the hashtable.
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Add automated check (with MPI_Tools) of monitoring.
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Fix procs list caching in common_monitoring_coll_data_t
* Fix monitoring_coll_data type definition.
* Use size(COMM_WORLD)-1 to determine max number of digits.
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Add linking to Fortran applications for LD_PRELOAD usage of monitoring_prof
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Add PVAR's handles. Clean up code (visibility, add comments...). Start updating the documentation
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Fix coll operations monitoring. Update check_monitoring accordingly to the added pvar. Fix monitoring array allocation.
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Documentation update.
Update and then move the latex and README documentation to a more logical place
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Aggregate monitoring COLL data to the generated matrix. Update documentation accordingly.
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Fix monitoring_prof (bad variable.vector used, and wrong array in PMPI_Gather).
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Add reduce_scatter and reduce_scatter_block monitoring. Reduce memory footprint of monitoring_prof. Unify OSC related outputs.
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Add the use of a machine file for overhead benchmark
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Check for out-of-bound write in histogram
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Fix common_monitoring_cache object init for MPI_COMM_WORLD
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Add RDMA benchmarks to test_overhead
Add error file output. Add MPI_Put and MPI_Get results analysis. Add overhead computation for complete sending (pingpong / 2).
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Add computation of average and median of overheads. Add comments and copyrigths to the test_overhead script
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Add technical documentation
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Adapt to the new definition of communicators
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Update expected output in test/monitoring/monitoring_test.c
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Add dumping histogram in edge case
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Adding a reduce(pml_monitoring_messages_count, MPI_MAX) example
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Add consistency in header inclusion.
Include ompi/mpi/fortran/mpif-h/bindings.h only if needed.
Add sanity check before emptying hashtable.
Fix typos in documentation.
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* misc monitoring fixes
* test/monitoring: fix test when weak symbols are not available
* monitoring: fix a typo and add a missing file in Makefile.am
and have monitoring_common.h and monitoring_common_coll.h included in the distro
* test/monitoring: cleanup all tests and make distclean a happy panda
* test/monitoring: use gettimeofday() if clock_gettime() is unavailable
* monitoring: silence misc warnings (#3)
Signed-off-by: Gilles Gouaillardet <gilles@rist.or.jp>
* Cleanups.
Signed-off-by: George Bosilca <bosilca@icl.utk.edu>
* Changing int64_t to size_t.
Keep the size_t used accross all monitoring components.
Adapt the documentation.
Remove useless MPI_Request and MPI_Status from monitoring_test.c.
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Add parameter for RMA test case
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Clean the maximum bound computation for proc list dump.
Use ptrdiff_t instead of OPAL_PTRDIFF_TYPE to reflect the changes from commit fa5cd0dbe5d261bd9d2cc61d5b305b4ef6a2dda6.
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Add communicator-specific monitored collective data reset
Signed-off-by: Clement Foyer <clement.foyer@inria.fr>
* Add monitoring scripts to the 'make dist'
Also install them in the build and the install directories.
Signed-off-by: George Bosilca <bosilca@icl.utk.edu>
2017-06-26 19:21:39 +03:00
|
|
|
/* read the value directly from the variable. */
|
|
|
|
ret = handle->pvar->set_value (handle->pvar, value, handle->obj_handle);
|
2013-07-16 20:02:13 +04:00
|
|
|
|
|
|
|
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;
|
|
|
|
|
2013-10-23 19:47:15 +04:00
|
|
|
if (mca_base_pvar_is_invalid (handle->pvar)) {
|
|
|
|
return OPAL_ERR_NOT_BOUND;
|
|
|
|
}
|
|
|
|
|
2013-07-16 20:02:13 +04:00
|
|
|
/* 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;
|
|
|
|
|
2013-10-23 19:47:15 +04:00
|
|
|
if (mca_base_pvar_is_invalid (handle->pvar)) {
|
|
|
|
return OPAL_ERR_NOT_BOUND;
|
|
|
|
}
|
|
|
|
|
2013-07-16 20:02:13 +04:00
|
|
|
/* 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 */
|
2017-06-30 04:18:46 +03:00
|
|
|
memset (handle->current_value, 0, handle->count * ompi_var_type_sizes[handle->pvar->type]);
|
2013-07-16 20:02:13 +04:00
|
|
|
|
|
|
|
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;
|
2013-08-28 20:03:23 +04:00
|
|
|
int ret, enum_count = 0;
|
2013-07-16 20:02:13 +04:00
|
|
|
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*/
|
2014-06-19 22:56:57 +04:00
|
|
|
(void)asprintf(&tmp, "mca:%s:%s:pvar:%s:", framework, component, full_name);
|
2013-07-16 20:02:13 +04:00
|
|
|
|
2014-06-19 22:56:57 +04:00
|
|
|
(void)asprintf(out[0] + line++, "%sclass:%s", tmp, pvar_class_names[pvar->var_class]);
|
|
|
|
(void)asprintf(out[0] + line++, "%sread-only:%s", tmp, mca_base_pvar_is_readonly(pvar) ? "true" : "false");
|
|
|
|
(void)asprintf(out[0] + line++, "%scontinuous:%s", tmp, mca_base_pvar_is_continuous(pvar) ? "true" : "false");
|
|
|
|
(void)asprintf(out[0] + line++, "%satomic:%s", tmp, mca_base_pvar_is_atomic(pvar) ? "true" : "false");
|
2013-07-16 20:02:13 +04:00
|
|
|
|
|
|
|
/* if it has a help message, output the help message */
|
|
|
|
if (pvar->description) {
|
2014-06-19 22:56:57 +04:00
|
|
|
(void)asprintf(out[0] + line++, "%shelp:%s", tmp, pvar->description);
|
2013-07-16 20:02:13 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2014-06-19 22:56:57 +04:00
|
|
|
(void)asprintf(out[0] + line++, "%senumerator:value:%d:%s", tmp, enum_value, enum_string);
|
2013-07-16 20:02:13 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-30 04:18:46 +03:00
|
|
|
(void)asprintf(out[0] + line++, "%stype:%s", tmp, ompi_var_type_names[pvar->type]);
|
2014-06-19 22:56:57 +04:00
|
|
|
free(tmp); // release tmp storage
|
2013-07-16 20:02:13 +04:00
|
|
|
} 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;
|
|
|
|
}
|
|
|
|
|
2014-06-19 22:56:57 +04:00
|
|
|
(void)asprintf (out[0] + line++, "performance \"%s\" (type: %s, class: %s)", full_name,
|
2017-06-30 04:18:46 +03:00
|
|
|
ompi_var_type_names[pvar->type], pvar_class_names[pvar->var_class]);
|
2013-07-16 20:02:13 +04:00
|
|
|
|
|
|
|
if (pvar->description) {
|
2014-06-19 22:56:57 +04:00
|
|
|
(void)asprintf(out[0] + line++, "%s", pvar->description);
|
2013-07-16 20:02:13 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
if (NULL != pvar->enumerator) {
|
|
|
|
char *values;
|
|
|
|
|
|
|
|
ret = pvar->enumerator->dump(pvar->enumerator, &values);
|
|
|
|
if (OPAL_SUCCESS == ret) {
|
2014-06-19 22:56:57 +04:00
|
|
|
(void)asprintf (out[0] + line++, "Values: %s", values);
|
2013-07-16 20:02:13 +04:00
|
|
|
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 */
|
George did the work and deserves all the credit for it. Ralph did the merge, and deserves whatever blame results from errors in it :-)
WHAT: Open our low-level communication infrastructure by moving all necessary components (btl/rcache/allocator/mpool) down in OPAL
All the components required for inter-process communications are currently deeply integrated in the OMPI layer. Several groups/institutions have express interest in having a more generic communication infrastructure, without all the OMPI layer dependencies. This communication layer should be made available at a different software level, available to all layers in the Open MPI software stack. As an example, our ORTE layer could replace the current OOB and instead use the BTL directly, gaining access to more reactive network interfaces than TCP. Similarly, external software libraries could take advantage of our highly optimized AM (active message) communication layer for their own purpose. UTK with support from Sandia, developped a version of Open MPI where the entire communication infrastucture has been moved down to OPAL (btl/rcache/allocator/mpool). Most of the moved components have been updated to match the new schema, with few exceptions (mainly BTLs where I have no way of compiling/testing them). Thus, the completion of this RFC is tied to being able to completing this move for all BTLs. For this we need help from the rest of the Open MPI community, especially those supporting some of the BTLs. A non-exhaustive list of BTLs that qualify here is: mx, portals4, scif, udapl, ugni, usnic.
This commit was SVN r32317.
2014-07-26 04:47:28 +04:00
|
|
|
static void opal_mpi_pvar_session_constructor (mca_base_pvar_session_t *session)
|
2013-07-16 20:02:13 +04:00
|
|
|
{
|
|
|
|
OBJ_CONSTRUCT(&session->handles, opal_list_t);
|
|
|
|
}
|
|
|
|
|
George did the work and deserves all the credit for it. Ralph did the merge, and deserves whatever blame results from errors in it :-)
WHAT: Open our low-level communication infrastructure by moving all necessary components (btl/rcache/allocator/mpool) down in OPAL
All the components required for inter-process communications are currently deeply integrated in the OMPI layer. Several groups/institutions have express interest in having a more generic communication infrastructure, without all the OMPI layer dependencies. This communication layer should be made available at a different software level, available to all layers in the Open MPI software stack. As an example, our ORTE layer could replace the current OOB and instead use the BTL directly, gaining access to more reactive network interfaces than TCP. Similarly, external software libraries could take advantage of our highly optimized AM (active message) communication layer for their own purpose. UTK with support from Sandia, developped a version of Open MPI where the entire communication infrastucture has been moved down to OPAL (btl/rcache/allocator/mpool). Most of the moved components have been updated to match the new schema, with few exceptions (mainly BTLs where I have no way of compiling/testing them). Thus, the completion of this RFC is tied to being able to completing this move for all BTLs. For this we need help from the rest of the Open MPI community, especially those supporting some of the BTLs. A non-exhaustive list of BTLs that qualify here is: mx, portals4, scif, udapl, ugni, usnic.
This commit was SVN r32317.
2014-07-26 04:47:28 +04:00
|
|
|
static void opal_mpi_pvar_session_destructor (mca_base_pvar_session_t *session)
|
2013-07-16 20:02:13 +04:00
|
|
|
{
|
|
|
|
mca_base_pvar_handle_t *handle, *next;
|
|
|
|
|
|
|
|
/* it is likely a user error if there are any allocated handles when the session
|
2013-10-23 19:47:15 +04:00
|
|
|
* is freed. clean it up anyway. The handle destructor will remove the handle from
|
|
|
|
* the session's handle list. */
|
2013-07-16 20:02:13 +04:00
|
|
|
OPAL_LIST_FOREACH_SAFE(handle, next, &session->handles, mca_base_pvar_handle_t) {
|
|
|
|
OBJ_DESTRUCT(handle);
|
|
|
|
}
|
|
|
|
|
|
|
|
OBJ_DESTRUCT(&session->handles);
|
|
|
|
}
|
|
|
|
|
George did the work and deserves all the credit for it. Ralph did the merge, and deserves whatever blame results from errors in it :-)
WHAT: Open our low-level communication infrastructure by moving all necessary components (btl/rcache/allocator/mpool) down in OPAL
All the components required for inter-process communications are currently deeply integrated in the OMPI layer. Several groups/institutions have express interest in having a more generic communication infrastructure, without all the OMPI layer dependencies. This communication layer should be made available at a different software level, available to all layers in the Open MPI software stack. As an example, our ORTE layer could replace the current OOB and instead use the BTL directly, gaining access to more reactive network interfaces than TCP. Similarly, external software libraries could take advantage of our highly optimized AM (active message) communication layer for their own purpose. UTK with support from Sandia, developped a version of Open MPI where the entire communication infrastucture has been moved down to OPAL (btl/rcache/allocator/mpool). Most of the moved components have been updated to match the new schema, with few exceptions (mainly BTLs where I have no way of compiling/testing them). Thus, the completion of this RFC is tied to being able to completing this move for all BTLs. For this we need help from the rest of the Open MPI community, especially those supporting some of the BTLs. A non-exhaustive list of BTLs that qualify here is: mx, portals4, scif, udapl, ugni, usnic.
This commit was SVN r32317.
2014-07-26 04:47:28 +04:00
|
|
|
OBJ_CLASS_INSTANCE(mca_base_pvar_session_t, opal_object_t, opal_mpi_pvar_session_constructor,
|
|
|
|
opal_mpi_pvar_session_destructor);
|
2013-07-16 20:02:13 +04:00
|
|
|
|
|
|
|
/* 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);
|
|
|
|
}
|
|
|
|
|
2013-10-23 19:47:15 +04:00
|
|
|
/* remove this handle from the pvar list */
|
2015-02-12 21:55:50 +03:00
|
|
|
if (handle->pvar) {
|
|
|
|
opal_list_remove_item (&handle->pvar->bound_handles, &handle->list2);
|
|
|
|
}
|
2013-10-23 19:47:15 +04:00
|
|
|
|
2013-07-16 20:02:13 +04:00
|
|
|
OBJ_DESTRUCT(&handle->list2);
|
2013-10-23 19:47:15 +04:00
|
|
|
|
|
|
|
/* remove this handle from the session */
|
|
|
|
if (handle->session) {
|
|
|
|
opal_list_remove_item (&handle->session->handles, &handle->super);
|
|
|
|
}
|
2013-07-16 20:02:13 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
OBJ_CLASS_INSTANCE(mca_base_pvar_handle_t, opal_list_item_t, mca_base_pvar_handle_constructor,
|
|
|
|
mca_base_pvar_handle_destructor);
|