int ompi_group_incl_plist(ompi_group_t* group, int n, const int *ranks, ompi_group_t **new_group) { /* local variables */ int proc,my_group_rank; ompi_group_t *group_pointer, *new_group_pointer; ompi_proc_t *my_proc_pointer; group_pointer = (ompi_group_t *)group; if ( 0 == n ) { *new_group = MPI_GROUP_EMPTY; OBJ_RETAIN(MPI_GROUP_EMPTY); return OMPI_SUCCESS; } /* get new group struct */ new_group_pointer=ompi_group_allocate(n); if( NULL == new_group_pointer ) { return MPI_ERR_GROUP; } /* put group elements in the list */ for (proc = 0; proc < n; proc++) { new_group_pointer->grp_proc_pointers[proc] = ompi_group_peer_lookup(group_pointer,ranks[proc]); } /* end proc loop */ /* increment proc reference counters */ ompi_group_increment_proc_count(new_group_pointer); /* 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 { new_group_pointer->grp_my_rank = MPI_UNDEFINED; } *new_group = (MPI_Group)new_group_pointer; return OMPI_SUCCESS; }
/* * Group Union has to use the dense format since we don't support * two parent groups in the group structure and maintain functions */ int ompi_group_union (ompi_group_t* group1, ompi_group_t* group2, ompi_group_t **new_group) { /* local variables */ int new_group_size, proc1, proc2, found_in_group; int my_group_rank, cnt; ompi_group_t *group1_pointer, *group2_pointer, *new_group_pointer; ompi_proc_t *proc1_pointer, *proc2_pointer, *my_proc_pointer = NULL; group1_pointer = (ompi_group_t *) group1; group2_pointer = (ompi_group_t *) group2; /* * 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 = ompi_group_peer_lookup(group2_pointer,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 = ompi_group_peer_lookup(group1_pointer,proc1); if (proc1_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 */ if ( 0 == new_group_size ) { *new_group = MPI_GROUP_EMPTY; OBJ_RETAIN(MPI_GROUP_EMPTY); return MPI_SUCCESS; } /* get new group struct */ new_group_pointer = ompi_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] = ompi_group_peer_lookup(group1_pointer,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 = ompi_group_peer_lookup(group2_pointer,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 = ompi_group_peer_lookup(group1_pointer,proc1); if (proc1_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] = ompi_group_peer_lookup(group2_pointer,proc2); cnt++; } /* end proc loop */ /* increment proc reference counters */ ompi_group_increment_proc_count(new_group_pointer); /* find my rank */ my_group_rank = group1_pointer->grp_my_rank; if (MPI_UNDEFINED == my_group_rank) { my_group_rank = group2_pointer->grp_my_rank; if ( MPI_UNDEFINED != my_group_rank) { my_proc_pointer = ompi_group_peer_lookup(group2_pointer,my_group_rank); } } else { my_proc_pointer = ompi_group_peer_lookup(group1_pointer,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; }
/* * Initialize comm world/self/null/parent. */ int ompi_comm_init(void) { ompi_group_t *group; size_t size; /* Setup communicator array */ OBJ_CONSTRUCT(&ompi_mpi_communicators, opal_pointer_array_t); if( OPAL_SUCCESS != opal_pointer_array_init(&ompi_mpi_communicators, 0, OMPI_FORTRAN_HANDLE_MAX, 64) ) { return OMPI_ERROR; } /* Setup MPI_COMM_WORLD */ OBJ_CONSTRUCT(&ompi_mpi_comm_world, ompi_communicator_t); group = OBJ_NEW(ompi_group_t); group->grp_proc_pointers = ompi_proc_world(&size); group->grp_proc_count = (int)size; OMPI_GROUP_SET_INTRINSIC (group); OMPI_GROUP_SET_DENSE (group); ompi_set_group_rank(group, ompi_proc_local()); ompi_group_increment_proc_count (group); ompi_mpi_comm_world.comm.c_contextid = 0; ompi_mpi_comm_world.comm.c_id_start_index = 4; ompi_mpi_comm_world.comm.c_id_available = 4; ompi_mpi_comm_world.comm.c_f_to_c_index = 0; ompi_mpi_comm_world.comm.c_my_rank = group->grp_my_rank; ompi_mpi_comm_world.comm.c_local_group = group; ompi_mpi_comm_world.comm.c_remote_group = group; OBJ_RETAIN(ompi_mpi_comm_world.comm.c_remote_group); ompi_mpi_comm_world.comm.c_cube_dim = opal_cube_dim((int)size); ompi_mpi_comm_world.comm.error_handler = &ompi_mpi_errors_are_fatal.eh; OBJ_RETAIN( &ompi_mpi_errors_are_fatal.eh ); OMPI_COMM_SET_PML_ADDED(&ompi_mpi_comm_world.comm); opal_pointer_array_set_item (&ompi_mpi_communicators, 0, &ompi_mpi_comm_world); MEMCHECKER (memset (ompi_mpi_comm_world.comm.c_name, 0, MPI_MAX_OBJECT_NAME)); strncpy (ompi_mpi_comm_world.comm.c_name, "MPI_COMM_WORLD", strlen("MPI_COMM_WORLD")+1 ); ompi_mpi_comm_world.comm.c_flags |= OMPI_COMM_NAMEISSET; ompi_mpi_comm_world.comm.c_flags |= OMPI_COMM_INTRINSIC; /* We have to create a hash (although it is legal to leave this filed NULL -- the attribute accessor functions will intepret this as "there are no attributes cached on this object") because MPI_COMM_WORLD has some predefined attributes. */ ompi_attr_hash_init(&ompi_mpi_comm_world.comm.c_keyhash); /* Setup MPI_COMM_SELF */ OBJ_CONSTRUCT(&ompi_mpi_comm_self, ompi_communicator_t); group = OBJ_NEW(ompi_group_t); group->grp_proc_pointers = ompi_proc_self(&size); group->grp_my_rank = 0; group->grp_proc_count = (int)size; OMPI_GROUP_SET_INTRINSIC (group); OMPI_GROUP_SET_DENSE (group); ompi_mpi_comm_self.comm.c_contextid = 1; ompi_mpi_comm_self.comm.c_f_to_c_index = 1; ompi_mpi_comm_self.comm.c_id_start_index = 20; ompi_mpi_comm_self.comm.c_id_available = 20; ompi_mpi_comm_self.comm.c_my_rank = group->grp_my_rank; ompi_mpi_comm_self.comm.c_local_group = group; ompi_mpi_comm_self.comm.c_remote_group = group; OBJ_RETAIN(ompi_mpi_comm_self.comm.c_remote_group); ompi_mpi_comm_self.comm.error_handler = &ompi_mpi_errors_are_fatal.eh; OBJ_RETAIN( &ompi_mpi_errors_are_fatal.eh ); OMPI_COMM_SET_PML_ADDED(&ompi_mpi_comm_self.comm); opal_pointer_array_set_item (&ompi_mpi_communicators, 1, &ompi_mpi_comm_self); MEMCHECKER (memset (ompi_mpi_comm_self.comm.c_name, 0, MPI_MAX_OBJECT_NAME)); strncpy(ompi_mpi_comm_self.comm.c_name,"MPI_COMM_SELF",strlen("MPI_COMM_SELF")+1); ompi_mpi_comm_self.comm.c_flags |= OMPI_COMM_NAMEISSET; ompi_mpi_comm_self.comm.c_flags |= OMPI_COMM_INTRINSIC; /* We can set MPI_COMM_SELF's keyhash to NULL because it has no predefined attributes. If a user defines an attribute on MPI_COMM_SELF, the keyhash will automatically be created. */ ompi_mpi_comm_self.comm.c_keyhash = NULL; /* Setup MPI_COMM_NULL */ OBJ_CONSTRUCT(&ompi_mpi_comm_null, ompi_communicator_t); ompi_mpi_comm_null.comm.c_local_group = &ompi_mpi_group_null.group; ompi_mpi_comm_null.comm.c_remote_group = &ompi_mpi_group_null.group; OBJ_RETAIN(&ompi_mpi_group_null.group); OBJ_RETAIN(&ompi_mpi_group_null.group); ompi_mpi_comm_null.comm.c_contextid = 2; ompi_mpi_comm_null.comm.c_f_to_c_index = 2; ompi_mpi_comm_null.comm.c_my_rank = MPI_PROC_NULL; ompi_mpi_comm_null.comm.error_handler = &ompi_mpi_errors_are_fatal.eh; OBJ_RETAIN( &ompi_mpi_errors_are_fatal.eh ); opal_pointer_array_set_item (&ompi_mpi_communicators, 2, &ompi_mpi_comm_null); MEMCHECKER (memset (ompi_mpi_comm_null.comm.c_name, 0, MPI_MAX_OBJECT_NAME)); strncpy(ompi_mpi_comm_null.comm.c_name,"MPI_COMM_NULL",strlen("MPI_COMM_NULL")+1); ompi_mpi_comm_null.comm.c_flags |= OMPI_COMM_NAMEISSET; ompi_mpi_comm_null.comm.c_flags |= OMPI_COMM_INTRINSIC; /* Initialize the parent communicator to MPI_COMM_NULL */ ompi_mpi_comm_parent = &ompi_mpi_comm_null.comm; OBJ_RETAIN(&ompi_mpi_comm_null); OBJ_RETAIN(&ompi_mpi_group_null.group); OBJ_RETAIN(&ompi_mpi_errors_are_fatal.eh); /* initialize the comm_reg stuff for multi-threaded comm_cid allocation */ ompi_comm_reg_init(); return OMPI_SUCCESS; }
/* * Group Difference has to use the dense format since we don't support * two parent groups in the group structure and maintain functions */ int ompi_group_difference(ompi_group_t* group1, ompi_group_t* group2, ompi_group_t **new_group) { /* local varibles */ int new_group_size, proc1, proc2, found_in_group2, cnt; int my_group_rank; ompi_group_t *group1_pointer, *group2_pointer, *new_group_pointer; ompi_proc_t *proc1_pointer, *proc2_pointer, *my_proc_pointer = NULL; group1_pointer=(ompi_group_t *)group1; group2_pointer=(ompi_group_t *)group2; /* * 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 = ompi_group_peer_lookup(group1_pointer,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 = ompi_group_peer_lookup(group2_pointer,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 ( 0 == new_group_size ) { *new_group = MPI_GROUP_EMPTY; OBJ_RETAIN(MPI_GROUP_EMPTY); return MPI_SUCCESS; } /* allocate a new ompi_group_t structure */ new_group_pointer=ompi_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 = ompi_group_peer_lookup(group1_pointer,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 = ompi_group_peer_lookup(group2_pointer,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] = ompi_group_peer_lookup(group1_pointer,proc1); cnt++; } /* end proc loop */ /* increment proc reference counters */ ompi_group_increment_proc_count(new_group_pointer); /* find my rank */ my_group_rank=group1_pointer->grp_my_rank; if ( MPI_UNDEFINED != my_group_rank ) { my_proc_pointer = ompi_group_peer_lookup(group1_pointer,my_group_rank); } else { my_group_rank=group2_pointer->grp_my_rank; if ( MPI_UNDEFINED != my_group_rank ) { my_proc_pointer = ompi_group_peer_lookup(group2_pointer,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; }
/* * Group Difference has to use the dense format since we don't support * two parent groups in the group structure and maintain functions */ int ompi_group_difference(ompi_group_t* group1, ompi_group_t* group2, ompi_group_t **new_group) { /* local varibles */ int new_group_size, overlap_count, rc; ompi_group_t *new_group_pointer; ompi_proc_t *proc1_pointer; opal_bitmap_t bitmap; /* * form union */ /* get new group size */ 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 */ 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); 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) { 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 */ 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, ompi_proc_local_proc); } *new_group = (MPI_Group)new_group_pointer; return OMPI_SUCCESS; }