1
1

Update collectives selection logic to allow for multiple components to be

used at nce (up to one unique collective module per collective function).
Matches r15795:15921 of the tmp/bwb-coll-select branch

This commit was SVN r15924.

The following SVN revisions from the original message are invalid or
inconsistent and therefore were not cross-referenced:
  r15795
  r15921
This commit is contained in:
Brian Barrett 2007-08-19 03:37:49 +00:00
parent 2b8af283de
commit af4e86c25f
145 changed files with 3661 additions and 3472 deletions

View File

@ -31,6 +31,7 @@ dnl
sinclude(@M4DIR@/ompi_setup_cc.m4)
sinclude(@M4DIR@/ompi_check_optflags.m4)
sinclude(@M4DIR@/ompi_check_vendor.m4)
dnl
dnl C++ compiler tests

View File

@ -225,7 +225,7 @@ if test -z "$with_openmpi"; then
top_ompi_srcdir='$(top_srcdir)/../../../..'
top_ompi_builddir='$(top_builddir)/../../../..'
INCFLAGS='-I$(top_ompi_srcdir)/include -I$(top_ompi_builddir)/include -I$(top_ompi_srcdir) -I$(top_ompi_builddir) -I$(top_ompi_srcdir)/opal -I$(top_ompi_builddir)/opal -I$(top_ompi_srcdir)/orte -I$(top_ompi_builddir)/orte -I$(top_ompi_srcdir)/ompi -I$(top_ompi_builddir)/ompi'" $CPPFLAGS"
INCFLAGS='-I$(top_ompi_srcdir) -I$(top_ompi_builddir) -I$(top_ompi_srcdir)/opal/include -I$(top_ompi_builddir)/opal/include -I$(top_ompi_srcdir)/orte/include -I$(top_ompi_builddir)/orte/include -I$(top_ompi_srcdir)/ompi/include -I$(top_ompi_builddir)/ompi/include'" $CPPFLAGS"
found_ompi_headers=1
AC_MSG_RESULT([already in Open MPI source tree])
fi

View File

@ -18,6 +18,7 @@ int main(int argc, char* argv[])
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
printf("Hello, world, I am %d of %d\n", rank, size);
MPI_Barrier(MPI_COMM_WORLD);
MPI_Finalize();
return 0;

View File

@ -60,12 +60,14 @@ static int ompi_comm_fill_rest (ompi_communicator_t *comm,
*/
typedef int ompi_comm_allgatherfct (void* inbuf, int incount, MPI_Datatype intype,
void* outbuf, int outcount, MPI_Datatype outtype,
ompi_communicator_t *comm);
ompi_communicator_t *comm,
struct mca_coll_base_module_1_1_0_t *data);
static int ompi_comm_allgather_emulate_intra (void* inbuf, int incount, MPI_Datatype intype,
void* outbuf, int outcount,
MPI_Datatype outtype,
ompi_communicator_t *comm);
ompi_communicator_t *comm,
struct mca_coll_base_module_1_1_0_t *data);
static int ompi_comm_copy_topo (ompi_communicator_t *oldcomm,
ompi_communicator_t *newcomm);
@ -269,7 +271,8 @@ int ompi_comm_create ( ompi_communicator_t *comm, ompi_group_t *group,
rc = comm->c_coll.coll_allgather ( &(group->grp_my_rank),
1, MPI_INT, allranks,
1, MPI_INT, comm );
1, MPI_INT, comm,
comm->c_coll.coll_allgather_module);
if ( OMPI_SUCCESS != rc ) {
goto exit;
}
@ -355,8 +358,7 @@ int ompi_comm_create ( ompi_communicator_t *comm, ompi_group_t *group,
NULL, /* remote_leader */
mode, /* mode */
-1, /* send first */
0, /* sync_flag */
NULL ); /* coll component */
0); /* sync_flag */
if ( OMPI_SUCCESS != rc ) {
goto exit;
@ -430,7 +432,7 @@ int ompi_comm_split ( ompi_communicator_t* comm, int color, int key,
return OMPI_ERR_OUT_OF_RESOURCE;
}
rc = allgatherfct( myinfo, 2, MPI_INT, results, 2, MPI_INT, comm );
rc = allgatherfct( myinfo, 2, MPI_INT, results, 2, MPI_INT, comm, comm->c_coll.coll_allgather_module );
if ( OMPI_SUCCESS != rc ) {
goto exit;
}
@ -485,7 +487,8 @@ int ompi_comm_split ( ompi_communicator_t* comm, int color, int key,
/* this is an allgather on an inter-communicator */
rc = comm->c_coll.coll_allgather( myinfo, 2, MPI_INT, rresults, 2,
MPI_INT, comm );
MPI_INT, comm,
comm->c_coll.coll_allgather_module);
if ( OMPI_SUCCESS != rc ) {
goto exit;
}
@ -586,8 +589,7 @@ int ompi_comm_split ( ompi_communicator_t* comm, int color, int key,
NULL, /* remote_leader */
mode, /* mode */
-1, /* send first */
0, /* sync_flag */
NULL ); /* coll component */
0); /* sync_flag */
if ( OMPI_SUCCESS != rc ) {
goto exit;
@ -691,8 +693,7 @@ int ompi_comm_dup ( ompi_communicator_t * comm, ompi_communicator_t **newcomm,
NULL, /* remote_leader */
mode, /* mode */
-1, /* send_first */
0, /* sync_flag */
(mca_base_component_t *) comp->c_coll_selected_component /* coll component */
0 /* sync_flag */
);
if ( MPI_SUCCESS != rc ) {
return rc;
@ -706,8 +707,7 @@ int ompi_comm_dup ( ompi_communicator_t * comm, ompi_communicator_t **newcomm,
NULL, /* remote_leader */
mode, /* mode */
-1, /* send_first */
1, /* sync_flag */
(mca_base_component_t *) comp->c_coll_selected_component /* coll component */
1 /* sync_flag */
);
if ( MPI_SUCCESS != rc ) {
return rc;
@ -883,7 +883,8 @@ int ompi_comm_set_name (ompi_communicator_t *comm, char *name )
static int ompi_comm_allgather_emulate_intra( void *inbuf, int incount,
MPI_Datatype intype, void* outbuf,
int outcount, MPI_Datatype outtype,
ompi_communicator_t *comm)
ompi_communicator_t *comm,
struct mca_coll_base_module_1_1_0_t *data)
{
int rank, size, rsize, i, rc;
int *tmpbuf=NULL;
@ -1090,7 +1091,8 @@ ompi_proc_t **ompi_comm_get_rprocs ( ompi_communicator_t *local_comm,
/* broadcast buffer length to all processes in local_comm */
rc = local_comm->c_coll.coll_bcast( &rlen, 1, MPI_INT,
local_leader, local_comm );
local_leader, local_comm,
local_comm->c_coll.coll_bcast_module );
if ( OMPI_SUCCESS != rc ) {
goto err_exit;
}
@ -1123,7 +1125,8 @@ ompi_proc_t **ompi_comm_get_rprocs ( ompi_communicator_t *local_comm,
/* broadcast name list to all proceses in local_comm */
rc = local_comm->c_coll.coll_bcast( recvbuf, rlen, MPI_BYTE,
local_leader, local_comm );
local_leader, local_comm,
local_comm->c_coll.coll_bcast_module);
if ( OMPI_SUCCESS != rc ) {
goto err_exit;
}
@ -1220,7 +1223,8 @@ int ompi_comm_determine_first ( ompi_communicator_t *intercomm, int high )
rc = intercomm->c_coll.coll_allgatherv(&high, scount, MPI_INT,
&rhigh, rcounts, rdisps,
MPI_INT, intercomm);
MPI_INT, intercomm,
intercomm->c_coll.coll_allgatherv_module);
if ( rc != OMPI_SUCCESS ) {
flag = MPI_UNDEFINED;
}
@ -1542,8 +1546,7 @@ int ompi_topo_create (ompi_communicator_t *old_comm,
NULL, /* remote_leader */
OMPI_COMM_CID_INTRA, /* mode */
-1, /* send first, doesn't matter */
0, /* sync_flag */
NULL ); /* coll component */
0); /* sync_flag */
if (OMPI_SUCCESS != ret) {
/* something wrong happened during setting the communicator */

View File

@ -405,8 +405,7 @@ int ompi_comm_activate ( ompi_communicator_t* newcomm,
void* remote_leader,
int mode,
int send_first,
int sync_flag,
mca_base_component_t *collcomponent )
int sync_flag)
{
int ok=0, gok=0;
ompi_comm_cid_allredfct* allredfnct;
@ -475,7 +474,7 @@ int ompi_comm_activate ( ompi_communicator_t* newcomm,
/* Let the collectives components fight over who will do
collective on this new comm. */
if (OMPI_SUCCESS !=
(ok = mca_coll_base_comm_select(newcomm, collcomponent))) {
(ok = mca_coll_base_comm_select(newcomm))) {
return ok;
}
}
@ -501,7 +500,8 @@ static int ompi_comm_allreduce_intra ( int *inbuf, int *outbuf,
int send_first )
{
return comm->c_coll.coll_allreduce ( inbuf, outbuf, count, MPI_INT,
op,comm );
op,comm,
comm->c_coll.coll_allreduce_module );
}
/* Arguments not used in this implementation:
@ -548,7 +548,8 @@ static int ompi_comm_allreduce_inter ( int *inbuf, int *outbuf,
/* Execute the inter-allreduce: the result of our group will
be in the buffer of the remote group */
rc = intercomm->c_coll.coll_allreduce ( inbuf, tmpbuf, count, MPI_INT,
op, intercomm );
op, intercomm,
intercomm->c_coll.coll_allreduce_module);
if ( OMPI_SUCCESS != rc ) {
goto exit;
}
@ -610,7 +611,8 @@ static int ompi_comm_allreduce_inter ( int *inbuf, int *outbuf,
sbuf = outbuf;
rc = intercomm->c_coll.coll_allgatherv (sbuf, scount, MPI_INT, outbuf,
rcounts, rdisps, MPI_INT,
intercomm);
intercomm,
intercomm->c_coll.coll_allgatherv_module);
exit:
if ( NULL != tmpbuf ) {
@ -658,7 +660,7 @@ static int ompi_comm_allreduce_intra_bridge (int *inbuf, int *outbuf,
/* Intercomm_create */
rc = comm->c_coll.coll_allreduce ( inbuf, tmpbuf, count, MPI_INT,
op, comm );
op, comm, comm->c_coll.coll_allreduce_module );
if ( OMPI_SUCCESS != rc ) {
goto exit;
}
@ -707,7 +709,7 @@ static int ompi_comm_allreduce_intra_bridge (int *inbuf, int *outbuf,
}
rc = comm->c_coll.coll_bcast ( outbuf, count, MPI_INT, local_leader,
comm);
comm, comm->c_coll.coll_bcast_module );
exit:
if (NULL != tmpbuf ) {
@ -755,7 +757,8 @@ static int ompi_comm_allreduce_intra_oob (int *inbuf, int *outbuf,
}
/* comm is an intra-communicator */
rc = comm->c_coll.coll_allreduce(inbuf,tmpbuf,count,MPI_INT,op, comm );
rc = comm->c_coll.coll_allreduce(inbuf,tmpbuf,count,MPI_INT,op, comm,
comm->c_coll.coll_allreduce_module);
if ( OMPI_SUCCESS != rc ) {
goto exit;
}
@ -811,7 +814,8 @@ static int ompi_comm_allreduce_intra_oob (int *inbuf, int *outbuf,
}
rc = comm->c_coll.coll_bcast (outbuf, count, MPI_INT,
local_leader, comm);
local_leader, comm,
comm->c_coll.coll_bcast_module);
exit:
if (NULL != tmpbuf ) {

View File

@ -175,7 +175,8 @@ int ompi_comm_connect_accept ( ompi_communicator_t *comm, int root,
rnamebuflen_int = (int)rnamebuflen;
/* bcast the buffer-length to all processes in the local comm */
rc = comm->c_coll.coll_bcast (&rnamebuflen_int, 1, MPI_INT, root, comm );
rc = comm->c_coll.coll_bcast (&rnamebuflen_int, 1, MPI_INT, root, comm,
comm->c_coll.coll_bcast_module);
if ( OMPI_SUCCESS != rc ) {
goto exit;
}
@ -195,7 +196,8 @@ int ompi_comm_connect_accept ( ompi_communicator_t *comm, int root,
adds processes, which were not known yet to our
process pool.
*/
rc = comm->c_coll.coll_bcast (rnamebuf, rnamebuflen_int, MPI_BYTE, root, comm );
rc = comm->c_coll.coll_bcast (rnamebuf, rnamebuflen_int, MPI_BYTE, root, comm,
comm->c_coll.coll_bcast_module);
if ( OMPI_SUCCESS != rc ) {
goto exit;
}
@ -280,8 +282,7 @@ int ompi_comm_connect_accept ( ompi_communicator_t *comm, int root,
rport, /* remote leader */
OMPI_COMM_CID_INTRA_OOB, /* mode */
send_first, /* send or recv first */
0, /* sync_flag */
NULL ); /* coll component */
0); /* sync_flag */
if ( OMPI_SUCCESS != rc ) {
goto exit;
}

View File

@ -304,21 +304,17 @@ static void ompi_comm_construct(ompi_communicator_t* comm)
this communiucator */
comm->c_keyhash = NULL;
#if OMPI_ENABLE_DEBUG
memset (&(comm->c_coll), 0, sizeof(mca_coll_base_module_1_0_0_t));
#endif
comm->c_coll_selected_component = NULL;
comm->c_coll_selected_module = NULL;
comm->c_coll_selected_data = NULL;
comm->c_coll_basic_module = NULL;
comm->c_coll_basic_data = NULL;
comm->errhandler_type = OMPI_ERRHANDLER_TYPE_COMM;
#ifdef OMPI_WANT_PERUSE
comm->c_peruse_handles = NULL;
#endif
/* Need to zero out the collectives module because we sometimes
call coll_unselect without a matching call to coll_select, and
we need an easy way for the coll base code to realize we've
done this. */
memset(&comm->c_coll, 0, sizeof(mca_coll_base_comm_coll_t));
return;
}

View File

@ -31,9 +31,7 @@
#include "orte/mca/rml/rml_types.h"
#include "ompi/proc/proc.h"
#if defined(c_plusplus) || defined(__cplusplus)
extern "C" {
#endif
BEGIN_C_DECLS
OMPI_DECLSPEC OBJ_CLASS_DECLARATION(ompi_communicator_t);
@ -154,24 +152,8 @@ struct ompi_communicator_t {
/* Hooks for PML to hang things */
struct mca_pml_comm_t *c_pml_comm;
mca_coll_base_module_1_0_0_t c_coll;
/**< Selected collective module, saved by value for speed (instead
of by reference) */
const mca_coll_base_component_1_0_0_t *c_coll_selected_component;
/**< Selected coll component */
const mca_coll_base_module_1_0_0_t *c_coll_selected_module;
/**< The selected module, but only when the selected module
is not* the basic module. Used during comm_unselect(). */
struct mca_coll_base_comm_t *c_coll_selected_data;
/**< Allow the selected module to cache data on the communicator */
const mca_coll_base_module_1_0_0_t *c_coll_basic_module;
/**< Save the basic module; only necessary when the selected
module is *not* the basic module, but was supplemented
with methods from the basic module. */
struct mca_coll_base_comm_t *c_coll_basic_data;
/**< Allow the basic module to cache data on the communicator */
/* Collectives module interface and data */
mca_coll_base_comm_coll_t c_coll;
};
typedef struct ompi_communicator_t ompi_communicator_t;
OMPI_DECLSPEC extern ompi_communicator_t *ompi_mpi_comm_parent;
@ -436,8 +418,7 @@ struct ompi_communicator_t {
void* remote_leader,
int mode,
int send_first,
int sync_flag,
mca_base_component_t *collcomponent );
int sync_flag );
/**
@ -536,8 +517,6 @@ struct ompi_communicator_t {
ompi_comm_disconnect_obj *ompi_comm_disconnect_init (ompi_communicator_t *comm);
void ompi_comm_disconnect_waitall (int count, ompi_comm_disconnect_obj **objs );
#if defined(c_plusplus) || defined(__cplusplus)
}
#endif
END_C_DECLS
#endif /* OMPI_COMMUNICATOR_H */

View File

@ -117,32 +117,6 @@ int mca_coll_base_find_available(bool enable_progress_threads,
* almost everything else is functional on the communicator (e.g.,
* point-to-point communication).
*
* This function invokes the selection process for coll components,
* which works as follows:
*
* - If the \em preferred argument is NULL, the selection set is
* defined to be all the components found during
* mca_coll_base_find_available().
* - If \em preferred is not NULL, then the selection set is just
* that component. (However, in this mode, we may make 2 passes
* through the selection process -- more on this below).
* - All components in the selection set are queried to see if they
* want to run with that communicator. All components that want to
* run are ranked by their priority and the highest priority
* component is selected. All non-selected components have their
* "unquery" function invoked to let them know that they were not
* selected.
* - The selected component will have its "init" function invoked to
* let it know that it was selected.
* - If we fall through this entire process and no component is
* selected \em and the \em preferred argument is not NULL, then
* run the entire process again as if the \em preferred argument
* was NULL (i.e., use the entire available set of components).
*
* At the end of this process, we'll either have a single component
* that is selected and initialized for the communicator, or no
* component was selected and an error is returned up the stack.
*
* Note that new communicators may be created as a result of
* invoking this function. Specifically: this function is called in
* the depths of communicator creation, but during the execution of
@ -150,8 +124,7 @@ int mca_coll_base_find_available(bool enable_progress_threads,
* communicator creation functions may be re-entered (albiet with
* different arguments).
*/
int mca_coll_base_comm_select(struct ompi_communicator_t *comm,
struct mca_base_component_t *preferred);
int mca_coll_base_comm_select(struct ompi_communicator_t *comm);
/**
* Finalize a coll component on a specific communicator.
@ -176,15 +149,6 @@ int mca_coll_base_comm_select(struct ompi_communicator_t *comm,
*/
int mca_coll_base_comm_unselect(struct ompi_communicator_t *comm);
/**
* Finalize the coll usage on a communicator.
*
* @param comm The communicator that is being destroyed.
*
* @retval OMPI_SUCCESS Always.
*/
int mca_coll_base_comm_finalize(struct ompi_communicator_t *comm);
/**
* Shut down the coll MCA framework.
*
@ -240,14 +204,6 @@ extern bool mca_coll_base_components_available_valid;
*/
extern opal_list_t mca_coll_base_components_available;
/**
* Pointer to the "basic" component so that it can be found easily
* (since the "basic" component is fairly special -- it's the lowest
* common denominator between all coll components and may be used
* interchangably).
*/
OMPI_DECLSPEC extern const mca_coll_base_component_1_0_0_t *mca_coll_base_basic_component;
END_C_DECLS
#endif /* MCA_BASE_COLL_H */

View File

@ -37,19 +37,6 @@
/*
* Local variables
*/
static int basic_priority = -1;
static mca_coll_base_module_1_0_0_t null_module = {
/* Module init and finalize */
NULL, NULL,
/* Collective function pointers */
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL
};
/*
@ -59,9 +46,7 @@ struct avail_coll_t {
opal_list_item_t super;
int ac_priority;
const mca_coll_base_component_1_0_0_t *ac_component;
const mca_coll_base_module_1_0_0_t *ac_module;
struct mca_coll_base_comm_t *ac_data;
mca_coll_base_module_1_1_0_t *ac_module;
};
typedef struct avail_coll_t avail_coll_t;
@ -74,31 +59,15 @@ static opal_list_t *check_components(opal_list_t *components,
char **names, int num_names);
static int check_one_component(ompi_communicator_t *comm,
const mca_base_component_t *component,
const mca_coll_base_module_1_0_0_t **module,
struct mca_coll_base_comm_t **data);
mca_coll_base_module_1_1_0_t **module);
static int query(const mca_base_component_t *component,
ompi_communicator_t *comm, int *priority,
const mca_coll_base_module_1_0_0_t **module,
struct mca_coll_base_comm_t **data);
static int query_1_0_0(const mca_coll_base_component_1_0_0_t *coll_component,
mca_coll_base_module_1_1_0_t **module);
static int query_1_1_0(const mca_coll_base_component_1_1_0_t *coll_component,
ompi_communicator_t *comm, int *priority,
const mca_coll_base_module_1_0_0_t **module,
struct mca_coll_base_comm_t **data);
static void unquery(const mca_coll_base_component_1_0_0_t *coll_component,
ompi_communicator_t *comm,
struct mca_coll_base_comm_t *data);
static void unquery_1_0_0(const mca_coll_base_component_1_0_0_t *coll_component,
ompi_communicator_t *comm,
struct mca_coll_base_comm_t *data);
static int module_init(const mca_coll_base_module_1_0_0_t *module,
ompi_communicator_t *comm);
static int query_basic(ompi_communicator_t *comm);
static int replace_null_with_basic(ompi_communicator_t *comm);
mca_coll_base_module_1_1_0_t **module);
/*
* Stuff for the OBJ interface
@ -106,6 +75,18 @@ static int replace_null_with_basic(ompi_communicator_t *comm);
static OBJ_CLASS_INSTANCE(avail_coll_t, opal_list_item_t, NULL, NULL);
#define COPY(module, comm, func) \
do { \
if (NULL != module->coll_ ## func) { \
if (NULL != comm->c_coll.coll_ ## func ## _module) { \
OBJ_RELEASE(comm->c_coll.coll_ ## func ## _module); \
} \
comm->c_coll.coll_ ## func = module->coll_ ## func; \
comm->c_coll.coll_ ## func ## _module = module; \
OBJ_RETAIN(module); \
} \
} while (0)
/*
* This function is called at the initialization time of every
* communicator. It is used to select which coll component will be
@ -113,23 +94,15 @@ static OBJ_CLASS_INSTANCE(avail_coll_t, opal_list_item_t, NULL, NULL);
*
* This selection logic is not for the weak.
*/
int mca_coll_base_comm_select(ompi_communicator_t *comm,
mca_base_component_t *preferred)
int mca_coll_base_comm_select(ompi_communicator_t *comm)
{
bool found, using_basic;
int err, num_names;
char name[MPI_MAX_OBJECT_NAME + 32];
char *names, **name_array;
char *str;
avail_coll_t *avail;
opal_list_t *selectable;
opal_list_item_t *item;
const mca_coll_base_component_1_0_0_t *selected_component, *component;
const mca_coll_base_module_1_0_0_t *selected_module;
struct mca_coll_base_comm_t *selected_data;
int ret, num_names;
char name[MPI_MAX_OBJECT_NAME + 32];
char *names, **name_array;
opal_list_t *selectable;
opal_list_item_t *item;
/* Announce */
snprintf(name, sizeof(name), "%s (cid %d)", comm->c_name,
comm->c_contextid);
name[sizeof(name) - 1] = '\0';
@ -139,58 +112,15 @@ int mca_coll_base_comm_select(ompi_communicator_t *comm,
/* Initialize all the relevant pointers, since they're used as
sentinel values */
comm->c_coll = null_module;
comm->c_coll_selected_component = NULL;
comm->c_coll_selected_data = NULL;
comm->c_coll_selected_module = NULL;
comm->c_coll_basic_data = NULL;
comm->c_coll_basic_module = NULL;
memset(&comm->c_coll, 0, sizeof(mca_coll_base_comm_coll_t));
/* See if a set of component was requested by the MCA parameter.
Don't check for error. */
names = NULL;
mca_base_param_lookup_string(mca_coll_base_param, &names);
/* Compute the intersection of all of my available components with
the components from all the other processes in this
communicator */
/* JMS CONTINUE HERE */
/* See if a preferred component was provided. If so, try to select
it. If we don't succeed, fall through and do a normal
selection. */
err = OMPI_ERROR;
if (NULL != preferred) {
str = &(preferred->mca_component_name[0]);
opal_output_verbose(10, mca_coll_base_output,
"coll:base:comm_select: Checking preferred module: %s",
str);
selectable = check_components(&mca_coll_base_components_available,
comm, &str, 1);
/* If we didn't get a preferred module, then call again without a
preferred module. This makes the logic below dramatically
simpler. */
if (NULL == selectable) {
return mca_coll_base_comm_select(comm, NULL);
}
/* We only fall through here if we were able to select one of the
preferred modules */
}
/* If there was no preferred module, then see if there were any listed
in the MCA parameter; parse them and check them all */
else if (NULL != names && 0 < strlen(names)) {
if (NULL != names && 0 < strlen(names)) {
/* mca param based */
name_array = opal_argv_split(names, ',');
num_names = opal_argv_count(name_array);
@ -200,12 +130,8 @@ int mca_coll_base_comm_select(ompi_communicator_t *comm,
selectable = check_components(&mca_coll_base_components_available,
comm, name_array, num_names);
opal_argv_free(name_array);
}
/* Nope -- a specific [set of] component[s] was not requested. Go
check them all. */
else {
} else {
/* no specific components given -- try all */
opal_output_verbose(10, mca_coll_base_output,
"coll:base:comm_select: Checking all available modules");
selectable = check_components(&mca_coll_base_components_available,
@ -215,112 +141,72 @@ int mca_coll_base_comm_select(ompi_communicator_t *comm,
/* Upon return from the above, the modules list will contain the
list of modules that returned (priority >= 0). If we have no
collective modules available, then use the basic component */
if (NULL == selectable) {
found = false;
if (NULL != mca_coll_base_basic_component) {
query_basic(comm);
if (NULL != comm->c_coll_basic_module) {
found = true;
}
}
if (!found) {
/* There's no modules available -- including basic. Doh! */
/* There's no modules available */
opal_show_help("help-mca-coll-base",
"comm-select:none-available", true);
return OMPI_ERROR;
}
}
/* Do some kind of collective operation to find a module that
everyone has available */
/* FIX ME - Do some kind of collective operation to find a module
that everyone has available */
#if 1
/* For the moment, just take the top module off the list */
/* do the selection loop */
for (item = opal_list_get_first(selectable) ;
item != opal_list_get_end(selectable) ;
item = opal_list_get_next(item)) {
avail_coll_t *avail = (avail_coll_t*) item;
if (NULL != selectable) {
using_basic = false;
item = opal_list_remove_first(selectable);
avail = (avail_coll_t *) item;
/* initialize the module */
ret = avail->ac_module->coll_module_enable(avail->ac_module, comm);
if (OMPI_SUCCESS != ret) {
mca_coll_base_comm_unselect(comm);
continue;
}
/* Check to see if the basic component has a higher priority than
the highest priority component on the selectable list. If so,
use basic. */
/* copy over any of the pointers */
COPY(avail->ac_module, comm, allgather);
COPY(avail->ac_module, comm, allgatherv);
COPY(avail->ac_module, comm, allreduce);
COPY(avail->ac_module, comm, alltoall);
COPY(avail->ac_module, comm, alltoallv);
COPY(avail->ac_module, comm, alltoallw);
COPY(avail->ac_module, comm, barrier);
COPY(avail->ac_module, comm, bcast);
COPY(avail->ac_module, comm, exscan);
COPY(avail->ac_module, comm, gather);
COPY(avail->ac_module, comm, gatherv);
COPY(avail->ac_module, comm, reduce);
COPY(avail->ac_module, comm, reduce_scatter);
COPY(avail->ac_module, comm, scan);
COPY(avail->ac_module, comm, scatter);
COPY(avail->ac_module, comm, scatterv);
if (NULL != mca_coll_base_basic_component) {
query_basic(comm);
}
if (avail->ac_priority > basic_priority) {
selected_component = avail->ac_component;
selected_module = avail->ac_module;
selected_data = avail->ac_data;
OBJ_RELEASE(avail);
} else {
opal_output_verbose(10, mca_coll_base_output,
"coll:base:comm_select: component available: basic, priority: %d\n", basic_priority);
using_basic = true;
selected_component = mca_coll_base_basic_component;
selected_module = comm->c_coll_basic_module;
selected_data = comm->c_coll_basic_data;
}
} else {
using_basic = true;
selected_component = mca_coll_base_basic_component;
selected_module = comm->c_coll_basic_module;
selected_data = comm->c_coll_basic_data;
}
#else
/* JMS CONTINUE HERE */
#endif
/* Everything left in the selectable list is therefore unwanted,
and we call their unquery() method (because they all had query()
invoked, but will never have init() invoked in this scope). */
if (NULL != selectable) {
for (item = opal_list_remove_first(selectable); item != NULL;
item = opal_list_remove_first(selectable)) {
avail = (avail_coll_t *) item;
component = avail->ac_component;
unquery(component, comm, avail->ac_data);
OBJ_RELEASE(avail);
}
OBJ_RELEASE(selectable);
/* release the original module reference */
OBJ_RELEASE(avail->ac_module);
}
/* If we're not using the basic module, then set it up, replace all
NULL function pointers with those from basic, and then initialize
it. */
comm->c_coll_selected_component = selected_component;
comm->c_coll_selected_module = selected_module;
comm->c_coll_selected_data = selected_data;
if (!using_basic) {
comm->c_coll = *selected_module;
replace_null_with_basic(comm);
/* Finally -- intialize the selected module. If it's the basic
module, we've initialized it already. */
err = module_init(selected_module, comm);
if (OMPI_SUCCESS != err) {
return err;
}
/* Now double check because we may have gotten a different module
back from the init function; ensure that there are no NULL's in
there */
replace_null_with_basic(comm);
/* check to make sure no NULLs */
if ((NULL == comm->c_coll.coll_allgather) ||
(NULL == comm->c_coll.coll_allgatherv) ||
(NULL == comm->c_coll.coll_allreduce) ||
(NULL == comm->c_coll.coll_alltoall) ||
(NULL == comm->c_coll.coll_alltoallv) ||
(NULL == comm->c_coll.coll_alltoallw) ||
(NULL == comm->c_coll.coll_barrier) ||
(NULL == comm->c_coll.coll_bcast) ||
((OMPI_COMM_IS_INTRA(comm)) && (NULL == comm->c_coll.coll_exscan)) ||
(NULL == comm->c_coll.coll_gather) ||
(NULL == comm->c_coll.coll_gatherv) ||
(NULL == comm->c_coll.coll_reduce) ||
(NULL == comm->c_coll.coll_reduce_scatter) ||
((OMPI_COMM_IS_INTRA(comm)) && (NULL == comm->c_coll.coll_scan)) ||
(NULL == comm->c_coll.coll_scatter) ||
(NULL == comm->c_coll.coll_scatterv)) {
mca_coll_base_comm_unselect(comm);
return OMPI_ERR_NOT_FOUND;
}
/* Announce the winner */
opal_output_verbose(10, mca_coll_base_output,
"coll:base:comm_select: Selected coll module %s",
selected_component->collm_version.mca_component_name);
return OMPI_SUCCESS;
}
@ -339,11 +225,10 @@ static opal_list_t *check_components(opal_list_t *components,
int i, priority;
const mca_base_component_t *component;
opal_list_item_t *item, *item2;
const mca_coll_base_module_1_0_0_t *module;
mca_coll_base_module_1_1_0_t *module;
bool want_to_check;
opal_list_t *selectable;
avail_coll_t *avail, *avail2;
struct mca_coll_base_comm_t *data;
/* Make a list of the components that query successfully */
@ -376,7 +261,7 @@ static opal_list_t *check_components(opal_list_t *components,
so */
if (want_to_check) {
priority = check_one_component(comm, component, &module, &data);
priority = check_one_component(comm, component, &module);
if (priority >= 0) {
/* We have a component that indicated that it wants to run by
@ -384,11 +269,9 @@ static opal_list_t *check_components(opal_list_t *components,
avail = OBJ_NEW(avail_coll_t);
avail->ac_priority = priority;
avail->ac_component = (mca_coll_base_component_1_0_0_t *) component;
avail->ac_module = module;
avail->ac_data = data;
/* Put this item on the list in priority order (highest
/* Put this item on the list in priority order (lowest
priority first). Should it go first? */
if (opal_list_is_empty(selectable)) {
@ -396,13 +279,13 @@ static opal_list_t *check_components(opal_list_t *components,
} else {
item2 = opal_list_get_first(selectable);
avail2 = (avail_coll_t *) item2;
if (avail->ac_priority > avail2->ac_priority) {
if (avail->ac_priority < avail2->ac_priority) {
opal_list_prepend(selectable, (opal_list_item_t *) avail);
} else {
for (i = 1; item2 != opal_list_get_end(selectable);
item2 = opal_list_get_next(item2), ++i) {
avail2 = (avail_coll_t *) item2;
if (avail->ac_priority > avail2->ac_priority) {
if (avail->ac_priority < avail2->ac_priority) {
opal_list_insert(selectable,
(opal_list_item_t *) avail, i);
break;
@ -440,13 +323,12 @@ static opal_list_t *check_components(opal_list_t *components,
*/
static int check_one_component(ompi_communicator_t *comm,
const mca_base_component_t *component,
const mca_coll_base_module_1_0_0_t **module,
struct mca_coll_base_comm_t **data)
mca_coll_base_module_1_1_0_t **module)
{
int err;
int priority = -1;
err = query(component, comm, &priority, module, data);
err = query(component, comm, &priority, module);
if (OMPI_SUCCESS == err) {
priority = (priority < 100) ? priority : 100;
@ -475,8 +357,7 @@ static int check_one_component(ompi_communicator_t *comm,
*/
static int query(const mca_base_component_t *component,
ompi_communicator_t *comm,
int *priority, const mca_coll_base_module_1_0_0_t **module,
struct mca_coll_base_comm_t **data)
int *priority, mca_coll_base_module_1_1_0_t **module)
{
/* coll v1.0.0 */
@ -484,10 +365,10 @@ static int query(const mca_base_component_t *component,
if (1 == component->mca_major_version &&
0 == component->mca_minor_version &&
0 == component->mca_release_version) {
const mca_coll_base_component_1_0_0_t *coll100 =
(mca_coll_base_component_1_0_0_t *) component;
const mca_coll_base_component_1_1_0_t *coll100 =
(mca_coll_base_component_1_1_0_t *) component;
return query_1_0_0(coll100, comm, priority, module, data);
return query_1_1_0(coll100, comm, priority, module);
}
/* Unknown coll API version -- return error */
@ -496,16 +377,15 @@ static int query(const mca_base_component_t *component,
}
static int query_1_0_0(const mca_coll_base_component_1_0_0_t *component,
static int query_1_1_0(const mca_coll_base_component_1_1_0_t *component,
ompi_communicator_t *comm, int *priority,
const mca_coll_base_module_1_0_0_t **module,
struct mca_coll_base_comm_t **data)
mca_coll_base_module_1_1_0_t **module)
{
const mca_coll_base_module_1_0_0_t *ret;
mca_coll_base_module_1_1_0_t *ret;
/* There's currently no need for conversion */
ret = component->collm_comm_query(comm, priority, data);
ret = component->collm_comm_query(comm, priority);
if (NULL != ret) {
*module = ret;
return OMPI_SUCCESS;
@ -513,128 +393,3 @@ static int query_1_0_0(const mca_coll_base_component_1_0_0_t *component,
return OMPI_ERROR;
}
/**************************************************************************
* Unquery functions
**************************************************************************/
static void unquery(const mca_coll_base_component_1_0_0_t *component,
ompi_communicator_t *comm,
struct mca_coll_base_comm_t *data)
{
if (1 == component->collm_version.mca_major_version &&
0 == component->collm_version.mca_minor_version &&
0 == component->collm_version.mca_release_version) {
const mca_coll_base_component_1_0_0_t *coll100 =
(mca_coll_base_component_1_0_0_t *) component;
unquery_1_0_0(coll100, comm, data);
}
/* There's no way to have a version that we don't recognize here --
it would have already been removed from the list */
}
static void unquery_1_0_0(const mca_coll_base_component_1_0_0_t *component,
ompi_communicator_t *comm,
struct mca_coll_base_comm_t *data)
{
if (NULL != component->collm_comm_unquery) {
component->collm_comm_unquery(comm, data);
}
}
/**************************************************************************
* Module_Init functions
**************************************************************************/
/*
* Initialize a module
*/
static int module_init(const mca_coll_base_module_1_0_0_t *module,
ompi_communicator_t *comm)
{
const mca_coll_base_module_1_0_0_t *ret;
/* There's currently no need for conversion */
ret = module->coll_module_init(comm);
if (NULL != ret) {
if (comm->c_coll_selected_module != ret) {
comm->c_coll = *ret;
comm->c_coll_selected_module = ret;
}
return OMPI_SUCCESS;
}
return OMPI_ERROR;
}
/**************************************************************************
* Misc functions
**************************************************************************/
/*
* If the basic module has not already been setup on this
* communicator, query and initialize it.
*/
static int query_basic(ompi_communicator_t *comm)
{
int ret;
struct mca_coll_base_comm_t *data;
ret = OMPI_SUCCESS;
if (NULL == comm->c_coll_basic_module) {
ret = query((mca_base_component_t *) mca_coll_base_basic_component, comm,
&basic_priority, &comm->c_coll_basic_module, &data);
if (ret != OMPI_SUCCESS) {
comm->c_coll_basic_module = NULL;
return ret;
}
comm->c_coll_basic_data = data;
ret = module_init(comm->c_coll_basic_module, comm);
}
return ret;
}
/*
* Replace the NULL pointers by corresponsing ompi_basic pointers
*/
static int replace_null_with_basic(ompi_communicator_t *comm)
{
int err;
#define CHECK(name) \
if (NULL == comm->c_coll.coll_##name) { \
if (OMPI_SUCCESS != (err = query_basic(comm))) { \
return err; \
} \
comm->c_coll.coll_##name = comm->c_coll_basic_module->coll_##name; \
}
CHECK(allgather);
CHECK(allgatherv);
CHECK(allreduce);
CHECK(alltoall);
CHECK(alltoallv);
CHECK(alltoallw);
CHECK(barrier);
CHECK(bcast);
CHECK(exscan);
CHECK(gather);
CHECK(gatherv);
CHECK(reduce);
CHECK(reduce_scatter);
CHECK(scan);
CHECK(scatter);
CHECK(scatterv);
/* Happiness; all done */
return OMPI_SUCCESS;
}

View File

@ -30,57 +30,35 @@
#include "ompi/mca/coll/coll.h"
#include "ompi/mca/coll/base/base.h"
extern opal_list_t mca_coll_base_available;
#define CLOSE(comm, func) \
do { \
if (NULL != comm->c_coll.coll_ ## func ## _module) { \
OBJ_RELEASE(comm->c_coll.coll_ ## func ## _module); \
comm->c_coll.coll_## func = NULL; \
comm->c_coll.coll_## func ## _module = NULL; \
} \
} while (0)
/*
* This function is called to shut down a collective module on a
* specific communicator. If we used some of the basic module
* functions in here to fill in NULL pointers, we also need to shut
* down the basic module.
*/
int mca_coll_base_comm_unselect(ompi_communicator_t *comm)
{
int err;
CLOSE(comm, allgather);
CLOSE(comm, allgatherv);
CLOSE(comm, allreduce);
CLOSE(comm, alltoall);
CLOSE(comm, alltoallv);
CLOSE(comm, alltoallw);
CLOSE(comm, barrier);
CLOSE(comm, bcast);
CLOSE(comm, exscan);
CLOSE(comm, gather);
CLOSE(comm, gatherv);
CLOSE(comm, reduce);
CLOSE(comm, reduce_scatter);
CLOSE(comm, scan);
CLOSE(comm, scatter);
CLOSE(comm, scatterv);
/* Shut down the selected module. Note that this pointer can be
NULL if only the basic module was selected. */
if (NULL != comm->c_coll_selected_module &&
comm->c_coll_basic_module != comm->c_coll_selected_module &&
NULL != comm->c_coll_selected_module->coll_module_finalize) {
err = comm->c_coll_selected_module->coll_module_finalize(comm);
if (OMPI_SUCCESS != err) {
opal_show_help("help-mca-coll-base",
"comm-unselect:failed-finalize", true);
return err;
}
}
/* If the basic module was used at all (even if it was just to fill
in NULL pointers for functions that the selected module did not
provide), it may have hung stuff on c_coll_comm_basic, and
therefore needs to be finalized in this scope. */
if (NULL != comm->c_coll_basic_module &&
NULL != comm->c_coll_basic_module->coll_module_finalize) {
err = comm->c_coll_basic_module->coll_module_finalize(comm);
if (OMPI_SUCCESS != err) {
opal_show_help("help-mca-coll-base",
"comm-unselect:basic-failed-finalize", true);
return err;
}
}
/* Zero them all out, since they act as sentinel values */
comm->c_coll_selected_data = NULL;
comm->c_coll_selected_module = NULL;
comm->c_coll_basic_data = NULL;
comm->c_coll_basic_module = NULL;
/* All done */
return OMPI_SUCCESS;
/* All done */
return OMPI_SUCCESS;
}

View File

@ -39,7 +39,6 @@
*/
bool mca_coll_base_components_available_valid = false;
opal_list_t mca_coll_base_components_available;
const mca_coll_base_component_1_0_0_t *mca_coll_base_basic_component = NULL;
/*
@ -49,7 +48,7 @@ static int init_query(const mca_base_component_t *ls,
mca_base_component_priority_list_item_t *entry,
bool enable_progress_threads,
bool enable_mpi_threads);
static int init_query_1_0_0(const mca_base_component_t *ls,
static int init_query_1_1_0(const mca_base_component_t *ls,
mca_base_component_priority_list_item_t *entry,
bool enable_progress_threads,
bool enable_mpi_threads);
@ -98,32 +97,9 @@ int mca_coll_base_find_available(bool enable_progress_threads,
if (OMPI_SUCCESS == init_query(component, entry,
enable_progress_threads,
enable_mpi_threads)) {
/* Is this the basic component? If so, save it, because it's
special. Keep it off the available list -- we'll use it
specially in the selection process. */
if (0 == strcmp(component->mca_component_name, "basic")) {
mca_coll_base_basic_component =
(mca_coll_base_component_1_0_0_t *) component;
OBJ_RELEASE(entry);
}
/* Otherwise, save the results in the list. The priority isn't
relevant, because selection is decided at
communicator-constructor time. But we save the thread
arguments (set in the init_query() function) so that the
initial selection algorithm can negotiate the overall thread
level for this process. */
else {
opal_list_append(&mca_coll_base_components_available,
(opal_list_item_t *) entry);
}
/* Either way, we found something :-) */
found = true;
found = true;
} else {
/* If the component doesn't want to run, then close it. It's
@ -185,7 +161,7 @@ static int init_query(const mca_base_component_t *m,
if (1 == m->mca_type_major_version &&
0 == m->mca_type_minor_version &&
0 == m->mca_type_release_version) {
ret = init_query_1_0_0(m, entry, enable_progress_threads,
ret = init_query_1_1_0(m, entry, enable_progress_threads,
enable_mpi_threads);
} else {
/* Unrecognized coll API version */
@ -222,13 +198,13 @@ static int init_query(const mca_base_component_t *m,
/*
* Query a specific component, coll v1.0.0
*/
static int init_query_1_0_0(const mca_base_component_t *component,
static int init_query_1_1_0(const mca_base_component_t *component,
mca_base_component_priority_list_item_t *entry,
bool enable_progress_threads,
bool enable_mpi_threads)
{
mca_coll_base_component_1_0_0_t *coll =
(mca_coll_base_component_1_0_0_t *) component;
mca_coll_base_component_1_1_0_t *coll =
(mca_coll_base_component_1_1_0_t *) component;
return coll->collm_init_query(enable_progress_threads,
enable_mpi_threads);

View File

@ -51,6 +51,7 @@ int mca_coll_base_associative = 1;
bool mca_coll_base_components_opened_valid = false;
opal_list_t mca_coll_base_components_opened;
OBJ_CLASS_INSTANCE(mca_coll_base_module_1_1_0_t, opal_object_t, NULL, NULL);
/*
* Function for finding and opening either all MCA components, or the one

View File

@ -28,13 +28,11 @@
#include "ompi/mca/pml/pml.h"
#include "ompi/communicator/communicator.h"
#if defined(c_plusplus) || defined(__cplusplus)
extern "C" {
#endif
BEGIN_C_DECLS
/* Globally exported variables */
OMPI_MODULE_DECLSPEC extern const mca_coll_base_component_1_0_0_t
OMPI_MODULE_DECLSPEC extern const mca_coll_base_component_1_1_0_t
mca_coll_basic_component;
extern int mca_coll_basic_priority;
extern int mca_coll_basic_crossover;
@ -43,58 +41,64 @@ extern "C" {
int mca_coll_basic_init_query(bool enable_progress_threads,
bool enable_mpi_threads);
const struct mca_coll_base_module_1_0_0_t
struct mca_coll_base_module_1_1_0_t
*mca_coll_basic_comm_query(struct ompi_communicator_t *comm,
int *priority,
struct mca_coll_base_comm_t **data);
int *priority);
const struct mca_coll_base_module_1_0_0_t
*mca_coll_basic_module_init(struct ompi_communicator_t *comm);
int mca_coll_basic_module_finalize(struct ompi_communicator_t *comm);