newmad_poll.c 18.4 KB
Newer Older
1
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
2
3
4
/*
 *  (C) 2006 by Argonne National Laboratory.
 *      See COPYRIGHT in top-level directory.
5
6
7
8
 *
 * Copyright  2006-2011 Guillaume Mercier, Institut Polytechnique de
 * Bordeaux. All rights reserved. Permission is hereby granted to use,
 * reproduce, prepare derivative works, and to redistribute to others.
9
10
11
 */

#include "newmad_impl.h"
12
#include "newmad_extended_interface.h"
13
#include "my_papi_defs.h"
14
#include "../mx/uthash.h"
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

typedef struct mpid_nem_nmad_hash_struct {
    MPID_Request    *mpid_req_ptr;
    nm_sr_request_t *nmad_req_ptr;
    UT_hash_handle  hh;
}mpid_nem_nmad_hash_t;

static mpid_nem_nmad_hash_t *mpid_nem_nmad_asreqs = NULL;
#define MPID_MEM_NMAD_ADD_REQ_IN_HASH(_mpi_req,_nmad_req) do{		            \
	mpid_nem_nmad_hash_t *s;	       				            \
	s = MPIU_Malloc(sizeof(mpid_nem_nmad_hash_t));			            \
	s->mpid_req_ptr = (_mpi_req);					            \
	s->nmad_req_ptr = (_nmad_req);					            \
	HASH_ADD(hh, mpid_nem_nmad_asreqs, mpid_req_ptr, sizeof(MPID_Request*), s); \
    }while(0)
#define MPID_NEM_NMAD_GET_REQ_FROM_HASH(_mpi_req_ptr,_nmad_req) do{		                                    \
	mpid_nem_nmad_hash_t *s;						                                    \
	HASH_FIND(hh, mpid_nem_nmad_asreqs, &(_mpi_req_ptr), sizeof(MPID_Request*), s);                             \
33
	if(s){HASH_DELETE(hh, mpid_nem_nmad_asreqs, s); (_nmad_req) = s->nmad_req_ptr; MPIU_Free(s);} else {(_nmad_req) = NULL;} \
34
35
    }while(0)

36
static int  MPID_nem_newmad_handle_rreq(MPID_Request *req, nm_tag_t match_info, size_t size);
37
static void MPID_nem_newmad_handle_sreq(MPID_Request *req);
38
39
40
41
42

#undef FUNCNAME
#define FUNCNAME MPID_nem_newmad_get_adi_msg
#undef FCNAME
#define FCNAME MPIDI_QUOTE(FUNCNAME)
43
44
void 
MPID_nem_newmad_get_adi_msg(nm_sr_event_t event, const nm_sr_event_info_t*info)
45
{
46
    nm_tag_t          match_info = info->recv_unexpected.tag;
47
    MPIR_Context_id_t ctxt;
48
49
50
51
52

#ifdef DEBUG
    fprintf(stdout,"===> Getting ADI MSG match is %lx \n",match_info);
#endif

53
54
55
    NEM_NMAD_MATCH_GET_CTXT(match_info, ctxt);
    if(ctxt == NEM_NMAD_INTRA_CTXT)
    {
56
57
58
59
        MPID_nem_newmad_internal_req_t *rreq;
	mpid_nem_newmad_p_gate_t        from   = info->recv_unexpected.p_gate;
	int                             length = info->recv_unexpected.len; 
	void                           *data;
60

61
62
63
64
        MPID_nem_newmad_internal_req_dequeue(&rreq);
        rreq->kind = MPID_REQUEST_RECV;   
        rreq->vc = nm_gate_ref_get(from);
       
65
        if(length <= sizeof(MPIDI_CH3_Pkt_t))
66
67
	{
	  data = (char*)&(rreq->pending_pkt);
68
	}
69
70
71
72
73
74
75
       else
       {
	  rreq->tmpbuf = MPIU_Malloc(length);
	  MPIU_Assert(rreq->tmpbuf);
	  rreq->tmpbuf_sz = length;                   
	  data = (char*)(rreq->tmpbuf);
       }
76
	
77
78
	nm_sr_irecv_with_ref_tagged(mpid_nem_newmad_session, from, match_info, 
				    NEM_NMAD_MATCH_FULL_MASK, data,length, &(rreq->newmad_req),(void *)rreq);	
79
80
81
82
83
84
85
86
87
88
89
90
91
92
    }
    return;
}

#undef FUNCNAME
#define FUNCNAME MPID_nem_newmad_directRecv
#undef FCNAME
#define FCNAME MPIDI_QUOTE(FUNCNAME)
int MPID_nem_newmad_directRecv(MPIDI_VC_t *vc, MPID_Request *rreq)
{
    int mpi_errno = MPI_SUCCESS;    
    MPIDI_STATE_DECL(MPID_STATE_MPID_NEM_NEWMAD_DIRECTRECV);    
    MPIDI_FUNC_ENTER(MPID_STATE_MPID_NEM_NEWMAD_DIRECTRECV);    
    
93
    if (!vc->ch.is_local)
94
95
    {
	nm_tag_t          match_info = 0; 
96
	nm_tag_t          match_mask = NEM_NMAD_MATCH_FULL_MASK; 	    
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
	MPIR_Rank_t       source     = rreq->dev.match.parts.rank;
	MPIR_Context_id_t context    = rreq->dev.match.parts.context_id;
	Nmad_Nem_tag_t    tag        = rreq->dev.match.parts.tag;
	int               ret;
	MPIDI_msg_sz_t    data_sz;
	int               dt_contig;
	MPI_Aint          dt_true_lb;
	MPID_Datatype    *dt_ptr;
	
	NEM_NMAD_DIRECT_MATCH(match_info,0,source,context);
	if (tag != MPI_ANY_TAG)
	{
	    NEM_NMAD_SET_TAG(match_info,tag);
	}
	else
	{
113
114
	    NEM_NMAD_SET_ANYTAG(match_info);
	    NEM_NMAD_SET_ANYTAG(match_mask);
115
	}
116

117
118
119
#ifdef DEBUG
	fprintf(stdout,"========> Posting Recv req  %p (match is %lx) \n",rreq,match_info);
#endif
120
121
	MPIDI_Datatype_get_info(rreq->dev.user_count,rreq->dev.datatype, dt_contig, data_sz, dt_ptr,dt_true_lb);
	rreq->dev.OnDataAvail = NULL;
122

123
124
	if (dt_contig)
	{
125
126
127
128
	    ret = nm_sr_irecv_with_ref_tagged(mpid_nem_newmad_session,VC_FIELD(vc,p_gate),match_info,match_mask,
					      (char*)(rreq->dev.user_buf) + dt_true_lb,data_sz,
					      &(REQ_FIELD(rreq,newmad_req)),(void*)rreq);
	    REQ_FIELD(rreq,iov) = NULL;
129
      	    REQ_FIELD(rreq,iov_to_delete) = 0;
130
131
132
	}
	else
	{
133
134
135
	    int           num_seg        = 0;
	    struct iovec *newmad_iov     = (struct iovec *)MPIU_Malloc(NMAD_IOV_MAX_DEPTH*sizeof(struct iovec));	    
	    struct iovec *newmad_iov_ptr = &(newmad_iov[0]); 
136
	    MPID_nem_newmad_process_rdtype(&rreq,dt_ptr,data_sz,&newmad_iov_ptr,&num_seg);
137
138
139
140
141
142
143
144
145
146
147
148
	    MPIU_Assert(num_seg <= NMAD_IOV_MAX_DEPTH);
#ifdef DEBUG
	    {
		int index;
		for(index = 0; index < num_seg ; index++)
		    {
			fprintf(stdout,"======================\n");
			fprintf(stdout,"RECV nmad_iov[%i]: [base %p][len %i]\n",index,
				newmad_iov[index].iov_base,newmad_iov[index].iov_len);
		    }
	    }
#endif
149
150
	    ret = nm_sr_irecv_iov_with_ref_tagged(mpid_nem_newmad_session,VC_FIELD(vc,p_gate),match_info,match_mask,
						  newmad_iov,num_seg,&(REQ_FIELD(rreq,newmad_req)),(void*)rreq);	
151
	    REQ_FIELD(rreq,iov) = newmad_iov;
152
	    REQ_FIELD(rreq,iov_to_delete) = 1;
153
154
	}
    }
155
156
157
158
159
160
    else
    {
	/* Fixme : this might not work in the case of multiple netmods */ 
	memset((&(REQ_FIELD(rreq,newmad_req))),0,sizeof(nm_sr_request_t));
    }

161
162
163
 fn_exit:
    MPIDI_FUNC_EXIT(MPID_STATE_MPID_NEM_NEWMAD_DIRECTRECV);
    return mpi_errno;
164
 fn_fail:  ATTRIBUTE((unused))
165
166
167
    goto fn_exit;
}

168

169
#undef FUNCNAME
170
#define FUNCNAME MPID_nem_newmad_poll
171
172
#undef FCNAME
#define FCNAME MPIDI_QUOTE(FUNCNAME)
173
174
int 
MPID_nem_newmad_poll(int in_blocking_poll)
175
{
176
177
178
179
   nm_sr_request_t *p_request = NULL;
   nm_tag_t         match_info = 0;
   int mpi_errno = MPI_SUCCESS;   
   
180
   nm_sr_send_success(mpid_nem_newmad_session, &p_request);
181
   if (p_request != NULL)
182
   {
183
184
      MPID_nem_newmad_unified_req_t *ref;
      MPID_Request                  *req;
185
      MPID_Request_kind_t            kind;      
186
      MPIR_Context_id_t              ctxt;
187
      
188
      nm_sr_get_stag(mpid_nem_newmad_session,p_request, &match_info);
189
190
      NEM_NMAD_MATCH_GET_CTXT(match_info, ctxt);
            
191
      nm_sr_get_ref(mpid_nem_newmad_session,p_request,(void *)&ref);
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
      req = &(ref->mpi_req);
      MPIU_Assert(req != NULL);
      kind = req->kind;
	
      if(ctxt == NEM_NMAD_INTRA_CTXT)
      {
	 if ((kind == MPID_REQUEST_SEND) || (kind == MPID_PREQUEST_SEND))
	 {
	    MPID_nem_newmad_handle_sreq(req);	    
	 }
      }
      else
      {
	 if ((kind == MPID_REQUEST_SEND) || (kind == MPID_PREQUEST_SEND))
	 {
	    MPIU_Assert(MPIDI_Request_get_type(req) != MPIDI_REQUEST_TYPE_GET_RESP);                  
	    MPID_nem_newmad_handle_sreq(req);	    
	 }
      }   
211
   }
212
   
213
   nm_sr_recv_success(mpid_nem_newmad_session, &p_request);
214
   if (p_request != NULL)
215
   {
216
217
      MPID_nem_newmad_unified_req_t *ref;
      MPID_Request                  *req;
218
219
220
221
      MPID_Request_kind_t            kind;      
      MPIR_Context_id_t              ctxt;
      size_t                         size;
            
222
      nm_sr_get_ref(mpid_nem_newmad_session,p_request,(void *)&ref);
223
224
225
      req = &(ref->mpi_req);
      MPIU_Assert(req != NULL);
      kind = req->kind;
226
227
      nm_sr_get_size(mpid_nem_newmad_session, p_request, &size);
      nm_sr_get_rtag(mpid_nem_newmad_session,p_request, &match_info);
228
229
230
      NEM_NMAD_MATCH_GET_CTXT(match_info, ctxt);
	
      if(ctxt == NEM_NMAD_INTRA_CTXT)
231
	  {
232
233
234
	 MPID_nem_newmad_internal_req_t *adi_req = &(ref->nem_newmad_req);
	 if (kind == MPID_REQUEST_RECV)
	 {
235
	    if (size <= sizeof(MPIDI_CH3_Pkt_t))
236
237
238
239
240
241
242
243
	    {
	       MPID_nem_handle_pkt(adi_req->vc,(char *)&(adi_req->pending_pkt),(MPIDI_msg_sz_t)(size));
	    }
	    else
	    {
	       MPID_nem_handle_pkt(adi_req->vc,(char *)(adi_req->tmpbuf),(MPIDI_msg_sz_t)(adi_req->tmpbuf_sz));
	       MPIU_Free(adi_req->tmpbuf);
	    }
244
	    /* nm_core_disable_progression(mpid_nem_newmad_session->p_core); */
245
	    MPID_nem_newmad_internal_req_enqueue(adi_req);
246
	    /* nm_core_enable_progression(mpid_nem_newmad_session->p_core); */
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
	 }
	 else
	 {
	    MPIU_Assert(0);
	 }	 
      }
      else
      {
	 if ((kind == MPID_REQUEST_RECV) || (kind == MPID_PREQUEST_RECV))
	 {
	    int found = FALSE;
	    nm_sr_request_t *nmad_request = NULL;	       
	    MPIU_Assert(MPIDI_Request_get_type(req) != MPIDI_REQUEST_TYPE_GET_RESP);
	    MPIU_THREAD_CS_ENTER(MSGQUEUE,req);
	    MPID_NEM_NMAD_GET_REQ_FROM_HASH(req,nmad_request);
	    if(nmad_request != NULL)
	    {
264
265
	       MPIU_Assert(req->dev.match.parts.rank == MPI_ANY_SOURCE);
	       MPIU_Free(nmad_request);
266
	    }
267
268
269
270
	    found = MPIDI_CH3U_Recvq_DP(req);
	    if(found){
		MPID_nem_newmad_handle_rreq(req,match_info,size);
	    }
271
272
273
274
	    MPIU_THREAD_CS_EXIT(MSGQUEUE,req);
	 }
	 else
	 {
275
276
	    fprintf(stdout, ">>>>>>>>>>>>> ERROR: Wrong req type : %i (%p)\n",(int)kind,req);
	    MPIU_Assert(0);
277
278
	 }
      }   
279
   }
280
281
282

 fn_exit:
   return mpi_errno;
283
 fn_fail:  ATTRIBUTE((unused))
284
285
286
287
288
289
290
291
   goto fn_exit;   
}

#undef FUNCNAME
#define FUNCNAME MPID_nem_newmad_handle_sreq
#undef FCNAME
#define FCNAME MPIDI_QUOTE(FUNCNAME)
void
292
MPID_nem_newmad_handle_sreq(MPID_Request *req)
293
294
{
    int (*reqFn)(MPIDI_VC_t *, MPID_Request *, int *);
295
#ifdef DEBUG
296
    fprintf(stdout,"========> Completing Send req  %p \n",req);
297
#endif
298
    (VC_FIELD(req->ch.vc,pending_sends)) -= 1;
299
    if (((req->dev.datatype_ptr != NULL) && (req->dev.tmpbuf != NULL))
300
        || (REQ_FIELD(req,deltmpbuf) == TMP_DEL_VALUE))
301
302
     {
	
303
	MPIU_Free(req->dev.tmpbuf);
304
	REQ_FIELD(req,deltmpbuf) = 0;
305
     }
306
      
307
308
309
310
311
312
313
314
315
    reqFn = req->dev.OnDataAvail;
    if (!reqFn){
	MPIDI_CH3U_Request_complete(req);
	MPIU_DBG_MSG(CH3_CHANNEL, VERBOSE, ".... complete");
    }
    else{
	MPIDI_VC_t *vc = req->ch.vc;
	int complete   = 0;
	reqFn(vc, req, &complete);
316
317
318
	if(!complete)
        {   
	   MPIU_Assert(complete == TRUE);
319
320
321
322
	}
    }
}

323
324
325
326
327
#undef FUNCNAME
#define FUNCNAME MPID_nem_new_handle_rreq
#undef FCNAME
#define FCNAME MPIDI_QUOTE(FUNCNAME)
static int
328
MPID_nem_newmad_handle_rreq(MPID_Request *req, nm_tag_t match_info, size_t size)
329
330
331
332
333
334
335
336
337
338
{
    int            mpi_errno = MPI_SUCCESS;
    int            complete = FALSE;
    int            dt_contig;
    MPI_Aint       dt_true_lb;
    MPIDI_msg_sz_t userbuf_sz;
    MPID_Datatype *dt_ptr;
    MPIDI_msg_sz_t data_sz;
    MPIDI_VC_t    *vc = NULL;

339
340
341
#ifdef DEBUG
   fprintf(stdout,"========> Completing Recv req  %p (match is %lx) \n",req,match_info);
#endif
342

343
    NEM_NMAD_MATCH_GET_RANK(match_info,req->status.MPI_SOURCE);
344
    NEM_NMAD_MATCH_GET_TAG(match_info,req->status.MPI_TAG);
Pavan Balaji's avatar
Pavan Balaji committed
345
    MPIR_STATUS_SET_COUNT(req->status, size);
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
    req->dev.recv_data_sz = size;

    MPIDI_Datatype_get_info(req->dev.user_count, req->dev.datatype, dt_contig, userbuf_sz, dt_ptr, dt_true_lb);

    if (size <=  userbuf_sz) {
	data_sz = req->dev.recv_data_sz;
    }
    else
    {
	MPIU_DBG_MSG_FMT(CH3_OTHER,VERBOSE,(MPIU_DBG_FDEST,
					    "receive buffer too small; message truncated, msg_sz="
					    MPIDI_MSG_SZ_FMT ", userbuf_sz="
					    MPIDI_MSG_SZ_FMT,
					    req->dev.recv_data_sz, userbuf_sz));
	req->status.MPI_ERROR = MPIR_Err_create_code(MPI_SUCCESS,
						     MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_TRUNCATE,
						     "**truncate", "**truncate %d %d %d %d",
						     req->status.MPI_SOURCE, req->status.MPI_TAG,
						     req->dev.recv_data_sz, userbuf_sz );
Pavan Balaji's avatar
Pavan Balaji committed
365
	MPIR_STATUS_SET_COUNT(req->status, userbuf_sz);
366
367
368
369
370
371
372
373
374
375
	data_sz = userbuf_sz;
    }
    
    if ((!dt_contig)&&(req->dev.tmpbuf != NULL))
    {
	MPIDI_msg_sz_t last;
	last = req->dev.recv_data_sz;
	MPID_Segment_unpack( req->dev.segment_ptr, 0, &last, req->dev.tmpbuf);
	MPIU_Free(req->dev.tmpbuf);
	if (last != data_sz) {
376
	    MPIR_STATUS_SET_COUNT(req->status, last);
377
378
379
380
381
	    if (req->dev.recv_data_sz <= userbuf_sz) {
		MPIU_ERR_SETSIMPLE(req->status.MPI_ERROR,MPI_ERR_TYPE,"**dtypemismatch");
	    }
	}
    }
382

383
    if (REQ_FIELD(req,iov_to_delete) == 1)
384
      MPIU_Free(REQ_FIELD(req,iov));	
385

386
    MPIDI_Comm_get_vc_set_active(req->comm, req->status.MPI_SOURCE, &vc);
387
388
    MPIDI_CH3U_Handle_recv_req(vc, req, &complete);
    MPIU_Assert(complete == TRUE);
389
390
391
392
393
394


#ifdef DEBUG
   fprintf(stdout,"========> Completing Recv req  %p done \n",req);
#endif

395
396
397
398
399
400
401
402
 fn_exit:
    return mpi_errno;
 fn_fail: ATTRIBUTE((unused))
	goto fn_exit;
}



403
404
405
406
#undef FUNCNAME
#define FUNCNAME MPID_nem_newmad_anysource_posted
#undef FCNAME
#define FCNAME MPIDI_QUOTE(FUNCNAME)
407
void MPID_nem_newmad_anysource_posted(MPID_Request *rreq)
408
409
410
{
    /* This function is called whenever an anyource request has been
       posted to the posted receive queue.  */
411
412
    MPIR_Context_id_t context;
    Nmad_Nem_tag_t    tag;
413
414
415
416
    nm_tag_t          match_info  = 0;
    nm_tag_t          match_mask  = NEM_NMAD_MATCH_FULL_MASK; 
    nm_sr_request_t  *newmad_req  = MPIU_Malloc(sizeof(nm_sr_request_t));
    int               num_seg     = 1;
417
418
419
420
421
    int               ret;
    MPIDI_msg_sz_t    data_sz;
    int               dt_contig;
    MPI_Aint          dt_true_lb;
    MPID_Datatype    *dt_ptr;               
422
    struct iovec     *newmad_iov  = (struct iovec *)MPIU_Malloc(NMAD_IOV_MAX_DEPTH*sizeof(struct iovec));
423
424
425
426
427
428
429
430
431
432
  
    tag     = rreq->dev.match.parts.tag;
    context = rreq->dev.match.parts.context_id;                       
    NEM_NMAD_DIRECT_MATCH(match_info,0,0,context);
    if (tag != MPI_ANY_TAG)
    {
	NEM_NMAD_SET_TAG(match_info,tag);	
    }
    else
    {
433
434
	NEM_NMAD_SET_ANYTAG(match_info);
	NEM_NMAD_SET_ANYTAG(match_mask); 
435
    }
436
437
438
439
440
441
442
    NEM_NMAD_SET_ANYSRC(match_info);
    NEM_NMAD_SET_ANYSRC(match_mask);

#ifdef DEBUG
    fprintf(stdout,"========> Any Source : Posting Recv req  %p (nmad req is %p) (match is %lx) (mask is %lx) \n",
	    rreq,newmad_req,match_info,match_mask);
#endif
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457

    MPIDI_Datatype_get_info(rreq->dev.user_count,rreq->dev.datatype, dt_contig, data_sz, dt_ptr,dt_true_lb);
    rreq->dev.OnDataAvail = NULL;
    
    if (dt_contig)
    {
	newmad_iov[0].iov_base = (char*)(rreq->dev.user_buf) + dt_true_lb;
	newmad_iov[0].iov_len  = data_sz;
    }
    else
    {
	struct iovec *newmad_iov_ptr = &(newmad_iov[0]); 
	MPID_nem_newmad_process_rdtype(&rreq,dt_ptr,data_sz,&newmad_iov_ptr,&num_seg);
    }

458
459
460
    ret = nm_sr_irecv_iov_with_ref_tagged(mpid_nem_newmad_session,NM_ANY_GATE,match_info,match_mask,
					  newmad_iov,num_seg,newmad_req,(void*)rreq);	
    REQ_FIELD(rreq,iov) = newmad_iov;    
461
    REQ_FIELD(rreq,iov_to_delete) = 1;
462
    MPID_MEM_NMAD_ADD_REQ_IN_HASH(rreq,newmad_req);  
463
464
465
466
467
    /*
      #ifdef DEBUG
      fprintf(stdout,"========> Any Source : callback end \n");
      #endif
    */
468
469
470
471
472
473
474
475
476
477
}

#undef FUNCNAME
#define FUNCNAME MPID_nem_newmad_anysource_matched
#undef FCNAME
#define FCNAME MPIDI_QUOTE(FUNCNAME)
int MPID_nem_newmad_anysource_matched(MPID_Request *rreq)
{
    /* This function is called when an anysource request in the posted
       receive queue is matched and dequeued */
478
479
480
481
    nm_sr_request_t *nmad_request = NULL;
    int ret;
    int matched = FALSE;

482
483
484
485
#ifdef DEBUG
    fprintf(stdout,"========> Any Source : MPID_nem_newmad_anysource_matched , req is %p\n",rreq);
#endif

486
    MPID_NEM_NMAD_GET_REQ_FROM_HASH(rreq,nmad_request);
487

488
489
    if(nmad_request != NULL)
    {	
490
491
492
493

#ifdef DEBUG
	fprintf(stdout,"========> Any Source nmad req found :%p \n",nmad_request);
#endif
494
	ret = nm_sr_rcancel(mpid_nem_newmad_session,nmad_request);
495
	if (ret !=  NM_ESUCCESS)
496
	{
497
498
499
500

#ifdef DEBUG
	    fprintf(stdout,"========> Any Source nmad req (%p) not cancelled \n",nmad_request);
#endif
501
502
503
	    size_t size;
	    nm_tag_t match_info;
	    MPIU_Assert(MPIDI_Request_get_type(rreq) != MPIDI_REQUEST_TYPE_GET_RESP);                  	
504
	    ret = nm_sr_rwait(mpid_nem_newmad_session,nmad_request);
505
	    MPIU_Assert(ret ==  NM_ESUCCESS);
506
	    nm_sr_request_unset_completion_queue(mpid_nem_newmad_session,nmad_request);
507
508
	    nm_sr_get_rtag(mpid_nem_newmad_session,nmad_request,&match_info);
	    nm_sr_get_size(mpid_nem_newmad_session,nmad_request,&size);
509
	    MPID_nem_newmad_handle_rreq(rreq,match_info, size);
510
511
512
513
514
	    matched = TRUE;
	}
	else
	{
	    MPID_Segment_free(rreq->dev.segment_ptr);
515
   	    if (REQ_FIELD(rreq,iov_to_delete) == 1)
516
	      MPIU_Free(REQ_FIELD(rreq,iov));	
517
518
519
520
521
522
523
524
525
526
527
528
529
	}    
	MPIU_Free(nmad_request);
    }    
    return matched;
}


#undef FUNCNAME
#define FUNCNAME MPID_nem_newmad_process_rdtype
#undef FCNAME
#define FCNAME MPIDI_QUOTE(FUNCNAME)
int MPID_nem_newmad_process_rdtype(MPID_Request **rreq_p, MPID_Datatype * dt_ptr, MPIDI_msg_sz_t data_sz, struct iovec *newmad_iov[], int *num_iov)
{
530
    MPID_Request  *rreq      = *rreq_p;
531
532
    MPIDI_msg_sz_t last;
    MPID_IOV      *iov;
533
534
    int            n_iov     = 0;
    int            mpi_errno = MPI_SUCCESS;
535
536
537
538
539
540
541
542
543
544
545
546
547
548
    int            index;
    
    MPIDI_STATE_DECL(MPID_STATE_MPID_NEM_NEWMAD_PROCESS_RDTYPE);
    MPIDI_FUNC_ENTER(MPID_STATE_MPID_NEM_NEWMAD_PROCESS_RDTYPE);

    if (rreq->dev.segment_ptr == NULL)
    {
	rreq->dev.segment_ptr = MPID_Segment_alloc( );
	MPIU_ERR_CHKANDJUMP1((rreq->dev.segment_ptr == NULL), mpi_errno, MPI_ERR_OTHER, "**nomem", "**nomem %s", "MPID_Segment_alloc");
    }
    MPID_Segment_init(rreq->dev.user_buf, rreq->dev.user_count, rreq->dev.datatype, rreq->dev.segment_ptr, 0);
    rreq->dev.segment_first = 0;
    rreq->dev.segment_size = data_sz;
    last = rreq->dev.segment_size;
549
550
551
552
553

    MPID_Segment_count_contig_blocks(rreq->dev.segment_ptr,rreq->dev.segment_first,&last,&n_iov);
    MPIU_Assert(n_iov > 0);
    iov = MPIU_Malloc(n_iov*sizeof(MPID_IOV));

554
555
    MPID_Segment_unpack_vector(rreq->dev.segment_ptr, rreq->dev.segment_first, &last,iov, &n_iov);
    MPIU_Assert(last == rreq->dev.segment_size);
556

557
558
559
560
561
562
563
564
#ifdef DEBUG
    for(index = 0; index < n_iov ; index++)
	{
	    fprintf(stdout,"======================\n");
	    fprintf(stdout,"RECV iov[%i]: [base %p][len %i]\n",index,
		    iov[index].MPID_IOV_BUF,iov[index].MPID_IOV_LEN);
	}
#endif
565

566
567
568
569
570
571
572
573
574
575
576
577
578
    if(n_iov <= NMAD_IOV_MAX_DEPTH) 
    {
	for(index=0; index < n_iov ; index++)
	{
	    (*newmad_iov)[index].iov_base = iov[index].MPID_IOV_BUF;
	    (*newmad_iov)[index].iov_len  = iov[index].MPID_IOV_LEN;
	}
	rreq->dev.tmpbuf = NULL;
	*num_iov = n_iov;
    }
    else
    {
	int packsize = 0;
579
	MPIR_Pack_size_impl(rreq->dev.user_count, rreq->dev.datatype, &packsize);
580
581
582
583
584
585
586
587
	rreq->dev.tmpbuf = MPIU_Malloc((size_t) packsize);
	MPIU_Assert(rreq->dev.tmpbuf);
	rreq->dev.tmpbuf_sz = packsize;
	(*newmad_iov)[0].iov_base = (char *)  rreq->dev.tmpbuf;
	(*newmad_iov)[0].iov_len  = (uint32_t) packsize;
	*num_iov = 1 ;
    }
    MPIU_Free(iov);
588
 fn_exit:
589
    MPIDI_FUNC_EXIT(MPID_STATE_MPID_NEM_NEWMAD_PROCESS_RDTYPE);
590
    return mpi_errno;
591
 fn_fail:  ATTRIBUTE((unused))
592
593
594
    goto fn_exit;
}

595
596