QUDA  1.0.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
color_spinor.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <complex_quda.h>
4 #include <quda_matrix.h>
5 
15 namespace quda {
16 
17  template<typename Float, typename T> struct colorspinor_wrapper;
18  template<typename Float, typename T> struct colorspinor_ghost_wrapper;
19 
23  template <typename Float, int Nc, int Ns>
24  struct ColorSpinor {
25 
26  static constexpr int size = Nc * Ns;
27  complex<Float> data[size];
28 
29  __device__ __host__ inline ColorSpinor<Float, Nc, Ns>()
30  {
31 #pragma unroll
32  for (int i = 0; i < size; i++) { data[i] = 0; }
33  }
34 
35  __device__ __host__ inline ColorSpinor<Float, Nc, Ns>(const ColorSpinor<Float, Nc, Ns> &a) {
36 #pragma unroll
37  for (int i = 0; i < size; i++) { data[i] = a.data[i]; }
38  }
39 
40  __device__ __host__ inline ColorSpinor<Float, Nc, Ns>& operator=(const ColorSpinor<Float, Nc, Ns> &a) {
41  if (this != &a) {
42 #pragma unroll
43  for (int i = 0; i < size; i++) { data[i] = a.data[i]; }
44  }
45  return *this;
46  }
47 
48  __device__ __host__ inline ColorSpinor<Float, Nc, Ns> operator-() const
49  {
51 #pragma unroll
52  for (int i = 0; i < size; i++) { a.data[i] = -data[i]; }
53  return a;
54  }
55 
56  __device__ __host__ inline ColorSpinor<Float, Nc, Ns>& operator+=(const ColorSpinor<Float, Nc, Ns> &a) {
57 #pragma unroll
58  for (int i = 0; i < size; i++) { data[i] += a.data[i]; }
59  return *this;
60  }
61 
62  template <typename T> __device__ __host__ inline ColorSpinor<Float, Nc, Ns> &operator*=(const T &a)
63  {
64 #pragma unroll
65  for (int i = 0; i < size; i++) { data[i] *= a; }
66  return *this;
67  }
68 
70  {
71  if (this != &a) {
72 #pragma unroll
73  for (int i = 0; i < Nc * Ns; i++) { data[i] -= a.data[i]; }
74  }
75  return *this;
76  }
77 
78  template<typename S>
79  __device__ __host__ inline ColorSpinor<Float, Nc, Ns>(const colorspinor_wrapper<Float, S> &s);
80 
81  template<typename S>
82  __device__ __host__ inline void operator=(const colorspinor_wrapper<Float, S> &s);
83 
84  template<typename S>
85  __device__ __host__ inline ColorSpinor<Float, Nc, Ns>(const colorspinor_ghost_wrapper<Float, S> &s);
86 
87  template<typename S>
88  __device__ __host__ inline void operator=(const colorspinor_ghost_wrapper<Float, S> &s);
89 
96  __device__ __host__ inline complex<Float>& operator()(int s, int c) { return data[s*Nc + c]; }
97 
104  __device__ __host__ inline const complex<Float>& operator()(int s, int c) const { return data[s*Nc + c]; }
105 
111  __device__ __host__ inline complex<Float>& operator()(int idx) { return data[idx]; }
112 
118  __device__ __host__ inline const complex<Float>& operator()(int idx) const { return data[idx]; }
119 
123  __device__ __host__ void print() const
124  {
125  for (int s=0; s<Ns; s++) {
126  for (int c=0; c<Nc; c++) {
127  printf("s=%d c=%d %e %e\n", s, c, data[s*Nc+c].real(), data[s*Nc+c].imag());
128  }
129  }
130  }
131  };
132 
137  template <typename Float, int Nc> struct ColorSpinor<Float, Nc, 4> {
138  static constexpr int Ns = 4;
139  static constexpr int size = Nc * Ns;
140  complex<Float> data[size];
141 
142  __device__ __host__ inline ColorSpinor<Float, Nc, 4>()
143  {
144 #pragma unroll
145  for (int i = 0; i < size; i++) { data[i] = 0; }
146  }
147 
148  __device__ __host__ inline ColorSpinor<Float, Nc, 4>(const ColorSpinor<Float, Nc, 4> &a) {
149 #pragma unroll
150  for (int i = 0; i < size; i++) { data[i] = a.data[i]; }
151  }
152 
153  __device__ __host__ inline ColorSpinor<Float, Nc, 4>& operator=(const ColorSpinor<Float, Nc, 4> &a) {
154  if (this != &a) {
155 #pragma unroll
156  for (int i = 0; i < size; i++) { data[i] = a.data[i]; }
157  }
158  return *this;
159  }
160 
161  __device__ __host__ inline ColorSpinor<Float, Nc, 4>& operator+=(const ColorSpinor<Float, Nc, 4> &a) {
162 #pragma unroll
163  for (int i = 0; i < size; i++) { data[i] += a.data[i]; }
164  return *this;
165  }
166 
167  template <typename T> __device__ __host__ inline ColorSpinor<Float, Nc, 4> &operator*=(const T &a)
168  {
169 #pragma unroll
170  for (int i = 0; i < size; i++) { data[i] *= a; }
171  return *this;
172  }
173 
179  __device__ __host__ inline ColorSpinor<Float,Nc,4> gamma(int dim) {
181  complex<Float> j(0.0,1.0);
182 
183  switch (dim) {
184  case 0: // x dimension
185 #pragma unroll
186  for (int i=0; i<Nc; i++) {
187  a(0,i) = j*(*this)(3,i);
188  a(1,i) = j*(*this)(2,i);
189  a(2,i) = -j*(*this)(1,i);
190  a(3,i) = -j*(*this)(0,i);
191  }
192  break;
193  case 1: // y dimension
194 #pragma unroll
195  for (int i=0; i<Nc; i++) {
196  a(0,i) = (*this)(3,i);
197  a(1,i) = -(*this)(2,i);
198  a(2,i) = -(*this)(1,i);
199  a(3,i) = (*this)(0,i);
200  }
201  break;
202  case 2: // z dimension
203 #pragma unroll
204  for (int i=0; i<Nc; i++) {
205  a(0,i) = j*(*this)(2,i);
206  a(1,i) = -j*(*this)(3,i);
207  a(2,i) = -j*(*this)(0,i);
208  a(3,i) = j*(*this)(1,i);
209  }
210  break;
211  case 3: // t dimension
212 #pragma unroll
213  for (int i=0; i<Nc; i++) {
214  a(0,i) = (*this)(0,i);
215  a(1,i) = (*this)(1,i);
216  a(2,i) = -(*this)(2,i);
217  a(3,i) = -(*this)(3,i);
218  }
219  break;
220  case 4: // gamma_5
221 #pragma unroll
222  for (int i=0; i<Nc; i++) {
223  a(0,i) = (*this)(2,i);
224  a(1,i) = (*this)(3,i);
225  a(2,i) = (*this)(0,i);
226  a(3,i) = (*this)(1,i);
227  }
228  break;
229  }
230 
231  return a;
232  }
233 
239  __device__ __host__ inline ColorSpinor<Float,Nc,4> igamma(int dim) {
241  complex<Float> j(0.0,1.0);
242 
243  switch (dim) {
244  case 0: // x dimension
245 #pragma unroll
246  for (int i=0; i<Nc; i++) {
247  a(0,i) = -(*this)(3,i);
248  a(1,i) = -(*this)(2,i);
249  a(2,i) = (*this)(1,i);
250  a(3,i) = (*this)(0,i);
251  }
252  break;
253  case 1: // y dimension
254 #pragma unroll
255  for (int i=0; i<Nc; i++) {
256  a(0,i) = j*(*this)(3,i);
257  a(1,i) = -j*(*this)(2,i);
258  a(2,i) = -j*(*this)(1,i);
259  a(3,i) = j*(*this)(0,i);
260  }
261  break;
262  case 2: // z dimension
263 #pragma unroll
264  for (int i=0; i<Nc; i++) {
265  a(0,i) = -(*this)(2,i);
266  a(1,i) = (*this)(3,i);
267  a(2,i) = (*this)(0,i);
268  a(3,i) = -(*this)(1,i);
269  }
270  break;
271  case 3: // t dimension
272 #pragma unroll
273  for (int i=0; i<Nc; i++) {
274  a(0,i) = j*(*this)(0,i);
275  a(1,i) = j*(*this)(1,i);
276  a(2,i) = -j*(*this)(2,i);
277  a(3,i) = -j*(*this)(3,i);
278  }
279  break;
280  case 4: // gamma_5
281 #pragma unroll
282  for (int i=0; i<Nc; i++) {
283  a(0,i) = complex<Float>(-(*this)(2,i).imag(), (*this)(2,i).real());
284  a(1,i) = complex<Float>(-(*this)(3,i).imag(), (*this)(3,i).real());
285  a(2,i) = complex<Float>(-(*this)(0,i).imag(), (*this)(0,i).real());
286  a(3,i) = complex<Float>(-(*this)(1,i).imag(), (*this)(1,i).real());
287  }
288  break;
289  }
290 
291  return a;
292  }
293 
298  __device__ __host__ inline ColorSpinor<Float,Nc,2> chiral_project(int chirality) const {
300 #pragma unroll
301  for (int s=0; s<Ns/2; s++) {
302 #pragma unroll
303  for (int c=0; c<Nc; c++) {
304  proj(s,c) = (*this)(chirality*Ns/2+s,c);
305  }
306  }
307  return proj;
308  }
309 
316  __device__ __host__ inline ColorSpinor<Float, Nc, 2> project(int dim, int sign) const
317  {
319  complex<Float> j(0.0,1.0);
320 
321  switch (dim) {
322  case 0: // x dimension
323  switch (sign) {
324  case 1: // positive projector
325 #pragma unroll
326  for (int i=0; i<Nc; i++) {
327  proj(0,i) = (*this)(0,i) + j * (*this)(3,i);
328  proj(1,i) = (*this)(1,i) + j * (*this)(2,i);
329  }
330  break;
331  case -1: // negative projector
332 #pragma unroll
333  for (int i=0; i<Nc; i++) {
334  proj(0,i) = (*this)(0,i) - j * (*this)(3,i);
335  proj(1,i) = (*this)(1,i) - j * (*this)(2,i);
336  }
337  break;
338  }
339  break;
340  case 1: // y dimension
341  switch (sign) {
342  case 1: // positive projector
343 #pragma unroll
344  for (int i=0; i<Nc; i++) {
345  proj(0,i) = (*this)(0,i) + (*this)(3,i);
346  proj(1,i) = (*this)(1,i) - (*this)(2,i);
347  }
348  break;
349  case -1: // negative projector
350 #pragma unroll
351  for (int i=0; i<Nc; i++) {
352  proj(0,i) = (*this)(0,i) - (*this)(3,i);
353  proj(1,i) = (*this)(1,i) + (*this)(2,i);
354  }
355  break;
356  }
357  break;
358  case 2: // z dimension
359  switch (sign) {
360  case 1: // positive projector
361 #pragma unroll
362  for (int i=0; i<Nc; i++) {
363  proj(0,i) = (*this)(0,i) + j * (*this)(2,i);
364  proj(1,i) = (*this)(1,i) - j * (*this)(3,i);
365  }
366  break;
367  case -1: // negative projector
368 #pragma unroll
369  for (int i=0; i<Nc; i++) {
370  proj(0,i) = (*this)(0,i) - j * (*this)(2,i);
371  proj(1,i) = (*this)(1,i) + j * (*this)(3,i);
372  }
373  break;
374  }
375  break;
376  case 3: // t dimension
377  switch (sign) {
378  case 1: // positive projector
379 #pragma unroll
380  for (int i=0; i<Nc; i++) {
381  proj(0,i) = 2*(*this)(0,i);
382  proj(1,i) = 2*(*this)(1,i);
383  }
384  break;
385  case -1: // negative projector
386 #pragma unroll
387  for (int i=0; i<Nc; i++) {
388  proj(0,i) = 2*(*this)(2,i);
389  proj(1,i) = 2*(*this)(3,i);
390  }
391  break;
392  }
393  break;
394  case 4:
395  switch (sign) {
396  case 1: // positive projector
397 #pragma unroll
398  for (int i = 0; i < Nc; i++) {
399  proj(0, i) = (*this)(0, i) + (*this)(2, i);
400  proj(1, i) = (*this)(1, i) + (*this)(3, i);
401  }
402  break;
403  case -1: // negative projector
404 #pragma unroll
405  for (int i = 0; i < Nc; i++) {
406  proj(0, i) = (*this)(0, i) - (*this)(2, i);
407  proj(1, i) = (*this)(1, i) - (*this)(3, i);
408  }
409  break;
410  }
411  break;
412  }
413 
414  return proj;
415  }
416 
452  __device__ __host__ inline ColorSpinor<Float,Nc,4> sigma(int mu, int nu) {
454  ColorSpinor<Float,Nc,4> &b = *this;
455  complex<Float> j(0.0,1.0);
456 
457  switch(mu) {
458  case 0:
459  switch(nu) {
460  case 1:
461 #pragma unroll
462  for (int i=0; i<Nc; i++) {
463  a(0,i) = j*b(0,i);
464  a(1,i) = -j*b(1,i);
465  a(2,i) = j*b(2,i);
466  a(3,i) = -j*b(3,i);
467  }
468  break;
469  case 2:
470 #pragma unroll
471  for (int i=0; i<Nc; i++) {
472  a(0,i) = -b(1,i);
473  a(1,i) = b(0,i);
474  a(2,i) = -b(3,i);
475  a(3,i) = b(2,i);
476  }
477  break;
478  case 3:
479 #pragma unroll
480  for (int i=0; i<Nc; i++) {
481  a(0,i) = -j*b(3,i);
482  a(1,i) = -j*b(2,i);
483  a(2,i) = -j*b(1,i);
484  a(3,i) = -j*b(0,i);
485  }
486  break;
487  }
488  break;
489  case 1:
490  switch(nu) {
491  case 0:
492 #pragma unroll
493  for (int i=0; i<Nc; i++) {
494  a(0,i) = -j*b(0,i);
495  a(1,i) = j*b(1,i);
496  a(2,i) = -j*b(2,i);
497  a(3,i) = j*b(3,i);
498  }
499  break;
500  case 2:
501 #pragma unroll
502  for (int i=0; i<Nc; i++) {
503  a(0,i) = j*b(1,i);
504  a(1,i) = j*b(0,i);
505  a(2,i) = j*b(3,i);
506  a(3,i) = j*b(2,i);
507  }
508  break;
509  case 3:
510 #pragma unroll
511  for (int i=0; i<Nc; i++) {
512  a(0,i) = -b(3,i);
513  a(1,i) = b(2,i);
514  a(2,i) = -b(1,i);
515  a(3,i) = b(0,i);
516  }
517  break;
518  }
519  break;
520  case 2:
521  switch(nu) {
522  case 0:
523 #pragma unroll
524  for (int i=0; i<Nc; i++) {
525  a(0,i) = b(1,i);
526  a(1,i) = -b(0,i);
527  a(2,i) = b(3,i);
528  a(3,i) = -b(2,i);
529  }
530  break;
531  case 1:
532 #pragma unroll
533  for (int i=0; i<Nc; i++) {
534  a(0,i) = -j*b(1,i);
535  a(1,i) = -j*b(0,i);
536  a(2,i) = -j*b(3,i);
537  a(3,i) = -j*b(2,i);
538  }
539  break;
540  case 3:
541 #pragma unroll
542  for (int i=0; i<Nc; i++) {
543  a(0,i) = -j*b(2,i);
544  a(1,i) = j*b(3,i);
545  a(2,i) = -j*b(0,i);
546  a(3,i) = j*b(1,i);
547  }
548  break;
549  }
550  break;
551  case 3:
552  switch(nu) {
553  case 0:
554 #pragma unroll
555  for (int i=0; i<Nc; i++) {
556  a(0,i) = j*b(3,i);
557  a(1,i) = j*b(2,i);
558  a(2,i) = j*b(1,i);
559  a(3,i) = j*b(0,i);
560  }
561  break;
562  case 1:
563 #pragma unroll
564  for (int i=0; i<Nc; i++) {
565  a(0,i) = b(3,i);
566  a(1,i) = -b(2,i);
567  a(2,i) = b(1,i);
568  a(3,i) = -b(0,i);
569  }
570  break;
571  case 2:
572 #pragma unroll
573  for (int i=0; i<Nc; i++) {
574  a(0,i) = j*b(2,i);
575  a(1,i) = -j*b(3,i);
576  a(2,i) = j*b(0,i);
577  a(3,i) = -j*b(1,i);
578  }
579  break;
580  }
581  break;
582  }
583  return a;
584  }
585 
586 
593  __device__ __host__ inline complex<Float>& operator()(int s, int c) { return data[s*Nc + c]; }
594 
601  __device__ __host__ inline const complex<Float>& operator()(int s, int c) const { return data[s*Nc + c]; }
602 
608  __device__ __host__ inline complex<Float>& operator()(int idx) { return data[idx]; }
609 
615  __device__ __host__ inline const complex<Float>& operator()(int idx) const { return data[idx]; }
616 
617  template<typename S>
618  __device__ __host__ inline ColorSpinor<Float, Nc, Ns>(const colorspinor_wrapper<Float, S> &s);
619 
620  template<typename S>
621  __device__ __host__ inline void operator=(const colorspinor_wrapper<Float, S> &s);
622 
623  template<typename S>
624  __device__ __host__ inline ColorSpinor<Float, Nc, Ns>(const colorspinor_ghost_wrapper<Float, S> &s);
625 
626  template<typename S>
627  __device__ __host__ inline void operator=(const colorspinor_ghost_wrapper<Float, S> &s);
628 
633  __device__ __host__ inline void toNonRel() {
635 #pragma unroll
636  for (int c=0; c<Nc; c++) {
637  a(0,c) = (*this)(1,c)+(*this)(3,c);
638  a(1,c) = -(*this)(2,c)-(*this)(0,c);
639  a(2,c) = -(*this)(3,c)+(*this)(1,c);
640  a(3,c) = -(*this)(0,c)+(*this)(2,c);
641  }
642  *this = a;
643  }
644 
648  __device__ __host__ inline void toRel() {
650 #pragma unroll
651  for (int c=0; c<Nc; c++) {
652  a(0,c) = -(*this)(1,c)-(*this)(3,c);
653  a(1,c) = (*this)(2,c)+(*this)(0,c);
654  a(2,c) = (*this)(3,c)-(*this)(1,c);
655  a(3,c) = (*this)(0,c)-(*this)(2,c);
656  }
657  *this = a;
658  }
659 
660  __device__ __host__ void print() const
661  {
662  for (int s=0; s<Ns; s++) {
663  for (int c=0; c<Nc; c++) {
664  printf("s=%d c=%d %e %e\n", s, c, data[s*Nc+c].real(), data[s*Nc+c].imag());
665  }
666  }
667  }
668  };
669 
674  template <typename Float, int Nc>
675  struct ColorSpinor<Float, Nc, 2> {
676  static constexpr int Ns = 2;
677  static constexpr int size = Ns * Nc;
678  complex<Float> data[size];
679 
680  __device__ __host__ inline ColorSpinor<Float, Nc, 2>() {
681 #pragma unroll
682  for (int i = 0; i < size; i++) { data[i] = 0; }
683  }
684 
685  __device__ __host__ inline ColorSpinor<Float, Nc, 2>(const ColorSpinor<Float, Nc, 2> &a) {
686 #pragma unroll
687  for (int i = 0; i < size; i++) { data[i] = a.data[i]; }
688  }
689 
690 
691  __device__ __host__ inline ColorSpinor<Float, Nc, 2>& operator=(const ColorSpinor<Float, Nc, 2> &a) {
692  if (this != &a) {
693 #pragma unroll
694  for (int i = 0; i < size; i++) { data[i] = a.data[i]; }
695  }
696  return *this;
697  }
698 
699  __device__ __host__ inline ColorSpinor<Float, Nc, 2>& operator+=(const ColorSpinor<Float, Nc, 2> &a) {
700 #pragma unroll
701  for (int i = 0; i < size; i++) { data[i] += a.data[i]; }
702  return *this;
703  }
704 
705  template <typename T> __device__ __host__ inline ColorSpinor<Float, Nc, 2> &operator*=(const T &a)
706  {
707 #pragma unroll
708  for (int i = 0; i < size; i++) { data[i] *= a; }
709  return *this;
710  }
711 
716  __device__ __host__ inline ColorSpinor<Float,Nc,4> chiral_reconstruct(int chirality) const {
718 #pragma unroll
719  for (int s=0; s<Ns; s++) {
720 #pragma unroll
721  for (int c=0; c<Nc; c++) {
722  recon(chirality*Ns+s,c) = (*this)(s,c);
723  }
724  }
725  return recon;
726  }
727 
734  __device__ __host__ inline ColorSpinor<Float, Nc, 4> reconstruct(int dim, int sign) const
735  {
737  complex<Float> j(0.0,1.0);
738 
739  switch (dim) {
740  case 0: // x dimension
741  switch (sign) {
742  case 1: // positive projector
743 #pragma unroll
744  for (int i=0; i<Nc; i++) {
745  recon(0,i) = (*this)(0,i);
746  recon(1,i) = (*this)(1,i);
747  recon(2,i) = -j*(*this)(1,i);
748  recon(3,i) = -j*(*this)(0,i);
749  }
750  break;
751  case -1: // negative projector
752 #pragma unroll
753  for (int i=0; i<Nc; i++) {
754  recon(0,i) = (*this)(0,i);
755  recon(1,i) = (*this)(1,i);
756  recon(2,i) = j*(*this)(1,i);
757  recon(3,i) = j*(*this)(0,i);
758  }
759  break;
760  }
761  break;
762  case 1: // y dimension
763  switch (sign) {
764  case 1: // positive projector
765 #pragma unroll
766  for (int i=0; i<Nc; i++) {
767  recon(0,i) = (*this)(0,i);
768  recon(1,i) = (*this)(1,i);
769  recon(2,i) = -(*this)(1,i);
770  recon(3,i) = (*this)(0,i);
771  }
772  break;
773  case -1: // negative projector
774 #pragma unroll
775  for (int i=0; i<Nc; i++) {
776  recon(0,i) = (*this)(0,i);
777  recon(1,i) = (*this)(1,i);
778  recon(2,i) = (*this)(1,i);
779  recon(3,i) = -(*this)(0,i);
780  }
781  break;
782  }
783  break;
784  case 2: // z dimension
785  switch (sign) {
786  case 1: // positive projector
787 #pragma unroll
788  for (int i=0; i<Nc; i++) {
789  recon(0,i) = (*this)(0,i);
790  recon(1,i) = (*this)(1,i);
791  recon(2,i) = -j*(*this)(0,i);
792  recon(3,i) = j*(*this)(1,i);
793  }
794  break;
795  case -1: // negative projector
796 #pragma unroll
797  for (int i=0; i<Nc; i++) {
798  recon(0,i) = (*this)(0,i);
799  recon(1,i) = (*this)(1,i);
800  recon(2,i) = j*(*this)(0,i);
801  recon(3,i) = -j*(*this)(1,i);
802  }
803  break;
804  }
805  break;
806  case 3: // t dimension
807  switch (sign) {
808  case 1: // positive projector
809 #pragma unroll
810  for (int i=0; i<Nc; i++) {
811  recon(0,i) = (*this)(0,i);
812  recon(1,i) = (*this)(1,i);
813  recon(2,i) = 0;
814  recon(3,i) = 0;
815  }
816  break;
817  case -1: // negative projector
818 #pragma unroll
819  for (int i=0; i<Nc; i++) {
820  recon(0,i) = 0;
821  recon(1,i) = 0;
822  recon(2,i) = (*this)(0,i);
823  recon(3,i) = (*this)(1,i);
824  }
825  break;
826  }
827  break;
828  case 4:
829  switch (sign) {
830  case 1: // positive projector
831 #pragma unroll
832  for (int i = 0; i < Nc; i++) {
833  recon(0, i) = (*this)(0, i);
834  recon(1, i) = (*this)(1, i);
835  recon(2, i) = (*this)(0, i);
836  recon(3, i) = (*this)(1, i);
837  }
838  break;
839  case -1: // negative projector
840 #pragma unroll
841  for (int i = 0; i < Nc; i++) {
842  recon(0, i) = (*this)(0, i);
843  recon(1, i) = (*this)(1, i);
844  recon(2, i) = -(*this)(0, i);
845  recon(3, i) = -(*this)(1, i);
846  }
847  break;
848  }
849  break;
850  }
851  return recon;
852  }
853 
860  __device__ __host__ inline complex<Float>& operator()(int s, int c) { return data[s*Nc + c]; }
861 
868  __device__ __host__ inline const complex<Float>& operator()(int s, int c) const { return data[s*Nc + c]; }
869 
875  __device__ __host__ inline complex<Float>& operator()(int idx) { return data[idx]; }
876 
882  __device__ __host__ inline const complex<Float>& operator()(int idx) const { return data[idx]; }
883 
884  template<typename S>
885  __device__ __host__ inline ColorSpinor<Float, Nc, Ns>(const colorspinor_wrapper<Float, S> &s);
886 
887  template<typename S>
888  __device__ __host__ inline void operator=(const colorspinor_wrapper<Float, S> &s);
889 
890  template<typename S>
891  __device__ __host__ inline ColorSpinor<Float, Nc, Ns>(const colorspinor_ghost_wrapper<Float, S> &s);
892 
893  template<typename S>
894  __device__ __host__ inline void operator=(const colorspinor_ghost_wrapper<Float, S> &s);
895 
896  __device__ __host__ void print() const
897  {
898  for (int s=0; s<Ns; s++) {
899  for (int c=0; c<Nc; c++) {
900  printf("s=%d c=%d %e %e\n", s, c, data[s*Nc+c].real(), data[s*Nc+c].imag());
901  }
902  }
903  }
904  };
905 
913  template <typename Float, int Nc, int Ns>
914  __device__ __host__ inline complex<Float> innerProduct(const ColorSpinor<Float, Nc, Ns> &a,
916  {
917  complex<Float> dot = 0;
918 #pragma unroll
919  for (int s = 0; s < Ns; s++) { dot += innerProduct(a, b, s, s); }
920  return dot;
921  }
922 
931  template <typename Float, int Nc, int Ns>
932  __device__ __host__ inline complex<Float> innerProduct(const ColorSpinor<Float, Nc, Ns> &a,
933  const ColorSpinor<Float, Nc, Ns> &b, int s)
934  {
935  return innerProduct(a, b, s, s);
936  }
937 
947  template <typename Float, int Nc, int Ns>
948  __device__ __host__ inline complex<Float> innerProduct(const ColorSpinor<Float, Nc, Ns> &a,
949  const ColorSpinor<Float, Nc, Ns> &b, int sa, int sb)
950  {
951  complex<Float> dot = 0;
952 #pragma unroll
953  for (int c = 0; c < Nc; c++) {
954  dot.x += a(sa, c).real() * b(sb, c).real();
955  dot.x += a(sa, c).imag() * b(sb, c).imag();
956  dot.y += a(sa, c).real() * b(sb, c).imag();
957  dot.y -= a(sa, c).imag() * b(sb, c).real();
958  }
959  return dot;
960  }
961 
970  template <typename Float, int Nc, int Ns>
971  __device__ __host__ inline complex<Float> innerProduct(const ColorSpinor<Float, Nc, 1> &a,
972  const ColorSpinor<Float, Nc, Ns> &b, int s)
973  {
974  return innerProduct(a, b, 0, s);
975  }
976 
984  template <typename Float, int Nc, int Ns>
985  __device__ __host__ inline Matrix<complex<Float>, Nc> outerProdSpinTrace(const ColorSpinor<Float, Nc, Ns> &a,
987  {
988 
989  Matrix<complex<Float>, Nc> out;
990 
991  // outer product over color
992 #pragma unroll
993  for (int i = 0; i < Nc; i++) {
994 #pragma unroll
995  for (int j = 0; j < Nc; j++) {
996  // trace over spin (manual unroll for perf)
997  out(j, i).real(a(0, j).real() * b(0, i).real());
998  out(j, i).real(out(j, i).real() + a(0, j).imag() * b(0, i).imag());
999  out(j, i).imag(a(0, j).imag() * b(0, i).real());
1000  out(j, i).imag(out(j, i).imag() - a(0, j).real() * b(0, i).imag());
1001  // out(j,i) = a(0,j) * conj(b(0,i));
1002 
1003 #pragma unroll
1004  for (int s=1; s<Ns; s++) {
1005  out(j,i).real( out(j,i).real() + a(s,j).real() * b(s,i).real() );
1006  out(j,i).real( out(j,i).real() + a(s,j).imag() * b(s,i).imag() );
1007  out(j,i).imag( out(j,i).imag() + a(s,j).imag() * b(s,i).real() );
1008  out(j,i).imag( out(j,i).imag() - a(s,j).real() * b(s,i).imag() );
1009  // out(j,i) += a(s,j) * conj(b(s,i));
1010  }
1011  }
1012  }
1013  return out;
1014  }
1015 
1022  template<typename Float, int Nc, int Ns> __device__ __host__ inline
1024 
1026 
1027 #pragma unroll
1028  for (int i=0; i<Nc; i++) {
1029 #pragma unroll
1030  for (int s=0; s<Ns; s++) {
1031  z.data[s*Nc + i] = x.data[s*Nc + i] + y.data[s*Nc + i];
1032  }
1033  }
1034 
1035  return z;
1036  }
1037 
1044  template<typename Float, int Nc, int Ns> __device__ __host__ inline
1046 
1048 
1049 #pragma unroll
1050  for (int i=0; i<Nc; i++) {
1051 #pragma unroll
1052  for (int s=0; s<Ns; s++) {
1053  z.data[s*Nc + i] = x.data[s*Nc + i] - y.data[s*Nc + i];
1054  }
1055  }
1056 
1057  return z;
1058  }
1059 
1066  template<typename Float, int Nc, int Ns, typename S> __device__ __host__ inline
1068 
1070 
1071 #pragma unroll
1072  for (int i=0; i<Nc; i++) {
1073 #pragma unroll
1074  for (int s=0; s<Ns; s++) {
1075  y.data[s*Nc + i] = a * x.data[s*Nc + i];
1076  }
1077  }
1078 
1079  return y;
1080  }
1081 
1088  template<typename Float, int Nc, int Ns> __device__ __host__ inline
1089  ColorSpinor<Float,Nc,Ns> operator*(const Matrix<complex<Float>,Nc> &A, const ColorSpinor<Float,Nc,Ns> &x) {
1090 
1092 
1093 #pragma unroll
1094  for (int i=0; i<Nc; i++) {
1095 #pragma unroll
1096  for (int s=0; s<Ns; s++) {
1097  y.data[s*Nc + i].x = A(i,0).real() * x.data[s*Nc + 0].real();
1098  y.data[s*Nc + i].x -= A(i,0).imag() * x.data[s*Nc + 0].imag();
1099  y.data[s*Nc + i].y = A(i,0).real() * x.data[s*Nc + 0].imag();
1100  y.data[s*Nc + i].y += A(i,0).imag() * x.data[s*Nc + 0].real();
1101  }
1102 #pragma unroll
1103  for (int j=1; j<Nc; j++) {
1104 #pragma unroll
1105  for (int s=0; s<Ns; s++) {
1106  y.data[s*Nc + i].x += A(i,j).real() * x.data[s*Nc + j].real();
1107  y.data[s*Nc + i].x -= A(i,j).imag() * x.data[s*Nc + j].imag();
1108  y.data[s*Nc + i].y += A(i,j).real() * x.data[s*Nc + j].imag();
1109  y.data[s*Nc + i].y += A(i,j).imag() * x.data[s*Nc + j].real();
1110  }
1111  }
1112  }
1113 
1114  return y;
1115  }
1116 
1123  template<typename Float, int Nc, int Ns> __device__ __host__ inline
1125 
1127  constexpr int N = Ns * Nc;
1128 
1129 #pragma unroll
1130  for (int i=0; i<N; i++) {
1131  if (i==0) {
1132  y.data[i].x = A(i,0).real() * x.data[0].real();
1133  y.data[i].y = A(i,0).real() * x.data[0].imag();
1134  } else {
1135  y.data[i].x = A(i,0).real() * x.data[0].real();
1136  y.data[i].x -= A(i,0).imag() * x.data[0].imag();
1137  y.data[i].y = A(i,0).real() * x.data[0].imag();
1138  y.data[i].y += A(i,0).imag() * x.data[0].real();
1139  }
1140 #pragma unroll
1141  for (int j=1; j<N; j++) {
1142  if (i==j) {
1143  y.data[i].x += A(i,j).real() * x.data[j].real();
1144  y.data[i].y += A(i,j).real() * x.data[j].imag();
1145  } else {
1146  y.data[i].x += A(i,j).real() * x.data[j].real();
1147  y.data[i].x -= A(i,j).imag() * x.data[j].imag();
1148  y.data[i].y += A(i,j).real() * x.data[j].imag();
1149  y.data[i].y += A(i,j).imag() * x.data[j].real();
1150  }
1151  }
1152  }
1153 
1154  return y;
1155  }
1156 
1157 } // namespace quda
__device__ __host__ ColorSpinor< Float, Nc, 2 > & operator=(const ColorSpinor< Float, Nc, 2 > &a)
Definition: color_spinor.h:691
__device__ __host__ ColorSpinor< Float, Nc, Ns > & operator+=(const ColorSpinor< Float, Nc, Ns > &a)
Definition: color_spinor.h:56
__device__ __host__ ColorSpinor< Float, Nc, 2 > chiral_project(int chirality) const
Project four-component spinor to either chirality.
Definition: color_spinor.h:298
double mu
Definition: test_util.cpp:1648
__device__ __host__ void toNonRel()
Transform from relativistic into non-relavisitic basis Required normalization factor of 1/2 included ...
Definition: color_spinor.h:633
__device__ __host__ ColorSpinor< Float, Nc, 2 > & operator+=(const ColorSpinor< Float, Nc, 2 > &a)
Definition: color_spinor.h:699
__device__ __host__ ColorSpinor< Float, Nc, 4 > gamma(int dim)
Definition: color_spinor.h:179
complex< Float > data[size]
Definition: color_spinor.h:678
complex< Float > data[size]
Definition: color_spinor.h:27
colorspinor_wrapper is an internal class that is used to wrap instances of colorspinor accessors...
Definition: color_spinor.h:17
__device__ __host__ void print() const
Prints the NsxNc complex elements of the color spinor.
Definition: color_spinor.h:123
__device__ __host__ ColorSpinor< Float, Nc, Ns > & operator-=(const ColorSpinor< Float, Nc, Ns > &a)
Definition: color_spinor.h:69
__device__ __host__ complex< Float > & operator()(int idx)
1-d accessor functor
Definition: color_spinor.h:608
__device__ __host__ complex< Float > & operator()(int idx)
1-d accessor functor
Definition: color_spinor.h:111
__device__ __host__ Matrix< complex< Float >, Nc > outerProdSpinTrace(const ColorSpinor< Float, Nc, Ns > &a, const ColorSpinor< Float, Nc, Ns > &b)
Definition: color_spinor.h:985
__device__ __host__ const complex< Float > & operator()(int s, int c) const
2-d accessor functor
Definition: color_spinor.h:868
__device__ __host__ ColorSpinor< Float, Nc, 4 > & operator*=(const T &a)
Definition: color_spinor.h:167
__device__ __host__ const complex< Float > & operator()(int idx) const
1-d accessor functor
Definition: color_spinor.h:615
This is just a dummy structure we use for trove to define the required structure size.
__device__ __host__ ColorSpinor< Float, Nc, 4 > & operator=(const ColorSpinor< Float, Nc, 4 > &a)
Definition: color_spinor.h:153
__device__ __host__ ColorSpinor< Float, Nc, 4 > sigma(int mu, int nu)
Definition: color_spinor.h:452
__device__ __host__ ColorSpinor< Float, Nc, 2 > & operator*=(const T &a)
Definition: color_spinor.h:705
__device__ __host__ ColorSpinor< Float, Nc, Ns > & operator*=(const T &a)
Definition: color_spinor.h:62
Specialized container for Hermitian matrices (e.g., used for wrapping clover matrices) ...
Definition: quda_matrix.h:61
__device__ __host__ const complex< Float > & operator()(int idx) const
1-d accessor functor
Definition: color_spinor.h:882
__device__ __host__ const complex< Float > & operator()(int idx) const
1-d accessor functor
Definition: color_spinor.h:118
__device__ __host__ const complex< Float > & operator()(int s, int c) const
2-d accessor functor
Definition: color_spinor.h:601
__device__ __host__ complex< Float > innerProduct(const ColorSpinor< Float, Nc, Ns > &a, const ColorSpinor< Float, Nc, Ns > &b)
Compute the inner product over color and spin dot = ,c conj(a(s,c)) * b(s,c)
Definition: color_spinor.h:914
__device__ __host__ ColorSpinor< Float, Nc, 2 > project(int dim, int sign) const
Definition: color_spinor.h:316
__device__ __host__ ColorSpinor< Float, Nc, Ns > & operator=(const ColorSpinor< Float, Nc, Ns > &a)
Definition: color_spinor.h:40
__device__ __host__ ColorSpinor< Float, Nc, 4 > igamma(int dim)
Definition: color_spinor.h:239
__device__ __host__ void print() const
Definition: color_spinor.h:660
__device__ __host__ ColorSpinor< Float, Nc, 4 > reconstruct(int dim, int sign) const
Spin reconstruct the full Spinor from the projected spinor.
Definition: color_spinor.h:734
colorspinor_ghost_wrapper is an internal class that is used to wrap instances of colorspinor accessor...
Definition: color_spinor.h:18
__device__ __host__ void print() const
Definition: color_spinor.h:896
cpuColorSpinorField * out
__device__ __host__ complex< Float > & operator()(int idx)
1-d accessor functor
Definition: color_spinor.h:875
__shared__ float s[]
__device__ __host__ ColorSpinor< Float, Nc, Ns > operator+(const ColorSpinor< Float, Nc, Ns > &x, const ColorSpinor< Float, Nc, Ns > &y)
ColorSpinor addition operator.
complex< Float > data[size]
Definition: color_spinor.h:140
__device__ __host__ ColorSpinor< Float, Nc, Ns > operator-() const
Definition: color_spinor.h:48
__device__ __host__ ColorSpinor< Float, Nc, 4 > chiral_reconstruct(int chirality) const
Reconstruct two-component spinor to a four-component spinor.
Definition: color_spinor.h:716
__device__ __host__ ColorSpinor< Float, Nc, Ns > operator*(const S &a, const ColorSpinor< Float, Nc, Ns > &x)
Compute the scalar-vector product y = a * x.
__device__ __host__ const complex< Float > & operator()(int s, int c) const
2-d accessor functor
Definition: color_spinor.h:104
__device__ __host__ void toRel()
Transform from non-relativistic into relavisitic basis.
Definition: color_spinor.h:648
__device__ __host__ ColorSpinor< Float, Nc, 4 > & operator+=(const ColorSpinor< Float, Nc, 4 > &a)
Definition: color_spinor.h:161
__device__ __host__ complex< Float > & operator()(int s, int c)
2-d accessor functor
Definition: color_spinor.h:593
__device__ __host__ complex< Float > & operator()(int s, int c)
2-d accessor functor
Definition: color_spinor.h:860
static constexpr int size
Definition: color_spinor.h:26
__device__ __host__ complex< Float > & operator()(int s, int c)
2-d accessor functor
Definition: color_spinor.h:96
static void dot(sFloat *res, gFloat *a, sFloat *b)
Definition: dslash_util.h:56