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-2005 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-2009 Cisco Systems, Inc.  All rights reserved.
13  * $COPYRIGHT$
14  *
15  * Additional copyrights may follow
16  *
17  * $HEADER$
18  */
19 
20 #include "ompi_config.h"
21 
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 
26 #include "mpi.h"
27 
28 #include "opal/class/opal_list.h"
29 #include "opal/util/output.h"
30 #include "ompi/mca/mca.h"
31 #include "opal/mca/base/base.h"
32 #include "opal/mca/base/mca_base_component_repository.h"
33 
34 
35 #include "ompi/constants.h"
36 #include "ompi/mca/op/op.h"
37 #include "ompi/mca/op/base/base.h"
38 
39 /*
40  * Private functions
41  */
42 static int init_query(const mca_base_component_t * ls,
43                       bool enable_progress_threads,
44                       bool enable_mpi_threads);
45 static int init_query_1_0_0(const mca_base_component_t * ls,
46                             bool enable_progress_threads,
47                             bool enable_mpi_threads);
48 
49 /*
50  * Scan down the list of successfully opened components and query each
51  * of them (the opened list will be one or more components.  If the
52  * user requested a specific set of components, they will be the only
53  * components in the opened list).  Create and populate the available
54  * list of all components who indicate that they want to be considered
55  * for selection.  Close all components who do not want to be
56  * considered for selection.  Finally, destroy the "opened" list,
57  * because the only the "available" list is relevant now.
58  */
ompi_op_base_find_available(bool enable_progress_threads,bool enable_mpi_threads)59 int ompi_op_base_find_available(bool enable_progress_threads,
60                                 bool enable_mpi_threads)
61 {
62     mca_base_component_list_item_t *cli, *next;
63 
64     /* The list of components that we should check has already been
65        established in ompi_op_base_open. */
66 
67     OPAL_LIST_FOREACH_SAFE(cli, next, &ompi_op_base_framework.framework_components, mca_base_component_list_item_t) {
68         const mca_base_component_t *component = cli->cli_component;
69 
70         /* Call a subroutine to do the work, because the component may
71            represent different versions of the op MCA. */
72 
73         if (OMPI_SUCCESS != init_query(component,
74                                        enable_progress_threads,
75                                        enable_mpi_threads)) {
76 
77             /* If the component doesn't want to run, then close it. */
78             opal_list_remove_item(&ompi_op_base_framework.framework_components, &cli->super);
79             mca_base_component_close(component, ompi_op_base_framework.framework_output);
80             OBJ_RELEASE(cli);
81         }
82     }
83 
84     /* It is not an error if there are no components available; we'll
85        just fall back to the base functions. */
86 
87     return OMPI_SUCCESS;
88 }
89 
90 
91 /*
92  * Query a component, see if it wants to run at all.  If it does, save
93  * some information.  If it doesn't, close it.
94  */
init_query(const mca_base_component_t * c,bool enable_progress_threads,bool enable_mpi_threads)95 static int init_query(const mca_base_component_t * c,
96                       bool enable_progress_threads, bool enable_mpi_threads)
97 {
98     int ret;
99 
100     opal_output_verbose(10, ompi_op_base_framework.framework_output,
101                         "op:find_available: querying op component %s",
102                         c->mca_component_name);
103 
104     /* This component has already been successfully opened.  So now
105        query it. */
106 
107     if (1 == c->mca_type_major_version &&
108         0 == c->mca_type_minor_version &&
109         0 == c->mca_type_release_version) {
110         ret = init_query_1_0_0(c, enable_progress_threads,
111                                enable_mpi_threads);
112     } else {
113         /* Unrecognized op API version */
114 
115         opal_output_verbose(10, ompi_op_base_framework.framework_output,
116                             "op:find_available: unrecognized op API version (%d.%d.%d, ignored)",
117                             c->mca_type_major_version,
118                             c->mca_type_minor_version,
119                             c->mca_type_release_version);
120         return OMPI_ERROR;
121     }
122 
123     /* Query done -- look at the return value to see what happened */
124 
125     if (OMPI_SUCCESS != ret) {
126         opal_output_verbose(10, ompi_op_base_framework.framework_output,
127                             "op:find_available: op component %s is not available",
128                             c->mca_component_name);
129     } else {
130         opal_output_verbose(10, ompi_op_base_framework.framework_output,
131                             "op:find_available: op component %s is available",
132                             c->mca_component_name);
133     }
134 
135     /* All done */
136 
137     return ret;
138 }
139 
140 
141 /*
142  * Query a specific component, op v2.0.0
143  */
init_query_1_0_0(const mca_base_component_t * component,bool enable_progress_threads,bool enable_mpi_threads)144 static int init_query_1_0_0(const mca_base_component_t * component,
145                             bool enable_progress_threads,
146                             bool enable_mpi_threads)
147 {
148     ompi_op_base_component_1_0_0_t *op =
149         (ompi_op_base_component_1_0_0_t *) component;
150 
151     return op->opc_init_query(enable_progress_threads,
152                               enable_mpi_threads);
153 }
154