/************************************************************************************* Grid physics library, www.github.com/paboyle/Grid Source file: ./lib/stencil/Lebesgue.cc Copyright (C) 2015 Author: Peter Boyle Author: paboyle This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. See the full license in the file "LICENSE" in the top level distribution directory *************************************************************************************/ /* END LEGAL */ #include #include namespace Grid { int LebesgueOrder::UseLebesgueOrder; std::vector LebesgueOrder::Block({2,2,2,2}); LebesgueOrder::IndexInteger LebesgueOrder::alignup(IndexInteger n){ n--; // 1000 0011 --> 1000 0010 n |= n >> 1; // 1000 0010 | 0100 0001 = 1100 0011 n |= n >> 2; // 1100 0011 | 0011 0000 = 1111 0011 n |= n >> 4; // 1111 0011 | 0000 1111 = 1111 1111 n |= n >> 8; // ... (At this point all bits are 1, so further bitwise-or n |= n >> 16; // operations produce no effect.) n++; // 1111 1111 --> 1 0000 0000 return n; }; LebesgueOrder::LebesgueOrder(GridBase *_grid) { grid = _grid; if ( Block[0]==0) ZGraph(); else CartesianBlocking(); } void LebesgueOrder::CartesianBlocking(void) { _LebesgueReorder.resize(0); std::cout << GridLogMessage << " CartesianBlocking "; for(int d=0;d_ndimension; assert(ND==4); assert(ND==Block.size()); std::vector dims(ND); std::vector xo(ND,0); std::vector xi(ND,0); for(IndexInteger mu=0;mu_rdimensions[mu]; } IterateO(ND,ND-1,xo,xi,dims); }; void LebesgueOrder::IterateO(int ND,int dim, std::vector & xo, std::vector & xi, std::vector &dims) { for(xo[dim]=0;xo[dim] 0 ) { IterateO(ND,dim-1,xo,xi,dims); } else { IterateI(ND,ND-1,xo,xi,dims); } } }; void LebesgueOrder::IterateI(int ND, int dim, std::vector & xo, std::vector & xi, std::vector &dims) { std::vector x(ND); for(xi[dim]=0;xi[dim] 0 ) { IterateI(ND,dim-1,xo,xi,dims); } else { for(int d=0;dIndexFromCoor(x,index,grid->_rdimensions); _LebesgueReorder.push_back(index); } } } void LebesgueOrder::ZGraph(void) { _LebesgueReorder.resize(0); // Align up dimensions to power of two. const IndexInteger one=1; IndexInteger ND = grid->_ndimension; std::vector dims(ND); std::vector adims(ND); std::vector > bitlist(ND); for(IndexInteger mu=0;mu_rdimensions[mu]; assert ( dims[mu] != 0 ); adims[mu] = alignup(dims[mu]); } // List which bits of padded volume coordinate contribute; this strategy // i) avoids recursion // ii) has loop lengths at most the width of a 32 bit word. int sitebit=0; for(int bit=0;bit<32;bit++){ IndexInteger mask = one< ax(ND); for(IndexInteger asite=0;asitedims[mu]-1 ) contained = 0; } if ( contained ) { int site = ax[0] + dims[0]*ax[1] +dims[0]*dims[1]*ax[2] +dims[0]*dims[1]*dims[2]*ax[3]; assert(site < vol); _LebesgueReorder.push_back(site); } } assert( _LebesgueReorder.size() == vol ); std::vector coor(4); for(IndexInteger asite=0;asiteoCoorFromOindex (coor,_LebesgueReorder[asite]); std::cout << " site "<" << _LebesgueReorder[asite]<< " = [" << coor[0]<<"," << coor[1]<<"," << coor[2]<<"," << coor[3]<<"]" <