CHROMA
clover_apply_ssed.cc
Go to the documentation of this file.
1 #include "qdp_config.h"
2 #include "qdp_precision.h"
3 
4 
5 namespace Chroma {
6 
7 #include "scalarsite_sse/sse_dcomplex_mult_macros.h"
8  void ssed_clover_apply(REAL64* diag, REAL64* offd, REAL64* psiptr, REAL64* chiptr, int n_sites)
9  {
10 
11  __m128d chi0;
12  __m128d chi1;
13 
14  __m128d psi0;
15  __m128d psi1;
16  __m128d psi2;
17  __m128d psi3;
18  __m128d psi4;
19  __m128d psi5;
20 
21  __m128d tmp0;
22  __m128d tmp1;
23 
24 
25 
26  REAL64* chi_p=chiptr;
27  REAL64* psi_p=(REAL64 *)psiptr;
28  REAL64* offd_p = (REAL64 *)offd;
29  REAL64* diag_p = (REAL64 *)diag;
30 
31  // Upper and lower blocks are the same so just do the loop 2n times
32  for(int site=0; site < 2*n_sites; site++) {
33  // First evaluate the multiplies by the diags
34  // This is because they are REALs, so we can do
35 
36 
37  // First things first: Registerize half of psi
38  psi0 = _mm_load_pd(psi_p); // ppsi[0]
39  psi1 = _mm_load_pd(psi_p+2); // ppsi[1]
40  psi2 = _mm_load_pd(psi_p+4); // ppsi[2]
41  psi3 = _mm_load_pd(psi_p+6); // ppsi[3]
42  psi4 = _mm_load_pd(psi_p+8); // ppsi[4]
43  psi5 = _mm_load_pd(psi_p+10); // ppsi[5]
44 
45  // cchi[ 0] = tri_diag[site][0][ 0] * ppsi[ 0]
46  // cchi[ 1] = tri_diag[site][0][ 1] * ppsi[ 1]
47 
48  // tmp0 = [ diag[1] | diag[0] ]
49  tmp0 = _mm_load_pd(diag_p); // reads tri_diag[site][0][0]
50  // AND tri_diat[site][0][1]
51  // tmp1 = [ diag[0] | diag[1] ]
52  tmp1 = _mm_shuffle_pd(tmp0,tmp0,0x1);
53  // tmp0 = [ diag[0] | diag[0] ]
54  tmp0 = _mm_shuffle_pd(tmp0,tmp0, 0x0);
55  // tmp1 = [ diag[1] | diag[1] ]
56  tmp1 = _mm_shuffle_pd(tmp1,tmp1, 0x0);
57 
58  // cchi[ 0] = tri_diag[site][0][ 0] * ppsi[ 0]
59  chi0 = _mm_mul_pd(tmp0,psi0);
60 
61  // cchi[ 1] = tri_diag[site][0][ 1] * ppsi[ 1]
62  chi1 = _mm_mul_pd(tmp1,psi1);
63 
64  // cchi[ 0] += conj(tri_off_diag[site][0][ 0]) * ppsi[ 1]
65  // cchi[ 1] += tri_off_diag[site][0][ 0] * ppsi[ 0]
66  tmp0 = _mm_load_pd(offd_p); // tri_off_diag[site][0][ 0]
67  CONJMADD(chi0,psi1,tmp0);
68  CMADD(chi1, psi0, tmp0);
69 
70  // cchi[ 0] += conj(tri_off_diag[site][0][ 1]) * ppsi[ 2]
71  // cchi[ 1] += conj(tri_off_diag[site][0][ 2]) * ppsi[ 2]
72  tmp0 = _mm_load_pd(offd_p+2);
73  tmp1 = _mm_load_pd(offd_p+4);
74  CONJMADD(chi0, psi2, tmp0);
75  CONJMADD(chi1, psi2, tmp1);
76 
77  // cchi[ 0] += conj(tri_off_diag[site][0][ 3]) * ppsi[ 3]
78  // cchi[ 1] += conj(tri_off_diag[site][0][ 4]) * ppsi[ 3]
79  tmp0 = _mm_load_pd(offd_p+6); // tri_off_diag[site][0][3]
80  tmp1 = _mm_load_pd(offd_p+8); // tri_off_diag[site][0][4]
81  CONJMADD(chi0, psi3, tmp0);
82  CONJMADD(chi1, psi3, tmp1);
83 
84  // cchi[ 0] += conj(tri_off_diag[site][0][ 6]) * ppsi[ 4]
85  // cchi[ 1] += conj(tri_off_diag[site][0][ 7]) * ppsi[ 4]
86  tmp0 = _mm_load_pd(offd_p+12); // tri_off_diag[site][0][6]
87  tmp1 = _mm_load_pd(offd_p+14); // tri_off_diag[site][0][7]
88  CONJMADD(chi0, psi4,tmp0);
89  CONJMADD(chi1, psi4,tmp1);
90 
91  // cchi[ 0] += conj(tri_off_diag[site][0][10]) * ppsi[ 5];
92  // cchi[ 1] += conj(tri_off_diag[site][0][11]) * ppsi[ 5];
93  tmp0 = _mm_load_pd(offd_p+20); // tri_off_diag[site][0][10]
94  tmp1 = _mm_load_pd(offd_p+22); // tri_off_diag[site][0][11]
95  CONJMADD(chi0, psi5,tmp0);
96  CONJMADD(chi1, psi5,tmp1);
97 
98  _mm_store_pd(chi_p, chi0);
99  _mm_store_pd(chi_p+2, chi1);
100 
101 
102  // cchi[ 2] = tri_diag[site][0][ 2] * ppsi[ 2]
103  // cchi[ 3] = tri_diag[site][0][ 3] * ppsi[ 3]
104 
105  tmp0 = _mm_load_pd(diag_p+2); // reads tri_diag[site][0][2]
106  // AND tri_diat[site][0][3]
107 
108  // tmp1 = [ diag[2] | diag[3] ]
109  tmp1 = _mm_shuffle_pd(tmp0,tmp0,0x1);
110  // tmp0 = [ diag[2] | diag[2] ]
111  tmp0 = _mm_shuffle_pd(tmp0,tmp0, 0x0);
112  // tmp1 = [ diag[3] | diag[3] ]
113  tmp1 = _mm_shuffle_pd(tmp1,tmp1, 0x0);
114 
115  // cchi[ 2] = tri_diag[site][0][ 2] * ppsi[2]
116  chi0 = _mm_mul_pd(tmp0,psi2);
117 
118  // cchi[ 3] = tri_diag[site][0][ 3] * ppsi[ 3]
119  chi1 = _mm_mul_pd(tmp1,psi3);
120 
121  // cchi[ 2] += tri_off_diag[site][0][ 1] * ppsi[ 0]
122  // cchi[ 2] += tri_off_diag[site][0][ 2] * ppsi[ 1]
123  tmp0 = _mm_load_pd(offd_p+2); // tri_off_diag[site][0][ 1]
124  tmp1 = _mm_load_pd(offd_p+4); // tri_off_diag[site][0][ 2]
125  CMADD(chi0,psi0,tmp0);
126  CMADD(chi0,psi1,tmp1);
127 
128  // cchi[ 3] += tri_off_diag[site][0][ 3] * ppsi[ 0]
129  // cchi[ 3] += tri_off_diag[site][0][ 4] * ppsi[ 1]
130  tmp0 = _mm_load_pd(offd_p+6);
131  tmp1 = _mm_load_pd(offd_p+8);
132  CMADD(chi1,psi0,tmp0);
133  CMADD(chi1,psi1,tmp1);
134 
135  // cchi[ 2] += conj(tri_off_diag[site][0][ 5]) * ppsi[ 3]
136  // cchi[ 3] += tri_off_diag[site][0][ 5] * ppsi[ 2]
137  tmp0 = _mm_load_pd(offd_p+10); // tri_off_diag[site][0][ 5]
138  CONJMADD(chi0,psi3,tmp0);
139  CMADD(chi1,psi2, tmp0);
140 
141  // cchi[ 2] += conj(tri_off_diag[site][0][ 8]) * ppsi[ 4]
142  // cchi[ 3] += conj(tri_off_diag[site][0][ 9]) * ppsi[ 4]
143  tmp0 = _mm_load_pd(offd_p+16); // tri_off_diag[site][0][ 8]
144  tmp1 = _mm_load_pd(offd_p+18); // tri_off_diag[site][0][ 9]
145  CONJMADD(chi0,psi4,tmp0);
146  CONJMADD(chi1,psi4,tmp1);
147 
148  // cchi[ 2] += conj(tri_off_diag[site][0][12]) * ppsi[ 5];
149  // cchi[ 3] += conj(tri_off_diag[site][0][13]) * ppsi[ 5];
150  tmp0 = _mm_load_pd(offd_p+24); // tri_off_diag[site][0][12]
151  tmp1 = _mm_load_pd(offd_p+26); // tri_off_diag[site][0][13]
152  CONJMADD(chi0,psi5,tmp0);
153  CONJMADD(chi1,psi5,tmp1);
154 
155  _mm_store_pd(chi_p+4, chi0);
156  _mm_store_pd(chi_p+6, chi1);
157 
158 
159  // cchi[ 4] = tri_diag[site][0][ 4] * ppsi[ 4]
160  // cchi[ 5] = tri_diag[site][0][ 5] * ppsi[ 5]
161 
162  // tmp 0 = [ diag[5] | diag[4] ]_low
163  tmp0 = _mm_load_pd(diag_p+4); // reads tri_diag[site][0][4]
164  // AND tri_diat[site][0][5]
165 
166  // tmp1 = [ diag[4] | diag[5] ]
167  tmp1 = _mm_shuffle_pd(tmp0,tmp0,0x1);
168  // tmp0 = [ diag[4] | diag[4] ]
169  tmp0 = _mm_shuffle_pd(tmp0,tmp0, 0x0);
170  // tmp1 = [ diag[5] | diag[5] ]
171  tmp1 = _mm_shuffle_pd(tmp1,tmp1, 0x0);
172 
173  // cchi[ 4] = tri_diag[site][0][4] * ppsi[4]
174  chi0 = _mm_mul_pd(tmp0,psi4);
175 
176  // cchi[ 5] = tri_diag[site][0][5] * ppsi[5]
177  chi1 = _mm_mul_pd(tmp1,psi5);
178 
179  // cchi[ 4] += tri_off_diag[site][0][ 6] * ppsi[ 0]
180  // cchi[ 4] += tri_off_diag[site][0][ 7] * ppsi[ 1]
181  tmp0 = _mm_load_pd(offd_p+12);
182  tmp1 = _mm_load_pd(offd_p+14);
183  CMADD(chi0,psi0,tmp0);
184  CMADD(chi0,psi1,tmp1);
185 
186  // cchi[ 4] += tri_off_diag[site][0][ 8] * ppsi[ 2]
187  // cchi[ 4] += tri_off_diag[site][0][ 9] * ppsi[ 3]
188  tmp0 = _mm_load_pd(offd_p+16);
189  tmp1 = _mm_load_pd(offd_p+18);
190  CMADD(chi0,psi2,tmp0);
191  CMADD(chi0,psi3,tmp1);
192 
193  // cchi[ 5] += tri_off_diag[site][0][10] * ppsi[ 0]
194  // cchi[ 5] += tri_off_diag[site][0][11] * ppsi[ 1]
195  tmp0 = _mm_load_pd(offd_p+20);
196  tmp1 = _mm_load_pd(offd_p+22);
197  CMADD(chi1,psi0,tmp0);
198  CMADD(chi1,psi1,tmp1);
199 
200  // cchi[ 5] += tri_off_diag[site][0][12] * ppsi[ 2]
201  // cchi[ 5] += tri_off_diag[site][0][13] * ppsi[ 3]
202  tmp0 = _mm_load_pd(offd_p+24);
203  tmp1 = _mm_load_pd(offd_p+26);
204  CMADD(chi1,psi2,tmp0);
205  CMADD(chi1,psi3,tmp1);
206 
207  // cchi[ 4] += conj(tri_off_diag[site][0][14]) * ppsi[ 5];
208  // cchi[ 5] += tri_off_diag[site][0][14] * ppsi[ 4];
209  tmp0 = _mm_load_pd(offd_p+28);
210  CONJMADD(chi0,psi5,tmp0);
211  CMADD(chi1,psi4,tmp0);
212 
213  _mm_store_pd(chi_p+8, chi0);
214  _mm_store_pd(chi_p+10,chi1);
215 
216  chi_p +=12;
217  psi_p +=12;
218  offd_p += 32;
219  diag_p += 8;
220 
221  // Do next block
222 
223  }
224  }
225 };
Asqtad Staggered-Dirac operator.
Definition: klein_gord.cc:10
void ssed_clover_apply(REAL64 *diag, REAL64 *offd, REAL64 *psiptr, REAL64 *chiptr, int n_sites)