btl_gm_component.c

来自「MPI stands for the Message Passing Inter」· C语言 代码 · 共 730 行 · 第 1/2 页

C
730
字号
 * Scan all ports on the boards. As it's difficult to find the total number of boards * so we use a predefined maximum.   */static int mca_btl_gm_discover( void ){    uint32_t board_no;    uint32_t  port_no;    uint32_t node_id;    struct gm_port* port;#if GM_API_VERSION > 0x200    uint32_t global_id;#else    char  global_id[GM_MAX_HOST_NAME_LEN];#endif  /* GM_API_VERSION > 0x200 */    int rc;        for( board_no = 0; board_no < mca_btl_gm_component.gm_max_boards; board_no++ ) {        mca_btl_gm_module_t *btl;        /* open the first available gm port for this board  */        for( port_no = 4; port_no < mca_btl_gm_component.gm_max_ports; port_no++ ) {            if (3 == port_no) {                continue;  /* port 0,1,3 reserved  */            } else if (GM_SUCCESS == gm_open(&port, board_no, port_no,                mca_btl_gm_component.gm_port_name, GM_API_VERSION) ) {                break;            }        }        if( port_no == mca_btl_gm_component.gm_max_ports ) {            continue;        }        /*  Get node local Id */        if( GM_SUCCESS != gm_get_node_id( port, &node_id) ) {            opal_output (0, " failure to get node_id \n");            continue;        }        /* Gather an unique id for the node */#if GM_API_VERSION > 0x200        if (GM_SUCCESS != gm_node_id_to_global_id( port, node_id, &global_id) ) {            opal_output (0, "[%s:%d] Unable to get my GM global unique id", __FILE__, __LINE__);            continue;        }#else        if( GM_SUCCESS != gm_get_host_name( port, global_id ) ) {            opal_output( 0, "[%s:%d] Unable to get the GM host name\n", __FILE__, __LINE__);            continue;        }#endif  /* GM_API_VERSION > 0x200 */        /* create the btl module */        btl = (mca_btl_gm_module_t *)malloc( sizeof(mca_btl_gm_module_t) );        if (NULL == btl) {            opal_output( 0, "[%s:%d] out of resources", __FILE__, __LINE__);            return OMPI_ERR_OUT_OF_RESOURCE;        }        /* copy the basic informations into the new BTL */        memcpy (btl, &mca_btl_gm_module, sizeof(mca_btl_gm_module_t));        /* setup local address */        btl->port = port;        btl->gm_addr.port_id  = port_no;        btl->gm_addr.node_id = node_id;#if GM_API_VERSION > 0x200        btl->gm_addr.global_id = global_id;#else        strncpy( btl->gm_addr.global_id, global_id, GM_MAX_HOST_NAME_LEN );#endif  /* GM_API_VERSION > 0x200 */        if(mca_btl_gm_component.gm_debug > 0) {            opal_output(0, "[%d,%d,%d] gm_port %08X, board %lu, global %lu node %lu port %lu\n",                 ORTE_NAME_ARGS(orte_process_info.my_name), port, board_no, global_id, node_id, port_no);        }        if((rc = mca_btl_gm_module_init(btl)) != OMPI_SUCCESS) {            opal_output(0, "[%s:%d] unable to initialze gm port", __FILE__, __LINE__);            return rc;        }        /* everything is OK let's mark it as usable and go to the next one */        mca_btl_gm_component.gm_btls[mca_btl_gm_component.gm_num_btls] = btl;        if(++mca_btl_gm_component.gm_num_btls >= mca_btl_gm_component.gm_max_btls ) {            break;        }    }    return OMPI_SUCCESS;}/* *  Register GM component addressing information. The MCA framework *  will make this available to all peers. */static intmca_btl_gm_modex_send(void){    int         rc;    size_t      i;    size_t      size;    mca_btl_gm_addr_t *addrs = NULL;    size = mca_btl_gm_component.gm_num_btls * sizeof (mca_btl_gm_addr_t);    if (0 != size) {        addrs = (mca_btl_gm_addr_t *)malloc (size);        if (NULL == addrs) {            return OMPI_ERR_OUT_OF_RESOURCE;        }        for (i = 0; i < mca_btl_gm_component.gm_num_btls; i++) {            mca_btl_gm_module_t *btl = mca_btl_gm_component.gm_btls[i];            addrs[i] = btl->gm_addr;            MCA_BTL_GM_ADDR_HTON(addrs[i]);        }    }    rc = mca_pml_base_modex_send (&mca_btl_gm_component.super.btl_version, addrs, size);    if (NULL != addrs) {        free (addrs);    }    return rc;}                                                                                                                /* * Initialize the GM component, * check how many boards are available and open ports on them. */                                                                                                                mca_btl_base_module_t **mca_btl_gm_component_init (int *num_btl_modules,                           bool enable_progress_threads,                           bool enable_mpi_threads){    mca_btl_base_module_t **btls;    *num_btl_modules = 0;    OPAL_THREAD_LOCK(&mca_btl_gm_component.gm_lock);    /* try to initialize GM */    if( GM_SUCCESS != gm_init() ) {        opal_output( 0, "[%s:%d] error in initializing the gm library\n", __FILE__, __LINE__ );        mca_btl_gm_component.gm_num_btls = 0;        mca_btl_gm_modex_send();        OPAL_THREAD_UNLOCK(&mca_btl_gm_component.gm_lock);        return NULL;    }    /* First discover all available boards. For each board we create a unique BTL */    mca_btl_gm_component.gm_btls = malloc( mca_btl_gm_component.gm_max_btls * sizeof (mca_btl_gm_module_t *));    if (NULL == mca_btl_gm_component.gm_btls) {        opal_output( 0, "[%s:%d] out of resources.", __FILE__, __LINE__ );        OPAL_THREAD_UNLOCK(&mca_btl_gm_component.gm_lock);        return NULL;    }    /* initialize gm */    if (OMPI_SUCCESS != mca_btl_gm_discover()) {        mca_btl_base_error_no_nics("Myrinet/GM", "NIC");        mca_btl_gm_component.gm_num_btls = 0;        mca_btl_gm_modex_send();        OPAL_THREAD_UNLOCK(&mca_btl_gm_component.gm_lock);        return NULL;    }    if (mca_btl_gm_component.gm_num_btls == 0) {        mca_btl_base_error_no_nics("Myrinet/GM", "NIC");        mca_btl_gm_component.gm_num_btls = 0;        mca_btl_gm_modex_send();        OPAL_THREAD_UNLOCK(&mca_btl_gm_component.gm_lock);        return NULL;    }    /* publish GM parameters with the MCA framework */    if (OMPI_SUCCESS != mca_btl_gm_modex_send()) {        OPAL_THREAD_UNLOCK(&mca_btl_gm_component.gm_lock);        return NULL;    }    /* return array of BTLs */    btls = (mca_btl_base_module_t**) malloc (                mca_btl_gm_component.gm_num_btls * sizeof(mca_btl_base_module_t *));    if (NULL == btls) {        OPAL_THREAD_UNLOCK(&mca_btl_gm_component.gm_lock);        return NULL;    }    memcpy(btls, mca_btl_gm_component.gm_btls,           mca_btl_gm_component.gm_num_btls * sizeof(mca_btl_gm_module_t *));    *num_btl_modules = mca_btl_gm_component.gm_num_btls;    OPAL_THREAD_UNLOCK(&mca_btl_gm_component.gm_lock);    return btls;}                                                                                                                /* *  GM component progress. */int mca_btl_gm_component_progress(){    static int32_t inprogress = 0;    int count = 0;    size_t i;        /* could get into deadlock in this case as we post recvs after callback completes */    if(OPAL_THREAD_ADD32(&inprogress, 1) > 1) {        OPAL_THREAD_ADD32(&inprogress, -1);        return OMPI_SUCCESS;    }    OPAL_THREAD_LOCK(&mca_btl_gm_component.gm_lock);    for( i = 0; i < mca_btl_gm_component.gm_num_btls; ) {        mca_btl_gm_module_t* btl = mca_btl_gm_component.gm_btls[i];        gm_recv_event_t* event = gm_receive(btl->port);        /* If there are no receive events just skip the function call */        switch(gm_ntohc(event->recv.type)) {            case GM_FAST_RECV_EVENT:            case GM_FAST_PEER_RECV_EVENT:            case GM_FAST_HIGH_RECV_EVENT:            case GM_FAST_HIGH_PEER_RECV_EVENT:                {                unsigned char* buffer = (unsigned char*)gm_ntohp(event->recv.buffer);                mca_btl_gm_frag_t* frag = (mca_btl_gm_frag_t*)(buffer - sizeof(mca_btl_gm_frag_t));                mca_btl_base_header_t* hdr = (mca_btl_base_header_t *)gm_ntohp(event->recv.message);                mca_btl_base_recv_reg_t* reg;                frag->segment.seg_addr.pval = (hdr+1);                frag->segment.seg_len = gm_ntohl(event->recv.length) - sizeof(mca_btl_base_header_t);                reg = &btl->gm_reg[hdr->tag];                /* cbfunc may be null if interface goes down.. */                if(reg->cbfunc) {                     OPAL_THREAD_UNLOCK(&mca_btl_gm_component.gm_lock);                    reg->cbfunc(&btl->super, hdr->tag, &frag->base, reg->cbdata);                    OPAL_THREAD_LOCK(&mca_btl_gm_component.gm_lock);                } else {                     btl->error_cb(&btl->super,                                   MCA_BTL_ERROR_FLAGS_FATAL);                    return 0;                }                MCA_BTL_GM_FRAG_POST(btl,frag);                count++;                break;                }            case GM_RECV_EVENT:            case GM_PEER_RECV_EVENT:            case GM_HIGH_RECV_EVENT:            case GM_HIGH_PEER_RECV_EVENT:                {                unsigned char* buffer = (unsigned char*)gm_ntohp(event->recv.buffer);                mca_btl_gm_frag_t* frag = (mca_btl_gm_frag_t*)(buffer - sizeof(mca_btl_gm_frag_t));                mca_btl_base_header_t* hdr = (mca_btl_base_header_t*)buffer;                mca_btl_base_recv_reg_t* reg;                frag->segment.seg_addr.pval = (hdr+1);                frag->segment.seg_len = gm_ntohl(event->recv.length) - sizeof(mca_btl_base_header_t);                reg = &btl->gm_reg[hdr->tag];                if(reg->cbfunc) {                     OPAL_THREAD_UNLOCK(&mca_btl_gm_component.gm_lock);                    reg->cbfunc(&btl->super, hdr->tag, &frag->base, reg->cbdata);                    OPAL_THREAD_LOCK(&mca_btl_gm_component.gm_lock);                                        MCA_BTL_GM_FRAG_POST(btl,frag);                } else {                     btl->error_cb(&btl->super,                                   MCA_BTL_ERROR_FLAGS_FATAL);                    return 0;                }                count++;                break;                }            case GM_NO_RECV_EVENT:                i++;                break;            default:                gm_unknown(btl->port, event);                break;        }    }    OPAL_THREAD_UNLOCK(&mca_btl_gm_component.gm_lock);    OPAL_THREAD_ADD32(&inprogress, -1);    return count;}#if OMPI_ENABLE_PROGRESS_THREADSstatic void* mca_btl_gm_progress_thread( opal_object_t* arg ){    opal_thread_t* thread = (opal_thread_t*)arg;    mca_btl_gm_module_t* btl = thread->t_arg;    /* This thread enter in a cancel enabled state */    pthread_setcancelstate( PTHREAD_CANCEL_ENABLE, NULL );    pthread_setcanceltype( PTHREAD_CANCEL_ASYNCHRONOUS, NULL );    OPAL_THREAD_LOCK(&mca_btl_gm_component.gm_lock);    while(btl->gm_progress) {        gm_recv_event_t* event;        /* dont process events while the app is in the library */        while(opal_progress_threads()) {            OPAL_THREAD_UNLOCK(&mca_btl_gm_component.gm_lock);            while(opal_progress_threads())               sched_yield();            usleep(100); /* give app a chance to re-enter library */            OPAL_THREAD_LOCK(&mca_btl_gm_component.gm_lock);        }        /* otherwise processes any pending events */        event = gm_blocking_receive_no_spin(btl->port);        switch(gm_ntohc(event->recv.type)) {            case GM_FAST_RECV_EVENT:            case GM_FAST_PEER_RECV_EVENT:            case GM_FAST_HIGH_RECV_EVENT:            case GM_FAST_HIGH_PEER_RECV_EVENT:                {                unsigned char* buffer = (unsigned char*)gm_ntohp(event->recv.buffer);                mca_btl_gm_frag_t* frag = (mca_btl_gm_frag_t*)(buffer - sizeof(mca_btl_gm_frag_t));                mca_btl_base_header_t* hdr = (mca_btl_base_header_t *)gm_ntohp(event->recv.message);                mca_btl_base_recv_reg_t* reg;                frag->segment.seg_addr.pval = (hdr+1);                frag->segment.seg_len = gm_ntohl(event->recv.length) - sizeof(mca_btl_base_header_t);                reg = &btl->gm_reg[hdr->tag];                OPAL_THREAD_UNLOCK(&mca_btl_gm_component.gm_lock);                reg->cbfunc(&btl->super, hdr->tag, &frag->base, reg->cbdata);                OPAL_THREAD_LOCK(&mca_btl_gm_component.gm_lock);                MCA_BTL_GM_FRAG_POST(btl,frag);                break;                }            case GM_RECV_EVENT:            case GM_PEER_RECV_EVENT:            case GM_HIGH_RECV_EVENT:            case GM_HIGH_PEER_RECV_EVENT:                {                unsigned char* buffer = (unsigned char*)gm_ntohp(event->recv.buffer);                mca_btl_gm_frag_t* frag = (mca_btl_gm_frag_t*)(buffer - sizeof(mca_btl_gm_frag_t));                mca_btl_base_header_t* hdr = (mca_btl_base_header_t*)buffer;                mca_btl_base_recv_reg_t* reg;                frag->segment.seg_addr.pval = (hdr+1);                frag->segment.seg_len = gm_ntohl(event->recv.length) - sizeof(mca_btl_base_header_t);                reg = &btl->gm_reg[hdr->tag];                OPAL_THREAD_UNLOCK(&mca_btl_gm_component.gm_lock);                reg->cbfunc(&btl->super, hdr->tag, &frag->base, reg->cbdata);                OPAL_THREAD_LOCK(&mca_btl_gm_component.gm_lock);                MCA_BTL_GM_FRAG_POST(btl,frag);                break;                }            case _GM_SLEEP_EVENT:                OPAL_THREAD_UNLOCK(&mca_btl_gm_component.gm_lock);                gm_unknown(btl->port, event);                OPAL_THREAD_LOCK(&mca_btl_gm_component.gm_lock);                break;            default:                gm_unknown(btl->port, event);                break;        }    }    OPAL_THREAD_UNLOCK(&mca_btl_gm_component.gm_lock);    return PTHREAD_CANCELED;}#endif                                                                                                                                       

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?