2004-07-21 02:32:45 +04:00
|
|
|
/*
|
2005-11-05 22:57:48 +03:00
|
|
|
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
|
|
|
* University Research and Technology
|
|
|
|
* Corporation. All rights reserved.
|
2013-07-01 16:40:08 +04:00
|
|
|
* Copyright (c) 2004-2013 The University of Tennessee and The University
|
2005-11-05 22:57:48 +03:00
|
|
|
* of Tennessee Research Foundation. All rights
|
|
|
|
* reserved.
|
2015-06-24 06:59:57 +03:00
|
|
|
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
2004-11-28 23:09:25 +03:00
|
|
|
* University of Stuttgart. All rights reserved.
|
2005-03-24 15:43:37 +03:00
|
|
|
* Copyright (c) 2004-2005 The Regents of the University of California.
|
|
|
|
* All rights reserved.
|
2013-12-20 00:41:32 +04:00
|
|
|
* Copyright (c) 2008-2013 Cisco Systems, Inc. All rights reserved.
|
2014-05-17 02:23:52 +04:00
|
|
|
* Copyright (c) 2012-2013 Inria. All rights reserved.
|
2004-11-22 04:38:40 +03:00
|
|
|
* $COPYRIGHT$
|
2015-06-24 06:59:57 +03:00
|
|
|
*
|
2004-11-22 04:38:40 +03:00
|
|
|
* Additional copyrights may follow
|
2015-06-24 06:59:57 +03:00
|
|
|
*
|
2004-07-21 02:32:45 +04:00
|
|
|
* $HEADER$
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "ompi_config.h"
|
|
|
|
|
2004-11-05 10:52:30 +03:00
|
|
|
#include <string.h>
|
|
|
|
|
2005-07-03 20:22:16 +04:00
|
|
|
#include "opal/class/opal_list.h"
|
2005-07-04 04:13:44 +04:00
|
|
|
#include "opal/util/argv.h"
|
2009-02-14 05:26:12 +03:00
|
|
|
#include "opal/util/output.h"
|
2015-03-06 06:50:44 +03:00
|
|
|
#include "ompi/mca/mca.h"
|
2006-02-12 04:33:29 +03:00
|
|
|
#include "opal/mca/base/base.h"
|
2013-07-01 16:40:08 +04:00
|
|
|
|
2006-02-12 04:33:29 +03:00
|
|
|
#include "ompi/mca/topo/topo.h"
|
|
|
|
#include "ompi/mca/topo/base/base.h"
|
|
|
|
#include "ompi/communicator/communicator.h"
|
2004-07-21 02:32:45 +04:00
|
|
|
|
2004-08-02 04:24:22 +04:00
|
|
|
/*
|
|
|
|
* Local functions
|
|
|
|
*/
|
2013-07-01 16:40:08 +04:00
|
|
|
static void fill_null_pointers(int type, mca_topo_base_module_t *module);
|
2004-08-02 04:24:22 +04:00
|
|
|
|
|
|
|
|
2004-07-21 02:32:45 +04:00
|
|
|
/*
|
2013-07-01 16:40:08 +04:00
|
|
|
* This structure is needed so that we can close the modules
|
2004-07-21 02:32:45 +04:00
|
|
|
* which are not selected but were opened. mca_base_modules_close
|
2005-07-03 20:22:16 +04:00
|
|
|
* which does this job for us requires a opal_list_t which contains
|
2004-07-21 02:32:45 +04:00
|
|
|
* these modules
|
|
|
|
*/
|
|
|
|
struct queried_module_t {
|
2005-07-03 20:22:16 +04:00
|
|
|
opal_list_item_t super;
|
2004-08-02 04:24:22 +04:00
|
|
|
mca_topo_base_component_t *om_component;
|
2004-07-21 02:32:45 +04:00
|
|
|
mca_topo_base_module_t *om_module;
|
|
|
|
};
|
|
|
|
typedef struct queried_module_t queried_module_t;
|
2005-07-03 20:22:16 +04:00
|
|
|
static OBJ_CLASS_INSTANCE(queried_module_t, opal_list_item_t, NULL, NULL);
|
2004-07-21 02:32:45 +04:00
|
|
|
|
|
|
|
/*
|
2013-07-01 16:40:08 +04:00
|
|
|
* Only one topo module can be attached to each communicator. The
|
|
|
|
* communicator provided as argument is the old communicator, and the
|
|
|
|
* newly selected topology is __not__ supposed to be attached to it.
|
2004-07-21 02:32:45 +04:00
|
|
|
*
|
2004-08-02 04:24:22 +04:00
|
|
|
* This module calls the query funtion on all the components that were
|
|
|
|
* detected by topo_base_open. This function is called on a
|
|
|
|
* per-communicator basis. This function has the following function.
|
2004-07-21 02:32:45 +04:00
|
|
|
*
|
2013-07-01 16:40:08 +04:00
|
|
|
* 1. Iterate over the list of available_components.
|
2004-08-02 04:24:22 +04:00
|
|
|
* 2. Call the query function on each of these components.
|
2013-07-01 16:40:08 +04:00
|
|
|
* 3. The query function returns a module and its priority.
|
|
|
|
* 4. Select the module with the highest priority.
|
|
|
|
* 5. OBJ_RELEASE all the "losing" modules.
|
2015-06-24 06:59:57 +03:00
|
|
|
*/
|
2013-07-01 16:40:08 +04:00
|
|
|
int mca_topo_base_comm_select(const ompi_communicator_t* comm,
|
|
|
|
mca_topo_base_module_t* preferred_module,
|
|
|
|
mca_topo_base_module_t** selected_module,
|
|
|
|
uint32_t type)
|
2004-08-02 04:24:22 +04:00
|
|
|
{
|
2013-07-01 16:40:08 +04:00
|
|
|
int priority;
|
|
|
|
int best_priority;
|
2015-06-24 06:59:57 +03:00
|
|
|
opal_list_item_t *item;
|
2013-03-28 01:17:31 +04:00
|
|
|
mca_base_component_list_item_t *cli;
|
2015-06-24 06:59:57 +03:00
|
|
|
mca_topo_base_component_t *component;
|
2004-08-02 04:24:22 +04:00
|
|
|
mca_topo_base_component_t *best_component;
|
2015-06-24 06:59:57 +03:00
|
|
|
mca_topo_base_module_t *module;
|
2005-07-03 20:22:16 +04:00
|
|
|
opal_list_t queried;
|
2004-07-21 02:32:45 +04:00
|
|
|
queried_module_t *om;
|
2004-09-23 03:58:13 +04:00
|
|
|
int err = MPI_SUCCESS;
|
2004-07-21 02:32:45 +04:00
|
|
|
|
2013-07-01 16:40:08 +04:00
|
|
|
/* Ensure the topo framework is initialized */
|
|
|
|
if (OMPI_SUCCESS != (err = mca_topo_base_lazy_init())) {
|
|
|
|
return err;
|
|
|
|
}
|
2013-03-28 01:17:31 +04:00
|
|
|
opal_output_verbose(10, ompi_topo_base_framework.framework_output,
|
2013-07-01 16:40:08 +04:00
|
|
|
"topo:base:comm_select: new communicator: %s (cid %d)",
|
|
|
|
comm->c_name, comm->c_contextid);
|
2004-08-06 00:31:14 +04:00
|
|
|
|
|
|
|
/* Check and see if a preferred component was provided. If it was
|
2013-07-01 16:40:08 +04:00
|
|
|
provided then it should be used (if possible) */
|
|
|
|
if (NULL != preferred_module) {
|
2004-08-02 04:24:22 +04:00
|
|
|
|
2013-07-01 16:40:08 +04:00
|
|
|
/* We have a preferred module. Check if it is available
|
2004-07-21 02:32:45 +04:00
|
|
|
and if so, whether it wants to run */
|
2015-06-24 06:59:57 +03:00
|
|
|
|
2013-03-28 01:17:31 +04:00
|
|
|
opal_output_verbose(10, ompi_topo_base_framework.framework_output,
|
2004-08-02 04:24:22 +04:00
|
|
|
"topo:base:comm_select: Checking preferred component: %s",
|
2013-07-01 16:40:08 +04:00
|
|
|
preferred_module->topo_component->topoc_version.mca_component_name);
|
2004-07-21 02:32:45 +04:00
|
|
|
|
2015-06-24 06:59:57 +03:00
|
|
|
/* query the component for its priority and get its module
|
2004-07-21 02:32:45 +04:00
|
|
|
structure. This is necessary to proceed */
|
2013-07-01 16:40:08 +04:00
|
|
|
component = (mca_topo_base_component_t *)preferred_module->topo_component;
|
|
|
|
module = component->topoc_comm_query(comm, &priority, type);
|
|
|
|
if (NULL != module) {
|
2004-07-21 02:32:45 +04:00
|
|
|
|
2004-08-02 04:24:22 +04:00
|
|
|
/* this query seems to have returned something legitimate
|
2013-07-01 16:40:08 +04:00
|
|
|
* and we can now go ahead fill the NULL functions with the
|
|
|
|
* corresponding base version and then return.
|
|
|
|
*/
|
|
|
|
fill_null_pointers(type, module);
|
|
|
|
*selected_module = module;
|
|
|
|
module->topo_component = component;
|
|
|
|
return OMPI_SUCCESS;
|
2015-06-24 06:59:57 +03:00
|
|
|
}
|
2013-07-01 16:40:08 +04:00
|
|
|
/* If we get here, the preferred component is present, but is
|
|
|
|
unable to run. This is not a good sign. We should try
|
|
|
|
selecting some other component. We let it fall through
|
|
|
|
and select from the list of available components */
|
|
|
|
}
|
2004-07-21 02:32:45 +04:00
|
|
|
|
|
|
|
/*
|
2013-07-01 16:40:08 +04:00
|
|
|
* We fall here if one of the two things happened:
|
2004-08-02 04:24:22 +04:00
|
|
|
* 1. The preferred component was provided but for some reason was
|
2013-07-01 16:40:08 +04:00
|
|
|
* not able to be selected
|
2004-08-02 04:24:22 +04:00
|
|
|
* 2. No preferred component was provided
|
2004-07-21 02:32:45 +04:00
|
|
|
*
|
2004-08-02 04:24:22 +04:00
|
|
|
* All we need to do is to go through the list of available
|
|
|
|
* components and find the one which has the highest priority and
|
|
|
|
* use that for this communicator
|
2015-06-24 06:59:57 +03:00
|
|
|
*/
|
2004-07-21 02:32:45 +04:00
|
|
|
|
2004-08-02 04:24:22 +04:00
|
|
|
best_component = NULL;
|
2004-07-21 02:32:45 +04:00
|
|
|
best_priority = -1;
|
2005-07-03 20:22:16 +04:00
|
|
|
OBJ_CONSTRUCT(&queried, opal_list_t);
|
2004-07-21 02:32:45 +04:00
|
|
|
|
2013-03-28 01:17:31 +04:00
|
|
|
OPAL_LIST_FOREACH(cli, &ompi_topo_base_framework.framework_components, mca_base_component_list_item_t) {
|
|
|
|
component = (mca_topo_base_component_t *) cli->cli_component;
|
|
|
|
opal_output_verbose(10, ompi_topo_base_framework.framework_output,
|
2004-08-02 04:24:22 +04:00
|
|
|
"select: initialising %s component %s",
|
2013-07-01 16:40:08 +04:00
|
|
|
component->topoc_version.mca_type_name,
|
|
|
|
component->topoc_version.mca_component_name);
|
2004-07-21 02:32:45 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* we can call the query function only if there is a function :-)
|
|
|
|
*/
|
2013-07-01 16:40:08 +04:00
|
|
|
if (NULL == component->topoc_comm_query) {
|
2013-03-28 01:17:31 +04:00
|
|
|
opal_output_verbose(10, ompi_topo_base_framework.framework_output,
|
2004-08-02 04:24:22 +04:00
|
|
|
"select: no query, ignoring the component");
|
2004-07-21 02:32:45 +04:00
|
|
|
} else {
|
|
|
|
/*
|
|
|
|
* call the query function and see what it returns
|
2015-06-24 06:59:57 +03:00
|
|
|
*/
|
2013-07-01 16:40:08 +04:00
|
|
|
module = component->topoc_comm_query(comm, &priority, type);
|
2004-07-21 02:32:45 +04:00
|
|
|
|
2013-07-01 16:40:08 +04:00
|
|
|
if (NULL == module) {
|
2004-07-21 02:32:45 +04:00
|
|
|
/*
|
|
|
|
* query did not return any action which can be used
|
2015-06-24 06:59:57 +03:00
|
|
|
*/
|
2013-03-28 01:17:31 +04:00
|
|
|
opal_output_verbose(10, ompi_topo_base_framework.framework_output,
|
2004-07-21 02:32:45 +04:00
|
|
|
"select: query returned failure");
|
|
|
|
} else {
|
2013-03-28 01:17:31 +04:00
|
|
|
opal_output_verbose(10, ompi_topo_base_framework.framework_output,
|
2007-01-30 23:56:31 +03:00
|
|
|
"select: query returned priority %d",
|
2004-07-21 02:32:45 +04:00
|
|
|
priority);
|
2015-06-24 06:59:57 +03:00
|
|
|
/*
|
2004-08-02 04:24:22 +04:00
|
|
|
* is this the best component we have found till now?
|
2004-07-21 02:32:45 +04:00
|
|
|
*/
|
|
|
|
if (priority > best_priority) {
|
|
|
|
best_priority = priority;
|
2004-08-02 04:24:22 +04:00
|
|
|
best_component = component;
|
2004-07-21 02:32:45 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
om = OBJ_NEW(queried_module_t);
|
|
|
|
/*
|
|
|
|
* check if we have run out of space
|
|
|
|
*/
|
|
|
|
if (NULL == om) {
|
|
|
|
OBJ_DESTRUCT(&queried);
|
|
|
|
return OMPI_ERR_OUT_OF_RESOURCE;
|
|
|
|
}
|
2004-08-02 04:24:22 +04:00
|
|
|
om->om_component = component;
|
2015-06-24 06:59:57 +03:00
|
|
|
om->om_module = module;
|
|
|
|
opal_list_append(&queried, (opal_list_item_t *)om);
|
2004-08-02 04:24:22 +04:00
|
|
|
} /* end else of if (NULL == module) */
|
2013-07-01 16:40:08 +04:00
|
|
|
} /* end else of if (NULL == component->init) */
|
2004-07-21 02:32:45 +04:00
|
|
|
} /* end for ... end of traversal */
|
|
|
|
|
|
|
|
/*
|
2004-08-02 04:24:22 +04:00
|
|
|
* Now we have alist of components which successfully returned
|
|
|
|
* their module struct. One of these components has the best
|
|
|
|
* priority. The rest have to be comm_unqueried to counter the
|
|
|
|
* effects of comm_query'ing them. Finalize happens only on
|
|
|
|
* components which should are initialized.
|
2004-07-21 02:32:45 +04:00
|
|
|
*/
|
2004-08-02 04:24:22 +04:00
|
|
|
if (NULL == best_component) {
|
2013-07-01 16:40:08 +04:00
|
|
|
return OMPI_ERR_NOT_FOUND;
|
2004-07-21 02:32:45 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2004-08-02 04:24:22 +04:00
|
|
|
* We now have a list of components which have successfully
|
|
|
|
* returned their priorities from the query. We now have to
|
|
|
|
* unquery() those components which have not been selected and
|
|
|
|
* init() the component which was selected
|
2015-06-24 06:59:57 +03:00
|
|
|
*/
|
2005-07-03 20:22:16 +04:00
|
|
|
for (item = opal_list_remove_first(&queried);
|
2004-07-21 02:32:45 +04:00
|
|
|
NULL != item;
|
2005-07-03 20:22:16 +04:00
|
|
|
item = opal_list_remove_first(&queried)) {
|
2004-07-21 02:32:45 +04:00
|
|
|
om = (queried_module_t *) item;
|
2004-08-02 04:24:22 +04:00
|
|
|
if (om->om_component == best_component) {
|
2004-07-21 02:32:45 +04:00
|
|
|
/*
|
2004-08-02 04:24:22 +04:00
|
|
|
* this is the chosen component, we have to initialise the
|
|
|
|
* module of this component.
|
2004-07-21 02:32:45 +04:00
|
|
|
*
|
2004-08-02 04:24:22 +04:00
|
|
|
* ANJU: a component might not have all the functions
|
|
|
|
* defined. Whereever a function pointer is null in the
|
|
|
|
* module structure we need to fill it in with the base
|
|
|
|
* structure function pointers. This is yet to be done
|
2015-06-24 06:59:57 +03:00
|
|
|
*/
|
2013-07-01 16:40:08 +04:00
|
|
|
fill_null_pointers(type, om->om_module);
|
|
|
|
om->om_module->topo_component = best_component;
|
|
|
|
*selected_module = om->om_module;
|
2004-07-21 02:32:45 +04:00
|
|
|
} else {
|
2013-07-01 16:40:08 +04:00
|
|
|
/* this is not the "choosen one", finalize */
|
|
|
|
opal_output_verbose(10, ompi_topo_base_framework.framework_output,
|
|
|
|
"select: component %s is not selected",
|
|
|
|
om->om_component->topoc_version.mca_component_name);
|
|
|
|
OBJ_RELEASE(om->om_module);
|
|
|
|
}
|
2004-07-21 02:32:45 +04:00
|
|
|
OBJ_RELEASE(om);
|
|
|
|
} /* traversing through the entire list */
|
2015-06-24 06:59:57 +03:00
|
|
|
|
2013-03-28 01:17:31 +04:00
|
|
|
opal_output_verbose(10, ompi_topo_base_framework.framework_output,
|
2004-08-02 04:24:22 +04:00
|
|
|
"select: component %s selected",
|
2013-07-01 16:40:08 +04:00
|
|
|
best_component->topoc_version.mca_component_name);
|
|
|
|
return OMPI_SUCCESS;
|
2004-07-21 02:32:45 +04:00
|
|
|
}
|
|
|
|
|
2004-08-02 04:24:22 +04:00
|
|
|
|
2004-07-21 02:32:45 +04:00
|
|
|
/*
|
|
|
|
* This function fills in the null function pointers, in other words,
|
2004-08-02 04:24:22 +04:00
|
|
|
* those functions which are not implemented by the module with the
|
|
|
|
* pointers from the base function. Somewhere, I need to incoroporate
|
|
|
|
* a check for the common minimum funtions being implemented by the
|
2013-07-01 16:40:08 +04:00
|
|
|
* module.
|
|
|
|
*/
|
2015-06-24 06:59:57 +03:00
|
|
|
static void fill_null_pointers(int type, mca_topo_base_module_t *module)
|
2004-08-02 04:24:22 +04:00
|
|
|
{
|
2013-07-01 16:40:08 +04:00
|
|
|
if( OMPI_COMM_CART == type ) {
|
|
|
|
if (NULL == module->topo.cart.cart_coords) {
|
|
|
|
module->topo.cart.cart_coords = mca_topo_base_cart_coords;
|
|
|
|
}
|
|
|
|
if (NULL == module->topo.cart.cart_create) {
|
|
|
|
module->topo.cart.cart_create = mca_topo_base_cart_create;
|
|
|
|
}
|
|
|
|
if (NULL == module->topo.cart.cart_get) {
|
|
|
|
module->topo.cart.cart_get = mca_topo_base_cart_get;
|
|
|
|
}
|
|
|
|
if (NULL == module->topo.cart.cartdim_get) {
|
|
|
|
module->topo.cart.cartdim_get = mca_topo_base_cartdim_get;
|
|
|
|
}
|
|
|
|
if (NULL == module->topo.cart.cart_map) {
|
|
|
|
module->topo.cart.cart_map = mca_topo_base_cart_map;
|
|
|
|
}
|
|
|
|
if (NULL == module->topo.cart.cart_rank) {
|
|
|
|
module->topo.cart.cart_rank = mca_topo_base_cart_rank;
|
|
|
|
}
|
|
|
|
if (NULL == module->topo.cart.cart_shift) {
|
|
|
|
module->topo.cart.cart_shift = mca_topo_base_cart_shift;
|
|
|
|
}
|
|
|
|
if (NULL == module->topo.cart.cart_sub) {
|
|
|
|
module->topo.cart.cart_sub = mca_topo_base_cart_sub;
|
|
|
|
}
|
|
|
|
} else if( OMPI_COMM_GRAPH == type ) {
|
|
|
|
if (NULL == module->topo.graph.graph_create) {
|
|
|
|
module->topo.graph.graph_create = mca_topo_base_graph_create;
|
|
|
|
}
|
|
|
|
if (NULL == module->topo.graph.graph_get) {
|
|
|
|
module->topo.graph.graph_get = mca_topo_base_graph_get;
|
|
|
|
}
|
|
|
|
if (NULL == module->topo.graph.graph_map) {
|
|
|
|
module->topo.graph.graph_map = mca_topo_base_graph_map;
|
|
|
|
}
|
|
|
|
if (NULL == module->topo.graph.graphdims_get) {
|
|
|
|
module->topo.graph.graphdims_get = mca_topo_base_graphdims_get;
|
|
|
|
}
|
|
|
|
if (NULL == module->topo.graph.graph_neighbors) {
|
|
|
|
module->topo.graph.graph_neighbors = mca_topo_base_graph_neighbors;
|
|
|
|
}
|
|
|
|
if (NULL == module->topo.graph.graph_neighbors_count) {
|
|
|
|
module->topo.graph.graph_neighbors_count = mca_topo_base_graph_neighbors_count;
|
|
|
|
}
|
|
|
|
} else if( OMPI_COMM_DIST_GRAPH == type ) {
|
|
|
|
if (NULL == module->topo.dist_graph.dist_graph_create) {
|
|
|
|
module->topo.dist_graph.dist_graph_create = mca_topo_base_dist_graph_create;
|
|
|
|
}
|
|
|
|
if (NULL == module->topo.dist_graph.dist_graph_create_adjacent) {
|
|
|
|
module->topo.dist_graph.dist_graph_create_adjacent = mca_topo_base_dist_graph_create_adjacent;
|
|
|
|
}
|
|
|
|
if (NULL == module->topo.dist_graph.dist_graph_neighbors) {
|
|
|
|
module->topo.dist_graph.dist_graph_neighbors = mca_topo_base_dist_graph_neighbors;
|
|
|
|
}
|
|
|
|
if (NULL == module->topo.dist_graph.dist_graph_neighbors_count) {
|
|
|
|
module->topo.dist_graph.dist_graph_neighbors_count = mca_topo_base_dist_graph_neighbors_count;
|
|
|
|
}
|
|
|
|
}
|
2004-07-21 02:32:45 +04:00
|
|
|
}
|