QUDA  0.9.0
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  complex<Float> data[Nc*Ns];
27 
28  __device__ __host__ inline ColorSpinor<Float, Nc, Ns>() {
29 #pragma unroll
30  for (int i=0; i<Nc*Ns; i++) {
31  data[i] = 0;
32  }
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<Nc*Ns; i++) {
38  data[i] = a.data[i];
39  }
40  }
41 
42  __device__ __host__ inline ColorSpinor<Float, Nc, Ns>& operator=(const ColorSpinor<Float, Nc, Ns> &a) {
43  if (this != &a) {
44 #pragma unroll
45  for (int i=0; i<Nc*Ns; i++) {
46  data[i] = a.data[i];
47  }
48  }
49  return *this;
50  }
51 
52  __device__ __host__ inline ColorSpinor<Float, Nc, Ns>& operator+=(const ColorSpinor<Float, Nc, Ns> &a) {
53  if (this != &a) {
54 #pragma unroll
55  for (int i=0; i<Nc*Ns; i++) {
56  data[i] += a.data[i];
57  }
58  }
59  return *this;
60  }
61 
62  template<typename S>
63  __device__ __host__ inline ColorSpinor<Float, Nc, Ns>(const colorspinor_wrapper<Float, S> &s);
64 
65  template<typename S>
66  __device__ __host__ inline void operator=(const colorspinor_wrapper<Float, S> &s);
67 
68  template<typename S>
69  __device__ __host__ inline ColorSpinor<Float, Nc, Ns>(const colorspinor_ghost_wrapper<Float, S> &s);
70 
71  template<typename S>
72  __device__ __host__ inline void operator=(const colorspinor_ghost_wrapper<Float, S> &s);
73 
80  __device__ __host__ inline complex<Float>& operator()(int s, int c) { return data[s*Nc + c]; }
81 
88  __device__ __host__ inline const complex<Float>& operator()(int s, int c) const { return data[s*Nc + c]; }
89 
95  __device__ __host__ inline complex<Float>& operator()(int idx) { return data[idx]; }
96 
102  __device__ __host__ inline const complex<Float>& operator()(int idx) const { return data[idx]; }
103 
104  };
105 
110  template <typename Float, int Nc>
111  struct ColorSpinor<Float, Nc, 4> {
112  static const int Ns = 4;
113  complex<Float> data[Nc*4];
114 
115  __device__ __host__ inline ColorSpinor<Float, Nc, 4>() {
116 #pragma unroll
117  for (int i=0; i<Nc*Ns; i++) {
118  data[i] = 0;
119  }
120  }
121 
122  __device__ __host__ inline ColorSpinor<Float, Nc, 4>(const ColorSpinor<Float, Nc, 4> &a) {
123 #pragma unroll
124  for (int i=0; i<Nc*Ns; i++) {
125  data[i] = a.data[i];
126  }
127  }
128 
129  __device__ __host__ inline ColorSpinor<Float, Nc, 4>& operator=(const ColorSpinor<Float, Nc, 4> &a) {
130  if (this != &a) {
131 #pragma unroll
132  for (int i=0; i<Nc*Ns; i++) {
133  data[i] = a.data[i];
134  }
135  }
136  return *this;
137  }
138 
139  __device__ __host__ inline ColorSpinor<Float, Nc, 4>& operator+=(const ColorSpinor<Float, Nc, 4> &a) {
140  if (this != &a) {
141 #pragma unroll
142  for (int i=0; i<Nc*Ns; i++) {
143  data[i] += a.data[i];
144  }
145  }
146  return *this;
147  }
148 
154  __device__ __host__ inline ColorSpinor<Float,Nc,4> gamma(int dim) {
156  complex<Float> j(0.0,1.0);
157 
158  switch (dim) {
159  case 0: // x dimension
160 #pragma unroll
161  for (int i=0; i<Nc; i++) {
162  a(0,i) = j*(*this)(3,i);
163  a(1,i) = j*(*this)(2,i);
164  a(2,i) = -j*(*this)(1,i);
165  a(3,i) = -j*(*this)(0,i);
166  }
167  break;
168  case 1: // y dimension
169 #pragma unroll
170  for (int i=0; i<Nc; i++) {
171  a(0,i) = (*this)(3,i);
172  a(1,i) = -(*this)(2,i);
173  a(2,i) = -(*this)(1,i);
174  a(3,i) = (*this)(0,i);
175  }
176  break;
177  case 2: // z dimension
178 #pragma unroll
179  for (int i=0; i<Nc; i++) {
180  a(0,i) = j*(*this)(2,i);
181  a(1,i) = -j*(*this)(3,i);
182  a(2,i) = -j*(*this)(0,i);
183  a(3,i) = j*(*this)(1,i);
184  }
185  break;
186  case 3: // t dimension
187 #pragma unroll
188  for (int i=0; i<Nc; i++) {
189  a(0,i) = (*this)(0,i);
190  a(1,i) = (*this)(1,i);
191  a(2,i) = -(*this)(2,i);
192  a(3,i) = -(*this)(3,i);
193  }
194  break;
195  case 4: // gamma_5
196 #pragma unroll
197  for (int i=0; i<Nc; i++) {
198  a(0,i) = (*this)(2,i);
199  a(1,i) = (*this)(3,i);
200  a(2,i) = (*this)(0,i);
201  a(3,i) = (*this)(1,i);
202  }
203  break;
204  }
205 
206  return a;
207  }
208 
214  __device__ __host__ inline ColorSpinor<Float,Nc,4> igamma(int dim) {
216  complex<Float> j(0.0,1.0);
217 
218  switch (dim) {
219  case 0: // x dimension
220 #pragma unroll
221  for (int i=0; i<Nc; i++) {
222  a(0,i) = -(*this)(3,i);
223  a(1,i) = -(*this)(2,i);
224  a(2,i) = (*this)(1,i);
225  a(3,i) = (*this)(0,i);
226  }
227  break;
228  case 1: // y dimension
229 #pragma unroll
230  for (int i=0; i<Nc; i++) {
231  a(0,i) = j*(*this)(3,i);
232  a(1,i) = -j*(*this)(2,i);
233  a(2,i) = -j*(*this)(1,i);
234  a(3,i) = j*(*this)(0,i);
235  }
236  break;
237  case 2: // z dimension
238 #pragma unroll
239  for (int i=0; i<Nc; i++) {
240  a(0,i) = -(*this)(2,i);
241  a(1,i) = (*this)(3,i);
242  a(2,i) = (*this)(0,i);
243  a(3,i) = -(*this)(1,i);
244  }
245  break;
246  case 3: // t dimension
247 #pragma unroll
248  for (int i=0; i<Nc; i++) {
249  a(0,i) = j*(*this)(0,i);
250  a(1,i) = j*(*this)(1,i);
251  a(2,i) = -j*(*this)(2,i);
252  a(3,i) = -j*(*this)(3,i);
253  }
254  break;
255  case 4: // gamma_5
256 #pragma unroll
257  for (int i=0; i<Nc; i++) {
258  a(0,i) = complex<Float>(-(*this)(2,i).imag(), (*this)(2,i).real());
259  a(1,i) = complex<Float>(-(*this)(3,i).imag(), (*this)(3,i).real());
260  a(2,i) = complex<Float>(-(*this)(0,i).imag(), (*this)(0,i).real());
261  a(3,i) = complex<Float>(-(*this)(1,i).imag(), (*this)(1,i).real());
262  }
263  break;
264  }
265 
266  return a;
267  }
268 
273  __device__ __host__ inline ColorSpinor<Float,Nc,2> chiral_project(int chirality) const {
275 #pragma unroll
276  for (int s=0; s<Ns/2; s++) {
277 #pragma unroll
278  for (int c=0; c<Nc; c++) {
279  proj(s,c) = (*this)(chirality*Ns/2+s,c);
280  }
281  }
282  return proj;
283  }
284 
291  __device__ __host__ inline ColorSpinor<Float,Nc,2> project(int dim, int sign) {
293  complex<Float> j(0.0,1.0);
294 
295  switch (dim) {
296  case 0: // x dimension
297  switch (sign) {
298  case 1: // positive projector
299 #pragma unroll
300  for (int i=0; i<Nc; i++) {
301  proj(0,i) = (*this)(0,i) + j * (*this)(3,i);
302  proj(1,i) = (*this)(1,i) + j * (*this)(2,i);
303  }
304  break;
305  case -1: // negative projector
306 #pragma unroll
307  for (int i=0; i<Nc; i++) {
308  proj(0,i) = (*this)(0,i) - j * (*this)(3,i);
309  proj(1,i) = (*this)(1,i) - j * (*this)(2,i);
310  }
311  break;
312  }
313  break;
314  case 1: // y dimension
315  switch (sign) {
316  case 1: // positive projector
317 #pragma unroll
318  for (int i=0; i<Nc; i++) {
319  proj(0,i) = (*this)(0,i) + (*this)(3,i);
320  proj(1,i) = (*this)(1,i) - (*this)(2,i);
321  }
322  break;
323  case -1: // negative projector
324 #pragma unroll
325  for (int i=0; i<Nc; i++) {
326  proj(0,i) = (*this)(0,i) - (*this)(3,i);
327  proj(1,i) = (*this)(1,i) + (*this)(2,i);
328  }
329  break;
330  }
331  break;
332  case 2: // z dimension
333  switch (sign) {
334  case 1: // positive projector
335 #pragma unroll
336  for (int i=0; i<Nc; i++) {
337  proj(0,i) = (*this)(0,i) + j * (*this)(2,i);
338  proj(1,i) = (*this)(1,i) - j * (*this)(3,i);
339  }
340  break;
341  case -1: // negative projector
342 #pragma unroll
343  for (int i=0; i<Nc; i++) {
344  proj(0,i) = (*this)(0,i) - j * (*this)(2,i);
345  proj(1,i) = (*this)(1,i) + j * (*this)(3,i);
346  }
347  break;
348  }
349  break;
350  case 3: // t dimension
351  switch (sign) {
352  case 1: // positive projector
353 #pragma unroll
354  for (int i=0; i<Nc; i++) {
355  proj(0,i) = 2*(*this)(0,i);
356  proj(1,i) = 2*(*this)(1,i);
357  }
358  break;
359  case -1: // negative projector
360 #pragma unroll
361  for (int i=0; i<Nc; i++) {
362  proj(0,i) = 2*(*this)(2,i);
363  proj(1,i) = 2*(*this)(3,i);
364  }
365  break;
366  }
367  break;
368  }
369 
370  return proj;
371  }
372 
408  __device__ __host__ inline ColorSpinor<Float,Nc,4> sigma(int mu, int nu) {
410  ColorSpinor<Float,Nc,4> &b = *this;
411  complex<Float> j(0.0,1.0);
412 
413  switch(mu) {
414  case 0:
415  switch(nu) {
416  case 1:
417 #pragma unroll
418  for (int i=0; i<Nc; i++) {
419  a(0,i) = j*b(0,i);
420  a(1,i) = -j*b(1,i);
421  a(2,i) = j*b(2,i);
422  a(3,i) = -j*b(3,i);
423  }
424  break;
425  case 2:
426 #pragma unroll
427  for (int i=0; i<Nc; i++) {
428  a(0,i) = -b(1,i);
429  a(1,i) = b(0,i);
430  a(2,i) = -b(3,i);
431  a(3,i) = b(2,i);
432  }
433  break;
434  case 3:
435 #pragma unroll
436  for (int i=0; i<Nc; i++) {
437  a(0,i) = -j*b(3,i);
438  a(1,i) = -j*b(2,i);
439  a(2,i) = -j*b(1,i);
440  a(3,i) = -j*b(0,i);
441  }
442  break;
443  }
444  break;
445  case 1:
446  switch(nu) {
447  case 0:
448 #pragma unroll
449  for (int i=0; i<Nc; i++) {
450  a(0,i) = -j*b(0,i);
451  a(1,i) = j*b(1,i);
452  a(2,i) = -j*b(2,i);
453  a(3,i) = j*b(3,i);
454  }
455  break;
456  case 2:
457 #pragma unroll
458  for (int i=0; i<Nc; i++) {
459  a(0,i) = j*b(1,i);
460  a(1,i) = j*b(0,i);
461  a(2,i) = j*b(3,i);
462  a(3,i) = j*b(2,i);
463  }
464  break;
465  case 3:
466 #pragma unroll
467  for (int i=0; i<Nc; i++) {
468  a(0,i) = -b(3,i);
469  a(1,i) = b(2,i);
470  a(2,i) = -b(1,i);
471  a(3,i) = b(0,i);
472  }
473  break;
474  }
475  break;
476  case 2:
477  switch(nu) {
478  case 0:
479 #pragma unroll
480  for (int i=0; i<Nc; i++) {
481  a(0,i) = b(1,i);
482  a(1,i) = -b(0,i);
483  a(2,i) = b(3,i);
484  a(3,i) = -b(2,i);
485  }
486  break;
487  case 1:
488 #pragma unroll
489  for (int i=0; i<Nc; i++) {
490  a(0,i) = -j*b(1,i);
491  a(1,i) = -j*b(0,i);
492  a(2,i) = -j*b(3,i);
493  a(3,i) = -j*b(2,i);
494  }
495  break;
496  case 3:
497 #pragma unroll
498  for (int i=0; i<Nc; i++) {
499  a(0,i) = -j*b(2,i);
500  a(1,i) = j*b(3,i);
501  a(2,i) = -j*b(0,i);
502  a(3,i) = j*b(1,i);
503  }
504  break;
505  }
506  break;
507  case 3:
508  switch(nu) {
509  case 0:
510 #pragma unroll
511  for (int i=0; i<Nc; i++) {
512  a(0,i) = j*b(3,i);
513  a(1,i) = j*b(2,i);
514  a(2,i) = j*b(1,i);
515  a(3,i) = j*b(0,i);
516  }
517  break;
518  case 1:
519 #pragma unroll
520  for (int i=0; i<Nc; i++) {
521  a(0,i) = b(3,i);
522  a(1,i) = -b(2,i);
523  a(2,i) = b(1,i);
524  a(3,i) = -b(0,i);
525  }
526  break;
527  case 2:
528 #pragma unroll
529  for (int i=0; i<Nc; i++) {
530  a(0,i) = j*b(2,i);
531  a(1,i) = -j*b(3,i);
532  a(2,i) = j*b(0,i);
533  a(3,i) = -j*b(1,i);
534  }
535  break;
536  }
537  break;
538  }
539 
540  return a;
541  }
542 
543 
550  __device__ __host__ inline complex<Float>& operator()(int s, int c) { return data[s*Nc + c]; }
551 
558  __device__ __host__ inline const complex<Float>& operator()(int s, int c) const { return data[s*Nc + c]; }
559 
565  __device__ __host__ inline complex<Float>& operator()(int idx) { return data[idx]; }
566 
572  __device__ __host__ inline const complex<Float>& operator()(int idx) const { return data[idx]; }
573 
574  template<typename S>
575  __device__ __host__ inline ColorSpinor<Float, Nc, Ns>(const colorspinor_wrapper<Float, S> &s);
576 
577  template<typename S>
578  __device__ __host__ inline void operator=(const colorspinor_wrapper<Float, S> &s);
579 
580  template<typename S>
581  __device__ __host__ inline ColorSpinor<Float, Nc, Ns>(const colorspinor_ghost_wrapper<Float, S> &s);
582 
583  template<typename S>
584  __device__ __host__ inline void operator=(const colorspinor_ghost_wrapper<Float, S> &s);
585 
590  __device__ __host__ inline void toNonRel() {
592 #pragma unroll
593  for (int c=0; c<Nc; c++) {
594  a(0,c) = (*this)(1,c)+(*this)(3,c);
595  a(1,c) = -(*this)(2,c)-(*this)(0,c);
596  a(2,c) = -(*this)(3,c)+(*this)(1,c);
597  a(3,c) = -(*this)(0,c)+(*this)(2,c);
598  }
599  *this = a;
600  }
601 
605  __device__ __host__ inline void toRel() {
607 #pragma unroll
608  for (int c=0; c<Nc; c++) {
609  a(0,c) = -(*this)(1,c)-(*this)(3,c);
610  a(1,c) = (*this)(2,c)+(*this)(0,c);
611  a(2,c) = (*this)(3,c)-(*this)(1,c);
612  a(3,c) = (*this)(0,c)-(*this)(2,c);
613  }
614  *this = a;
615  }
616 
617  __device__ __host__ void print() {
618  for (int s=0; s<Ns; s++) {
619  for (int c=0; c<Nc; c++) {
620  printf("s=%d c=%d %e %e\n", s, c, data[s*Nc+c].real(), data[s*Nc+c].imag());
621  }
622  }
623  }
624  };
625 
630  template <typename Float, int Nc>
631  struct ColorSpinor<Float, Nc, 2> {
632  static const int Ns = 2;
633  complex<Float> data[Nc*2];
634 
635  __device__ __host__ inline ColorSpinor<Float, Nc, 2>() {
636 #pragma unroll
637  for (int i=0; i<Nc*Ns; i++) {
638  data[i] = 0;
639  }
640  }
641 
642  __device__ __host__ inline ColorSpinor<Float, Nc, 2>(const ColorSpinor<Float, Nc, 2> &a) {
643 #pragma unroll
644  for (int i=0; i<Nc*Ns; i++) {
645  data[i] = a.data[i];
646  }
647  }
648 
649 
650  __device__ __host__ inline ColorSpinor<Float, Nc, 2>& operator=(const ColorSpinor<Float, Nc, 2> &a) {
651  if (this != &a) {
652 #pragma unroll
653  for (int i=0; i<Nc*Ns; i++) {
654  data[i] = a.data[i];
655  }
656  }
657  return *this;
658  }
659 
660  __device__ __host__ inline ColorSpinor<Float, Nc, 2>& operator+=(const ColorSpinor<Float, Nc, 2> &a) {
661  if (this != &a) {
662 #pragma unroll
663  for (int i=0; i<Nc*Ns; i++) {
664  data[i] += a.data[i];
665  }
666  }
667  return *this;
668  }
669 
674  __device__ __host__ inline ColorSpinor<Float,Nc,4> chiral_reconstruct(int chirality) const {
676 #pragma unroll
677  for (int s=0; s<Ns; s++) {
678 #pragma unroll
679  for (int c=0; c<Nc; c++) {
680  recon(chirality*Ns+s,c) = (*this)(s,c);
681  }
682  }
683  return recon;
684  }
685 
692  __device__ __host__ inline ColorSpinor<Float,Nc,4> reconstruct(int dim, int sign) {
694  complex<Float> j(0.0,1.0);
695 
696  switch (dim) {
697  case 0: // x dimension
698  switch (sign) {
699  case 1: // positive projector
700 #pragma unroll
701  for (int i=0; i<Nc; i++) {
702  recon(0,i) = (*this)(0,i);
703  recon(1,i) = (*this)(1,i);
704  recon(2,i) = -j*(*this)(1,i);
705  recon(3,i) = -j*(*this)(0,i);
706  }
707  break;
708  case -1: // negative projector
709 #pragma unroll
710  for (int i=0; i<Nc; i++) {
711  recon(0,i) = (*this)(0,i);
712  recon(1,i) = (*this)(1,i);
713  recon(2,i) = j*(*this)(1,i);
714  recon(3,i) = j*(*this)(0,i);
715  }
716  break;
717  }
718  break;
719  case 1: // y dimension
720  switch (sign) {
721  case 1: // positive projector
722 #pragma unroll
723  for (int i=0; i<Nc; i++) {
724  recon(0,i) = (*this)(0,i);
725  recon(1,i) = (*this)(1,i);
726  recon(2,i) = -(*this)(1,i);
727  recon(3,i) = (*this)(0,i);
728  }
729  break;
730  case -1: // negative projector
731 #pragma unroll
732  for (int i=0; i<Nc; i++) {
733  recon(0,i) = (*this)(0,i);
734  recon(1,i) = (*this)(1,i);
735  recon(2,i) = (*this)(1,i);
736  recon(3,i) = -(*this)(0,i);
737  }
738  break;
739  }
740  break;
741  case 2: // z dimension
742  switch (sign) {
743  case 1: // positive projector
744 #pragma unroll
745  for (int i=0; i<Nc; i++) {
746  recon(0,i) = (*this)(0,i);
747  recon(1,i) = (*this)(1,i);
748  recon(2,i) = -j*(*this)(0,i);
749  recon(3,i) = j*(*this)(1,i);
750  }
751  break;
752  case -1: // negative projector
753 #pragma unroll
754  for (int i=0; i<Nc; i++) {
755  recon(0,i) = (*this)(0,i);
756  recon(1,i) = (*this)(1,i);
757  recon(2,i) = j*(*this)(0,i);
758  recon(3,i) = -j*(*this)(1,i);
759  }
760  break;
761  }
762  break;
763  case 3: // t dimension
764  switch (sign) {
765  case 1: // positive projector
766 #pragma unroll
767  for (int i=0; i<Nc; i++) {
768  recon(0,i) = (*this)(0,i);
769  recon(1,i) = (*this)(1,i);
770  recon(2,i) = 0;
771  recon(3,i) = 0;
772  }
773  break;
774  case -1: // negative projector
775 #pragma unroll
776  for (int i=0; i<Nc; i++) {
777  recon(0,i) = 0;
778  recon(1,i) = 0;
779  recon(2,i) = (*this)(0,i);
780  recon(3,i) = (*this)(1,i);
781  }
782  break;
783  }
784  break;
785  }
786  return recon;
787  }
788 
795  __device__ __host__ inline complex<Float>& operator()(int s, int c) { return data[s*Nc + c]; }
796 
803  __device__ __host__ inline const complex<Float>& operator()(int s, int c) const { return data[s*Nc + c]; }
804 
810  __device__ __host__ inline complex<Float>& operator()(int idx) { return data[idx]; }
811 
817  __device__ __host__ inline const complex<Float>& operator()(int idx) const { return data[idx]; }
818 
819  template<typename S>
820  __device__ __host__ inline ColorSpinor<Float, Nc, Ns>(const colorspinor_wrapper<Float, S> &s);
821 
822  template<typename S>
823  __device__ __host__ inline void operator=(const colorspinor_wrapper<Float, S> &s);
824 
825  template<typename S>
826  __device__ __host__ inline ColorSpinor<Float, Nc, Ns>(const colorspinor_ghost_wrapper<Float, S> &s);
827 
828  template<typename S>
829  __device__ __host__ inline void operator=(const colorspinor_ghost_wrapper<Float, S> &s);
830 
831  __device__ __host__ void print() {
832  for (int s=0; s<Ns; s++) {
833  for (int c=0; c<Nc; c++) {
834  printf("s=%d c=%d %e %e\n", s, c, data[s*Nc+c].real(), data[s*Nc+c].imag());
835  }
836  }
837  }
838  };
839 
840 
848  template<typename Float, int Nc, int Ns> __device__ __host__ inline
850 
852 
853  // outer product over color
854 #pragma unroll
855  for (int i=0; i<Nc; i++) {
856 #pragma unroll
857  for(int j=0; j<Nc; j++) {
858  // trace over spin (manual unroll for perf)
859  out(j,i).real( a(0,j).real() * b(0,i).real() );
860  out(j,i).real( out(j,i).real() + a(0,j).imag() * b(0,i).imag() );
861  out(j,i).imag( a(0,j).imag() * b(0,i).real() );
862  out(j,i).imag( out(j,i).imag() - a(0,j).real() * b(0,i).imag() );
863  //out(j,i) = a(0,j) * conj(b(0,i));
864 
865 #pragma unroll
866  for (int s=1; s<Ns; s++) {
867  out(j,i).real( out(j,i).real() + a(s,j).real() * b(s,i).real() );
868  out(j,i).real( out(j,i).real() + a(s,j).imag() * b(s,i).imag() );
869  out(j,i).imag( out(j,i).imag() + a(s,j).imag() * b(s,i).real() );
870  out(j,i).imag( out(j,i).imag() - a(s,j).real() * b(s,i).imag() );
871  // out(j,i) += a(s,j) * conj(b(s,i));
872  }
873  }
874  }
875  return out;
876  }
877 
884  template<typename Float, int Nc, int Ns> __device__ __host__ inline
886 
888 
889 #pragma unroll
890  for (int i=0; i<Nc; i++) {
891 #pragma unroll
892  for (int s=0; s<Ns; s++) {
893  z.data[s*Nc + i] = x.data[s*Nc + i] + y.data[s*Nc + i];
894  }
895  }
896 
897  return z;
898  }
899 
906  template<typename Float, int Nc, int Ns> __device__ __host__ inline
908 
910 
911 #pragma unroll
912  for (int i=0; i<Nc; i++) {
913 #pragma unroll
914  for (int s=0; s<Ns; s++) {
915  z.data[s*Nc + i] = x.data[s*Nc + i] - y.data[s*Nc + i];
916  }
917  }
918 
919  return z;
920  }
921 
928  template<typename Float, int Nc, int Ns, typename S> __device__ __host__ inline
930 
932 
933 #pragma unroll
934  for (int i=0; i<Nc; i++) {
935 #pragma unroll
936  for (int s=0; s<Ns; s++) {
937  y.data[s*Nc + i] = a * x.data[s*Nc + i];
938  }
939  }
940 
941  return y;
942  }
943 
950  template<typename Float, int Nc, int Ns> __device__ __host__ inline
951  ColorSpinor<Float,Nc,Ns> operator*(const Matrix<complex<Float>,Nc> &A, const ColorSpinor<Float,Nc,Ns> &x) {
952 
954 
955 #pragma unroll
956  for (int i=0; i<Nc; i++) {
957 #pragma unroll
958  for (int s=0; s<Ns; s++) {
959  y.data[s*Nc + i].x = A(i,0).real() * x.data[s*Nc + 0].real();
960  y.data[s*Nc + i].x -= A(i,0).imag() * x.data[s*Nc + 0].imag();
961  y.data[s*Nc + i].y = A(i,0).real() * x.data[s*Nc + 0].imag();
962  y.data[s*Nc + i].y += A(i,0).imag() * x.data[s*Nc + 0].real();
963  }
964 #pragma unroll
965  for (int j=1; j<Nc; j++) {
966 #pragma unroll
967  for (int s=0; s<Ns; s++) {
968  y.data[s*Nc + i].x += A(i,j).real() * x.data[s*Nc + j].real();
969  y.data[s*Nc + i].x -= A(i,j).imag() * x.data[s*Nc + j].imag();
970  y.data[s*Nc + i].y += A(i,j).real() * x.data[s*Nc + j].imag();
971  y.data[s*Nc + i].y += A(i,j).imag() * x.data[s*Nc + j].real();
972  }
973  }
974  }
975 
976  return y;
977  }
978 
985  template<typename Float, int Nc, int Ns> __device__ __host__ inline
987 
989  constexpr int N = Nc*Ns;
990 
991 #pragma unroll
992  for (int i=0; i<N; i++) {
993  if (i==0) {
994  y.data[i].x = A(i,0).real() * x.data[0].real();
995  y.data[i].y = A(i,0).real() * x.data[0].imag();
996  } else {
997  y.data[i].x = A(i,0).real() * x.data[0].real();
998  y.data[i].x -= A(i,0).imag() * x.data[0].imag();
999  y.data[i].y = A(i,0).real() * x.data[0].imag();
1000  y.data[i].y += A(i,0).imag() * x.data[0].real();
1001  }
1002 #pragma unroll
1003  for (int j=1; j<N; j++) {
1004  if (i==j) {
1005  y.data[i].x += A(i,j).real() * x.data[j].real();
1006  y.data[i].y += A(i,j).real() * x.data[j].imag();
1007  } else {
1008  y.data[i].x += A(i,j).real() * x.data[j].real();
1009  y.data[i].x -= A(i,j).imag() * x.data[j].imag();
1010  y.data[i].y += A(i,j).real() * x.data[j].imag();
1011  y.data[i].y += A(i,j).imag() * x.data[j].real();
1012  }
1013  }
1014  }
1015 
1016  return y;
1017  }
1018 
1019 } // namespace quda
__device__ __host__ ColorSpinor< Float, Nc, 2 > & operator=(const ColorSpinor< Float, Nc, 2 > &a)
Definition: color_spinor.h:650
__device__ __host__ ColorSpinor< Float, Nc, Ns > & operator+=(const ColorSpinor< Float, Nc, Ns > &a)
Definition: color_spinor.h:52
__device__ __host__ ColorSpinor< Float, Nc, 2 > chiral_project(int chirality) const
Project four-component spinor to either chirality.
Definition: color_spinor.h:273
double mu
Definition: test_util.cpp:1643
__device__ __host__ void toNonRel()
Transform from relativistic into non-relavisitic basis Required normalization factor of 1/2 included ...
Definition: color_spinor.h:590
__device__ __host__ ColorSpinor< Float, Nc, 2 > & operator+=(const ColorSpinor< Float, Nc, 2 > &a)
Definition: color_spinor.h:660
__device__ __host__ ColorSpinor< Float, Nc, 4 > gamma(int dim)
Definition: color_spinor.h:154
colorspinor_wrapper is an internal class that is used to wrap instances of colorspinor accessors...
Definition: color_spinor.h:17
static __inline__ dim3 dim3 void size_t cudaStream_t int dim
__device__ __host__ ColorSpinor< Float, Nc, 2 > project(int dim, int sign)
Definition: color_spinor.h:291
__device__ __host__ complex< Float > & operator()(int idx)
1-d accessor functor
Definition: color_spinor.h:565
__device__ __host__ complex< Float > & operator()(int idx)
1-d accessor functor
Definition: color_spinor.h:95
__device__ __host__ Matrix< complex< Float >, Nc > outerProdSpinTrace(const ColorSpinor< Float, Nc, Ns > &a, const ColorSpinor< Float, Nc, Ns > &b)
Definition: color_spinor.h:849
__device__ __host__ const complex< Float > & operator()(int s, int c) const
2-d accessor functor
Definition: color_spinor.h:803
__device__ __host__ const complex< Float > & operator()(int idx) const
1-d accessor functor
Definition: color_spinor.h:572
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:129
#define b
int printf(const char *,...) __attribute__((__format__(__printf__
__device__ __host__ ColorSpinor< Float, Nc, 4 > sigma(int mu, int nu)
Definition: color_spinor.h:408
__device__ __host__ ColorSpinor< Float, Nc, Ns > operator-(const ColorSpinor< Float, Nc, Ns > &x, const ColorSpinor< Float, Nc, Ns > &y)
ColorSpinor subtraction operator.
Definition: color_spinor.h:907
Specialized container for Hermitian matrices (e.g., used for wrapping clover matrices) ...
Definition: quda_matrix.h:65
complex< Float > data[Nc *Ns]
Definition: color_spinor.h:26
__device__ __host__ const complex< Float > & operator()(int idx) const
1-d accessor functor
Definition: color_spinor.h:817
__device__ __host__ const complex< Float > & operator()(int idx) const
1-d accessor functor
Definition: color_spinor.h:102
__device__ __host__ const complex< Float > & operator()(int s, int c) const
2-d accessor functor
Definition: color_spinor.h:558
__device__ __host__ ColorSpinor< Float, Nc, Ns > & operator=(const ColorSpinor< Float, Nc, Ns > &a)
Definition: color_spinor.h:42
__device__ __host__ ColorSpinor< Float, Nc, 4 > igamma(int dim)
Definition: color_spinor.h:214
colorspinor_ghost_wrapper is an internal class that is used to wrap instances of colorspinor accessor...
Definition: color_spinor.h:18
cpuColorSpinorField * out
__device__ __host__ complex< Float > & operator()(int idx)
1-d accessor functor
Definition: color_spinor.h:810
__device__ __host__ ColorSpinor< Float, Nc, Ns > operator+(const ColorSpinor< Float, Nc, Ns > &x, const ColorSpinor< Float, Nc, Ns > &y)
ColorSpinor addition operator.
Definition: color_spinor.h:885
__device__ __host__ void print()
Definition: color_spinor.h:831
__device__ __host__ void print()
Definition: color_spinor.h:617
const void * c
__device__ __host__ ColorSpinor< Float, Nc, 4 > chiral_reconstruct(int chirality) const
Reconstruct twor-component spinor to a four-component spinor.
Definition: color_spinor.h:674
__device__ __host__ ColorSpinor< Float, Nc, Ns > operator*(const S &a, const ColorSpinor< Float, Nc, Ns > &x)
Compute the scalar-vector product y = a * x.
Definition: color_spinor.h:929
__device__ __host__ const complex< Float > & operator()(int s, int c) const
2-d accessor functor
Definition: color_spinor.h:88
__device__ __host__ void toRel()
Transform from non-relativistic into relavisitic basis.
Definition: color_spinor.h:605
__device__ __host__ ColorSpinor< Float, Nc, 4 > & operator+=(const ColorSpinor< Float, Nc, 4 > &a)
Definition: color_spinor.h:139
#define a
__device__ __host__ ColorSpinor< Float, Nc, 4 > reconstruct(int dim, int sign)
Spin reconstruct the full Spinor from the projected spinor.
Definition: color_spinor.h:692
__device__ __host__ complex< Float > & operator()(int s, int c)
2-d accessor functor
Definition: color_spinor.h:550
__device__ __host__ complex< Float > & operator()(int s, int c)
2-d accessor functor
Definition: color_spinor.h:795
__device__ __host__ complex< Float > & operator()(int s, int c)
2-d accessor functor
Definition: color_spinor.h:80