Skip to content

Commit 9fae5bf

Browse files
hjelmnjsquyres
authored andcommitted
mca/base: add support for component aliasing
This commit adds support for aliasing component names. A component name alias is created by calling: mca_base_alias_register. The name of the project and framework are optional. The component name and component alias are required. Once an alias is registered all variables registered after the alias creation will have synonyms also registered. For example: ```c mca_base_alias_register("opal", "btl", "vader", "sm", false); ``` would cause all of the variables registered by btl/vader to have aliases that start with btl_sm. Ex: btl_vader_single_copy_mechanism would have the synonym: btl_sm_single_copy_mechanism. If aliases are registered before component filtering the alias can also be used for component selection. For example, if sm is registered as an alias to vader in the btl framework register function then ```--mca btl self,sm``` would be equivalent to ```--mca btl self,vader```. Signed-off-by: Nathan Hjelm <hjelmn@google.com>
1 parent 3a036f8 commit 9fae5bf

File tree

5 files changed

+340
-22
lines changed

5 files changed

+340
-22
lines changed

opal/mca/base/Makefile.am

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
# Copyright (c) 2004-2005 The Regents of the University of California.
1111
# All rights reserved.
1212
# Copyright (c) 2010 Cisco Systems, Inc. All rights reserved.
13+
# Copyright (c) 2020 Google LLC. All rights reserved.
1314
# $COPYRIGHT$
1415
#
1516
# Additional copyrights may follow
@@ -31,6 +32,7 @@ dist_opaldata_DATA = help-mca-base.txt help-mca-var.txt
3132

3233
headers = \
3334
base.h \
35+
mca_base_alias.h \
3436
mca_base_component_repository.h \
3537
mca_base_var.h \
3638
mca_base_pvar.h \
@@ -43,6 +45,7 @@ headers = \
4345

4446
libmca_base_la_SOURCES = \
4547
$(headers) \
48+
mca_base_alias.c \
4649
mca_base_close.c \
4750
mca_base_cmd_line.c \
4851
mca_base_component_compare.c \

opal/mca/base/mca_base_alias.c

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
2+
/*
3+
* Copyright (c) 2020 Google, LLC. All rights reserved.
4+
* $COPYRIGHT$
5+
*
6+
* Additional copyrights may follow
7+
*
8+
* $HEADER$
9+
*/
10+
11+
#include "mca_base_alias.h"
12+
#include "opal/class/opal_hash_table.h"
13+
#include "opal/runtime/opal.h"
14+
15+
static void mca_base_alias_init (mca_base_alias_t *alias)
16+
{
17+
OBJ_CONSTRUCT(&alias->component_aliases, opal_list_t);
18+
}
19+
20+
static void mca_base_alias_fini (mca_base_alias_t *alias)
21+
{
22+
OPAL_LIST_DESTRUCT(&alias->component_aliases);
23+
}
24+
25+
OBJ_CLASS_INSTANCE(mca_base_alias_t, opal_object_t, mca_base_alias_init,
26+
mca_base_alias_fini);
27+
28+
static void mca_base_alias_item_init (mca_base_alias_item_t *alias_item) {
29+
alias_item->component_alias = NULL;
30+
}
31+
32+
static void mca_base_alias_item_fini (mca_base_alias_item_t *alias_item) {
33+
free (alias_item->component_alias);
34+
}
35+
36+
OBJ_CLASS_INSTANCE(mca_base_alias_item_t, opal_list_item_t, mca_base_alias_item_init,
37+
mca_base_alias_item_fini);
38+
39+
/*
40+
* local variables
41+
*/
42+
static opal_hash_table_t *alias_hash_table;
43+
44+
static void mca_base_alias_cleanup (void)
45+
{
46+
if (!alias_hash_table) {
47+
return;
48+
}
49+
50+
void *key;
51+
opal_object_t *value;
52+
OPAL_HASH_TABLE_FOREACH_PTR(key, value, alias_hash_table, {
53+
OBJ_RELEASE(value);
54+
});
55+
56+
OBJ_RELEASE(alias_hash_table);
57+
alias_hash_table = NULL;
58+
}
59+
60+
static int mca_base_alias_setup (void)
61+
{
62+
if (NULL != alias_hash_table) {
63+
return OPAL_SUCCESS;
64+
}
65+
66+
opal_finalize_register_cleanup (mca_base_alias_cleanup);
67+
68+
alias_hash_table = OBJ_NEW(opal_hash_table_t);
69+
if (NULL == alias_hash_table) {
70+
return OPAL_ERR_OUT_OF_RESOURCE;
71+
}
72+
73+
int ret = opal_hash_table_init (alias_hash_table, 32);
74+
if (OPAL_SUCCESS != ret) {
75+
OBJ_RELEASE(alias_hash_table);
76+
alias_hash_table = NULL;
77+
return ret;
78+
}
79+
80+
return OPAL_SUCCESS;
81+
}
82+
83+
static char *mca_base_alias_generate_name (const char *project, const char *framework, const char *component_name)
84+
{
85+
size_t project_length = project ? strlen (project) : 0;
86+
size_t framework_length = framework ? strlen (framework) : 0;
87+
size_t component_name_length = strlen (component_name);
88+
size_t length = project_length + framework_length + component_name_length + 2;
89+
char *tmp = calloc (1, length + 1);
90+
if (NULL == tmp) {
91+
return tmp;
92+
}
93+
94+
if (project_length) {
95+
strncat (tmp, project, length);
96+
strncat (tmp, "_", 1);
97+
length -= project_length + 1;
98+
}
99+
100+
if (framework_length) {
101+
strncat (tmp, framework, length);
102+
strncat (tmp, "_", 1);
103+
length -= framework_length + 1;
104+
}
105+
106+
strncat (tmp, component_name, length);
107+
108+
return tmp;
109+
}
110+
111+
static mca_base_alias_t *mca_base_alias_lookup_internal (const char *name)
112+
{
113+
mca_base_alias_t *alias = NULL;
114+
if (NULL == alias_hash_table) {
115+
return NULL;
116+
}
117+
118+
(void) opal_hash_table_get_value_ptr (alias_hash_table, name, strlen (name), (void **) &alias);
119+
return alias;
120+
}
121+
122+
int mca_base_alias_register (const char *project, const char *framework, const char *component_name,
123+
const char *component_alias, uint32_t alias_flags)
124+
{
125+
if (NULL == component_name) {
126+
return OPAL_ERR_BAD_PARAM;
127+
}
128+
129+
int ret = mca_base_alias_setup ();
130+
if (OPAL_SUCCESS != ret) {
131+
return ret;
132+
}
133+
134+
char *name = mca_base_alias_generate_name (project, framework, component_name);
135+
assert (NULL != name);
136+
137+
mca_base_alias_t *alias = mca_base_alias_lookup_internal (name);
138+
if (NULL == alias) {
139+
alias = OBJ_NEW(mca_base_alias_t);
140+
if (NULL == alias) {
141+
return OPAL_ERR_OUT_OF_RESOURCE;
142+
}
143+
144+
opal_hash_table_set_value_ptr (alias_hash_table, name, strlen(name), alias);
145+
free (name);
146+
}
147+
148+
mca_base_alias_item_t *alias_item = OBJ_NEW(mca_base_alias_item_t);
149+
if (NULL == alias_item) {
150+
return OPAL_ERR_OUT_OF_RESOURCE;
151+
}
152+
153+
alias_item->component_alias = strdup (component_alias);
154+
alias_item->alias_flags = alias_flags;
155+
156+
opal_list_append (&alias->component_aliases, &alias_item->super);
157+
158+
return OPAL_SUCCESS;
159+
}
160+
161+
const mca_base_alias_t *mca_base_alias_lookup(const char *project, const char *framework, const char *component_name)
162+
{
163+
if (NULL == component_name) {
164+
return NULL;
165+
}
166+
167+
char *name = mca_base_alias_generate_name (project, framework, component_name);
168+
assert (NULL != name);
169+
const mca_base_alias_t *alias = mca_base_alias_lookup_internal (name);
170+
free (name);
171+
172+
return alias;
173+
}

opal/mca/base/mca_base_alias.h

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
2+
/*
3+
* Copyright (c) 2020 Google, LLC. All rights reserved.
4+
* $COPYRIGHT$
5+
*
6+
* Additional copyrights may follow
7+
*
8+
* $HEADER$
9+
*/
10+
11+
#ifndef OPAL_MCA_BASE_ALIAS_H
12+
#define OPAL_MCA_BASE_ALIAS_H
13+
14+
#include "opal_config.h"
15+
#include "opal/class/opal_list.h"
16+
17+
BEGIN_C_DECLS
18+
19+
enum mca_base_alias_flags_t {
20+
MCA_BASE_ALIAS_FLAG_NONE = 0,
21+
/** The aliased name has been deprecated. */
22+
MCA_BASE_ALIAS_FLAG_DEPRECATED = 1,
23+
};
24+
25+
typedef enum mca_base_alias_flags_t mca_base_alias_flags_t;
26+
27+
struct mca_base_alias_item_t {
28+
opal_list_item_t super;
29+
/** Name aias. */
30+
char *component_alias;
31+
/** Alias flags. */
32+
uint32_t alias_flags;
33+
};
34+
35+
typedef struct mca_base_alias_item_t mca_base_alias_item_t;
36+
37+
OBJ_CLASS_DECLARATION(mca_base_alias_item_t);
38+
39+
struct mca_base_alias_t {
40+
opal_object_t super;
41+
/** List of name aliases. */
42+
opal_list_t component_aliases;
43+
};
44+
45+
typedef struct mca_base_alias_t mca_base_alias_t;
46+
47+
OBJ_CLASS_DECLARATION(mca_base_alias_t);
48+
49+
/**
50+
* @brief Create a alias for a component name.
51+
*
52+
* @param[in] project Project name (may be NULL)
53+
* @param[in] framework Framework name (may be NULL)
54+
* @param[in] component_name Name of component to alias (may not be NULL)
55+
* @param[in] component_alias Aliased name (may not be NULL)
56+
* @param[in] alias_flags Flags (see mca_base_alias_flags_t)
57+
*
58+
* This function aliases one component name to another. When aliased
59+
* any variable registered with this project, framework, and
60+
* component_name will have synonyms created. For example, if
61+
* opal_btl_vader is aliased to sm then registers a variable
62+
* named btl_vader_flags then a synonym will be created with the
63+
* name btl_sm_flags. If an alias is registered early enough
64+
* (during framework registration for example) then the alias can
65+
* also be used for component selection. In the previous example
66+
* --mca btl vader and --mca btl sm would select the same
67+
* component if the synonym is registered in the btl framework
68+
* registration function.
69+
*/
70+
OPAL_DECLSPEC int mca_base_alias_register (const char *project, const char *framework,
71+
const char *component_name,
72+
const char *component_alias,
73+
uint32_t alias_flags);
74+
75+
/**
76+
* @brief Check for aliases for a component.
77+
*
78+
* @param[in] project Project name (may be NULL)
79+
* @param[in] frameworek Framework name (may be NULL)
80+
* @param[in] component_name Component name (may not be NULL)
81+
*/
82+
OPAL_DECLSPEC const mca_base_alias_t *mca_base_alias_lookup(const char *project,
83+
const char *framework,
84+
const char *component_name);
85+
86+
#endif /* OPAL_MCA_BASE_ALIAS_H */

0 commit comments

Comments
 (0)