PMPI_LOCAL int MPIR_Comm_create_create_and_map_vcrt(int n, int *mapping, MPID_VCR *mapping_vcr, MPID_VCRT *out_vcrt, MPID_VCR **out_vcr) { int mpi_errno = MPI_SUCCESS; int i; MPID_VCR *vcr = NULL; MPID_VCRT_Create(n, out_vcrt); MPID_VCRT_Get_ptr(*out_vcrt, out_vcr); vcr = *out_vcr; for (i=0; i<n; i++) { MPIU_DBG_MSG_FMT(COMM,VERBOSE, (MPIU_DBG_FDEST, "dupping from mapping_vcr=%p rank=%d into new_rank=%d/%d in new_vcr=%p", mapping_vcr, mapping[i], i, n, vcr)); mpi_errno = MPID_VCR_Dup(mapping_vcr[mapping[i]], &vcr[i]); if (mpi_errno) MPIU_ERR_POP(mpi_errno); } fn_fail: 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; }