void armci_memoffset_table_newentry(void *ptr, size_t seg_size) { void **ptr_arr; void *master_addr = NULL; size_t tile_size=0, offset=0; if(!ptr) armci_die("armci_memoffset_table_newentry : null ptr",0); if(seg_count >= MAX_SEGS) /* CHECK: make it dynamic */ armci_die("armci_cary_allocate: Increase MAX_SEGS > 512", armci_me); if(armci_me == armci_master) master_addr = ptr; armci_msg_brdcst(&master_addr, sizeof(void*), armci_master); ptr_arr = (void**)malloc(armci_nproc*sizeof(void*)); armci_cray_gettilesize(ptr, ptr_arr, &tile_size); offset = (size_t)((char*)master_addr - (char*)ptr_arr[armci_master]); /* enter in memoffset table */ armci_memoffset_table[seg_count].seg_addr = ptr_arr[armci_master]; armci_memoffset_table[seg_count].seg_size = seg_size; armci_memoffset_table[seg_count].tile_size = tile_size; armci_memoffset_table[seg_count].mem_offset = offset; #if DEBUG_ printf("%d: addr=%p seg_size=%ld tile_size=%ld offset=%ld\n", armci_me, ptr_arr[armci_master], seg_size, tile_size, offset); #endif ++seg_count; free(ptr_arr); }
/*\ release lock to the memory area locked by previous call to armci_lockemem \*/ void armci_unlockmem(int proc) { #ifdef ARMCIX ARMCIX_Unlockmem (proc); #else void *null[2] = {NULL,NULL}; memlock_t *memlock_table; #ifdef CORRECT_PTR if(! *armci_use_memlock_table) { /* if offset invalid, use dumb locking scheme ignoring addresses */ armci_unlockmem_(proc); return; } #endif #ifdef DEBUG if(locked_slot == INVALID_VAL) armci_die("armci_unlock: empty",0); if(locked_slot >= MAX_SLOTS || locked_slot <0) armci_die("armci_unlock: corrupted slot?",locked_slot); #endif memlock_table = (memlock_t*)memlock_table_array[proc]; armci_put(null,&memlock_table[locked_slot].start,2*sizeof(void*),proc); #endif /* ! ARMCIX */ }
void* PARMCI_Memat(armci_meminfo_t *meminfo, long memflg) { void *ptr=NULL; if(meminfo==NULL) armci_die("PARMCI_Memget: Invalid arg #2 (NULL ptr)",0); if(memflg!=0) armci_die("PARMCI_Memget: Invalid memflg", memflg); if(meminfo->cpid==armci_me) { ptr = meminfo->addr; return ptr; } if( !ARMCI_Uses_shm()) { ptr = meminfo->addr; } else { ptr = armci_shmem_memat(meminfo); } if(DEBUG_) { printf("%d:PARMCI_Memat: attached addr mptr=%p size=%ld\n", armci_me, ptr, meminfo->size); fflush(stdout); } return ptr; }
static char* alloc_munmap(size_t size) { char *tmp; unsigned long iptr; size_t bytes = size+pagesize-1; if(armci_elan_starting_address){ tmp = armci_elan_starting_address; armci_elan_starting_address += size; # ifdef ALLOC_MUNMAP_ALIGN armci_elan_starting_address += ALLOC_MUNMAP_ALIGN; # endif if(DEBUG_) {printf("%d: address for shm attachment is %p size=%ld\n", armci_me,tmp,(long)size); fflush(stdout); } } else { tmp = ALGN_MALLOC(bytes, getpagesize()); if(tmp){ iptr = (unsigned long)tmp + pagesize-1; iptr >>= logpagesize; iptr <<= logpagesize; if(DEBUG_) printf("%d:unmap ptr=%p->%p size=%d pagesize=%d\n",armci_me, tmp,(char*)iptr,(int)size,pagesize); tmp = (char*)iptr; if(munmap(tmp, size) == -1) armci_die("munmap failed",0); if(DEBUG_){printf("%d: unmap OK\n",armci_me); fflush(stdout);} }else armci_die("alloc_munmap: malloc failed",(int)size); }
void armci_profile_init() { int i,j; if(armci_me==0) {printf("\nProfiling ARMCI - ON\n");fflush(stdout);} gCURRENT_EVNT.is_set = 0; for(i=0; i<ARMCI_EVENTS; i++) for(j=0; j<ARMCI_MAX_MSG_RANGE; j++) { ARMCI_PROF[i][j].count = 0; ARMCI_PROF[i][j].time = 0.0; } #if ARMCI_PRINT_STRIDE for(i=0; i<ARMCI_EVENTS; i++) { if(strided_event(i)) for(j=0; j<ARMCI_MAX_MSG_RANGE; j++) { ARMCI_PROF[i][j].stride = (armci_stride_t*)malloc(STRIDE_COUNT*sizeof(armci_stride_t)); ARMCI_PROF[i][j].vector = NULL; if( ARMCI_PROF[i][j].stride == NULL) armci_die("armci_profile_init(): malloc failed", armci_me); } if(i==ARMCI_PROF_GETV || i==ARMCI_PROF_PUTV || i==ARMCI_PROF_ACCV || i==ARMCI_PROF_NBGETV || i==ARMCI_PROF_NBPUTV || i==ARMCI_PROF_NBACCV) for(j=0; j<ARMCI_MAX_MSG_RANGE; j++) { ARMCI_PROF[i][j].vector = (armci_vector_t*)malloc(STRIDE_COUNT*sizeof(armci_vector_t)); ARMCI_PROF[i][j].stride = NULL; if( ARMCI_PROF[i][j].vector == NULL) armci_die("armci_profile_init(): malloc failed", armci_me); } } #endif }
void ARMCI_Group_free(ARMCI_Group *group) { int rv; ARMCI_iGroup *igroup = (ARMCI_iGroup *)group; #ifdef ARMCI_GROUP int i, world_me = armci_msg_me(); for(i=0; i<igroup->grp_attr.nproc; i++) { if(igroup->grp_attr.proc_list[i] == world_me) { break; } } if(i==igroup->grp_attr.nproc) { return; /*not in group to be freed*/ } #endif assert(igroup); free(igroup->grp_attr.grp_clus_info); #ifdef ARMCI_GROUP free(igroup->grp_attr.proc_list); igroup->grp_attr.nproc = 0; #else rv=MPI_Group_free(&(igroup->igroup)); if(rv != MPI_SUCCESS) armci_die("MPI_Group_free: Failed ",armci_me); if(igroup->icomm != MPI_COMM_NULL) { rv = MPI_Comm_free( (MPI_Comm*)&(igroup->icomm) ); if(rv != MPI_SUCCESS) armci_die("MPI_Comm_free: Failed ",armci_me); } #endif }
/** * CHECK: On Altix we are forced to use SysV as shmalloc is collective. We * may use a preallocated shmalloc memory, however, it may NOT still solve * our problem... * NOTE: "int memflg" option for future optimiztions. */ void PARMCI_Memget(size_t bytes, armci_meminfo_t *meminfo, int memflg) { void *myptr=NULL; void *armci_ptr=NULL; /* legal ARCMI ptr used in ARMCI data xfer ops*/ size_t size = bytes; if(size<=0) armci_die("PARMCI_Memget: size must be > 0", (int)size); if(meminfo==NULL) armci_die("PARMCI_Memget: Invalid arg #2 (NULL ptr)",0); if(memflg!=0) armci_die("PARMCI_Memget: Invalid memflg", memflg); if( !ARMCI_Uses_shm() ) { /* fill the meminfo structure */ meminfo->armci_addr = armci_ptr; meminfo->addr = myptr; meminfo->size = size; meminfo->cpid = armci_me; /* meminfo->attr = NULL; */ } else { armci_shmem_memget(meminfo, size); } if(DEBUG_){ printf("%d: PARMCI_Memget: addresses server=%p myptr=%p bytes=%ld\n", armci_me, meminfo->armci_addr, meminfo->addr, bytes); fflush(stdout); } }
void armci_shmalloc_exchange_offsets(context_t *ctx_local) { void **ptr_arr; void *ptr; armci_size_t bytes = 128; int i; ptr_arr = (void**)malloc(armci_nproc*sizeof(void*)); offset_arr = (long*) malloc(armci_nproc*sizeof(long)); if(!ptr_arr || !offset_arr) armci_die("armci_shmalloc_get_offsets: malloc failed", 0); /* get memory with same size on all procs */ ptr = kr_malloc(bytes, ctx_local); if(!ptr) armci_die("armci_shmalloc_get_offsets: kr_malloc failed",bytes); bzero((char*)ptr_arr,armci_nproc*sizeof(void*)); ptr_arr[armci_me] = ptr; /* now combine individual addresses into a single array */ armci_exchange_address(ptr_arr, armci_nproc); /* identify offets */ for (i=0; i<armci_nproc; i++) { offset_arr[i] = (long) ((char*)ptr - (char*)ptr_arr[i]); } /* release memory */ kr_free(ptr, ctx_local); }
/*\ 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); }
void ARMCIX_DCMF_RecvRMWRequest (void * clientdata, const DCQuad * msginfo, unsigned count, unsigned peer, const char * src, unsigned bytes) { ARMCIX_DCMF_RMWRequest_t * info = (ARMCIX_DCMF_RMWRequest_t *) msginfo; /* Initialize the RMW response data */ ARMCIX_DCMF_RMWResponse_t response; response.op = info->op; response.ploc = info->ploc; response.active = info->active; //fprintf (stderr, "ARMCIX_DCMF_RecvRMWRequest() - info->op == %d, info->ploc == %p, info->prem == %p, info->extra == %d, peer == %d\n", info->op, info->ploc, info->prem, info->extra, peer); switch (info->op) { case ARMCI_FETCH_AND_ADD: case ARMCI_SWAP: response.ival = *((int *) info->prem); break; case ARMCI_FETCH_AND_ADD_LONG: case ARMCI_SWAP_LONG: response.lval = *((long *) info->prem); break; default: armci_die("rmw: operation not supported",info->op); break; } /* Send the rmw response. */ DCMF_Control (&__rmw_response_protocol, DCMF_SEQUENTIAL_CONSISTENCY, peer, (DCMF_Control_t *) &response); /* Perform the swap or add */ switch (info->op) { case ARMCI_FETCH_AND_ADD: *((int *) info->prem) += info->extra; break; case ARMCI_FETCH_AND_ADD_LONG: *((long *) info->prem) += info->extra; break; case ARMCI_SWAP: *((int *) info->prem) = info->extra; break; case ARMCI_SWAP_LONG: *((long *) info->prem) = info->extra; break; default: armci_die("rmw: operation not supported",info->op); break; } }
/* LAPI Put RDMA */ void armci_client_direct_send(int p, void *src_buf, void *dst_buf, int len, void** contextptr, int nbtag, ARMCI_MEMHDL_T *lochdl,ARMCI_MEMHDL_T *remhdl) { lapi_xfer_t xfer_struct; /* Data structure for the xfer call */ lapi_rdma_tag_t lapi_rdma_tag; /* RDMA notification tag */ uint src_offset, tgt_offset; int val, rc; /* can be any number that fits in ushort */ lapi_rdma_tag = 22; /* CHECK: offset problem. what if client and server attached (shmat) at diff address */ src_offset = (char *)src_buf- (char *)lochdl->start; tgt_offset = (char *)dst_buf - (char *)remhdl->start; #if DEBUG_ printf("%d: Doing LAPI_Xfer (RDMA Put): dst=%d srchdl_start=%p remhdl_start=%p (bytes=%ld src_off=%d tgt_off=%d)\n", armci_me, p, lochdl->start, remhdl->start, len, src_offset, tgt_offset); fflush(stdout); #endif bzero(&xfer_struct, sizeof(xfer_struct)); xfer_struct.HwXfer.Xfer_type = LAPI_RDMA_XFER; xfer_struct.HwXfer.tgt = p; /*xfer_struct.HwXfer.op = LAPI_RDMA_PUT|LAPI_RCNTR_UPDATE;*/ xfer_struct.HwXfer.op = LAPI_RDMA_PUT; xfer_struct.HwXfer.rdma_tag = lapi_rdma_tag; xfer_struct.HwXfer.remote_cxt = lapi_remote_cxt[p]; xfer_struct.HwXfer.src_pvo = lochdl->pvo; xfer_struct.HwXfer.tgt_pvo = remhdl->pvo; xfer_struct.HwXfer.src_offset = src_offset; xfer_struct.HwXfer.tgt_offset = tgt_offset; xfer_struct.HwXfer.len = (ulong) (len); xfer_struct.HwXfer.shdlr = (scompl_hndlr_t *) NULL; xfer_struct.HwXfer.sinfo = (void *) NULL; xfer_struct.HwXfer.org_cntr = &(ack_cntr->cntr); /* Initiate RDMA Xfer */ if((rc = LAPI_Xfer(lapi_handle, &xfer_struct)) != LAPI_SUCCESS) { LAPI_Msg_string(rc, err_msg_buf); fprintf(stderr, "LAPI ERROR: %s, rc = %d\n", err_msg_buf, rc); armci_die("LAPI_Xfer (RDMA Put) failed", 0); } /* wait for RDMA completion */ rc = LAPI_Waitcntr(lapi_handle, &(ack_cntr->cntr),1,&val); if(rc != LAPI_SUCCESS) { LAPI_Msg_string(rc, err_msg_buf); fprintf(stderr, "LAPI ERROR: %s, rc = %d\n", err_msg_buf, rc); armci_die("LAPI_Waitcntr (RDMA Put) failed", 0); } /* CHECK((LAPI_Fence(lapi_handle))); */ #if DEBUG_ printf("%d: Completed LAPI_Xfer RDMA (Put): dst=%d\n", armci_me, p); #endif }
/** * Construct the armci_clus_t arrays of structs for a given group. * * @param grp_nclus_nodes OUT #clus_info objects returned * @param igroup IN Group whose clus_info needs to be constructed * @return array of armci_clus_t objects */ static armci_clus_t* group_construct_clusinfo(int *grp_nclus_nodes, ARMCI_iGroup *igroup) { armci_clus_t *grp_clus_info=NULL; int i, *grp_clus_id, cluster, clus_id, grp_nproc, grp_nclus; ARMCI_Group_size((ARMCI_Group *)igroup, &grp_nproc); /* get the cluster_id of processes in the group */ grp_clus_id = (int *)malloc(grp_nproc*sizeof(int)); get_group_clus_id(igroup, grp_nproc, grp_clus_id); /* first find out how many cluster nodes we got for this group */ grp_nclus=1; for(i=0; i<grp_nproc-1; i++) { if(grp_clus_id[i] != grp_clus_id[i+1]) ++grp_nclus; } *grp_nclus_nodes = grp_nclus; grp_clus_info = (armci_clus_t*)malloc(grp_nclus*sizeof(armci_clus_t)); if(!grp_clus_info)armci_die("malloc failed for grp_clusinfo",grp_nclus); cluster = 1; clus_id = grp_clus_id[0]; grp_clus_info[0].nslave = 1; grp_clus_info[0].master = 0; strcpy(grp_clus_info[0].hostname, armci_clus_info[clus_id].hostname); for(i=1; i<grp_nproc; i++) { if(grp_clus_id[i-1] == grp_clus_id[i]) ++grp_clus_info[cluster-1].nslave; else { clus_id = grp_clus_id[i]; grp_clus_info[cluster].nslave = 1; grp_clus_info[cluster].master = i; strcpy(grp_clus_info[cluster].hostname, armci_clus_info[clus_id].hostname); ++cluster; } } free(grp_clus_id); if(grp_nclus != cluster) armci_die("inconsistency processing group clusterinfo", grp_nclus); # if DEBUG_ { int i,j; for(i=0; i<cluster;i++) { printf("%d: Cluster %d: Master=%d, #Slaves=%d, HostName=%s\n", grp_nclus, i, grp_clus_info[i].master, grp_clus_info[i].nslave, grp_clus_info[i].hostname); fflush(stdout); } } # endif return grp_clus_info; }
/*\ server receives request \*/ void armci_rcv_req(void *mesg, void *phdr, void *pdescr,void *pdata,int *buflen) { request_header_t *msginfo = (request_header_t*)MessageRcvBuffer; int hdrlen = sizeof(request_header_t); int stat, p = *(int*)mesg; int bytes; stat =armci_ReadFromSocket(CLN_sock[p],MessageRcvBuffer,hdrlen); if(stat<0) armci_die("armci_rcv_req: failed to receive header ",p); *(void**)phdr = msginfo; #if defined(USE_SOCKET_VECTOR_API) if(msginfo->operation == PUT && msginfo->datalen==0){ if(msginfo->format==STRIDED) armci_tcp_read_strided_data(msginfo,pdescr,p); if(msginfo->format==VECTOR){ armci_tcp_read_vector_data(msginfo,pdescr,p); } return; } #endif *buflen = MSG_BUFLEN - hdrlen; if (msginfo->operation == GET) bytes = msginfo->dscrlen; else{ bytes = msginfo->bytes; if(bytes >*buflen)armci_die2("armci_rcv_req: message overflowing rcv buf", msginfo->bytes,*buflen); } if(msginfo->bytes){ stat = armci_ReadFromSocket(CLN_sock[p],msginfo+1,bytes); if(stat<0)armci_die("armci_rcv_req: read of data failed",stat); *(void**)pdescr = msginfo+1; *(void**)pdata = msginfo->dscrlen + (char*)(msginfo+1); *buflen -= msginfo->dscrlen; if (msginfo->operation != GET) if(msginfo->datalen)*buflen -= msginfo->datalen; }else { *(void**)pdata = msginfo+1; *(void**)pdescr = NULL; } if(msginfo->datalen>0 && msginfo->operation != GET){ if(msginfo->datalen > MSG_BUFLEN -hdrlen -msginfo->dscrlen) armci_die2("armci_rcv_req:data overflowing buffer", msginfo->dscrlen,msginfo->datalen); *buflen -= msginfo->datalen; } }
static void armci_gather_hostnames(char **hostname_arr) { int i, j, k, namelen, is_master; char hostname[MPI_MAX_PROCESSOR_NAME], *hostnames=NULL; int *master_arr=NULL; master_arr = (int*) malloc(armci_nproc * sizeof(int)); hostnames = (char*) malloc(armci_nproc * MPI_MAX_PROCESSOR_NAME * sizeof(char)); if(hostnames==NULL || master_arr==NULL) { armci_die("armci_gather_hostnames: malloc failed.", 0); } MPI_Get_processor_name(hostname, &namelen); MPI_Check( MPI_Allgather(hostname, MPI_MAX_PROCESSOR_NAME, MPI_CHAR, hostnames, MPI_MAX_PROCESSOR_NAME, MPI_CHAR, MPI_COMM_WORLD) ); if(armci_me == armci_master) { is_master = 1; } else { is_master = 0; } MPI_Check(MPI_Allgather(&is_master, 1, MPI_INT, master_arr, 1, MPI_INT, MPI_COMM_WORLD)); { /* get only the hostname of armci master processes */ for(i=0,j=0,k=0; i<armci_nproc; i++) { if(master_arr[i] == 1) { if(j>=armci_nserver) armci_die("armci_gather_hostnames: Invalid masters.",0); strncpy(hostname_arr[j++], &hostnames[k], MPI_MAX_PROCESSOR_NAME); } k += MPI_MAX_PROCESSOR_NAME; } } free(hostnames); free(master_arr); }
static int sr_gethostname(char *name, int len) { int no; pid_t ppid; if(hmpp_nself (&_armci_group,&no,&ppid,0,NULL) <0) return -1; if(len<6)armci_die("len too small",len); if(no>1024)armci_die("expected node id <1024",no); sprintf(name,"n%d",no); return 0; }
void PARMCI_Unlock(int mutex, int proc) { if(DEBUG)fprintf(stderr,"%d enter unlock\n",armci_me); if(!num_mutexes) armci_die("armci_lock: create mutexes first",0); if(mutex > glob_mutex[proc].count) armci_die2("armci_lock: mutex not allocated", mutex, glob_mutex[proc].count); if(armci_nproc == 1) return; # if defined(SERVER_LOCK) if(armci_nclus >1) { if(proc != armci_me) armci_rem_unlock(mutex, proc, glob_mutex[proc].tickets[mutex]); else { int ticket = glob_mutex[proc].tickets[mutex]; msg_tag_t tag; int waiting; waiting = armci_server_unlock_mutex(mutex, proc, ticket, &tag); if(waiting >-1) armci_unlock_waiting_process(tag, waiting, ++ticket); } } else # endif armci_generic_unlock(mutex, proc); if(DEBUG)fprintf(stderr,"%d leave unlock\n",armci_me); }
/*\ 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); }
/*\ find cluster node id the specified process is on \*/ int armci_clus_id(int p) { int from, to, found, c; if (p <0 || p >= armci_nproc) armci_die("armci_clus_id: out of range",p); if (p < armci_clus_first){ from = 0; to = armci_clus_me; } else { from = armci_clus_me; to = armci_nclus; } found = to - 1; /* Binary search algorithm to be implemented, * sequential search for now */ for(c = from; c < to - 1; c++) if (p < armci_clus_info[c+1].master) { found = c; break; } return found; }
static char* merge_names(char *name) { int jump = 1, rem, to, from; int lenmes, lenbuf, curlen, totbuflen= armci_nproc*HOSTNAME_LEN; int len = strlen(name); char *work = malloc(totbuflen); if(!work)armci_die("armci: merge_names: malloc failed: ",totbuflen); strcpy(work, name); curlen = len+1; /* prefix tree merges names in the order of process numbering in log(P)time * result = name_1//name_2//...//name_P-1 */ do { jump *= 2; rem = armci_me%jump; if(rem){ to = armci_me - rem; armci_msg_snd(ARMCI_TAG, work, curlen, to); break; }else{ from = armci_me + jump/2; if(from < armci_nproc){ lenbuf = totbuflen - curlen; armci_msg_rcv(ARMCI_TAG, work+curlen, lenbuf, &lenmes, from); curlen += lenmes; } } }while (jump < armci_nproc); return(work); }
void armci_profile_start_strided(int count[], int stride_levels, int proc, int event_type) { int i, status, bytes=1, range; if(stride_levels >= ARMCI_MAX_DIM) armci_die("ARMCI_PROFILE: stride_levels >= ARMCI_MAX_DIM. Increase ARMCI_MAX_DIM.", armci_me); /* find the message range */ for(i=0; i<= stride_levels; i++) bytes *= count[i]; if(bytes<=0) range=0; else range = (int) (log((double)bytes)/log(2.0)); if(range>=ARMCI_MAX_MSG_RANGE-1) range = ARMCI_MAX_MSG_RANGE-1; /* set the curent event for timer */ status = armci_profile_set_event(event_type, range); if(status == ARMCI_EVENT_SET) { /* new event set */ /* profile update: i.e. update event count */ ARMCI_PROF[event_type][range].count++; # if ARMCI_PRINT_STRIDE if(strided_event(event_type)) { int idx = ARMCI_PROF[event_type][range].count-1; if(idx<STRIDE_COUNT) { ARMCI_PROF[event_type][range].stride[idx].stride_levels = stride_levels; ARMCI_PROF[event_type][range].stride[idx].proc = proc; for(i=0;i<=stride_levels;i++) { ARMCI_PROF[event_type][range].stride[idx].count[i]=count[i]; } } } # endif } else { /* Do nothing. It is just an event overlap */ } }
void InitLocks(int num_locks, lockset_t lockid) { /* what are you doing here ? All processes should've called CreateInitLocks(). Check preprocessor directtives and see lock allocation in armci_init */ armci_die("InitLocks(): what are you doing here ?",armci_me); }
static void emulate_armci_init_clusinfo() { int psize; MPI_Comm_remote_size(MPI_COMM_SERVER2CLIENT, &psize); /* server id (i.e. server's armci_me) is derived from node master's id. Similar to armci_create_server_process() to set SERVER_CONTEXT */ armci_me = SOFFSET - armci_client_first; armci_nproc = psize; armci_usr_tid = THREAD_ID_SELF(); /*remember the main user thread id */ armci_master = armci_client_first; /* ***** emulate armci_init_clusinfo() ***** */ armci_clus_me = armci_server_me; armci_nclus = armci_nserver; armci_clus_first = armci_clus_info[armci_clus_me].master; armci_clus_last = (armci_clus_first + armci_clus_info[armci_clus_me].nslave - 1); if(armci_clus_first != armci_client_first || armci_nclients != armci_clus_info[armci_clus_me].nslave) { armci_mpi2_server_debug(armci_server_me, "armci_clus_first=%d, armci_clus_last=%d\n", armci_clus_first, armci_clus_last); armci_die("mpi2_server: armci_clus_info is incorrect.", 0); } }
/** * \brief Receive a read-modify-write response message. * * \param[in] clientdata Registered clientdata * \param[in] info Read-Modify-Write data sent from the target node * \param[in] peer Rank of the node that sent this control message * * \see ARMCIX_DCMF_Connection_t * \see ARMCIX_DCMF_Control_t * \see DCMF_RecvControl */ void ARMCIX_DCMF_ReceiveRMWResponse (void * clientdata, const DCMF_Control_t * info, unsigned peer) { ARMCIX_DCMF_RMWResponse_t * response = (ARMCIX_DCMF_RMWResponse_t *) info; //fprintf (stderr, "ARMCIX_DCMF_ReceiveRMWResponse() - response->op == %d, response->ploc == %p, response->ival == %d, response->lval == %d, response->active == %p\n", response->op, response->ploc, response->ival, response->lval, response->active); switch (response->op) { case ARMCI_FETCH_AND_ADD: case ARMCI_SWAP: *((int *) response->ploc) = response->ival; break; case ARMCI_FETCH_AND_ADD_LONG: case ARMCI_SWAP_LONG: *((long *) response->ploc) = response->lval; break; default: armci_die("rmw: operation not supported",response->op); break; } // Complete the rmw operation *(response->active) = 0; }
/*\ server initializes its copy of the memory lock data structures \*/ static void server_alloc_memlock(void *ptr_myclus) { int i; /* for protection, set pointers for processes outside local node NULL */ memlock_table_array = calloc(armci_nproc,sizeof(void*)); if(!memlock_table_array) armci_die("malloc failed for ARMCI lock array",0); /* set pointers for processes on local cluster node * ptr_myclus - corresponds to the master process */ for(i=0; i< armci_clus_info[armci_clus_me].nslave; i++){ memlock_table_array[armci_master +i] = ((char*)ptr_myclus) + MAX_SLOTS*sizeof(memlock_t)*i; } /* set pointer to the use flag */ #ifdef MEMLOCK_SHMEM_FLAG armci_use_memlock_table = (int*) (MAX_SLOTS*sizeof(memlock_t) + (char*) memlock_table_array[armci_clus_last]); if(DEBUG_) fprintf(stderr,"server initialized memlock %p\n",armci_use_memlock_table); #endif }
void PARMCI_Lock(int mutex, int proc) { #if defined(SERVER_LOCK) int direct; #endif if(DEBUG)fprintf(stderr,"%d enter lock\n",armci_me); if(!num_mutexes) armci_die("armci_lock: create mutexes first",0); if(mutex > glob_mutex[proc].count) armci_die2("armci_lock: mutex not allocated", mutex, glob_mutex[proc].count); if(armci_nproc == 1) return; # if defined(SERVER_LOCK) direct=SAMECLUSNODE(proc); if(!direct) armci_rem_lock(mutex,proc, glob_mutex[proc].tickets + mutex ); else # endif armci_generic_lock(mutex,proc); if(DEBUG)fprintf(stderr,"%d leave lock\n",armci_me); }
int armci_agg_save_giov_descriptor(armci_giov_t dscr[], int len, int proc, int op, armci_ihdl_t nb_handle) { int i, j, k, idx, bytes, ptr_array_len; armci_giov_t * darr; /* set up the handle if it is a new aggregation request */ AGG_INIT_NB_HANDLE(op, proc, nb_handle); for(i=0; i<len; i++) { k = 0; bytes = dscr[i].bytes; ptr_array_len = dscr[i].ptr_array_len; do { darr=_armci_agg_get_descriptor(&ptr_array_len,bytes,nb_handle,0,0); idx = darr->ptr_array_len; for(j=idx; j<idx+ptr_array_len; j++, k++) { darr->src_ptr_array[j] = dscr[i].src_ptr_array[k]; darr->dst_ptr_array[j] = dscr[i].dst_ptr_array[k]; } darr->bytes = dscr[i].bytes; darr->ptr_array_len += ptr_array_len; ptr_array_len = dscr[i].ptr_array_len - ptr_array_len; if(ptr_array_len <0) armci_die("agg_save_giov_descr failed", 0L); } while(k < darr[i].ptr_array_len); } return 0; }
void armci_lapi_unlock(int *lock) { atomic_p word_addr = (atomic_p)lock; if(_check_lock(word_addr, LOCKED, 0) == TRUE ) armci_die("somebody else unlocked",0); }
/*\ 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); } } }
/* get the index of the aggregation buffer to be used */ static int _armci_agg_get_bufferid(armci_ihdl_t nb_handle) { int i, index, tag = nb_handle->tag, proc = nb_handle->proc; /* check if there is an entry for this handle in the existing list*/ for(i=ulist.size-1; i>=0; i--) { index = ulist.index[i]; if(aggr[index]->tag == tag && aggr[index]->proc == proc) return index; } /* else it is a new handle, so get a aggr buffer from either of the lists. ???? don't throw exception here */ if(ulist.size >= _MAX_AGG_BUFFERS && alist.size == 0) armci_die("_armci_agg_get_index: Too many outstanding aggregation requests\n", ulist.size); /*If there is a buffer in readily available list,use it*/ if(alist.size > 0) index = alist.index[--alist.size]; else { /* else use/get a buffer from the main list */ index = ulist.size; /* allocate memory for aggregate request handle */ aggr[index] = (agg_req_t *)agg_buf[index]; aggr[index]->request_len = 0; aggr[index]->ptr_array_len = 0; aggr[index]->buf_pos_end = _MAX_AGG_BUFSIZE; /* allocate memory for giov vector field in aggregate request handler */ aggr[index]->darr = (armci_giov_t *)(agg_buf[index]+sizeof(agg_req_t)); } _armci_agg_set_buffer(index, tag, proc, 0); return index; }
void armci_region_clus_record(int node, void *start, long size) { if(node > armci_nclus || node <0 ) armci_die("armci_region_remote: bad node ",node); (void)armci_region_record(start,((char*)start)+size,clus_regions+node); }