Grid 0.7.0
Lebesgue.cc
Go to the documentation of this file.
1#if 0
2/*************************************************************************************
3
4 Grid physics library, www.github.com/paboyle/Grid
5
6 Source file: ./lib/stencil/Lebesgue.cc
7
8 Copyright (C) 2015
9
10Author: Peter Boyle <paboyle@ph.ed.ac.uk>
11Author: paboyle <paboyle@ph.ed.ac.uk>
12
13 This program is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation; either version 2 of the License, or
16 (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
22
23 You should have received a copy of the GNU General Public License along
24 with this program; if not, write to the Free Software Foundation, Inc.,
25 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26
27 See the full license in the file "LICENSE" in the top level distribution directory
28*************************************************************************************/
29/* END LEGAL */
30#include <Grid/GridCore.h>
31#include <algorithm>
32
34
36#ifdef KNL
37std::vector<int> LebesgueOrder::Block({8,2,2,2});
38#else
39std::vector<int> LebesgueOrder::Block({2,2,2,2});
40#endif
42 n--; // 1000 0011 --> 1000 0010
43 n |= n >> 1; // 1000 0010 | 0100 0001 = 1100 0011
44 n |= n >> 2; // 1100 0011 | 0011 0000 = 1111 0011
45 n |= n >> 4; // 1111 0011 | 0000 1111 = 1111 1111
46 n |= n >> 8; // ... (At this point all bits are 1, so further bitwise-or
47 n |= n >> 16; // operations produce no effect.)
48 n++; // 1111 1111 --> 1 0000 0000
49 return n;
50};
51
53{
54 grid = _grid;
55 if ( Block[0]==0) ZGraph();
56 else if ( Block[1]==0) NoBlocking();
57 else CartesianBlocking();
58
59 if (0) {
60 std::cout << "Thread Interleaving"<<std::endl;
62 }
63}
65{
67 Vector<IndexInteger> throrder;
68 int vol = _LebesgueReorder.size();
69 int threads = GridThread::GetThreads();
70 int blockbits=3;
71 // int blocklen = 8;
72 // int msk = 0x7;
73
74 for(int t=0;t<threads;t++){
75 for(int ss=0;ss<vol;ss++){
76 if ( ( ss >> blockbits) % threads == t ) {
77 throrder.push_back(reorder[ss]);
78 }
79 }
80 }
81 _LebesgueReorder = throrder;
82}
84{
85 std::cout<<GridLogDebug<<"Lexicographic : no cache blocking"<<std::endl;
86 _LebesgueReorder.resize(0);
87 for ( int s = 0 ; s!= grid->oSites();s++){
88 _LebesgueReorder.push_back(s);
89 }
90}
92{
93 _LebesgueReorder.resize(0);
94
95 // std::cout << GridLogDebug << " CartesianBlocking ";
96 // for(int d=0;d<Block.size();d++) std::cout <<Block[d]<<" ";
97 // std::cout<<std::endl;
98
99 IndexInteger ND = grid->_ndimension;
100
101 assert(ND==4);
102 assert(ND==Block.size());
103
104 Coordinate dims(ND);
105 Coordinate xo(ND,0);
106 Coordinate xi(ND,0);
107
108 for(IndexInteger mu=0;mu<ND;mu++){
109 dims[mu] = grid->_rdimensions[mu];
110 }
111
112 IterateO(ND,ND-1,xo,xi,dims);
113};
114
115void LebesgueOrder::IterateO(int ND,int dim,
116 Coordinate & xo,
117 Coordinate & xi,
118 Coordinate &dims)
119{
120 for(xo[dim]=0;xo[dim]<dims[dim];xo[dim]+=Block[dim]){
121 if ( dim > 0 ) {
122 IterateO(ND,dim-1,xo,xi,dims);
123 } else {
124 IterateI(ND,ND-1,xo,xi,dims);
125 }
126 }
127};
128
129void LebesgueOrder::IterateI(int ND,
130 int dim,
131 Coordinate & xo,
132 Coordinate & xi,
133 Coordinate &dims)
134{
135 Coordinate x(ND);
136 for(xi[dim]=0;xi[dim]<std::min(dims[dim]-xo[dim],Block[dim]);xi[dim]++){
137 if ( dim > 0 ) {
138 IterateI(ND,dim-1,xo,xi,dims);
139 } else {
140 for(int d=0;d<ND;d++){
141 x[d]=xi[d]+xo[d];
142 // std::cout << x[d]<<" ";
143 }
144 // std::cout << "\n";
145 IndexInteger index;
146 Lexicographic::IndexFromCoor(x,index,grid->_rdimensions);
147 _LebesgueReorder.push_back(index);
148 }
149 }
150}
151
152void LebesgueOrder::ZGraph(void)
153{
154 _LebesgueReorder.resize(0);
155
156 std::cout << GridLogDebug << " Lebesgue order "<<std::endl;
157 // Align up dimensions to power of two.
158 const IndexInteger one=1;
159
160 IndexInteger ND = grid->_ndimension;
161 Coordinate dims(ND);
162 Coordinate adims(ND);
163 std::vector<std::vector<IndexInteger> > bitlist(ND);
164
165 for(IndexInteger mu=0;mu<ND;mu++){
166 dims[mu] = grid->_rdimensions[mu];
167 assert ( dims[mu] != 0 );
168 adims[mu] = alignup(dims[mu]);
169 }
170
171 // List which bits of padded volume coordinate contribute; this strategy
172 // i) avoids recursion
173 // ii) has loop lengths at most the width of a 32 bit word.
174 int sitebit=0;
175 for(int bit=0;bit<32;bit++){
176 IndexInteger mask = one<<bit;
177 for(int mu=0;mu<ND;mu++){ // mu 0 takes bit 0; mu 1 takes bit 1 etc...
178 if ( mask&(adims[mu]-1) ){
179 bitlist[mu].push_back(sitebit);
180 sitebit++;
181 }
182 }
183 }
184
185 // Work out padded and unpadded volumes
186 IndexInteger avol = 1;
187 for(int mu=0;mu<ND;mu++) avol = avol * adims[mu];
188
189 IndexInteger vol = 1;
190 for(int mu=0;mu<ND;mu++) vol = vol * dims[mu];
191
192 // Loop over padded volume, following Lebesgue curve
193 // We interleave the bits from sequential "mu".
194 std::vector<IndexInteger> ax(ND);
195
196 for(IndexInteger asite=0;asite<avol;asite++){
197
198 // Start with zero and collect bits
199 for(int mu=0;mu<ND;mu++) ax[mu] = 0;
200
201 int contained = 1;
202 for(int mu=0;mu<ND;mu++){
203
204 // Build the coordinate on the aligned volume
205 for(int bit=0;bit<bitlist[mu].size();bit++){
206 int sbit=bitlist[mu][bit];
207
208 if(asite&(one<<sbit)){
209 ax[mu]|=one<<bit;
210 }
211 }
212
213 // Is it contained in original box
214 if ( ax[mu]>dims[mu]-1 ) contained = 0;
215
216 }
217
218 if ( contained ) {
219 int site = ax[0]
220 + dims[0]*ax[1]
221 +dims[0]*dims[1]*ax[2]
222 +dims[0]*dims[1]*dims[2]*ax[3];
223
224 assert(site < vol);
225 _LebesgueReorder.push_back(site);
226 }
227 }
228 assert( _LebesgueReorder.size() == vol );
229
230 /*
231 std::vector<int> coor(4);
232 for(IndexInteger asite=0;asite<vol;asite++){
233 grid->oCoorFromOindex (coor,_LebesgueReorder[asite]);
234 std::cout << " site "<<asite << "->" << _LebesgueReorder[asite]<< " = ["
235 << coor[0]<<","
236 << coor[1]<<","
237 << coor[2]<<","
238 << coor[3]<<"]"
239 <<std::endl;
240 }
241 */
242}
244
245#endif
std::vector< T, uvmAllocator< T > > Vector
#define one
Definition BGQQPX.h:108
AcceleratorVector< int, MaxDims > Coordinate
Definition Coordinate.h:95
GridLogger GridLogDebug(1, "Debug", GridLogColours, "PURPLE")
#define NAMESPACE_BEGIN(A)
Definition Namespace.h:35
#define NAMESPACE_END(A)
Definition Namespace.h:36
static int GetThreads(void)
void CartesianBlocking(void)
static int UseLebesgueOrder
Definition Lebesgue.h:41
void ZGraph(void)
LebesgueOrder(GridBase *_grid)
deviceVector< IndexInteger > _LebesgueReorder
Definition Lebesgue.h:75
void ThreadInterleave(void)
static std::vector< int > Block
Definition Lebesgue.h:60
int32_t IndexInteger
Definition Lebesgue.h:40
void IterateI(int ND, int dim, Coordinate &xo, Coordinate &xi, Coordinate &dims)
GridBase * grid
Definition Lebesgue.h:42
void NoBlocking(void)
void IterateO(int ND, int dim, Coordinate &xo, Coordinate &xi, Coordinate &dims)
IndexInteger alignup(IndexInteger n)