1 /* begin_generated_IBM_copyright_prolog                             */
2 /*                                                                  */
3 /* This is an automatically generated copyright prolog.             */
4 /* After initializing,  DO NOT MODIFY OR MOVE                       */
5 /*  --------------------------------------------------------------- */
6 /* Licensed Materials - Property of IBM                             */
7 /* Blue Gene/Q 5765-PER 5765-PRP                                    */
8 /*                                                                  */
9 /* (C) Copyright IBM Corp. 2011, 2012 All Rights Reserved           */
10 /* US Government Users Restricted Rights -                          */
11 /* Use, duplication, or disclosure restricted                       */
12 /* by GSA ADP Schedule Contract with IBM Corp.                      */
13 /*                                                                  */
14 /*  --------------------------------------------------------------- */
15 /*                                                                  */
16 /* end_generated_IBM_copyright_prolog                               */
17 /*  (C)Copyright IBM Corp.  2007, 2011  */
18 /**
19  * \file src/pt2pt/mpidi_recv.h
20  * \brief ADI level implemenation of MPI_Irecv()
21  */
22 
23 #ifndef __src_pt2pt_mpidi_recv_h__
24 #define __src_pt2pt_mpidi_recv_h__
25 
26 #include <mpidimpl.h>
27 #include "../mpid_recvq.h"
28 #include "mpid_datatype.h"
29 /*#ifdef MPIDI_STATISTICS
30   #include "../../include/mpidi_datatypes.h"
31 #endif*/
32 
33 
34 /**
35  * \brief ADI level implemenation of MPI_(I)Recv()
36  *
37  * \param[in]  buf            The buffer to receive into
38  * \param[in]  count          Number of expected elements in the buffer
39  * \param[in]  datatype       The datatype of each element
40  * \param[in]  rank           The sending rank
41  * \param[in]  tag            The message tag
42  * \param[in]  comm           Pointer to the communicator
43  * \param[in]  context_offset Offset from the communicator context ID
44  * \param[out] status         Update the status structure
45  * \param[out] request        Return a pointer to the new request object
46  *
47  * \returns An MPI Error code
48  */
49 static inline int
MPIDI_Recv(void * buf,int count,MPI_Datatype datatype,int rank,int tag,MPID_Comm * comm,int context_offset,unsigned is_blocking,MPI_Status * status,MPID_Request ** request)50 MPIDI_Recv(void          * buf,
51            int             count,
52            MPI_Datatype    datatype,
53            int             rank,
54            int             tag,
55            MPID_Comm     * comm,
56            int             context_offset,
57            unsigned        is_blocking,
58            MPI_Status    * status,
59            MPID_Request ** request)
60 {
61   MPID_Request * rreq;
62   int found;
63   int mpi_errno = MPI_SUCCESS;
64 
65   /* ---------------------------------------- */
66   /* NULL rank means empty request            */
67   /* ---------------------------------------- */
68   if (unlikely(rank == MPI_PROC_NULL))
69     {
70       MPIDI_RecvMsg_procnull(comm, is_blocking, status, request);
71       return MPI_SUCCESS;
72     }
73 #if (MPIDI_STATISTICS)
74   MPID_NSTAT(mpid_statp->recvs);
75 #endif
76   MPIR_Comm_add_ref(comm);
77 
78   /* ---------------------------------------- */
79   /* find our request in the unexpected queue */
80   /* or allocate one in the posted queue      */
81   /* ---------------------------------------- */
82   MPID_Request *newreq = MPIDI_Request_create2();
83   MPIU_THREAD_CS_ENTER(MSGQUEUE,0);
84 #ifndef OUT_OF_ORDER_HANDLING
85   rreq = MPIDI_Recvq_FDU_or_AEP(newreq, rank,
86                                 tag,
87                                 comm->recvcontext_id + context_offset,
88                                 &found);
89 #ifdef MPIDI_TRACE
90 {
91   size_t ll;
92   ll = count * MPID_Datatype_get_basic_size(datatype);
93   SET_REC_PR(rreq,buf,count,ll,datatype,pami_source,rank,tag,comm,is_blocking);
94 }
95 #endif
96 #else
97   int pami_source;
98   if(rank != MPI_ANY_SOURCE) {
99     pami_source = MPID_VCR_GET_LPID(comm->vcr, rank);
100   } else {
101     pami_source = MPI_ANY_SOURCE;
102   }
103   if ((pami_source != MPI_ANY_SOURCE) && (MPIDI_In_cntr[pami_source].n_OutOfOrderMsgs>0))  {
104         /* returns unlock    */
105         MPIDI_Recvq_process_out_of_order_msgs(pami_source, MPIDI_Context[0]);
106   }
107   rreq = MPIDI_Recvq_FDU_or_AEP(newreq, rank,
108                                 pami_source,
109                                 tag,
110                                 comm->recvcontext_id + context_offset,
111                                 &found);
112 #endif
113 
114   /* ----------------------------------------------------------------- */
115   /* populate request with our data                                    */
116   /* We can do this because this is not a multithreaded implementation */
117   /* ----------------------------------------------------------------- */
118 
119   rreq->comm              = comm;
120   rreq->mpid.userbuf      = buf;
121   rreq->mpid.userbufcount = count;
122   rreq->mpid.datatype     = datatype;
123   /* We don't need this because MPIDI_CA_COMPLETE is the initialized default */
124   /* MPIDI_Request_setCA(rreq, MPIDI_CA_COMPLETE); */
125 
126   if (unlikely(found))
127     {
128       MPIDI_RecvMsg_Unexp(rreq, buf, count, datatype);
129       mpi_errno = rreq->status.MPI_ERROR;
130       MPIU_THREAD_CS_EXIT(MSGQUEUE,0);
131       MPID_Request_discard(newreq);
132     }
133   else
134     {
135       /* ----------------------------------------------------------- */
136       /* request not found in unexpected queue, allocated and posted */
137       /* ----------------------------------------------------------- */
138       if (HANDLE_GET_KIND(datatype) != HANDLE_KIND_BUILTIN)
139         {
140           MPID_Datatype_get_ptr(datatype, rreq->mpid.datatype_ptr);
141           MPID_Datatype_add_ref(rreq->mpid.datatype_ptr);
142         }
143       MPIU_THREAD_CS_EXIT(MSGQUEUE,0);
144     }
145 
146   /* mutex has been dropped... */
147   *request = rreq;
148   if (status != MPI_STATUS_IGNORE)
149     *status = rreq->status;
150   #ifdef MPIDI_STATISTICS
151     if (!(MPID_cc_is_complete(&rreq->cc))) {
152         MPID_NSTAT(mpid_statp->recvWaitsComplete);
153     }
154   #endif
155 
156   return mpi_errno;
157 }
158 
159 #endif
160