/************************************************************************************* 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_BEGIN(Grid); int LebesgueOrder::UseLebesgueOrder; #ifdef KNL std::vector LebesgueOrder::Block({8,2,2,2}); #else std::vector LebesgueOrder::Block({2,2,2,2}); #endif 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 if ( Block[1]==0) NoBlocking(); else CartesianBlocking(); if (0) { std::cout << "Thread Interleaving"< reorder = _LebesgueReorder; std::vector throrder; int vol = _LebesgueReorder.size(); int threads = GridThread::GetThreads(); int blockbits=3; // int blocklen = 8; // int msk = 0x7; for(int t=0;t> blockbits) % threads == t ) { throrder.push_back(reorder[ss]); } } } _LebesgueReorder = throrder; } void LebesgueOrder::NoBlocking(void) { std::cout<oSites();s++){ _LebesgueReorder.push_back(s); } } void LebesgueOrder::CartesianBlocking(void) { _LebesgueReorder.resize(0); // std::cout << GridLogDebug << " CartesianBlocking "; // for(int d=0;d_ndimension; assert(ND==4); assert(ND==Block.size()); Coordinate dims(ND); Coordinate xo(ND,0); Coordinate xi(ND,0); for(IndexInteger mu=0;mu_rdimensions[mu]; } IterateO(ND,ND-1,xo,xi,dims); }; void LebesgueOrder::IterateO(int ND,int dim, Coordinate & xo, Coordinate & xi, Coordinate &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, Coordinate & xo, Coordinate & xi, Coordinate &dims) { Coordinate x(ND); for(xi[dim]=0;xi[dim] 0 ) { IterateI(ND,dim-1,xo,xi,dims); } else { for(int d=0;d_rdimensions); _LebesgueReorder.push_back(index); } } } void LebesgueOrder::ZGraph(void) { _LebesgueReorder.resize(0); std::cout << GridLogDebug << " Lebesgue order "<_ndimension; Coordinate dims(ND); Coordinate 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]<<"]" <