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