From 8e9f32b5d0d8b63f96da1c382c0b4633e17254fb Mon Sep 17 00:00:00 2001 From: Rich Graham Date: Fri, 27 Feb 2004 19:22:14 +0000 Subject: [PATCH] continue to implement first cut of the group functionality. This code has not yet been tested. Bug fix for group_excl.c . Add support funtion to set rank within the group. This commit was SVN r814. --- src/mpi/group/Makefile.am | 3 +- src/mpi/group/group.h | 15 +++- src/mpi/group/mpi_set_group_rank.c | 30 +++++++ src/mpi/interface/c/group_difference.c | 86 ++++++++++++++++++- src/mpi/interface/c/group_excl.c | 4 +- src/mpi/interface/c/group_f2c.c | 23 ++++- src/mpi/interface/c/group_union.c | 113 ++++++++++++++++++++++++- 7 files changed, 264 insertions(+), 10 deletions(-) create mode 100644 src/mpi/group/mpi_set_group_rank.c diff --git a/src/mpi/group/Makefile.am b/src/mpi/group/Makefile.am index 7e6b6db69a..4bb1ae56eb 100644 --- a/src/mpi/group/Makefile.am +++ b/src/mpi/group/Makefile.am @@ -14,7 +14,8 @@ headers = \ libmpi_group_la_SOURCES = \ $(headers) \ - mpi_group_init.c + mpi_group_init.c \ + mpi_set_group_rank.c # Conditionally install the header files diff --git a/src/mpi/group/group.h b/src/mpi/group/group.h index 4f98ed09b5..09c6a4183b 100644 --- a/src/mpi/group/group.h +++ b/src/mpi/group/group.h @@ -71,11 +71,24 @@ static inline int lam_group_size(lam_group_t *group){ /** * Get group rank * - * @param group Pointer to lam_group_t structute (IN) + * @param group Pointer to lam_group_t structure (IN) * * @return Group rank */ static inline int lam_group_rank(lam_group_t *group){ return group->grp_proc_count; } + +/** + * Set group rank in the input group structure + * + * @param group Group Pointer to lam_group_t structure (IN) + * @param proc_pointer Pointer to lam_proc_t structure for process. + * MPI_PROC_NULL may be used to indicate proc not + * in group + * + * @return Error code + */ +void lam_set_group_rank(lam_group_t *group, lam_proc_t *proc_pointer); + #endif /* LAM_GROUP_H */ diff --git a/src/mpi/group/mpi_set_group_rank.c b/src/mpi/group/mpi_set_group_rank.c new file mode 100644 index 0000000000..731e63cbd3 --- /dev/null +++ b/src/mpi/group/mpi_set_group_rank.c @@ -0,0 +1,30 @@ +/* + * $HEADER$ + */ + +#include "mpi/group/group.h" +#include "lam/constants.h" + +void lam_set_group_rank(lam_group_t *group, lam_proc_t *proc_pointer) +{ + /* local variables */ + int proc; + + /* set the rank to proc_null, just in case this process is not + * in this group + */ + group->grp_my_rank = MPI_PROC_NULL; + if( MPI_PROC_NULL != proc_pointer ) { + /* loop over all procs in the group */ + for ( proc=0 ; proc < group->grp_proc_count ; proc++ ){ + /* check and see if this proc pointer matches proc_pointer + */ + if( group->grp_proc_pointers[proc] == proc_pointer ) { + group->grp_my_rank = proc; + } + } /* end proc loop */ + } + + /* return */ + return; +} diff --git a/src/mpi/interface/c/group_difference.c b/src/mpi/interface/c/group_difference.c index a1c15833e0..d253088e1b 100644 --- a/src/mpi/interface/c/group_difference.c +++ b/src/mpi/interface/c/group_difference.c @@ -6,12 +6,94 @@ #include "mpi.h" #include "mpi/interface/c/bindings.h" +#include "mpi/group/group.h" #if LAM_HAVE_WEAK_SYMBOLS && LAM_PROFILING_DEFINES #pragma weak MPI_Group_difference = PMPI_Group_difference #endif int MPI_Group_difference(MPI_Group group1, MPI_Group group2, - MPI_Group *newgroup) { - return MPI_SUCCESS; + MPI_Group *new_group) { + + /* local varibles */ + int return_value, new_group_size, proc1, proc2, found_in_group2, cnt; + lam_group_t *group1_pointer, *group2_pointer, *new_group_pointer; + lam_proc_t *proc1_pointer, *proc2_pointer; + + return_value=MPI_SUCCESS; + group1_pointer=(lam_group_t *)group1; + group2_pointer=(lam_group_t *)group2; + + /* the difference of an empty group and anything is an empty group */ + if (MPI_GROUP_EMPTY == group1 ) { + *new_group = MPI_GROUP_EMPTY; + return MPI_SUCCESS; + } + + /* the difference of a group with the empty group is the group itself */ + if (MPI_GROUP_EMPTY == group2 ) { + *new_group=group1; + OBJ_RETAIN(group1_pointer); + return MPI_SUCCESS; + } + + /* + * form union + */ + + /* get new group size */ + new_group_size=0; + + /* loop over group1 members */ + for( proc1=0; proc1 < group1_pointer->grp_proc_count; proc1++ ) { + proc1_pointer=group1_pointer->grp_proc_pointers[proc1]; + /* check to see if this proc is in group2 */ + found_in_group2=0; + for( proc2=0 ; proc2 < group2_pointer->grp_proc_count ; proc2++ ) { + proc2_pointer=group2_pointer->grp_proc_pointers[proc2]; + if( proc1_pointer == proc2_pointer ) { + found_in_group2=true; + break; + } + } /* end proc1 loop */ + if(found_in_group2) + continue; + new_group_size++; + } /* end proc loop */ + + if (new_group_size == 0) { + *new_group = MPI_GROUP_EMPTY; + return MPI_SUCCESS; + } + + /* allocate a new lam_group_t structure */ + new_group_pointer=group_allocate(new_group_size); + if( NULL == new_group_pointer ) { + return MPI_ERR_GROUP; + } + + /* fill in group list */ + cnt=0; + /* loop over group1 members */ + for( proc1=0; proc1 < group1_pointer->grp_proc_count; proc1++ ) { + proc1_pointer=group1_pointer->grp_proc_pointers[proc1]; + /* check to see if this proc is in group2 */ + found_in_group2=0; + for( proc2=0 ; proc2 < group2_pointer->grp_proc_count ; proc2++ ) { + proc2_pointer=group2_pointer->grp_proc_pointers[proc2]; + if( proc1_pointer == proc2_pointer ) { + found_in_group2=true; + break; + } + } /* end proc1 loop */ + if(found_in_group2) + continue; + + new_group_pointer->grp_proc_pointers[cnt] = + group1_pointer->grp_proc_pointers[proc1]; + + cnt++; + } /* end proc loop */ + + return return_value; } diff --git a/src/mpi/interface/c/group_excl.c b/src/mpi/interface/c/group_excl.c index 48cee668ba..e3a54581a3 100644 --- a/src/mpi/interface/c/group_excl.c +++ b/src/mpi/interface/c/group_excl.c @@ -72,6 +72,7 @@ int MPI_Group_excl(MPI_Group group, int n, int *ranks, cnt=0; for (proc = 0; proc < n; proc++) { found=0; + /* check to see if this proc is in the exclusion list */ for( i_excl=0 ; i_excl < n ; ++i_excl ) { excl_proc=ranks[i_excl]; /* check to see if this proc is within range */ @@ -86,7 +87,8 @@ int MPI_Group_excl(MPI_Group group, int n, int *ranks, } /* end i_excl loop */ if( !found ) { - new_group_pointer->grp_proc_pointers[cnt] = proc; + new_group_pointer->grp_proc_pointers[cnt] = + group_pointer->grp_proc_pointers[proc]; cnt++; } diff --git a/src/mpi/interface/c/group_f2c.c b/src/mpi/interface/c/group_f2c.c index 696f1c8968..411d1d037d 100644 --- a/src/mpi/interface/c/group_f2c.c +++ b/src/mpi/interface/c/group_f2c.c @@ -6,11 +6,30 @@ #include "mpi.h" #include "mpi/interface/c/bindings.h" +#include "mpi/group/group.h" #if LAM_HAVE_WEAK_SYMBOLS && LAM_PROFILING_DEFINES #pragma weak MPI_Group_f2c = PMPI_Group_f2c #endif -MPI_Group MPI_Group_f2c(MPI_Fint group) { - return (MPI_Group)0; +MPI_Group MPI_Group_f2c(MPI_Fint group_f) { + /* local variable */ + lam_group_t *group_c; + int group_index; + + group_index=(int)group_f; + + /* error checks */ + if( MPI_PARAM_CHECK ) { + if( 0 > group_index ) { + return NULL; + } + if( group_index >= lam_group_f_to_c_table->size ) { + return NULL; + } + } + + group_c=lam_group_f_to_c_table->addr[group_index]; + + return (MPI_Group) group_c; } diff --git a/src/mpi/interface/c/group_union.c b/src/mpi/interface/c/group_union.c index 85d48f9070..d58311c518 100644 --- a/src/mpi/interface/c/group_union.c +++ b/src/mpi/interface/c/group_union.c @@ -6,12 +6,119 @@ #include "mpi.h" #include "mpi/interface/c/bindings.h" +#include "mpi/group/group.h" #if LAM_HAVE_WEAK_SYMBOLS && LAM_PROFILING_DEFINES #pragma weak MPI_Group_union = PMPI_Group_union #endif -int MPI_Group_union(MPI_Group group1, MPI_Group group2, - MPI_Group *newgroup) { - return MPI_SUCCESS; +int MPI_Group_union(MPI_Group group1, MPI_Group group2, MPI_Group *new_group) +{ + /* local variables */ + int return_value, new_group_size, proc, proc1, proc2, found_in_group; + int my_group_rank, cnt; + lam_group_t *group1_pointer, *group2_pointer, *new_group_pointer; + lam_proc_t *proc1_pointer, *proc2_pointer, *my_proc_pointer; + + return_value=MPI_SUCCESS; + group1_pointer= (lam_group_t *) group1; + group2_pointer= (lam_group_t *) group2; + + /* check to see if one of the groups is the empty group */ + if ((MPI_GROUP_EMPTY == group1) && (MPI_GROUP_EMPTY == group2)) { + /* both group1 and group2 are MPI_GROUP_EMPTY */ + *new_group = MPI_GROUP_EMPTY; + return return_value; + } else if ( MPI_GROUP_EMPTY == group1 ) { + /* group1 is MPI_GROUP_EMPTY */ + *new_group = group2; + /* increment group count */ + OBJ_RETAIN(group2_pointer); + return return_value; + } else if ( MPI_GROUP_EMPTY == group2 ) { + /* group2 is MPI_GROUP_EMPTY */ + *new_group = group1; + /* increment group count */ + OBJ_RETAIN(group1_pointer); + return return_value; + } + /* + * form union + */ + + /* get new group size */ + new_group_size=group1_pointer->grp_proc_count; + + /* check group2 elements to see if they need to be included in the list */ + for (proc2 = 0; proc2 < group2_pointer->grp_proc_count; proc2++) { + proc2_pointer=group2_pointer->grp_proc_pointers[proc2]; + + /* check to see if this proc2 is alread in the group */ + found_in_group = 0; + for (proc1 = 0; proc1 < group1_pointer->grp_proc_count; proc1++) { + proc1_pointer=group1_pointer->grp_proc_pointers[proc1]; + if (proc2_pointer == proc2_pointer ) { + /* proc2 is in group1 - don't double count */ + found_in_group = 1; + break; + } + } /* end proc1 loop */ + + if (found_in_group) + continue; + + new_group_size++; + } /* end proc loop */ + + /* get new group struct */ + new_group_pointer=group_allocate(new_group_size); + if( NULL == new_group_pointer ) { + return MPI_ERR_GROUP; + } + + /* fill in the new group list */ + + /* put group1 elements in the list */ + for (proc1 = 0; proc1 < group1_pointer->grp_proc_count; proc1++) { + new_group_pointer->grp_proc_pointers[proc1] = + group1_pointer->grp_proc_pointers[proc1]; + } + cnt=group1_pointer->grp_proc_count; + + /* check group2 elements to see if they need to be included in the list */ + for (proc2 = 0; proc2 < group2_pointer->grp_proc_count; proc2++) { + proc2_pointer=group2_pointer->grp_proc_pointers[proc2]; + + /* check to see if this proc2 is alread in the group */ + found_in_group = 0; + for (proc1 = 0; proc1 < group1_pointer->grp_proc_count; proc1++) { + proc1_pointer=group1_pointer->grp_proc_pointers[proc1]; + if (proc2_pointer == proc2_pointer ) { + /* proc2 is in group1 - don't double count */ + found_in_group = 1; + break; + } + } /* end proc1 loop */ + + if (found_in_group) + continue; + + new_group_pointer->grp_proc_pointers[cnt] = + group2_pointer->grp_proc_pointers[proc2]; + cnt++; + } /* end proc loop */ + + /* find my rank */ + my_group_rank=group1_pointer->grp_my_rank; + my_proc_pointer=group1_pointer->grp_proc_pointers[my_group_rank]; + if( MPI_PROC_NULL == my_proc_pointer ) { + my_group_rank=group2_pointer->grp_my_rank; + my_proc_pointer=group2_pointer->grp_proc_pointers[my_group_rank]; + } + lam_set_group_rank(new_group_pointer,my_proc_pointer); + + *new_group = (MPI_Group)new_group_pointer; + + /* return */ + return return_value; }