"Fossies" - the Fresh Open Source Software Archive

Member "mvapich2-2.3.2/src/mpid/ch3/channels/mrail/src/rdma/ch3_istartmsg.c" (8 Aug 2019, 11038 Bytes) of package /linux/misc/mvapich2-2.3.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "ch3_istartmsg.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 2.3.1_vs_2.3.2.

    1 /* -*- Mode: C; c-basic-offset:4 ; -*- */
    2 /*
    3  *  (C) 2001 by Argonne National Laboratory.
    4  *      See COPYRIGHT in top-level directory.
    5  */
    6 
    7 /* Copyright (c) 2001-2019, The Ohio State University. All rights
    8  * reserved.
    9  *
   10  * This file is part of the MVAPICH2 software package developed by the
   11  * team members of The Ohio State University's Network-Based Computing
   12  * Laboratory (NBCL), headed by Professor Dhabaleswar K. (DK) Panda.
   13  *
   14  * For detailed copyright and licensing information, please refer to the
   15  * copyright file COPYRIGHT in the top level MVAPICH2 directory.
   16  *
   17  */
   18 
   19 #include "mpidi_ch3_impl.h"
   20 #include "rdma_impl.h"
   21 
   22 #ifdef MPICH_DBG_OUTPUT
   23 #ifdef HAVE_ERRNO_H
   24 #include <errno.h>
   25 #endif
   26 #endif
   27 
   28 #undef DEBUG_PRINT
   29 #define DEBUG_PRINT(args...)                                  \
   30 do {                                                          \
   31     int rank;                                                 \
   32     UPMI_GET_RANK(&rank);                                      \
   33     fprintf(stderr, "[%d][%s:%d] ", rank, __FILE__, __LINE__);\
   34     fprintf(stderr, args);                                    \
   35 } while (0)
   36 
   37 #ifndef DEBUG
   38 #undef DEBUG_PRINT
   39 #define DEBUG_PRINT(args...)
   40 #endif
   41 
   42 #undef FUNCNAME
   43 #define FUNCNAME create_request
   44 #undef FCNAME
   45 #define FCNAME MPL_QUOTE(FUNCNAME)
   46 MPID_Request * create_request(void * hdr, MPIDI_msg_sz_t hdr_sz,
   47                         MPIU_Size_t nb)
   48 {
   49     MPIDI_STATE_DECL(MPID_STATE_CREATE_REQUEST);
   50     MPIDI_FUNC_ENTER(MPID_STATE_CREATE_REQUEST);
   51 
   52     MPID_Request* sreq = MPID_Request_create();
   53     /* --BEGIN ERROR HANDLING-- */
   54     if (sreq == NULL)
   55     {
   56         MPIDI_FUNC_EXIT(MPID_STATE_CREATE_REQUEST);
   57         return NULL;
   58     }
   59     /* --END ERROR HANDLING-- */
   60     MPIU_Object_set_ref(sreq, 2);
   61     sreq->kind = MPID_REQUEST_SEND;
   62     MV2_INC_NUM_POSTED_SEND();
   63 #ifdef _ENABLE_CUDA_
   64     sreq->dev.pending_pkt = MPIU_Malloc(hdr_sz - nb);
   65     MPIU_Memcpy(sreq->dev.pending_pkt, (char *)hdr + nb, hdr_sz - nb);
   66     sreq->dev.iov[0].MPL_IOV_BUF = (MPL_IOV_BUF_CAST)((char *)sreq->dev.pending_pkt);
   67 #else
   68     MPIU_Memcpy(&sreq->dev.pending_pkt, hdr, sizeof(MPIDI_CH3_Pkt_t));
   69     sreq->dev.iov[0].MPL_IOV_BUF = (MPL_IOV_BUF_CAST)((char *) &sreq->dev.pending_pkt + nb);
   70 #endif
   71     sreq->ch.reqtype = REQUEST_NORMAL;
   72     sreq->dev.iov[0].MPL_IOV_LEN = hdr_sz - nb;
   73     sreq->dev.iov_count = 1;
   74     sreq->dev.OnDataAvail = 0;
   75 
   76     MPIDI_FUNC_EXIT(MPID_STATE_CREATE_REQUEST);
   77     return sreq;
   78 }
   79 
   80 int MPIDI_CH3_SMP_iStartMsg(MPIDI_VC_t * vc, void *pkt,
   81                                           MPIDI_msg_sz_t pkt_sz,
   82                                           MPID_Request ** sreq_ptr);
   83 /*
   84  * MPIDI_CH3_iStartMsg() attempts to send the message immediately.  If the
   85  * entire message is successfully sent, then NULL is returned.  Otherwise a
   86  * request is allocated, the header is copied into the request, and a pointer
   87  * to the request is returned.  An error condition also results in a request be
   88  * allocated and the errror being returned in the status field of the
   89  * request.
   90  */
   91 #undef FUNCNAME
   92 #define FUNCNAME MPIDI_CH3_iStartMsg
   93 #undef FCNAME
   94 #define FCNAME MPL_QUOTE(FUNCNAME)
   95 int MPIDI_CH3_iStartMsg(MPIDI_VC_t * vc, void *pkt, MPIDI_msg_sz_t pkt_sz,
   96                         MPID_Request ** sreq_ptr)
   97 {
   98     int mpi_errno = MPI_SUCCESS;
   99     MPID_Request *sreq = NULL;
  100     MPL_IOV iov[1];
  101     MPIDI_STATE_DECL(MPID_STATE_MPIDI_CH3_ISTARTMSG);
  102 
  103     MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_CH3_ISTARTMSG);
  104 
  105     MPIU_DBG_PRINTF(("ch3_istartmsg\n"));
  106     MPIDI_DBG_PRINTF((50, FCNAME, "entering"));
  107 
  108 #if defined(CKPT)
  109     MPIDI_CH3I_CR_lock();
  110 #endif
  111 
  112     /* If send queue is empty attempt to send
  113        data, queuing any unsent data. */
  114     if (SMP_INIT && vc->smp.local_nodes >= 0 &&
  115         vc->smp.local_nodes != g_smpi.my_local_id) {
  116         mpi_errno = MPIDI_CH3_SMP_iStartMsg(vc, pkt, pkt_sz,sreq_ptr);
  117         MPIDI_DBG_PRINTF((50, FCNAME, "exiting"));
  118         MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_CH3_ISTARTMSG);
  119 #ifdef CKPT
  120     MPIDI_CH3I_CR_unlock();
  121 #endif
  122         return(mpi_errno);
  123     }
  124 
  125 #ifdef CKPT
  126     /*Detect whether the packet is CTS*/
  127     MPIDI_CH3_Pkt_t *upkt = (MPIDI_CH3_Pkt_t *)pkt;
  128     if (upkt->type == MPIDI_CH3_PKT_RNDV_CLR_TO_SEND) {
  129         MPIDI_CH3_Pkt_rndv_clr_to_send_t * cts_pkt = &(upkt->rndv_clr_to_send);
  130         if (cts_pkt->rndv.protocol == MV2_RNDV_PROTOCOL_RPUT) {
  131             /*If using rput protocol, keep track of the request*/
  132             MPID_Request *rreq;
  133             MPID_Request_get_ptr(cts_pkt->receiver_req_id, rreq);
  134             MPIDI_CH3I_CR_req_enqueue(rreq, vc);
  135         }
  136     }
  137 #endif
  138 
  139     /*CM code*/
  140     if ((vc->ch.state != MPIDI_CH3I_VC_STATE_IDLE 
  141 #ifdef _ENABLE_XRC_
  142             || (USE_XRC && VC_XST_ISUNSET (vc, XF_SEND_IDLE))
  143 #endif
  144             ) || !MPIDI_CH3I_CM_SendQ_empty(vc)) {
  145         /*Request need to be queued*/
  146         MPIDI_DBG_PRINTF((55, FCNAME, "not connected, enqueuing"));
  147         sreq = create_request(pkt, pkt_sz, 0);
  148         MPIDI_CH3I_CM_SendQ_enqueue(vc, sreq);
  149         if (vc->ch.state == MPIDI_CH3I_VC_STATE_UNCONNECTED)  {
  150             MPIDI_CH3I_CM_Connect(vc);
  151         }
  152         goto fn_exit;
  153     }
  154 
  155     if (MPIDI_CH3I_SendQ_empty(vc)) {   /* MT */
  156         int nb;
  157         int pkt_len;
  158         vbuf *buf;
  159 
  160         /* MT - need some signalling to lock down our right to use the
  161            channel, thus insuring that the progress engine does also try to
  162            write */
  163 
  164         iov[0].MPL_IOV_BUF = pkt;
  165         iov[0].MPL_IOV_LEN = pkt_sz;
  166         pkt_len = pkt_sz;
  167 
  168         /* TODO: Codes to send pkt through send/recv path */
  169         mpi_errno =
  170             MPIDI_CH3I_MRAILI_Eager_send(vc, iov, 1, pkt_len, &nb, &buf);
  171         DEBUG_PRINT("[istartmsgv] mpierr %d, nb %d\n", mpi_errno, nb);
  172 
  173         if (mpi_errno == MPI_SUCCESS) {
  174             DEBUG_PRINT("[send path] eager send return %d bytes\n", nb);
  175             goto fn_exit;
  176         } else if (MPI_MRAIL_MSG_QUEUED == mpi_errno) {
  177             /* fast rdma ok but cannot send: there is no send wqe available */
  178             /* sreq = create_request(pkt, pkt_sz, 0);
  179             buf->sreq = (void *) sreq;   */ 
  180             mpi_errno = MPI_SUCCESS;
  181             goto fn_exit;
  182         } else {
  183             sreq = MPID_Request_create();
  184             if (sreq == NULL) {
  185                 mpi_errno =
  186                     MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_FATAL,
  187                                          FCNAME, __LINE__,
  188                                          MPI_ERR_OTHER, "**nomem", 0);
  189                 goto fn_exit;
  190             }
  191             sreq->kind = MPID_REQUEST_SEND;
  192             MV2_INC_NUM_POSTED_SEND();
  193             MPID_cc_set(&sreq->cc, 0);
  194             /* TODO: Create an appropriate error message based on the value of errno
  195              * */
  196             sreq->status.MPI_ERROR = MPI_ERR_INTERN;
  197             PRINT_DEBUG(DEBUG_SHM_verbose>1,
  198                     "Enqueue send to rank: %d, sreq: %p, type: %d, ch.reqtype: %d\n",
  199                     vc->pg_rank, sreq, MPIDI_Request_get_type(sreq), sreq->ch.reqtype);
  200         }
  201     } else {
  202         sreq = create_request(pkt, pkt_sz, 0);
  203         MPIDI_CH3I_SendQ_enqueue(vc, sreq);
  204         PRINT_DEBUG(DEBUG_SHM_verbose>1,
  205                 "Eqnueue send to rank: %d, sreq: %p, type: %d, ch.reqtype: %d\n",
  206                 vc->pg_rank, sreq, MPIDI_Request_get_type(sreq), sreq->ch.reqtype);
  207     }
  208 
  209   fn_exit:
  210     *sreq_ptr = sreq;
  211 #ifdef CKPT
  212     MPIDI_CH3I_CR_unlock();
  213 #endif
  214 
  215     DEBUG_PRINT("Exiting istartmsg\n");
  216     MPIDI_DBG_PRINTF((50, FCNAME, "exiting"));
  217     MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_CH3_ISTARTMSG);
  218     return mpi_errno;
  219 }
  220 
  221 #undef FUNCNAME
  222 #define FUNCNAME MPIDI_CH3_SMP_iStartMsg
  223 #undef FCNAME
  224 #define FCNAME MPL_QUOTE(FUNCNAME)
  225 int MPIDI_CH3_SMP_iStartMsg(MPIDI_VC_t * vc, void *pkt,
  226                                           MPIDI_msg_sz_t pkt_sz,
  227                                           MPID_Request ** sreq_ptr)
  228 {
  229     MPIDI_STATE_DECL(MPID_STATE_MPIDI_CH3_SMP_ISTARTMSG);
  230     MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_CH3_SMP_ISTARTMSG);
  231     int mpi_errno = MPI_SUCCESS;
  232     MPID_Request *sreq = NULL;
  233     MPL_IOV iov[1];
  234     MPIDI_CH3_Pkt_send_t *pkt_header;
  235 
  236     DEBUG_PRINT("entering ch3_istartmsg\n");
  237 
  238     pkt_header = (MPIDI_CH3_Pkt_send_t *)pkt;
  239 
  240     /* If send queue is empty attempt to send
  241        data, queuing any unsent data. */
  242     if (MPIDI_CH3I_SMP_SendQ_empty(vc)) {       /* MT */
  243         int nb;
  244 
  245         /* MT - need some signalling to lock down our right to use the
  246            channel, thus insuring that the progress engine does also try to
  247            write */
  248 
  249         iov[0].MPL_IOV_BUF = pkt;
  250         iov[0].MPL_IOV_LEN = pkt_sz;
  251 
  252         if (pkt_header->type == MPIDI_CH3_PKT_RNDV_R3_DATA)
  253         {
  254             MPIDI_CH3I_SMP_writev_rndv_header(vc, iov, 1, &nb);
  255         }
  256         else
  257         {
  258             MPIDI_CH3I_SMP_writev(vc, iov, 1, &nb);
  259         }
  260 #ifdef CKPT
  261         MPIDI_CH3I_MRAILI_Pkt_comm_header* p = (MPIDI_CH3I_MRAILI_Pkt_comm_header*)pkt;
  262         if( p->type >= MPIDI_CH3_PKT_CM_SUSPEND && 
  263             p->type<= MPIDI_CH3_PKT_CR_REMOTE_UPDATE ) {
  264             DEBUG_PRINT("%s [%d => %d]: imm-write pkt %s(%d), ret nb=%d,pkt-size=%d\n", __func__, 
  265             MPIDI_Process.my_pg_rank, vc->pg_rank,  MPIDI_CH3_Pkt_type_to_string[p->type],
  266             p->type, nb, pkt_sz );
  267         }
  268 #endif  // CKPT
  269         if (nb != pkt_sz) 
  270         {
  271             sreq = create_request(pkt, pkt_sz, nb);
  272             if(pkt_header->type == MPIDI_CH3_PKT_RNDV_R3_DATA)
  273             { 
  274                 sreq->ch.reqtype = REQUEST_RNDV_R3_HEADER;
  275             }
  276 
  277             MPIDI_CH3I_SMP_SendQ_enqueue_head(vc, sreq);
  278             vc->smp.send_active = sreq;
  279 
  280             PRINT_DEBUG(DEBUG_SHM_verbose>1,
  281                     "send to %d delayed, request enqueued: %p, type: %d, pkt_sz: %d, ch.reqtype: %d\n",
  282                     vc->pg_rank, sreq, MPIDI_Request_get_type(sreq), pkt_sz, sreq->ch.reqtype);
  283         }
  284 #if defined(DEBUG)
  285         else
  286         {
  287             DEBUG_PRINT("data sent immediately.\n");
  288         }
  289 #endif /* defined(DEBUG) */
  290     } else {
  291         sreq = create_request(pkt, pkt_sz, 0);
  292         if(pkt_header->type == MPIDI_CH3_PKT_RNDV_R3_DATA) {
  293             sreq->ch.reqtype = REQUEST_RNDV_R3_HEADER;
  294         }
  295 
  296         MPIDI_CH3I_SMP_SendQ_enqueue(vc, sreq);
  297         PRINT_DEBUG(DEBUG_SHM_verbose>1,
  298                 "send to %d delayed, request enqueued: %p, type: %d, pkt_sz: %d, ch.reqtype: %d\n",
  299                 vc->pg_rank, sreq, MPIDI_Request_get_type(sreq), pkt_sz, sreq->ch.reqtype);
  300 #ifdef CKPT  
  301         MPIDI_CH3I_MRAILI_Pkt_comm_header* p = (MPIDI_CH3I_MRAILI_Pkt_comm_header*)pkt;
  302         if( p->type >= MPIDI_CH3_PKT_CM_SUSPEND && 
  303             p->type<= MPIDI_CH3_PKT_CR_REMOTE_UPDATE ) 
  304         {
  305             DEBUG_PRINT("%s [%d => %d]: Enqueue:  pkt %s(%d), pkt-size=%d\n", __func__, 
  306                 MPIDI_Process.my_pg_rank, vc->pg_rank,  MPIDI_CH3_Pkt_type_to_string[p->type],
  307                 p->type, pkt_sz );
  308         } 
  309 #endif   // end of CKPT
  310     }
  311 
  312 fn_exit:
  313     *sreq_ptr = sreq;
  314     MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_CH3_SMP_ISTARTMSG);
  315     return mpi_errno;
  316 
  317 #ifndef CHANNEL_MRAIL
  318 fn_fail:
  319 #endif
  320     goto fn_exit;
  321 }
  322