OpenMPI  0.1.1
pml_cm_recvreq.h
1 /*
2  * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
3  * University Research and Technology
4  * Corporation. All rights reserved.
5  * Copyright (c) 2004-2007 The University of Tennessee and The University
6  * of Tennessee Research Foundation. All rights
7  * reserved.
8  * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
9  * University of Stuttgart. All rights reserved.
10  * Copyright (c) 2004-2006 The Regents of the University of California.
11  * All rights reserved.
12  * Copyright (c) 2012 Sandia National Laboratories. All rights reserved.
13  * $COPYRIGHT$
14  *
15  * Additional copyrights may follow
16  *
17  * $HEADER$
18  */
19 
20 #ifndef PML_CM_RECVREQ_H
21 #define PML_CM_RECVREQ_H
22 
23 #include "pml_cm_request.h"
25 #include "ompi/mca/mtl/mtl.h"
26 
28  mca_pml_cm_request_t req_base;
29  mca_mtl_request_t req_mtl; /**< the mtl specific memory. This field should be the last in the struct */
30 };
33 
35  mca_pml_cm_request_t req_base;
36  void *req_addr; /**< pointer to application buffer */
37  size_t req_count; /**< count of user datatype elements */
38  int32_t req_peer; /**< peer process - rank w/in this communicator */
39  int32_t req_tag; /**< user defined tag */
40  void *req_buff; /**< pointer to send buffer - may not be application buffer */
41  size_t req_bytes_packed; /**< packed size of a message given the datatype and count */
42  bool req_blocking;
43  mca_mtl_request_t req_mtl; /**< the mtl specific memory. This field should be the last in the struct */
44 };
46 
48 
49 /**
50  * Allocate a recv request from the modules free list.
51  *
52  * @param rc (OUT) OMPI_SUCCESS or error status on failure.
53  * @return Receive request.
54  */
55 #define MCA_PML_CM_THIN_RECV_REQUEST_ALLOC(recvreq, rc) \
56  do { \
57  ompi_free_list_item_t*item; \
58  OMPI_FREE_LIST_GET(&mca_pml_base_recv_requests, item, rc); \
59  recvreq = (mca_pml_cm_thin_recv_request_t*) item; \
60  recvreq->req_base.req_pml_type = MCA_PML_CM_REQUEST_RECV_THIN; \
61  recvreq->req_mtl.ompi_req = (ompi_request_t*) recvreq; \
62  recvreq->req_mtl.completion_callback = mca_pml_cm_recv_request_completion; \
63  } while (0)
64 
65 #define MCA_PML_CM_HVY_RECV_REQUEST_ALLOC(recvreq, rc) \
66 do { \
67  ompi_free_list_item_t*item; \
68  OMPI_FREE_LIST_GET(&mca_pml_base_recv_requests, item, rc); \
69  recvreq = (mca_pml_cm_hvy_recv_request_t*) item; \
70  recvreq->req_base.req_pml_type = MCA_PML_CM_REQUEST_RECV_HEAVY; \
71  recvreq->req_mtl.ompi_req = (ompi_request_t*) recvreq; \
72  recvreq->req_mtl.completion_callback = mca_pml_cm_recv_request_completion; \
73  } while (0)
74 
75 
76 /**
77  * Initialize a receive request with call parameters.
78  *
79  * @param request (IN) Receive request.
80  * @param addr (IN) User buffer.
81  * @param count (IN) Number of elements of indicated datatype.
82  * @param datatype (IN) User defined datatype.
83  * @param src (IN) Source rank w/in the communicator.
84  * @param comm (IN) Communicator.
85  * @param persistent (IN) Is this a ersistent request.
86  */
87 #define MCA_PML_CM_THIN_RECV_REQUEST_INIT( request, \
88  ompi_proc, \
89  comm, \
90  src, \
91  datatype, \
92  addr, \
93  count ) \
94 do { \
95  OMPI_REQUEST_INIT(&(request)->req_base.req_ompi, false); \
96  (request)->req_base.req_ompi.req_mpi_object.comm = comm; \
97  (request)->req_base.req_pml_complete = false; \
98  (request)->req_base.req_free_called = false; \
99  request->req_base.req_comm = comm; \
100  request->req_base.req_datatype = datatype; \
101  OBJ_RETAIN(comm); \
102  OBJ_RETAIN(datatype); \
103  \
104  if( MPI_ANY_SOURCE == src ) { \
105  ompi_proc = ompi_proc_local_proc; \
106  } else { \
107  ompi_proc = ompi_comm_peer_lookup( comm, src ); \
108  } \
109  opal_convertor_copy_and_prepare_for_recv( \
110  ompi_proc->proc_convertor, \
111  &(datatype->super), \
112  count, \
113  addr, \
114  0, \
115  &(request)->req_base.req_convertor ); \
116 } while(0)
117 
118 #define MCA_PML_CM_HVY_RECV_REQUEST_INIT( request, \
119  ompi_proc, \
120  comm, \
121  tag, \
122  src, \
123  datatype, \
124  addr, \
125  count, \
126  persistent) \
127 do { \
128  OMPI_REQUEST_INIT(&(request)->req_base.req_ompi, persistent); \
129  (request)->req_base.req_ompi.req_mpi_object.comm = comm; \
130  (request)->req_base.req_pml_complete = OPAL_INT_TO_BOOL(persistent); \
131  (request)->req_base.req_free_called = false; \
132  request->req_base.req_comm = comm; \
133  request->req_base.req_datatype = datatype; \
134  request->req_tag = tag; \
135  request->req_peer = src; \
136  request->req_addr = addr; \
137  request->req_count = count; \
138  OBJ_RETAIN(comm); \
139  OBJ_RETAIN(datatype); \
140  \
141  if( MPI_ANY_SOURCE == src ) { \
142  ompi_proc = ompi_proc_local_proc; \
143  } else { \
144  ompi_proc = ompi_comm_peer_lookup( comm, src ); \
145  } \
146  opal_convertor_copy_and_prepare_for_recv( \
147  ompi_proc->proc_convertor, \
148  &(datatype->super), \
149  count, \
150  addr, \
151  0, \
152  &(request)->req_base.req_convertor ); \
153  } while(0)
154 
155 
156 /**
157  * Start an initialized request.
158  *
159  * @param request Receive request.
160  * @return OMPI_SUCESS or error status on failure.
161  */
162 #define MCA_PML_CM_THIN_RECV_REQUEST_START(request, comm, tag, src, ret) \
163 do { \
164  /* init/re-init the request */ \
165  request->req_base.req_pml_complete = false; \
166  request->req_base.req_ompi.req_complete = false; \
167  request->req_base.req_ompi.req_state = OMPI_REQUEST_ACTIVE; \
168  \
169  /* always set the req_status.MPI_TAG to ANY_TAG before starting the \
170  * request. This field is used if cancelled to find out if the request \
171  * has been matched or not. \
172  */ \
173  request->req_base.req_ompi.req_status.MPI_TAG = OMPI_ANY_TAG; \
174  request->req_base.req_ompi.req_status.MPI_ERROR = OMPI_SUCCESS; \
175  request->req_base.req_ompi.req_status._cancelled = 0; \
176  ret = OMPI_MTL_CALL(irecv(ompi_mtl, \
177  comm, \
178  src, \
179  tag, \
180  &recvreq->req_base.req_convertor, \
181  &recvreq->req_mtl)); \
182 } while (0)
183 
184 #define MCA_PML_CM_THIN_RECV_REQUEST_MATCHED_START(request, message, ret) \
185 do { \
186  /* init/re-init the request */ \
187  request->req_base.req_pml_complete = false; \
188  request->req_base.req_ompi.req_complete = false; \
189  request->req_base.req_ompi.req_state = OMPI_REQUEST_ACTIVE; \
190  \
191  /* always set the req_status.MPI_TAG to ANY_TAG before starting the \
192  * request. This field is used if cancelled to find out if the request \
193  * has been matched or not. \
194  */ \
195  request->req_base.req_ompi.req_status.MPI_TAG = OMPI_ANY_TAG; \
196  request->req_base.req_ompi.req_status.MPI_ERROR = OMPI_SUCCESS; \
197  request->req_base.req_ompi.req_status._cancelled = 0; \
198  ret = OMPI_MTL_CALL(imrecv(ompi_mtl, \
199  &recvreq->req_base.req_convertor, \
200  message, \
201  &recvreq->req_mtl)); \
202 } while (0)
203 
204 
205 #define MCA_PML_CM_HVY_RECV_REQUEST_START(request, ret) \
206 do { \
207 /* opal_output(0, "posting hvy request %d\n", request); */ \
208  /* init/re-init the request */ \
209  request->req_base.req_pml_complete = false; \
210  request->req_base.req_ompi.req_complete = false; \
211  request->req_base.req_ompi.req_state = OMPI_REQUEST_ACTIVE; \
212  \
213  /* always set the req_status.MPI_TAG to ANY_TAG before starting the \
214  * request. This field is used if cancelled to find out if the request \
215  * has been matched or not. \
216  */ \
217  request->req_base.req_ompi.req_status.MPI_TAG = OMPI_ANY_TAG; \
218  request->req_base.req_ompi.req_status.MPI_ERROR = OMPI_SUCCESS; \
219  request->req_base.req_ompi.req_status._cancelled = 0; \
220  ret = OMPI_MTL_CALL(irecv(ompi_mtl, \
221  request->req_base.req_comm, \
222  request->req_peer, \
223  request->req_tag, \
224  &recvreq->req_base.req_convertor, \
225  &recvreq->req_mtl)); \
226 } while (0)
227 
228 
229 /**
230  * Mark the request as completed at MPI level for internal purposes.
231  *
232  * @param recvreq (IN) Receive request.
233  */
234 #define MCA_PML_CM_THIN_RECV_REQUEST_MPI_COMPLETE( recvreq ) \
235 do { \
236  ompi_request_complete( &(recvreq->req_base.req_ompi), true ); \
237  } while (0)
238 
239 
240 /**
241  * Return a recv request to the modules free list.
242  *
243  * @param recvreq (IN) Receive request.
244  */
245 #define MCA_PML_CM_THIN_RECV_REQUEST_PML_COMPLETE(recvreq) \
246 do { \
247  assert( false == recvreq->req_base.req_pml_complete ); \
248  \
249  OPAL_THREAD_LOCK(&ompi_request_lock); \
250  \
251  if( true == recvreq->req_base.req_free_called ) { \
252  MCA_PML_CM_THIN_RECV_REQUEST_RETURN( recvreq ); \
253  } else { \
254  recvreq->req_base.req_pml_complete = true; \
255  ompi_request_complete( &(recvreq->req_base.req_ompi), true ); \
256  } \
257  OPAL_THREAD_UNLOCK(&ompi_request_lock); \
258  } while(0)
259 
260 
261 
262 
263 /**
264  * Return a recv request to the modules free list.
265  *
266  * @param recvreq (IN) Receive request.
267  */
268 #define MCA_PML_CM_HVY_RECV_REQUEST_PML_COMPLETE(recvreq) \
269 do { \
270  assert( false == recvreq->req_base.req_pml_complete ); \
271  \
272  OPAL_THREAD_LOCK(&ompi_request_lock); \
273  \
274  if( true == recvreq->req_base.req_free_called ) { \
275  MCA_PML_CM_HVY_RECV_REQUEST_RETURN( recvreq ); \
276  } else { \
277  /* initialize request status */ \
278  if(recvreq->req_base.req_ompi.req_persistent) { \
279  /* rewind convertor */ \
280  size_t offset = 0; \
281  opal_convertor_set_position(&recvreq->req_base.req_convertor, &offset); \
282  } \
283  recvreq->req_base.req_pml_complete = true; \
284  ompi_request_complete( &(recvreq->req_base.req_ompi), true ); \
285  } \
286  OPAL_THREAD_UNLOCK(&ompi_request_lock); \
287  } while(0)
288 
289 
290 /**
291  * Free the PML receive request
292  */
293 #define MCA_PML_CM_HVY_RECV_REQUEST_RETURN(recvreq) \
294 { \
295  OBJ_RELEASE((recvreq)->req_base.req_comm); \
296  OBJ_RELEASE((recvreq)->req_base.req_datatype); \
297  OMPI_REQUEST_FINI(&(recvreq)->req_base.req_ompi); \
298  opal_convertor_cleanup( &((recvreq)->req_base.req_convertor) ); \
299  OMPI_FREE_LIST_RETURN( &mca_pml_base_recv_requests, \
300  (ompi_free_list_item_t*)(recvreq)); \
301 }
302 
303 /**
304  * Free the PML receive request
305  */
306 #define MCA_PML_CM_THIN_RECV_REQUEST_RETURN(recvreq) \
307 { \
308  OBJ_RELEASE((recvreq)->req_base.req_comm); \
309  OBJ_RELEASE((recvreq)->req_base.req_datatype); \
310  OMPI_REQUEST_FINI(&(recvreq)->req_base.req_ompi); \
311  opal_convertor_cleanup( &((recvreq)->req_base.req_convertor) ); \
312  OMPI_FREE_LIST_RETURN( &mca_pml_base_recv_requests, \
313  (ompi_free_list_item_t*)(recvreq)); \
314 }
315 
316 extern void mca_pml_cm_recv_request_completion(struct mca_mtl_request_t *mtl_request);
317 
318 #endif
319 
320 
mca_mtl_request_t req_mtl
the mtl specific memory.
Definition: pml_cm_recvreq.h:43
void * req_buff
pointer to send buffer - may not be application buffer
Definition: pml_cm_recvreq.h:40
size_t req_count
count of user datatype elements
Definition: pml_cm_recvreq.h:37
Definition: mtl.h:51
Definition: pml_cm_recvreq.h:27
Definition: pml_cm_recvreq.h:34
int32_t req_tag
user defined tag
Definition: pml_cm_recvreq.h:39
int32_t req_peer
peer process - rank w/in this communicator
Definition: pml_cm_recvreq.h:38
Matching Transport Layer.
size_t req_bytes_packed
packed size of a message given the datatype and count
Definition: pml_cm_recvreq.h:41
mca_mtl_request_t req_mtl
the mtl specific memory.
Definition: pml_cm_recvreq.h:29
Base type for PML CM P2P requests.
Definition: pml_cm_request.h:41
#define OBJ_CLASS_DECLARATION(NAME)
Declaration for class descriptor.
Definition: opal_object.h:236
void * req_addr
pointer to application buffer
Definition: pml_cm_recvreq.h:36