Grid 0.7.0
Cartesian_base.h
Go to the documentation of this file.
1/*************************************************************************************
2
3 Grid physics library, www.github.com/paboyle/Grid
4
5 Source file: ./lib/cartesian/Cartesian_base.h
6
7 Copyright (C) 2015
8
9 Author: Peter Boyle <paboyle@ph.ed.ac.uk>
10 Author: paboyle <paboyle@ph.ed.ac.uk>
11 Author: Guido Cossu <guido.cossu@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#ifndef GRID_CARTESIAN_BASE_H
31#define GRID_CARTESIAN_BASE_H
32
34
36// Commicator provides information on the processor grid
38// unsigned long _ndimension;
39// Coordinate _processors; // processor grid
40// int _processor; // linear processor rank
41// Coordinate _processor_coor; // linear processor rank
43class GridBase : public CartesianCommunicator , public GridThread {
44
45public:
46 int dummy;
47 // Give Lattice access
48 template<class object> friend class Lattice;
49
50 GridBase(const Coordinate & processor_grid) : CartesianCommunicator(processor_grid) { LocallyPeriodic=0;};
51
52 GridBase(const Coordinate & processor_grid,
53 const CartesianCommunicator &parent,
54 int &split_rank)
55 : CartesianCommunicator(processor_grid,parent,split_rank) {LocallyPeriodic=0;};
56
57 GridBase(const Coordinate & processor_grid,
58 const CartesianCommunicator &parent)
59 : CartesianCommunicator(processor_grid,parent,dummy) {LocallyPeriodic=0;};
60
61 virtual ~GridBase() = default;
62
63 // Physics Grid information.
64 Coordinate _simd_layout;// Which dimensions get relayed out over simd lanes.
65 Coordinate _fdimensions;// (full) Global dimensions of array prior to cb removal
66 Coordinate _gdimensions;// Global dimensions of array after cb removal
67 Coordinate _ldimensions;// local dimensions of array with processor images removed
68 Coordinate _rdimensions;// Reduced local dimensions with simd lane images and processor images removed
69 Coordinate _ostride; // Outer stride for each dimension
70 Coordinate _istride; // Inner stride i.e. within simd lane
71 int _osites; // _isites*_osites = product(dimensions).
73 int64_t _fsites; // _isites*_osites = product(dimensions).
74 int64_t _gsites;
75 Coordinate _slice_block;// subslice information
78
79 Coordinate _lstart; // local start of array in gcoors _processor_coor[d]*_ldimensions[d]
80 Coordinate _lend ; // local end of array in gcoors _processor_coor[d]*_ldimensions[d]+_ldimensions_[d]-1
81
86
87public:
88
90 // Checkerboarding interface is virtual and overridden by
91 // GridCartesian / GridRedBlackCartesian
93 virtual int CheckerBoarded(int dim) =0;
94 virtual int CheckerBoard(const Coordinate &site)=0;
95 virtual int CheckerBoardDestination(int source_cb,int shift,int dim)=0;
96 virtual int CheckerBoardShift(int source_cb,int dim,int shift,int osite)=0;
97 virtual int CheckerBoardShiftForCB(int source_cb,int dim,int shift,int cb)=0;
98 virtual int CheckerBoardFromOindex (int Oindex)=0;
99 virtual int CheckerBoardFromOindexTable (int Oindex)=0;
100
102 // Local layout calculations
104 // These routines are key. Subdivide the linearised cartesian index into
105 // "inner" index identifying which simd lane of object<vFcomplex> is associated with coord
106 // "outer" index identifying which element of _odata in class "Lattice" is associated with coord.
107 //
108 // Compared to, say, Blitz++ we simply need to store BOTH an inner stride and an outer
109 // stride per dimension. The cost of evaluating the indexing information is doubled for an n-dimensional
110 // coordinate. Note, however, for data parallel operations the "inner" indexing cost is not paid and all
111 // lanes are operated upon simultaneously.
112
113 virtual int oIndex(Coordinate &coor)
114 {
115 int idx=0;
116 // Works with either global or local coordinates
117 for(int d=0;d<_ndimension;d++) idx+=_ostride[d]*(coor[d]%_rdimensions[d]);
118 return idx;
119 }
120 virtual int iIndex(Coordinate &lcoor)
121 {
122 int idx=0;
123 for(int d=0;d<_ndimension;d++) idx+=_istride[d]*(lcoor[d]/_rdimensions[d]);
124 return idx;
125 }
126 inline int oIndexReduced(Coordinate &ocoor)
127 {
128 int idx=0;
129 // ocoor is already reduced so can eliminate the modulo operation
130 // for fast indexing and inline the routine
131 for(int d=0;d<_ndimension;d++) idx+=_ostride[d]*ocoor[d];
132 return idx;
133 }
134 inline void oCoorFromOindex (Coordinate& coor,int Oindex){
135 Lexicographic::CoorFromIndex(coor,Oindex,_rdimensions);
136 }
137
138 inline void InOutCoorToLocalCoor (Coordinate &ocoor, Coordinate &icoor, Coordinate &lcoor) {
139 lcoor.resize(_ndimension);
140 for (int d = 0; d < _ndimension; d++)
141 lcoor[d] = ocoor[d] + _rdimensions[d] * icoor[d];
142 }
143
145 // SIMD lane addressing
147 inline void iCoorFromIindex(Coordinate &coor,int lane)
148 {
149 Lexicographic::CoorFromIndex(coor,lane,_simd_layout);
150 }
151
152 inline int PermuteDim(int dimension){
153 return _simd_layout[dimension]>1;
154 }
155 inline int PermuteType(int dimension){
156 int permute_type=0;
157 //
158 // Best way to encode this would be to present a mask
159 // for which simd dimensions are rotated, and the rotation
160 // size. If there is only one simd dimension rotated, this is just
161 // a permute.
162 //
163 // Cases: PermuteType == 1,2,4,8
164 // Distance should be either 0,1,2..
165 //
166 if ( _simd_layout[dimension] > 2 ) {
167 for(int d=0;d<_ndimension;d++){
168 if ( d != dimension ) assert ( (_simd_layout[d]==1) );
169 }
170 permute_type = RotateBit; // How to specify distance; this is not just direction.
171 return permute_type;
172 }
173
174 for(int d=_ndimension-1;d>dimension;d--){
175 if (_simd_layout[d]>1 ) permute_type++;
176 }
177 return permute_type;
178 }
179
180 // Array sizing queries
182
183 inline int iSites(void) const { return _isites; };
184 inline int Nsimd(void) const { return _isites; };// Synonymous with iSites
185 inline int oSites(void) const { return _osites; };
186 inline int lSites(void) const { return _isites*_osites; };
187 inline int64_t gSites(void) const { return (int64_t)_isites*(int64_t)_osites*(int64_t)_Nprocessors; };
188 inline int Nd (void) const { return _ndimension;};
189
190 inline const Coordinate LocalStarts(void) { return _lstart; };
191 inline const Coordinate &FullDimensions(void) { return _fdimensions;};
192 inline const Coordinate &GlobalDimensions(void) { return _gdimensions;};
193 inline const Coordinate &LocalDimensions(void) { return _ldimensions;};
194 inline const Coordinate &VirtualLocalDimensions(void) { return _ldimensions;};
195
197 // Utility to print the full decomposition details
199
201 std::cout << GridLogMessage << "\tFull Dimensions : " << _fdimensions << std::endl;
202 std::cout << GridLogMessage << "\tSIMD layout : " << _simd_layout << std::endl;
203 std::cout << GridLogMessage << "\tGlobal Dimensions : " << _gdimensions << std::endl;
204 std::cout << GridLogMessage << "\tLocal Dimensions : " << _ldimensions << std::endl;
205 std::cout << GridLogMessage << "\tReduced Dimensions : " << _rdimensions << std::endl;
206 std::cout << GridLogMessage << "\tOuter strides : " << _ostride << std::endl;
207 std::cout << GridLogMessage << "\tInner strides : " << _istride << std::endl;
208 std::cout << GridLogMessage << "\tiSites : " << _isites << std::endl;
209 std::cout << GridLogMessage << "\toSites : " << _osites << std::endl;
210 std::cout << GridLogMessage << "\tlSites : " << lSites() << std::endl;
211 std::cout << GridLogMessage << "\tgSites : " << gSites() << std::endl;
212 std::cout << GridLogMessage << "\tNd : " << _ndimension << std::endl;
213 }
214
216 // Global addressing
218 void GlobalIndexToGlobalCoor(int64_t gidx,Coordinate &gcoor){
219 assert(gidx< gSites());
220 Lexicographic::CoorFromIndex(gcoor,gidx,_gdimensions);
221 }
222 void LocalIndexToLocalCoor(int lidx,Coordinate &lcoor){
223 assert(lidx<lSites());
224 Lexicographic::CoorFromIndex(lcoor,lidx,_ldimensions);
225 }
226 void GlobalCoorToGlobalIndex(const Coordinate & gcoor,int64_t & gidx){
227 gidx=0;
228 int mult=1;
229 for(int mu=0;mu<_ndimension;mu++) {
230 gidx+=mult*gcoor[mu];
231 mult*=_gdimensions[mu];
232 }
233 }
235 {
236 pcoor.resize(_ndimension);
237 lcoor.resize(_ndimension);
238 for(int mu=0;mu<_ndimension;mu++){
239 int _fld = _fdimensions[mu]/_processors[mu];
240 pcoor[mu] = gcoor[mu]/_fld;
241 lcoor[mu] = gcoor[mu]%_fld;
242 }
243 }
244 void GlobalCoorToRankIndex(int &rank, int &o_idx, int &i_idx ,const Coordinate &gcoor)
245 {
246 Coordinate pcoor;
247 Coordinate lcoor;
248 GlobalCoorToProcessorCoorLocalCoor(pcoor,lcoor,gcoor);
249 rank = RankFromProcessorCoor(pcoor);
250 /*
251 Coordinate cblcoor(lcoor);
252 for(int d=0;d<cblcoor.size();d++){
253 if( this->CheckerBoarded(d) ) {
254 cblcoor[d] = lcoor[d]/2;
255 }
256 }
257 */
258 i_idx= iIndex(lcoor);
259 o_idx= oIndex(lcoor);
260 }
261
262 void RankIndexToGlobalCoor(int rank, int o_idx, int i_idx , Coordinate &gcoor)
263 {
264 gcoor.resize(_ndimension);
266
267 ProcessorCoorFromRank(rank,coor);
268 for(int mu=0;mu<_ndimension;mu++) gcoor[mu] = _ldimensions[mu]*coor[mu];
269
270 iCoorFromIindex(coor,i_idx);
271 for(int mu=0;mu<_ndimension;mu++) gcoor[mu] += _rdimensions[mu]*coor[mu];
272
273 oCoorFromOindex (coor,o_idx);
274 for(int mu=0;mu<_ndimension;mu++) gcoor[mu] += coor[mu];
275
276 }
277 void RankIndexCbToFullGlobalCoor(int rank, int o_idx, int i_idx, int cb,Coordinate &fcoor)
278 {
279 RankIndexToGlobalCoor(rank,o_idx,i_idx ,fcoor);
280 if(CheckerBoarded(0)){
281 fcoor[0] = fcoor[0]*2+cb;
282 }
283 }
285 {
286 gcoor.resize(_ndimension);
287 for(int mu=0;mu<_ndimension;mu++) gcoor[mu] = Pcoor[mu]*_ldimensions[mu]+Lcoor[mu];
288 }
289};
290
292#endif
AcceleratorVector< int, MaxDims > Coordinate
Definition Coordinate.h:95
void mult(Lattice< obj1 > &ret, const Lattice< obj2 > &lhs, const Lattice< obj3 > &rhs)
GridLogger GridLogMessage(1, "Message", GridLogColours, "NORMAL")
#define NAMESPACE_BEGIN(A)
Definition Namespace.h:35
#define NAMESPACE_END(A)
Definition Namespace.h:36
#define RotateBit
Definition Simd.h:54
accelerator_inline void resize(size_type sz)
Definition Coordinate.h:54
void ProcessorCoorFromRank(int rank, Coordinate &coor)
CartesianCommunicator(const Coordinate &processors, const CartesianCommunicator &parent, int &srank)
int RankFromProcessorCoor(Coordinate &coor)
void LocalIndexToLocalCoor(int lidx, Coordinate &lcoor)
GridBase(const Coordinate &processor_grid, const CartesianCommunicator &parent, int &split_rank)
Coordinate _lstart
int PermuteDim(int dimension)
friend class Lattice
const Coordinate & GlobalDimensions(void)
Coordinate _slice_stride
Coordinate _fdimensions
Coordinate _lend
virtual int CheckerBoardFromOindex(int Oindex)=0
int oIndexReduced(Coordinate &ocoor)
int64_t gSites(void) const
int PermuteType(int dimension)
virtual int oIndex(Coordinate &coor)
Coordinate _istride
Coordinate _slice_nblock
void GlobalCoorToRankIndex(int &rank, int &o_idx, int &i_idx, const Coordinate &gcoor)
Coordinate _slice_block
int lSites(void) const
Coordinate _checker_dim_mask
virtual int CheckerBoarded(int dim)=0
bool _isCheckerBoarded
void InOutCoorToLocalCoor(Coordinate &ocoor, Coordinate &icoor, Coordinate &lcoor)
int64_t _fsites
GridBase(const Coordinate &processor_grid)
virtual int CheckerBoard(const Coordinate &site)=0
int LocallyPeriodic
int oSites(void) const
void oCoorFromOindex(Coordinate &coor, int Oindex)
Coordinate _rdimensions
void show_decomposition()
virtual ~GridBase()=default
void GlobalCoorToProcessorCoorLocalCoor(Coordinate &pcoor, Coordinate &lcoor, const Coordinate &gcoor)
virtual int CheckerBoardFromOindexTable(int Oindex)=0
int Nd(void) const
void GlobalCoorToGlobalIndex(const Coordinate &gcoor, int64_t &gidx)
void RankIndexToGlobalCoor(int rank, int o_idx, int i_idx, Coordinate &gcoor)
virtual int CheckerBoardShift(int source_cb, int dim, int shift, int osite)=0
virtual int iIndex(Coordinate &lcoor)
Coordinate _simd_layout
const Coordinate & FullDimensions(void)
void ProcessorCoorLocalCoorToGlobalCoor(Coordinate &Pcoor, Coordinate &Lcoor, Coordinate &gcoor)
Coordinate _ostride
void RankIndexCbToFullGlobalCoor(int rank, int o_idx, int i_idx, int cb, Coordinate &fcoor)
void GlobalIndexToGlobalCoor(int64_t gidx, Coordinate &gcoor)
Coordinate _ldimensions
const Coordinate & LocalDimensions(void)
virtual int CheckerBoardDestination(int source_cb, int shift, int dim)=0
const Coordinate LocalStarts(void)
Coordinate _gdimensions
void iCoorFromIindex(Coordinate &coor, int lane)
GridBase(const Coordinate &processor_grid, const CartesianCommunicator &parent)
virtual int CheckerBoardShiftForCB(int source_cb, int dim, int shift, int cb)=0
const Coordinate & VirtualLocalDimensions(void)
int64_t _gsites
int iSites(void) const
int Nsimd(void) const