newmad_send.c 13.9 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
14
15
16
17
18
19
20
21
22
#include "my_papi_defs.h"

#undef FUNCNAME
#define FUNCNAME MPID_nem_newmad_iSendContig
#undef FCNAME
#define FCNAME MPIDI_QUOTE(FUNCNAME)
int MPID_nem_newmad_iSendContig(MPIDI_VC_t *vc, MPID_Request *sreq, void *hdr, MPIDI_msg_sz_t hdr_sz, void *data, MPIDI_msg_sz_t data_sz)
{
    int           mpi_errno = MPI_SUCCESS;
    nm_tag_t      match_info = 0;
23
    struct iovec  newmad_iov[2];
24
25
26
27
28
    int           num_iov = 1;
    
    MPIDI_STATE_DECL(MPID_STATE_MPID_NEM_NEWMAD_ISENDCONTIG);    
    MPIDI_FUNC_ENTER(MPID_STATE_MPID_NEM_NEWMAD_ISENDCONTIG);    

29
    MPIU_Assert(hdr_sz <= sizeof(MPIDI_CH3_Pkt_t));
30
    MPIU_DBG_MSG(CH3_CHANNEL, VERBOSE, "newmad_iSendContig");
31
32
33
    MPIDI_DBG_Print_packet((MPIDI_CH3_Pkt_t *)hdr);

    NEM_NMAD_ADI_MATCH(match_info);
34

35
#ifdef DEBUG
36
    fprintf(stdout,"iSendContig ========> Sending ADI msg  for req %p (match is %lx) \n",sreq,match_info);
37
#endif
38

39
    MPIU_Memcpy(&(sreq->dev.pending_pkt),(char *)hdr,sizeof(MPIDI_CH3_Pkt_t));
40
    newmad_iov[0].iov_base = (char *)&(sreq->dev.pending_pkt);
41
    newmad_iov[0].iov_len  = sizeof(MPIDI_CH3_Pkt_t);
42
43
    if(data_sz)
    {
44
45
	newmad_iov[1].iov_base = data;
	newmad_iov[1].iov_len  = data_sz;
46
47
	num_iov += 1;
    }
48
    REQ_FIELD(sreq,iov) = NULL;
49
    REQ_FIELD(sreq,iov_to_delete) = 0;
50
   
51
    nm_sr_isend_iov_with_ref(mpid_nem_newmad_session, VC_FIELD(vc, p_gate), match_info, 
52
			     newmad_iov, num_iov, &(REQ_FIELD(sreq,newmad_req)),(void *)sreq);    
53
    (VC_FIELD(vc,pending_sends)) += 1;
54
55
56
57
58
    sreq->ch.vc = vc;

 fn_exit:
    MPIDI_FUNC_EXIT(MPID_STATE_MPID_NEM_NEWMAD_ISENDCONTIG);
    return mpi_errno;
59
 fn_fail:  ATTRIBUTE((unused))
60
61
62
63
64
65
66
67
68
69
70
    goto fn_exit;
}

#undef FUNCNAME
#define FUNCNAME MPID_nem_newmad_iStartContigMsg
#undef FCNAME
#define FCNAME MPIDI_QUOTE(FUNCNAME)
int MPID_nem_newmad_iStartContigMsg(MPIDI_VC_t *vc, void *hdr, MPIDI_msg_sz_t hdr_sz, void *data, MPIDI_msg_sz_t data_sz, MPID_Request **sreq_ptr)
{
    MPID_Request *sreq = NULL;
    nm_tag_t      match_info = 0;
71
    struct iovec  newmad_iov[2];
72
73
74
75
76
    int           num_iov = 1;
    int           mpi_errno = MPI_SUCCESS;

    MPIDI_STATE_DECL(MPID_STATE_MPID_NEM_NEWMAD_ISTARTCONTIGMSG);    
    MPIDI_FUNC_ENTER(MPID_STATE_MPID_NEM_NEWMAD_ISTARTCONTIGMSG);    
77
    MPIU_Assert(hdr_sz <= sizeof(MPIDI_CH3_Pkt_t));
78
    MPIU_DBG_MSG(CH3_CHANNEL, VERBOSE, "newmad_iSendContig");
79
80
81
82
83
84
85
86
87
88
    MPIDI_DBG_Print_packet((MPIDI_CH3_Pkt_t *)hdr);

    /* create a request */
    sreq = MPID_Request_create();
    MPIU_Assert (sreq != NULL);
    MPIU_Object_set_ref (sreq, 2);
    sreq->kind = MPID_REQUEST_SEND;
    sreq->dev.OnDataAvail = 0;

    NEM_NMAD_ADI_MATCH(match_info);
89
90
91
92
#ifdef DEBUG
    fprintf(stdout,"StartcontigMsg ========> Sending ADI msg  for req %p (match is %lx) \n",sreq,match_info);
#endif

93
    MPIU_Memcpy(&(sreq->dev.pending_pkt),(char *)hdr,sizeof(MPIDI_CH3_Pkt_t));
94
    newmad_iov[0].iov_base = (char *)&(sreq->dev.pending_pkt);
95
    newmad_iov[0].iov_len  = sizeof(MPIDI_CH3_Pkt_t);
96
97
    if (data_sz)
    {
98
99
	newmad_iov[1].iov_base = (char *)data;
	newmad_iov[1].iov_len  = data_sz;
100
101
	num_iov += 1;
    }
102
    REQ_FIELD(sreq,iov) = NULL;
103
    REQ_FIELD(sreq,iov_to_delete) = 0;    
104
    nm_sr_isend_iov_with_ref(mpid_nem_newmad_session, VC_FIELD(vc, p_gate), match_info, 
105
			     newmad_iov, num_iov, &(REQ_FIELD(sreq,newmad_req)),(void *)sreq);    
106
    (VC_FIELD(vc,pending_sends)) += 1;
107
108
109
110
111
112
    sreq->ch.vc = vc;

 fn_exit:
    *sreq_ptr = sreq;
    MPIDI_FUNC_EXIT(MPID_STATE_MPID_NEM_NEWMAD_ISTARTCONTIGMSG);
    return mpi_errno;
113
 fn_fail:  ATTRIBUTE((unused))
114
115
116
117
118
119
120
121
122
123
124
125
126
    goto fn_exit;
}



#undef FUNCNAME
#define FUNCNAME MPID_nem_newmad_SendNoncontig
#undef FCNAME
#define FCNAME MPIDI_QUOTE(FUNCNAME)
int MPID_nem_newmad_SendNoncontig(MPIDI_VC_t *vc, MPID_Request *sreq, void *header, MPIDI_msg_sz_t hdr_sz)
{
    int            mpi_errno = MPI_SUCCESS;
    nm_tag_t       match_info = 0;
Guillaume Mercier's avatar
Guillaume Mercier committed
127
    struct iovec   newmad_iov[2];
128
    int            num_iov = 1;
Guillaume Mercier's avatar
Guillaume Mercier committed
129
    MPIDI_msg_sz_t last;
130
    MPIDI_msg_sz_t data_sz;
Guillaume Mercier's avatar
Guillaume Mercier committed
131
132
133

    /*
    struct iovec  *newmad_iov = (struct iovec *)MPIU_Malloc(NMAD_IOV_MAX_DEPTH*sizeof(struct iovec));
134
135
136
137
    MPIDI_msg_sz_t data_sz;
    int            dt_contig;
    MPI_Aint       dt_true_lb;
    MPID_Datatype *dt_ptr;
Guillaume Mercier's avatar
Guillaume Mercier committed
138
139
    */

140
141
    MPIDI_STATE_DECL(MPID_STATE_MPID_NEM_NEWMAD_SENDNONCONTIGMSG);    
    MPIDI_FUNC_ENTER(MPID_STATE_MPID_NEM_NEWMAD_SENDNONCONTIGMSG);    
142
    MPIU_Assert(hdr_sz <= sizeof(MPIDI_CH3_Pkt_t));   
143
    MPIU_DBG_MSG(CH3_CHANNEL, VERBOSE, "MPID_nem_newmad_iSendNoncontig");    
Guillaume Mercier's avatar
Guillaume Mercier committed
144
145
    
    NEM_NMAD_ADI_MATCH(match_info);
146

147
    MPIU_Memcpy(&(sreq->dev.pending_pkt),(char *)header,sizeof(MPIDI_CH3_Pkt_t));
Guillaume Mercier's avatar
Guillaume Mercier committed
148
    newmad_iov[0].iov_base = (char *)&(sreq->dev.pending_pkt);
149
    newmad_iov[0].iov_len  = sizeof(MPIDI_CH3_Pkt_t);
150

151
    data_sz = sreq->dev.segment_size - sreq->dev.segment_first;
Guillaume Mercier's avatar
Guillaume Mercier committed
152
    last = sreq->dev.segment_size;
153
    if (data_sz > 0)
Guillaume Mercier's avatar
Guillaume Mercier committed
154
    {
155
	sreq->dev.tmpbuf = MPIU_Malloc((size_t) data_sz);
156
157
        REQ_FIELD(sreq,deltmpbuf) = TMP_DEL_VALUE;
        MPID_Segment_pack(sreq->dev.segment_ptr,sreq->dev.segment_first, &last,(char *)(sreq->dev.tmpbuf));
Guillaume Mercier's avatar
Guillaume Mercier committed
158
159
	MPIU_Assert(last == sreq->dev.segment_size);
	newmad_iov[1].iov_base = (char *)(sreq->dev.tmpbuf);
Guillaume Mercier's avatar
Guillaume Mercier committed
160
161
	newmad_iov[1].iov_len = (uint32_t)last;
	num_iov++;
Guillaume Mercier's avatar
Guillaume Mercier committed
162
163
    }

164
165
    REQ_FIELD(sreq,iov) = NULL;        
    REQ_FIELD(sreq,iov_to_delete) = 0;
Guillaume Mercier's avatar
Guillaume Mercier committed
166
167
168

    /*
    MPIDI_Datatype_get_info(sreq->dev.user_count,sreq->dev.datatype, dt_contig, data_sz, dt_ptr,dt_true_lb);
169
170
    if(data_sz)
    {
171
	struct iovec *mad_iov_ptr = &(newmad_iov[0]);
172
173
	MPID_nem_newmad_process_sdtype(&sreq,sreq->dev.datatype,dt_ptr,sreq->dev.user_buf,
				       sreq->dev.user_count,data_sz, &mad_iov_ptr,&num_iov,1);
174
    }
175
176
177
#ifdef DEBUG
    fprintf(stdout,"SendNonContig ========> Sending ADI msg  for req %p (match is %lx) \n",sreq,match_info);
#endif
Guillaume Mercier's avatar
Guillaume Mercier committed
178
    */
179

180
    nm_sr_isend_iov_with_ref(mpid_nem_newmad_session, VC_FIELD(vc, p_gate), match_info, 
181
			     newmad_iov, num_iov, &(REQ_FIELD(sreq,newmad_req)),(void*)sreq);    
182
183
    (VC_FIELD(vc,pending_sends)) += 1;
   
184
185
186
 fn_exit:
    MPIDI_FUNC_EXIT(MPID_STATE_MPID_NEM_NEWMAD_SENDNONCONTIGMSG);
    return mpi_errno;
187
 fn_fail:  ATTRIBUTE((unused))
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
    goto fn_exit;
}


#undef FUNCNAME
#define FUNCNAME MPID_nem_newmad_directSend
#undef FCNAME
#define FCNAME MPIDI_QUOTE(FUNCNAME)
int  MPID_nem_newmad_directSend(MPIDI_VC_t *vc, const void * buf, int count, MPI_Datatype datatype, int rank, int tag,
				MPID_Comm * comm, int context_offset, MPID_Request **sreq_p)
{
    MPID_Request  *sreq = NULL;
    nm_tag_t       match_info = 0;
    int            num_iov = 0;    
    int            mpi_errno = MPI_SUCCESS;
    MPID_Datatype *dt_ptr;
    int            dt_contig;
    MPIDI_msg_sz_t data_sz;
    MPI_Aint       dt_true_lb;

    MPIDI_STATE_DECL(MPID_STATE_MPID_NEM_NEWMAD_DIRECTSEND);    
    MPIDI_FUNC_ENTER(MPID_STATE_MPID_NEM_NEWMAD_DIRECTSEND);

    MPIDI_Datatype_get_info(count, datatype, dt_contig, data_sz, dt_ptr, dt_true_lb);

    MPIDI_Request_create_sreq(sreq, mpi_errno, goto fn_exit);
    MPIDI_Request_set_type(sreq, MPIDI_REQUEST_TYPE_SEND);
    sreq->partner_request = NULL;
    MPIDI_VC_FAI_send_seqnum(vc, seqnum);
    MPIDI_Request_set_seqnum(sreq, seqnum);
    sreq->ch.vc = vc;
    sreq->dev.OnDataAvail = NULL;
    NEM_NMAD_DIRECT_MATCH(match_info,tag,comm->rank,comm->context_id + context_offset);
221
222
223
#ifdef DEBUG
    fprintf(stdout,"Direct Send ========> Sending NON ADI msg for req %p (match is %lx) \n",sreq,match_info);
#endif
224

225
226
    if(data_sz)
    {
227
	struct iovec newmad_iov[NMAD_IOV_MAX_DEPTH];
228
229
	if (dt_contig)
	{
230
231
	    newmad_iov[0].iov_base = (char*)(buf + dt_true_lb);
	    newmad_iov[0].iov_len  = data_sz;
232
	    num_iov = 1;
233
234
235
	}
	else
	{
236
	    struct iovec  *mad_iov_ptr = &(newmad_iov[0]);
237
	    MPID_nem_newmad_process_sdtype(&sreq,datatype,dt_ptr,buf,count,data_sz,&mad_iov_ptr,&num_iov,0);	    	    
238
	}
239
	MPIU_Assert(num_iov <= NMAD_IOV_MAX_DEPTH);
240
241
242
243
244
#ifdef DEBUG
	for(index = 0; index < num_iov ; index++)
	    {
		fprintf(stdout,"======================\n");
		fprintf(stdout,"SEND nmad_iov[%i]: [base %p][len %i]\n",index,
245
			newmad_iov[index].iov_base,newmad_iov[index].iov_len);
246
247
	    }
#endif
248
	nm_sr_isend_iov_with_ref(mpid_nem_newmad_session, VC_FIELD(vc, p_gate), match_info, 
249
				 newmad_iov, num_iov, &(REQ_FIELD(sreq,newmad_req)),(void*)sreq);    
250
251
252
    }
    else
    {
253
	nm_sr_isend_with_ref(mpid_nem_newmad_session, VC_FIELD(vc, p_gate), match_info, 
254
			     NULL, 0, &(REQ_FIELD(sreq,newmad_req)),(void*)sreq);    
255
    }
256
257
    REQ_FIELD(sreq,iov) = NULL;
    REQ_FIELD(sreq,iov_to_delete) = 0;   
258
   (VC_FIELD(vc,pending_sends)) += 1;
259
260
261
262
263

 fn_exit:
    *sreq_p = sreq;
    MPIDI_FUNC_EXIT(MPID_STATE_MPID_NEM_NEWMAD_DIRECTSEND);
    return mpi_errno;
264
 fn_fail:  ATTRIBUTE((unused))
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
    goto fn_exit;
}

#undef FUNCNAME
#define FUNCNAME MPID_nem_newmad_directSsend
#undef FCNAME
#define FCNAME MPIDI_QUOTE(FUNCNAME)
int  MPID_nem_newmad_directSsend(MPIDI_VC_t *vc, const void * buf, int count, MPI_Datatype datatype, int rank, int tag,
				MPID_Comm * comm, int context_offset, MPID_Request **sreq_p)
{
    MPID_Request  *sreq = NULL;
    nm_tag_t       match_info = 0;
    int            num_iov = 0;    
    int            mpi_errno = MPI_SUCCESS;
    MPID_Datatype *dt_ptr;
    int            dt_contig;
    MPIDI_msg_sz_t data_sz;
    MPI_Aint       dt_true_lb;

    MPIDI_STATE_DECL(MPID_STATE_MPID_NEM_NEWMAD_DIRECTSSEND);    
    MPIDI_FUNC_ENTER(MPID_STATE_MPID_NEM_NEWMAD_DIRECTSSEND);

    MPIDI_Datatype_get_info(count, datatype, dt_contig, data_sz, dt_ptr, dt_true_lb);

    MPIDI_Request_create_sreq(sreq, mpi_errno, goto fn_exit);
    MPIDI_Request_set_type(sreq, MPIDI_REQUEST_TYPE_SEND);
    sreq->partner_request = NULL;
    MPIDI_VC_FAI_send_seqnum(vc, seqnum);
    MPIDI_Request_set_seqnum(sreq, seqnum);
    sreq->ch.vc = vc;
    sreq->dev.OnDataAvail = NULL;

    NEM_NMAD_DIRECT_MATCH(match_info,tag,comm->rank,comm->context_id + context_offset);
    if(data_sz)
    {
300
	struct iovec newmad_iov[NMAD_IOV_MAX_DEPTH];
301
302
	if (dt_contig)
	{
303
304
	    newmad_iov[0].iov_base = (char*)(buf + dt_true_lb);
	    newmad_iov[0].iov_len  = data_sz;
305
	    num_iov = 1;
306
307
308
	}
	else
	{
309
	    struct iovec *mad_iov_ptr = &(newmad_iov[0]);
310
	    MPID_nem_newmad_process_sdtype(&sreq,datatype,dt_ptr,buf,count,data_sz,&mad_iov_ptr,&num_iov,0);	    	    
311
	}
312
313
	nm_sr_issend_iov(mpid_nem_newmad_session, VC_FIELD(vc, p_gate), match_info, 
			 newmad_iov, num_iov, &(REQ_FIELD(sreq,newmad_req)));    
314
315
316
    }
    else
    {
317
318
	nm_sr_issend(mpid_nem_newmad_session, VC_FIELD(vc, p_gate), match_info, 
		     NULL, 0, &(REQ_FIELD(sreq,newmad_req)));    
319
    }
320
321
   REQ_FIELD(sreq,iov) = NULL;
   REQ_FIELD(sreq,iov_to_delete) = 0;
322
   (VC_FIELD(vc,pending_sends)) += 1;
323
324
325
326
327

 fn_exit:
    *sreq_p = sreq;
    MPIDI_FUNC_EXIT(MPID_STATE_MPID_NEM_NEWMAD_DIRECTSSEND);
    return mpi_errno;
328
 fn_fail:  ATTRIBUTE((unused))
329
330
331
332
333
334
335
336
    goto fn_exit;
}


#undef FUNCNAME
#define FUNCNAME MPID_nem_newmad_process_sdtype
#undef FCNAME
#define FCNAME MPIDI_QUOTE(FUNCNAME)
337
int MPID_nem_newmad_process_sdtype(MPID_Request **sreq_p,  MPI_Datatype datatype,  MPID_Datatype *dt_ptr, const void *buf, 
338
				   int count, MPIDI_msg_sz_t data_sz, struct iovec *mad_iov[], int  *num_iov, int first_taken)
339
{
340
    MPID_Request  *sreq        =*sreq_p;
341
    MPID_IOV      *iov;
342
343
    MPIDI_msg_sz_t last;
    int            n_iov       = 0; 
344
345
346
    int            num_entries = NMAD_IOV_MAX_DEPTH - first_taken;
    int            mpi_errno   = MPI_SUCCESS;
    int            index;
347
348
349
350
351
352
353
354
355
356

    MPIDI_STATE_DECL(MPID_STATE_MPID_NEM_NEWMAD_PROCESS_SDTYPE);
    MPIDI_FUNC_ENTER(MPID_STATE_MPID_NEM_NEWMAD_PROCESS_SDTYPE);

    sreq->dev.segment_ptr = MPID_Segment_alloc( );
    MPIU_ERR_CHKANDJUMP1((sreq->dev.segment_ptr == NULL), mpi_errno, MPI_ERR_OTHER, "**nomem", "**nomem %s", "MPID_Segment_alloc");
    MPID_Segment_init(buf, count, datatype, sreq->dev.segment_ptr, 0);
    sreq->dev.segment_first = 0;
    sreq->dev.segment_size = data_sz;
    last = sreq->dev.segment_size;
357
358
359
360

    MPID_Segment_count_contig_blocks(sreq->dev.segment_ptr,sreq->dev.segment_first,&last,&n_iov);
    MPIU_Assert(n_iov > 0);
    iov = MPIU_Malloc(n_iov*sizeof(MPID_IOV));
361
    
362
    MPID_Segment_pack_vector(sreq->dev.segment_ptr, sreq->dev.segment_first, &last,iov, &n_iov);
363
364
    MPIU_Assert(last == sreq->dev.segment_size);

365
366
367
368
369
370
371
372
373
#ifdef DEBUG
    for(index = 0; index < n_iov ; index++)
	{
	    fprintf(stdout,"======================\n");
	    fprintf(stdout,"SEND: iov[%i]: [base %p][len %i]\n",index,
		    iov[index].MPID_IOV_BUF,iov[index].MPID_IOV_LEN);
	}
#endif

374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
    if(n_iov <= num_entries) 
    {
	for(index = 0; index < n_iov ; index++)
	{
	    (*mad_iov)[first_taken+index].iov_base = iov[index].MPID_IOV_BUF;
	    (*mad_iov)[first_taken+index].iov_len  = iov[index].MPID_IOV_LEN;
	}
	*num_iov = n_iov + first_taken;
    }
    else
    {
	int size_to_copy = 0;
        int offset = 0;
        int last_entry = num_entries - 1;
        for(index = 0; index < n_iov ; index++)
	{
	    if (index <= (last_entry-1))
	    {
		(*mad_iov)[first_taken+index].iov_base = iov[index].MPID_IOV_BUF;
		(*mad_iov)[first_taken+index].iov_len  = iov[index].MPID_IOV_LEN;
	    }
	    else
	    {
		size_to_copy += iov[index].MPID_IOV_LEN;
	    }
	}
	sreq->dev.tmpbuf = MPIU_Malloc(size_to_copy);
        MPIU_Assert(sreq->dev.tmpbuf);
402
        REQ_FIELD(sreq,deltmpbuf) = TMP_DEL_VALUE;
403
404
	for(index = last_entry; index < n_iov; index++)
	{
405
	    MPIU_Memcpy((char *)(sreq->dev.tmpbuf) + offset, iov[index].MPID_IOV_BUF, iov[index].MPID_IOV_LEN);
406
407
408
409
410
411
412
	    offset += iov[index].MPID_IOV_LEN;
	}
        (*mad_iov)[NMAD_IOV_MAX_DEPTH-1].iov_base = sreq->dev.tmpbuf;
        (*mad_iov)[NMAD_IOV_MAX_DEPTH-1].iov_len  = size_to_copy;
        *num_iov = NMAD_IOV_MAX_DEPTH;
    }
    MPIU_Free(iov);
413
414
415
 fn_exit:
    MPIDI_FUNC_EXIT(MPID_STATE_MPID_NEM_NEWMAD_PROCESS_SDTYPE);
    return mpi_errno;
416
 fn_fail:  ATTRIBUTE((unused))
417
418
419
420
    goto fn_exit;
}