/*\ master exports its address of shmem region at the beggining of that region \*/ static void armci_master_exp_attached_ptr(void* ptr) { ARMCI_PR_DBG("enter",0); if(!ptr) armci_die("armci_master_exp_att_ptr: null ptr",0); *(volatile void**)ptr = ptr; ARMCI_PR_DBG("exit",0); }
/*\ 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); }
/**Free a pending buffer * @param pbuf IN Pointer to Pending buffer to be freed * @return none */ static void _armci_serv_pendbuf_freebuf(pendbuf_t *pbuf){ const request_header_t *msginfo = (request_header_t *)pbuf->buf; proc_waitlist_t *info = &pbuf_proc_list_info[msginfo->from]; ARMCI_PR_DBG("enter",0); assert(pbuf != NULL); pbuf->avail=1; pbuf->status = -1; pbuf->vbuf = NULL; /* assert(info->waiting_on == pbuf); */ /* info->waiting_on = NULL; */ if(pbuf->order_prev) pbuf->order_prev->order_next = pbuf->order_next; if(pbuf->order_next) pbuf->order_next->order_prev = pbuf->order_prev; if(info->order_head == pbuf) { assert(pbuf->order_prev == NULL); info->order_head = pbuf->order_next; } if(info->order_tail == pbuf) { assert(pbuf->order_next == NULL); info->order_tail = pbuf->order_prev; } pbuf->order_prev = pbuf->order_next = NULL; /*not necessary here*/ _nPendBufsUsed -= 1; assert(_nPendBufsUsed>=0); ARMCI_PR_DBG("exit",0); }
/*\ Routine called from buffers.c to complete a request for which the buffer was * used for, so that the buffer can be reused. \*/ void armci_complete_req_buf(BUF_INFO_T *info, void *buffer) { request_header_t *msginfo = (request_header_t*) buffer; ARMCI_PR_DBG("enter",0); if(info->protocol==0)return; else if(info->protocol==SDSCR_IN_PLACE){ char *dscr = info->dscr; void *loc_ptr; int stride_levels; int *loc_stride_arr,*count; loc_ptr = *(void**)dscr; dscr += sizeof(void*); stride_levels = *(int*)dscr; dscr += sizeof(int); loc_stride_arr = (int*)dscr; dscr += stride_levels*sizeof(int); count = (int*)dscr; if(0 || DEBUG_){ if(armci_me==0){ printf("\n%d:extracted loc_ptr=%p, stridelevels=%d\n",armci_me, loc_ptr,stride_levels); fflush(stdout); } } armci_rcv_strided_data(msginfo->to, msginfo, msginfo->datalen, loc_ptr, stride_levels,loc_stride_arr,count); FREE_SEND_BUFFER(msginfo); } else if(info->protocol==VDSCR_IN_PLACE || info->protocol==VDSCR_IN_PTR){ char *dscr; int len,i; if(info->protocol==VDSCR_IN_PLACE){ dscr = info->dscr; //printf("\n%d:vdscr in place\n",armci_me); } else { dscr = info->ptr.dscrbuf; //printf("\n%d:vdscr in buf\n",armci_me); } GETBUF(dscr, long ,len); { armci_giov_t *darr; darr = (armci_giov_t *)malloc(sizeof(armci_giov_t)*len); if(!darr)armci_die("malloc in complete_req_buf failed",len); for(i = 0; i< len; i++){ int parlen, bytes; GETBUF(dscr, int, parlen); GETBUF(dscr, int, bytes); darr[i].ptr_array_len = parlen; darr[i].bytes = bytes; if(msginfo->operation==GET)darr[i].dst_ptr_array=(void **)dscr; else darr[i].src_ptr_array=(void **)dscr; dscr+=sizeof(void *)*parlen; } if (msginfo->operation==GET) armci_complete_vector_get(darr,len,buffer); } } else armci_die("armci_complete_req_buf,protocol val invalid",info->protocol); ARMCI_PR_DBG("exit",0); }
int PARMCI_Free(void *ptr) { ARMCI_PR_DBG("enter",0); if(!ptr)return 1; ARMCI_PR_DBG("exit",0); return 0; }
/** Enqueue a message. It could be an immediate message that cannot * make progress or a non-immediate message that cannot make progress * either due to ordering constraints or lack of pending buffers. * @param vbuf IN Immediate buffer to be enqueud * @return Pending buffer into which the message was enqueued. NULL * if no pending buffer was allocated (which is always the case for * immediate messages) */ static pendbuf_t* _armci_serv_pendbuf_enqueue(immbuf_t *vbuf) { request_header_t *msginfo=(request_header_t *)vbuf->buf; int from = msginfo->from; pendbuf_t *pbuf; immbuf_t *ibuf; proc_waitlist_t *info = &pbuf_proc_list_info[msginfo->from]; ARMCI_PR_DBG("enter",0); /* printf("%d: Entered serv_pbuf_enqueue\n", armci_me); */ pbuf=NULL; if(msginfo->tag.imm_msg) { assert(!_armci_serv_pendbuf_can_progress(vbuf)); } else if(_armci_serv_pendbuf_can_progress(vbuf)) { pbuf = _armci_serv_pendbuf_assignbuf(vbuf); assert(pbuf != NULL); /*can_progress() should ensure this*/ } if(pbuf == NULL) { /* printf("%d(s):: Enqueing op=%d imm=%d from %d. n_pending=%d\n", armci_me, msginfo->operation, msginfo->tag.imm_msg, msginfo->from,info->n_pending); */ /* fflush(stdout); */ vbuf->immbuf_list_next = NULL; assert(info->n_pending < IMM_BUF_NUM); /*How another message now?*/ for(ibuf=info->immbuf_wlist_head;ibuf!=NULL;ibuf=ibuf->immbuf_list_next) { assert(vbuf != ibuf); /*enqueueing the same buffer twice*/ } info->n_pending += 1; if(!info->immbuf_wlist_head) { assert(!info->immbuf_wlist_tail); assert(!info->prev && !info->next); /*insert proc into proc list*/ if(!pbuf_ordering_plist_head) { pbuf_ordering_plist_head=info->next=info->prev=info; } else { info->next = pbuf_ordering_plist_head; info->prev = pbuf_ordering_plist_head->prev; pbuf_ordering_plist_head->prev->next = info; pbuf_ordering_plist_head->prev = info; } } /*insert vbuf into immbuf list for this proc*/ if(info->immbuf_wlist_tail) info->immbuf_wlist_tail->immbuf_list_next=vbuf; info->immbuf_wlist_tail = vbuf; if(!info->immbuf_wlist_head) info->immbuf_wlist_head = vbuf; } /* printf("%d: Leaving serv_pbuf_enqueue\n", armci_me); */ ARMCI_PR_DBG("exit",0); return pbuf; }
/** Goes through the set of immediate buffers waiting to be processed * and completed, and identifies a buffer that can be processed * now. Removes it from the list and returns it. Promote also * considers availability of pending buffers if need be. * @return Pointer to buffer that can be processed now. NULL if none exists. */ static immbuf_t* _armci_serv_pendbuf_promote() { immbuf_t *immbuf = NULL; proc_waitlist_t *info; ARMCI_PR_DBG("enter",0); assert(_nPendBufsUsed>=0); if(!pbuf_ordering_plist_head) { return NULL; /*nothing to promote*/ } info = pbuf_ordering_plist_head; do { if(info->immbuf_wlist_head==NULL) { printf("%d(s): Why is info->immbuf_wlist_head NULL\n", armci_me); fflush(stdout); pause(); } assert(info->immbuf_wlist_head!=NULL); assert(info->n_pending>0); if(_armci_serv_pendbuf_can_progress(info->immbuf_wlist_head)) { immbuf = info->immbuf_wlist_head; info->immbuf_wlist_head = immbuf->immbuf_list_next; info->n_pending -= 1; immbuf->immbuf_list_next = NULL; if(!info->immbuf_wlist_head) { assert(info->immbuf_wlist_tail == immbuf); info->immbuf_wlist_tail = NULL; /*remove this proc from proc list*/ info->prev->next = info->next; info->next->prev = info->prev; if(pbuf_ordering_plist_head == info) { pbuf_ordering_plist_head = (info->next==info)?NULL:info->next; } info->prev = info->next = NULL; } break; } info = info->next; } while(info != pbuf_ordering_plist_head); if(DEBUG_SERVER) if(immbuf) { request_header_t *msginfo=(request_header_t*)immbuf->buf; printf("%d:: promoting a buffer immbuf=%p op=%d from=%d n_pending=%d\n", armci_me,immbuf,msginfo->operation,msginfo->from,info->n_pending); fflush(stdout); } ARMCI_PR_DBG("exit",0); return immbuf; }
/*\ ************** Begin Group Collective Memory Allocation ****************** * returns array of pointers to blocks of memory allocated by everybody * Note: as the same shared memory region can be mapped at different locations * in each process address space, the array might hold different values * on every process. However, the addresses are legitimate * and can be used in the ARMCI data transfer operations. * ptr_arr[nproc] \*/ int ARMCI_Malloc_group(void *ptr_arr[], armci_size_t bytes, ARMCI_Group *group) { void *ptr; int grp_me, grp_nproc; ARMCI_PR_DBG("enter",0); ARMCI_Group_size(group, &grp_nproc); ARMCI_Group_rank(group, &grp_me); if(DEBUG_)fprintf(stderr,"%d (grp_id=%d) bytes in armci_malloc_group %d\n", armci_me, grp_me, (int)bytes); ARMCI_PR_DBG("exit",0); return(0); }
void armci_altix_shm_malloc(void *ptr_arr[], armci_size_t bytes) { long size=bytes; void *ptr; int i; ARMCI_PR_DBG("enter",0); armci_msg_lgop(&size,1,"max"); ptr=kr_malloc((size_t)size, &altix_ctx_shmem); bzero(ptr_arr,(armci_nproc)*sizeof(void*)); ptr_arr[armci_me] = ptr; if(size!=0 && ptr==NULL) armci_die("armci_altix_shm_malloc(): malloc failed", armci_me); for(i=0; i< armci_nproc; i++) if(i!=armci_me) ptr_arr[i]=shmem_ptr(ptr,i); ARMCI_PR_DBG("exit",0); }
void armci_server_region_destroy() { armci_reglist_t *reg; int i; #ifdef REGIONS_REQUIRE_MEMHDL ARMCI_MEMHDL_T *loc_memhdl; ARMCI_PR_DBG("enter",0); reg=serv_regions+armci_clus_me; for(i=0; i<reg->n; i++){ loc_memhdl=&((reg->list+i)->memhdl); armci_network_server_deregister_memory(loc_memhdl); } ARMCI_PR_DBG("exit",0); #endif }
static void armci_region_register(void *start, long size, armci_reglist_t *reg) { int regid; ARMCI_PR_DBG("enter",0); if(reg->n >= MAX_REGIONS) return; if(armci_nclus<=1)return; regid = reg->n; #ifdef REGIONS_REQUIRE_MEMHDL # if defined(PORTALS) /*we really shouldn't have network specific ifdef's here but this is an * exception to avoid significant code change in the portals layer * ARMCI portals layer maintains a list of memory descriptors for each * region allocated. It uses them in a round robin fashion. We store it * in the memhdl to identify which memory region the memory used by a * communication call corresponds to. */ (reg->list+(regid))->memhdl.regid=regid; # endif if(!armci_pin_contig_hndl(start, size, &((reg->list+reg->n)->memhdl))){ printf("%d pin failed %p bytes=%ld\n",armci_me,start,size); fflush(stdout); return; } #else if(!armci_pin_contig1(start, size)){ printf("%d pin failed %p bytes=%ld\n",armci_me,start,size); fflush(stdout); return; } #endif (void) armci_region_record(start,((char*)start)+size,reg); }
/*\ send RMW request to server \*/ void armci_rem_rmw(int op, int *ploc, int *prem, int extra, int proc) { request_header_t *msginfo; char *buf; void *buffer; int bufsize = sizeof(request_header_t)+sizeof(long)+sizeof(void*); long offst; ARMCI_PR_DBG("enter",0); msginfo = (request_header_t*)GET_SEND_BUFFER(bufsize,op,proc); bzero(msginfo,sizeof(request_header_t)); msginfo->dscrlen = sizeof(void*); msginfo->from = armci_me; msginfo->to = proc; msginfo->operation = op; msginfo->datalen = sizeof(long); # ifdef PORTALS_UNRESOLVED offst=x_net_offset(prem,proc); prem = (int *)((char *)prem+offst); # endif buf = (char*)(msginfo+1); ADDBUF(buf, void*, prem); /* pointer is shipped as descriptor */ /* data field: extra argument in fetch&add and local value in swap */ if(op==ARMCI_SWAP){ ADDBUF(buf, int, *ploc); }else if(op==ARMCI_SWAP_LONG) {
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; }
/*\ based on address for set by master, determine correction for * memory addresses set in memlock table * if the correction/offset ever changes stop using memlock table locking \*/ void armci_set_mem_offset(void *ptr) { extern size_t armci_mem_offset; size_t off; static int first_time=1; volatile void *ref_ptr; ARMCI_PR_DBG("enter",0); /* do not care if memlock not used */ if(! *armci_use_memlock_table) return; if(!ptr) armci_die("armci_set_mem_offset : null ptr",0); ref_ptr = *(void**)ptr; off = (size_t)((char*)ref_ptr - (char*)ptr); if(first_time){ armci_mem_offset =off; first_time =0; if(DEBUG_){ printf("%d memlock offset=%ld ref=%p ptr=%p\n",armci_me, (long)armci_mem_offset, ref_ptr, ptr); fflush(stdout); } }else{ if(armci_mem_offset != off){ *armci_use_memlock_table =0; fprintf(stderr, "%d: WARNING:armci_set_mem_offset: offset changed %ld to %ld\n", armci_me, (long)armci_mem_offset, (long)off); fflush(stdout); } } }
void armci_generic_rmw(int op, void *ploc, void *prem, int extra, int proc) { #if defined(CLUSTER) && !defined(SGIALTIX) int lock = (proc-armci_clus_info[armci_clus_id(proc)].master)%NUM_LOCKS; #else int lock = 0; #endif ARMCI_PR_DBG("enter",0); NATIVE_LOCK(lock,proc); switch (op) { case ARMCI_FETCH_AND_ADD: armci_get(prem,ploc,sizeof(int),proc); _a_temp = *(int*)ploc + extra; armci_put(&_a_temp,prem,sizeof(int),proc); break; case ARMCI_FETCH_AND_ADD_LONG: armci_get(prem,ploc,sizeof(long),proc); _a_ltemp = *(long*)ploc + extra; armci_put(&_a_ltemp,prem,sizeof(long),proc); break; case ARMCI_SWAP: #if (defined(__i386__) || defined(__x86_64__)) if(SERVER_CONTEXT || armci_nclus==1){ atomic_exchange(ploc, prem, sizeof(int)); } else #endif { armci_get(prem,&_a_temp,sizeof(int),proc); armci_put(ploc,prem,sizeof(int),proc); *(int*)ploc = _a_temp; } break; case ARMCI_SWAP_LONG: armci_get(prem,&_a_ltemp,sizeof(long),proc); armci_put(ploc,prem,sizeof(long),proc); *(long*)ploc = _a_ltemp; break; default: armci_die("rmw: operation not supported",op); } /*TODO memfence here*/ NATIVE_UNLOCK(lock,proc); ARMCI_PR_DBG("exit",0); }
void armci_region_init() { ARMCI_PR_DBG("enter",0); allow_pin =1; clus_regions=(armci_reglist_t*)calloc(armci_nclus,sizeof(armci_reglist_t)); if(!clus_regions)armci_die("armci_region_init: calloc failed",armci_nclus); #ifdef REGIONS_REQUIRE_MEMHDL serv_regions=(armci_reglist_t*)calloc(armci_nclus,sizeof(armci_reglist_t)); if(!serv_regions)armci_die("armci_region_init: calloc failed",armci_nclus); #endif exch_list = (void**)calloc(2*armci_nclus, sizeof(void*)); if(!exch_list) armci_die("armci_region_init: calloc 2 failed",armci_nclus); bzero(exch_loc,sizeof(exch_loc)); bzero(exch_rem,sizeof(exch_rem)); if(needs_pin_ptr) armci_region_register_loc(needs_pin_ptr,needs_pin_size); if(needs_pin_shmptr) armci_region_register_shm(needs_pin_shmptr,needs_pin_shmsize); ARMCI_PR_DBG("exit",0); }
void armci_print_ptr(void **ptr_arr, int bytes, int size, void* myptr, int off) { int i; int nproc = armci_clus_info[armci_clus_me].nslave; ARMCI_PR_DBG("enter",0); for(i=0; i< armci_nproc; i++){ int j; if(armci_me ==i){ printf("%d master =%d nproc=%d off=%d\n",armci_me, armci_master,nproc, off); printf("%d:bytes=%d mptr=%p s=%d ",armci_me, bytes, myptr,size); for(j = 0; j< armci_nproc; j++)printf(" %p",ptr_arr[j]); printf("\n"); fflush(stdout); } armci_msg_barrier(); } ARMCI_PR_DBG("exit",0); }
void armci_altix_shm_malloc_group(void *ptr_arr[], armci_size_t bytes, ARMCI_Group *group) { long size=bytes; void *ptr; int i,grp_me, grp_nproc; armci_grp_attr_t *grp_attr=ARMCI_Group_getattr(group); ARMCI_PR_DBG("enter",0); ARMCI_Group_size(group, &grp_nproc); ARMCI_Group_rank(group, &grp_me); armci_msg_group_lgop(&size,1,"max",group); ptr=kr_malloc((size_t)size, &altix_ctx_shmem_grp); if(size!=0 && ptr==NULL) armci_die("armci_altix_shm_malloc_group(): malloc failed for groups. Increase _SHMMAX_ALTIX_GRP", armci_me); bzero(ptr_arr,(grp_nproc)*sizeof(void*)); ptr_arr[grp_me] = ptr; for(i=0; i< grp_nproc; i++) if(i!=grp_me) ptr_arr[i]=shmem_ptr(ptr,ARMCI_Absolute_id(group, i)); ARMCI_PR_DBG("exit",0); }
/*\ save a part of strided descriptor needed to complete request rmo: it seems as if save_ \*/ void armci_save_strided_dscr(char **bptr, void *rem_ptr,int rem_stride_arr[], int count[], int stride_levels,int is_nb,int proc) { int i; char *bufptr=*bptr; BUF_INFO_T *info=NULL; long network_offset,tmpoffset; ARMCI_PR_DBG("enter",0); # ifdef PORTALS_UNRESOLVED if(!is_nb){ network_offset=x_net_offset(rem_ptr,proc); if(DEBUG_){printf("\n%d:rem_ptr=%p offset=%d newrem=%p",armci_me,rem_ptr,network_offset,(char *)rem_ptr+network_offset);fflush(stdout);} rem_ptr = (char *)rem_ptr+network_offset; } # endif if(is_nb){ info=BUF_TO_BUFINFO(*bptr); bufptr = (info->dscr); } *(void**)bufptr = rem_ptr; bufptr += sizeof(void*); *(int*)bufptr = stride_levels; bufptr += sizeof(int); for(i=0;i<stride_levels;i++)((int*)bufptr)[i] = rem_stride_arr[i]; bufptr += stride_levels*sizeof(int); for(i=0;i< stride_levels+1;i++)((int*)bufptr)[i] = count[i]; bufptr += (1+stride_levels)*sizeof(int); if((0 || DEBUG_) && is_nb){ bufptr = (info->dscr); if(armci_me==0) printf("\n%d:rem_ptr %p=%p stride_levels %d=%d\n",armci_me, *(void**)bufptr,rem_ptr, *(int*)(bufptr + sizeof(void*)),stride_levels); } /*remote_strided expects the pointer to point to the end of descr hence..*/ if(is_nb) info->protocol=SDSCR_IN_PLACE; else *bptr=bufptr; ARMCI_PR_DBG("exit",0); }
/** Initialize array of pending buffers * @return none */ void armci_pendbuf_init() { int i; ARMCI_PR_DBG("enter",0); /* bzero(serv_pendbuf_arr, sizeof(pendbuf_t)*PENDING_BUF_NUM); */ for(i=0; i<PENDING_BUF_NUM; i++) { pendbuf_t *pbuf = &serv_pendbuf_arr[i]; char *buf = pbuf->buf; bzero(pbuf, sizeof(pendbuf_t)); pbuf->buf = buf; pbuf->avail=1; } pbuf_ordering_plist_head=NULL; pbuf_proc_list_info = (proc_waitlist_t *)malloc(sizeof(proc_waitlist_t)*armci_nproc); assert(pbuf_proc_list_info != NULL); bzero(pbuf_proc_list_info, sizeof(proc_waitlist_t)*armci_nproc); ARMCI_PR_DBG("exit",0); }
void armci_server_lock(request_header_t *msginfo) { int *ibuf = (int*)(msginfo+1); int proc = msginfo->from; int mutex; int ticket; ARMCI_PR_DBG("enter",0); mutex = *(int*)ibuf; /* acquire lock on behalf of requesting process */ ticket = armci_server_lock_mutex(mutex, proc, msginfo->tag); if(ticket >-1){ /* got lock */ msginfo->datalen = sizeof(int); armci_send_data(msginfo, &ticket); } ARMCI_PR_DBG("exit",0); }
void armci_altix_shm_init() { ARMCI_PR_DBG("enter",0); altix_pagesize = getpagesize(); kr_malloc_init(SHM_UNIT, _SHMMAX_ALTIX, 0, armci_altix_allocate, 0, &altix_ctx_shmem); kr_malloc_init(SHM_UNIT, _SHMMAX_ALTIX_GRP, _SHMMAX_ALTIX_GRP, armci_altix_allocate, 0, &altix_ctx_shmem_grp); /* allocate a huge segment for groups. When kr_malloc() is called for the first time for this altix_ctx_shmem_grp context with some minimal size of 8 bytes, a huge segment of size (SHM_UNIT*_SHMMAX_ALTIX_GRP) will be created */ { void *ptr; ptr=kr_malloc((size_t)8, &altix_ctx_shmem_grp); if(ptr==NULL) armci_die("armci_altix_shm_init(): malloc failed", armci_me); } ARMCI_PR_DBG("exit",0); }
void *armci_altix_allocate(size_t bytes) { void *ptr, *sptr; ARMCI_PR_DBG("enter",0); sptr=ptr= shmalloc(bytes); if(sptr == NULL) armci_die("armci_altix_allocate: shmalloc failed\n", armci_me); armci_memoffset_table_newentry(ptr, bytes); #if 0 if(ptr){ /* touch each page to establish ownership */ int i; for(i=0; i< bytes/altix_pagesize; i++){ *(double*)ptr=0.; ((char*)ptr) += altix_pagesize; } } #endif ARMCI_PR_DBG("exit",0); return sptr; }
int armci_region_loc_found(void *start, int size) { armci_reglist_t *reg = &loc_regions_arr; int i,found=-1; ARMCI_PR_DBG("enter",0); if(!allow_pin) return 0; for(i=0; i<reg->n; i++) if((reg->list+i)->start <= start && (reg->list+i)->end > start){ found=i; break; } #ifdef DEBUG if(found){ printf("%d: found loc %d n=%ld (%p,%p) %p\n",armci_me,found,reg->n, (reg->list)->start,(reg->list)->end, start); fflush(stdout); } #endif ARMCI_PR_DBG("exit",0); return(found); }
/*\ server actions triggered by client request to ATTACH \*/ void armci_server_ipc(request_header_t* msginfo, void* descr, void* buffer, int buflen) { double *ptr; long *idlist = (long*)descr; long size = *(long*)buffer; int rlen = *(int*)(sizeof(long)+(char*)buffer); extern int **_armci_int_mutexes; ARMCI_PR_DBG("enter",0); if(size<0) armci_die("armci_server_ipc: size<0",(int)size); if(DEBUG_MEM)printf("\n%d:got idlist+1 %p, size %d, idlist[0] %d, idlist[1] %d",armci_me,idlist+1,size,idlist[0],idlist[1]); ptr=(double*)Attach_Shared_Region(idlist+1,size,idlist[0]); if(!ptr)armci_die("armci_server_ipc: failed to attach",0); /* provide data server with access to the memory lock data structures */ if(allocate_memlock){ allocate_memlock = 0; server_alloc_memlock(ptr); } if(_armci_int_mutexes==NULL){ printf("unresolved portals external\n"); abort(); # ifdef PORTALS_UNRESOLVED extern int _armci_server_mutex_ready; extern void *_armci_server_mutex_ptr; if(_armci_server_mutex_ready){ _armci_int_mutexes=(int **)_armci_server_mutex_ptr; } # endif } if(size>0)armci_set_mem_offset(ptr); if(msginfo->datalen != sizeof(long)+sizeof(int)) armci_die("armci_server_ipc: bad msginfo->datalen ",msginfo->datalen); if(rlen==sizeof(ptr)){ msginfo->datalen = rlen; armci_send_data(msginfo, &ptr); } else armci_die("armci_server_ipc: bad rlen",rlen); ARMCI_PR_DBG("exit",0); }
int ARMCI_Free_group(void *ptr, ARMCI_Group *group) { int grp_me, grp_nproc, grp_master, grp_clus_me; armci_grp_attr_t *grp_attr=ARMCI_Group_getattr(group); ARMCI_PR_DBG("enter",0); if(!ptr)return 1; ARMCI_Group_size(group, &grp_nproc); ARMCI_Group_rank(group, &grp_me); if(grp_me == MPI_UNDEFINED) { /* check if the process is in this group */ armci_die("armci_malloc_group: process is not a member in this group", armci_me); } /* get the group cluster info */ grp_clus_me = grp_attr->grp_clus_me; grp_master = grp_attr->grp_clus_info[grp_clus_me].master; ARMCI_PR_DBG("exit",0); return 0; }
int ARMCI_Uses_shm_grp(ARMCI_Group *group) { int uses=0, grp_me, grp_nproc, grp_nclus; ARMCI_PR_DBG("enter",0); armci_grp_attr_t *grp_attr=ARMCI_Group_getattr(group); ARMCI_Group_size(group, &grp_nproc); ARMCI_Group_rank(group, &grp_me); grp_nclus = grp_attr->grp_nclus; #if (defined(SYSV) || defined(WIN32) || defined(MMAP) ||defined(HITACHI)) \ && !defined(NO_SHM) # ifdef RMA_NEEDS_SHMEM if(grp_nproc >1) uses= 1; /* always unless serial mode */ # else if(grp_nproc != grp_nclus)uses= 1; /* only when > 1 node used */ # endif #endif if(DEBUG_) fprintf(stderr,"%d (grp_id=%d):uses shmem %d\n",armci_me, grp_me, uses); ARMCI_PR_DBG("exit",0); return uses; }
void CreateInitLocks(int num_locks, lockset_t *plockid) { int locks_per_proc, size; extern void armci_set_serv_mutex_arr(void *); ARMCI_PR_DBG("enter",0); ptr_arr = (void**)malloc(armci_nproc*sizeof(void*)); locks_per_proc = (num_locks*armci_nclus)/armci_nproc + 1; size=locks_per_proc*sizeof(PAD_LOCK_T); PARMCI_Malloc(ptr_arr, size); _armci_int_mutexes = (PAD_LOCK_T*) ptr_arr[armci_master]; # ifdef PORTALS_SPECIFIC_QUESTION if(armci_me==armci_master)armci_set_serv_mutex_arr(_armci_int_mutexes); # endif if(!_armci_int_mutexes) armci_die("Failed to create spinlocks",size); #ifdef PMUTEXES if(armci_me == armci_master) { int i; pthread_mutexattr_t pshared; if(pthread_mutexattr_init(&pshared)) armci_die("armci_allocate_locks: could not init mutex attr",0); # ifndef LINUX if(pthread_mutexattr_setpshared(&pshared,PTHREAD_PROCESS_SHARED)) armci_die("armci_allocate_locks: could not set PROCESS_SHARED",0); # endif for(i=0; i< locks_per_proc*armci_clus_info[armci_clus_me].nslave; i++){ if(pthread_mutex_init(_armci_int_mutexes+i,&pshared)) armci_die("armci_allocate_locks: could not init mutex",i); } } #else bzero((char*)ptr_arr[armci_me],size); ARMCI_PR_DBG("exit",0); #endif }
/**Get a buffer to process an incoming request with non-immediate * data. * @return Pointer to available pending buffer */ static void* _armci_serv_pendbuf_getbuf(){ int i; for(i=0; i<PENDING_BUF_NUM; i++) { if(serv_pendbuf_arr[i].avail) { serv_pendbuf_arr[i].status = INIT; serv_pendbuf_arr[i].avail=0; serv_pendbuf_arr[i].order_prev = NULL; serv_pendbuf_arr[i].order_next = NULL; serv_pendbuf_arr[i].commit_me = 0; /*fprintf(stderr, "%d:: getbuf returns idx=%d pbuf=%p\n", armci_me, i, &serv_pendbuf_arr[i]);*/ _nPendBufsUsed += 1; assert(_nPendBufsUsed<=PENDING_BUF_NUM); ARMCI_PR_DBG("exit",0); return &serv_pendbuf_arr[i]; } } return NULL; }
/*\ Collective Memory Allocation on shared memory systems \*/ void armci_shmem_malloc(void *ptr_arr[], armci_size_t bytes) { void *myptr=NULL, *ptr=NULL; long idlist[SHMIDLEN]; long size=0, offset=0; long *size_arr; void **ptr_ref_arr; int i,cn, len; int nproc = armci_clus_info[armci_clus_me].nslave; ARMCI_PR_DBG("enter",0); bzero((char*)ptr_arr,armci_nproc*sizeof(void*)); /* allocate work arrays */ size_arr = (long*)calloc(armci_nproc,sizeof(long)); if(!size_arr)armci_die("armci_malloc:calloc failed",armci_nproc); /* allocate arrays for cluster address translations */ # if defined(DATA_SERVER) len = armci_nclus; # else len = nproc; # endif ptr_ref_arr = calloc(len,sizeof(void*)); /* must be zero */ if(!ptr_ref_arr)armci_die("armci_malloc:calloc 2 failed",len); /* combine all memory requests into size_arr */ size_arr[armci_me] = bytes; armci_msg_lgop(size_arr, armci_nproc, "+"); /* determine aggregate request size on the cluster node */ for(i=0, size=0; i< nproc; i++) size += size_arr[i+armci_master]; /* master process creates shmem region and then others attach to it */ if(armci_me == armci_master ){ /* can malloc if there is no data server process and has 1 process/node*/ # ifndef RMA_NEEDS_SHMEM if(nproc == 1) myptr = kr_malloc(size, &ctx_localmem); else # endif myptr = Create_Shared_Region(idlist+1,size,idlist); if(!myptr && size>0 )armci_die("armci_malloc: could not create", (int)(size>>10)); /* place its address at begining of attached region for others to see */ if(size)armci_master_exp_attached_ptr(myptr); if(DEBUG_){ printf("%d:armci_malloc addr mptr=%p size=%ld\n",armci_me,myptr,size); fflush(stdout); } } /* broadcast shmem id to other processes on the same cluster node */ armci_msg_clus_brdcst(idlist, SHMIDLEN*sizeof(long)); if(armci_me != armci_master){ myptr=(double*)Attach_Shared_Region(idlist+1,size,idlist[0]); if(!myptr)armci_die("armci_malloc: could not attach", (int)(size>>10)); /* now every process in a SMP node needs to find out its offset * w.r.t. master - this offset is necessary to use memlock table */ if(size) armci_set_mem_offset(myptr); if(DEBUG_){ printf("%d:armci_malloc attached addr mptr=%p ref=%p size=%ld\n", armci_me,myptr, *(void**)myptr,size); fflush(stdout); } }