5
/* $Id: lapi2.c,v 1.18.2.3 2007-07-02 05:24:34 d3p687 Exp $ */
7
#define DSCR_SIZE 4096*8 /*given that bufsize=30000*8,conservative,indeed*/
9
#define LAPI_CLEAR_CNTR(ocmpl_) if((ocmpl_)->val) {\
11
if(LAPI_Waitcntr(lapi_handle,&((ocmpl_)->cntr), ((ocmpl_)->val), &_val_))\
12
armci_die("LAPI_Waitcntr failed",-1);\
13
if(_val_ != 0) armci_die("CLEAR_COUNTER: nonzero in file ", _val_);\
18
/*\ create lapi vector descriptors from the buffer
20
static void lapi2_create_vec_info(lapi_vec_t **srcv, lapi_vec_t **dstv,
21
int iovnum,int iovlen,char *bufptr)
23
int dsize = iovnum*sizeof(void *);
24
int dlen = iovlen*sizeof(int);
27
*srcv = (lapi_vec_t *)(bufptr+offset); offset+=sizeof(lapi_vec_t);
28
*dstv = (lapi_vec_t *)(bufptr+offset); offset+=sizeof(lapi_vec_t);
31
(*srcv)->info= (void **)(bufptr+offset); offset+=dsize;
32
(*dstv)->info= (void **)(bufptr+offset); offset+=dsize;
34
(*srcv)->len = (unsigned long *)(bufptr+offset); offset+=dlen;
35
(*dstv)->len = (unsigned long *)(bufptr+offset); offset+=dlen;
38
(*srcv)->len = (*dstv)->len = NULL;
43
/*\ 2D strided get/put using lapi vector/strided transfer
45
void armcill_op2D(int op,void *src_ptr,int src_stride,void *dst_ptr,
46
int dst_stride,int count, int bytes, int p,
47
lapi_cntr_t *ocntr,char *bufptr)
49
lapi_vec_t *src, *dst;
54
printf("\n%d:in put2d p=%d bytes=%d\n",armci_me,p,bytes);fflush(stdout);
57
/*lapi2_create_vec_info(&src,&dst,3,0,bufptr);*/
58
src = (lapi_vec_t *)(bufptr+offset); offset+=sizeof(lapi_vec_t);
59
dst = (lapi_vec_t *)(bufptr+offset); offset+=sizeof(lapi_vec_t);
60
src->info = (void **)(bufptr+offset); offset+=3*sizeof(void *);
61
dst->info = (void **)(bufptr+offset); offset+=3*sizeof(void *);
64
src->vec_type = dst->vec_type = LAPI_GEN_STRIDED_XFER;
65
src->num_vecs = (uint)count; dst->num_vecs= (uint)count;
67
src->len = NULL; dst->len = NULL;
68
src->info[0] = src_ptr; dst->info[0] = dst_ptr;
69
src->info[1] = (void*)bytes; dst->info[1] = (void*)bytes;
70
src->info[2] = (void*)src_stride; dst->info[2] = (void*)dst_stride;
73
rc = LAPI_Getv(lapi_handle, (uint)p, src, dst,NULL,ocntr);
75
rc = LAPI_Putv(lapi_handle,(uint)p,dst,src,NULL,ocntr,&cmpl_arr[p].cntr);
77
if(rc) armci_die2("LAPI_op2D failed",rc,op);
79
if(DEBUG)printf("\n%d: put completed \n",armci_me);
83
/*\ ND strided get/put packed and sent as vectors
85
void armcill_opND(int op,void *src_ptr, int src_stride_arr[],void* dst_ptr,
86
int dst_stride_arr[],int count[], int stride_levels,
87
int proc, lapi_cmpl_t *ocmpl,char *bufptr)
89
char *dst=(char*)dst_ptr;
90
char *src=(char*)src_ptr;
93
int i,j,k,num_xmit=0,lastiovlength,iovlength,n=0,max_iovec,totalsize=0;
95
int index[MAX_STRIDE_LEVEL], unit[MAX_STRIDE_LEVEL];
97
lapi_vec_t *srcv, *dstv;
98
lapi_cntr_t *ocntr=&(ocmpl->cntr);
102
printf("\n%d:in getND count[0] is %d and strarr[0] is%d maxiov=%d\n",
103
armci_me,count[0],dst_stride_arr[0],max_iovec);
107
index[2] = 0; unit[2] = 1;
109
total_of_2D = count[2];
110
for(j=3; j<=stride_levels; j++) {
111
index[j] = 0; unit[j] = unit[j-1] * count[j-1];
112
total_of_2D *= count[j];
116
max_iovec=(DSCR_SIZE-2*sizeof(lapi_vec_t))/(2*(sizeof(int)+sizeof(void*)));
118
/*compute number of loops and the size of last iovector based of buf size*/
119
num_xmit = total_of_2D*count[1]/max_iovec;
120
lastiovlength = (total_of_2D*count[1])%max_iovec;
121
if(num_xmit == 0) num_xmit = 1;
122
else if(lastiovlength!=0)num_xmit++;
124
/*set the current iov length*/
126
if(lastiovlength!=0 && k==(num_xmit-1))iovlength=lastiovlength;
127
else iovlength=max_iovec;
129
/*create the lapi_vec_t from the buffer*/
130
/*lapi2_create_vec_info(&srcv,&dstv,iovlength,iovlength,bufptr);*/
131
srcv = (lapi_vec_t *)(bufptr+offset); offset+=sizeof(lapi_vec_t);
132
dstv = (lapi_vec_t *)(bufptr+offset); offset+=sizeof(lapi_vec_t);
133
srcv->info= (void **)(bufptr+offset); offset+=iovlength*sizeof(void*);
134
dstv->info= (void **)(bufptr+offset); offset+=iovlength*sizeof(void*);
135
srcv->len = (unsigned long *)(bufptr+offset);offset+=iovlength*sizeof(unsigned long);
136
dstv->len = (unsigned long *)(bufptr+offset);offset+=iovlength*sizeof(unsigned long);
139
srcv->vec_type = dstv->vec_type = LAPI_GEN_IOVECTOR;
140
srcv->num_vecs = (uint)iovlength; dstv->num_vecs= (uint)iovlength;
142
for(i=0; i<total_of_2D; i++) {
143
dst = (char *)dst_ptr;
144
src = (char *)src_ptr;
145
for(j=2; j<=stride_levels; j++) {
146
dst += index[j] * dst_stride_arr[j-1];
147
src += index[j] * src_stride_arr[j-1];
148
if(((i+1) % unit[j]) == 0) index[j]++;
149
if(index[j] >= count[j]) index[j] = 0;
153
for(j=0;j<count[1];j++,vecind++){
154
if(vecind==iovlength){
155
LAPI_CLEAR_CNTR((ocmpl));
158
rc = LAPI_Getv(lapi_handle,(uint)proc,srcv,dstv,NULL,ocntr);
161
UPDATE_FENCE_STATE(proc,PUT,1);
162
rc = LAPI_Putv(lapi_handle,(uint)proc,dstv,srcv,NULL,ocntr,
163
&cmpl_arr[proc].cntr);
165
if(rc) armci_die2("LAPI_opND failed",rc,op);
166
vecind = 0; totalsize=0; k++;
167
if(lastiovlength!=0 && k==(num_xmit-1))iovlength=lastiovlength;
168
else iovlength=max_iovec;
169
srcv->num_vecs = (uint)iovlength; dstv->num_vecs= (uint)iovlength;
172
dstv->info[vecind] = dst1;
173
dstv->len[vecind] = count[0];
174
srcv->info[vecind] = src1;
175
srcv->len[vecind] = count[0];
177
dst1+=dst_stride_arr[0];
178
src1+=src_stride_arr[0];
180
if(vecind==iovlength){
181
LAPI_CLEAR_CNTR((ocmpl));
184
rc = LAPI_Getv(lapi_handle,(uint)proc,srcv,dstv,NULL,ocntr);
187
UPDATE_FENCE_STATE(proc,PUT,1);
188
rc = LAPI_Putv(lapi_handle,(uint)proc,dstv,srcv,NULL,ocntr,
189
&cmpl_arr[proc].cntr);
191
if(rc) armci_die2("LAPI_opND failed",rc,op);
192
vecind = 0; totalsize=0; k++;
193
if(lastiovlength!=0 && k==(num_xmit-1))iovlength=lastiovlength;
194
else iovlength=max_iovec;
195
srcv->num_vecs = (uint)iovlength; dstv->num_vecs= (uint)iovlength;
198
if(DEBUG)printf("\n%d: get completed \n",armci_me);
203
void lapi_op_2d(int op, uint proc, void *src_ptr, void *dst_ptr,uint bytes,
204
int count, int src_stride, int dst_stride,lapi_cmpl_t* o_cmpl)
207
if(op==PUT)UPDATE_FENCE_STATE(proc, PUT, count);
209
for(i=0;i<count;i++){
211
rc=LAPI_Put(lapi_handle,proc,bytes,(dst_ptr),(src_ptr),
212
NULL,&(o_cmpl->cntr),&cmpl_arr[proc].cntr);
214
rc=LAPI_Get(lapi_handle,proc,bytes,(src_ptr),(dst_ptr),NULL,
216
if(rc)ARMCI_Error("LAPI_put failed",0);
217
src_ptr = (void*) ((unsigned long)src_ptr+src_stride);
218
dst_ptr = (void*) ((unsigned long)dst_ptr+dst_stride);
223
/*\This function is designed as follows.
224
* CONTIG code breaks ND into 1D chunks a does Lapi_Put on each chunk.
225
* STRIDED code uses strided option in the LAPI_PutV call
226
* VECTOR code packs multi-strided/vector data as vectors as transmits.
227
* ____________________________________
228
* | type small/medium large |
229
* |------------------------------------
230
* | 1D CONTIG CONTIG|
231
* | 2D STRIDED CONTIG|
232
* | >2D VECTOR CONTIG|
233
* |-----------------------------------|
234
* this code uses orig counter from nb_handle for non-blk call
235
* completion counter should always be same for non-blk and blk code to be
236
* able to do ordering/fence.
238
void armci_network_strided(int op, void* scale, int proc,void *src_ptr,
239
int src_stride_arr[], void* dst_ptr, int dst_stride_arr[],
240
int count[], int stride_levels, armci_ihdl_t nb_handle)
245
char *src = (char*)src_ptr, *dst=(char*)dst_ptr;
247
int index[MAX_STRIDE_LEVEL], unit[MAX_STRIDE_LEVEL];
248
int dsize=3*sizeof(void*);
249
/*pick a counter, default for blocking, from descriptor for non-blocking*/
251
INIT_COUNTER((nb_handle->cmpl_info),0);
252
o_cmpl = &(nb_handle->cmpl_info);
261
/* multithreaded lapi uses array of counters (one per thread) */
262
o_cmpl = get_cntr; /* same as &(get_cntr[0]) */
264
o_cmpl = ack_cntr; /* same as &(ack_cntr[0]) */
267
/*CONTIG protocol: used for 1D(contiguous) or if stride is very large in
268
a multi strided case*/
269
if(stride_levels==0 || count[0]>LONG_PUT_THRESHOLD){
270
/*set bufid in nb_handle, in this case, no buffer used, hence NB_NONE*/
272
armci_set_nbhandle_bufid(nb_handle,NULL,NB_NONE);
273
switch (stride_levels) {
275
lapi_op_2d(op, (uint)proc, src_ptr, dst_ptr, count[0], 1,
279
lapi_op_2d(op, (uint)proc, src_ptr,dst_ptr, (uint)count[0], count[1],
280
src_stride_arr[0], dst_stride_arr[0], o_cmpl);
282
default: /* N-dimensional */
284
index[2] = 0; unit[2] = 1; total_of_2D = count[2];
285
for(j=3; j<=stride_levels; j++) {
286
index[j] = 0; unit[j] = unit[j-1] * count[j-1];
287
total_of_2D *= count[j];
289
for(i=0; i<total_of_2D; i++) {
290
src = (char *)src_ptr; dst = (char *)dst_ptr;
291
for(j=2; j<=stride_levels; j++) {
292
src += index[j] * src_stride_arr[j-1];
293
dst += index[j] * dst_stride_arr[j-1];
294
if(((i+1) % unit[j]) == 0) index[j]++;
295
if(index[j] >= count[j]) index[j] = 0;
297
lapi_op_2d(op, (uint)proc, src, dst,(uint)count[0], count[1],
298
src_stride_arr[0], dst_stride_arr[0],o_cmpl);
303
else{ /* greated than 1D small/med stride */
305
if(stride_levels==1){ /*small/med 2D, use lapi STRIDED */
306
bufptr = GET_SEND_BUFFER(2*(sizeof(lapi_vec_t)+dsize),op,proc);
308
/*update info in the buf_info_t data-structure*/
309
SET_BUF_TAG(bufptr,nb_handle->tag,0);
310
/*set the buffer id in nb_handle*/
311
armci_set_nbhandle_bufid(nb_handle,bufptr,0);
313
if(op==PUT)UPDATE_FENCE_STATE(proc, PUT, 1);
315
/*we use the counter in the buffer*/
316
o_cmpl = (BUF_TO_EVBUF(bufptr));
318
armcill_op2D(op,src_ptr,src_stride_arr[0],dst_ptr,dst_stride_arr[0],
319
count[1],count[0],proc,&(o_cmpl->cntr),bufptr);
321
else { /*small/med >2D, use lapi VECTOR*/
322
bufptr = GET_SEND_BUFFER(DSCR_SIZE,op,proc);
324
/*update info in the buf_info_t data-structure*/
325
SET_BUF_TAG(bufptr,nb_handle->tag,0);
326
/*set the buffer id in nb_handle*/
327
armci_set_nbhandle_bufid(nb_handle,bufptr,0);
329
/*we use the counter in the buffer*/
330
o_cmpl = (BUF_TO_EVBUF(bufptr));
332
/*val set to 0 because of the way opND is writted, to be modified*/
335
armcill_opND(op,src_ptr,src_stride_arr,dst_ptr, dst_stride_arr,count,
336
stride_levels,proc,o_cmpl,bufptr);
340
for blocking cases, we can free cmpldescr buffer and wait for op
344
/*for now, we manually clear the counter here for blocking calls.
345
for later, this has to be done in FREE_SEND_BUFFER.*/
346
LAPI_CLEAR_CNTR(o_cmpl);
347
FREE_SEND_BUFFER(bufptr);
354
void armci_send_strided_data_bypass(int proc, request_header_t *msginfo,
355
void *bufptr, int msg_buflen,
356
void *src_ptr, int *loc_stride_arr,
357
void *dst_ptr, int *rem_stride_arr,
358
int *pcount, int stride_levels)
361
int count= pcount[1],bytes=pcount[0],rc;
362
int src_stride= loc_stride_arr[0];
363
int dst_stride= rem_stride_arr[0];
364
lapi_vec_t *src, *dst;
369
if(stride_levels!=1)armci_die("armci_send_strided_data_bypass wrong stride",stride_levels);
371
LAPI_Setcntr(lapi_handle,&c,0);
373
src = (lapi_vec_t *)((unsigned long)bufptr+offset); offset+=sizeof(lapi_vec_t);
374
dst = (lapi_vec_t *)((unsigned long)bufptr+offset); offset+=sizeof(lapi_vec_t);
375
src->info = (void **)((unsigned long)bufptr+offset); offset+=3*sizeof(void *);
376
dst->info = (void **)((unsigned long)bufptr+offset); offset+=3*sizeof(void *);
379
src->vec_type = dst->vec_type = LAPI_GEN_STRIDED_XFER;
380
src->num_vecs = (uint)count; dst->num_vecs= (uint)count;
382
src->len = NULL; dst->len = NULL;
383
src->info[0] = src_ptr; dst->info[0] = dst_ptr;
384
src->info[1] = (void*)bytes; dst->info[1] = (void*)bytes;
385
src->info[2] = (void*)src_stride; dst->info[2] = (void*)dst_stride;
387
rc = LAPI_Putv(lapi_handle,(uint)p,dst,src,msginfo->tag.cntr,&c,NULL);
388
if(rc)armci_die("armci_send_strided_data_bypass failed",rc);
391
printf("%dserv: did putv to %d cntr =%p\n",armci_me,p,msginfo->tag.cntr); fflush(stdout);
393
LAPI_Waitcntr(lapi_handle, &c,1,NULL);
398
/*\ client receives strided data from server
400
void armci_rcv_strided_data_bypass_both(int proc, request_header_t* msginfo,
401
void *ptr, int count[], int strides)
403
lapi_cmpl_t *pcntr=BUF_TO_EVBUF(msginfo);
405
printf("%d: expecting data from %d cntr =%p v=%d\n",armci_me,proc,&pcntr->cntr,pcntr->val);
408
CLEAR_COUNTER((*pcntr));
410
printf("%d: got data from %d\n",armci_me,proc); fflush(stdout);