Bridge++  Ver. 2.0.2
mult_Clover_coarse_parts_qxs-inc.h
Go to the documentation of this file.
1 
10 #ifndef MULT_CLOVER_COARSE_PARTS_QXS_H
11 #define MULT_CLOVER_COARSE_PARTS_QXS_H
12 
13 namespace {
14 //====================================================================
15  inline void accum_mult_u_i(svreal_t& out_e1r, svreal_t& out_e1i,
16  svreal_t& out_e2r, svreal_t& out_e2i,
17  const real_t *__restrict__ in,
18  const real_t *__restrict__ u0,
19  int i, const int ncol)
20  {
21  const int nh = ncol / 2;
22  enum velem
23  {
24  e1r, e1i, e2r, e2i
25  };
26  svbool_t pg = set_predicate();
27 
28  const real_t *u = u0 + VLEN * 4 * i * ncol;
29  for (int j = 0; j < nh; j++) {
30  svreal_t u_e1r, u_e1i, u_e2r, u_e2i;
31  svreal_t in_e1r, in_e1i, in_e2r, in_e2i;
32  const real_t *uij = u + VLEN * 4 * j;
33  const real_t *inj = in + VLEN * 4 * j;
34  load_vec(pg, u_e1r, uij);
35  load_vec(pg, u_e1i, uij + VLEN);
36  load_vec(pg, u_e2r, uij + 2 * VLEN);
37  load_vec(pg, u_e2i, uij + 3 * VLEN);
38  load_vec(pg, in_e1r, inj);
39  load_vec(pg, in_e1i, inj + VLEN);
40  load_vec(pg, in_e2r, inj + 2 * VLEN);
41  load_vec(pg, in_e2i, inj + 3 * VLEN);
42 
43  // out1 += (u[2*j ]) * in[2*j]; // ch:--
44  axpy_vec(pg, out_e1r, u_e1r, in_e1r);
45  ymax_vec(pg, out_e1r, u_e1i, in_e1i);
46  axpy_vec(pg, out_e1i, u_e1r, in_e1i);
47  axpy_vec(pg, out_e1i, u_e1i, in_e1r);
48 
49  // out1 += u[2*j+1) * in[2*j+1]; // ch:-+
50  axpy_vec(pg, out_e1r, u_e2r, in_e2r);
51  ymax_vec(pg, out_e1r, u_e2i, in_e2i);
52  axpy_vec(pg, out_e1i, u_e2r, in_e2i);
53  axpy_vec(pg, out_e1i, u_e2i, in_e2r);
54 
55  svreal_t uu_e1r, uu_e1i, uu_e2r, uu_e2i;
56  const real_t *uuij = u + VLEN * 4 * (j + nh);
57  load_vec(pg, uu_e1r, uuij);
58  load_vec(pg, uu_e1i, uuij + VLEN);
59  load_vec(pg, uu_e2r, uuij + 2 * VLEN);
60  load_vec(pg, uu_e2i, uuij + 3 * VLEN);
61 
62  // out2 += (u[2*j ]) * in[2*j]; // ch:--
63  axpy_vec(pg, out_e2r, uu_e1r, in_e1r);
64  ymax_vec(pg, out_e2r, uu_e1i, in_e1i);
65  axpy_vec(pg, out_e2i, uu_e1r, in_e1i);
66  axpy_vec(pg, out_e2i, uu_e1i, in_e1r);
67 
68  // out2 += u[2*j+1) * in[2*j+1]; // ch:-+
69  axpy_vec(pg, out_e2r, uu_e2r, in_e2r);
70  ymax_vec(pg, out_e2r, uu_e2i, in_e2i);
71  axpy_vec(pg, out_e2i, uu_e2r, in_e2i);
72  axpy_vec(pg, out_e2i, uu_e2i, in_e2r);
73  } // j
74  }
75 
76 
77 //====================================================================
78  inline void accum_mult_u_i(real_t *__restrict__ out,
79  const real_t *__restrict__ in,
80  const real_t *__restrict__ u0,
81  int i, const int ncol, const svbool_t pgin)
82  {
83  const int nh = ncol / 2;
84  svbool_t pg = set_predicate();
85  svreal_t out_e1r, out_e1i, out_e2r, out_e2i;
86  load_vec(pgin, out_e1r, out);
87  load_vec(pgin, out_e1i, out + VLEN);
88  load_vec(pgin, out_e2r, out + 2 * VLEN);
89  load_vec(pgin, out_e2i, out + 3 * VLEN);
90 
91  const real_t *u = u0 + VLEN * 4 * i * ncol;
92  for (int j = 0; j < nh; j++) {
93  svreal_t u_e1r, u_e1i, u_e2r, u_e2i;
94  svreal_t in_e1r, in_e1i, in_e2r, in_e2i;
95  const real_t *uij = u + VLEN * 4 * j;
96  const real_t *inj = in + VLEN * 4 * j;
97  load_vec(pg, u_e1r, uij);
98  load_vec(pg, u_e1i, uij + VLEN);
99  load_vec(pg, u_e2r, uij + 2 * VLEN);
100  load_vec(pg, u_e2i, uij + 3 * VLEN);
101  load_vec(pg, in_e1r, inj);
102  load_vec(pg, in_e1i, inj + VLEN);
103  load_vec(pg, in_e2r, inj + 2 * VLEN);
104  load_vec(pg, in_e2i, inj + 3 * VLEN);
105 
106  // out1 += (u[2*j ]) * in[2*j]; // ch:--
107  axpy_vec(pg, out_e1r, u_e1r, in_e1r);
108  ymax_vec(pg, out_e1r, u_e1i, in_e1i);
109  axpy_vec(pg, out_e1i, u_e1r, in_e1i);
110  axpy_vec(pg, out_e1i, u_e1i, in_e1r);
111 
112  // out1 += u[2*j+1) * in[2*j+1]; // ch:-+
113  axpy_vec(pg, out_e1r, u_e2r, in_e2r);
114  ymax_vec(pg, out_e1r, u_e2i, in_e2i);
115  axpy_vec(pg, out_e1i, u_e2r, in_e2i);
116  axpy_vec(pg, out_e1i, u_e2i, in_e2r);
117 
118  svreal_t uu_e1r, uu_e1i, uu_e2r, uu_e2i;
119  const real_t *uuij = u + VLEN * 4 * (j + nh);
120  load_vec(pg, uu_e1r, uuij);
121  load_vec(pg, uu_e1i, uuij + VLEN);
122  load_vec(pg, uu_e2r, uuij + 2 * VLEN);
123  load_vec(pg, uu_e2i, uuij + 3 * VLEN);
124 
125  // out2 += (u[2*j ]) * in[2*j]; // ch:--
126  axpy_vec(pg, out_e2r, uu_e1r, in_e1r);
127  ymax_vec(pg, out_e2r, uu_e1i, in_e1i);
128  axpy_vec(pg, out_e2i, uu_e1r, in_e1i);
129  axpy_vec(pg, out_e2i, uu_e1i, in_e1r);
130 
131  // out2 += u[2*j+1) * in[2*j+1]; // ch:-+
132  axpy_vec(pg, out_e2r, uu_e2r, in_e2r);
133  ymax_vec(pg, out_e2r, uu_e2i, in_e2i);
134  axpy_vec(pg, out_e2i, uu_e2r, in_e2i);
135  axpy_vec(pg, out_e2i, uu_e2i, in_e2r);
136  } // j
137  save_vec(pg, out, out_e1r);
138  save_vec(pg, out + VLEN, out_e1i);
139  save_vec(pg, out + 2 * VLEN, out_e2r);
140  save_vec(pg, out + 3 * VLEN, out_e2i);
141  }
142 
143 
144 //====================================================================
145  inline void accum_mult_u(real_t *out, const real_t *in, const real_t *u0,
146  const int ncol)
147  { // simple implementation
148  const int nh = ncol / 2;
149 
150  for (int i = 0; i < nh; i++) {
151  real_t *outi = out + VLEN * 4 * i;
152  accum_mult_u_i(outi, in, u0, i, ncol, set_predicate());
153  }
154  }
155 
156 
157 //====================================================================
158  inline void accum_mult_udag_i(svbool_t pg,
159  svreal_t& out_e1r, svreal_t& out_e1i,
160  svreal_t& out_e2r, svreal_t& out_e2i,
161  const real_t *__restrict__ in,
162  const real_t *__restrict__ u0,
163  const int i, const int ncol)
164  {
165  const int dof2 = ncol * ncol;
166  const int nh = ncol / 2;
167 
168  for (int j = 0; j < nh; j++) {
169  const real_t *u = u0 + VLEN * 4 * j * ncol;
170  svreal_t u_e1r, u_e1i, u_e2r, u_e2i;
171  const real_t *uji = u + VLEN * 4 * i;
172  load_vec(pg, u_e1r, uji);
173  load_vec(pg, u_e1i, uji + VLEN);
174  load_vec(pg, u_e2r, uji + 2 * VLEN);
175  load_vec(pg, u_e2i, uji + 3 * VLEN);
176 
177  svreal_t in_e1r, in_e1i, in_e2r, in_e2i;
178  const real_t *inj = in + VLEN * 4 * j;
179  load_vec(pg, in_e1r, inj);
180  load_vec(pg, in_e1i, inj + VLEN);
181  load_vec(pg, in_e2r, inj + 2 * VLEN);
182  load_vec(pg, in_e2i, inj + 3 * VLEN);
183 
184  axpy_vec(pg, out_e1r, u_e1r, in_e1r);
185  axpy_vec(pg, out_e1r, u_e1i, in_e1i);
186  axpy_vec(pg, out_e1i, u_e1r, in_e1i);
187  ymax_vec(pg, out_e1i, u_e1i, in_e1r);
188 
189  ymax_vec(pg, out_e2r, u_e2r, in_e1r);
190  ymax_vec(pg, out_e2r, u_e2i, in_e1i);
191  ymax_vec(pg, out_e2i, u_e2r, in_e1i);
192  axpy_vec(pg, out_e2i, u_e2i, in_e1r);
193 
194  svreal_t uu_e1r, uu_e1i, uu_e2r, uu_e2i;
195  const real_t *uuji = u + VLEN * (2 * ncol + 4 * i);
196  load_vec(pg, uu_e1r, uuji);
197  load_vec(pg, uu_e1i, uuji + VLEN);
198  load_vec(pg, uu_e2r, uuji + 2 * VLEN);
199  load_vec(pg, uu_e2i, uuji + 3 * VLEN);
200 
201  ymax_vec(pg, out_e1r, uu_e1r, in_e2r);
202  ymax_vec(pg, out_e1r, uu_e1i, in_e2i);
203  ymax_vec(pg, out_e1i, uu_e1r, in_e2i);
204  axpy_vec(pg, out_e1i, uu_e1i, in_e2r);
205 
206  axpy_vec(pg, out_e2r, uu_e2r, in_e2r);
207  axpy_vec(pg, out_e2r, uu_e2i, in_e2i);
208  axpy_vec(pg, out_e2i, uu_e2r, in_e2i);
209  ymax_vec(pg, out_e2i, uu_e2i, in_e2r);
210  }
211  }
212 
213 
214 //====================================================================
215  inline void accum_mult_udag_i(real_t *__restrict__ out,
216  const real_t *__restrict__ in,
217  const real_t *__restrict__ u0,
218  int i, const int ncol,
219  const svbool_t pgin)
220  {
221  const int dof2 = ncol * ncol;
222  const int nh = ncol / 2;
223 
224  svbool_t pg = set_predicate();
225  svreal_t out_e1r, out_e1i, out_e2r, out_e2i;
226  load_vec(pgin, out_e1r, out);
227  load_vec(pgin, out_e1i, out + VLEN);
228  load_vec(pgin, out_e2r, out + 2 * VLEN);
229  load_vec(pgin, out_e2i, out + 3 * VLEN);
230 
231  for (int j = 0; j < nh; j++) {
232  const real_t *u = u0 + VLEN * 4 * j * ncol;
233 
234  svreal_t u_e1r, u_e1i, u_e2r, u_e2i;
235  const real_t *uji = u + VLEN * 4 * i;
236  load_vec(pg, u_e1r, uji);
237  load_vec(pg, u_e1i, uji + VLEN);
238  load_vec(pg, u_e2r, uji + 2 * VLEN);
239  load_vec(pg, u_e2i, uji + 3 * VLEN);
240 
241  svreal_t in_e1r, in_e1i, in_e2r, in_e2i;
242  const real_t *inj = in + VLEN * 4 * j;
243  load_vec(pg, in_e1r, inj);
244  load_vec(pg, in_e1i, inj + VLEN);
245  load_vec(pg, in_e2r, inj + 2 * VLEN);
246  load_vec(pg, in_e2i, inj + 3 * VLEN);
247 
248  // out1 += conj(u[2*i ]) * in[2*j]; // ch:--
249  axpy_vec(pg, out_e1r, u_e1r, in_e1r);
250  axpy_vec(pg, out_e1r, u_e1i, in_e1i);
251  axpy_vec(pg, out_e1i, u_e1r, in_e1i);
252  ymax_vec(pg, out_e1i, u_e1i, in_e1r);
253 
254  // out2 -= conj(u[2*i+1]) * in[2*j]; // ch:-+
255  ymax_vec(pg, out_e2r, u_e2r, in_e1r);
256  ymax_vec(pg, out_e2r, u_e2i, in_e1i);
257  ymax_vec(pg, out_e2i, u_e2r, in_e1i);
258  axpy_vec(pg, out_e2i, u_e2i, in_e1r);
259 
260  svreal_t uu_e1r, uu_e1i, uu_e2r, uu_e2i;
261  const real_t *uuji = u + VLEN * (2 * ncol + 4 * i);
262  load_vec(pg, uu_e1r, uuji);
263  load_vec(pg, uu_e1i, uuji + VLEN);
264  load_vec(pg, uu_e2r, uuji + 2 * VLEN);
265  load_vec(pg, uu_e2i, uuji + 3 * VLEN);
266 
267  // out1 -= conj(u[ncol+2*i ]) * in[2*j+1]; // ch:+-
268  ymax_vec(pg, out_e1r, uu_e1r, in_e2r);
269  ymax_vec(pg, out_e1r, uu_e1i, in_e2i);
270  ymax_vec(pg, out_e1i, uu_e1r, in_e2i);
271  axpy_vec(pg, out_e1i, uu_e1i, in_e2r);
272 
273  // out2 += conj(u[ncol+2*i+1]) * in[2*j+1]; // ch:++
274  axpy_vec(pg, out_e2r, uu_e2r, in_e2r);
275  axpy_vec(pg, out_e2r, uu_e2i, in_e2i);
276  axpy_vec(pg, out_e2i, uu_e2r, in_e2i);
277  ymax_vec(pg, out_e2i, uu_e2i, in_e2r);
278  }
279 
280  save_vec(pg, out, out_e1r);
281  save_vec(pg, out + VLEN, out_e1i);
282  save_vec(pg, out + 2 * VLEN, out_e2r);
283  save_vec(pg, out + 3 * VLEN, out_e2i);
284  }
285 
286 
287 //====================================================================
288  inline void accum_mult_udag_i(real_t *out, const real_t *in, const real_t *u0,
289  const int i, const int ncol)
290  {
291  accum_mult_udag_i(out, in, u0, i, ncol, set_predicate());
292  }
293 
294 
295 //====================================================================
296  inline void accum_mult_udag_xm_i(svbool_t& pg1, svbool_t& pg2,
297  real_t *__restrict__ out,
298  real_t *__restrict__ in,
299  real_t *u1, real_t *u2,
300  int i, const int ncol)
301  {
302  // u1 and u2 may overlap
303  const int nh = ncol / 2;
304  svbool_t pg = set_predicate();
305  svreal_t out_e1r, out_e1i, out_e2r, out_e2i;
306  load_vec(pg, out_e1r, out);
307  load_vec(pg, out_e1i, out + VLEN);
308  load_vec(pg, out_e2r, out + 2 * VLEN);
309  load_vec(pg, out_e2i, out + 3 * VLEN);
310 
311  for (int j = 0; j < nh; j++) {
312  real_t *uu1 = u1 + VLEN * 4 * j * ncol;
313  real_t *uu2 = u2 + VLEN * 4 * j * ncol;
314 
315  // shifted gauge field: for ch -*
316  svreal_t u_e1r, u_e1i, u_e2r, u_e2i;
317  shift_vec_xfw(pg1, pg2, u_e1r, &uu1[VLEN * (4 * i)],
318  &uu2[VLEN * (4 * i)]);
319  shift_vec_xfw(pg1, pg2, u_e1i, &uu1[VLEN * (4 * i + 1)],
320  &uu2[VLEN * (4 * i + 1)]);
321  shift_vec_xfw(pg1, pg2, u_e2r, &uu1[VLEN * (4 * i + 2)],
322  &uu2[VLEN * (4 * i + 2)]);
323  shift_vec_xfw(pg1, pg2, u_e2i, &uu1[VLEN * (4 * i + 3)],
324  &uu2[VLEN * (4 * i + 3)]);
325 
326  const real_t *inj = in + VLEN * 4 * j;
327 
328  svreal_t in_e1r, in_e1i, in_e2r, in_e2i;
329  load_vec(pg, in_e1r, inj);
330  load_vec(pg, in_e1i, inj + VLEN);
331  load_vec(pg, in_e2r, inj + 2 * VLEN);
332  load_vec(pg, in_e2i, inj + 3 * VLEN);
333 
334  // out1 += conj(u[2*i ]) * in[2*j]; // ch:--
335  axpy_vec(pg, out_e1r, u_e1r, in_e1r);
336  axpy_vec(pg, out_e1r, u_e1i, in_e1i);
337  axpy_vec(pg, out_e1i, u_e1r, in_e1i);
338  ymax_vec(pg, out_e1i, u_e1i, in_e1r);
339 
340  // out2 -= conj(u[2*i+1]) * in[2*j]; // ch:-+
341  ymax_vec(pg, out_e2r, u_e2r, in_e1r);
342  ymax_vec(pg, out_e2r, u_e2i, in_e1i);
343  ymax_vec(pg, out_e2i, u_e2r, in_e1i);
344  axpy_vec(pg, out_e2i, u_e2i, in_e1r);
345 
346  // shifted gauge field: for ch +*
347  shift_vec_xfw(pg1, pg2, u_e1r, &uu1[VLEN * (2 * ncol + 4 * i)],
348  &uu2[VLEN * (2 * ncol + 4 * i)]);
349  shift_vec_xfw(pg1, pg2, u_e1i, &uu1[VLEN * (2 * ncol + 4 * i + 1)],
350  &uu2[VLEN * (2 * ncol + 4 * i + 1)]);
351  shift_vec_xfw(pg1, pg2, u_e2r, &uu1[VLEN * (2 * ncol + 4 * i + 2)],
352  &uu2[VLEN * (2 * ncol + 4 * i + 2)]);
353  shift_vec_xfw(pg1, pg2, u_e2i, &uu1[VLEN * (2 * ncol + 4 * i + 3)],
354  &uu2[VLEN * (2 * ncol + 4 * i + 3)]);
355 
356  // out1 -= conj(u[ncol+2*i ]) * in[2*j+1]; // ch:+-
357  ymax_vec(pg, out_e1r, u_e1r, in_e2r);
358  ymax_vec(pg, out_e1r, u_e1i, in_e2i);
359  ymax_vec(pg, out_e1i, u_e1r, in_e2i);
360  axpy_vec(pg, out_e1i, u_e1i, in_e2r);
361 
362  // out2 += conj(u[ncol+2*i+1]) * in[2*j+1]; // ch:++
363  axpy_vec(pg, out_e2r, u_e2r, in_e2r);
364  axpy_vec(pg, out_e2r, u_e2i, in_e2i);
365  axpy_vec(pg, out_e2i, u_e2r, in_e2i);
366  ymax_vec(pg, out_e2i, u_e2i, in_e2r);
367  }
368 
369  save_vec(pg, out, out_e1r);
370  save_vec(pg, out + VLEN, out_e1i);
371  save_vec(pg, out + 2 * VLEN, out_e2r);
372  save_vec(pg, out + 3 * VLEN, out_e2i);
373  }
374 
375 
376 //====================================================================
377  inline void accum_mult_udag_ym_i(svbool_t& pg1, svbool_t& pg2,
378  real_t *__restrict__ out,
379  real_t *__restrict__ in,
380  real_t *u1, real_t *u2,
381  int i, const int ncol)
382  {
383  const int nh = ncol / 2;
384  svbool_t pg = set_predicate();
385  svreal_t out_e1r, out_e1i, out_e2r, out_e2i;
386  load_vec(pg, out_e1r, out);
387  load_vec(pg, out_e1i, out + VLEN);
388  load_vec(pg, out_e2r, out + 2 * VLEN);
389  load_vec(pg, out_e2i, out + 3 * VLEN);
390 
391  for (int j = 0; j < nh; j++) {
392  real_t *uu1 = u1 + VLEN * 4 * j * ncol;
393  real_t *uu2 = u2 + VLEN * 4 * j * ncol;
394 
395  // shifted gauge field: for ch -*
396  svreal_t u_e1r, u_e1i, u_e2r, u_e2i;
397  shift_vec_yfw(pg1, pg2, u_e1r, &uu1[VLEN * (4 * i)],
398  &uu2[VLEN * (4 * i)]);
399  shift_vec_yfw(pg1, pg2, u_e1i, &uu1[VLEN * (4 * i + 1)],
400  &uu2[VLEN * (4 * i + 1)]);
401  shift_vec_yfw(pg1, pg2, u_e2r, &uu1[VLEN * (4 * i + 2)],
402  &uu2[VLEN * (4 * i + 2)]);
403  shift_vec_yfw(pg1, pg2, u_e2i, &uu1[VLEN * (4 * i + 3)],
404  &uu2[VLEN * (4 * i + 3)]);
405 
406  real_t *inj = in + VLEN * 4 * j;
407 
408  svreal_t in_e1r, in_e1i, in_e2r, in_e2i;
409  load_vec(pg, in_e1r, inj);
410  load_vec(pg, in_e1i, inj + VLEN);
411  load_vec(pg, in_e2r, inj + 2 * VLEN);
412  load_vec(pg, in_e2i, inj + 3 * VLEN);
413 
414  // out1 += conj(u[2*i ]) * in[2*j]; // ch:--
415  axpy_vec(pg, out_e1r, u_e1r, in_e1r);
416  axpy_vec(pg, out_e1r, u_e1i, in_e1i);
417  axpy_vec(pg, out_e1i, u_e1r, in_e1i);
418  ymax_vec(pg, out_e1i, u_e1i, in_e1r);
419 
420  // out2 -= conj(u[2*i+1]) * in[2*j]; // ch:-+
421  ymax_vec(pg, out_e2r, u_e2r, in_e1r);
422  ymax_vec(pg, out_e2r, u_e2i, in_e1i);
423  ymax_vec(pg, out_e2i, u_e2r, in_e1i);
424  axpy_vec(pg, out_e2i, u_e2i, in_e1r);
425 
426  // shifted gauge field: for ch +*
427  shift_vec_yfw(pg1, pg2, u_e1r, &uu1[VLEN * (2 * ncol + 4 * i)],
428  &uu2[VLEN * (2 * ncol + 4 * i)]);
429  shift_vec_yfw(pg1, pg2, u_e1i, &uu1[VLEN * (2 * ncol + 4 * i + 1)],
430  &uu2[VLEN * (2 * ncol + 4 * i + 1)]);
431  shift_vec_yfw(pg1, pg2, u_e2r, &uu1[VLEN * (2 * ncol + 4 * i + 2)],
432  &uu2[VLEN * (2 * ncol + 4 * i + 2)]);
433  shift_vec_yfw(pg1, pg2, u_e2i, &uu1[VLEN * (2 * ncol + 4 * i + 3)],
434  &uu2[VLEN * (2 * ncol + 4 * i + 3)]);
435 
436  // out1 -= conj(u[ncol+2*i ]) * in[2*j+1]; // ch:+-
437  ymax_vec(pg, out_e1r, u_e1r, in_e2r);
438  ymax_vec(pg, out_e1r, u_e1i, in_e2i);
439  ymax_vec(pg, out_e1i, u_e1r, in_e2i);
440  axpy_vec(pg, out_e1i, u_e1i, in_e2r);
441 
442  // out2 += conj(u[ncol+2*i+1]) * in[2*j+1]; // ch:++
443  axpy_vec(pg, out_e2r, u_e2r, in_e2r);
444  axpy_vec(pg, out_e2r, u_e2i, in_e2i);
445  axpy_vec(pg, out_e2i, u_e2r, in_e2i);
446  ymax_vec(pg, out_e2i, u_e2i, in_e2r);
447  }
448 
449  save_vec(pg, out, out_e1r);
450  save_vec(pg, out + VLEN, out_e1i);
451  save_vec(pg, out + 2 * VLEN, out_e2r);
452  save_vec(pg, out + 3 * VLEN, out_e2i);
453  }
454 
455 
456 //====================================================================
457  inline void accum_mult_udag(real_t *out, const real_t *in, const real_t *u0,
458  const int ncol)
459  {
460  // c.c. of U(X,i,s;Y,j,t) = s t U(Y,j,t;X,i,s)
461  // X,Y: coordiante
462  // i,j: label for testvectors
463  // s,t: +-1 for chirality
464  // mult of
465  // sum_{j,t} U(X,i,s; X-mu,j,t) f(X-mu,j,t)
466  // = sum_{j,t} U(X-mu,j,t; X,i,s)^* s t f(X-mu,j,t)
467  // [^* is complex conjugate]
468 
469  const int nh = ncol / 2;
470  for (int i = 0; i < nh; ++i) {
471  real_t *outi = out + VLEN * 4 * i;
472  accum_mult_udag_i(outi, in, u0, i, ncol);
473  }
474  }
475 
476 
477 //====================================================================
478  inline void set_mult_u(real_t *out,
479  const real_t *in, const real_t *u0,
480  const int ncol)
481  {
482  const int nh = ncol / 2;
483  // svbool_t pgfalse = svpfalse();
484  svbool_t pgfalse = set_predicate_false();
485 
486  for (int i = 0; i < nh; i++) {
487  real_t *outi = out + VLEN * 4 * i;
488  accum_mult_u_i(outi, in, u0, i, ncol, pgfalse);
489  }
490  }
491 
492 
493 //====================================================================
494  inline void set_mult_udag(real_t *out,
495  const real_t *in, const real_t *u,
496  const int ncol)
497  {
498  const int nh = ncol / 2;
499  // svbool_t pgfalse = svpfalse_b();
500  svbool_t pgfalse = set_predicate_false();
501 
502  for (int i = 0; i < nh; i++) {
503  real_t *outi = out + VLEN * 4 * i;
504  accum_mult_udag_i(outi, in, u, i, ncol, pgfalse);
505  }
506  }
507 
508 
509 //====================================================================
510  inline void accum_buf(real_t *__restrict__ out,
511  real_t *__restrict__ in, const int ncol)
512  {
513  svbool_t pg = set_predicate();
514  for (int i = 0; i < 2 * ncol; i++) { // 2 for complex
515  svreal_t vin, vout;
516  load_vec(pg, vin, &in[VLEN * i]);
517  load_vec(pg, vout, &out[VLEN * i]);
518  add_vec(pg, vout, vin);
519  save_vec(pg, &out[VLEN * i], vout);
520  }
521  }
522 
523 
524 //====================================================================
525  inline void copy_buf(real_t *__restrict__ out,
526  real_t *__restrict__ in, const int ncol)
527  {
528  svbool_t pg = set_predicate();
529 
530  for (int i = 0; i < VLEN * 2 * ncol; i += VLEN) { // 2 for complex
531  svreal_t vinout;
532  load_vec(pg, vinout, &in[i]);
533  save_vec(pg, &out[i], vinout);
534  }
535  }
536 
537 
538 //====================================================================
539  inline void mult_coarse_xp1(svbool_t& pg2, svint_t& svidx,
540  real_t *__restrict__ buf, real_t *__restrict__ in, const int ncol)
541  {
542  const int nh = ncol / 2;
543  for (int i = 0; i < nh; i++) {
544  svreal_t vt1, vt2, vt3, vt4;
545  load_vec(pg2, vt1, &in[VLEN * (4 * i)]);
546  load_vec(pg2, vt2, &in[VLEN * (4 * i + 1)]);
547  load_vec(pg2, vt3, &in[VLEN * (4 * i + 2)]);
548  load_vec(pg2, vt4, &in[VLEN * (4 * i + 3)]);
549  save_vec_scatter(pg2, &buf[VLENY * (4 * i)], vt1, svidx);
550  save_vec_scatter(pg2, &buf[VLENY * (4 * i + 1)], vt2, svidx);
551  save_vec_scatter(pg2, &buf[VLENY * (4 * i + 2)], vt3, svidx);
552  save_vec_scatter(pg2, &buf[VLENY * (4 * i + 3)], vt4, svidx);
553  }
554  }
555 
556 
557 //====================================================================
558  inline void mult_coarse_xp2(svbool_t& pg1, svbool_t& pg2, svint_t& svidx,
559  real_t *__restrict__ out,
560  real_t *__restrict__ u0,
561  real_t *__restrict__ in0,
562  real_t *__restrict__ buf,
563  const int ncol, real_t *__restrict__ work)
564  {
565  svbool_t pg = set_predicate();
566  const int nh = ncol / 2;
567 
568  for (int i = 0; i < nh; ++i) {
569  svreal_t vt1, vt2, vt3, vt4;
570  load_vec(pg1, vt1, &in0[VLEN * (4 * i) + 1]);
571  load_vec(pg1, vt2, &in0[VLEN * (4 * i + 1) + 1]);
572  load_vec(pg1, vt3, &in0[VLEN * (4 * i + 2) + 1]);
573  load_vec(pg1, vt4, &in0[VLEN * (4 * i + 3) + 1]);
574  load_add_gather(pg2, vt1, &buf[VLENY * (4 * i)], svidx);
575  load_add_gather(pg2, vt2, &buf[VLENY * (4 * i + 1)], svidx);
576  load_add_gather(pg2, vt3, &buf[VLENY * (4 * i + 2)], svidx);
577  load_add_gather(pg2, vt4, &buf[VLENY * (4 * i + 3)], svidx);
578  save_vec(pg, &work[VLEN * (4 * i)], vt1);
579  save_vec(pg, &work[VLEN * (4 * i + 1)], vt2);
580  save_vec(pg, &work[VLEN * (4 * i + 2)], vt3);
581  save_vec(pg, &work[VLEN * (4 * i + 3)], vt4);
582  }
583 
584  accum_mult_u(out, work, u0, ncol);
585  }
586 
587 
588 //====================================================================
589  inline void mult_coarse_xpb(svbool_t& pg1, svbool_t& pg2,
590  real_t *__restrict__ out,
591  real_t *__restrict__ u,
592  real_t *in1, real_t *in2,
593  const int ncol, real_t *__restrict__ work)
594  {
595  real_t *in = work;
596 
597  int ncol2 = 2 * ncol;
598  svbool_t pg = set_predicate();
599  for (int i = 0; i < ncol2; ++i) {
600  svreal_t wt;
601  shift_vec_xbw(pg1, pg2, wt, &in1[VLEN * i], &in2[VLEN * i]);
602  save_vec(pg, &in[VLEN * i], wt);
603  }
604  accum_mult_u(out, in, u, ncol);
605  }
606 
607 
608 //====================================================================
609  inline void mult_coarse_xm1(svbool_t& pg2, svint_t& svidx,
610  real_t *buf, real_t *u, real_t *in, const int ncol)
611  {
612  const int nh = ncol / 2;
613  for (int i = 0; i < nh; ++i) {
614  svreal_t vt1, vt2, vt3, vt4;
615  clear_vec(pg2, vt1);
616  clear_vec(pg2, vt2);
617  clear_vec(pg2, vt3);
618  clear_vec(pg2, vt4);
619  accum_mult_udag_i(pg2, vt1, vt2, vt3, vt4, in, u, i, ncol);
620  save_vec_scatter(pg2, &buf[VLENY * (4 * i)], vt1, svidx);
621  save_vec_scatter(pg2, &buf[VLENY * (4 * i + 1)], vt2, svidx);
622  save_vec_scatter(pg2, &buf[VLENY * (4 * i + 2)], vt3, svidx);
623  save_vec_scatter(pg2, &buf[VLENY * (4 * i + 3)], vt4, svidx);
624  }
625  }
626 
627 
628 //====================================================================
629  inline void mult_coarse_xm2(svbool_t& pg1, svbool_t& pg2, svint_t& svidx,
630  real_t *out, real_t *u0, real_t *in0,
631  real_t *buf, const int ncol)
632  {
633  svbool_t pg = set_predicate();
634  const int nh = ncol / 2;
635 
636  for (int i = 0; i < nh; ++i) {
637  svreal_t vt1, vt2, vt3, vt4;
638  load_vec(pg, vt1, &out[VLEN * (4 * i)]);
639  load_vec(pg, vt2, &out[VLEN * (4 * i + 1)]);
640  load_vec(pg, vt3, &out[VLEN * (4 * i + 2)]);
641  load_vec(pg, vt4, &out[VLEN * (4 * i + 3)]);
642  accum_mult_udag_i(pg1, vt1, vt2, vt3, vt4,
643  &in0[-1], &u0[-1], i, ncol);
644 
645  svreal_t wt1, wt2, wt3, wt4;
646  load_vec_gather(pg2, wt1, &buf[VLENY * (4 * i)], svidx);
647  load_vec_gather(pg2, wt2, &buf[VLENY * (4 * i + 1)], svidx);
648  load_vec_gather(pg2, wt3, &buf[VLENY * (4 * i + 2)], svidx);
649  load_vec_gather(pg2, wt4, &buf[VLENY * (4 * i + 3)], svidx);
650  add_vec(pg2, vt1, wt1);
651  add_vec(pg2, vt2, wt2);
652  add_vec(pg2, vt3, wt3);
653  add_vec(pg2, vt4, wt4);
654 
655  save_vec(pg, &out[VLEN * (4 * i)], vt1);
656  save_vec(pg, &out[VLEN * (4 * i + 1)], vt2);
657  save_vec(pg, &out[VLEN * (4 * i + 2)], vt3);
658  save_vec(pg, &out[VLEN * (4 * i + 3)], vt4);
659  }
660  }
661 
662 
663 //====================================================================
664  inline void mult_coarse_xmb(svbool_t& pg1, svbool_t& pg2,
665  real_t *__restrict__ out,
666  real_t *u1, real_t *u2,
667  real_t *in1, real_t *in2,
668  const int ncol, real_t *__restrict__ work)
669  {
670  real_t *in = work;
671 
672  int ncol2 = 2 * ncol;
673  svbool_t pg = set_predicate();
674  for (int i = 0; i < ncol2; ++i) {
675  svreal_t wt;
676  shift_vec_xfw(pg1, pg2, wt, &in1[VLEN * i], &in2[VLEN * i]);
677  save_vec(pg, &in[VLEN * i], wt);
678  }
679 
680  const int nh = ncol / 2;
681  for (int i = 0; i < nh; i++) {
682  real_t *outi = out + VLEN * 4 * i;
683  accum_mult_udag_xm_i(pg1, pg2, outi, in, u1, u2, i, ncol);
684  }
685  }
686 
687 
688 //====================================================================
689  inline void mult_coarse_yp1(svbool_t& pg2,
690  real_t *__restrict__ buf,
691  real_t *__restrict__ in, const int ncol)
692  {
693  const int nh = ncol / 2;
694  for (int i = 0; i < nh; i++) {
695  svreal_t vt1, vt2, vt3, vt4;
696  load_vec(pg2, vt1, &in[VLEN * (4 * i)]);
697  load_vec(pg2, vt2, &in[VLEN * (4 * i + 1)]);
698  load_vec(pg2, vt3, &in[VLEN * (4 * i + 2)]);
699  load_vec(pg2, vt4, &in[VLEN * (4 * i + 3)]);
700  save_vec(pg2, &buf[VLENX * (4 * i)], vt1);
701  save_vec(pg2, &buf[VLENX * (4 * i + 1)], vt2);
702  save_vec(pg2, &buf[VLENX * (4 * i + 2)], vt3);
703  save_vec(pg2, &buf[VLENX * (4 * i + 3)], vt4);
704  }
705  }
706 
707 
708 //====================================================================
709  inline void mult_coarse_yp2(svbool_t& pg1, svbool_t& pg2,
710  real_t *__restrict__ out,
711  real_t *__restrict__ u0,
712  real_t *__restrict__ in0,
713  real_t *__restrict__ buf,
714  const int ncol, real_t *work)
715  {
716  svbool_t pg = set_predicate();
717  const int nh = ncol / 2;
718 
719  int offset = -VLENX * (VLENY - 1);
720  for (int i = 0; i < nh; ++i) {
721  svreal_t vt1, vt2, vt3, vt4;
722  load_vec(pg1, vt1, &in0[VLEN * (4 * i) + VLENX]);
723  load_vec(pg1, vt2, &in0[VLEN * (4 * i + 1) + VLENX]);
724  load_vec(pg1, vt3, &in0[VLEN * (4 * i + 2) + VLENX]);
725  load_vec(pg1, vt4, &in0[VLEN * (4 * i + 3) + VLENX]);
726  load_add(pg2, vt1, &buf[offset + VLENY * (4 * i)]);
727  load_add(pg2, vt2, &buf[offset + VLENY * (4 * i + 1)]);
728  load_add(pg2, vt3, &buf[offset + VLENY * (4 * i + 2)]);
729  load_add(pg2, vt4, &buf[offset + VLENY * (4 * i + 3)]);
730  save_vec(pg, &work[VLEN * (4 * i)], vt1);
731  save_vec(pg, &work[VLEN * (4 * i + 1)], vt2);
732  save_vec(pg, &work[VLEN * (4 * i + 2)], vt3);
733  save_vec(pg, &work[VLEN * (4 * i + 3)], vt4);
734  }
735 
736  accum_mult_u(out, work, u0, ncol);
737  }
738 
739 
740 //====================================================================
741  inline void mult_coarse_ypb(svbool_t& pg1, svbool_t& pg2,
742  real_t *__restrict__ out,
743  real_t *__restrict__ u,
744  real_t *in1, real_t *in2,
745  const int ncol, real_t *work)
746  {
747  real_t *in = work;
748 
749  int ncol2 = 2 * ncol;
750  svbool_t pg = set_predicate();
751  for (int i = 0; i < ncol2; ++i) {
752  svreal_t wt;
753  shift_vec_ybw(pg1, pg2, wt, &in1[VLEN * i], &in2[VLEN * i]);
754  save_vec(pg, &in[VLEN * i], wt);
755  }
756  const int nh = ncol / 2;
757  for (int i = 0; i < nh; ++i) {
758  real_t *outi = out + VLEN * 4 * i;
759  accum_mult_u_i(outi, in, u, i, ncol, set_predicate());
760  }
761  }
762 
763 
764 //====================================================================
765  inline void mult_coarse_ym1(svbool_t& pg2,
766  real_t *__restrict__ buf,
767  real_t *__restrict__ u,
768  real_t *__restrict__ in,
769  const int ncol)
770  {
771  const int nh = ncol / 2;
772 
773  int offset = -VLENX * (VLENY - 1);
774  for (int i = 0; i < nh; ++i) {
775  svreal_t vt1, vt2, vt3, vt4;
776  clear_vec(pg2, vt1);
777  clear_vec(pg2, vt2);
778  clear_vec(pg2, vt3);
779  clear_vec(pg2, vt4);
780  accum_mult_udag_i(pg2, vt1, vt2, vt3, vt4, in, u, i, ncol);
781  save_vec(pg2, &buf[offset + VLENX * (4 * i)], vt1);
782  save_vec(pg2, &buf[offset + VLENX * (4 * i + 1)], vt2);
783  save_vec(pg2, &buf[offset + VLENX * (4 * i + 2)], vt3);
784  save_vec(pg2, &buf[offset + VLENX * (4 * i + 3)], vt4);
785  }
786  }
787 
788 
789 //====================================================================
790  inline void mult_coarse_ym2(svbool_t& pg1, svbool_t& pg2,
791  real_t *out, real_t *u0, real_t *in0,
792  real_t *buf, const int ncol)
793  {
794  svbool_t pg = set_predicate();
795  const int nh = ncol / 2;
796 
797  for (int i = 0; i < nh; ++i) {
798  svreal_t vt1, vt2, vt3, vt4;
799  load_vec(pg, vt1, &out[VLEN * (4 * i)]);
800  load_vec(pg, vt2, &out[VLEN * (4 * i + 1)]);
801  load_vec(pg, vt3, &out[VLEN * (4 * i + 2)]);
802  load_vec(pg, vt4, &out[VLEN * (4 * i + 3)]);
803  accum_mult_udag_i(pg1, vt1, vt2, vt3, vt4,
804  &in0[-VLENX], &u0[-VLENX], i, ncol);
805 
806  svreal_t wt1, wt2, wt3, wt4;
807  load_vec(pg2, wt1, &buf[VLENX * (4 * i)]);
808  load_vec(pg2, wt2, &buf[VLENX * (4 * i + 1)]);
809  load_vec(pg2, wt3, &buf[VLENX * (4 * i + 2)]);
810  load_vec(pg2, wt4, &buf[VLENX * (4 * i + 3)]);
811  add_vec(pg2, vt1, wt1);
812  add_vec(pg2, vt2, wt2);
813  add_vec(pg2, vt3, wt3);
814  add_vec(pg2, vt4, wt4);
815 
816  save_vec(pg, &out[VLEN * (4 * i)], vt1);
817  save_vec(pg, &out[VLEN * (4 * i + 1)], vt2);
818  save_vec(pg, &out[VLEN * (4 * i + 2)], vt3);
819  save_vec(pg, &out[VLEN * (4 * i + 3)], vt4);
820  }
821  }
822 
823 
824 //====================================================================
825  inline void mult_coarse_ymb(svbool_t& pg1, svbool_t& pg2,
826  real_t *__restrict__ out,
827  real_t *u1, real_t *u2,
828  real_t *in1, real_t *in2,
829  const int ncol, real_t *__restrict__ work)
830  {
831  real_t *in = work;
832 
833  int ncol2 = 2 * ncol;
834  svbool_t pg = set_predicate();
835  for (int i = 0; i < ncol2; ++i) {
836  svreal_t wt;
837  shift_vec_yfw(pg1, pg2, wt, &in1[VLEN * i], &in2[VLEN * i]);
838  save_vec(pg, &in[VLEN * i], wt);
839  }
840 
841  const int nh = ncol / 2;
842  for (int i = 0; i < nh; i++) {
843  real_t *outi = out + VLEN * 4 * i;
844  accum_mult_udag_ym_i(pg1, pg2, outi, in, u1, u2, i, ncol);
845  }
846  }
847 
848 
849 //====================================================================
850  inline void mult_coarse_zp1(real_t *out, real_t *in, const int ncol)
851  {
852  copy_buf(out, in, ncol);
853  }
854 
855 
856 //====================================================================
857  inline void mult_coarse_zp2(real_t *out, real_t *u, real_t *buf,
858  const int ncol)
859  {
860  accum_mult_u(out, buf, u, ncol);
861  }
862 
863 
864 //====================================================================
865  inline void mult_coarse_zpb(real_t *out, real_t *u, real_t *in,
866  const int ncol)
867  {
868  accum_mult_u(out, in, u, ncol);
869  }
870 
871 
872 //====================================================================
873  inline void mult_coarse_zm1(real_t *out, real_t *u, real_t *buf,
874  const int ncol)
875  {
876  set_mult_udag(out, buf, u, ncol);
877  }
878 
879 
880 //====================================================================
881  inline void mult_coarse_zm2(real_t *out, real_t *buf, const int ncol)
882  {
883  accum_buf(out, buf, ncol);
884  }
885 
886 
887 //====================================================================
888  inline void mult_coarse_zmb(real_t *out, real_t *u, real_t *in,
889  const int ncol)
890  {
891  accum_mult_udag(out, in, u, ncol);
892  }
893 
894 
895 //====================================================================
896  inline void mult_coarse_tp1(real_t *out, real_t *in, const int ncol)
897  {
898  copy_buf(out, in, ncol);
899  }
900 
901 
902 //====================================================================
903  inline void mult_coarse_tp2(real_t *out, real_t *u, real_t *buf, const int ncol)
904  {
905  accum_mult_u(out, buf, u, ncol);
906  }
907 
908 
909 //====================================================================
910  inline void mult_coarse_tpb(real_t *out, real_t *u, real_t *in,
911  const int ncol)
912  {
913  accum_mult_u(out, in, u, ncol);
914  }
915 
916 
917 //====================================================================
918  inline void mult_coarse_tm1(real_t *out, real_t *u, real_t *buf,
919  const int ncol)
920  {
921  set_mult_udag(out, buf, u, ncol);
922  }
923 
924 
925 //====================================================================
926  inline void mult_coarse_tm2(real_t *out, real_t *buf, const int ncol)
927  {
928  accum_buf(out, buf, ncol);
929  }
930 
931 
932 //====================================================================
933  inline void mult_coarse_tmb(real_t *out, real_t *u, real_t *in,
934  const int ncol)
935  {
936  accum_mult_udag(out, in, u, ncol);
937  }
938 
939 
940 //====================================================================
941 } // nameless namespace end
942 
943 #endif
VLEN
#define VLEN
Definition: bridgeQXS_Clover_coarse_double.cpp:12
Vsimd_t
Definition: vsimd_double-inc.h:13
Isimd_t
Definition: vsimd_double-inc.h:20
real_t
double real_t
Definition: bridgeQXS_Clover_coarse_double.cpp:16
VLENY
#define VLENY
Definition: bridgeQXS_Clover_coarse_double.cpp:14
svbool_t
Definition: vsimd_double-inc.h:30
VLENX
#define VLENX
Definition: bridgeQXS_Clover_coarse_double.cpp:13
Bridge::vout
BridgeIO vout
Definition: bridgeIO.cpp:512