QDP_Subset * qhmcqdp_get_timeslices(lattice_t *lat) { if(lat->timeslices==NULL) { int dir = lat->nd - 1; int n = QDP_coord_size_L(lat->qlat, dir); lat->timeslices = QDP_create_subset_L(lat->qlat, slice_func, (void*)&dir, sizeof(dir), n); } return lat->timeslices; }
QDP_Subset * qhmcqdp_get_eodir(lattice_t *lat, int dir) { if(lat->eodir[dir]==NULL) { int nd = lat->nd; int args[2] = {dir, nd}; // We get only even or odd for 0->nd-1. // We get even, odd, or neither for nd. lat->eodir[dir] = QDP_create_subset_L(lat->qlat, eodir_func, (void*)args, sizeof(args), (dir==nd?3:2)); } return lat->eodir[dir]; }
QDP_Subset * qhmcqdp_get_staggered(lattice_t *lat) { if(lat->staggered==NULL) { int nd = QDP_ndim_L(lat->qlat); int n = 1 << nd; //printf("creating staggered: %i %i\n", nd, n); lat->staggered = QDP_create_subset_L(lat->qlat, staggered_func, (void*)&nd,sizeof(nd),n); //printf("... done.\n"); } return lat->staggered; }
QDP_Subset * qhmcqdp_get_hyper(lattice_t *lat, int ha[], int *n) { int nd = lat->nd; int hn[nd]; *n = 1; for(int i=0; i<nd; i++) { int c = QDP_coord_size_L(lat->qlat, i); hn[i] = (c+ha[i]-1)/ha[i]; *n *= hn[i]; } int *args[3] = {&nd, ha, hn}; QDP_Subset *s = QDP_create_subset_L(lat->qlat, hyper_func, (void*)args, sizeof(args), *n); return s; }
// creates shifts and maps for copying hypercubic region of size rlen // from slat to rlat. // the point soff in slat will get copied to roff in rlat. // subsequent points in rlat will correspond to the permuted directions // in slat given by sdir // j = sdir[i] // r[i] = ( roff[i] + (s[j]-soff[j]+ss[j])%ss[j] )%rs[i] // s[j] = ( soff[j] + (r[i]-roff[i]+rs[i])%rs[i] )%ss[j] void qhmc_qopqdp_getCopyHyper(QDP_Shift *map, QDP_Subset **subset, QDP_Lattice *rlat, int roff[], int rlen[], int sdir[], QDP_Lattice *slat, int soff[], int num) { int rnd = QDP_ndim_L(rlat); int snd = QDP_ndim_L(slat); //int sublen[rnd], rof[rnd], rs[rnd], sd[rnd], sof[snd], ss[snd]; int sublen[4*rnd+2*snd], *rof, *rs, *sd, *sof, *ss, nsub[rnd], nsubs=1; rof = sublen + rnd; rs = rof + rnd; sd = rs + rnd; sof = sd + rnd; ss = sof + snd; QDP_latsize_L(rlat, rs); QDP_latsize_L(slat, ss); // get subvolume size for(int i=0; i<rnd; i++) { sd[i] = sdir[i]; int j = sdir[i]; sublen[i] = rlen[i]; if(sublen[i]>rs[i]) sublen[i] = rs[i]; if(j<0||j>=snd) sublen[i] = 1; else if(sublen[i]>ss[j]) sublen[i] = ss[j]; nsub[i] = (rlen[i]+sublen[i]-1)/sublen[i]; nsubs *= nsub[i]; } if(num<0||num>=nsubs) { *map = NULL; *subset = NULL; return; } // calculate which subvolume we will work on and adjust size if necessary int n = num; for(int j=0; j<snd; j++) sof[j] = soff[j]; for(int i=0; i<rnd; i++) { int j = sdir[i]; int k = n%nsub[i]; n = n/nsub[i]; int off = k*sublen[i]; rof[i] = (roff[i]+off)%rs[i]; if(j>=0&&j<snd) sof[j] = (sof[j]+off)%ss[j]; if(sublen[i]>(rlen[i]-off)) sublen[i] = rlen[i]-off; } *subset=QDP_create_subset_L(rlat,subCopyHyper,sublen,3*rnd*sizeof(int),2); *map=QDP_create_map_L(rlat,slat,mapCopyHyper,rof,(3*rnd+2*snd)*sizeof(int)); }