1
1

ompi/group: clean up union/difference code

Updated the union/difference code to remove an extra n^2 translation
of ranks. This comes at the cost of extra memory but greatly
simplifies the code.

Signed-off-by: Nathan Hjelm <hjelmn@me.com>
Этот коммит содержится в:
Nathan Hjelm 2015-06-23 14:26:59 -06:00 коммит произвёл Nathan Hjelm
родитель 5b7943db78
Коммит 0a0e6d8eef

Просмотреть файл

@ -29,6 +29,34 @@
#include <math.h>
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;