Skip to content

Commit 2ed9438

Browse files
committed
mca/base: add a new MCA variable type for include lists
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 <hjelmn@google.com>
1 parent e4b98d7 commit 2ed9438

File tree

8 files changed

+461
-23
lines changed

8 files changed

+461
-23
lines changed

configure.ac

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1505,6 +1505,7 @@ AC_CONFIG_FILES([
15051505
test/asm/Makefile
15061506
test/datatype/Makefile
15071507
test/class/Makefile
1508+
test/mca/Makefile
15081509
test/mpool/Makefile
15091510
test/support/Makefile
15101511
test/threads/Makefile

ompi/mpi/tool/cvar_read.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
* reserved.
1111
* Copyright (c) 2021 Amazon.com, Inc. or its affiliates. All Rights
1212
* reserved.
13+
* Copyright (c) 2024 Google, LLC. All rights reserved.
1314
* $COPYRIGHT$
1415
*
1516
* Additional copyrights may follow
@@ -88,6 +89,17 @@ int MPI_T_cvar_read (MPI_T_cvar_handle handle, void *buf)
8889
}
8990

9091
break;
92+
case MCA_BASE_VAR_TYPE_INCLUDE_LIST: {
93+
char *tmp = mca_base_var_string_value (handle->var->mbv_index);
94+
if (strlen(tmp) == 0) {
95+
((char *)buf)[0] = '\0';
96+
} else {
97+
strcpy ((char *) buf, tmp);
98+
free (tmp);
99+
}
100+
101+
break;
102+
}
91103
default:
92104
rc = MPI_T_ERR_INVALID;
93105
}

ompi/mpi/tool/mpit_common.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
* Copyright (c) 2020 The University of Tennessee and The University
99
* of Tennessee Research Foundation. All rights
1010
* reserved.
11+
* Copyright (c) 2024 Google, LLC. All rights reserved.
1112
* $COPYRIGHT$
1213
*
1314
* Additional copyrights may follow
@@ -56,6 +57,7 @@ static MPI_Datatype mca_to_mpi_datatypes[MCA_BASE_VAR_TYPE_MAX] = {
5657
[MCA_BASE_VAR_TYPE_UINT32_T] = MPI_UINT32_T,
5758
[MCA_BASE_VAR_TYPE_INT64_T] = MPI_INT64_T,
5859
[MCA_BASE_VAR_TYPE_UINT64_T] = MPI_UINT64_T,
60+
[MCA_BASE_VAR_TYPE_INCLUDE_LIST] = MPI_CHAR,
5961
};
6062

6163
int ompit_var_type_to_datatype (mca_base_var_type_t type, MPI_Datatype *datatype)

opal/mca/base/mca_base_var.c

Lines changed: 101 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
* Copyright (c) 2018 Amazon.com, Inc. or its affiliates. All Rights reserved.
2121
* Copyright (c) 2018 Triad National Security, LLC. All rights
2222
* reserved.
23-
* Copyright (c) 2020 Google, LLC. All rights reserved.
23+
* Copyright (c) 2020-2024 Google, LLC. All rights reserved.
2424
* Copyright (c) 2021 Nanook Consulting. All rights reserved.
2525
* Copyright (c) 2022 Computer Architecture and VLSI Systems (CARV)
2626
* Laboratory, ICS Forth. All rights reserved.
@@ -138,6 +138,11 @@ static void fv_constructor(mca_base_var_file_value_t *p);
138138
static void fv_destructor(mca_base_var_file_value_t *p);
139139
OBJ_CLASS_INSTANCE(mca_base_var_file_value_t, opal_list_item_t, fv_constructor, fv_destructor);
140140

141+
static void include_list_contructor(mca_base_var_include_list_t *p);
142+
static void include_list_destructor(mca_base_var_include_list_t *p);
143+
OBJ_CLASS_INSTANCE(mca_base_var_include_list_t, opal_object_t, include_list_contructor,
144+
include_list_destructor);
145+
141146
static const char *mca_base_var_source_file(const mca_base_var_t *var)
142147
{
143148
mca_base_var_file_value_t *fv = (mca_base_var_file_value_t *) var->mbv_file_value;
@@ -766,6 +771,9 @@ static int var_set_from_string(mca_base_var_t *var, char *src)
766771
case MCA_BASE_VAR_TYPE_VERSION_STRING:
767772
var_set_string(var, src);
768773
break;
774+
case MCA_BASE_VAR_TYPE_INCLUDE_LIST:
775+
mca_base_var_parse_include_list(src, &var->mbv_storage->ilistval);
776+
break;
769777
case MCA_BASE_VAR_TYPE_MAX:
770778
return OPAL_ERROR;
771779
}
@@ -803,11 +811,13 @@ int mca_base_var_set_value(int vari, const void *value, size_t size, mca_base_va
803811
}
804812
}
805813

806-
if (MCA_BASE_VAR_TYPE_STRING != var->mbv_type
807-
&& MCA_BASE_VAR_TYPE_VERSION_STRING != var->mbv_type) {
808-
memmove(var->mbv_storage, value, ompi_var_type_sizes[var->mbv_type]);
814+
if (MCA_BASE_VAR_TYPE_STRING == var->mbv_type ||
815+
MCA_BASE_VAR_TYPE_VERSION_STRING == var->mbv_type) {
816+
ret = var_set_string(var, (char *) value);
817+
} else if (MCA_BASE_VAR_TYPE_INCLUDE_LIST == var->mbv_type) {
818+
ret = mca_base_var_parse_include_list((char *) value, &var->mbv_storage->ilistval);
809819
} else {
810-
var_set_string(var, (char *) value);
820+
memmove(var->mbv_storage, value, ompi_var_type_sizes[var->mbv_type]);
811821
}
812822

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

820-
return OPAL_SUCCESS;
830+
return ret;
821831
}
822832

823833
/*
@@ -847,11 +857,12 @@ int mca_base_var_deregister(int vari)
847857
}
848858

849859
/* Release the current value if it is a string. */
850-
if ((MCA_BASE_VAR_TYPE_STRING == var->mbv_type
851-
|| MCA_BASE_VAR_TYPE_VERSION_STRING == var->mbv_type)
852-
&& var->mbv_storage->stringval) {
860+
if (MCA_BASE_VAR_TYPE_STRING == var->mbv_type
861+
|| MCA_BASE_VAR_TYPE_VERSION_STRING == var->mbv_type) {
853862
free(var->mbv_storage->stringval);
854863
var->mbv_storage->stringval = NULL;
864+
} else if (MCA_BASE_VAR_TYPE_INCLUDE_LIST == var->mbv_type) {
865+
OBJ_DESTRUCT(&var->mbv_storage->ilistval);
855866
} else {
856867
OPAL_MCA_VAR_MBV_ENUMERATOR_FREE(var->mbv_enumerator);
857868
}
@@ -1046,9 +1057,11 @@ int mca_base_var_build_env(char ***env, int *num_env, bool internal)
10461057
continue;
10471058
}
10481059

1049-
if ((MCA_BASE_VAR_TYPE_STRING == var->mbv_type
1060+
if (((MCA_BASE_VAR_TYPE_STRING == var->mbv_type
10501061
|| MCA_BASE_VAR_TYPE_VERSION_STRING == var->mbv_type)
1051-
&& NULL == var->mbv_storage->stringval) {
1062+
&& NULL == var->mbv_storage->stringval) ||
1063+
(MCA_BASE_VAR_TYPE_INCLUDE_LIST == var->mbv_type &&
1064+
NULL == var->mbv_storage->ilistval.items)) {
10521065
continue;
10531066
}
10541067

@@ -1331,7 +1344,11 @@ static int register_variable(const char *project_name, const char *framework_nam
13311344
align = OPAL_ALIGNMENT_DOUBLE;
13321345
break;
13331346
case MCA_BASE_VAR_TYPE_VERSION_STRING:
1347+
/* fall through */
13341348
case MCA_BASE_VAR_TYPE_STRING:
1349+
/* fall through */
1350+
case MCA_BASE_VAR_TYPE_INCLUDE_LIST:
1351+
/* fall through */
13351352
default:
13361353
align = 0;
13371354
break;
@@ -1533,6 +1550,9 @@ int mca_base_var_register(const char *project_name, const char *framework_name,
15331550
assert(NULL == enumerator
15341551
|| (MCA_BASE_VAR_TYPE_INT == type || MCA_BASE_VAR_TYPE_UNSIGNED_INT == type));
15351552

1553+
1554+
assert(MCA_BASE_VAR_TYPE_INCLUDE_LIST != type || ((mca_base_var_include_list_t *) storage)->super.obj_reference_count > 0);
1555+
15361556
ret = register_variable(project_name, framework_name, component_name, variable_name,
15371557
description, type, enumerator, bind, flags, info_lvl, scope, -1,
15381558
storage);
@@ -1855,25 +1875,26 @@ static void var_constructor(mca_base_var_t *var)
18551875
*/
18561876
static void var_destructor(mca_base_var_t *var)
18571877
{
1858-
if ((MCA_BASE_VAR_TYPE_STRING == var->mbv_type
1859-
|| MCA_BASE_VAR_TYPE_VERSION_STRING == var->mbv_type)
1860-
&& NULL != var->mbv_storage && NULL != var->mbv_storage->stringval) {
1861-
free(var->mbv_storage->stringval);
1862-
var->mbv_storage->stringval = NULL;
1878+
if (NULL != var->mbv_storage) {
1879+
if (MCA_BASE_VAR_TYPE_STRING == var->mbv_type
1880+
|| MCA_BASE_VAR_TYPE_VERSION_STRING == var->mbv_type) {
1881+
free(var->mbv_storage->stringval);
1882+
var->mbv_storage->stringval = NULL;
1883+
} else if (MCA_BASE_VAR_TYPE_INCLUDE_LIST == var->mbv_type) {
1884+
OBJ_DESTRUCT(&var->mbv_storage->ilistval);
1885+
}
1886+
1887+
var->mbv_storage = NULL;
18631888
}
18641889

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

1868-
if (NULL != var->mbv_long_name) {
1869-
free(var->mbv_long_name);
1870-
}
1893+
free(var->mbv_long_name);
18711894
var->mbv_full_name = NULL;
18721895
var->mbv_variable_name = NULL;
18731896

1874-
if (NULL != var->mbv_description) {
1875-
free(var->mbv_description);
1876-
}
1897+
free(var->mbv_description);
18771898

18781899
/* Destroy the synonym array */
18791900
OBJ_DESTRUCT(&var->mbv_synonyms);
@@ -1994,6 +2015,19 @@ static int var_value_string(mca_base_var_t *var, char **value_string)
19942015
case MCA_BASE_VAR_TYPE_DOUBLE:
19952016
ret = opal_asprintf(value_string, "%lf", value->lfval);
19962017
break;
2018+
case MCA_BASE_VAR_TYPE_INCLUDE_LIST:
2019+
if (NULL == value->ilistval.items) {
2020+
*value_string = strdup("");
2021+
} else {
2022+
char *tmp = opal_argv_join(value->ilistval.items, ',');
2023+
if (value->ilistval.is_exclude) {
2024+
ret = opal_asprintf(value_string, "^%s", tmp);
2025+
free(tmp);
2026+
} else {
2027+
*value_string = tmp;
2028+
}
2029+
}
2030+
break;
19972031
default:
19982032
ret = -1;
19992033
break;
@@ -2014,6 +2048,20 @@ static int var_value_string(mca_base_var_t *var, char **value_string)
20142048
return ret;
20152049
}
20162050

2051+
char *mca_base_var_string_value(int vari)
2052+
{
2053+
char *tmp = NULL;
2054+
mca_base_var_t *var;
2055+
2056+
int ret = var_get(vari, &var, false);
2057+
if (OPAL_SUCCESS != ret) {
2058+
return NULL;
2059+
}
2060+
2061+
(void) var_value_string(var, &tmp);
2062+
return tmp;
2063+
}
2064+
20172065
int mca_base_var_check_exclusive(const char *project, const char *type_a, const char *component_a,
20182066
const char *param_a, const char *type_b, const char *component_b,
20192067
const char *param_b)
@@ -2290,3 +2338,34 @@ int mca_base_var_dump(int vari, char ***out, mca_base_var_dump_type_t output_typ
22902338

22912339
return OPAL_SUCCESS;
22922340
}
2341+
2342+
static void include_list_contructor(mca_base_var_include_list_t *p)
2343+
{
2344+
p->items = NULL;
2345+
p->is_exclude = false;
2346+
}
2347+
2348+
static void include_list_destructor(mca_base_var_include_list_t *p)
2349+
{
2350+
opal_argv_free(p->items);
2351+
include_list_contructor(p);
2352+
}
2353+
2354+
int mca_base_var_parse_include_list(const char *value, mca_base_var_include_list_t *result)
2355+
{
2356+
/* release any current value and set to defaults */
2357+
include_list_destructor(result);
2358+
2359+
if (NULL == value || 0 == strlen(value)) {
2360+
return OPAL_SUCCESS;
2361+
}
2362+
2363+
if ('^' == value[0]) {
2364+
result->is_exclude = true;
2365+
++value;
2366+
}
2367+
2368+
result->items = opal_argv_split(value, ',');
2369+
return OPAL_SUCCESS;
2370+
}
2371+

opal/mca/base/mca_base_var.h

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
* reserved.
2020
* Copyright (c) 2022 Computer Architecture and VLSI Systems (CARV)
2121
* Laboratory, ICS Forth. All rights reserved.
22+
* Copyright (c) 2024 Google, LLC. All rights reserved.
2223
* $COPYRIGHT$
2324
*
2425
* Additional copyrights may follow
@@ -106,6 +107,10 @@ typedef enum {
106107
MCA_BASE_VAR_TYPE_INT64_T,
107108
/** The variable is of type uint64_t */
108109
MCA_BASE_VAR_TYPE_UINT64_T,
110+
/** The variable is an include list. Must be OBJ_CONSTRUCTed before
111+
* registration to be valid. The destuction is automatic when the
112+
* variable is deregistered. */
113+
MCA_BASE_VAR_TYPE_INCLUDE_LIST,
109114

110115
/** Maximum variable type. */
111116
MCA_BASE_VAR_TYPE_MAX
@@ -212,6 +217,22 @@ typedef enum {
212217
MCA_BASE_VAR_FLAG_DEF_UNSET = 0x0080,
213218
} mca_base_var_flag_t;
214219

220+
/**
221+
* An include list. These are strings of the form:
222+
* foo,bar,baz (include)
223+
* ^foo,bar,baz (exclude)
224+
*/
225+
struct mca_base_var_include_list {
226+
opal_object_t super;
227+
/** argv array of items */
228+
char **items;
229+
/** is this an exclude list */
230+
bool is_exclude;
231+
};
232+
typedef struct mca_base_var_include_list mca_base_var_include_list_t;
233+
234+
OPAL_DECLSPEC OBJ_CLASS_DECLARATION(mca_base_var_include_list_t);
235+
215236
/**
216237
* Types for MCA parameters.
217238
*/
@@ -242,6 +263,8 @@ typedef union {
242263
size_t sizetval;
243264
/** double value */
244265
double lfval;
266+
/** include/exclude list */
267+
mca_base_var_include_list_t ilistval;
245268
} mca_base_var_storage_t;
246269

247270
/**
@@ -718,6 +741,29 @@ typedef enum {
718741
*/
719742
OPAL_DECLSPEC int mca_base_var_dump(int vari, char ***out, mca_base_var_dump_type_t output_type);
720743

744+
/**
745+
* Get a string representation of a variable.
746+
*
747+
* @param[in] vari Variable index
748+
*
749+
* This function returns the string representation of the variable or NULL if an
750+
* error occurs. It is the caller's responsibility to free the string.
751+
*/
752+
OPAL_DECLSPEC char *mca_base_var_string_value(int vari);
753+
754+
/**
755+
* Parse an include list.
756+
*
757+
* @param[in] value Include list string
758+
* @param[out] result Parsed include/exclude list (must already be OBJ_CONSTRUCTed)
759+
*
760+
* In Open MPI include lists are a comma-seperated list of things that can be negated
761+
* by prefixing the list with a ^. Example: self,vader,ugni or ^tcp,ofi. This method
762+
* fills in the mca_base_var_include_list_t struct with an argv array of items and
763+
* a boolean indicating whether this is an exclude list or not.
764+
*/
765+
OPAL_DECLSPEC int mca_base_var_parse_include_list(const char *value, mca_base_var_include_list_t *result);
766+
721767
#define MCA_COMPILETIME_VER "print_compiletime_version"
722768
#define MCA_RUNTIME_VER "print_runtime_version"
723769

test/Makefile.am

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
# Copyright (c) 2015-2016 Research Organization for Information Science
1515
# and Technology (RIST). All rights reserved.
1616
# Copyright (c) 2017 IBM Corporation. All rights reserved.
17+
# Copyright (c) 2024 Google, LLC. All rights reserved.
1718
# $COPYRIGHT$
1819
#
1920
# Additional copyrights may follow
@@ -22,7 +23,7 @@
2223
#
2324

2425
# support needs to be first for dependencies
25-
SUBDIRS = support asm class threads datatype util mpool
26+
SUBDIRS = support asm class threads datatype util mpool mca
2627
if PROJECT_OMPI
2728
SUBDIRS += monitoring spc
2829
endif

0 commit comments

Comments
 (0)