int MPIR_Setup_intercomm_localcomm(MPID_Comm * intercomm_ptr) { MPID_Comm *localcomm_ptr; int mpi_errno = MPI_SUCCESS; MPID_MPI_STATE_DECL(MPID_STATE_MPIR_SETUP_INTERCOMM_LOCALCOMM); MPID_MPI_FUNC_ENTER(MPID_STATE_MPIR_SETUP_INTERCOMM_LOCALCOMM); localcomm_ptr = (MPID_Comm *) MPIU_Handle_obj_alloc(&MPID_Comm_mem); MPIR_ERR_CHKANDJUMP(!localcomm_ptr, mpi_errno, MPI_ERR_OTHER, "**nomem"); /* get sensible default values for most fields (usually zeros) */ mpi_errno = MPIR_Comm_init(localcomm_ptr); if (mpi_errno) MPIR_ERR_POP(mpi_errno); /* use the parent intercomm's recv ctx as the basis for our ctx */ localcomm_ptr->recvcontext_id = MPID_CONTEXT_SET_FIELD(IS_LOCALCOMM, intercomm_ptr->recvcontext_id, 1); localcomm_ptr->context_id = localcomm_ptr->recvcontext_id; MPIU_DBG_MSG_FMT(COMM, TYPICAL, (MPIU_DBG_FDEST, "setup_intercomm_localcomm ic=%p ic->context_id=%d ic->recvcontext_id=%d lc->recvcontext_id=%d", intercomm_ptr, intercomm_ptr->context_id, intercomm_ptr->recvcontext_id, localcomm_ptr->recvcontext_id)); /* Save the kind of the communicator */ localcomm_ptr->comm_kind = MPID_INTRACOMM; /* Set the sizes and ranks */ localcomm_ptr->remote_size = intercomm_ptr->local_size; localcomm_ptr->local_size = intercomm_ptr->local_size; localcomm_ptr->rank = intercomm_ptr->rank; MPIR_Comm_map_dup(localcomm_ptr, intercomm_ptr, MPIR_COMM_MAP_DIR_L2L); /* TODO More advanced version: if the group is available, dup it by * increasing the reference count instead of recreating it later */ /* FIXME : No coll_fns functions for the collectives */ /* FIXME : No local functions for the topology routines */ intercomm_ptr->local_comm = localcomm_ptr; /* sets up the SMP-aware sub-communicators and tables */ mpi_errno = MPIR_Comm_commit(localcomm_ptr); if (mpi_errno) MPIR_ERR_POP(mpi_errno); fn_fail: MPID_MPI_FUNC_EXIT(MPID_STATE_MPIR_SETUP_INTERCOMM_LOCALCOMM); return mpi_errno; }
static int MPIDI_CH3I_Initialize_tmp_comm(MPID_Comm **comm_pptr, MPIDI_VC_t *vc_ptr, int is_low_group, int context_id_offset) { int mpi_errno = MPI_SUCCESS; MPID_Comm *tmp_comm, *commself_ptr; MPIDI_STATE_DECL(MPID_STATE_MPIDI_CH3I_INITIALIZE_TMP_COMM); MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_CH3I_INITIALIZE_TMP_COMM); MPID_Comm_get_ptr( MPI_COMM_SELF, commself_ptr ); /* WDG-old code allocated a context id that was then discarded */ mpi_errno = MPIR_Comm_create(&tmp_comm); if (mpi_errno != MPI_SUCCESS) { MPIU_ERR_POP(mpi_errno); } /* fill in all the fields of tmp_comm. */ /* We use the second half of the context ID bits for dynamic * processes. This assumes that the context ID mask array is made * up of uint32_t's. */ /* FIXME: This code is still broken for the following case: * If the same process opens connections to the multiple * processes, this context ID might get out of sync. */ tmp_comm->context_id = MPID_CONTEXT_SET_FIELD(DYNAMIC_PROC, context_id_offset, 1); tmp_comm->recvcontext_id = tmp_comm->context_id; /* sanity: the INVALID context ID value could potentially conflict with the * dynamic proccess space */ MPIU_Assert(tmp_comm->context_id != MPIR_INVALID_CONTEXT_ID); MPIU_Assert(tmp_comm->recvcontext_id != MPIR_INVALID_CONTEXT_ID); /* FIXME - we probably need a unique context_id. */ tmp_comm->remote_size = 1; /* Fill in new intercomm */ tmp_comm->local_size = 1; tmp_comm->rank = 0; tmp_comm->comm_kind = MPID_INTERCOMM; tmp_comm->local_comm = NULL; tmp_comm->is_low_group = is_low_group; /* No pg structure needed since vc has already been set up (connection has been established). */ /* Point local vcr, vcrt at those of commself_ptr */ /* FIXME: Explain why */ tmp_comm->local_vcrt = commself_ptr->vcrt; MPID_VCRT_Add_ref(commself_ptr->vcrt); tmp_comm->local_vcr = commself_ptr->vcr; /* No pg needed since connection has already been formed. FIXME - ensure that the comm_release code does not try to free an unallocated pg */ /* Set up VC reference table */ mpi_errno = MPID_VCRT_Create(tmp_comm->remote_size, &tmp_comm->vcrt); if (mpi_errno != MPI_SUCCESS) { MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER, "**init_vcrt"); } mpi_errno = MPID_VCRT_Get_ptr(tmp_comm->vcrt, &tmp_comm->vcr); if (mpi_errno != MPI_SUCCESS) { MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER, "**init_getptr"); } /* FIXME: Why do we do a dup here? */ MPID_VCR_Dup(vc_ptr, tmp_comm->vcr); /* Even though this is a tmp comm and we don't call MPI_Comm_commit, we still need to call the creation hook because the destruction hook will be called in comm_release */ mpi_errno = MPID_Dev_comm_create_hook(tmp_comm); if (mpi_errno) MPIU_ERR_POP(mpi_errno); *comm_pptr = tmp_comm; fn_exit: MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_CH3I_INITIALIZE_TMP_COMM); return mpi_errno; fn_fail: goto fn_exit; }