void armci_region_exchange(void *start, long size) { int found=0, i; armci_region_t *reg=0; #ifdef REGIONS_REQUIRE_MEMHDL ARMCI_MEMHDL_T *hdlarr; hdlarr = calloc(armci_nclus,sizeof(ARMCI_MEMHDL_T)); #endif if(!allow_pin)return; if(armci_nclus<=1)return; found=armci_region_clus_found(armci_clus_me, start,size); if(found>-1){ if(!exch_rem[found]){ reg = (clus_regions+armci_clus_me)->list+found; exch_rem[found]=1; } }else{ found= armci_region_loc_found(start,size); if(found>-1){ if(!exch_loc[found]){ reg = (&loc_regions_arr)->list+found; exch_loc[found]=1; } } } bzero(exch_list,2*armci_nclus*sizeof(void *)); if( reg && (armci_me == armci_master)){ exch_list[2*armci_clus_me] = reg->start; exch_list[2*armci_clus_me+1] = reg->end; #ifdef REGIONS_REQUIRE_MEMHDL armci_copy(®->memhdl,&hdlarr[armci_clus_me],sizeof(ARMCI_MEMHDL_T)); #endif } /* exchange info on new regions with other nodes */ armci_exchange_address(exch_list,2*armci_nclus); #ifdef REGIONS_REQUIRE_MEMHDL i = armci_nclus*sizeof(ARMCI_MEMHDL_T)/sizeof(int); armci_msg_gop_scope(SCOPE_ALL,hdlarr,i,"+",ARMCI_INT); #endif for(i=0; i<armci_nclus; i++){ armci_reglist_t *r=clus_regions+i; if(i==armci_clus_me) continue; if(exch_list[2*i]){ #if 0 printf("%d recording clus=%d mem %p-%p n=%d\n",armci_me,i,exch_list[2*i], exch_list[2*i+1],r->n); fflush(stdout); #endif #ifdef REGIONS_REQUIRE_MEMHDL armci_copy(&hdlarr[i],&(r->list+r->n)->memhdl,sizeof(ARMCI_MEMHDL_T)); #endif armci_region_record(exch_list[2*i],exch_list[2*i+1], r); } } }
/*\ control message to the server, e.g.: ATTACH to shmem, return ptr etc. \*/ void armci_serv_attach_req(void *info, int ilen, long size, void* resp,int rlen) { char *buf; ARMCI_PR_DBG("enter",0); int bufsize = 2*sizeof(request_header_t)+ilen + sizeof(long)+sizeof(rlen); long *idlist=(long *)info; request_header_t *msginfo = (request_header_t*)GET_SEND_BUFFER(bufsize,ATTACH,armci_me); bzero(msginfo,sizeof(request_header_t)); msginfo->from = armci_me; msginfo->to = SERVER_NODE(armci_clus_me); msginfo->dscrlen = ilen; msginfo->datalen = sizeof(long)+sizeof(int); msginfo->operation = ATTACH; msginfo->bytes = msginfo->dscrlen+ msginfo->datalen; armci_copy(info, msginfo +1, ilen); if(DEBUG_MEM){printf("\n%d:sending idlist+1 %d, size %d, idlist[0] %d, idlist[1] %d\n",armci_me,idlist+1,size,idlist[0],idlist[1]);} buf = ((char*)msginfo) + ilen + sizeof(request_header_t); *((long*)buf) =size; *(int*)(buf+ sizeof(long)) = rlen; armci_send_req(armci_master, msginfo, bufsize,0); if(rlen){ buf= armci_rcv_data(armci_master, msginfo,rlen); /* receive response */ bcopy(buf, resp, rlen); FREE_SEND_BUFFER(msginfo); if(DEBUG_MEM){printf("%d:client attaching got ptr=%p %d bytes\n",armci_me,buf,rlen); fflush(stdout); } } ARMCI_PR_DBG("exit",0); }
void * armci_server_ptr(int id){ char *buf; int bufsize = sizeof(int); request_header_t *msginfo = (request_header_t*)GET_SEND_BUFFER(bufsize,ATTACH,armci_me); bzero(msginfo,sizeof(request_header_t)); msginfo->from = armci_me; msginfo->to = SERVER_NODE(armci_clus_me); msginfo->dscrlen = 0; msginfo->datalen = sizeof(int); msginfo->operation = ATTACH; msginfo->bytes = msginfo->dscrlen+ msginfo->datalen; armci_copy(&id, msginfo +1, sizeof(int)); if(DEBUG_MEM){ printf("\n%d:attach req:sending id %d \n",armci_me,id);fflush(stdout); } armci_send_req(armci_master, msginfo, bufsize,0); buf= armci_rcv_data(armci_master,msginfo,sizeof(void *));/* receive response */ if(DEBUG_MEM){ printf("\n%d:attach req:got %p \n",armci_me,buf);fflush(stdout); } FREE_SEND_BUFFER(msginfo); ARMCI_PR_DBG("exit",0); return (void *)buf; }
void armci_vector_to_buf(armci_giov_t darr[], int len, void* buf) { int i,s; char *ptr = (char*)buf; for(i = 0; i< len; i++){ for( s=0; s< darr[i].ptr_array_len; s++){ armci_copy(darr[i].src_ptr_array[s],ptr,darr[i].bytes); ptr += darr[i].bytes; } } }
int armci_copy_vector(int op, /* operation code */ armci_giov_t darr[], /* descriptor array */ int len, /* length of descriptor array */ int proc /* remote process(or) ID */ ) { int i,s,shmem= SAMECLUSNODE(proc); int armci_th_idx = ARMCI_THREAD_IDX; if(shmem){ /* local/shared memory copy */ for(i = 0; i< len; i++){ for( s=0; s< darr[i].ptr_array_len; s++){ armci_copy(darr[i].src_ptr_array[s],darr[i].dst_ptr_array[s],darr[i].bytes); } } }else { switch(op){ case PUT: for(i = 0; i< len; i++){ UPDATE_FENCE_STATE(proc, PUT, darr[i].ptr_array_len); for( s=0; s< darr[i].ptr_array_len; s++){ armci_put(darr[i].src_ptr_array[s],darr[i].dst_ptr_array[s], darr[i].bytes, proc); } } break; case GET: for(i = 0; i< len; i++){ for( s=0; s< darr[i].ptr_array_len; s++){ armci_get(darr[i].src_ptr_array[s],darr[i].dst_ptr_array[s], darr[i].bytes,proc); } } break; default: armci_die("armci_copy_vector: wrong optype",op); } } return 0; }
/*\ Release mutex "id" held by proc * called from hrecv/AM handler AND application thread \*/ int armci_server_unlock_mutex(int mutex, int proc, int Ticket, msg_tag_t* ptag) { #define NOBODY -1 int owner = armci_me; int i, p=NOBODY, *mutex_ticket= glob_mutex[owner].turn + mutex; int len=sizeof(int); if(DEBUG) fprintf(stderr,"SUNLOCK=%d node=%d mutex=%d ticket=%d\n", armci_me,proc,mutex,Ticket); Ticket++; armci_copy(&Ticket, mutex_ticket, len); /* if mutex is free then nobody is reqistered in queue */ if(armci_mutex_free(mutex, proc)) return -1; /* search for the next process in queue waiting for this mutex */ for(i=0; i< armci_nproc; i++) { if(!blocked)break; /* not allocated yet - nobody is waiting */ if(DEBUG)fprintf(stderr,"SUNLOCK=%d node=%d list=(%d,%d)\n", armci_me, i, blocked[i].mutex, blocked[i].turn); if((blocked[i].mutex == mutex) && (blocked[i].turn == Ticket)) { p = i; break; } } /* send Ticket to a process waiting for mutex */ if(p != NOBODY) { if(p == armci_me)armci_die("server_unlock: cannot unlock self",0); else { if(DEBUG)fprintf(stderr,"SUNLOCK=%d node=%d unlock ticket=%d go=%d\n", armci_me, proc, Ticket, p); /* GA_SEND_REPLY(blocked[p].tag, &Ticket, sizeof(int), p); */ *ptag = blocked[p].tag; return p; } } return -1; /* nobody is waiting */ }
/*\ Acquire mutex for "proc" * -must be executed in hrecv/AM handler thread * -application thread must use generic_lock routine \*/ int armci_server_lock_mutex(int mutex, int proc, msg_tag_t tag) { int myturn; int *mutex_ticket, next_in_line, len=sizeof(int); int owner = armci_me; if(DEBUG)fprintf(stderr,"SLOCK=%d owner=%d p=%d m=%d\n", armci_me,owner, proc,mutex); mutex_ticket= glob_mutex[owner].turn + mutex; myturn = register_in_mutex_queue(mutex, owner); armci_copy(mutex_ticket, &next_in_line, len); if(next_in_line > myturn) armci_die2("armci-s: problem with tickets",myturn,next_in_line); if(next_in_line != myturn) { if(!blocked)armci_serv_mutex_create(); blocked[proc].mutex = mutex; blocked[proc].turn = myturn; blocked[proc].tag = tag; if(DEBUG) fprintf(stderr,"SLOCK=%d proc=%d blocked (%d,%d)\n", armci_me, proc, next_in_line,myturn); return -1; } else { if(DEBUG) fprintf(stderr,"SLOCK=%d proc=%d sending ticket (%d)\n", armci_me, proc, myturn); /* send ticket to requesting node */ /* GA_SEND_REPLY(tag, &myturn, sizeof(int), proc); */ return (myturn); } }
/*\ * for server thread to know which region is what in cases where there is one * process per node \*/ void armci_global_region_exchange(void *start, long size) { #ifdef REGIONS_REQUIRE_MEMHDL ARMCI_MEMHDL_T *hdlarr; hdlarr = calloc(armci_nclus,sizeof(ARMCI_MEMHDL_T)); #endif if(!allow_pin)return; if(armci_nclus<=1)return; armci_region_exchange(start,size); #ifdef REGIONS_REQUIRE_MEMHDL { int foundclus=0, foundserv=0, i,loc=0; armci_reglist_t *reglist=NULL,*clreglist=NULL; armci_region_t *reg=NULL; foundclus=armci_region_clus_found(armci_clus_me, start,size); foundserv=armci_region_serv_found(armci_clus_me, start,size); if(foundclus==-1){ foundclus = armci_region_loc_found(start,size); loc=1; } if(foundclus!=-1 && foundserv==-1){ reglist = (serv_regions+armci_clus_me); if(loc) clreglist = &(loc_regions_arr); else clreglist = (clus_regions+armci_clus_me); #if defined(DATA_SERVER) || defined(PORTALS) # if defined(PORTALS) ((reglist->list+reglist->n)->memhdl).regid=(reglist->n); # endif armci_serv_register_req((clreglist->list+foundclus)->start,((char *)(clreglist->list+foundclus)->end-(char *)((clreglist->list+foundclus)->start)),&((reglist->list+reglist->n)->memhdl)); #endif (void)armci_region_record((clreglist->list+foundclus)->start,(clreglist->list+foundclus)->end,reglist); #ifdef LAPI_RDMA armci_copy(&(clreglist->list+foundclus)->memhdl, &(reglist->list+foundclus)->memhdl, sizeof(ARMCI_MEMHDL_T)); #endif #if DEBUG printf("\n%d:serv recording st=%p end=%p sz=%d from %d n=%d sz=%d\n",armci_me,(clreglist->list+foundclus)->start,(clreglist->list+foundclus)->end,(clreglist->list+foundclus)->end-(clreglist->list+foundclus)->start,armci_clus_me,reglist->n,sizeof(ARMCI_MEMHDL_T));fflush(stdout); #endif foundserv=armci_region_serv_found(armci_clus_me, start,size); reg = (serv_regions+armci_clus_me)->list+foundserv; } if(reg) armci_copy(®->memhdl,&hdlarr[armci_clus_me],sizeof(ARMCI_MEMHDL_T)); i = armci_nclus*sizeof(ARMCI_MEMHDL_T)/sizeof(int); armci_msg_gop_scope(SCOPE_ALL,hdlarr,i,"+",ARMCI_INT); for(i=0; i<armci_nclus; i++){ armci_reglist_t *r=serv_regions+i; armci_reglist_t *rc=clus_regions+i; if(i==armci_clus_me) continue; if((rc->list+r->n)->start){ #if 0 printf("\n%d:serv recording %p from %d n=%d \n",armci_me,(rc->list+r->n)->start,i,r->n);fflush(stdout); #endif armci_copy(&hdlarr[i],&(r->list+r->n)->memhdl,sizeof(ARMCI_MEMHDL_T)); armci_region_record((rc->list+r->n)->start,(rc->list+r->n)->end,r); } } } #endif }
/*\ save a part of vector descriptor needed to complete request \*/ void armci_save_vector_dscr(char **bptr,armci_giov_t darr[],int len, int op,int is_nb, int proc) { int i,size=sizeof(int); BUF_INFO_T *info; char *buf,*bufptr=*bptr; void *rem_ptr; long offst; ARMCI_PR_DBG("enter",0); if(is_nb){ for(i=0;i<len;i++){ size+=(2*sizeof(int)+darr[i].ptr_array_len * sizeof(void*)); } info=BUF_TO_BUFINFO(bufptr); /*if descr fits in available buffer, use it else do malloc */ if(size<=UBUF_LEN){ buf = info->dscr; info->protocol=VDSCR_IN_PLACE; } else { info->ptr.dscrbuf = (void *)malloc(size); buf = (char *)info->ptr.dscrbuf; info->protocol=VDSCR_IN_PTR; } } else buf=bufptr; ADDBUF(buf,long,len); /* number of sets */ for(i=0;i<len;i++){ int j; ADDBUF(buf,int,darr[i].ptr_array_len); /* number of elements */ ADDBUF(buf,int,darr[i].bytes); /* sizeof element */ if(op==GET) { if(is_nb){ rem_ptr = darr[i].dst_ptr_array; } else { # ifdef PORTALS_UNRESOLVED for(j=0;j<darr[i].ptr_array_len;j++){ offst=x_net_offset(darr[i].src_ptr_array[j],proc); darr[i].src_ptr_array[j]= (char*)darr[i].src_ptr_array[j]+offst; } # endif rem_ptr = darr[i].src_ptr_array; } } else { # ifdef PORTALS_UNRESOLVED for(j=0;j<darr[i].ptr_array_len;j++){ offst=x_net_offset(darr[i].dst_ptr_array[j],proc); darr[i].dst_ptr_array[j]= (char*)darr[i].dst_ptr_array[j]+offst; } # endif rem_ptr = darr[i].dst_ptr_array; } armci_copy(rem_ptr,buf, darr[i].ptr_array_len * sizeof(void*)); buf += darr[i].ptr_array_len*sizeof(void*); } if(!is_nb) *bptr=buf; ARMCI_PR_DBG("exit",0); }