Skip to content

Commit b66e27d

Browse files
authored
Merge pull request #7671 from hjelmn/add_support_for_component_aliasing_and_reluctantly_rename_vader_to_btl_sm
Add support for component aliasing
2 parents 1b6622f + 9d8f634 commit b66e27d

35 files changed

+1676
-1315
lines changed

README

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -594,7 +594,6 @@ MPI Functionality and Features
594594
- tcp
595595
- ugni
596596
- usnic
597-
- vader (shared memory)
598597

599598
Currently, MPI File operations are not thread safe even if MPI is
600599
initialized for MPI_THREAD_MULTIPLE support.
@@ -675,8 +674,8 @@ Network Support
675674
- SMCUDA
676675
- Cisco usNIC
677676
- uGNI (Cray Gemini, Aries)
678-
- vader (XPMEM, Linux CMA, Linux KNEM, and copy-in/copy-out shared
679-
memory)
677+
- shared memory (XPMEM, Linux CMA, Linux KNEM, and
678+
copy-in/copy-out shared memory)
680679

681680
- "cm" supports a smaller number of networks (and they cannot be
682681
used together), but may provide better overall MPI performance:
@@ -785,16 +784,16 @@ Network Support
785784
v2.6.15 with libibverbs v1.1 or later (first released as part of
786785
OFED v1.2), per restrictions imposed by the OFED network stack.
787786

788-
- Linux "knem" support is used when the "vader" or "sm" (shared
789-
memory) BTLs are compiled with knem support (see the --with-knem
790-
configure option) and the knem Linux module is loaded in the running
791-
kernel. If the knem Linux kernel module is not loaded, the knem
792-
support is (by default) silently deactivated during Open MPI jobs.
787+
- Linux "knem" support is used when the "sm" (shared memory) BTL is
788+
compiled with knem support (see the --with-knem configure option)
789+
and the knem Linux module is loaded in the running kernel. If the
790+
knem Linux kernel module is not loaded, the knem support is (by
791+
default) silently deactivated during Open MPI jobs.
793792

794793
See https://knem.gforge.inria.fr/ for details on Knem.
795794

796-
- Linux Cross-Memory Attach (CMA) or XPMEM is used by the vader
797-
shared-memory BTL when the CMA/XPMEM libraries are installedm,
795+
- Linux Cross-Memory Attach (CMA) or XPMEM is used by the "sm" shared
796+
memory BTL when the CMA/XPMEM libraries are installedm,
798797
respectively. Linux CMA and XPMEM are similar (but different)
799798
mechanisms for Open MPI to utilize single-copy semantics for shared
800799
memory.
@@ -2154,14 +2153,14 @@ comma-delimited list to the "btl" MCA parameter:
21542153

21552154
shell$ mpirun --mca btl tcp,self hello_world_mpi
21562155

2157-
To add shared memory support, add "vader" into the command-delimited
2158-
list (list order does not matter):
2156+
To add shared memory support, add "sm" into the command-delimited list
2157+
(list order does not matter):
21592158

2160-
shell$ mpirun --mca btl tcp,vader,self hello_world_mpi
2159+
shell$ mpirun --mca btl tcp,sm,self hello_world_mpi
21612160

2162-
(there is an "sm" shared memory BTL, too, but "vader" is a newer
2163-
generation of shared memory support; by default, "vader" will be used
2164-
instead of "sm")
2161+
(there used to be a "vader" BTL for shared memory support; it was
2162+
renamed to "sm" in Open MPI v5.0.0, but the alias "vader" still works
2163+
as well)
21652164

21662165
To specifically deactivate a specific component, the comma-delimited
21672166
list can be prepended with a "^" to negate it:

opal/class/opal_hash_table.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,13 @@ OPAL_DECLSPEC int opal_proc_table_get_next_key(opal_proc_table_t *pt, opal_proce
486486
for (void *_nptr=NULL; \
487487
OPAL_SUCCESS == opal_hash_table_get_next_key_##type(ht, &key, (void **)&value, _nptr, &_nptr);)
488488

489+
#define OPAL_HASH_TABLE_FOREACH_PTR(key, value, ht, body) \
490+
{ \
491+
size_t key_size_; \
492+
for (void *_nptr=NULL; \
493+
OPAL_SUCCESS == opal_hash_table_get_next_key_ptr (ht, &key, &key_size_, (void **)&value, _nptr, &_nptr);) \
494+
body \
495+
}
489496
END_C_DECLS
490497

491498
#endif /* OPAL_HASH_TABLE_H */

opal/class/opal_list.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,11 @@ typedef struct opal_list_t opal_list_t;
215215
item != (type *) &(list)->opal_list_sentinel ; \
216216
item = (type *) ((opal_list_item_t *) (item))->opal_list_next)
217217

218+
#define OPAL_LIST_FOREACH_DECL(item, list, type) \
219+
for (type *item = (type *) (list)->opal_list_sentinel.opal_list_next ; \
220+
item != (type *) &(list)->opal_list_sentinel ; \
221+
item = (type *) ((opal_list_item_t *) (item))->opal_list_next)
222+
218223
/**
219224
* Loop over a list in reverse.
220225
*

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)