static int stormfs_chmod(const char *path, mode_t mode) { int result; struct file *f; struct stat st; DEBUG("chmod: %s\n", path); if((result = valid_path(path)) != 0) return result; if((result = stormfs_getattr(path, &st)) != 0) return result; st.st_mode = mode; st.st_ctime = time(NULL); st.st_mtime = time(NULL); if((result = proxy_chmod(path, &st)) != 0) return result; f = cache_get(path); if(cache_valid(f) && f->st != NULL) { pthread_mutex_lock(&f->lock); f->st->st_mode = mode; f->st->st_ctime = st.st_ctime; f->st->st_mtime = st.st_mtime; cache_touch(f); pthread_mutex_unlock(&f->lock); } return result; }
static int stormfs_truncate(const char *path, off_t size) { int fd; int result; struct stat st; struct file *f; DEBUG("truncate: %s\n", path); if((result = valid_path(path)) != 0) return result; if((result = stormfs_getattr(path, &st)) != 0) return -result; f = cache_get(path); if(cache_file_valid(f)) { char *cp = cache_path(f); if((result = truncate(cp, size)) != 0) perror("truncate"); free(cp); } else { fd = cache_create_file(f); close(fd); } pthread_mutex_lock(&f->lock); f->st->st_size = get_blocks(size); cache_touch(f); pthread_mutex_unlock(&f->lock); return 0; }
static int stormfs_create(const char *path, mode_t mode, struct fuse_file_info *fi) { int result; struct stat st; struct file *f; DEBUG("create: %s\n", path); if((result = valid_path(path)) != 0) return result; cache_invalidate_dir(path); f = cache_get(path); fi->fh = cache_create_file(f); st.st_gid = getgid(); st.st_uid = getuid(); st.st_mode = mode; st.st_ctime = time(NULL); st.st_mtime = time(NULL); if((result = proxy_create(path, &st)) != 0) return result; pthread_mutex_lock(&f->lock); if(f->st == NULL) f->st = g_new0(struct stat, 1); memcpy(f->st, &st, sizeof(struct stat)); cache_touch(f); pthread_mutex_unlock(&f->lock); return result; }
static int stormfs_utimens(const char *path, const struct timespec ts[2]) { int result; struct file *f; struct stat st; DEBUG("utimens: %s\n", path); if((result = valid_path(path)) != 0) return result; if((result = stormfs_getattr(path, &st)) != 0) return result; st.st_mtime = ts[1].tv_sec; if((result = proxy_utimens(path, &st)) != 0) return result; f = cache_get(path); if(cache_valid(f) && f->st != NULL) { pthread_mutex_lock(&f->lock); f->st->st_mtime = st.st_mtime; cache_touch(f); pthread_mutex_unlock(&f->lock); } return result; }
NSAPI_PUBLIC int dns_cache_touch(dns_cache_entry_t *entry) { if (!entry) return -1; return cache_touch(dns_cache, (cache_entry_t *)entry); }
void wfm::recon(Float *chi, Float *u, int cb, int dag) { Float *gauge_notpar; /*Gauge args*/ int lcb = (cb + base_parity) & 1; nthread=1; if ( cb == 0 ) { gauge_notpar = (Float *)u + GAUGE_SIZE*vol; } else { gauge_notpar = (Float *)u ; } cache_touch(gauge_notpar); cb = lcb; int svol = vol/nthread; if ( (svol * nthread) != vol ) { if ( isBoss() ) printf("Bagel threading model broke\n"); exit(-1); } recon_internal_arg *args = new recon_internal_arg[nthread]; args[0].cb = cb; args[0].dag = dag; args[0].vol = svol; args[0].bgl = WFM_BGL; args[0].sloppy = SloppyPrecision; for(int i=0;i<nthread;i++){ args[i] = args[0]; args[i].chi = chi + svol*i*SPINOR_SIZE; args[i].u = gauge_notpar + svol*i*GAUGE_SIZE; args[i].two_spinor = two_spinor + (svol*i*8*PAD_HALF_SPINOR_SIZE*TwoSpinSize())/sizeof(Float); } for ( int i=1;i<nthread;i++) { thread_create(recon_internal,(void *)&args[i],i); } recon_internal(&args[0]); for ( int i=1;i<nthread;i++) { thread_join(i); } delete [] args; CPS_NAMESPACE::DiracOp::CGflops += 1320*vol; return; }
static struct file * cache_insert(const char *path) { struct file *f = g_new0(struct file, 1); f->path = strdup(path); f->name = strdup(basename(f->path)); f->headers = NULL; f->st = NULL; pthread_mutex_init(&f->lock, NULL); cache_touch(f); g_hash_table_insert(cache.files, strdup(path), f); return f; }
static int stormfs_write(const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { struct file *f; DEBUG("write: %s\n", path); f = cache_get(path); if(cache_valid(f) && f->st != NULL) { pthread_mutex_lock(&f->lock); f->st->st_size += size; cache_touch(f); pthread_mutex_unlock(&f->lock); } return pwrite(fi->fh, buf, size, offset); }
int stormfs_getattr(const char *path, struct stat *stbuf) { int result; struct file *f = NULL; DEBUG("getattr: %s\n", path); if((result = valid_path(path)) != 0) return result; if(strcmp(path, "/") == 0) { stbuf->st_mode = stormfs.root_mode | S_IFDIR; return 0; } f = cache_get(path); if(cache_valid(f) && f->st != NULL) { memcpy(stbuf, f->st, sizeof(struct stat)); return 0; } if((result = proxy_getattr(path, stbuf)) != 0) return result; stbuf->st_nlink = 1; if(S_ISREG(stbuf->st_mode)) stbuf->st_blocks = get_blocks(stbuf->st_size); pthread_mutex_lock(&f->lock); if(f->st == NULL) f->st = g_new0(struct stat, 1); memcpy(f->st, stbuf, sizeof(struct stat)); cache_touch(f); pthread_mutex_unlock(&f->lock); return 0; }
static int stormfs_mknod(const char *path, mode_t mode, dev_t rdev) { int result; int fd; struct file *f; struct stat st; DEBUG("mknod: %s\n", path); if((result = valid_path(path)) != 0) return result; cache_invalidate_dir(path); f = cache_get(path); fd = cache_mknod(f, mode, rdev); st.st_gid = getgid(); st.st_uid = getuid(); st.st_mode = mode; st.st_rdev = rdev; st.st_ctime = time(NULL); st.st_mtime = time(NULL); if((result = proxy_mknod(path, &st)) != 0) return result; pthread_mutex_lock(&f->lock); if(f->st == NULL) f->st = g_new0(struct stat, 1); memcpy(f->st, &st, sizeof(struct stat)); cache_touch(f); pthread_mutex_unlock(&f->lock); return result; }
static int stormfs_chown(const char *path, uid_t uid, gid_t gid) { int result = 0; struct file *f; struct stat st; DEBUG("chown: %s\n", path); if((result = valid_path(path)) != 0) return result; if((result = stormfs_getattr(path, &st)) != 0) return result; st.st_uid = uid; st.st_gid = gid; st.st_ctime = time(NULL); st.st_mtime = time(NULL); if((result = proxy_chown(path, &st)) != 0) return result; f = cache_get(path); if(cache_valid(f) && f->st != NULL) { pthread_mutex_lock(&f->lock); f->st->st_uid = uid; f->st->st_gid = gid; f->st->st_ctime = st.st_ctime; f->st->st_mtime = st.st_mtime; cache_touch(f); pthread_mutex_unlock(&f->lock); } return result; }
static int stormfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi) { int result; struct file *dir; GList *files = NULL, *head = NULL, *next = NULL; DEBUG("readdir: %s\n", path); if((result = valid_path(path)) != 0) return result; filler(buf, ".", 0, 0); filler(buf, "..", 0, 0); dir = cache_get(path); if(cache_valid(dir) && dir->dir != NULL) { pthread_mutex_lock(&dir->lock); head = g_list_first(dir->dir); while(head != NULL) { next = head->next; struct file *f = head->data; filler(buf, (char *) f->name, f->st, 0); head = next; } pthread_mutex_unlock(&dir->lock); return 0; } if((result = proxy_readdir(path, &files)) != 0) return result; result = proxy_getattr_multi(path, files); pthread_mutex_lock(&dir->lock); head = g_list_first(files); while(head != NULL) { next = head->next; // FIXME: list_bucket is using the same structure (file) as // the cache which makes the code below confusing. struct file *file = head->data; char *fullpath = get_path(path, file->name); struct file *f = cache_get(fullpath); free(fullpath); pthread_mutex_lock(&f->lock); if(f->st == NULL) f->st = g_new0(struct stat, 1); memcpy(f->st, file->st, sizeof(struct stat)); f->st->st_nlink = 1; cache_touch(f); pthread_mutex_unlock(&f->lock); filler(buf, (char *) f->name, f->st, 0); dir->dir = g_list_append(dir->dir, f); head = next; } pthread_mutex_unlock(&dir->lock); free_files(files); return result; }
void wfm_dslash_two( Float *chi0, Float *chi1, Float *u, Float *psi0, Float *psi1, int cb0, int cb1, int dag) { static Float dslash_time=0.; static Float decom_time=0.; static Float recom_time=0.; static Float comm_time=0.; static Float comm_init_time=0.; called++; dslash_time -=DCLOCK(); wfm_scope_assert(0); wfm_scope_assert(1); decom_time -=DCLOCK(); cache_touch(psi0); cache_touch(psi0+4); cache_touch(psi0+8); cache_touch(psi0+12); cache_touch(psi0+16); cache_touch(psi0+20); StaticWilsonPAB[0].decom(psi0,u,cb0,dag); decom_time +=DCLOCK(); comm_init_time -=DCLOCK(); StaticWilsonPAB[0].comm_start(cb0); comm_init_time +=DCLOCK(); decom_time -=DCLOCK(); cache_touch(psi1); cache_touch(psi1+4); cache_touch(psi1+8); cache_touch(psi1+12); cache_touch(psi1+16); cache_touch(psi1+20); StaticWilsonPAB[1].decom(psi1,u,cb1,dag); decom_time +=DCLOCK(); comm_time -=DCLOCK(); StaticWilsonPAB[0].comm_complete(cb0); comm_time +=DCLOCK(); comm_init_time -=DCLOCK(); StaticWilsonPAB[1].comm_start(cb1); comm_init_time +=DCLOCK(); recom_time -=DCLOCK(); cache_touch(StaticWilsonPAB[0].two_spinor); cache_touch(StaticWilsonPAB[0].two_spinor+4); cache_touch(StaticWilsonPAB[0].two_spinor+8); StaticWilsonPAB[0].recon(chi0,u,cb0,dag); recom_time +=DCLOCK(); comm_time -=DCLOCK(); StaticWilsonPAB[1].comm_complete(cb1); comm_time +=DCLOCK(); recom_time -=DCLOCK(); cache_touch(StaticWilsonPAB[1].two_spinor); cache_touch(StaticWilsonPAB[1].two_spinor+4); cache_touch(StaticWilsonPAB[1].two_spinor+8); StaticWilsonPAB[1].recon(chi1,u,cb1,dag); recom_time +=DCLOCK(); dslash_time +=DCLOCK(); #ifdef PROFILE #ifndef UNIFORM_SEED_TESTING if (called%p_int==0){ CPS_NAMESPACE::print_time("wfm_dslash_two","dslash_time",dslash_time/m_num); CPS_NAMESPACE::print_time("wfm_dslash_two","decom_time",decom_time/m_num); CPS_NAMESPACE::print_time("wfm_dslash_two","recom_time",recom_time/m_num); CPS_NAMESPACE::print_time("wfm_dslash_two","comm_init_time",comm_init_time/m_num); CPS_NAMESPACE::print_time("wfm_dslash_two","comm_time",comm_time/m_num); called=0; decom_time=recom_time=comm_time=dslash_time=comm_init_time=0.; } #endif #endif return; }
void *cache_find(void **root,unsigned hashval,void *keyval,unsigned *retsts, int (*compare_func) (unsigned hashval,void *keyval,void *node), void *(*create_func) (unsigned hashval,void *keyval,unsigned *retsts)) { register struct CACHE *cacheobj,**parent = (struct CACHE **) root; cachefinds++; while ((cacheobj = *parent) != NULL) { register int cmp = hashval - cacheobj->hashval; #ifdef DEBUG if (cacheobj->parent != parent) { printk("CACHE Parent pointer is corrupt\n"); } #endif if (cmp == 0 && compare_func != NULL) cmp = (*compare_func) (hashval,keyval,cacheobj); if (cmp == 0) { cache_touch(cacheobj); if (retsts != NULL) *retsts = SS$_NORMAL; return cacheobj; } if (cmp < 0) { #ifdef IMBALANCE register struct CACHE *left_path = cacheobj->left; if (left_path != NULL && cacheobj->balance-- < -IMBALANCE) { cacheobj->left = left_path->right; if (cacheobj->left != NULL) cacheobj->left->parent = &cacheobj->left; left_path->right = cacheobj; cacheobj->parent = &left_path->right; *parent = left_path; left_path->parent = parent; cacheobj->balance = 0; } else { parent = &cacheobj->left; } } else { register struct CACHE *right_path = cacheobj->right; if (right_path != NULL && cacheobj->balance++ > IMBALANCE) { cacheobj->right = right_path->left; if (cacheobj->right != NULL) cacheobj->right->parent = &cacheobj->right; right_path->left = cacheobj; cacheobj->parent = &right_path->left; *parent = right_path; right_path->parent = parent; cacheobj->balance = 0; } else { parent = &cacheobj->right; } #else parent = &cacheobj->left; } else { parent = &cacheobj->right; #endif } }
void wfm::dslash(Float *chi, Float *u, Float *psi, int cb, int dag) { /* * To a first approximation, we simply * remap the arguments into a form acceptable * to the assembler, then call it */ /* *Pull in the first Psi to cache early */ cache_touch(psi); cache_touch(psi+4); cache_touch(psi+8); cache_touch(psi+12); cache_touch(psi+16); cache_touch(psi+20); decom(psi,u,cb,dag); #ifdef DEBUG_BENCHMARK_COMMS double ndata = 2*2*allbound * 12 * TwoSpinSize() * 1.0E-6 * 100; struct timeval start,stop,delta; gettimeofday(&start,NULL); for(int i=0;i<100;i++) { #endif comm_start(cb); /* * Hackers: you could split here and do something else... * Such as DWF fith dimension, or a clover term etc... * Might as well pull in a few sites worth of pointer table * while we're waiting for the comms */ comm_complete(cb); #ifdef DEBUG_BENCHMARK_COMMS } gettimeofday(&stop,NULL); timersub(&stop,&start,&delta); double seconds = delta.tv_usec * 1.0E-6 + delta.tv_sec; if ( isBoss() ) printf("Comms %le MB in %le seconds = %le MB/s\n",ndata,seconds,ndata/seconds); ndata = 2*2*allbound * 12 * TwoSpinSize() ; if ( isBoss() ) printf("ndata = %d \n",ndata); #endif #ifdef DEBUG_OUTPUT_VECTORS static int file_cnt; { char buf[256]; sprintf(buf,"2spin.%d.%d",UniqueID(),file_cnt); FILE *fp = fopen(buf,"w"); for(int i=0;i<vol;i++) { for(int pm=0;pm<2;pm++){ for(int mu=0;mu<4;mu++){ int offset = interleave_site(pm,mu,i); for(int s=0;s<2;s++){ for(int c=0;c<3;c++){ for(int r=0;r<2;r++){ int scri; if ( WFM_BGL ) scri = r + s*6+c*2; else scri = r + s*2+c*4; int gbl[4]; site_to_global(cb, i, gbl, local_latt ); if ( SloppyPrecision ) { float * pointer = (float *) two_spinor; fprintf(fp,"%d %d %d %d %d %d %d %d %d %e\n",gbl[0],gbl[1],gbl[2],gbl[3], pm,mu,s,c,r,pointer[PAD_HALF_SPINOR_SIZE*offset+scri]); } else { Float * pointer = (Float *) two_spinor; fprintf(fp,"%d %d %d %d %d %d %d %d %d %e\n",gbl[0],gbl[1],gbl[2],gbl[3], pm,mu,s,c,r,pointer[PAD_HALF_SPINOR_SIZE*offset+scri]); } }}} } } } fclose(fp);} #endif cache_touch(two_spinor); cache_touch(two_spinor+4); cache_touch(two_spinor+8); recon(chi,u,cb,dag); #ifdef DEBUG_OUTPUT_VECTORS { char buf[256]; sprintf(buf,"recon.%d.%d",UniqueID(),file_cnt++); FILE *fp = fopen(buf,"w"); for(int i=0;i<vol;i++) { for(int pm=0;pm<2;pm++){ for(int mu=0;mu<4;mu++){ int offset = interleave_site(pm,mu,i); for(int s=0;s<4;s++){ for(int c=0;c<3;c++){ for(int r=0;r<2;r++){ int scri; scri = r + s*6+c*2; Float * pointer = (Float *) chi; int gbl[4]; site_to_global(cb, i, gbl, local_latt ); fprintf(fp,"%d %d %d %d %d %d %d %d %d %d %e\n",gbl[0],gbl[1],gbl[2],gbl[3], i,pm,mu,s,c,r,pointer[SPINOR_SIZE*offset+scri]); }}} } } } fclose(fp);} exit(0); #endif return; }