1 /*
2 * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
3 * University Research and Technology
4 * Corporation. All rights reserved.
5 * Copyright (c) 2004-2017 The University of Tennessee and The University
6 * of Tennessee Research Foundation. All rights
7 * reserved.
8 * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
9 * University of Stuttgart. All rights reserved.
10 * Copyright (c) 2004-2005 The Regents of the University of California.
11 * All rights reserved.
12 * Copyright (c) 2008-2014 Cisco Systems, Inc. All rights reserved.
13 * Copyright (c) 2012 Los Alamos National Security, LLC.
14 * All rights reserved.
15 * Copyright (c) 2014 Research Organization for Information Science
16 * and Technology (RIST). All rights reserved.
17 * $COPYRIGHT$
18 *
19 * Additional copyrights may follow
20 *
21 * $HEADER$
22 */
23
24 #include "ompi_config.h"
25
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29
30 #include "mpi.h"
31 #include "opal/util/show_help.h"
32 #include "ompi/constants.h"
33 #include "opal/class/opal_list.h"
34 #include "opal/util/output.h"
35 #include "ompi/mca/mca.h"
36 #include "opal/mca/base/base.h"
37 #include "opal/mca/base/mca_base_component_repository.h"
38
39 #include "ompi/mca/rte/rte.h"
40 #include "ompi/mca/coll/coll.h"
41 #include "ompi/mca/coll/base/base.h"
42
43 /*
44 * Private functions
45 */
46 static int init_query(const mca_base_component_t * ls,
47 bool enable_progress_threads,
48 bool enable_mpi_threads);
49
50 /*
51 * Scan down the list of successfully opened components and query each of
52 * them (the opened list will be one or more components. If the user
53 * requested a specific component, it will be the only component in the
54 * opened list). Create and populate the available list of all
55 * components who indicate that they want to be considered for selection.
56 * Close all components who do not want to be considered for selection,
57 * and destroy the opened list.
58 *
59 * Also find the basic component while we're doing all of this, and save
60 * it in a global variable so that we can find it easily later (e.g.,
61 * during scope selection).
62 */
63 int mca_coll_base_find_available(bool enable_progress_threads,
64 bool enable_mpi_threads)
65 {
66 mca_base_component_list_item_t *cli, *next;
67 const mca_base_component_t *component;
68
69 /* The list of components that we should check has already been
70 established in mca_coll_base_open. */
71
72 OPAL_LIST_FOREACH_SAFE(cli, next, &ompi_coll_base_framework.framework_components, mca_base_component_list_item_t) {
73 component = cli->cli_component;
74
75 /* Call a subroutine to do the work, because the component may
76 represent different versions of the coll MCA. */
77
78 if (OMPI_SUCCESS != init_query(component, enable_progress_threads,
79 enable_mpi_threads)) {
80 /* If the component doesn't want to run, then close it.
81 Now close it out and release it from the DSO repository (if it's there). */
82 opal_list_remove_item(&ompi_coll_base_framework.framework_components, &cli->super);
83 mca_base_component_close(component, ompi_coll_base_framework.framework_output);
84 OBJ_RELEASE(cli);
85 }
86 }
87
88 /* If we have no collective components available, it's an error.
89 Thanks for playing! */
90
91 if (opal_list_get_size(&ompi_coll_base_framework.framework_components) == 0) {
92 opal_output_verbose(10, ompi_coll_base_framework.framework_output,
93 "coll:find_available: no coll components available!");
94 opal_show_help("help-mca-base.txt", "find-available:not-valid", true,
95 "coll");
96 return OMPI_ERROR;
97 }
98
99 /* All done */
100
101 return OMPI_SUCCESS;
102 }
103
104
105 /*
106 * Query a specific component, coll v2.0.0
107 */
108 static inline int
109 init_query_2_0_0(const mca_base_component_t * component,
110 bool enable_progress_threads,
111 bool enable_mpi_threads)
112 {
113 mca_coll_base_component_2_0_0_t *coll =
114 (mca_coll_base_component_2_0_0_t *) component;
115
116 return coll->collm_init_query(enable_progress_threads,
117 enable_mpi_threads);
118 }
119 /*
120 * Query a component, see if it wants to run at all. If it does, save
121 * some information. If it doesn't, close it.
122 */
123 static int init_query(const mca_base_component_t * component,
124 bool enable_progress_threads, bool enable_mpi_threads)
125 {
126 int ret;
127
128 opal_output_verbose(10, ompi_coll_base_framework.framework_output,
129 "coll:find_available: querying coll component %s",
130 component->mca_component_name);
131
132 /* This component has already been successfully opened. So now
133 query it. */
134
135 if (2 == component->mca_type_major_version &&
136 0 == component->mca_type_minor_version &&
137 0 == component->mca_type_release_version) {
138 ret = init_query_2_0_0(component, enable_progress_threads,
139 enable_mpi_threads);
140 } else {
141 /* Unrecognized coll API version */
142
143 opal_output_verbose(10, ompi_coll_base_framework.framework_output,
144 "coll:find_available: unrecognized coll API version (%d.%d.%d, ignored)",
145 component->mca_type_major_version,
146 component->mca_type_minor_version,
147 component->mca_type_release_version);
148 return OMPI_ERROR;
149 }
150
151 /* Query done -- look at the return value to see what happened */
152 opal_output_verbose(10, ompi_coll_base_framework.framework_output,
153 "coll:find_available: coll component %s is %savailable",
154 component->mca_component_name,
155 (OMPI_SUCCESS == ret) ? "": "not ");
156
157 return ret;
158 }
159