34 const ptrdiff_t unroll16 = max1(16 * VEC_SIZE >> ldf);
37 const ptrdiff_t unroll8 = max1(8 * VEC_SIZE >> ldf);
40 const ptrdiff_t unroll4 = max1(4 * VEC_SIZE >> ldf);
43 const ptrdiff_t unroll2 = max1(2 * VEC_SIZE >> ldf);
46 const ptrdiff_t unroll1 = max1(1 * VEC_SIZE >> ldf);
54 const double w0 = wcenter[0];
56 for (
l = 0;
l <
nri;
l++) {
62 for (;
i < (rimap_inv_max[
l] - unroll16 + 1);
i += unroll16) {
64 for (k = 0; k < (1 << ldf); k += 16 * VEC_SIZE) {
65 register VEC_TYPE a0, a1, a2, a3;
66 register VEC_TYPE a4, a5, a6, a7;
67 register VEC_TYPE a8, a9, aa, ab;
68 register VEC_TYPE ac, ad, ae, af;
70 a0 = a1 = a2 = a3 = VEC_ZERO;
71 a4 = a5 = a6 = a7 = VEC_ZERO;
72 a8 = a9 = aa = ab = VEC_ZERO;
73 ac = ad = ae = af = VEC_ZERO;
77 for (
j = 0;
j < npairs;
j++) {
78 register VEC_TYPE wj = VEC_SCAL(wpair[
j]);
81 register VEC_TYPE pos = LOAD(fi + indexj_pos);
82 register VEC_TYPE neg = LOAD(fi + indexj_neg);
83 a0 = VEC_FMA(wj, VEC_ADD(pos, neg), a0);
84 pos = LOAD(fi + indexj_pos + 1 * VEC_SIZE);
85 neg = LOAD(fi + indexj_neg + 1 * VEC_SIZE);
86 a1 = VEC_FMA(wj, VEC_ADD(pos, neg), a1);
87 pos = LOAD(fi + indexj_pos + 2 * VEC_SIZE);
88 neg = LOAD(fi + indexj_neg + 2 * VEC_SIZE);
89 a2 = VEC_FMA(wj, VEC_ADD(pos, neg), a2);
90 pos = LOAD(fi + indexj_pos + 3 * VEC_SIZE);
91 neg = LOAD(fi + indexj_neg + 3 * VEC_SIZE);
92 a3 = VEC_FMA(wj, VEC_ADD(pos, neg), a3);
93 pos = LOAD(fi + indexj_pos + 4 * VEC_SIZE);
94 neg = LOAD(fi + indexj_neg + 4 * VEC_SIZE);
95 a4 = VEC_FMA(wj, VEC_ADD(pos, neg), a4);
96 pos = LOAD(fi + indexj_pos + 5 * VEC_SIZE);
97 neg = LOAD(fi + indexj_neg + 5 * VEC_SIZE);
98 a5 = VEC_FMA(wj, VEC_ADD(pos, neg), a5);
99 pos = LOAD(fi + indexj_pos + 6 * VEC_SIZE);
100 neg = LOAD(fi + indexj_neg + 6 * VEC_SIZE);
101 a6 = VEC_FMA(wj, VEC_ADD(pos, neg), a6);
102 pos = LOAD(fi + indexj_pos + 7 * VEC_SIZE);
103 neg = LOAD(fi + indexj_neg + 7 * VEC_SIZE);
104 a7 = VEC_FMA(wj, VEC_ADD(pos, neg), a7);
105 pos = LOAD(fi + indexj_pos + 8 * VEC_SIZE);
106 neg = LOAD(fi + indexj_neg + 8 * VEC_SIZE);
107 a8 = VEC_FMA(wj, VEC_ADD(pos, neg), a8);
108 pos = LOAD(fi + indexj_pos + 9 * VEC_SIZE);
109 neg = LOAD(fi + indexj_neg + 9 * VEC_SIZE);
110 a9 = VEC_FMA(wj, VEC_ADD(pos, neg), a9);
111 pos = LOAD(fi + indexj_pos + 10 * VEC_SIZE);
112 neg = LOAD(fi + indexj_neg + 10 * VEC_SIZE);
113 aa = VEC_FMA(wj, VEC_ADD(pos, neg), aa);
114 pos = LOAD(fi + indexj_pos + 11 * VEC_SIZE);
115 neg = LOAD(fi + indexj_neg + 11 * VEC_SIZE);
116 ab = VEC_FMA(wj, VEC_ADD(pos, neg), ab);
117 pos = LOAD(fi + indexj_pos + 12 * VEC_SIZE);
118 neg = LOAD(fi + indexj_neg + 12 * VEC_SIZE);
119 ac = VEC_FMA(wj, VEC_ADD(pos, neg), ac);
120 pos = LOAD(fi + indexj_pos + 13 * VEC_SIZE);
121 neg = LOAD(fi + indexj_neg + 13 * VEC_SIZE);
122 ad = VEC_FMA(wj, VEC_ADD(pos, neg), ad);
123 pos = LOAD(fi + indexj_pos + 14 * VEC_SIZE);
124 neg = LOAD(fi + indexj_neg + 14 * VEC_SIZE);
125 ae = VEC_FMA(wj, VEC_ADD(pos, neg), ae);
126 pos = LOAD(fi + indexj_pos + 15 * VEC_SIZE);
127 neg = LOAD(fi + indexj_neg + 15 * VEC_SIZE);
128 af = VEC_FMA(wj, VEC_ADD(pos, neg), af);
131 const VEC_TYPE wj = VEC_SCAL(
w0);
132 a0 = VEC_FMA(wj, LOAD(fi + base_ik), a0);
133 a1 = VEC_FMA(wj, LOAD(fi + base_ik + 1 * VEC_SIZE), a1);
134 a2 = VEC_FMA(wj, LOAD(fi + base_ik + 2 * VEC_SIZE), a2);
135 a3 = VEC_FMA(wj, LOAD(fi + base_ik + 3 * VEC_SIZE), a3);
136 a4 = VEC_FMA(wj, LOAD(fi + base_ik + 4 * VEC_SIZE), a4);
137 a5 = VEC_FMA(wj, LOAD(fi + base_ik + 5 * VEC_SIZE), a5);
138 a6 = VEC_FMA(wj, LOAD(fi + base_ik + 6 * VEC_SIZE), a6);
139 a7 = VEC_FMA(wj, LOAD(fi + base_ik + 7 * VEC_SIZE), a7);
140 a8 = VEC_FMA(wj, LOAD(fi + base_ik + 8 * VEC_SIZE), a8);
141 a9 = VEC_FMA(wj, LOAD(fi + base_ik + 9 * VEC_SIZE), a9);
142 aa = VEC_FMA(wj, LOAD(fi + base_ik + 10 * VEC_SIZE), aa);
143 ab = VEC_FMA(wj, LOAD(fi + base_ik + 11 * VEC_SIZE), ab);
144 ac = VEC_FMA(wj, LOAD(fi + base_ik + 12 * VEC_SIZE), ac);
145 ad = VEC_FMA(wj, LOAD(fi + base_ik + 13 * VEC_SIZE), ad);
146 ae = VEC_FMA(wj, LOAD(fi + base_ik + 14 * VEC_SIZE), ae);
147 af = VEC_FMA(wj, LOAD(fi + base_ik + 15 * VEC_SIZE), af);
149 STORE(fo + base_ik, a0);
150 STORE(fo + base_ik + 1 * VEC_SIZE, a1);
151 STORE(fo + base_ik + 2 * VEC_SIZE, a2);
152 STORE(fo + base_ik + 3 * VEC_SIZE, a3);
153 STORE(fo + base_ik + 4 * VEC_SIZE, a4);
154 STORE(fo + base_ik + 5 * VEC_SIZE, a5);
155 STORE(fo + base_ik + 6 * VEC_SIZE, a6);
156 STORE(fo + base_ik + 7 * VEC_SIZE, a7);
157 STORE(fo + base_ik + 8 * VEC_SIZE, a8);
158 STORE(fo + base_ik + 9 * VEC_SIZE, a9);
159 STORE(fo + base_ik + 10 * VEC_SIZE, aa);
160 STORE(fo + base_ik + 11 * VEC_SIZE, ab);
161 STORE(fo + base_ik + 12 * VEC_SIZE, ac);
162 STORE(fo + base_ik + 13 * VEC_SIZE, ad);
163 STORE(fo + base_ik + 14 * VEC_SIZE, ae);
164 STORE(fo + base_ik + 15 * VEC_SIZE, af);
170 for (;
i < (rimap_inv_max[
l] - unroll8 + 1);
i += unroll8) {
172 for (k = 0; k < (1 << ldf); k += 8 * VEC_SIZE) {
173 register VEC_TYPE a0, a1, a2, a3;
174 register VEC_TYPE a4, a5, a6, a7;
176 a0 = a1 = a2 = a3 = VEC_ZERO;
177 a4 = a5 = a6 = a7 = VEC_ZERO;
181 for (
j = 0;
j < npairs;
j++) {
182 register VEC_TYPE wj = VEC_SCAL(wpair[
j]);
185 register VEC_TYPE pos = LOAD(fi + indexj_pos);
186 register VEC_TYPE neg = LOAD(fi + indexj_neg);
187 a0 = VEC_FMA(wj, VEC_ADD(pos, neg), a0);
188 pos = LOAD(fi + indexj_pos + 1 * VEC_SIZE);
189 neg = LOAD(fi + indexj_neg + 1 * VEC_SIZE);
190 a1 = VEC_FMA(wj, VEC_ADD(pos, neg), a1);
191 pos = LOAD(fi + indexj_pos + 2 * VEC_SIZE);
192 neg = LOAD(fi + indexj_neg + 2 * VEC_SIZE);
193 a2 = VEC_FMA(wj, VEC_ADD(pos, neg), a2);
194 pos = LOAD(fi + indexj_pos + 3 * VEC_SIZE);
195 neg = LOAD(fi + indexj_neg + 3 * VEC_SIZE);
196 a3 = VEC_FMA(wj, VEC_ADD(pos, neg), a3);
197 pos = LOAD(fi + indexj_pos + 4 * VEC_SIZE);
198 neg = LOAD(fi + indexj_neg + 4 * VEC_SIZE);
199 a4 = VEC_FMA(wj, VEC_ADD(pos, neg), a4);
200 pos = LOAD(fi + indexj_pos + 5 * VEC_SIZE);
201 neg = LOAD(fi + indexj_neg + 5 * VEC_SIZE);
202 a5 = VEC_FMA(wj, VEC_ADD(pos, neg), a5);
203 pos = LOAD(fi + indexj_pos + 6 * VEC_SIZE);
204 neg = LOAD(fi + indexj_neg + 6 * VEC_SIZE);
205 a6 = VEC_FMA(wj, VEC_ADD(pos, neg), a6);
206 pos = LOAD(fi + indexj_pos + 7 * VEC_SIZE);
207 neg = LOAD(fi + indexj_neg + 7 * VEC_SIZE);
208 a7 = VEC_FMA(wj, VEC_ADD(pos, neg), a7);
210 const VEC_TYPE wj = VEC_SCAL(
w0);
211 a0 = VEC_FMA(wj, LOAD(fi + base_ik), a0);
212 a1 = VEC_FMA(wj, LOAD(fi + base_ik + 1 * VEC_SIZE), a1);
213 a2 = VEC_FMA(wj, LOAD(fi + base_ik + 2 * VEC_SIZE), a2);
214 a3 = VEC_FMA(wj, LOAD(fi + base_ik + 3 * VEC_SIZE), a3);
215 a4 = VEC_FMA(wj, LOAD(fi + base_ik + 4 * VEC_SIZE), a4);
216 a5 = VEC_FMA(wj, LOAD(fi + base_ik + 5 * VEC_SIZE), a5);
217 a6 = VEC_FMA(wj, LOAD(fi + base_ik + 6 * VEC_SIZE), a6);
218 a7 = VEC_FMA(wj, LOAD(fi + base_ik + 7 * VEC_SIZE), a7);
219 STORE(fo + base_ik, a0);
220 STORE(fo + base_ik + 1 * VEC_SIZE, a1);
221 STORE(fo + base_ik + 2 * VEC_SIZE, a2);
222 STORE(fo + base_ik + 3 * VEC_SIZE, a3);
223 STORE(fo + base_ik + 4 * VEC_SIZE, a4);
224 STORE(fo + base_ik + 5 * VEC_SIZE, a5);
225 STORE(fo + base_ik + 6 * VEC_SIZE, a6);
226 STORE(fo + base_ik + 7 * VEC_SIZE, a7);
232 for (;
i < (rimap_inv_max[
l] - unroll4 + 1);
i += unroll4) {
234 for (k = 0; k < (1 << ldf); k += 4 * VEC_SIZE) {
235 register VEC_TYPE a0, a1, a2, a3;
237 a0 = a1 = a2 = a3 = VEC_ZERO;
241 for (
j = 0;
j < npairs;
j++) {
242 register VEC_TYPE wj = VEC_SCAL(wpair[
j]);
245 register VEC_TYPE pos = LOAD(fi + indexj_pos);
246 register VEC_TYPE neg = LOAD(fi + indexj_neg);
247 a0 = VEC_FMA(wj, VEC_ADD(pos, neg), a0);
248 pos = LOAD(fi + indexj_pos + 1 * VEC_SIZE);
249 neg = LOAD(fi + indexj_neg + 1 * VEC_SIZE);
250 a1 = VEC_FMA(wj, VEC_ADD(pos, neg), a1);
251 pos = LOAD(fi + indexj_pos + 2 * VEC_SIZE);
252 neg = LOAD(fi + indexj_neg + 2 * VEC_SIZE);
253 a2 = VEC_FMA(wj, VEC_ADD(pos, neg), a2);
254 pos = LOAD(fi + indexj_pos + 3 * VEC_SIZE);
255 neg = LOAD(fi + indexj_neg + 3 * VEC_SIZE);
256 a3 = VEC_FMA(wj, VEC_ADD(pos, neg), a3);
258 const VEC_TYPE wj = VEC_SCAL(
w0);
259 a0 = VEC_FMA(wj, LOAD(fi + base_ik), a0);
260 a1 = VEC_FMA(wj, LOAD(fi + base_ik + 1 * VEC_SIZE), a1);
261 a2 = VEC_FMA(wj, LOAD(fi + base_ik + 2 * VEC_SIZE), a2);
262 a3 = VEC_FMA(wj, LOAD(fi + base_ik + 3 * VEC_SIZE), a3);
263 STORE(fo + base_ik, a0);
264 STORE(fo + base_ik + 1 * VEC_SIZE, a1);
265 STORE(fo + base_ik + 2 * VEC_SIZE, a2);
266 STORE(fo + base_ik + 3 * VEC_SIZE, a3);
272 for (;
i < (rimap_inv_max[
l] - unroll2 + 1);
i += unroll2) {
274 for (k = 0; k < (1 << ldf); k += 2 * VEC_SIZE) {
275 register VEC_TYPE a0, a1;
281 for (
j = 0;
j < npairs;
j++) {
282 register VEC_TYPE wj = VEC_SCAL(wpair[
j]);
285 register VEC_TYPE pos = LOAD(fi + indexj_pos);
286 register VEC_TYPE neg = LOAD(fi + indexj_neg);
287 a0 = VEC_FMA(wj, VEC_ADD(pos, neg), a0);
288 pos = LOAD(fi + indexj_pos + 1 * VEC_SIZE);
289 neg = LOAD(fi + indexj_neg + 1 * VEC_SIZE);
290 a1 = VEC_FMA(wj, VEC_ADD(pos, neg), a1);
292 const VEC_TYPE wj = VEC_SCAL(
w0);
293 a0 = VEC_FMA(wj, LOAD(fi + base_ik), a0);
294 a1 = VEC_FMA(wj, LOAD(fi + base_ik + 1 * VEC_SIZE), a1);
295 STORE(fo + base_ik, a0);
296 STORE(fo + base_ik + 1 * VEC_SIZE, a1);
302 for (;
i < (rimap_inv_max[
l] - unroll1 + 1);
i += unroll1) {
304 for (k = 0; k < (1 << ldf); k += VEC_SIZE) {
305 register VEC_TYPE a0 = VEC_ZERO;
307 for (
j = 0;
j < npairs;
j++) {
308 register VEC_TYPE wj = VEC_SCAL(wpair[
j]);
311 register VEC_TYPE pos = LOAD(fi + indexj_pos);
312 register VEC_TYPE neg = LOAD(fi + indexj_neg);
313 a0 = VEC_FMA(wj, VEC_ADD(pos, neg), a0);
315 const VEC_TYPE wj = VEC_SCAL(
w0);
316 a0 = VEC_FMA(wj, LOAD(fi + base_ik), a0);
317 STORE(fo + base_ik, a0);
327 for (;
i < rimap_inv_max[
l];
i++) {
331 for (
j = 0;
j < npairs;
j++) {
334 const double sum = fi[indexj_pos] + fi[indexj_neg];
337 fo[base_ik] = a +
w0 * fi[base_ik];
346#if defined(ALIGNED) && defined(FENCE)
const int *restrict index_neg
const int *restrict index_pos