1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
2 /*
3  * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
4  *                         University Research and Technology
5  *                         Corporation.  All rights reserved.
6  * Copyright (c) 2004-2007 The University of Tennessee and The University
7  *                         of Tennessee Research Foundation.  All rights
8  *                         reserved.
9  * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
10  *                         University of Stuttgart.  All rights reserved.
11  * Copyright (c) 2004-2005 The Regents of the University of California.
12  *                         All rights reserved.
13  * Copyright (c) 2007      Sun Microsystems, Inc.  All rights reserved.
14  * Copyright (c) 2012-2014 Los Alamos National Security, LLC.
15  *                         All rights reserved.
16  * Copyright (c) 2014-2015 Research Organization for Information Science
17  *                         and Technology (RIST). All rights reserved.
18  * Copyright (c) 2014      Cisco Systems, Inc.  All rights reserved.
19  * $COPYRIGHT$
20  *
21  * Additional copyrights may follow
22  *
23  * $HEADER$
24  */
25 
26 #include "opal_config.h"
27 
28 #include "opal/util/argv.h"
29 #include "opal/util/output.h"
30 #include "opal/util/show_help.h"
31 #include "opal/mca/mca.h"
32 #include "opal/mca/base/base.h"
33 #include "opal/mca/base/mca_base_component_repository.h"
34 #include "opal/runtime/opal.h"
35 #include "opal/mca/btl/btl.h"
36 #include "opal/mca/btl/base/btl_base_error.h"
37 #include "opal/mca/btl/base/base.h"
38 
39 OBJ_CLASS_INSTANCE( mca_btl_base_selected_module_t,
40                     opal_list_item_t,
41                     NULL,
42                     NULL );
43 
44 /**
45  * Function for weeding out btl components that don't want to run.
46  *
47  * Call the init function on all available components to find out if
48  * they want to run.  Select all components that don't fail.  Failing
49  * components will be closed and unloaded.  The selected modules will
50  * be returned to the caller in a opal_list_t.
51  */
mca_btl_base_select(bool enable_progress_threads,bool enable_mpi_threads)52 int mca_btl_base_select(bool enable_progress_threads,
53                         bool enable_mpi_threads)
54 {
55     int i, num_btls;
56     mca_base_component_list_item_t *cli, *next;
57     mca_btl_base_component_t *component;
58     mca_btl_base_module_t **modules;
59     mca_btl_base_selected_module_t *sm;
60 
61     char** include = opal_argv_split(mca_btl_base_include, ',');
62     char** exclude = opal_argv_split(mca_btl_base_exclude, ',');
63 
64     /* Traverse the list of opened modules; call their init
65        functions. */
66 
67     OPAL_LIST_FOREACH_SAFE(cli, next, &opal_btl_base_framework.framework_components, mca_base_component_list_item_t) {
68         component = (mca_btl_base_component_t *) cli->cli_component;
69 
70         /* if there is an include list - item must be in the list to be included */
71         if ( NULL != include ) {
72             char** argv = include;
73             bool found = false;
74             while(argv && *argv) {
75                 if(strcmp(component->btl_version.mca_component_name,*argv) == 0) {
76                     found = true;
77                     break;
78                 }
79                 argv++;
80             }
81             if(found == false) {
82                 continue;
83             }
84 
85             /* otherwise - check the exclude list to see if this item has been specifically excluded */
86         } else if ( NULL != exclude ) {
87             char** argv = exclude;
88             bool found = false;
89             while(argv && *argv) {
90                 if(strcmp(component->btl_version.mca_component_name,*argv) == 0) {
91                     found = true;
92                     break;
93                 }
94                 argv++;
95             }
96             if(found == true) {
97                 continue;
98             }
99         }
100 
101         opal_output_verbose(10, opal_btl_base_framework.framework_output,
102                             "select: initializing %s component %s",
103                             component->btl_version.mca_type_name,
104                             component->btl_version.mca_component_name);
105         if (NULL == component->btl_init) {
106             opal_output_verbose(10, opal_btl_base_framework.framework_output,
107                                 "select: no init function; ignoring component %s",
108                                 component->btl_version.mca_component_name);
109         } else {
110             modules = component->btl_init(&num_btls, enable_progress_threads,
111                                           enable_mpi_threads);
112 
113             /* If the component didn't initialize, remove it from the opened
114                list and remove it from the component repository */
115 
116             if (NULL == modules) {
117                 opal_output_verbose(10, opal_btl_base_framework.framework_output,
118                                     "select: init of component %s returned failure",
119                                     component->btl_version.mca_component_name);
120 
121                 opal_list_remove_item(&opal_btl_base_framework.framework_components, &cli->super);
122                 OBJ_RELEASE(cli);
123                 mca_base_component_close((mca_base_component_t *) component,
124                                          opal_btl_base_framework.framework_output);
125             }
126 
127             /* Otherwise, if it initialized properly, save it. */
128 
129             else {
130                 opal_output_verbose(10, opal_btl_base_framework.framework_output,
131                                     "select: init of component %s returned success",
132                                     component->btl_version.mca_component_name);
133 
134                 for (i = 0; i < num_btls; ++i) {
135                     /* If modules[i] is NULL, it's a developer error */
136                     if (NULL == modules[i]) {
137                         BTL_ERROR(("BTL module init of %s returned a NULL -- this should never happen, and is a developer error.  Contact the Open MPI developers.",
138                                    component->btl_version.mca_component_name));
139                         exit(1);
140                     }
141                     sm = OBJ_NEW(mca_btl_base_selected_module_t);
142                     if (NULL == sm) {
143                         if (NULL != include) {
144                             opal_argv_free(include);
145                         }
146                         if (NULL != exclude) {
147                             opal_argv_free(exclude);
148                         }
149                         return OPAL_ERR_OUT_OF_RESOURCE;
150                     }
151                     sm->btl_component = component;
152                     sm->btl_module = modules[i];
153                     opal_list_append(&mca_btl_base_modules_initialized,
154                                      (opal_list_item_t*) sm);
155                 }
156                 free(modules);
157             }
158         }
159     }
160 
161     if (NULL != include) {
162         opal_argv_free(include);
163     }
164     if (NULL != exclude) {
165         opal_argv_free(exclude);
166     }
167 
168     /* Finished querying all components.  Check for the bozo case. */
169 
170     if (0 == opal_list_get_size(&mca_btl_base_modules_initialized)) {
171         opal_show_help("help-mca-base.txt", "find-available:none found",
172                        true,
173                        "btl",
174                        opal_process_info.nodename,
175                        "btl");
176         return OPAL_ERROR;
177     }
178     return OPAL_SUCCESS;
179 }
180