int MPIDI_CH3_Connect_to_root (const char *port_name, MPIDI_VC_t **new_vc) { int mpi_errno = MPI_SUCCESS; MPIDI_VC_t * vc; MPIU_CHKPMEM_DECL(1); MPIDI_STATE_DECL(MPID_STATE_MPIDI_CH3_CONNECT_TO_ROOT); MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_CH3_CONNECT_TO_ROOT); *new_vc = NULL; /* so that the err handling knows to cleanup */ MPIU_CHKPMEM_MALLOC (vc, MPIDI_VC_t *, sizeof(MPIDI_VC_t), mpi_errno, "vc"); /* FIXME - where does this vc get freed? ANSWER (goodell@) - ch3u_port.c FreeNewVC (but the VC_Destroy is in this file) */ /* init ch3 portion of vc */ MPIDI_VC_Init (vc, NULL, 0); /* init channel portion of vc */ MPIR_ERR_CHKINTERNAL(!nemesis_initialized, mpi_errno, "Nemesis not initialized"); vc->ch.recv_active = NULL; MPIDI_CHANGE_VC_STATE(vc, ACTIVE); *new_vc = vc; /* we now have a valid, disconnected, temp VC */ mpi_errno = MPID_nem_connect_to_root (port_name, vc); if (mpi_errno) MPIR_ERR_POP (mpi_errno); MPIU_CHKPMEM_COMMIT(); fn_exit: MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_CH3_CONNECT_TO_ROOT); return mpi_errno; fn_fail: /* freeing without giving the lower layer a chance to cleanup can lead to leaks on error */ if (*new_vc) MPIDI_CH3_VC_Destroy(*new_vc); MPIU_CHKPMEM_REAP(); goto fn_exit; }
int MPIDI_PG_Create(int vct_sz, void * pg_id, MPIDI_PG_t ** pg_ptr) { MPIDI_PG_t * pg = NULL, *pgnext; int p; int mpi_errno = MPI_SUCCESS; MPIR_CHKPMEM_DECL(2); MPIR_FUNC_VERBOSE_STATE_DECL(MPID_STATE_MPIDI_PG_CREATE); MPIR_FUNC_VERBOSE_ENTER(MPID_STATE_MPIDI_PG_CREATE); MPIR_CHKPMEM_MALLOC(pg,MPIDI_PG_t*,sizeof(MPIDI_PG_t),mpi_errno,"pg"); MPIR_CHKPMEM_MALLOC(pg->vct,MPIDI_VC_t *,sizeof(MPIDI_VC_t)*vct_sz, mpi_errno,"pg->vct"); if (verbose) { fprintf( stdout, "Creating a process group of size %d\n", vct_sz ); fflush(stdout); } pg->handle = 0; /* The reference count indicates the number of vc's that are or have been in use and not disconnected. It starts at zero, except for MPI_COMM_WORLD. */ MPIR_Object_set_ref(pg, 0); pg->size = vct_sz; pg->id = pg_id; pg->finalize = 0; /* Initialize the connection information to null. Use the appropriate MPIDI_PG_InitConnXXX routine to set up these fields */ pg->connData = 0; pg->getConnInfo = 0; pg->connInfoToString = 0; pg->connInfoFromString = 0; pg->freeConnInfo = 0; for (p = 0; p < vct_sz; p++) { /* Initialize device fields in the VC object */ MPIDI_VC_Init(&pg->vct[p], pg, p); } /* We may first need to initialize the channel before calling the channel VC init functions. This routine may be a no-op; look in the ch3_init.c file in each channel */ MPIDI_CH3_PG_Init(pg); /* These are now done in MPIDI_VC_Init */ #if 0 for (p = 0; p < vct_sz; p++) { /* Initialize the channel fields in the VC object */ MPIDI_CH3_VC_Init( &pg->vct[p] ); } #endif /* The first process group is always the world group */ if (!pg_world) { pg_world = pg; } /* Add pg's at the tail so that comm world is always the first pg */ pg->next = 0; if (!MPIDI_PG_list) { MPIDI_PG_list = pg; } else { pgnext = MPIDI_PG_list; while (pgnext->next) { pgnext = pgnext->next; } pgnext->next = pg; } *pg_ptr = pg; fn_exit: MPIR_FUNC_VERBOSE_EXIT(MPID_STATE_MPIDI_PG_CREATE); return mpi_errno; fn_fail: MPIR_CHKPMEM_REAP(); goto fn_exit; }
int MPIDI_CH3_Connect_to_root(const char* port_name, MPIDI_VC_t** new_vc) { int mpi_errno = MPI_SUCCESS; int str_errno; char ifname[MAX_HOST_DESCRIPTION_LEN]; MPIDI_VC_t *vc; MPIDI_CH3_Pkt_cm_establish_t pkt; MPID_Request * sreq; int seqnum; MPIDI_STATE_DECL(MPID_STATE_MPIDI_CH3_CONNECT_TO_ROOT); MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_CH3_CONNECT_TO_ROOT); *new_vc = NULL; if (!MPIDI_CH3I_Process.has_dpm) return MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_FATAL, FCNAME, __LINE__, MPI_ERR_OTHER, "**notimpl", 0); str_errno = MPIU_Str_get_string_arg(port_name, MPIDI_CH3I_HOST_DESCRIPTION_KEY, ifname, MAX_HOST_DESCRIPTION_LEN); if (str_errno != MPIU_STR_SUCCESS) { /* --BEGIN ERROR HANDLING */ if (str_errno == MPIU_STR_FAIL) { MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER,"**argstr_missinghost"); } else { /* MPIU_STR_TRUNCATED or MPIU_STR_NONEM */ MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER, "**argstr_hostd"); } /* --END ERROR HANDLING-- */ } vc = MPIU_Malloc(sizeof(MPIDI_VC_t)); if (!vc) { MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER, "**nomem"); } MPIDI_VC_Init(vc, NULL, 0); mpi_errno = MPIDI_CH3I_CM_Connect_raw_vc(vc, ifname); if (mpi_errno) { MPIU_ERR_POP(mpi_errno); } while (vc->ch.state != MPIDI_CH3I_VC_STATE_IDLE) { mpi_errno = MPID_Progress_test(); /* --BEGIN ERROR HANDLING-- */ if (mpi_errno != MPI_SUCCESS) { MPIU_ERR_POP(mpi_errno); } } /* fprintf(stderr, "[###] vc state to idel, now send cm_establish msg\n") */ /* Now a connection is created, send a cm_establish message */ /* FIXME: vc->mrail.remote_vc_addr is used to find remote vc * A more elegant way is needed */ MPIDI_Pkt_init(&pkt, MPIDI_CH3_PKT_CM_ESTABLISH); MPIDI_VC_FAI_send_seqnum(vc, seqnum); MPIDI_Pkt_set_seqnum(&pkt, seqnum); pkt.vc_addr = vc->mrail.remote_vc_addr; mpi_errno = MPIDI_GetTagFromPort(port_name, &pkt.port_name_tag); if (mpi_errno != MPIU_STR_SUCCESS) { MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER, "**argstr_port_name_tag"); } mpi_errno = MPIDI_CH3_iStartMsg(vc, &pkt, sizeof(pkt), &sreq); if (mpi_errno != MPI_SUCCESS) { MPIU_ERR_SETANDJUMP1(mpi_errno,MPI_ERR_OTHER,"**fail", "**fail %s", "Failed to send cm establish message"); } if (sreq != NULL) { if (sreq->status.MPI_ERROR != MPI_SUCCESS) { mpi_errno = MPIR_Err_create_code(sreq->status.MPI_ERROR, MPIR_ERR_FATAL, FCNAME, __LINE__, MPI_ERR_OTHER, "**fail", 0); MPID_Request_release(sreq); goto fn_fail; } MPID_Request_release(sreq); } *new_vc = vc; fn_fail: MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_CH3_CONNECT_TO_ROOT); return mpi_errno; }