Skip to content

Commit

Permalink
mca/base: add a new MCA variable type for include lists
Browse files Browse the repository at this point in the history
It is not uncommon in Open MPI to register a string variable to allow specifying
an exclude or exclude list (every framework registers one). Given this common
patten it is worthwhile to formalize an MCA include list variable type:
MCA_BASE_VAR_TYPE_INCLUDE_LIST. Variables of this type use a new opal object
(mca_base_var_include_list_t) that stores and argv-style array and an exclude-
list flag. To register an include list variable the caller must first either
OBJ_CONSTRUCT the object or allocate it with OBJ_NEW. Variables of this type are
exposed as strings to MPI_T.

Signed-off-by: Nathan Hjelm <[email protected]>
  • Loading branch information
hjelmn committed Sep 24, 2024
1 parent e4b98d7 commit 2ed9438
Show file tree
Hide file tree
Showing 8 changed files with 461 additions and 23 deletions.
1 change: 1 addition & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -1505,6 +1505,7 @@ AC_CONFIG_FILES([
test/asm/Makefile
test/datatype/Makefile
test/class/Makefile
test/mca/Makefile
test/mpool/Makefile
test/support/Makefile
test/threads/Makefile
Expand Down
12 changes: 12 additions & 0 deletions ompi/mpi/tool/cvar_read.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
* reserved.
* Copyright (c) 2021 Amazon.com, Inc. or its affiliates. All Rights
* reserved.
* Copyright (c) 2024 Google, LLC. All rights reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
Expand Down Expand Up @@ -88,6 +89,17 @@ int MPI_T_cvar_read (MPI_T_cvar_handle handle, void *buf)
}

break;
case MCA_BASE_VAR_TYPE_INCLUDE_LIST: {
char *tmp = mca_base_var_string_value (handle->var->mbv_index);
if (strlen(tmp) == 0) {
((char *)buf)[0] = '\0';
} else {
strcpy ((char *) buf, tmp);
free (tmp);
}

break;
}
default:
rc = MPI_T_ERR_INVALID;
}
Expand Down
2 changes: 2 additions & 0 deletions ompi/mpi/tool/mpit_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
* Copyright (c) 2020 The University of Tennessee and The University
* of Tennessee Research Foundation. All rights
* reserved.
* Copyright (c) 2024 Google, LLC. All rights reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
Expand Down Expand Up @@ -56,6 +57,7 @@ static MPI_Datatype mca_to_mpi_datatypes[MCA_BASE_VAR_TYPE_MAX] = {
[MCA_BASE_VAR_TYPE_UINT32_T] = MPI_UINT32_T,
[MCA_BASE_VAR_TYPE_INT64_T] = MPI_INT64_T,
[MCA_BASE_VAR_TYPE_UINT64_T] = MPI_UINT64_T,
[MCA_BASE_VAR_TYPE_INCLUDE_LIST] = MPI_CHAR,
};

int ompit_var_type_to_datatype (mca_base_var_type_t type, MPI_Datatype *datatype)
Expand Down
123 changes: 101 additions & 22 deletions opal/mca/base/mca_base_var.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
* Copyright (c) 2018 Amazon.com, Inc. or its affiliates. All Rights reserved.
* Copyright (c) 2018 Triad National Security, LLC. All rights
* reserved.
* Copyright (c) 2020 Google, LLC. All rights reserved.
* Copyright (c) 2020-2024 Google, LLC. All rights reserved.
* Copyright (c) 2021 Nanook Consulting. All rights reserved.
* Copyright (c) 2022 Computer Architecture and VLSI Systems (CARV)
* Laboratory, ICS Forth. All rights reserved.
Expand Down Expand Up @@ -138,6 +138,11 @@ static void fv_constructor(mca_base_var_file_value_t *p);
static void fv_destructor(mca_base_var_file_value_t *p);
OBJ_CLASS_INSTANCE(mca_base_var_file_value_t, opal_list_item_t, fv_constructor, fv_destructor);

static void include_list_contructor(mca_base_var_include_list_t *p);
static void include_list_destructor(mca_base_var_include_list_t *p);
OBJ_CLASS_INSTANCE(mca_base_var_include_list_t, opal_object_t, include_list_contructor,
include_list_destructor);

static const char *mca_base_var_source_file(const mca_base_var_t *var)
{
mca_base_var_file_value_t *fv = (mca_base_var_file_value_t *) var->mbv_file_value;
Expand Down Expand Up @@ -766,6 +771,9 @@ static int var_set_from_string(mca_base_var_t *var, char *src)
case MCA_BASE_VAR_TYPE_VERSION_STRING:
var_set_string(var, src);
break;
case MCA_BASE_VAR_TYPE_INCLUDE_LIST:
mca_base_var_parse_include_list(src, &var->mbv_storage->ilistval);
break;
case MCA_BASE_VAR_TYPE_MAX:
return OPAL_ERROR;
}
Expand Down Expand Up @@ -803,11 +811,13 @@ int mca_base_var_set_value(int vari, const void *value, size_t size, mca_base_va
}
}

if (MCA_BASE_VAR_TYPE_STRING != var->mbv_type
&& MCA_BASE_VAR_TYPE_VERSION_STRING != var->mbv_type) {
memmove(var->mbv_storage, value, ompi_var_type_sizes[var->mbv_type]);
if (MCA_BASE_VAR_TYPE_STRING == var->mbv_type ||
MCA_BASE_VAR_TYPE_VERSION_STRING == var->mbv_type) {
ret = var_set_string(var, (char *) value);
} else if (MCA_BASE_VAR_TYPE_INCLUDE_LIST == var->mbv_type) {
ret = mca_base_var_parse_include_list((char *) value, &var->mbv_storage->ilistval);
} else {
var_set_string(var, (char *) value);
memmove(var->mbv_storage, value, ompi_var_type_sizes[var->mbv_type]);
}

var->mbv_source = source;
Expand All @@ -817,7 +827,7 @@ int mca_base_var_set_value(int vari, const void *value, size_t size, mca_base_va
var->mbv_source_file = append_filename_to_list(source_file);
}

return OPAL_SUCCESS;
return ret;
}

/*
Expand Down Expand Up @@ -847,11 +857,12 @@ int mca_base_var_deregister(int vari)
}

/* Release the current value if it is a string. */
if ((MCA_BASE_VAR_TYPE_STRING == var->mbv_type
|| MCA_BASE_VAR_TYPE_VERSION_STRING == var->mbv_type)
&& var->mbv_storage->stringval) {
if (MCA_BASE_VAR_TYPE_STRING == var->mbv_type
|| MCA_BASE_VAR_TYPE_VERSION_STRING == var->mbv_type) {
free(var->mbv_storage->stringval);
var->mbv_storage->stringval = NULL;
} else if (MCA_BASE_VAR_TYPE_INCLUDE_LIST == var->mbv_type) {
OBJ_DESTRUCT(&var->mbv_storage->ilistval);
} else {
OPAL_MCA_VAR_MBV_ENUMERATOR_FREE(var->mbv_enumerator);
}
Expand Down Expand Up @@ -1046,9 +1057,11 @@ int mca_base_var_build_env(char ***env, int *num_env, bool internal)
continue;
}

if ((MCA_BASE_VAR_TYPE_STRING == var->mbv_type
if (((MCA_BASE_VAR_TYPE_STRING == var->mbv_type
|| MCA_BASE_VAR_TYPE_VERSION_STRING == var->mbv_type)
&& NULL == var->mbv_storage->stringval) {
&& NULL == var->mbv_storage->stringval) ||
(MCA_BASE_VAR_TYPE_INCLUDE_LIST == var->mbv_type &&
NULL == var->mbv_storage->ilistval.items)) {
continue;
}

Expand Down Expand Up @@ -1331,7 +1344,11 @@ static int register_variable(const char *project_name, const char *framework_nam
align = OPAL_ALIGNMENT_DOUBLE;
break;
case MCA_BASE_VAR_TYPE_VERSION_STRING:
/* fall through */
case MCA_BASE_VAR_TYPE_STRING:
/* fall through */
case MCA_BASE_VAR_TYPE_INCLUDE_LIST:
/* fall through */
default:
align = 0;
break;
Expand Down Expand Up @@ -1533,6 +1550,9 @@ int mca_base_var_register(const char *project_name, const char *framework_name,
assert(NULL == enumerator
|| (MCA_BASE_VAR_TYPE_INT == type || MCA_BASE_VAR_TYPE_UNSIGNED_INT == type));


assert(MCA_BASE_VAR_TYPE_INCLUDE_LIST != type || ((mca_base_var_include_list_t *) storage)->super.obj_reference_count > 0);

ret = register_variable(project_name, framework_name, component_name, variable_name,
description, type, enumerator, bind, flags, info_lvl, scope, -1,
storage);
Expand Down Expand Up @@ -1855,25 +1875,26 @@ static void var_constructor(mca_base_var_t *var)
*/
static void var_destructor(mca_base_var_t *var)
{
if ((MCA_BASE_VAR_TYPE_STRING == var->mbv_type
|| MCA_BASE_VAR_TYPE_VERSION_STRING == var->mbv_type)
&& NULL != var->mbv_storage && NULL != var->mbv_storage->stringval) {
free(var->mbv_storage->stringval);
var->mbv_storage->stringval = NULL;
if (NULL != var->mbv_storage) {
if (MCA_BASE_VAR_TYPE_STRING == var->mbv_type
|| MCA_BASE_VAR_TYPE_VERSION_STRING == var->mbv_type) {
free(var->mbv_storage->stringval);
var->mbv_storage->stringval = NULL;
} else if (MCA_BASE_VAR_TYPE_INCLUDE_LIST == var->mbv_type) {
OBJ_DESTRUCT(&var->mbv_storage->ilistval);
}

var->mbv_storage = NULL;
}

/* don't release the boolean enumerator */
OPAL_MCA_VAR_MBV_ENUMERATOR_FREE(var->mbv_enumerator);

if (NULL != var->mbv_long_name) {
free(var->mbv_long_name);
}
free(var->mbv_long_name);
var->mbv_full_name = NULL;
var->mbv_variable_name = NULL;

if (NULL != var->mbv_description) {
free(var->mbv_description);
}
free(var->mbv_description);

/* Destroy the synonym array */
OBJ_DESTRUCT(&var->mbv_synonyms);
Expand Down Expand Up @@ -1994,6 +2015,19 @@ static int var_value_string(mca_base_var_t *var, char **value_string)
case MCA_BASE_VAR_TYPE_DOUBLE:
ret = opal_asprintf(value_string, "%lf", value->lfval);
break;
case MCA_BASE_VAR_TYPE_INCLUDE_LIST:
if (NULL == value->ilistval.items) {
*value_string = strdup("");
} else {
char *tmp = opal_argv_join(value->ilistval.items, ',');
if (value->ilistval.is_exclude) {
ret = opal_asprintf(value_string, "^%s", tmp);
free(tmp);
} else {
*value_string = tmp;
}
}
break;
default:
ret = -1;
break;
Expand All @@ -2014,6 +2048,20 @@ static int var_value_string(mca_base_var_t *var, char **value_string)
return ret;
}

char *mca_base_var_string_value(int vari)
{
char *tmp = NULL;
mca_base_var_t *var;

int ret = var_get(vari, &var, false);
if (OPAL_SUCCESS != ret) {
return NULL;
}

(void) var_value_string(var, &tmp);
return tmp;
}

int mca_base_var_check_exclusive(const char *project, const char *type_a, const char *component_a,
const char *param_a, const char *type_b, const char *component_b,
const char *param_b)
Expand Down Expand Up @@ -2290,3 +2338,34 @@ int mca_base_var_dump(int vari, char ***out, mca_base_var_dump_type_t output_typ

return OPAL_SUCCESS;
}

static void include_list_contructor(mca_base_var_include_list_t *p)
{
p->items = NULL;
p->is_exclude = false;
}

static void include_list_destructor(mca_base_var_include_list_t *p)
{
opal_argv_free(p->items);
include_list_contructor(p);
}

int mca_base_var_parse_include_list(const char *value, mca_base_var_include_list_t *result)
{
/* release any current value and set to defaults */
include_list_destructor(result);

if (NULL == value || 0 == strlen(value)) {
return OPAL_SUCCESS;
}

if ('^' == value[0]) {
result->is_exclude = true;
++value;
}

result->items = opal_argv_split(value, ',');
return OPAL_SUCCESS;
}

46 changes: 46 additions & 0 deletions opal/mca/base/mca_base_var.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
* reserved.
* Copyright (c) 2022 Computer Architecture and VLSI Systems (CARV)
* Laboratory, ICS Forth. All rights reserved.
* Copyright (c) 2024 Google, LLC. All rights reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
Expand Down Expand Up @@ -106,6 +107,10 @@ typedef enum {
MCA_BASE_VAR_TYPE_INT64_T,
/** The variable is of type uint64_t */
MCA_BASE_VAR_TYPE_UINT64_T,
/** The variable is an include list. Must be OBJ_CONSTRUCTed before
* registration to be valid. The destuction is automatic when the
* variable is deregistered. */
MCA_BASE_VAR_TYPE_INCLUDE_LIST,

/** Maximum variable type. */
MCA_BASE_VAR_TYPE_MAX
Expand Down Expand Up @@ -212,6 +217,22 @@ typedef enum {
MCA_BASE_VAR_FLAG_DEF_UNSET = 0x0080,
} mca_base_var_flag_t;

/**
* An include list. These are strings of the form:
* foo,bar,baz (include)
* ^foo,bar,baz (exclude)
*/
struct mca_base_var_include_list {
opal_object_t super;
/** argv array of items */
char **items;
/** is this an exclude list */
bool is_exclude;
};
typedef struct mca_base_var_include_list mca_base_var_include_list_t;

OPAL_DECLSPEC OBJ_CLASS_DECLARATION(mca_base_var_include_list_t);

/**
* Types for MCA parameters.
*/
Expand Down Expand Up @@ -242,6 +263,8 @@ typedef union {
size_t sizetval;
/** double value */
double lfval;
/** include/exclude list */
mca_base_var_include_list_t ilistval;
} mca_base_var_storage_t;

/**
Expand Down Expand Up @@ -718,6 +741,29 @@ typedef enum {
*/
OPAL_DECLSPEC int mca_base_var_dump(int vari, char ***out, mca_base_var_dump_type_t output_type);

/**
* Get a string representation of a variable.
*
* @param[in] vari Variable index
*
* This function returns the string representation of the variable or NULL if an
* error occurs. It is the caller's responsibility to free the string.
*/
OPAL_DECLSPEC char *mca_base_var_string_value(int vari);

/**
* Parse an include list.
*
* @param[in] value Include list string
* @param[out] result Parsed include/exclude list (must already be OBJ_CONSTRUCTed)
*
* In Open MPI include lists are a comma-seperated list of things that can be negated
* by prefixing the list with a ^. Example: self,vader,ugni or ^tcp,ofi. This method
* fills in the mca_base_var_include_list_t struct with an argv array of items and
* a boolean indicating whether this is an exclude list or not.
*/
OPAL_DECLSPEC int mca_base_var_parse_include_list(const char *value, mca_base_var_include_list_t *result);

#define MCA_COMPILETIME_VER "print_compiletime_version"
#define MCA_RUNTIME_VER "print_runtime_version"

Expand Down
3 changes: 2 additions & 1 deletion test/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
# Copyright (c) 2015-2016 Research Organization for Information Science
# and Technology (RIST). All rights reserved.
# Copyright (c) 2017 IBM Corporation. All rights reserved.
# Copyright (c) 2024 Google, LLC. All rights reserved.
# $COPYRIGHT$
#
# Additional copyrights may follow
Expand All @@ -22,7 +23,7 @@
#

# support needs to be first for dependencies
SUBDIRS = support asm class threads datatype util mpool
SUBDIRS = support asm class threads datatype util mpool mca
if PROJECT_OMPI
SUBDIRS += monitoring spc
endif
Expand Down
Loading

0 comments on commit 2ed9438

Please sign in to comment.