1 #if HAVE_CONFIG_H
2 # include "config.h"
3 #endif
4
5 /* preliminary implementation on top of portals */
6 /*there are 3 kinds of ARMCI memory: PARMCI_Malloc, PARMCI_Malloc_local, user
7 * allocated memory. For PARMCI_Malloc, we use region specific md that
8 * comes from completion descriptor.
9 * For PARMCI_Malloc_local, we use the MD from the lochdl
10 * For user allocated memory, we use another list of MD's
11 * which binds the user memory. We never keep track of non-armci allocated
12 * memory.
13 */
14 #if HAVE_STDIO_H
15 # include <stdio.h>
16 #endif
17 #if HAVE_STDLIB_H
18 # include <stdlib.h>
19 #endif
20 #if HAVE_STRING_H
21 # include <string.h>
22 #endif
23 #if HAVE_FLOAT_H
24 # include <float.h>
25 #endif
26 #include "armcip.h"
27 #include "message.h"
28 #if HAVE_STDINT_H
29 # include <stdint.h>
30 #endif
31
32 #define DEBUG_COMM 0
33 #define DEBUG_INIT 0
34 #ifndef PMI_SUCCESS
35 #define PMI_SUCCESS 0
36 #endif
37
38
39 #ifdef CRAY_XT
40 #include "locks.h"
41 typedef struct {
42 int off;
43 int desc;
44 } cnos_mutex_t;
45
46 static cnos_mutex_t *_mutex_array;
47 #endif
48
49
50 /*global variables and data structures */
51 armci_portals_proc_t _armci_portals_proc_struct;
52 armci_portals_proc_t *portals = &_armci_portals_proc_struct;
53 comp_desc *_region_compdesc_array[PORTALS_MEM_REGIONS+1];
54 int ptl_initialized = 0;
55 int free_desc_index[PORTALS_MEM_REGIONS+1];
56 FILE *utcp_lib_out;
57 FILE* utcp_api_out;
58 ptl_ni_limits_t armci_ptl_nilimits;
59
armci_init_portals(void)60 int armci_init_portals(void)
61 {
62 int num_interface;
63 int rc;
64 int npes,i;
65 comp_desc *armci_comp_desc;
66 ptl_process_id_t match_id;
67 ARMCI_PR_DBG("enter",0);
68
69 if (PtlInit(&num_interface) != PTL_OK) {
70 fprintf(stderr, "PtlInit() failed\n");
71 exit(1);
72 }
73 portals->ptl = 37; /* our own ptl number */
74 for(i=0;i<=PORTALS_MEM_REGIONS;i++){
75 free_desc_index[i]=0;
76 }
77
78 rc=PtlNIInit(IFACE_FROM_BRIDGE_AND_NALID(PTL_BRIDGE_UK,PTL_IFACE_SS), PTL_PID_ANY, NULL, &armci_ptl_nilimits, &(portals->ni_h));
79 switch(rc) {
80 case PTL_OK:
81 case PTL_IFACE_DUP:
82 break;
83 default:
84 printf( "PtlNIInit() failed %d error=%s\n",rc,ptl_err_str[rc]);
85 armci_die("NIInit Failed",0);
86 }
87 if(DEBUG_INIT || DEBUG_COMM)
88 PtlNIDebug(portals->ni_h,PTL_DEBUG_ALL);
89
90 PtlGetId(portals->ni_h,&portals->ptl_my_procid);
91 if(DEBUG_INIT){
92 printf("%d:the rank is %d, size is %d\n",armci_me,
93 portals->ptl_my_procid,portals->size);
94 }
95
96 if((rc=PMI_CNOS_Get_nidpid_map(&portals->ptl_pe_procid_map))!=PMI_SUCCESS){
97 printf("Getting proc map failed (npes=%d)\n", armci_nproc);
98 }
99
100 /* Allocate one shared event queue for all operations
101 * TODO tune size.
102 */
103 rc = PtlEQAlloc(portals->ni_h,1024,NULL, &(portals->eq_h));
104 if (rc != PTL_OK) {
105 printf("%d:PtlEQAlloc() failed: %s (%d)\n",
106 portals->ptl_my_procid, ptl_err_str[rc], rc);
107 armci_die("EQ Alloc failed",rc);
108 }
109
110 ptl_initialized = 1;
111 portals->num_match_entries = 0;
112
113 #ifndef CRAY_XT
114 utcp_lib_out = stdout;
115 utcp_api_out = stdout;
116 #endif
117
118 /*now prepare for use of local memory*/
119 armci_comp_desc = (comp_desc *)malloc(sizeof(comp_desc)*MAX_OUT);
120 for(i=0; i< MAX_OUT;i++){
121 ptl_md_t *md_ptr;
122 ptl_handle_md_t *md_h;
123 armci_comp_desc[i].active=0;
124 md_ptr = &armci_comp_desc[i].mem_dsc;
125 md_h = &armci_comp_desc[i].mem_dsc_hndl;
126 md_ptr->eq_handle = portals->eq_h;
127 md_ptr->max_size =0;
128 md_ptr->threshold = 2;/*PTL_MD_THRESH_INF;*/
129 md_ptr->options = PTL_MD_OP_GET | PTL_MD_OP_PUT | PTL_MD_EVENT_START_DISABLE;
130 }
131 _region_compdesc_array[PORTALS_MEM_REGIONS]=armci_comp_desc;
132 ARMCI_PR_DBG("exit",0);
133 return 0;
134 }
135
136
137
armci_fini_portals()138 void armci_fini_portals()
139 {
140 ARMCI_PR_DBG("enter",0);
141 if(DEBUG_INIT){
142 printf("ENTERING ARMCI_FINI_PORTALS\n");fflush(stdout);
143 }
144 PtlNIFini(portals->ni_h);
145 /*PtlFini();*/
146 if(DEBUG_INIT){
147 printf("LEAVING ARMCI_FINI_PORTALS\n");fflush(stdout);
148 }
149 ARMCI_PR_DBG("exit",0);
150 }
151
152
153
armci_serv_register_req(void * start,long bytes,ARMCI_MEMHDL_T * reg_mem)154 void armci_serv_register_req(void *start,long bytes, ARMCI_MEMHDL_T *reg_mem)
155 {
156 int rc;
157 void * context;
158 ptl_md_t *md_ptr;
159 ptl_match_bits_t *mb;
160 ptl_process_id_t match_id;
161 ptl_handle_md_t *md_h;
162 ptl_match_bits_t ignbits = 0xFFFFFFFFFFFFFFF0;
163
164 ARMCI_PR_DBG("enter",reg_mem->regid);
165 if(DEBUG_COMM){
166 printf("%d:armci_serv_register_req:size of mem_hndl is %d\n",
167 armci_me,sizeof(region_memhdl_t));
168 printf("\n%d:armci_serv_register_req start=%p bytes=%d\n",
169 armci_me,start,bytes);fflush(stdout);
170 }
171
172 md_ptr = ®_mem->cdesc.mem_dsc;
173 mb = ®_mem->match_bits;
174 md_h = ®_mem->cdesc.mem_dsc_hndl;
175 context = NULL;
176
177 md_ptr->start = start;
178 md_ptr->length = bytes;
179 md_ptr->threshold = PTL_MD_THRESH_INF;
180 md_ptr->options = PTL_MD_OP_PUT | PTL_MD_OP_GET | PTL_MD_MANAGE_REMOTE;
181 md_ptr->user_ptr = context;
182 /*eq_hdl is null for the attaches done for a remote proc*/
183 /*md_ptr->eq_handle = portals->eq_h;*/
184 md_ptr->eq_handle = PTL_EQ_NONE;
185 md_ptr->max_size =0;
186 *mb = 0x0000000000000000;
187 *mb = (*mb+reg_mem->regid);
188
189 match_id.nid = PTL_NID_ANY;
190 match_id.pid = PTL_PID_ANY;
191
192 rc = PtlMEAttach(portals->ni_h,portals->ptl,match_id,*mb,ignbits,
193 PTL_RETAIN,PTL_INS_AFTER,
194 &(portals->me_h[portals->num_match_entries]));
195
196 if (rc != PTL_OK) {
197 printf("%d:PtlMEAttach: %s\n", portals->ptl_my_procid, ptl_err_str[rc]);
198 armci_die("portals attach error2",rc);
199 }
200
201 rc = PtlMDAttach(portals->me_h[portals->num_match_entries],*md_ptr,PTL_RETAIN,md_h);
202
203 if (rc != PTL_OK) {
204 printf("%d:PtlMDAttach: %s\n", portals->ptl_my_procid, ptl_err_str[rc]);
205 armci_die("portals attach error1",rc);
206 }
207
208 portals->num_match_entries++;
209 ARMCI_PR_DBG("exit",reg_mem->regid);
210
211 }
212
armci_pin_contig_hndl(void * start,int bytes,ARMCI_MEMHDL_T * reg_mem)213 int armci_pin_contig_hndl(void *start,int bytes, ARMCI_MEMHDL_T *reg_mem)
214 {
215 int rc,i;
216 void * context;
217 ptl_md_t *md_ptr;
218 ptl_process_id_t match_id;
219 ptl_handle_md_t *md_h;
220 comp_desc *armci_comp_desc;
221
222 ARMCI_PR_DBG("enter",reg_mem->regid);
223 /*first create comp_desc arr for this region if it is not local*/
224 if(!reg_mem->islocal){
225 armci_comp_desc = (comp_desc *)malloc(sizeof(comp_desc)*MAX_OUT);
226 for(i=0; i< MAX_OUT;i++){
227 armci_comp_desc[i].active=0;
228 md_ptr = &armci_comp_desc[i].mem_dsc;
229 md_h = &armci_comp_desc[i].mem_dsc_hndl;
230 context = NULL;
231 md_ptr->start = start;
232 md_ptr->length = bytes;
233 md_ptr->threshold = 2;/*PTL_MD_THRESH_INF;*/
234 md_ptr->options = PTL_MD_OP_GET | PTL_MD_OP_PUT | PTL_MD_EVENT_START_DISABLE;
235 /*md_ptr->options = PTL_MD_EVENT_START_DISABLE;*/
236
237 md_ptr->user_ptr = context;
238 md_ptr->eq_handle = portals->eq_h;
239 md_ptr->max_size =0;
240 #ifdef DO_MD_UPDATE
241 rc = PtlMDBind(portals->ni_h,*md_ptr, PTL_RETAIN, md_h);
242 if (rc != PTL_OK){
243 printf("%d:PtlMDBind: %s\n", portals->ptl_my_procid, ptl_err_str[rc]);
244 armci_die("ptlmdbind failed",0);
245 }
246 #endif
247 }
248 _region_compdesc_array[reg_mem->regid]=armci_comp_desc;
249 ARMCI_PR_DBG("exit",0);
250 return 1;
251 }
252 else {
253 md_ptr = ®_mem->cdesc.mem_dsc;
254 md_h = ®_mem->cdesc.mem_dsc_hndl;
255 context = NULL;
256 md_ptr->start = start;
257 md_ptr->length = bytes;
258 md_ptr->threshold = 2;/*PTL_MD_THRESH_INF;*/
259 md_ptr->options = PTL_MD_OP_PUT | PTL_MD_EVENT_START_DISABLE;
260
261 md_ptr->user_ptr = context;
262 md_ptr->eq_handle = portals->eq_h;
263 md_ptr->max_size =0;
264 #if DO_MD_UPDATE
265 rc = PtlMDBind(portals->ni_h,*md_ptr, PTL_RETAIN, md_h);
266 if (rc != PTL_OK){
267 printf("%d:PtlMDBind: %s\n", portals->ptl_my_procid, ptl_err_str[rc]);
268 armci_die("ptlmdbind failed",0);
269 }
270 #endif
271 ARMCI_PR_DBG("exit",1);
272 return 1;
273 }
274 }
275
276
armci_client_complete(ptl_event_kind_t * evt,int proc_id,int nb_tag,comp_desc * cdesc)277 int armci_client_complete(ptl_event_kind_t *evt,int proc_id, int nb_tag,
278 comp_desc *cdesc)
279 {
280 int rc;
281 ptl_event_t ev_t;
282 ptl_event_t *ev=&ev_t;
283 comp_desc *temp_comp = NULL;
284 int loop=1;
285 int temp_proc;
286 ARMCI_PR_DBG("enter",0);
287 if(DEBUG_COMM){
288 printf("\n%d:enter:client_complete active=%d tag=%d %d\n",armci_me,
289 cdesc->active,cdesc->tag,nb_tag);fflush(stdout);
290 }
291 while(cdesc->active!=0){
292 ev->type=0;
293 if((rc = PtlEQWait(portals->eq_h, ev)) != PTL_OK){
294 printf("%d:PtlEQWait(): %d %s\n", portals->ptl_my_procid,rc,
295 ptl_err_str[rc]);
296 armci_die("EQWait problem",rc);
297 }
298 if (ev->ni_fail_type != PTL_NI_OK) {
299 printf("%d:NI sent %d in event.\n",
300 portals->ptl_my_procid, ev->ni_fail_type);
301 armci_die("event failure problem",0);
302 }
303 if(DEBUG_COMM){
304 printf("\n%d:armci_client_complete:done waiting type=%d\n",armci_me,
305 ev->type);
306 fflush(stdout);
307 }
308 if (ev->type == PTL_EVENT_SEND_END){
309 if(DEBUG_COMM){
310 printf("\n%d:armci_client_complete:event send end\n",armci_me);
311 fflush(stdout);
312 }
313 temp_comp = (comp_desc *)ev->md.user_ptr;
314 #ifdef PUT_LOCAL_ONLY_COMPLETION
315 if(temp_comp->type==ARMCI_PORTALS_PUT || temp_comp->type=ARMCI_PORTALS_NBPUT){
316 temp_comp->active=0;
317 temp_comp->tag=-1;
318 }
319 else
320 #else
321 temp_comp->active++;
322 #endif
323 continue;
324 }
325
326 if (ev->type == PTL_EVENT_REPLY_END){
327 if(DEBUG_COMM){
328 printf("\n%d:client_send_complete:reply end\n",armci_me);
329 fflush(stdout);
330 }
331 temp_comp = (comp_desc *)ev->md.user_ptr;
332 temp_comp->active = 0; /*this was a get request, so we are done*/
333 temp_comp->tag=-1;
334 continue;
335 }
336 if (ev->type == PTL_EVENT_ACK){
337 if(DEBUG_COMM){
338 printf("\n%d:client_send_complete:event ack\n",armci_me);
339 fflush(stdout);
340 }
341 temp_comp = (comp_desc *)ev->md.user_ptr;
342 temp_comp->active=0;
343 temp_comp->tag=-1;
344 armci_update_fence_array(temp_comp->dest_id,0);
345 portals->outstanding_puts--;
346 }
347 }
348 if(DEBUG_COMM){
349 printf("\n%d:exit:client_complete active=%d tag=%d %d\n",armci_me,
350 cdesc->active,cdesc->tag,nb_tag);fflush(stdout);
351 }
352 ARMCI_PR_DBG("exit",0);
353 return rc;
354 }
355
356
get_free_comp_desc(int region_id,int * comp_id)357 comp_desc * get_free_comp_desc(int region_id, int * comp_id)
358 {
359 comp_desc * c;
360 int rc = PTL_OK;
361 ARMCI_PR_DBG("enter",region_id);
362 c = &(_region_compdesc_array[region_id][free_desc_index[region_id]]);
363 if(c->active!=0 && c->tag>0)armci_client_complete(NULL,c->dest_id,c->tag,c);
364 #ifdef PUT_LOCAL_ONLY_COMPLETION
365 if(region_id<PORTALS_MEM_REGIONS){
366 do {
367 rc = PtlMDUnlink(*md_hdl_local);
368 }while(rc==PTL_MD_IN_USE);
369 }
370 #endif
371 *comp_id = (region_id*PORTALS_MEM_REGIONS+free_desc_index[region_id]);
372 if(DEBUG_COMM){
373 printf("the value of comp_desc_id is %d\n",*comp_id);
374 fflush(stdout);
375 }
376 free_desc_index[region_id] = ((free_desc_index[region_id] + 1) % MAX_OUT);
377 ARMCI_PR_DBG("exit",0);
378 return c;
379 }
380
381
print_mem_desc(ptl_md_t * md)382 void print_mem_desc(ptl_md_t * md)
383 {
384 printf("%d:md : start %p : length %d\n",armci_me,md->start, md->length);
385 fflush(stdout);
386
387 }
388
armci_client_direct_get(int proc,void * src_buf,void * dst_buf,int bytes,void ** cptr,int tag,ARMCI_MEMHDL_T * lochdl,ARMCI_MEMHDL_T * remhdl)389 void armci_client_direct_get(int proc, void *src_buf, void *dst_buf, int bytes,
390 void** cptr,int tag,ARMCI_MEMHDL_T *lochdl,
391 ARMCI_MEMHDL_T *remhdl)
392 {
393 int clus = armci_clus_id(proc);
394 int rc, i;
395 ptl_size_t offset_local = 0, offset_remote=0;
396 ptl_match_bits_t mb = remhdl->regid;
397 ptl_md_t *md_remote,md, *md_local;
398 ptl_md_t * md_ptr;
399 ptl_handle_md_t *md_hdl_local;
400 comp_desc *cdesc;
401 ptl_process_id_t dest_proc;
402 int c_info;
403 int lproc,rproc,user_memory=0;
404
405 ARMCI_PR_DBG("enter",remhdl->regid);
406
407 if(DEBUG_COMM){
408 printf("%d:armci_client_direct_get:src_buf %p dstbuf %p loc_hd is %p\n"
409 "rem_hndl is %p, BYTES = %d\n",armci_me,src_buf,dst_buf,
410 lochdl,remhdl,bytes);
411 fflush(stdout);
412 }
413
414 /*first process information*/
415 dest_proc.nid = portals->ptl_pe_procid_map[proc].nid;
416 dest_proc.pid = portals->ptl_pe_procid_map[proc].pid;
417 md_remote =&remhdl->cdesc.mem_dsc;
418
419 /*updating md to send*/
420 if(lochdl == NULL){ /*this is user memory (stack/heap/whatever) */
421 user_memory=1;
422 cdesc = get_free_comp_desc(PORTALS_MEM_REGIONS,&c_info);
423 md_local = &cdesc->mem_dsc;
424 md_hdl_local = &cdesc->mem_dsc_hndl;
425 md_local->length=bytes;
426 md_local->start=dst_buf;
427 }
428 else {
429 if(lochdl->islocal){ /*PARMCI_Malloc_local memory*/
430 user_memory=1;
431 #if 1
432 cdesc = get_free_comp_desc(PORTALS_MEM_REGIONS,&c_info);
433 md_local = &cdesc->mem_dsc;
434 md_hdl_local = &cdesc->mem_dsc_hndl;
435 md_local->length=bytes;
436 md_local->start=dst_buf;
437 #else
438 cdesc=&lochdl->cdesc;
439 md_local = &lochdl->cdesc.mem_dsc;
440 md_hdl_local = &lochdl->cdesc.mem_dsc_hndl;
441 #endif
442 }
443 else{
444 /*we need to pass region id to get corresponding md*/
445 cdesc = get_free_comp_desc(lochdl->regid,&c_info);
446 md_local = &cdesc->mem_dsc;
447 md_hdl_local = &cdesc->mem_dsc_hndl;
448 }
449 }
450
451 /*compute the local and remote offsets*/
452 offset_local = (char*)dst_buf - (char *)md_local->start;
453 offset_remote = (char*)src_buf - (char *)md_remote->start;
454 if(DEBUG_COMM){
455 printf("\n%d:offr=%d offl=%d %p %p\n",armci_me,offset_remote,offset_local,md_local->start,md_remote->start);
456 }
457 /*printf("\n%d:get offr=%d ptrr=%p offl=%d ptrl=%p\n",armci_me,offset_remote,md_remote->start,offset_local,md_local->start);fflush(stdout);*/
458
459 if(tag) *((comp_desc **)cptr) = cdesc;
460 /*if(tag){printf("\n%d:get tag=%d c_info=%d %p",armci_me,tag,c_info,cdesc);fflush(stdout);}*/
461 if (tag){
462 cdesc->tag = tag;
463 cdesc->dest_id = proc;
464 cdesc->type = ARMCI_PORTALS_NBGET;
465 }
466 else{
467 cdesc->tag = 0;
468 cdesc->dest_id = proc;
469 cdesc->type = ARMCI_PORTALS_GET;
470 }
471 cdesc->active = 1;
472 md_local->user_ptr = (void *)cdesc;
473 md_local->options = PTL_MD_OP_GET | PTL_MD_EVENT_START_DISABLE;
474 #if DO_MD_UPDATE
475 if(user_memory==0){
476 do{
477 rc = PtlMDUpdate(*md_hdl_local,NULL,md_local,portals->eq_h);
478 printf("\n%d:trying to update\n",armci_me);fflush(stdout);
479 } while (rc == PTL_MD_NO_UPDATE);
480 if (rc != PTL_OK){
481 printf("%d:PtlMDUpdate: %s\n", portals->rank, ptl_err_str[rc]);
482 armci_die("ptlmdbind failed",0);
483 }
484 }
485 else{
486 #endif
487 rc = PtlMDBind(portals->ni_h,*md_local, PTL_UNLINK, md_hdl_local);
488 if (rc != PTL_OK){
489 fprintf(stderr, "%d:PtlMDBind: %s\n", portals->rank, ptl_err_str[rc]);
490 armci_die("ptlmdbind failed",0);
491 }
492 #if DO_MD_UPDATE
493 }
494 #endif
495
496 rc = PtlGetRegion(*md_hdl_local,offset_local,bytes,dest_proc,
497 portals->ptl,
498 0,
499 mb,
500 offset_remote);
501 if (rc != PTL_OK){
502 printf("%d:PtlGetRegion: %s\n", portals->rank,ptl_err_str[rc]);
503 armci_die("PtlGetRegion failed",0);
504 }
505
506 if(DEBUG_COMM){
507 printf("\n%d:issued get to %d %d\n",armci_me,proc,c_info);fflush(stdout);
508 }
509
510 if(!tag){
511 armci_client_complete(NULL,proc,0,cdesc); /* check this later */
512 }
513 /*printf("\n%d:issued get to %d %d\n",armci_me,proc,c_info);fflush(stdout);*/
514 ARMCI_PR_DBG("exit",remhdl->regid);
515 }
516
517
armci_client_nb_get(int proc,void * src_buf,int * src_stride_arr,void * dst_buf,int * dst_stride_arr,int bytes,void ** cptr,int tag,ARMCI_MEMHDL_T * lochdl,ARMCI_MEMHDL_T * remhdl)518 void armci_client_nb_get(int proc, void *src_buf, int *src_stride_arr,
519 void *dst_buf, int *dst_stride_arr, int bytes,
520 void** cptr,int tag,ARMCI_MEMHDL_T *lochdl,
521 ARMCI_MEMHDL_T *remhdl)
522 {
523 }
524
525
armci_client_direct_send(int proc,void * src,void * dst,int bytes,void ** cptr,int tag,ARMCI_MEMHDL_T * lochdl,ARMCI_MEMHDL_T * remhdl)526 int armci_client_direct_send(int proc,void *src, void* dst, int bytes,
527 void **cptr, int tag, ARMCI_MEMHDL_T *lochdl,
528 ARMCI_MEMHDL_T *remhdl )
529 {
530 int clus = armci_clus_id(proc);
531 int rc, i;
532 ptl_size_t offset_local = 0, offset_remote = 0;
533 ptl_match_bits_t mb = remhdl->regid;
534 ptl_md_t *md_remote,md, *md_local;
535 ptl_md_t * md_ptr;
536 ptl_match_bits_t * mb_ptr;
537 ptl_handle_md_t *md_hdl_local;
538 comp_desc *cdesc;
539 ptl_process_id_t dest_proc;
540 int c_info;
541 int lproc,rproc,user_memory=0;
542
543 ARMCI_PR_DBG("enter",remhdl->regid);
544 dest_proc.nid = portals->ptl_pe_procid_map[proc].nid;
545 dest_proc.pid = portals->ptl_pe_procid_map[proc].pid;
546 md_remote =&remhdl->cdesc.mem_dsc;
547
548 if(lochdl == NULL){ /*this is user memory*/
549 user_memory=1;
550 cdesc = get_free_comp_desc(PORTALS_MEM_REGIONS,&c_info);
551 md_local = &cdesc->mem_dsc;
552 md_hdl_local = &cdesc->mem_dsc_hndl;
553 md_local->length=bytes;
554 md_local->start=src;
555 }
556 else {
557 if(lochdl->islocal){ /*PARMCI_Malloc_local memory*/
558 user_memory=1;
559 #if 1
560 cdesc = get_free_comp_desc(PORTALS_MEM_REGIONS,&c_info);
561 md_local = &cdesc->mem_dsc;
562 md_hdl_local = &cdesc->mem_dsc_hndl;
563 md_local->length=bytes;
564 md_local->start=src;
565 #else
566 cdesc=&lochdl->cdesc;
567 md_local = &lochdl->cdesc.mem_dsc;
568 md_hdl_local = &lochdl->cdesc.mem_dsc_hndl;
569 #endif
570 }
571 else{
572 /*we need to pass region id to get corresponding md*/
573 cdesc = get_free_comp_desc(lochdl->regid,&c_info);
574 md_local = &cdesc->mem_dsc;
575 md_hdl_local = &cdesc->mem_dsc_hndl;
576
577 }
578 }
579
580 offset_local = (char *)src - (char *)md_local->start;
581 offset_remote =(char *)dst - (char *)md_remote->start;
582 if(DEBUG_COMM){
583 printf("\n%d:offr=%d offl=%d\n",armci_me,offset_remote,offset_local);
584 }
585 /*printf("\n%d:offr=%d ptrr=%p offl=%d ptrl=%p\n",armci_me,offset_remote,md_remote->start,offset_local,md_local->start);fflush(stdout);*/
586
587 if(tag) *((comp_desc **)cptr) = cdesc; /*TOED*/
588 /*
589 if(tag){printf("\n%d:put tag=%d c_info=%d %p",armci_me,tag,c_info,cdesc);fflush(stdout);}
590 */
591 if (tag){
592 cdesc->tag = tag;
593 cdesc->dest_id = proc;
594 cdesc->type = ARMCI_PORTALS_NBPUT;
595 }
596 else{
597 cdesc->tag = 0;
598 cdesc->dest_id = proc;
599 cdesc->type = ARMCI_PORTALS_PUT;
600 }
601 #ifdef PUT_LOCAL_COMPLETION_ONLY
602 cdesc->active = 2;
603 #else
604 cdesc->active = 1;
605 #endif
606
607 md_local->user_ptr = (void *)cdesc;
608 md_local->options = PTL_MD_OP_PUT | PTL_MD_EVENT_START_DISABLE;
609 #if DO_MD_UPDATE
610 if(user_memory==0){
611 do{
612 rc = PtlMDUpdate(*md_hdl_local,NULL,md_local,portals->eq_h);
613 } while (rc == PTL_MD_NO_UPDATE);
614 if (rc != PTL_OK){
615 printf("%d:PtlMDUpdate: %s\n", portals->rank, ptl_err_str[rc]);
616 armci_die("ptlmdupdate failed",0);
617 }
618 }
619 else{
620 #endif
621 rc = PtlMDBind(portals->ni_h,*md_local, PTL_UNLINK, md_hdl_local);
622 if (rc != PTL_OK){
623 fprintf(stderr, "%d:PtlMDBind: %s\n", portals->rank, ptl_err_str[rc]);
624 armci_die("ptlmdbind failed",0);
625 }
626 #if DO_MD_UPDATE
627 }
628 #endif
629
630 rc = PtlPutRegion(*md_hdl_local,offset_local,bytes,
631 #ifdef PUT_LOCAL_COMPLETION_ONLY
632 PTL_NOACK_REQ,
633 #else
634 PTL_ACK_REQ,
635 #endif
636 dest_proc,
637 portals->ptl,
638 0, mb,offset_remote, 0);
639 if (rc != PTL_OK){
640 fprintf(stderr, "%d:PtlPutRegion: %s\n", portals->rank,ptl_err_str[rc]);
641 armci_die("PtlPutRegion failed",0);
642 }
643 if(DEBUG_COMM){
644 printf("\n%d:issued put to %d\n",armci_me,proc);fflush(stdout);
645 }
646
647 armci_update_fence_array(proc, 1);
648 if(!tag){
649 armci_client_complete(NULL,proc,0,cdesc); /* check this later */
650 }
651 else
652 portals->outstanding_puts++;
653 ARMCI_PR_DBG("exit",remhdl->regid);
654 return rc;
655 }
656
armci_client_nb_send(int proc,void * src_buf,int * src_stride_arr,void * dst_buf,int * dst_stride_arr,int bytes,void ** cptr,int tag,ARMCI_MEMHDL_T * lochdl,ARMCI_MEMHDL_T * remhdl)657 void armci_client_nb_send(int proc, void *src_buf, int *src_stride_arr,
658 void *dst_buf, int *dst_stride_arr, int bytes,
659 void** cptr,int tag,ARMCI_MEMHDL_T *lochdl,
660 ARMCI_MEMHDL_T *remhdl)
661 {
662 }
663 #if 1
664 /*using non-blocking for multiple 1ds inside a 2d*/
armci_network_strided(int op,void * scale,int proc,void * src_ptr,int src_stride_arr[],void * dst_ptr,int dst_stride_arr[],int count[],int stride_levels,armci_ihdl_t nb_handle)665 void armci_network_strided(int op, void* scale, int proc,void *src_ptr,
666 int src_stride_arr[], void* dst_ptr, int dst_stride_arr[],
667 int count[], int stride_levels, armci_ihdl_t nb_handle)
668 {
669 int i, j,tag=0;
670 long idxs,idxd; /* index offset of current block position to ptr */
671 int n1dim; /* number of 1 dim block */
672 int bvalues[MAX_STRIDE_LEVEL], bunit[MAX_STRIDE_LEVEL];
673 int bvalued[MAX_STRIDE_LEVEL];
674 int bytes = count[0];
675 void *loc, *rem;
676 void *sptr,*dptr;
677 ARMCI_MEMHDL_T *loc_memhdl=NULL,*rem_memhdl=NULL;
678 NB_CMPL_T cptr;
679 int armci_region_both_found_hndl(void *loc, void *rem, int size, int node,
680 ARMCI_MEMHDL_T **loc_memhdl,ARMCI_MEMHDL_T **rem_memhdl);
681 if(nb_handle)tag=nb_handle->tag;
682 if(op==GET){
683 loc = dst_ptr;
684 rem = src_ptr;
685 }
686 else {
687 loc = src_ptr;
688 rem = dst_ptr;
689 }
690 armci_region_both_found_hndl(loc,rem,bytes,armci_clus_id(proc),
691 &loc_memhdl,&rem_memhdl);
692 /* number of n-element of the first dimension */
693 n1dim = 1;
694 for(i=1; i<=stride_levels; i++)
695 n1dim *= count[i];
696 /* calculate the destination indices */
697 bvalues[0] = 0; bvalues[1] = 0; bunit[0] = 1;
698 bvalued[0] = 0; bvalued[1] = 0; bunit[1] = 1;
699 for(i=2; i<=stride_levels; i++) {
700 bvalues[i] = bvalued[i] = 0;
701 bunit[i] = bunit[i-1] * count[i-1];
702 }
703 if(ARMCI_ACC(op)){
704 /*lock here*/
705 printf("\nSHOULD NOT DO NETWORK_STRIDED FOR ACCS \n",armci_me);
706 fflush(stdout);
707 armci_die("network_strided called for acc",proc);
708 }
709 for(i=0; i<n1dim; i++) {
710 tag = GET_NEXT_NBTAG();
711 idxs = 0;
712 idxd = 0;
713 for(j=1; j<=stride_levels; j++) {
714 idxs += bvalues[j] * src_stride_arr[j-1];
715 idxd += bvalued[j] * dst_stride_arr[j-1];
716 if((i+1) % bunit[j] == 0) {bvalues[j]++;bvalued[j]++;}
717 if(bvalues[j] > (count[j]-1)) bvalues[j] = 0;
718 if(bvalued[j] > (count[j]-1)) bvalued[j] = 0;
719 }
720
721 sptr = ((char *)src_ptr)+idxs;
722 dptr = ((char *)dst_ptr)+idxd;
723 if(op==GET){
724 armci_client_direct_get(proc,sptr,dptr,bytes,&cptr,tag,loc_memhdl,
725 rem_memhdl);
726 }
727 else if(op==PUT){
728 armci_client_direct_send(proc,sptr,dptr,bytes,&cptr,tag,loc_memhdl,
729 rem_memhdl);
730 }
731 else if(ARMCI_ACC(op)){
732 armci_client_direct_get(proc,sptr,dptr,bytes,&cptr,tag,loc_memhdl,
733 rem_memhdl);
734 /*DO ACC*/
735 armci_client_direct_send(proc,sptr,dptr,bytes,&cptr,tag,loc_memhdl,
736 rem_memhdl);
737 }
738 else
739 armci_die("in network_strided unknown opcode",op);
740 }
741 if(ARMCI_ACC(op)){
742 /*unlock here*/
743 }
744 if(nb_handle){
745 nb_handle->tag=tag;
746 nb_handle->cmpl_info=cptr;
747 }
748 else{
749 armci_client_complete(NULL,proc,tag,cptr); /* check this later */
750 }
751 }
752 #else /*using blocking for multiple 1ds inside a 2d*/
armci_network_strided(int op,void * scale,int proc,void * src_ptr,int src_stride_arr[],void * dst_ptr,int dst_stride_arr[],int count[],int stride_levels,armci_ihdl_t nb_handle)753 void armci_network_strided(int op, void* scale, int proc,void *src_ptr,
754 int src_stride_arr[], void* dst_ptr, int dst_stride_arr[],
755 int count[], int stride_levels, armci_ihdl_t nb_handle)
756 {
757 int i, j;
758 long idxs,idxd; /* index offset of current block position to ptr */
759 int n1dim; /* number of 1 dim block */
760 int bvalues[MAX_STRIDE_LEVEL], bunit[MAX_STRIDE_LEVEL];
761 int bvalued[MAX_STRIDE_LEVEL];
762 int bytes = count[0];
763 void *loc, *rem;
764 void *sptr,*dptr;
765 #if 0
766 ARMCI_MEMHDL_T *loc_memhdl=NULL,*rem_memhdl=NULL;
767 int armci_region_both_found_hndl(void *loc, void *rem, int size, int node,
768 ARMCI_MEMHDL_T **loc_memhdl,ARMCI_MEMHDL_T **rem_memhdl);
769 #endif
770 if(op==GET){
771 loc = dst_ptr;
772 rem = src_ptr;
773 }
774 else {
775 loc = src_ptr;
776 rem = dst_ptr;
777 }
778 #if 0
779 armci_region_both_found_hndl(loc,rem,count[0],armci_clus_id(proc),
780 &loc_memhdl,&rem_memhdl);
781 #endif
782 /* number of n-element of the first dimension */
783 n1dim = 1;
784 for(i=1; i<=stride_levels; i++)
785 n1dim *= count[i];
786
787 /* calculate the destination indices */
788 bvalues[0] = 0; bvalues[1] = 0; bunit[0] = 1;
789 bvalued[0] = 0; bvalued[1] = 0; bunit[1] = 1;
790 for(i=2; i<=stride_levels; i++) {
791 bvalues[i] = bvalued[i] = 0;
792 bunit[i] = bunit[i-1] * count[i-1];
793 }
794
795 for(i=0; i<n1dim; i++) {
796 idxs = 0;
797 idxd = 0;
798 for(j=1; j<=stride_levels; j++) {
799 idxs += bvalues[j] * src_stride_arr[j-1];
800 idxd += bvalued[j] * dst_stride_arr[j-1];
801 if((i+1) % bunit[j] == 0) {bvalues[j]++;bvalued[j]++;}
802 if(bvalues[j] > (count[j]-1)) bvalues[j] = 0;
803 if(bvalued[j] > (count[j]-1)) bvalued[j] = 0;
804 }
805
806 sptr = ((char *)src_ptr)+idxs;
807 dptr = ((char *)dst_ptr)+idxd;
808 if((i<(n1dim-1)) || nb_handle==NULL){
809 if(op==GET)
810 PARMCI_Get(sptr,dptr,bytes,proc);
811 else if(op==PUT)
812 PARMCI_Put(sptr,dptr,bytes,proc);
813 else if(ARMCI_ACC(op))
814 PARMCI_AccS(op,scale,sptr,NULL,dptr,NULL,count,1,proc);
815 else
816 armci_die("in network_strided unknown opcode",op);
817 }
818 }
819 if(nb_handle!=NULL){
820 if(op==GET)
821 PARMCI_NbGet(sptr,dptr,bytes,proc,(armci_hdl_t *)nb_handle);
822 else if(op==PUT)
823 PARMCI_NbPut(sptr,dptr,bytes,proc,(armci_hdl_t *)nb_handle);
824 else if(ARMCI_ACC(op))
825 PARMCI_NbAccS(op,scale,sptr,NULL,dptr,NULL,count,1,proc,(armci_hdl_t *)nb_handle);
826 else
827 armci_die("in network_strided unknown opcode",op);
828 }
829 }
830 #endif
831
armci_client_direct_getput(int proc,void * getinto,void * putfrom,void * dst,int bytes,void ** cptr,int tag,ARMCI_MEMHDL_T * lochdl,ARMCI_MEMHDL_T * remhdl)832 int armci_client_direct_getput(int proc,void *getinto, void *putfrom, void* dst,
833 int bytes, void **cptr, int tag, ARMCI_MEMHDL_T *lochdl,
834 ARMCI_MEMHDL_T *remhdl )
835
836 {
837 int clus = armci_clus_id(proc);
838 int rc, i;
839 ptl_size_t offset_get = 0, offset_put=0, offset_remote = 0;
840 ptl_match_bits_t mb = 100;
841 ptl_md_t *md_remote,md, *md_local_put, *md_local_get;
842 ptl_md_t * md_ptr;
843 ptl_match_bits_t * mb_ptr;
844 ptl_handle_md_t *md_hdl_local_put,*md_hdl_local_get;
845 comp_desc *cdesc;
846 ptl_process_id_t dest_proc;
847 int c_info;
848 int lproc,rproc;
849 printf("\n%d:****************getput*********\n",armci_me);
850 dest_proc.nid = portals->ptl_pe_procid_map[proc].nid;
851 dest_proc.pid = portals->ptl_pe_procid_map[proc].pid;
852 md_remote =&remhdl->cdesc.mem_dsc;
853
854 cdesc = get_free_comp_desc(PORTALS_MEM_REGIONS,&c_info);
855 md_local_get = &cdesc->mem_dsc;
856 md_hdl_local_get = &cdesc->mem_dsc_hndl;
857 md_local_get->length=bytes;
858 md_local_get->start=getinto;
859 offset_get = (char *)getinto - (char *)md_local_get->start;
860 offset_remote =(char *)dst - (char *)md_remote->start;
861 cdesc->tag = 999999;
862 cdesc->dest_id = proc;
863 cdesc->type = ARMCI_PORTALS_PUT;
864 cdesc->active = 0;
865 md_local_get->user_ptr = (void *)cdesc;
866 md_local_get->options = PTL_MD_OP_GET | PTL_MD_OP_PUT | PTL_MD_EVENT_START_DISABLE | PTL_MD_EVENT_END_DISABLE;
867 rc = PtlMDBind(portals->ni_h,*md_local_get, PTL_UNLINK, md_hdl_local_get);
868 if (rc != PTL_OK){
869 fprintf(stderr, "%d:PtlMDBind: %s\n", portals->rank, ptl_err_str[rc]);
870 armci_die("ptlmdbind failed",0);
871 }
872
873 cdesc = get_free_comp_desc(PORTALS_MEM_REGIONS,&c_info);
874 md_local_put = &cdesc->mem_dsc;
875 md_hdl_local_put = &cdesc->mem_dsc_hndl;
876 md_local_put->length=bytes;
877 md_local_put->start=putfrom;
878 offset_put = (char *)putfrom - (char *)md_local_put->start;
879 cdesc->tag = 999999;
880 cdesc->dest_id = proc;
881 cdesc->type = ARMCI_PORTALS_GET;
882 cdesc->active = 0;
883 md_local_put->user_ptr = (void *)cdesc;
884 md_local_put->options = PTL_MD_OP_PUT | PTL_MD_EVENT_START_DISABLE;
885 rc = PtlMDBind(portals->ni_h,*md_local_put, PTL_UNLINK, md_hdl_local_put);
886 if (rc != PTL_OK){
887 fprintf(stderr, "%d:PtlMDBind: %s\n", portals->rank, ptl_err_str[rc]);
888 armci_die("ptlmdbind failed",0);
889 }
890
891 rc = PtlGetPutRegion(*md_hdl_local_get,offset_get,*md_hdl_local_put,
892 offset_put,bytes,dest_proc, portals->ptl,0,mb,offset_remote,
893 0);
894 if (rc != PTL_OK){
895 printf("%d:PtlPutRegion: %s\n", portals->rank,ptl_err_str[rc]);
896 armci_die("PtlPutRegion failed",0);
897 }
898 if(DEBUG_COMM){
899 printf("\n%d:issued getput to %d\n",armci_me,proc);fflush(stdout);
900 }
901
902 armci_client_complete(NULL,proc,0,cdesc); /* check this later */
903 return rc;
904 }
905
armci_network_client_deregister_memory(ARMCI_MEMHDL_T * mh)906 void armci_network_client_deregister_memory(ARMCI_MEMHDL_T *mh)
907 {
908 }
909
910
armci_network_server_deregister_memory(ARMCI_MEMHDL_T * mh)911 void armci_network_server_deregister_memory(ARMCI_MEMHDL_T *mh)
912 {
913 }
914
915 #ifdef CRAY_XT_
916 static int num_locks=0;
917 static long **all_locks;
918 #define ARMCI_PORTALS_MAX_LOCKS 16
919 typedef struct {
920 ptl_handle_md_t mem_dsc_h;
921 ptl_handle_me_t me_lock_h;
922 region_memhdl_t armci_portal_lock_memhdl;
923 } armci_lock_struct;
924 armci_lock_struct armci_portals_lock_st;
armcill_allocate_locks(int num)925 void armcill_allocate_locks(int num)
926 {
927 ptl_md_t *md_ptr;
928 ptl_match_bits_t *mb;
929 ptl_process_id_t match_id;
930 ptl_handle_md_t *md_h;
931 int ace_any=1;
932 int rc;
933 long *my_locks;
934 int elems;
935 armci_lock_struct *armci_portals_lock=&armci_portals_lock_st;
936
937 num_locks = num;
938 if(DEBUG_COMM){
939 printf("%d:armci_allocate_locks num=%d\n",
940 armci_me,num_locks);
941 }
942 if(MAX_LOCKS<num)armci_die2("too many locks",ARMCI_PORTALS_MAX_LOCKS,num);
943
944 /* allocate memory to hold lock info for all the processors */
945 all_locks = malloc(armci_nproc*sizeof(long *));
946 if(!all_locks) armci_die("armcill_init_locks: malloc failed",0);
947 bzero(all_locks,armci_nproc*sizeof(long));
948 /* initialize local locks */
949 my_locks = malloc(num*sizeof(long));
950 if(!my_locks) armci_die("armcill_init_locks: malloc failed",0);
951 bzero(all_locks,armci_nproc*sizeof(long));
952
953 all_locks[armci_me]=my_locks;
954 /* now we use all-reduce to exchange locks info among everybody */
955 elems = armci_nproc;
956 armci_exchange_address((void **)all_locks,elems);
957 #if 0
958 rc = PtlACEntry(portals->ni_h, ace_any,
959 (ptl_process_id_t){PTL_NID_ANY, PTL_PID_ANY},
960 PTL_PID_ANY, 128);
961 if (rc != PTL_OK) {
962 printf("%d: PtlACEntry() failed: %s\n",
963 armci_me, ptl_err_str[rc]);
964 armci_die("PtlACEntry failed",0);
965 }
966 #endif
967 armci_portals_lock->armci_portal_lock_memhdl.cdesc.mem_dsc.start =&my_locks;
968 armci_portals_lock->armci_portal_lock_memhdl.cdesc.mem_dsc.length =
969 sizeof(my_locks);
970 armci_portals_lock->armci_portal_lock_memhdl.cdesc.mem_dsc.threshold =
971 PTL_MD_THRESH_INF;
972 armci_portals_lock->armci_portal_lock_memhdl.cdesc.mem_dsc.options =
973 PTL_MD_OP_PUT | PTL_MD_OP_GET |
974 PTL_MD_MANAGE_REMOTE | PTL_MD_TRUNCATE |
975 PTL_MD_EVENT_START_DISABLE;
976 armci_portals_lock->armci_portal_lock_memhdl.cdesc.mem_dsc.max_size = 0;
977 armci_portals_lock->armci_portal_lock_memhdl.cdesc.mem_dsc.user_ptr = NULL;
978 armci_portals_lock->armci_portal_lock_memhdl.cdesc.mem_dsc.eq_handle =
979 PTL_EQ_NONE;
980 match_id.nid = PTL_NID_ANY;
981 match_id.pid = PTL_PID_ANY;
982
983 /* Lockmaster needs a match entry for clients to access lock value.
984 */
985 rc = PtlMEAttach(portals->ni_h, portals->ptl,
986 match_id, /* source address */
987 100, /* expected match bits */
988 0, /* ignore bits to mask */
989 PTL_RETAIN, /* unlink when md is unlinked */
990 PTL_INS_AFTER,
991 &armci_portals_lock->me_lock_h);
992 if (rc != PTL_OK){
993 printf("%d: PtlMEAttach(): %s\n",
994 armci_me, ptl_err_str[rc]);
995 armci_die("PtlMEAttach in init_locks failed",0);
996 }
997 rc = PtlMDAttach(armci_portals_lock->me_lock_h,
998 armci_portals_lock->armci_portal_lock_memhdl.cdesc.mem_dsc,
999 PTL_RETAIN,
1000 &armci_portals_lock->mem_dsc_h);
1001 if (rc != PTL_OK) {
1002 printf("%d: PtlMDAttach(): %s\n",
1003 armci_me, ptl_err_str[rc]);
1004 armci_die("PtlMDAttach in init_locks failed",0);
1005 }
1006 }
1007
armcill_lock(int mutex,int proc)1008 void armcill_lock(int mutex, int proc)
1009 {
1010 long getinto=0,putfrom=1;
1011 armci_lock_struct *armci_portal_lock=&armci_portals_lock_st;
1012 region_memhdl_t *rem_lock_hdl=&armci_portal_lock->armci_portal_lock_memhdl;
1013 printf("\n%d:in lock before\n",armci_me);fflush(stdout);
1014 do{
1015 armci_client_direct_getput(proc,&getinto,&putfrom,(all_locks[proc]+mutex),
1016 sizeof(long), NULL, 0, NULL,rem_lock_hdl);
1017 }while(getinto!=0);
1018 printf("\n%d:in lock after\n",armci_me);fflush(stdout);
1019 }
1020
1021
1022 /*\ unlock specified mutex on node where process proc is running
1023 \*/
armcill_unlock(int mutex,int proc)1024 void armcill_unlock(int mutex, int proc)
1025 {
1026 long getinto=0,putfrom=0;
1027 armci_lock_struct *armci_portal_lock=&armci_portals_lock_st;
1028 region_memhdl_t *rem_lock_hdl=&armci_portal_lock->armci_portal_lock_memhdl;
1029 armci_client_direct_getput(proc,&getinto,&putfrom,(all_locks[proc]+mutex),
1030 sizeof(long), NULL, 0, NULL,rem_lock_hdl);
1031 }
1032
armci_portals_rmw_(int op,int * ploc,int * prem,int extra,int proc)1033 int armci_portals_rmw_(int op, int *ploc, int *prem, int extra, int proc)
1034 {
1035 return(0);
1036 }
1037 #endif
1038
armci_portals_shmalloc_allocate_mem(int num_lks)1039 void armci_portals_shmalloc_allocate_mem(int num_lks)
1040 {
1041 void **ptr_arr;
1042 void *ptr;
1043 armci_size_t bytes = 128;
1044 int i;
1045
1046 ptr_arr = (void**)malloc(armci_nproc*sizeof(void*));
1047 if(!ptr_arr) armci_die("armci_shmalloc_get_offsets: malloc failed", 0);
1048 bzero((char*)ptr_arr,armci_nproc*sizeof(void*));
1049
1050 PARMCI_Malloc(ptr_arr,bytes);
1051
1052 return;
1053 }
1054