#ifndef GRID_SUMMATION_H #define GRID_SUMMATION_H namespace Grid { inline void subdivides(GridBase *coarse,GridBase *fine) { assert(coarse->_ndimension == fine->_ndimension); int _ndimension = coarse->_ndimension; // local and global volumes subdivide cleanly after SIMDization for(int d=0;d<_ndimension;d++){ assert(coarse->_processors[d] == fine->_processors[d]); assert(coarse->_simd_layout[d] == fine->_simd_layout[d]); assert((fine->_rdimensions[d] / coarse->_rdimensions[d])* coarse->_rdimensions[d]==fine->_rdimensions[d]); } } // useful in multigrid project; // Generic name : Coarsen? template inline void sumBlocks(Lattice &coarseData,const Lattice &fineData) { GridBase * fine = fineData._grid; GridBase * coarse= coarseData._grid; subdivides(coarse,fine); // require they map int _ndimension = coarse->_ndimension; std::vector block_r (_ndimension); /////////////////////////////////////////////////////////// // Detect whether the result is replicated in dimension d /////////////////////////////////////////////////////////// for(int d=0 ; d<_ndimension;d++){ block_r[d] = fine->_rdimensions[d] / coarse->_rdimensions[d]; } coarseData=zero; for(int sf=0;sfoSites();sf++){ int sc; std::vector coor_c(_ndimension); std::vector coor_f(_ndimension); GridBase::CoorFromIndex(coor_f,sf,fine->_rdimensions); for(int d=0;d<_ndimension;d++) coor_c[d]=coor_f[d]/block_r[d]; GridBase::IndexFromCoor(coor_c,sc,coarse->_rdimensions); coarseData._odata[sc]=coarseData._odata[sc]+fineData._odata[sf]; } return; } template inline void sliceSum(const Lattice &Data,std::vector &result,int orthogdim) { typedef typename vobj::scalar_object sobj; GridBase *grid = Data._grid; const int Nd = grid->_ndimension; const int Nsimd = grid->Nsimd(); assert(orthogdim >= 0); assert(orthogdim < Nd); int fd=grid->_fdimensions[orthogdim]; int ld=grid->_ldimensions[orthogdim]; int rd=grid->_rdimensions[orthogdim]; std::vector > lvSum(rd); // will locally sum vectors first std::vector lsSum(ld,sobj(zero)); // sum across these down to scalars std::vector extracted(Nsimd); // splitting the SIMD result.resize(fd); // And then global sum to return the same vector to every node for IO to file for(int r=0;r coor(Nd); // sum over reduced dimension planes, breaking out orthog dir for(int ss=0;ssoSites();ss++){ GridBase::CoorFromIndex(coor,ss,grid->_rdimensions); int r = coor[orthogdim]; lvSum[r]=lvSum[r]+Data._odata[ss]; } // Sum across simd lanes in the plane, breaking out orthog dir. std::vector icoor(Nd); for(int rt=0;rtiCoorFromIindex(icoor,idx); int ldx =rt+icoor[orthogdim]*rd; lsSum[ldx]=lsSum[ldx]+extracted[idx]; } } // sum over nodes. sobj gsum; for(int t=0;t_processor_coor[orthogdim] ) { gsum=lsSum[lt]; } else { gsum=zero; } grid->GlobalSum(gsum); result[t]=gsum; } } } #endif