diff --git a/ompi/group/group_plist.c b/ompi/group/group_plist.c index 29a969bf85..0f17422e22 100644 --- a/ompi/group/group_plist.c +++ b/ompi/group/group_plist.c @@ -29,6 +29,34 @@ #include +static int ompi_group_dense_overlap (ompi_group_t *group1, ompi_group_t *group2, opal_bitmap_t *bitmap) +{ + ompi_proc_t *proc1_pointer, *proc2_pointer; + int rc, overlap_count; + + overlap_count = 0; + + for (int proc1 = 0 ; proc1 < group1->grp_proc_count ; ++proc1) { + proc1_pointer = ompi_group_get_proc_ptr_raw (group1, proc1); + + /* check to see if this proc is in group2 */ + for (int proc2 = 0 ; proc2 < group2->grp_proc_count ; ++proc2) { + proc2_pointer = ompi_group_get_proc_ptr_raw (group2, proc2); + if( proc1_pointer == proc2_pointer ) { + rc = opal_bitmap_set_bit (bitmap, proc2); + if (OPAL_SUCCESS != rc) { + return rc; + } + ++overlap_count; + + break; + } + } /* end proc1 loop */ + } /* end proc loop */ + + return overlap_count; +} + static struct ompi_proc_t *ompi_group_dense_lookup_raw (ompi_group_t *group, const int peer_id) { if (OPAL_UNLIKELY((intptr_t) group->grp_proc_pointers[peer_id] < 0)) { @@ -71,7 +99,6 @@ int ompi_group_incl_plist(ompi_group_t* group, int n, const int *ranks, /* local variables */ int my_group_rank; ompi_group_t *group_pointer, *new_group_pointer; - ompi_proc_t *my_proc_pointer; group_pointer = (ompi_group_t *)group; @@ -99,10 +126,8 @@ int ompi_group_incl_plist(ompi_group_t* group, int n, const int *ranks, /* find my rank */ my_group_rank=group_pointer->grp_my_rank; if (MPI_UNDEFINED != my_group_rank) { - my_proc_pointer=ompi_group_peer_lookup (group_pointer,my_group_rank); - ompi_set_group_rank(new_group_pointer,my_proc_pointer); - } - else { + ompi_set_group_rank(new_group_pointer, ompi_proc_local_proc); + } else { new_group_pointer->grp_my_rank = MPI_UNDEFINED; } @@ -119,50 +144,41 @@ int ompi_group_union (ompi_group_t* group1, ompi_group_t* group2, ompi_group_t **new_group) { /* local variables */ - int new_group_size, my_group_rank, cnt; + int new_group_size, cnt, rc, overlap_count; ompi_group_t *new_group_pointer; - ompi_proc_t *proc1_pointer, *proc2_pointer, *my_proc_pointer = NULL; + ompi_proc_t *proc2_pointer; + opal_bitmap_t bitmap; /* * form union */ /* get new group size */ - new_group_size = group1->grp_proc_count; + OBJ_CONSTRUCT(&bitmap, opal_bitmap_t); + rc = opal_bitmap_init (&bitmap, 32); + if (OPAL_SUCCESS != rc) { + return rc; + } /* check group2 elements to see if they need to be included in the list */ - for (int proc2 = 0; proc2 < group2->grp_proc_count; ++proc2) { - bool found_in_group = false; - - proc2_pointer = ompi_group_get_proc_ptr_raw (group2, proc2); - - /* check to see if this proc2 is alread in the group */ - for (int proc1 = 0; proc1 < group1->grp_proc_count; ++proc1) { - proc1_pointer = ompi_group_get_proc_ptr_raw (group1, proc1); - - if (proc1_pointer == proc2_pointer) { - /* proc2 is in group1 - don't double count */ - found_in_group = true; - break; - } - } /* end proc1 loop */ - - if (found_in_group) { - continue; - } - - new_group_size++; - } /* end proc loop */ + overlap_count = ompi_group_dense_overlap (group1, group2, &bitmap); + if (0 > overlap_count) { + OBJ_DESTRUCT(&bitmap); + return overlap_count; + } + new_group_size = group1->grp_proc_count + group2->grp_proc_count - overlap_count; if ( 0 == new_group_size ) { *new_group = MPI_GROUP_EMPTY; OBJ_RETAIN(MPI_GROUP_EMPTY); + OBJ_DESTRUCT(&bitmap); return MPI_SUCCESS; } /* get new group struct */ new_group_pointer = ompi_group_allocate(new_group_size); if (NULL == new_group_pointer) { + OBJ_DESTRUCT(&bitmap); return MPI_ERR_GROUP; } @@ -177,52 +193,28 @@ int ompi_group_union (ompi_group_t* group1, ompi_group_t* group2, /* check group2 elements to see if they need to be included in the list */ for (int proc2 = 0; proc2 < group2->grp_proc_count; ++proc2) { - bool found_in_group = false; - - proc2_pointer = ompi_group_get_proc_ptr_raw (group2, proc2); - - /* check to see if this proc2 is alread in the group */ - for (int proc1 = 0; proc1 < group1->grp_proc_count; ++proc1) { - proc1_pointer = ompi_group_get_proc_ptr_raw (group1, proc1); - - if (proc1_pointer == proc2_pointer) { - /* proc2 is in group1 - don't double count */ - found_in_group = true; - break; - } - } /* end proc1 loop */ - - if (found_in_group) { + if (opal_bitmap_is_set_bit (&bitmap, proc2)) { continue; } + proc2_pointer = ompi_group_get_proc_ptr_raw (group2, proc2); new_group_pointer->grp_proc_pointers[cnt++] = proc2_pointer; } /* end proc loop */ + OBJ_DESTRUCT(&bitmap); + /* increment proc reference counters */ ompi_group_increment_proc_count(new_group_pointer); /* find my rank */ - my_group_rank = group1->grp_my_rank; - if (MPI_UNDEFINED == my_group_rank) { - my_group_rank = group2->grp_my_rank; - if ( MPI_UNDEFINED != my_group_rank) { - my_proc_pointer = ompi_group_peer_lookup(group2,my_group_rank); - } + if (MPI_UNDEFINED != group1->grp_my_rank || MPI_UNDEFINED != group2->grp_my_rank) { + ompi_set_group_rank(new_group_pointer, ompi_proc_local_proc); } else { - my_proc_pointer = ompi_group_peer_lookup(group1,my_group_rank); - } - - if ( MPI_UNDEFINED == my_group_rank ) { new_group_pointer->grp_my_rank = MPI_UNDEFINED; } - else { - ompi_set_group_rank(new_group_pointer, my_proc_pointer); - } *new_group = (MPI_Group) new_group_pointer; - return OMPI_SUCCESS; } @@ -234,85 +226,65 @@ int ompi_group_difference(ompi_group_t* group1, ompi_group_t* group2, ompi_group_t **new_group) { /* local varibles */ - int new_group_size, my_group_rank; + int new_group_size, overlap_count, rc; ompi_group_t *new_group_pointer; - ompi_proc_t *proc1_pointer, *proc2_pointer, *my_proc_pointer = NULL; + ompi_proc_t *proc1_pointer; + opal_bitmap_t bitmap; /* * form union */ /* get new group size */ - new_group_size = group1->grp_proc_count; + OBJ_CONSTRUCT(&bitmap, opal_bitmap_t); + rc = opal_bitmap_init (&bitmap, 32); + if (OPAL_SUCCESS != rc) { + return rc; + } - /* loop over group1 members */ - for (int proc1 = 0 ; proc1 < group1->grp_proc_count ; ++proc1) { - proc1_pointer = ompi_group_get_proc_ptr_raw (group1, proc1); - - /* check to see if this proc is in group2 */ - for (int proc2 = 0 ; proc2 < group2->grp_proc_count ; ++proc2) { - proc2_pointer = ompi_group_get_proc_ptr_raw (group2, proc2); - if( proc1_pointer == proc2_pointer ) { - --new_group_size; - break; - } - } /* end proc1 loop */ - } /* end proc loop */ + /* check group2 elements to see if they need to be included in the list */ + overlap_count = ompi_group_dense_overlap (group2, group1, &bitmap); + if (0 > overlap_count) { + OBJ_DESTRUCT(&bitmap); + return overlap_count; + } + new_group_size = group1->grp_proc_count - overlap_count; if ( 0 == new_group_size ) { *new_group = MPI_GROUP_EMPTY; OBJ_RETAIN(MPI_GROUP_EMPTY); + OBJ_DESTRUCT(&bitmap); return MPI_SUCCESS; } /* allocate a new ompi_group_t structure */ - new_group_pointer=ompi_group_allocate(new_group_size); + new_group_pointer = ompi_group_allocate(new_group_size); if( NULL == new_group_pointer ) { + OBJ_DESTRUCT(&bitmap); return MPI_ERR_GROUP; } /* fill in group list */ /* loop over group1 members */ for (int proc1 = 0, cnt = 0 ; proc1 < group1->grp_proc_count ; ++proc1) { - bool found_in_group2 = false; - - proc1_pointer = ompi_group_get_proc_ptr_raw (group1, proc1); - /* check to see if this proc is in group2 */ - for (int proc2 = 0 ; proc2 < group2->grp_proc_count ; ++proc2) { - proc2_pointer = ompi_group_get_proc_ptr_raw (group2, proc2); - if( proc1_pointer == proc2_pointer ) { - found_in_group2 = true; - break; - } - } /* end proc1 loop */ - - if (found_in_group2) { + if (opal_bitmap_is_set_bit (&bitmap, proc1)) { continue; } + proc1_pointer = ompi_group_get_proc_ptr_raw (group1, proc1); new_group_pointer->grp_proc_pointers[cnt++] = proc1_pointer; } /* end proc loop */ + OBJ_DESTRUCT(&bitmap); + /* increment proc reference counters */ ompi_group_increment_proc_count(new_group_pointer); /* find my rank */ - my_group_rank=group1->grp_my_rank; - if ( MPI_UNDEFINED != my_group_rank ) { - my_proc_pointer = ompi_group_peer_lookup(group1,my_group_rank); - } - else { - my_group_rank=group2->grp_my_rank; - if ( MPI_UNDEFINED != my_group_rank ) { - my_proc_pointer = ompi_group_peer_lookup(group2,my_group_rank); - } - } - - if ( MPI_UNDEFINED == my_group_rank ) { + if (MPI_UNDEFINED == group1->grp_my_rank || MPI_UNDEFINED != group2->grp_my_rank) { new_group_pointer->grp_my_rank = MPI_UNDEFINED; - } - else { - ompi_set_group_rank(new_group_pointer,my_proc_pointer); + } else { + ompi_set_group_rank(new_group_pointer, ompi_proc_local_proc); } *new_group = (MPI_Group)new_group_pointer;