pml_ob1_recvfrag.c

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

C
772
字号
/* * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana *                         University Research and Technology *                         Corporation.  All rights reserved. * Copyright (c) 2004-2006 The University of Tennessee and The University *                         of Tennessee Research Foundation.  All rights *                         reserved. * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,  *                         University of Stuttgart.  All rights reserved. * Copyright (c) 2004-2005 The Regents of the University of California. *                         All rights reserved. * $COPYRIGHT$ *  * Additional copyrights may follow *  * $HEADER$ *//** * @file */#include "ompi_config.h"#include "opal/class/opal_list.h"#include "opal/threads/mutex.h"#include "ompi/constants.h"#include "ompi/communicator/communicator.h"#include "ompi/mca/pml/pml.h"#include "pml_ob1.h"#include "pml_ob1_comm.h"#include "pml_ob1_recvfrag.h"#include "pml_ob1_recvreq.h"#include "pml_ob1_sendreq.h"#include "pml_ob1_hdr.h"#include "ompi/datatype/dt_arch.h"#include "ompi/peruse/peruse-internal.h"OBJ_CLASS_INSTANCE( mca_pml_ob1_buffer_t,                    ompi_free_list_item_t,                    NULL,                    NULL );OBJ_CLASS_INSTANCE( mca_pml_ob1_recv_frag_t,                    opal_list_item_t,                    NULL,                    NULL );/** * Static functions. *//** * Match incoming recv_frags against posted receives.   * Supports out of order delivery. *  * @param frag_header (IN)          Header of received recv_frag. * @param frag_desc (IN)            Received recv_frag descriptor. * @param match_made (OUT)          Flag indicating wether a match was made. * @param additional_matches (OUT)  List of additional matches  * @return                          OMPI_SUCCESS or error status on failure. */static int mca_pml_ob1_recv_frag_match( mca_btl_base_module_t *btl,                                         mca_pml_ob1_match_hdr_t *hdr,                                        mca_btl_base_segment_t* segments,                                        size_t num_segments );/** *  Callback from BTL on receive. */                                                                                                                      void mca_pml_ob1_recv_frag_callback( mca_btl_base_module_t* btl,                                      mca_btl_base_tag_t tag,                                     mca_btl_base_descriptor_t* des,                                     void* cbdata ){    mca_btl_base_segment_t* segments = des->des_dst;    mca_pml_ob1_hdr_t* hdr = (mca_pml_ob1_hdr_t*)segments->seg_addr.pval;    if(segments->seg_len < sizeof(mca_pml_ob1_common_hdr_t)) {        return;    }    /* hdr_type and hdr_flags are uint8_t, so no endian problems */    switch(hdr->hdr_common.hdr_type) {    case MCA_PML_OB1_HDR_TYPE_MATCH:        {#if !defined(WORDS_BIGENDIAN) && OMPI_ENABLE_HETEROGENEOUS_SUPPORT            if (hdr->hdr_common.hdr_flags & MCA_PML_OB1_HDR_FLAGS_NBO) {                MCA_PML_OB1_MATCH_HDR_NTOH(hdr->hdr_match);            }#endif            mca_pml_ob1_recv_frag_match(btl, &hdr->hdr_match, segments,des->des_dst_cnt);            break;        }    case MCA_PML_OB1_HDR_TYPE_RNDV:        {#if !defined(WORDS_BIGENDIAN) && OMPI_ENABLE_HETEROGENEOUS_SUPPORT            if (hdr->hdr_common.hdr_flags & MCA_PML_OB1_HDR_FLAGS_NBO) {                MCA_PML_OB1_RNDV_HDR_NTOH(hdr->hdr_rndv);            }#endif            mca_pml_ob1_recv_frag_match(btl, &hdr->hdr_match, segments,des->des_dst_cnt);            break;        }    case MCA_PML_OB1_HDR_TYPE_RGET:        {#if !defined(WORDS_BIGENDIAN) && OMPI_ENABLE_HETEROGENEOUS_SUPPORT            /* RDMA is currently disabled by bml if arch doesn't               match, so this shouldn't be needed.  here to make sure               we remember if we ever change the bml. */            assert(0 == (hdr->hdr_common.hdr_flags & MCA_PML_OB1_HDR_FLAGS_NBO));#endif            mca_pml_ob1_recv_frag_match(btl, &hdr->hdr_match, segments,des->des_dst_cnt);            break;        }    case MCA_PML_OB1_HDR_TYPE_ACK:        {            mca_pml_ob1_send_request_t* sendreq;#if !defined(WORDS_BIGENDIAN) && OMPI_ENABLE_HETEROGENEOUS_SUPPORT            if (hdr->hdr_common.hdr_flags & MCA_PML_OB1_HDR_FLAGS_NBO) {                MCA_PML_OB1_ACK_HDR_NTOH(hdr->hdr_ack);            }#endif            sendreq = (mca_pml_ob1_send_request_t*)                hdr->hdr_ack.hdr_src_req.pval;            sendreq->req_recv = hdr->hdr_ack.hdr_dst_req;            sendreq->req_rdma_offset = (size_t)hdr->hdr_ack.hdr_rdma_offset;            if(OPAL_THREAD_ADD32(&sendreq->req_state, 1) == 2 &&                    sendreq->req_bytes_delivered >=                    sendreq->req_send.req_bytes_packed) {                MCA_PML_OB1_SEND_REQUEST_PML_COMPLETE(sendreq);            } else {                mca_pml_ob1_send_request_schedule(sendreq);            }                            break;        }    case MCA_PML_OB1_HDR_TYPE_FRAG:        {            mca_pml_ob1_recv_request_t* recvreq;#if !defined(WORDS_BIGENDIAN) && OMPI_ENABLE_HETEROGENEOUS_SUPPORT            if (hdr->hdr_common.hdr_flags & MCA_PML_OB1_HDR_FLAGS_NBO) {                MCA_PML_OB1_FRAG_HDR_NTOH(hdr->hdr_frag);            }#endif            recvreq = (mca_pml_ob1_recv_request_t*)                hdr->hdr_frag.hdr_dst_req.pval;            mca_pml_ob1_recv_request_progress(recvreq,btl,segments,des->des_dst_cnt);            break;        }    case MCA_PML_OB1_HDR_TYPE_PUT:        {            mca_pml_ob1_send_request_t* sendreq;#if !defined(WORDS_BIGENDIAN) && OMPI_ENABLE_HETEROGENEOUS_SUPPORT            /* RDMA is currently disabled by bml if arch doesn't               match, so this shouldn't be needed.  here to make sure               we remember if we ever change the bml. */            assert(0 == (hdr->hdr_common.hdr_flags & MCA_PML_OB1_HDR_FLAGS_NBO));#endif            sendreq = (mca_pml_ob1_send_request_t*)                hdr->hdr_rdma.hdr_req.pval;            mca_pml_ob1_send_request_put(sendreq,btl,&hdr->hdr_rdma);            break;        }    case MCA_PML_OB1_HDR_TYPE_FIN:        {            mca_btl_base_descriptor_t* rdma;#if !defined(WORDS_BIGENDIAN) && OMPI_ENABLE_HETEROGENEOUS_SUPPORT            if (hdr->hdr_common.hdr_flags & MCA_PML_OB1_HDR_FLAGS_NBO) {                MCA_PML_OB1_FIN_HDR_NTOH(hdr->hdr_fin);            }#endif            rdma = (mca_btl_base_descriptor_t*)                hdr->hdr_fin.hdr_des.pval;            rdma->des_cbfunc(btl, NULL, rdma, OMPI_SUCCESS);            break;        }    default:        break;    }}/** * Try and match the incoming message fragment to a generic * list of receives * * @param hdr Matching data from received fragment (IN) * * @param generic_receives Pointer to the receive list used for * matching purposes. (IN) * * @return Matched receive * * This routine assumes that the appropriate matching locks are * set by the upper level routine. */#define MCA_PML_OB1_MATCH_GENERIC_RECEIVES(hdr,generic_receives,proc,return_match) \    do {                                                                           \        /* local variables */                                                      \        mca_pml_ob1_recv_request_t *generic_recv = (mca_pml_ob1_recv_request_t *)  \                     opal_list_get_first(generic_receives);                        \        mca_pml_ob1_recv_request_t *last_recv = (mca_pml_ob1_recv_request_t *)     \            opal_list_get_end(generic_receives);                                   \        register int recv_tag, frag_tag = hdr->hdr_tag;                            \                                                                                   \        /* Loop over the receives. If the received tag is less than zero  */       \        /* enter in a special mode, where we match only our internal tags */       \        /* (such as those used by the collectives.*/                               \        if( 0 <= frag_tag ) {                                                      \            for( ; generic_recv != last_recv;                                      \                 generic_recv = (mca_pml_ob1_recv_request_t *)                     \                     ((opal_list_item_t *)generic_recv)->opal_list_next) {         \                /* Check for a match */                                            \                recv_tag = generic_recv->req_recv.req_base.req_tag;                \                if ( (frag_tag == recv_tag) || (recv_tag == OMPI_ANY_TAG) ) {      \                    break;                                                         \                }                                                                  \            }                                                                      \        } else {                                                                   \            for( ; generic_recv != last_recv;                                      \                 generic_recv = (mca_pml_ob1_recv_request_t *)                     \                     ((opal_list_item_t *)generic_recv)->opal_list_next) {         \                /* Check for a match */                                            \                recv_tag = generic_recv->req_recv.req_base.req_tag;                \                if(frag_tag == recv_tag) {                        \                    break;                                                         \                }                                                                  \            }                                                                      \        }                                                                          \        if( generic_recv != (mca_pml_ob1_recv_request_t *)                         \            opal_list_get_end(generic_receives) ) {                                \                                                                                   \            /* Match made */                                                       \            return_match = generic_recv;                                           \                                                                                   \            /* remove descriptor from posted specific ireceive list */             \            opal_list_remove_item(generic_receives,                                \                                  (opal_list_item_t *)generic_recv);               \                                                                                   \        }                                                                          \    } while(0)/** * Try and match the incoming message fragment to the list of * "wild" receives * * @param hdr Matching data from recived fragment (IN) * * @param pml_comm Pointer to the communicator structure used for * matching purposes. (IN) * * @return Matched receive * * This routine assumes that the appropriate matching locks are * set by the upper level routine. */

⌨️ 快捷键说明

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