int ompi_osc_pt2pt_module_post(ompi_group_t *group, int assert, ompi_win_t *win) { int i; ompi_osc_pt2pt_module_t *module = P2P_MODULE(win); OBJ_RETAIN(group); ompi_group_increment_proc_count(group); OPAL_THREAD_LOCK(&(module->p2p_lock)); assert(NULL == module->p2p_pw_group); module->p2p_pw_group = group; /* Set our mode to expose w/ post */ ompi_win_remove_mode(win, OMPI_WIN_FENCE); ompi_win_append_mode(win, OMPI_WIN_EXPOSE_EPOCH | OMPI_WIN_POSTED); /* list how many complete counters we're still waiting on */ module->p2p_num_complete_msgs += ompi_group_size(module->p2p_pw_group); OPAL_THREAD_UNLOCK(&(module->p2p_lock)); /* send a hello counter to everyone in group */ for (i = 0 ; i < ompi_group_size(module->p2p_pw_group) ; ++i) { ompi_osc_pt2pt_control_send(module, ompi_group_peer_lookup(group, i), OMPI_OSC_PT2PT_HDR_POST, 1, 0); } return OMPI_SUCCESS; }
/** * ompi_osc_pt2pt_get_comm_ranks: * * @param[in] module - OSC PT2PT module * @param[in] sub_group - Group with ranks to translate * * @returns an array of translated ranks on success or NULL on failure * * Translate the ranks given in {sub_group} into ranks in the * communicator used to create {module}. */ static int *ompi_osc_sm_group_ranks (ompi_group_t *group, ompi_group_t *sub_group) { int size = ompi_group_size(sub_group); int *ranks1, *ranks2; int ret; ranks1 = calloc (size, sizeof(int)); ranks2 = calloc (size, sizeof(int)); if (NULL == ranks1 || NULL == ranks2) { free (ranks1); free (ranks2); return NULL; } for (int i = 0 ; i < size ; ++i) { ranks1[i] = i; } ret = ompi_group_translate_ranks (sub_group, size, ranks1, group, ranks2); free (ranks1); if (OMPI_SUCCESS != ret) { free (ranks2); return NULL; } qsort (ranks2, size, sizeof (int), compare_ranks); return ranks2; }
int ompi_osc_sm_start(struct ompi_group_t *group, int assert, struct ompi_win_t *win) { ompi_osc_sm_module_t *module = (ompi_osc_sm_module_t*) win->w_osc_module; int my_rank = ompi_comm_rank (module->comm); void *_tmp_ptr = NULL; OBJ_RETAIN(group); if (!OPAL_ATOMIC_COMPARE_EXCHANGE_STRONG_PTR(&module->start_group, (void *) &_tmp_ptr, group)) { OBJ_RELEASE(group); return OMPI_ERR_RMA_SYNC; } if (0 == (assert & MPI_MODE_NOCHECK)) { int size; int *ranks = ompi_osc_sm_group_ranks (module->comm->c_local_group, group); if (NULL == ranks) { return OMPI_ERR_OUT_OF_RESOURCE; } size = ompi_group_size(module->start_group); for (int i = 0 ; i < size ; ++i) { int rank_byte = ranks[i] >> OSC_SM_POST_BITS; osc_sm_post_type_t rank_bit = ((osc_sm_post_type_t) 1) << (ranks[i] & 0x3f); /* wait for rank to post */ while (!(module->posts[my_rank][rank_byte] & rank_bit)) { opal_progress(); opal_atomic_mb(); } opal_atomic_rmb (); #if OPAL_HAVE_ATOMIC_MATH_64 (void) opal_atomic_fetch_xor_64 ((volatile int64_t *) module->posts[my_rank] + rank_byte, rank_bit); #else (void) opal_atomic_fetch_xor_32 ((volatile int32_t *) module->posts[my_rank] + rank_byte, rank_bit); #endif } free (ranks); }
int MPI_Group_excl(MPI_Group group, int n, int ranks[], MPI_Group *new_group) { ompi_group_t *group_pointer = (ompi_group_t *)group; int i, err, group_size; group_size = ompi_group_size ( group_pointer); if( MPI_PARAM_CHECK ) { OMPI_ERR_INIT_FINALIZE(FUNC_NAME); /* verify that group is valid group */ if ( (MPI_GROUP_NULL == group) || (NULL == group) || (NULL == new_group) ) { return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_GROUP, FUNC_NAME); } else if (NULL == ranks && n > 0) { return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_ARG, FUNC_NAME); } /* check that new group is no larger than old group */ if ( n > group_size) { return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_GROUP, FUNC_NAME); } /* check to see if procs are within range */ for( i=0 ; i < n ; i++ ) { if( ( 0 > ranks[i] ) || (ranks[i] >= group_size)){ return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_RANK, FUNC_NAME ); } } } /* end if( MPI_CHECK_ARGS) */ if ( n == group_size ) { *new_group = MPI_GROUP_EMPTY; OBJ_RETAIN(MPI_GROUP_EMPTY); return MPI_SUCCESS; } OPAL_CR_ENTER_LIBRARY(); err = ompi_group_excl ( group, n, ranks, new_group ); OMPI_ERRHANDLER_RETURN(err, MPI_COMM_WORLD, err, FUNC_NAME ); }
int ompi_osc_sm_start(struct ompi_group_t *group, int assert, struct ompi_win_t *win) { ompi_osc_sm_module_t *module = (ompi_osc_sm_module_t*) win->w_osc_module; int my_rank = ompi_comm_rank (module->comm); OBJ_RETAIN(group); if (!OPAL_ATOMIC_CMPSET_PTR(&module->start_group, NULL, group)) { OBJ_RELEASE(group); return OMPI_ERR_RMA_SYNC; } if (0 == (assert & MPI_MODE_NOCHECK)) { int size; int *ranks = ompi_osc_sm_group_ranks (module->comm->c_local_group, group); if (NULL == ranks) { return OMPI_ERR_OUT_OF_RESOURCE; } size = ompi_group_size(module->start_group); for (int i = 0 ; i < size ; ++i) { int rank_byte = ranks[i] >> 6; uint64_t old, rank_bit = ((uint64_t) 1) << (ranks[i] & 0x3f); /* wait for rank to post */ while (!(module->posts[my_rank][rank_byte] & rank_bit)) { opal_progress(); opal_atomic_mb(); } opal_atomic_rmb (); do { old = module->posts[my_rank][rank_byte]; } while (!opal_atomic_cmpset_64 ((int64_t *) module->posts[my_rank] + rank_byte, old, old ^ rank_bit)); } free (ranks); }
int MPI_Group_incl(MPI_Group group, int n, const int ranks[], MPI_Group *new_group) { int i, group_size, err; ompi_group_t *group_pointer; group_pointer = (ompi_group_t *)group; group_size = ompi_group_size ( group_pointer ); if( MPI_PARAM_CHECK ) { OMPI_ERR_INIT_FINALIZE(FUNC_NAME); /* verify that group is valid group */ if ( (MPI_GROUP_NULL == group) || ( NULL == group) || (NULL == new_group) ) { return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_GROUP, FUNC_NAME); } else if (NULL == ranks && n > 0) { return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_ARG, FUNC_NAME); } /* check that new group is no larger than old group */ if ( n > group_size ) { return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_RANK, FUNC_NAME); } for (i = 0; i < n; i++) { if ((ranks[i] < 0) || (ranks[i] >= group_size)){ return OMPI_ERRHANDLER_INVOKE (MPI_COMM_WORLD, MPI_ERR_RANK, FUNC_NAME); } } } /* end if( MPI_CHECK_ARGS) */ if ( 0 == n ) { *new_group = MPI_GROUP_EMPTY; OBJ_RETAIN(MPI_GROUP_EMPTY); return MPI_SUCCESS; } err = ompi_group_incl(group,n,ranks,new_group); OMPI_ERRHANDLER_RETURN(err, MPI_COMM_WORLD,err,FUNC_NAME); }
static inline int check_sync_state(ompi_osc_ucx_module_t *module, int target, bool is_req_ops) { if (is_req_ops == false) { if (module->epoch_type.access == NONE_EPOCH) { return OMPI_ERR_RMA_SYNC; } else if (module->epoch_type.access == START_COMPLETE_EPOCH) { int i, size = ompi_group_size(module->start_group); for (i = 0; i < size; i++) { if (module->start_grp_ranks[i] == target) { break; } } if (i == size) { return OMPI_ERR_RMA_SYNC; } } else if (module->epoch_type.access == PASSIVE_EPOCH) { ompi_osc_ucx_lock_t *item = NULL; opal_hash_table_get_value_uint32(&module->outstanding_locks, (uint32_t) target, (void **) &item); if (item == NULL) { return OMPI_ERR_RMA_SYNC; } } } else { if (module->epoch_type.access != PASSIVE_EPOCH && module->epoch_type.access != PASSIVE_ALL_EPOCH) { return OMPI_ERR_RMA_SYNC; } else if (module->epoch_type.access == PASSIVE_EPOCH) { ompi_osc_ucx_lock_t *item = NULL; opal_hash_table_get_value_uint32(&module->outstanding_locks, (uint32_t) target, (void **) &item); if (item == NULL) { return OMPI_ERR_RMA_SYNC; } } } return OMPI_SUCCESS; }
static void ompi_win_dump (ompi_win_t *win) { opal_output(0, "Dumping information for window: %s\n", win->w_name); opal_output(0," Fortran window handle: %d, window size: %d\n", win->w_f_to_c_index, ompi_group_size (win->w_group)); }
int ompi_osc_pt2pt_module_complete(ompi_win_t *win) { int i; int ret = OMPI_SUCCESS; ompi_group_t *group; opal_list_item_t *item; ompi_osc_pt2pt_module_t *module = P2P_MODULE(win); /* wait for all the post messages */ OPAL_THREAD_LOCK(&module->p2p_lock); while (0 != module->p2p_num_post_msgs) { opal_condition_wait(&module->p2p_cond, &module->p2p_lock); } ompi_osc_pt2pt_flip_sendreqs(module); /* for each process in group, send a control message with number of updates coming, then start all the requests */ for (i = 0 ; i < ompi_group_size(module->p2p_sc_group) ; ++i) { int comm_rank = module->p2p_sc_remote_ranks[i]; module->p2p_num_pending_out += module->p2p_copy_num_pending_sendreqs[comm_rank]; } OPAL_THREAD_UNLOCK(&module->p2p_lock); for (i = 0 ; i < ompi_group_size(module->p2p_sc_group) ; ++i) { int comm_rank = module->p2p_sc_remote_ranks[i]; ret = ompi_osc_pt2pt_control_send(module, ompi_group_peer_lookup(module->p2p_sc_group, i), OMPI_OSC_PT2PT_HDR_COMPLETE, module->p2p_copy_num_pending_sendreqs[comm_rank], 0); assert(ret == OMPI_SUCCESS); } /* try to start all the requests. We've copied everything we need out of pending_sendreqs, so don't need the lock here */ while (NULL != (item = opal_list_remove_first(&(module->p2p_copy_pending_sendreqs)))) { ompi_osc_pt2pt_sendreq_t *req = (ompi_osc_pt2pt_sendreq_t*) item; ret = ompi_osc_pt2pt_sendreq_send(module, req); if (OMPI_ERR_TEMP_OUT_OF_RESOURCE == ret ) { opal_output_verbose(5, ompi_osc_base_output, "complete: failure in starting sendreq (%d). Will try later.", ret); opal_list_append(&(module->p2p_copy_pending_sendreqs), item); } else if (OMPI_SUCCESS != ret) { return ret; } } /* wait for all the requests */ OPAL_THREAD_LOCK(&module->p2p_lock); while (0 != module->p2p_num_pending_out) { opal_condition_wait(&module->p2p_cond, &module->p2p_lock); } group = module->p2p_sc_group; module->p2p_sc_group = NULL; OPAL_THREAD_UNLOCK(&module->p2p_lock); /* remove WIN_POSTED from our mode */ ompi_win_remove_mode(win, OMPI_WIN_ACCESS_EPOCH | OMPI_WIN_STARTED); ompi_group_decrement_proc_count(group); OBJ_RELEASE(group); return ret; }
int ompi_osc_pt2pt_module_start(ompi_group_t *group, int assert, ompi_win_t *win) { int i, ret = OMPI_SUCCESS; ompi_osc_pt2pt_module_t *module = P2P_MODULE(win); OBJ_RETAIN(group); ompi_group_increment_proc_count(group); OPAL_THREAD_LOCK(&(module->p2p_lock)); if (NULL != module->p2p_sc_group) { OPAL_THREAD_UNLOCK(&module->p2p_lock); ret = MPI_ERR_RMA_SYNC; goto cleanup; } module->p2p_sc_group = group; /* possible we've already received a couple in messages, so add however many we're going to wait for */ module->p2p_num_post_msgs += ompi_group_size(module->p2p_sc_group); OPAL_THREAD_UNLOCK(&(module->p2p_lock)); memset(module->p2p_sc_remote_active_ranks, 0, sizeof(bool) * ompi_comm_size(module->p2p_comm)); /* for each process in the specified group, find it's rank in our communicator, store those indexes, and set the true / false in the active ranks table */ for (i = 0 ; i < ompi_group_size(group) ; i++) { int comm_rank = -1, j; /* find the rank in the communicator associated with this windows */ for (j = 0 ; j < ompi_comm_size(module->p2p_comm) ; ++j) { if (ompi_group_peer_lookup(module->p2p_sc_group, i) == ompi_comm_peer_lookup(module->p2p_comm, j)) { comm_rank = j; break; } } if (comm_rank == -1) { ret = MPI_ERR_RMA_SYNC; goto cleanup; } module->p2p_sc_remote_active_ranks[comm_rank] = true; module->p2p_sc_remote_ranks[i] = comm_rank; } /* Set our mode to access w/ start */ ompi_win_remove_mode(win, OMPI_WIN_FENCE); ompi_win_append_mode(win, OMPI_WIN_ACCESS_EPOCH | OMPI_WIN_STARTED); return OMPI_SUCCESS; cleanup: ompi_group_decrement_proc_count(group); OBJ_RELEASE(group); return ret; }
int ompi_osc_pt2pt_free(ompi_win_t *win) { int ret = OMPI_SUCCESS; ompi_osc_pt2pt_module_t *module = GET_MODULE(win); if (NULL == module) { return OMPI_SUCCESS; } if (NULL != module->comm) { opal_output_verbose(1, ompi_osc_base_framework.framework_output, "pt2pt component destroying window with id %d", ompi_comm_get_cid(module->comm)); /* finish with a barrier */ if (ompi_group_size(win->w_group) > 1) { ret = module->comm->c_coll.coll_barrier(module->comm, module->comm->c_coll.coll_barrier_module); } /* remove from component information */ OPAL_THREAD_SCOPED_LOCK(&mca_osc_pt2pt_component.lock, opal_hash_table_remove_value_uint32(&mca_osc_pt2pt_component.modules, ompi_comm_get_cid(module->comm))); } win->w_osc_module = NULL; OBJ_DESTRUCT(&module->outstanding_locks); OBJ_DESTRUCT(&module->locks_pending); OBJ_DESTRUCT(&module->locks_pending_lock); OBJ_DESTRUCT(&module->acc_lock); OBJ_DESTRUCT(&module->cond); OBJ_DESTRUCT(&module->lock); /* it is erroneous to close a window with active operations on it so we should * probably produce an error here instead of cleaning up */ OPAL_LIST_DESTRUCT(&module->pending_acc); OPAL_LIST_DESTRUCT(&module->pending_posts); osc_pt2pt_gc_clean (module); OPAL_LIST_DESTRUCT(&module->request_gc); OPAL_LIST_DESTRUCT(&module->buffer_gc); OBJ_DESTRUCT(&module->gc_lock); if (NULL != module->peers) { for (int i = 0 ; i < ompi_comm_size (module->comm) ; ++i) { OBJ_DESTRUCT(module->peers + i); } free(module->peers); } if (NULL != module->epoch_outgoing_frag_count) free(module->epoch_outgoing_frag_count); if (NULL != module->frag_request) { module->frag_request->req_complete_cb = NULL; ompi_request_cancel (module->frag_request); ompi_request_free (&module->frag_request); } if (NULL != module->comm) { ompi_comm_free(&module->comm); } if (NULL != module->incoming_buffer) free (module->incoming_buffer); if (NULL != module->free_after) free(module->free_after); free (module); return ret; }
/* * Invoked when there's a new communicator that has been created. * Look at the communicator and decide which set of functions and * priority we want to return. */ mca_scoll_base_module_t * mca_scoll_mpi_comm_query(oshmem_group_t *osh_group, int *priority) { mca_scoll_base_module_t *module; mca_scoll_mpi_module_t *mpi_module; int err, i; int tag; ompi_group_t* parent_group, *new_group; ompi_communicator_t* newcomm = NULL; *priority = 0; mca_scoll_mpi_component_t *cm; cm = &mca_scoll_mpi_component; int* ranks; if (!cm->mpi_enable){ return NULL; } if ((osh_group->proc_count < 2) || (osh_group->proc_count < cm->mpi_np)) { return NULL; } /* Create OMPI_Comm object and store ptr to it in group obj*/ if (NULL == oshmem_group_all) { osh_group->ompi_comm = &(ompi_mpi_comm_world.comm); } else { int my_rank = MPI_UNDEFINED; err = ompi_comm_group(&(ompi_mpi_comm_world.comm), &parent_group); if (OPAL_UNLIKELY(OMPI_SUCCESS != err)) { return NULL; } ranks = (int*) malloc(osh_group->proc_count * sizeof(int)); if (OPAL_UNLIKELY(NULL == ranks)) { return NULL; } tag = 1; for (i = 0; i < osh_group->proc_count; i++) { ompi_proc_t* ompi_proc; for( int j = 0; j < ompi_group_size(parent_group); j++ ) { ompi_proc = ompi_group_peer_lookup(parent_group, j); if( 0 == opal_compare_proc(ompi_proc->super.proc_name, osh_group->proc_array[i]->super.proc_name)) { ranks[i] = j; break; } } /* NTH: keep track of my rank in the new group for the workaround below */ if (ranks[i] == ompi_comm_rank (&ompi_mpi_comm_world.comm)) { my_rank = i; } } err = ompi_group_incl(parent_group, osh_group->proc_count, ranks, &new_group); if (OPAL_UNLIKELY(OMPI_SUCCESS != err)) { free(ranks); return NULL; } /* NTH: XXX -- WORKAROUND -- The oshmem code overwrites ompi_proc_local_proc with its * own proc but does not update the proc list in comm world or comm self. This causes * the code in ompi_group_incl that updates grp_my_rank to fail. This will cause failures * here and when an application attempts to mix oshmem and mpi so it will really need to * be fixed in oshmem/proc and not here. For now we need to work around a new jenkins * failure so set my group ranking so we do not crash when running ompi_comm_create_group. */ new_group->grp_my_rank = my_rank; err = ompi_comm_create_group(&(ompi_mpi_comm_world.comm), new_group, tag, &newcomm); if (OPAL_UNLIKELY(OMPI_SUCCESS != err)) { free(ranks); return NULL; } err = ompi_group_free(&new_group); if (OPAL_UNLIKELY(OMPI_SUCCESS != err)) { free(ranks); return NULL; } free(ranks); osh_group->ompi_comm = newcomm; } mpi_module = OBJ_NEW(mca_scoll_mpi_module_t); if (!mpi_module){ return NULL; } mpi_module->comm = osh_group->ompi_comm; mpi_module->super.scoll_module_enable = mca_scoll_mpi_module_enable; mpi_module->super.scoll_barrier = mca_scoll_mpi_barrier; mpi_module->super.scoll_broadcast = mca_scoll_mpi_broadcast; mpi_module->super.scoll_reduce = mca_scoll_mpi_reduce; mpi_module->super.scoll_collect = mca_scoll_mpi_collect; *priority = cm->mpi_priority; module = &mpi_module->super; return module; }
int MPI_Group_range_incl(MPI_Group group, int n_triplets, int ranges[][3], MPI_Group *new_group) { int err, i,indx; int group_size; int * elements_int_list; /* can't act on NULL group */ if( MPI_PARAM_CHECK ) { OMPI_ERR_INIT_FINALIZE(FUNC_NAME); if ( (MPI_GROUP_NULL == group) || (NULL == group) || (NULL == new_group) ) { return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_GROUP, FUNC_NAME); } group_size = ompi_group_size ( group); elements_int_list = (int *) malloc(sizeof(int) * (group_size+1)); if (NULL == elements_int_list) { return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_OTHER, FUNC_NAME); } for (i = 0; i < group_size; i++) { elements_int_list[i] = -1; } for ( i=0; i < n_triplets; i++) { if ((0 > ranges[i][0]) || (ranges[i][0] > group_size)) { goto error_rank; } if ((0 > ranges[i][1]) || (ranges[i][1] > group_size)) { goto error_rank; } if (ranges[i][2] == 0) { goto error_rank; } if ((ranges[i][0] < ranges[i][1])) { if (ranges[i][2] < 0) { goto error_rank; } /* positive stride */ for (indx = ranges[i][0]; indx <= ranges[i][1]; indx += ranges[i][2]) { /* make sure rank has not already been selected */ if (elements_int_list[indx] != -1) { goto error_rank; } elements_int_list[indx] = i; } } else if (ranges[i][0] > ranges[i][1]) { if (ranges[i][2] > 0) { goto error_rank; } /* negative stride */ for (indx = ranges[i][0]; indx >= ranges[i][1]; indx += ranges[i][2]) { /* make sure rank has not already been selected */ if (elements_int_list[indx] != -1) { goto error_rank; } elements_int_list[indx] = i; } } else { /* first_rank == last_rank */ indx = ranges[i][0]; if (elements_int_list[indx] != -1) { goto error_rank; } elements_int_list[indx] = i; } } free ( elements_int_list); } OPAL_CR_ENTER_LIBRARY(); err = ompi_group_range_incl ( group, n_triplets, ranges, new_group ); OMPI_ERRHANDLER_RETURN(err, MPI_COMM_WORLD, err, FUNC_NAME ); error_rank: free(elements_int_list); return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_RANK, FUNC_NAME); }
/* * Invoked when there's a new communicator that has been created. * Look at the communicator and decide which set of functions and * priority we want to return. */ mca_scoll_base_module_t * mca_scoll_mpi_comm_query(oshmem_group_t *osh_group, int *priority) { mca_scoll_base_module_t *module; mca_scoll_mpi_module_t *mpi_module; int err, i; int tag; ompi_group_t* parent_group, *new_group; ompi_communicator_t* newcomm = NULL; *priority = 0; mca_scoll_mpi_component_t *cm; cm = &mca_scoll_mpi_component; int* ranks; if (!cm->mpi_enable){ return NULL; } if ((osh_group->proc_count < 2) || (osh_group->proc_count < cm->mpi_np)) { return NULL; } /* Create OMPI_Comm object and store ptr to it in group obj*/ if (NULL == oshmem_group_all) { osh_group->ompi_comm = &(ompi_mpi_comm_world.comm); } else { err = ompi_comm_group(&(ompi_mpi_comm_world.comm), &parent_group); if (OPAL_UNLIKELY(OMPI_SUCCESS != err)) { return NULL; } ranks = (int*) malloc(osh_group->proc_count * sizeof(int)); if (OPAL_UNLIKELY(NULL == ranks)) { return NULL; } tag = 1; for (i = 0; i < osh_group->proc_count; i++) { ompi_proc_t* ompi_proc; for( int j = 0; j < ompi_group_size(parent_group); j++ ) { ompi_proc = ompi_group_peer_lookup(parent_group, j); if( 0 == opal_compare_proc(ompi_proc->super.proc_name, osh_group->proc_array[i]->super.proc_name)) { ranks[i] = j; break; } } } err = ompi_group_incl(parent_group, osh_group->proc_count, ranks, &new_group); if (OPAL_UNLIKELY(OMPI_SUCCESS != err)) { free(ranks); return NULL; } err = ompi_comm_create_group(&(ompi_mpi_comm_world.comm), new_group, tag, &newcomm); if (OPAL_UNLIKELY(OMPI_SUCCESS != err)) { free(ranks); return NULL; } err = ompi_group_free(&new_group); if (OPAL_UNLIKELY(OMPI_SUCCESS != err)) { free(ranks); return NULL; } free(ranks); osh_group->ompi_comm = newcomm; } mpi_module = OBJ_NEW(mca_scoll_mpi_module_t); if (!mpi_module){ return NULL; } mpi_module->comm = osh_group->ompi_comm; mpi_module->super.scoll_module_enable = mca_scoll_mpi_module_enable; mpi_module->super.scoll_barrier = mca_scoll_mpi_barrier; mpi_module->super.scoll_broadcast = mca_scoll_mpi_broadcast; mpi_module->super.scoll_reduce = mca_scoll_mpi_reduce; mpi_module->super.scoll_collect = mca_scoll_mpi_collect; mpi_module->super.scoll_alltoall = NULL; *priority = cm->mpi_priority; module = &mpi_module->super; return module; }
int ompi_osc_rdma_module_free(ompi_win_t *win) { int ret = OMPI_SUCCESS; int tmp, i; ompi_osc_rdma_module_t *module = GET_MODULE(win); opal_output_verbose(1, ompi_osc_base_output, "rdma component destroying window with id %d", ompi_comm_get_cid(module->m_comm)); /* finish with a barrier */ if (ompi_group_size(win->w_group) > 1) { ret = module->m_comm->c_coll.coll_barrier(module->m_comm, module->m_comm->c_coll.coll_barrier_module); } /* remove from component information */ OPAL_THREAD_LOCK(&mca_osc_rdma_component.c_lock); tmp = opal_hash_table_remove_value_uint32(&mca_osc_rdma_component.c_modules, ompi_comm_get_cid(module->m_comm)); /* only take the output of hast_table_remove if there wasn't already an error */ ret = (ret != OMPI_SUCCESS) ? ret : tmp; if (0 == opal_hash_table_get_size(&mca_osc_rdma_component.c_modules)) { #if OPAL_ENABLE_PROGRESS_THREADS void *foo; mca_osc_rdma_component.c_thread_run = false; opal_condition_broadcast(&ompi_request_cond); opal_thread_join(&mca_osc_rdma_component.c_thread, &foo); #else opal_progress_unregister(ompi_osc_rdma_component_progress); #endif } OPAL_THREAD_UNLOCK(&mca_osc_rdma_component.c_lock); win->w_osc_module = NULL; OBJ_DESTRUCT(&module->m_unlocks_pending); OBJ_DESTRUCT(&module->m_locks_pending); OBJ_DESTRUCT(&module->m_queued_sendreqs); OBJ_DESTRUCT(&module->m_copy_pending_sendreqs); OBJ_DESTRUCT(&module->m_pending_sendreqs); OBJ_DESTRUCT(&module->m_acc_lock); OBJ_DESTRUCT(&module->m_cond); OBJ_DESTRUCT(&module->m_lock); if (NULL != module->m_sc_remote_ranks) { free(module->m_sc_remote_ranks); } if (NULL != module->m_sc_remote_active_ranks) { free(module->m_sc_remote_active_ranks); } if (NULL != module->m_pending_buffers) { free(module->m_pending_buffers); } if (NULL != module->m_fence_coll_counts) { free(module->m_fence_coll_counts); } if (NULL != module->m_copy_num_pending_sendreqs) { free(module->m_copy_num_pending_sendreqs); } if (NULL != module->m_num_pending_sendreqs) { free(module->m_num_pending_sendreqs); } if (NULL != module->m_peer_info) { for (i = 0 ; i < ompi_comm_size(module->m_comm) ; ++i) { ompi_osc_rdma_peer_info_free(&module->m_peer_info[i]); } free(module->m_peer_info); } if (NULL != module->m_comm) ompi_comm_free(&module->m_comm); if (NULL != module) free(module); return ret; }
static int ompi_comm_allreduce_group_nb (int *inbuf, int *outbuf, int count, struct ompi_op_t *op, ompi_comm_cid_context_t *cid_context, ompi_request_t **req) { ompi_group_t *group = cid_context->newcomm->c_local_group; const int group_size = ompi_group_size (group); const int group_rank = ompi_group_rank (group); ompi_communicator_t *comm = cid_context->comm; int peers_group[3], *tmp, subreq_count = 0; ompi_comm_allreduce_context_t *context; ompi_comm_request_t *request; ompi_request_t *subreq[3]; context = ompi_comm_allreduce_context_alloc (inbuf, outbuf, count, op, cid_context); if (NULL == context) { return OMPI_ERR_OUT_OF_RESOURCE; } tmp = context->tmpbuf = calloc (sizeof (int), count * 3); if (NULL == context->tmpbuf) { OBJ_RELEASE(context); return OMPI_ERR_OUT_OF_RESOURCE; } request = ompi_comm_request_get (); if (NULL == request) { OBJ_RELEASE(context); return OMPI_ERR_OUT_OF_RESOURCE; } request->context = &context->super; /* basic recursive doubling allreduce on the group */ peers_group[0] = group_rank ? ((group_rank - 1) >> 1) : MPI_PROC_NULL; peers_group[1] = (group_rank * 2 + 1) < group_size ? group_rank * 2 + 1: MPI_PROC_NULL; peers_group[2] = (group_rank * 2 + 2) < group_size ? group_rank * 2 + 2 : MPI_PROC_NULL; /* translate the ranks into the ranks of the parent communicator */ ompi_group_translate_ranks (group, 3, peers_group, comm->c_local_group, context->peers_comm); /* reduce */ memmove (outbuf, inbuf, sizeof (int) * count); for (int i = 0 ; i < 2 ; ++i) { if (MPI_PROC_NULL != context->peers_comm[i + 1]) { int rc = MCA_PML_CALL(irecv(tmp, count, MPI_INT, context->peers_comm[i + 1], cid_context->pml_tag, comm, subreq + subreq_count++)); if (OMPI_SUCCESS != rc) { ompi_comm_request_return (request); return rc; } tmp += count; } } ompi_comm_request_schedule_append (request, ompi_comm_allreduce_group_recv_complete, subreq, subreq_count); ompi_comm_request_start (request); *req = &request->super; return OMPI_SUCCESS; }