QUDA  v0.7.0
A library for QCD on GPUs
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
clover_field_order.h
Go to the documentation of this file.
1 #include <register_traits.h>
2 #include <clover_field.h>
3 
4 namespace quda {
5 
55  template <typename Float, int length, int N>
56  struct FloatNOrder {
57  typedef typename mapper<Float>::type RegType;
59  float *norm[2];
60  const int volumeCB;
61  const int stride;
62 
63  /* NEW FOR CLOVER + TWISTED MASS (ALEX) */
64 
65  const bool twisted;
66  const Float mu2;
67 
68  FloatNOrder(const CloverField &clover, bool inverse, Float *clover_=0, float *norm_=0) : volumeCB(clover.VolumeCB()), stride(clover.Stride()),
69  twisted(clover.Twisted()), mu2(clover.Mu2()) {
70  this->clover[0] = clover_ ? clover_ : (Float*)(clover.V(inverse));
71  this->clover[1] = (Float*)((char*)this->clover[0] + clover.Bytes()/2);
72  this->norm[0] = norm_ ? norm_ : (float*)(clover.Norm(inverse));
73  this->norm[1] = (float*)((char*)this->norm[0] + clover.NormBytes()/2);
74  }
75 
76  bool Twisted() const {return twisted;}
77  Float Mu2() const {return mu2;}
78 
79  /* END OF MODIFICATIONS */
80 
81  __device__ __host__ inline void load(RegType v[length], int x, int parity) const {
82  const int M=length/(N*2);
83  for (int chirality=0; chirality<2; chirality++) {
84  for (int i=0; i<M; i++) {
85  for (int j=0; j<N; j++) {
86  int intIdx = (chirality*M + i)*N + j; // internal dof index
87  int padIdx = intIdx / N;
88  copy(v[(chirality*M+i)*N+j], clover[parity][(padIdx*stride + x)*N + intIdx%N]);
89  if (sizeof(Float)==sizeof(short)) v[(chirality*M+i)*N+j] *= norm[parity][chirality*volumeCB + x];
90  }
91  }
92  }
93  }
94 
95  __device__ __host__ inline void save(const RegType v[length], int x, int parity) {
96  // find the norm of each chiral block
97  RegType scale[2];
98  if (sizeof(Float)==sizeof(short)) {
99  const int M = length/2;
100  for (int chi=0; chi<2; chi++) { // chirality
101  scale[chi] = 0.0;
102  for (int i=0; i<M; i++)
103  scale[chi] = fabs(v[chi*M+i]) > scale[chi] ? fabs(v[chi*M+i]) : scale[chi];
104  norm[parity][chi*volumeCB + x] = scale[chi];
105  }
106  }
107 
108  const int M=length/(N*2);
109  for (int chirality=0; chirality<2; chirality++) {
110  for (int i=0; i<M; i++) {
111  for (int j=0; j<N; j++) {
112  int intIdx = (chirality*M + i)*N + j;
113  int padIdx = intIdx / N;
114  if (sizeof(Float)==sizeof(short))
115  copy(clover[parity][(padIdx*stride + x)*N + intIdx%N], v[(chirality*M+i)*N+j] / scale[chirality]);
116  else
117  copy(clover[parity][(padIdx*stride + x)*N + intIdx%N], v[(chirality*M+i)*N+j]);
118  }
119  }
120  }
121  }
122 
123  size_t Bytes() const {
124  size_t bytes = length*sizeof(Float);
125  if (sizeof(Float)==sizeof(short)) bytes += 2*sizeof(float);
126  return bytes;
127  }
128  };
129 
133  template <typename Float, int length>
134  struct QDPOrder {
135  typedef typename mapper<Float>::type RegType;
137  const int volumeCB;
138  const int stride;
139 
140  /* NEW FOR CLOVER + TWISTED MASS (ALEX) */
141 
142  const bool twisted;
143  const Float mu2;
144 
145  QDPOrder(const CloverField &clover, bool inverse, Float *clover_=0)
146  : volumeCB(clover.VolumeCB()), stride(volumeCB), twisted(clover.Twisted()), mu2(clover.Mu2()) {
147  this->clover[0] = clover_ ? clover_ : (Float*)(clover.V(inverse));
148  this->clover[1] = (Float*)((char*)this->clover[0] + clover.Bytes()/2);
149  }
150 
151  bool Twisted() const {return twisted;}
152  Float Mu2() const {return mu2;}
153 
154  /* END OF MODIFICATIONS */
155 
156  __device__ __host__ inline void load(RegType v[length], int x, int parity) const {
157  for (int i=0; i<length; i++) v[i] = 0.5*clover[parity][x*length+i]; // factor of 0.5 comes from basis change
158  }
159 
160  __device__ __host__ inline void save(const RegType v[length], int x, int parity) {
161  for (int i=0; i<length; i++) clover[parity][x*length+i] = 2.0*v[i];
162  }
163 
164  size_t Bytes() const { return length*sizeof(Float); }
165  };
166 
170  template <typename Float, int length>
171  struct QDPJITOrder {
172  typedef typename mapper<Float>::type RegType;
175  const int volumeCB;
176  const int stride;
177 
178  /* NEW FOR CLOVER + TWISTED MASS (ALEX) */
179 
180  const bool twisted;
181  const Float mu2;
182 
183  QDPJITOrder(const CloverField &clover, bool inverse, Float *clover_=0)
184  : volumeCB(clover.VolumeCB()), stride(volumeCB), twisted(clover.Twisted()), mu2(clover.Mu2()) {
185  offdiag = clover_ ? ((Float**)clover_)[0] : ((Float**)clover.V(inverse))[0];
186  diag = clover_ ? ((Float**)clover_)[1] : ((Float**)clover.V(inverse))[1];
187  }
188 
189  bool Twisted() const {return twisted;}
190  Float Mu2() const {return mu2;}
191 
192  /* END OF MODIFICATIONS */
193 
194  __device__ __host__ inline void load(RegType v[length], int x, int parity) const {
195  // the factor of 0.5 comes from a basis change
196  for (int chirality=0; chirality<2; chirality++) {
197  // set diagonal elements
198  for (int i=0; i<6; i++) {
199  v[chirality*36 + i] = 0.5*diag[((i*2 + chirality)*2 + parity)*volumeCB + x];
200  }
201 
202  // the off diagonal elements
203  for (int i=0; i<30; i++) {
204  int z = i%2;
205  int off = i/2;
206  const int idtab[15]={0,1,3,6,10,2,4,7,11,5,8,12,9,13,14};
207  v[chirality*36 + 6 + i] = 0.5*offdiag[(((z*15 + idtab[off])*2 + chirality)*2 + parity)*volumeCB + x];
208  }
209  }
210 
211  }
212 
213  __device__ __host__ inline void save(const RegType v[length], int x, int parity) {
214  // the factor of 2.0 comes from undoing the basis change
215  for (int chirality=0; chirality<2; chirality++) {
216  // set diagonal elements
217  for (int i=0; i<6; i++) {
218  diag[((i*2 + chirality)*2 + parity)*volumeCB + x] = 2.0*v[chirality*36 + i];
219  }
220 
221  // the off diagonal elements
222  for (int i=0; i<30; i++) {
223  int z = i%2;
224  int off = i/2;
225  const int idtab[15]={0,1,3,6,10,2,4,7,11,5,8,12,9,13,14};
226  offdiag[(((z*15 + idtab[off])*2 + chirality)*2 + parity)*volumeCB + x] = 2.0*v[chirality*36 + 6 + i];
227  }
228  }
229  }
230 
231  size_t Bytes() const { return length*sizeof(Float); }
232  };
233 
234 
241  template <typename Float, int length>
242  struct BQCDOrder {
243  typedef typename mapper<Float>::type RegType;
245  const int volumeCB;
246  const int stride;
247 
248  /* NEW FOR CLOVER + TWISTED MASS (ALEX) */
249 
250  const bool twisted;
251  const Float mu2;
252 
253  BQCDOrder(const CloverField &clover, bool inverse, Float *clover_=0)
254  : volumeCB(clover.Stride()), stride(volumeCB), twisted(clover.Twisted()), mu2(clover.Mu2()) {
255  this->clover[0] = clover_ ? clover_ : (Float*)(clover.V(inverse));
256  this->clover[1] = (Float*)((char*)this->clover[0] + clover.Bytes()/2);
257  }
258 
259 
260  bool Twisted() const {return twisted;}
261  Float Mu2() const {return mu2;}
262 
263  /* END OF MODIFICATIONS */
264 
265 
271  __device__ __host__ inline void load(RegType v[length], int x, int parity) const {
272  int bq[36] = { 21, 32, 33, 0, 1, 20, // diagonal
273  28, 29, 30, 31, 6, 7, 14, 15, 22, 23, // column 1 6
274  34, 35, 8, 9, 16, 17, 24, 25, // column 2 16
275  10, 11, 18, 19, 26, 27, // column 3 24
276  2, 3, 4, 5, // column 4 30
277  12, 13};
278 
279  // flip the sign of the imaginary components
280  int sign[36];
281  for (int i=0; i<6; i++) sign[i] = 1;
282  for (int i=6; i<36; i+=2) {
283  if ( (i >= 10 && i<= 15) || (i >= 18 && i <= 29) ) { sign[i] = -1; sign[i+1] = -1; }
284  else { sign[i] = 1; sign[i+1] = -1; }
285  }
286 
287  const int M=length/2;
288  for (int chirality=0; chirality<2; chirality++)
289  for (int i=0; i<M; i++)
290  v[chirality*M+i] = sign[i] * clover[parity][x*length+chirality*M+bq[i]];
291 
292  }
293 
294  // FIXME implement the save routine for BQCD ordered fields
295  __device__ __host__ inline void save(RegType v[length], int x, int parity) {
296 
297  };
298 
299  size_t Bytes() const { return length*sizeof(Float); }
300  };
301 
302 
303 }
void * V(bool inverse=false)
Definition: clover_field.h:59
__device__ __host__ void save(const RegType v[length], int x, int parity)
size_t Bytes() const
Definition: clover_field.h:67
__device__ __host__ void save(const RegType v[length], int x, int parity)
__host__ __device__ void copy(T1 &a, const T2 &b)
Float Mu2() const
int length[]
bool Twisted() const
Float Mu2() const
size_t Bytes() const
bool Twisted() const
mapper< Float >::type RegType
QDPJITOrder(const CloverField &clover, bool inverse, Float *clover_=0)
FloatingPoint< float > Float
Definition: gtest.h:7350
bool Twisted() const
size_t Bytes() const
mapper< Float >::type RegType
BQCDOrder(const CloverField &clover, bool inverse, Float *clover_=0)
__device__ __host__ void load(RegType v[length], int x, int parity) const
__device__ __host__ void save(RegType v[length], int x, int parity)
size_t Bytes() const
int x[4]
mapper< Float >::type RegType
void * Norm(bool inverse=false)
Definition: clover_field.h:60
__device__ __host__ void load(RegType v[length], int x, int parity) const
__device__ __host__ void load(RegType v[length], int x, int parity) const
mapper< Float >::type RegType
QDPOrder(const CloverField &clover, bool inverse, Float *clover_=0)
__device__ __host__ void save(const RegType v[length], int x, int parity)
FloatNOrder(const CloverField &clover, bool inverse, Float *clover_=0, float *norm_=0)
size_t NormBytes() const
Definition: clover_field.h:68
__device__ __host__ void load(RegType v[length], int x, int parity) const
const QudaParity parity
Definition: dslash_test.cpp:29
Float Mu2() const
size_t Bytes() const