Line data Source code
1 : // This file is part of ELPA.
2 : //
3 : // The ELPA library was originally created by the ELPA consortium,
4 : // consisting of the following organizations:
5 : //
6 : // - Max Planck Computing and Data Facility (MPCDF), formerly known as
7 : // Rechenzentrum Garching der Max-Planck-Gesellschaft (RZG),
8 : // - Bergische Universität Wuppertal, Lehrstuhl für angewandte
9 : // Informatik,
10 : // - Technische Universität München, Lehrstuhl für Informatik mit
11 : // Schwerpunkt Wissenschaftliches Rechnen ,
12 : // - Fritz-Haber-Institut, Berlin, Abt. Theorie,
13 : // - Max-Plack-Institut für Mathematik in den Naturwissenschaften,
14 : // Leipzig, Abt. Komplexe Strukutren in Biologie und Kognition,
15 : // and
16 : // - IBM Deutschland GmbH
17 : //
18 : // This particular source code file contains additions, changes and
19 : // enhancements authored by Intel Corporation which is not part of
20 : // the ELPA consortium.
21 : //
22 : // More information can be found here:
23 : // http://elpa.mpcdf.mpg.de/
24 : //
25 : // ELPA is free software: you can redistribute it and/or modify
26 : // it under the terms of the version 3 of the license of the
27 : // GNU Lesser General Public License as published by the Free
28 : // Software Foundation.
29 : //
30 : // ELPA is distributed in the hope that it will be useful,
31 : // but WITHOUT ANY WARRANTY; without even the implied warranty of
32 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33 : // GNU Lesser General Public License for more details.
34 : //
35 : // You should have received a copy of the GNU Lesser General Public License
36 : // along with ELPA. If not, see <http://www.gnu.org/licenses/>
37 : //
38 : // ELPA reflects a substantial effort on the part of the original
39 : // ELPA consortium, and we ask you to respect the spirit of the
40 : // license that we chose: i.e., please contribute any changes you
41 : // may have back to the original ELPA library distribution, and keep
42 : // any derivatives of ELPA under the same license that we chose for
43 : // the original distribution, the GNU Lesser General Public License.
44 : //
45 : //
46 : // --------------------------------------------------------------------------------------------------
47 : //
48 : // This file contains the compute intensive kernels for the Householder transformations.
49 : // It should be compiled with the highest possible optimization level.
50 : //
51 : // On Intel Nehalem or Intel Westmere or AMD Magny Cours use -O3 -msse3
52 : // On Intel Sandy Bridge use -O3 -mavx
53 : //
54 : // Copyright of the original code rests with the authors inside the ELPA
55 : // consortium. The copyright of any additional modifications shall rest
56 : // with their original authors, but shall adhere to the licensing terms
57 : // distributed along with the original code in the file "COPYING".
58 : //
59 : // Author: Alexander Heinecke (alexander.heinecke@mytum.de)
60 : // Adapted for building a shared-library by Andreas Marek, MPCDF (andreas.marek@mpcdf.mpg.de)
61 : // --------------------------------------------------------------------------------------------------
62 :
63 : #include "config-f90.h"
64 :
65 : #include <complex.h>
66 : #include <x86intrin.h>
67 :
68 : #ifdef DOUBLE_PRECISION_COMPLEX
69 : #define offset 2
70 : #define __SSE_DATATYPE __m128d
71 : #define _SSE_LOAD _mm_load_pd
72 : #define _SSE_STORE _mm_store_pd
73 : #define _SSE_MUL _mm_mul_pd
74 : #define _SSE_ADD _mm_add_pd
75 : #define _SSE_XOR _mm_xor_pd
76 : #define _SSE_MADDSUB _mm_maddsub_pd
77 : #define _SSE_ADDSUB _mm_addsub_pd
78 : #define _SSE_SHUFFLE _mm_shuffle_pd
79 : #define _SHUFFLE _MM_SHUFFLE2(0,1)
80 : #endif
81 : #ifdef SINGLE_PRECISION_COMPLEX
82 : #define offset 4
83 : #define __SSE_DATATYPE __m128
84 : #define _SSE_LOAD _mm_load_ps
85 : #define _SSE_STORE _mm_store_ps
86 : #define _SSE_MUL _mm_mul_ps
87 : #define _SSE_ADD _mm_add_ps
88 : #define _SSE_XOR _mm_xor_ps
89 : #define _SSE_MADDSUB _mm_maddsub_ps
90 : #define _SSE_ADDSUB _mm_addsub_ps
91 : #define _SSE_SHUFFLE _mm_shuffle_ps
92 : #define _SHUFFLE 0xb1
93 : #endif
94 :
95 : #define __forceinline __attribute__((always_inline))
96 :
97 : #ifdef HAVE_SSE_INTRINSICS
98 : #undef __AVX__
99 : #endif
100 :
101 : #ifdef DOUBLE_PRECISION_COMPLEX
102 : //Forward declaration
103 : static __forceinline void hh_trafo_complex_kernel_6_SSE_1hv_double(double complex* q, double complex* hh, int nb, int ldq);
104 : static __forceinline void hh_trafo_complex_kernel_4_SSE_1hv_double(double complex* q, double complex* hh, int nb, int ldq);
105 : static __forceinline void hh_trafo_complex_kernel_2_SSE_1hv_double(double complex* q, double complex* hh, int nb, int ldq);
106 : #endif
107 :
108 : #ifdef SINGLE_PRECISION_COMPLEX
109 : static __forceinline void hh_trafo_complex_kernel_6_SSE_1hv_single(float complex* q, float complex* hh, int nb, int ldq);
110 : static __forceinline void hh_trafo_complex_kernel_4_SSE_1hv_single(float complex* q, float complex* hh, int nb, int ldq);
111 : static __forceinline void hh_trafo_complex_kernel_2_SSE_1hv_single(float complex* q, float complex* hh, int nb, int ldq);
112 : #endif
113 :
114 : #ifdef DOUBLE_PRECISION_COMPLEX
115 : /*
116 : !f>#ifdef WITH_COMPLEX_SSE_BLOCK1_KERNEL
117 : !f> interface
118 : !f> subroutine single_hh_trafo_complex_sse_1hv_double(q, hh, pnb, pnq, pldq) &
119 : !f> bind(C, name="single_hh_trafo_complex_sse_1hv_double")
120 : !f> use, intrinsic :: iso_c_binding
121 : !f> integer(kind=c_int) :: pnb, pnq, pldq
122 : !f> ! complex(kind=c_double_complex) :: q(*)
123 : !f> type(c_ptr), value :: q
124 : !f> complex(kind=c_double_complex) :: hh(pnb,2)
125 : !f> end subroutine
126 : !f> end interface
127 : !f>#endif
128 : */
129 : #endif
130 :
131 : #ifdef SINGLE_PRECISION_COMPLEX
132 : /*
133 : !f>#ifdef HAVE_SSE_INTRINSICS
134 : !f> interface
135 : !f> subroutine single_hh_trafo_complex_sse_1hv_single(q, hh, pnb, pnq, pldq) &
136 : !f> bind(C, name="single_hh_trafo_complex_sse_1hv_single")
137 : !f> use, intrinsic :: iso_c_binding
138 : !f> integer(kind=c_int) :: pnb, pnq, pldq
139 : !f> ! complex(kind=c_float_complex) :: q(*)
140 : !f> type(c_ptr), value :: q
141 : !f> complex(kind=c_float_complex) :: hh(pnb,2)
142 : !f> end subroutine
143 : !f> end interface
144 : !f>#endif
145 : */
146 : #endif
147 :
148 : #ifdef DOUBLE_PRECISION_COMPLEX
149 1333248 : void single_hh_trafo_complex_sse_1hv_double(double complex* q, double complex* hh, int* pnb, int* pnq, int* pldq)
150 : #endif
151 : #ifdef SINGLE_PRECISION_COMPLEX
152 666624 : void single_hh_trafo_complex_sse_1hv_single(float complex* q, float complex* hh, int* pnb, int* pnq, int* pldq)
153 : #endif
154 : {
155 : int i;
156 1999872 : int nb = *pnb;
157 1999872 : int nq = *pldq;
158 1999872 : int ldq = *pldq;
159 : //int ldh = *pldh;
160 :
161 13999104 : for (i = 0; i < nq-4; i+=6)
162 : {
163 : #ifdef DOUBLE_PRECISION_COMPLEX
164 7999488 : hh_trafo_complex_kernel_6_SSE_1hv_double(&q[i], hh, nb, ldq);
165 : #endif
166 : #ifdef SINGLE_PRECISION_COMPLEX
167 3999744 : hh_trafo_complex_kernel_6_SSE_1hv_single(&q[i], hh, nb, ldq);
168 : #endif
169 : }
170 1999872 : if (nq-i == 0) {
171 0 : return;
172 : } else {
173 :
174 1999872 : if (nq-i > 2)
175 : {
176 : #ifdef DOUBLE_PRECISION_COMPLEX
177 1333248 : hh_trafo_complex_kernel_4_SSE_1hv_double(&q[i], hh, nb, ldq);
178 : #endif
179 : #ifdef SINGLE_PRECISION_COMPLEX
180 666624 : hh_trafo_complex_kernel_4_SSE_1hv_single(&q[i], hh, nb, ldq);
181 : #endif
182 : }
183 : else
184 : {
185 : #ifdef DOUBLE_PRECISION_COMPLEX
186 0 : hh_trafo_complex_kernel_2_SSE_1hv_double(&q[i], hh, nb, ldq);
187 : #endif
188 : #ifdef SINGLE_PRECISION_COMPLEX
189 0 : hh_trafo_complex_kernel_2_SSE_1hv_single(&q[i], hh, nb, ldq);
190 : #endif
191 : }
192 : }
193 : }
194 :
195 : #ifdef DOUBLE_PRECISION_COMPLEX
196 : static __forceinline void hh_trafo_complex_kernel_6_SSE_1hv_double(double complex* q, double complex* hh, int nb, int ldq)
197 : #endif
198 : #ifdef SINGLE_PRECISION_COMPLEX
199 : static __forceinline void hh_trafo_complex_kernel_6_SSE_1hv_single(float complex* q, float complex* hh, int nb, int ldq)
200 : #endif
201 : {
202 :
203 : #ifdef DOUBLE_PRECISION_COMPLEX
204 7999488 : double* q_dbl = (double*)q;
205 7999488 : double* hh_dbl = (double*)hh;
206 : #endif
207 : #ifdef SINGLE_PRECISION_COMPLEX
208 3999744 : float* q_dbl = (float*)q;
209 3999744 : float* hh_dbl = (float*)hh;
210 : #endif
211 : __SSE_DATATYPE x1, x2, x3, x4, x5, x6;
212 : __SSE_DATATYPE q1, q2, q3, q4, q5, q6;
213 : __SSE_DATATYPE h1_real, h1_imag;
214 : __SSE_DATATYPE tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
215 11999232 : int i=0;
216 :
217 : #ifdef DOUBLE_PRECISION_COMPLEX
218 7999488 : __SSE_DATATYPE sign = (__SSE_DATATYPE)_mm_set_epi64x(0x8000000000000000, 0x8000000000000000);
219 : #endif
220 : #ifdef SINGLE_PRECISION_COMPLEX
221 3999744 : __SSE_DATATYPE sign = (__SSE_DATATYPE)_mm_set_epi32(0x80000000, 0x80000000, 0x80000000, 0x80000000);
222 : #endif
223 :
224 11999232 : x1 = _SSE_LOAD(&q_dbl[0]);
225 23998464 : x2 = _SSE_LOAD(&q_dbl[offset]);
226 23998464 : x3 = _SSE_LOAD(&q_dbl[2*offset]);
227 : #ifdef DOUBLE_PRECISION_COMPLEX
228 15998976 : x4 = _SSE_LOAD(&q_dbl[3*offset]);
229 15998976 : x5 = _SSE_LOAD(&q_dbl[4*offset]);
230 15998976 : x6 = _SSE_LOAD(&q_dbl[5*offset]);
231 : #endif
232 383975424 : for (i = 1; i < nb; i++)
233 : {
234 :
235 : #ifdef DOUBLE_PRECISION_COMPLEX
236 495968256 : h1_real = _mm_loaddup_pd(&hh_dbl[i*2]);
237 495968256 : h1_imag = _mm_loaddup_pd(&hh_dbl[(i*2)+1]);
238 : #endif
239 : #ifdef SINGLE_PRECISION_COMPLEX
240 495968256 : h1_real = _mm_moveldup_ps(_mm_castpd_ps(_mm_loaddup_pd( (double *)(&hh_dbl[i*2]) )));
241 495968256 : h1_imag = _mm_moveldup_ps(_mm_castpd_ps(_mm_loaddup_pd( (double *)(&hh_dbl[(i*2)+1]) )));
242 : #endif
243 : #ifndef __ELPA_USE_FMA__
244 : // conjugate
245 371976192 : h1_imag = _SSE_XOR(h1_imag, sign);
246 : #endif
247 :
248 743952384 : q1 = _SSE_LOAD(&q_dbl[(2*i*ldq)+0]);
249 743952384 : q2 = _SSE_LOAD(&q_dbl[(2*i*ldq)+offset]);
250 743952384 : q3 = _SSE_LOAD(&q_dbl[(2*i*ldq)+2*offset]);
251 : #ifdef DOUBLE_PRECISION_COMPLEX
252 495968256 : q4 = _SSE_LOAD(&q_dbl[(2*i*ldq)+3*offset]);
253 495968256 : q5 = _SSE_LOAD(&q_dbl[(2*i*ldq)+4*offset]);
254 495968256 : q6 = _SSE_LOAD(&q_dbl[(2*i*ldq)+5*offset]);
255 : #endif
256 :
257 371976192 : tmp1 = _SSE_MUL(h1_imag, q1);
258 :
259 : #ifdef __ELPA_USE_FMA__
260 : x1 = _SSE_ADD(x1, _mm_msubadd_pd(h1_real, q1, _SSE_SHUFFLE(tmp1, tmp1, _SHUFFLE)));
261 : #else
262 1487904768 : x1 = _SSE_ADD(x1, _SSE_ADDSUB( _SSE_MUL(h1_real, q1), _SSE_SHUFFLE(tmp1, tmp1, _SHUFFLE)));
263 : #endif
264 371976192 : tmp2 = _SSE_MUL(h1_imag, q2);
265 : #ifdef __ELPA_USE_FMA__
266 : x2 = _SSE_ADD(x2, _mm_msubadd_pd(h1_real, q2, _SSE_SHUFFLE(tmp2, tmp2, _SHUFFLE)));
267 : #else
268 1487904768 : x2 = _SSE_ADD(x2, _SSE_ADDSUB( _SSE_MUL(h1_real, q2), _SSE_SHUFFLE(tmp2, tmp2, _SHUFFLE)));
269 : #endif
270 371976192 : tmp3 = _SSE_MUL(h1_imag, q3);
271 : #ifdef __ELPA_USE_FMA__
272 : x3 = _SSE_ADD(x3, _mm_msubadd_pd(h1_real, q3, _SSE_SHUFFLE(tmp3, tmp3, _SHUFFLE)));
273 : #else
274 1487904768 : x3 = _SSE_ADD(x3, _SSE_ADDSUB( _SSE_MUL(h1_real, q3), _SSE_SHUFFLE(tmp3, tmp3, _SHUFFLE)));
275 : #endif
276 :
277 : #ifdef DOUBLE_PRECISION_COMPLEX
278 247984128 : tmp4 = _SSE_MUL(h1_imag, q4);
279 : #ifdef __ELPA_USE_FMA__
280 : x4 = _SSE_ADD(x4, _mm_msubadd_pd(h1_real, q4, _SSE_SHUFFLE(tmp4, tmp4, _SHUFFLE)));
281 : #else
282 991936512 : x4 = _SSE_ADD(x4, _SSE_ADDSUB( _SSE_MUL(h1_real, q4), _SSE_SHUFFLE(tmp4, tmp4, _SHUFFLE)));
283 : #endif
284 247984128 : tmp5 = _SSE_MUL(h1_imag, q5);
285 : #ifdef __ELPA_USE_FMA__
286 : x5 = _SSE_ADD(x5, _mm_msubadd_pd(h1_real, q5, _SSE_SHUFFLE(tmp5, tmp5, _SHUFFLE)));
287 : #else
288 991936512 : x5 = _SSE_ADD(x5, _SSE_ADDSUB( _SSE_MUL(h1_real, q5), _SSE_SHUFFLE(tmp5, tmp5, _SHUFFLE)));
289 : #endif
290 247984128 : tmp6 = _SSE_MUL(h1_imag, q6);
291 : #ifdef __ELPA_USE_FMA__
292 : x6 = _SSE_ADD(x6, _mm_msubadd_pd(h1_real, q6, _SSE_SHUFFLE(tmp6, tmp6, _SHUFFLE)));
293 : #else
294 991936512 : x6 = _SSE_ADD(x6, _SSE_ADDSUB( _SSE_MUL(h1_real, q6), _SSE_SHUFFLE(tmp6, tmp6, _SHUFFLE)));
295 : #endif
296 :
297 : #endif /* DOUBLE_PRECISION_COMPLEX */
298 : }
299 :
300 : #ifdef DOUBLE_PRECISION_COMPLEX
301 7999488 : h1_real = _mm_loaddup_pd(&hh_dbl[0]);
302 15998976 : h1_imag = _mm_loaddup_pd(&hh_dbl[1]);
303 : #endif
304 : #ifdef SINGLE_PRECISION_COMPLEX
305 11999232 : h1_real = _mm_moveldup_ps(_mm_castpd_ps(_mm_loaddup_pd( (double *)(&hh_dbl[0]) )));
306 15998976 : h1_imag = _mm_moveldup_ps(_mm_castpd_ps(_mm_loaddup_pd( (double *)(&hh_dbl[1]) )));
307 : #endif
308 11999232 : h1_real = _SSE_XOR(h1_real, sign);
309 11999232 : h1_imag = _SSE_XOR(h1_imag, sign);
310 :
311 11999232 : tmp1 = _SSE_MUL(h1_imag, x1);
312 :
313 : #ifdef __ELPA_USE_FMA__
314 : x1 = _SSE_MADDSUB(h1_real, x1, _SSE_SHUFFLE(tmp1, tmp1, _SHUFFLE));
315 : #else
316 35997696 : x1 = _SSE_ADDSUB( _SSE_MUL(h1_real, x1), _SSE_SHUFFLE(tmp1, tmp1, _SHUFFLE));
317 : #endif
318 11999232 : tmp2 = _SSE_MUL(h1_imag, x2);
319 : #ifdef __ELPA_USE_FMA__
320 : x2 = _SSE_MADDSUB(h1_real, x2, _SSE_SHUFFLE(tmp2, tmp2, _SHUFFLE));
321 : #else
322 35997696 : x2 = _SSE_ADDSUB( _SSE_MUL(h1_real, x2), _SSE_SHUFFLE(tmp2, tmp2, _SHUFFLE));
323 : #endif
324 11999232 : tmp3 = _SSE_MUL(h1_imag, x3);
325 : #ifdef __ELPA_USE_FMA__
326 : x3 = _SSE_MADDSUB(h1_real, x3, _SSE_SHUFFLE(tmp3, tmp3, _SHUFFLE));
327 : #else
328 35997696 : x3 = _SSE_ADDSUB( _SSE_MUL(h1_real, x3), _SSE_SHUFFLE(tmp3, tmp3, _SHUFFLE));
329 : #endif
330 :
331 : #ifdef DOUBLE_PRECISION_COMPLEX
332 7999488 : tmp4 = _SSE_MUL(h1_imag, x4);
333 : #ifdef __ELPA_USE_FMA__
334 : x4 = _SSE_MADDSUB(h1_real, x4, _SSE_SHUFFLE(tmp4, tmp4, _SHUFFLE));
335 : #else
336 23998464 : x4 = _SSE_ADDSUB( _SSE_MUL(h1_real, x4), _SSE_SHUFFLE(tmp4, tmp4, _SHUFFLE));
337 : #endif
338 7999488 : tmp5 = _SSE_MUL(h1_imag, x5);
339 : #ifdef __ELPA_USE_FMA__
340 : x5 = _SSE_MADDSUB(h1_real, x5, _SSE_SHUFFLE(tmp5, tmp5, _SHUFFLE));
341 : #else
342 23998464 : x5 = _SSE_ADDSUB( _SSE_MUL(h1_real, x5), _SSE_SHUFFLE(tmp5, tmp5, _SHUFFLE));
343 : #endif
344 7999488 : tmp6 = _SSE_MUL(h1_imag, x6);
345 : #ifdef __ELPA_USE_FMA__
346 : x6 = _SSE_MADDSUB(h1_real, x6, _SSE_SHUFFLE(tmp6, tmp6, _SHUFFLE));
347 : #else
348 23998464 : x6 = _SSE_ADDSUB( _SSE_MUL(h1_real, x6), _SSE_SHUFFLE(tmp6, tmp6, _SHUFFLE));
349 : #endif
350 : #endif /* DOUBLE_PRECISION_COMPLEX */
351 :
352 11999232 : q1 = _SSE_LOAD(&q_dbl[0]);
353 23998464 : q2 = _SSE_LOAD(&q_dbl[offset]);
354 23998464 : q3 = _SSE_LOAD(&q_dbl[2*offset]);
355 : #ifdef DOUBLE_PRECISION_COMPLEX
356 15998976 : q4 = _SSE_LOAD(&q_dbl[3*offset]);
357 15998976 : q5 = _SSE_LOAD(&q_dbl[4*offset]);
358 15998976 : q6 = _SSE_LOAD(&q_dbl[5*offset]);
359 : #endif
360 :
361 11999232 : q1 = _SSE_ADD(q1, x1);
362 11999232 : q2 = _SSE_ADD(q2, x2);
363 11999232 : q3 = _SSE_ADD(q3, x3);
364 : #ifdef DOUBLE_PRECISION_COMPLEX
365 7999488 : q4 = _SSE_ADD(q4, x4);
366 7999488 : q5 = _SSE_ADD(q5, x5);
367 7999488 : q6 = _SSE_ADD(q6, x6);
368 : #endif
369 :
370 : _SSE_STORE(&q_dbl[0], q1);
371 11999232 : _SSE_STORE(&q_dbl[offset], q2);
372 11999232 : _SSE_STORE(&q_dbl[2*offset], q3);
373 : #ifdef DOUBLE_PRECISION_COMPLEX
374 7999488 : _SSE_STORE(&q_dbl[3*offset], q4);
375 7999488 : _SSE_STORE(&q_dbl[4*offset], q5);
376 7999488 : _SSE_STORE(&q_dbl[5*offset], q6);
377 : #endif
378 383975424 : for (i = 1; i < nb; i++)
379 : {
380 : #ifdef DOUBLE_PRECISION_COMPLEX
381 495968256 : h1_real = _mm_loaddup_pd(&hh_dbl[i*2]);
382 495968256 : h1_imag = _mm_loaddup_pd(&hh_dbl[(i*2)+1]);
383 : #endif
384 : #ifdef SINGLE_PRECISION_COMPLEX
385 495968256 : h1_real = _mm_moveldup_ps(_mm_castpd_ps(_mm_loaddup_pd( (double *)(&hh_dbl[i*2]) )));
386 495968256 : h1_imag = _mm_moveldup_ps(_mm_castpd_ps(_mm_loaddup_pd( (double *)(&hh_dbl[(i*2)+1]) )));
387 : #endif
388 :
389 743952384 : q1 = _SSE_LOAD(&q_dbl[(2*i*ldq)+0]);
390 743952384 : q2 = _SSE_LOAD(&q_dbl[(2*i*ldq)+offset]);
391 743952384 : q3 = _SSE_LOAD(&q_dbl[(2*i*ldq)+2*offset]);
392 : #ifdef DOUBLE_PRECISION_COMPLEX
393 495968256 : q4 = _SSE_LOAD(&q_dbl[(2*i*ldq)+3*offset]);
394 495968256 : q5 = _SSE_LOAD(&q_dbl[(2*i*ldq)+4*offset]);
395 495968256 : q6 = _SSE_LOAD(&q_dbl[(2*i*ldq)+5*offset]);
396 : #endif
397 371976192 : tmp1 = _SSE_MUL(h1_imag, x1);
398 :
399 : #ifdef __ELPA_USE_FMA__
400 : q1 = _SSE_ADD(q1, _SSE_MADDSUB(h1_real, x1, _SSE_SHUFFLE(tmp1, tmp1, _SHUFFLE)));
401 : #else
402 1487904768 : q1 = _SSE_ADD(q1, _SSE_ADDSUB( _SSE_MUL(h1_real, x1), _SSE_SHUFFLE(tmp1, tmp1, _SHUFFLE)));
403 : #endif
404 371976192 : tmp2 = _SSE_MUL(h1_imag, x2);
405 : #ifdef __ELPA_USE_FMA__
406 : q2 = _SSE_ADD(q2, _SSE_MADDSUB(h1_real, x2, _SSE_SHUFFLE(tmp2, tmp2, _SHUFFLE)));
407 : #else
408 1487904768 : q2 = _SSE_ADD(q2, _SSE_ADDSUB( _SSE_MUL(h1_real, x2), _SSE_SHUFFLE(tmp2, tmp2, _SHUFFLE)));
409 : #endif
410 371976192 : tmp3 = _SSE_MUL(h1_imag, x3);
411 : #ifdef __ELPA_USE_FMA__
412 : q3 = _SSE_ADD(q3, _SSE_MADDSUB(h1_real, x3, _SSE_SHUFFLE(tmp3, tmp3, _SHUFFLE)));
413 : #else
414 1487904768 : q3 = _SSE_ADD(q3, _SSE_ADDSUB( _SSE_MUL(h1_real, x3), _SSE_SHUFFLE(tmp3, tmp3, _SHUFFLE)));
415 : #endif
416 :
417 : #ifdef DOUBLE_PRECISION_COMPLEX
418 247984128 : tmp4 = _SSE_MUL(h1_imag, x4);
419 : #ifdef __ELPA_USE_FMA__
420 : q4 = _SSE_ADD(q4, _SSE_MADDSUB(h1_real, x4, _SSE_SHUFFLE(tmp4, tmp4, _SHUFFLE)));
421 : #else
422 991936512 : q4 = _SSE_ADD(q4, _SSE_ADDSUB( _SSE_MUL(h1_real, x4), _SSE_SHUFFLE(tmp4, tmp4, _SHUFFLE)));
423 : #endif
424 247984128 : tmp5 = _SSE_MUL(h1_imag, x5);
425 : #ifdef __ELPA_USE_FMA__
426 : q5 = _SSE_ADD(q5, _SSE_MADDSUB(h1_real, x5, _SSE_SHUFFLE(tmp5, tmp5, _SHUFFLE)));
427 : #else
428 991936512 : q5 = _SSE_ADD(q5, _SSE_ADDSUB( _SSE_MUL(h1_real, x5), _SSE_SHUFFLE(tmp5, tmp5, _SHUFFLE)));
429 : #endif
430 247984128 : tmp6 = _SSE_MUL(h1_imag, x6);
431 : #ifdef __ELPA_USE_FMA__
432 : q6 = _SSE_ADD(q6, _SSE_MADDSUB(h1_real, x6, _SSE_SHUFFLE(tmp6, tmp6, _SHUFFLE)));
433 : #else
434 991936512 : q6 = _SSE_ADD(q6, _SSE_ADDSUB( _SSE_MUL(h1_real, x6), _SSE_SHUFFLE(tmp6, tmp6, _SHUFFLE)));
435 : #endif
436 : #endif /* DOUBLE_PRECISION_COMPLEX */
437 :
438 371976192 : _SSE_STORE(&q_dbl[(2*i*ldq)+0], q1);
439 371976192 : _SSE_STORE(&q_dbl[(2*i*ldq)+offset], q2);
440 371976192 : _SSE_STORE(&q_dbl[(2*i*ldq)+2*offset], q3);
441 : #ifdef DOUBLE_PRECISION_COMPLEX
442 247984128 : _SSE_STORE(&q_dbl[(2*i*ldq)+3*offset], q4);
443 247984128 : _SSE_STORE(&q_dbl[(2*i*ldq)+4*offset], q5);
444 247984128 : _SSE_STORE(&q_dbl[(2*i*ldq)+5*offset], q6);
445 : #endif
446 : }
447 : }
448 :
449 : #ifdef DOUBLE_PRECISION_COMPLEX
450 : static __forceinline void hh_trafo_complex_kernel_4_SSE_1hv_double(double complex* q, double complex* hh, int nb, int ldq)
451 : #endif
452 : #ifdef SINGLE_PRECISION_COMPLEX
453 : static __forceinline void hh_trafo_complex_kernel_4_SSE_1hv_single(float complex* q, float complex* hh, int nb, int ldq)
454 : #endif
455 : {
456 : #ifdef DOUBLE_PRECISION_COMPLEX
457 1333248 : double* q_dbl = (double*)q;
458 1333248 : double* hh_dbl = (double*)hh;
459 : #endif
460 : #ifdef SINGLE_PRECISION_COMPLEX
461 666624 : float* q_dbl = (float*)q;
462 666624 : float* hh_dbl = (float*)hh;
463 : #endif
464 : __SSE_DATATYPE x1, x2, x3, x4;
465 : __SSE_DATATYPE q1, q2, q3, q4;
466 : __SSE_DATATYPE h1_real, h1_imag;
467 : __SSE_DATATYPE tmp1, tmp2, tmp3, tmp4;
468 1999872 : int i=0;
469 : #ifdef DOUBLE_PRECISION_COMPLEX
470 1333248 : __SSE_DATATYPE sign = (__SSE_DATATYPE)_mm_set_epi64x(0x8000000000000000, 0x8000000000000000);
471 : #endif
472 : #ifdef SINGLE_PRECISION_COMPLEX
473 666624 : __SSE_DATATYPE sign = (__SSE_DATATYPE)_mm_set_epi32(0x80000000, 0x80000000, 0x80000000, 0x80000000);
474 : #endif
475 :
476 1999872 : x1 = _SSE_LOAD(&q_dbl[0]);
477 3999744 : x2 = _SSE_LOAD(&q_dbl[offset]);
478 : #ifdef DOUBLE_PRECISION_COMPLEX
479 2666496 : x3 = _SSE_LOAD(&q_dbl[2*offset]);
480 2666496 : x4 = _SSE_LOAD(&q_dbl[3*offset]);
481 : #endif
482 63995904 : for (i = 1; i < nb; i++)
483 : {
484 : #ifdef DOUBLE_PRECISION_COMPLEX
485 82661376 : h1_real = _mm_loaddup_pd(&hh_dbl[i*2]);
486 82661376 : h1_imag = _mm_loaddup_pd(&hh_dbl[(i*2)+1]);
487 : #endif
488 : #ifdef SINGLE_PRECISION_COMPLEX
489 82661376 : h1_real = _mm_moveldup_ps(_mm_castpd_ps(_mm_loaddup_pd( (double *)(&hh_dbl[i*2]) )));
490 82661376 : h1_imag = _mm_moveldup_ps(_mm_castpd_ps(_mm_loaddup_pd( (double *)(&hh_dbl[(i*2)+1]) )));
491 : #endif
492 : #ifndef __ELPA_USE_FMA__
493 : // conjugate
494 61996032 : h1_imag = _SSE_XOR(h1_imag, sign);
495 : #endif
496 :
497 123992064 : q1 = _SSE_LOAD(&q_dbl[(2*i*ldq)+0]);
498 123992064 : q2 = _SSE_LOAD(&q_dbl[(2*i*ldq)+offset]);
499 : #ifdef DOUBLE_PRECISION_COMPLEX
500 82661376 : q3 = _SSE_LOAD(&q_dbl[(2*i*ldq)+2*offset]);
501 82661376 : q4 = _SSE_LOAD(&q_dbl[(2*i*ldq)+3*offset]);
502 : #endif
503 61996032 : tmp1 = _SSE_MUL(h1_imag, q1);
504 :
505 : #ifdef __ELPA_USE_FMA__
506 : x1 = _SSE_ADD(x1, _mm_msubadd_pd(h1_real, q1, _SSE_SHUFFLE(tmp1, tmp1, _SHUFFLE)));
507 : #else
508 247984128 : x1 = _SSE_ADD(x1, _SSE_ADDSUB( _SSE_MUL(h1_real, q1), _SSE_SHUFFLE(tmp1, tmp1, _SHUFFLE)));
509 : #endif
510 :
511 61996032 : tmp2 = _SSE_MUL(h1_imag, q2);
512 : #ifdef __ELPA_USE_FMA__
513 : x2 = _SSE_ADD(x2, _mm_msubadd_pd(h1_real, q2, _SSE_SHUFFLE(tmp2, tmp2, _SHUFFLE)));
514 : #else
515 247984128 : x2 = _SSE_ADD(x2, _SSE_ADDSUB( _SSE_MUL(h1_real, q2), _SSE_SHUFFLE(tmp2, tmp2, _SHUFFLE)));
516 : #endif
517 :
518 : #ifdef DOUBLE_PRECISION_COMPLEX
519 41330688 : tmp3 = _SSE_MUL(h1_imag, q3);
520 : #ifdef __ELPA_USE_FMA__
521 : x3 = _SSE_ADD(x3, _mm_msubadd_pd(h1_real, q3, _SSE_SHUFFLE(tmp3, tmp3, _SHUFFLE)));
522 : #else
523 165322752 : x3 = _SSE_ADD(x3, _SSE_ADDSUB( _SSE_MUL(h1_real, q3), _SSE_SHUFFLE(tmp3, tmp3, _SHUFFLE)));
524 : #endif
525 41330688 : tmp4 = _SSE_MUL(h1_imag, q4);
526 : #ifdef __ELPA_USE_FMA__
527 : x4 = _SSE_ADD(x4, _mm_msubadd_pd(h1_real, q4, _SSE_SHUFFLE(tmp4, tmp4, _SHUFFLE)));
528 : #else
529 165322752 : x4 = _SSE_ADD(x4, _SSE_ADDSUB( _SSE_MUL(h1_real, q4), _SSE_SHUFFLE(tmp4, tmp4, _SHUFFLE)));
530 : #endif
531 : #endif /* DOUBLE_PRECISION_COMPLEX */
532 : }
533 :
534 : #ifdef DOUBLE_PRECISION_COMPLEX
535 1333248 : h1_real = _mm_loaddup_pd(&hh_dbl[0]);
536 2666496 : h1_imag = _mm_loaddup_pd(&hh_dbl[1]);
537 : #endif
538 : #ifdef SINGLE_PRECISION_COMPLEX
539 1999872 : h1_real = _mm_moveldup_ps(_mm_castpd_ps(_mm_loaddup_pd( (double *)(&hh_dbl[0]) )));
540 2666496 : h1_imag = _mm_moveldup_ps(_mm_castpd_ps(_mm_loaddup_pd( (double *)(&hh_dbl[1]) )));
541 : #endif
542 1999872 : h1_real = _SSE_XOR(h1_real, sign);
543 1999872 : h1_imag = _SSE_XOR(h1_imag, sign);
544 :
545 1999872 : tmp1 = _SSE_MUL(h1_imag, x1);
546 :
547 : #ifdef __ELPA_USE_FMA__
548 : x1 = _SSE_MADDSUB(h1_real, x1, _SSE_SHUFFLE(tmp1, tmp1, _SHUFFLE));
549 : #else
550 5999616 : x1 = _SSE_ADDSUB( _SSE_MUL(h1_real, x1), _SSE_SHUFFLE(tmp1, tmp1, _SHUFFLE));
551 : #endif
552 1999872 : tmp2 = _SSE_MUL(h1_imag, x2);
553 : #ifdef __ELPA_USE_FMA__
554 : x2 = _SSE_MADDSUB(h1_real, x2, _SSE_SHUFFLE(tmp2, tmp2, _SHUFFLE));
555 : #else
556 5999616 : x2 = _SSE_ADDSUB( _SSE_MUL(h1_real, x2), _SSE_SHUFFLE(tmp2, tmp2, _SHUFFLE));
557 : #endif
558 :
559 : #ifdef DOUBLE_PRECISION_COMPLEX
560 1333248 : tmp3 = _SSE_MUL(h1_imag, x3);
561 : #ifdef __ELPA_USE_FMA__
562 : x3 = _SSE_MADDSUB(h1_real, x3, _SSE_SHUFFLE(tmp3, tmp3, _SHUFFLE));
563 : #else
564 3999744 : x3 = _SSE_ADDSUB( _SSE_MUL(h1_real, x3), _SSE_SHUFFLE(tmp3, tmp3, _SHUFFLE));
565 : #endif
566 1333248 : tmp4 = _SSE_MUL(h1_imag, x4);
567 : #ifdef __ELPA_USE_FMA__
568 : x4 = _SSE_MADDSUB(h1_real, x4, _SSE_SHUFFLE(tmp4, tmp4, _SHUFFLE));
569 : #else
570 3999744 : x4 = _SSE_ADDSUB( _SSE_MUL(h1_real, x4), _SSE_SHUFFLE(tmp4, tmp4, _SHUFFLE));
571 : #endif
572 : #endif /* DOUBLE_PRECISION_COMPLEX */
573 :
574 1999872 : q1 = _SSE_LOAD(&q_dbl[0]);
575 3999744 : q2 = _SSE_LOAD(&q_dbl[offset]);
576 : #ifdef DOUBLE_PRECISION_COMPLEX
577 2666496 : q3 = _SSE_LOAD(&q_dbl[2*offset]);
578 2666496 : q4 = _SSE_LOAD(&q_dbl[3*offset]);
579 : #endif
580 1999872 : q1 = _SSE_ADD(q1, x1);
581 1999872 : q2 = _SSE_ADD(q2, x2);
582 : #ifdef DOUBLE_PRECISION_COMPLEX
583 1333248 : q3 = _SSE_ADD(q3, x3);
584 1333248 : q4 = _SSE_ADD(q4, x4);
585 : #endif
586 : _SSE_STORE(&q_dbl[0], q1);
587 1999872 : _SSE_STORE(&q_dbl[offset], q2);
588 : #ifdef DOUBLE_PRECISION_COMPLEX
589 1333248 : _SSE_STORE(&q_dbl[2*offset], q3);
590 1333248 : _SSE_STORE(&q_dbl[3*offset], q4);
591 : #endif
592 63995904 : for (i = 1; i < nb; i++)
593 : {
594 : #ifdef DOUBLE_PRECISION_COMPLEX
595 82661376 : h1_real = _mm_loaddup_pd(&hh_dbl[i*2]);
596 82661376 : h1_imag = _mm_loaddup_pd(&hh_dbl[(i*2)+1]);
597 : #endif
598 : #ifdef SINGLE_PRECISION_COMPLEX
599 82661376 : h1_real = _mm_moveldup_ps(_mm_castpd_ps(_mm_loaddup_pd( (double *)(&hh_dbl[i*2]) )));
600 82661376 : h1_imag = _mm_moveldup_ps(_mm_castpd_ps(_mm_loaddup_pd( (double *)(&hh_dbl[(i*2)+1]) )));
601 : #endif
602 123992064 : q1 = _SSE_LOAD(&q_dbl[(2*i*ldq)+0]);
603 123992064 : q2 = _SSE_LOAD(&q_dbl[(2*i*ldq)+offset]);
604 : #ifdef DOUBLE_PRECISION_COMPLEX
605 82661376 : q3 = _SSE_LOAD(&q_dbl[(2*i*ldq)+2*offset]);
606 82661376 : q4 = _SSE_LOAD(&q_dbl[(2*i*ldq)+3*offset]);
607 : #endif
608 61996032 : tmp1 = _SSE_MUL(h1_imag, x1);
609 :
610 : #ifdef __ELPA_USE_FMA__
611 : q1 = _SSE_ADD(q1, _SSE_MADDSUB(h1_real, x1, _SSE_SHUFFLE(tmp1, tmp1, _SHUFFLE)));
612 : #else
613 247984128 : q1 = _SSE_ADD(q1, _SSE_ADDSUB( _SSE_MUL(h1_real, x1), _SSE_SHUFFLE(tmp1, tmp1, _SHUFFLE)));
614 : #endif
615 61996032 : tmp2 = _SSE_MUL(h1_imag, x2);
616 : #ifdef __ELPA_USE_FMA__
617 : q2 = _SSE_ADD(q2, _SSE_MADDSUB(h1_real, x2, _SSE_SHUFFLE(tmp2, tmp2, _SHUFFLE)));
618 : #else
619 247984128 : q2 = _SSE_ADD(q2, _SSE_ADDSUB( _SSE_MUL(h1_real, x2), _SSE_SHUFFLE(tmp2, tmp2, _SHUFFLE)));
620 : #endif
621 :
622 : #ifdef DOUBLE_PRECISION_COMPLEX
623 41330688 : tmp3 = _SSE_MUL(h1_imag, x3);
624 : #ifdef __ELPA_USE_FMA__
625 : q3 = _SSE_ADD(q3, _SSE_MADDSUB(h1_real, x3, _SSE_SHUFFLE(tmp3, tmp3, _SHUFFLE)));
626 : #else
627 165322752 : q3 = _SSE_ADD(q3, _SSE_ADDSUB( _SSE_MUL(h1_real, x3), _SSE_SHUFFLE(tmp3, tmp3, _SHUFFLE)));
628 : #endif
629 41330688 : tmp4 = _SSE_MUL(h1_imag, x4);
630 : #ifdef __ELPA_USE_FMA__
631 : q4 = _SSE_ADD(q4, _SSE_MADDSUB(h1_real, x4, _SSE_SHUFFLE(tmp4, tmp4, _SHUFFLE)));
632 : #else
633 165322752 : q4 = _SSE_ADD(q4, _SSE_ADDSUB( _SSE_MUL(h1_real, x4), _SSE_SHUFFLE(tmp4, tmp4, _SHUFFLE)));
634 : #endif
635 : #endif /* DOUBLE_PRECISION_COMPLEX */
636 :
637 61996032 : _SSE_STORE(&q_dbl[(2*i*ldq)+0], q1);
638 61996032 : _SSE_STORE(&q_dbl[(2*i*ldq)+offset], q2);
639 : #ifdef DOUBLE_PRECISION_COMPLEX
640 41330688 : _SSE_STORE(&q_dbl[(2*i*ldq)+2*offset], q3);
641 41330688 : _SSE_STORE(&q_dbl[(2*i*ldq)+3*offset], q4);
642 : #endif
643 : }
644 : }
645 :
646 : #ifdef DOUBLE_PRECISION_COMPLEX
647 : static __forceinline void hh_trafo_complex_kernel_2_SSE_1hv_double(double complex* q, double complex* hh, int nb, int ldq)
648 : #endif
649 : #ifdef SINGLE_PRECISION_COMPLEX
650 : static __forceinline void hh_trafo_complex_kernel_2_SSE_1hv_single(float complex* q, float complex* hh, int nb, int ldq)
651 : #endif
652 : {
653 :
654 : #ifdef DOUBLE_PRECISION_COMPLEX
655 0 : double* q_dbl = (double*)q;
656 0 : double* hh_dbl = (double*)hh;
657 : #endif
658 : #ifdef SINGLE_PRECISION_COMPLEX
659 0 : float* q_dbl = (float*)q;
660 0 : float* hh_dbl = (float*)hh;
661 : #endif
662 : __SSE_DATATYPE x1, x2;
663 : __SSE_DATATYPE q1, q2;
664 : __SSE_DATATYPE h1_real, h1_imag;
665 : __SSE_DATATYPE tmp1, tmp2;
666 0 : int i=0;
667 :
668 : #ifdef DOUBLE_PRECISION_COMPLEX
669 0 : __SSE_DATATYPE sign = (__SSE_DATATYPE)_mm_set_epi64x(0x8000000000000000, 0x8000000000000000);
670 : #endif
671 : #ifdef SINGLE_PRECISION_COMPLEX
672 0 : __SSE_DATATYPE sign = (__SSE_DATATYPE)_mm_set_epi32(0x80000000, 0x80000000, 0x80000000, 0x80000000);
673 : #endif
674 0 : x1 = _SSE_LOAD(&q_dbl[0]);
675 : #ifdef DOUBLE_PRECISION_COMPLEX
676 0 : x2 = _SSE_LOAD(&q_dbl[offset]);
677 : #endif
678 0 : for (i = 1; i < nb; i++)
679 : {
680 : #ifdef DOUBLE_PRECISION_COMPLEX
681 0 : h1_real = _mm_loaddup_pd(&hh_dbl[i*2]);
682 0 : h1_imag = _mm_loaddup_pd(&hh_dbl[(i*2)+1]);
683 : #endif
684 : #ifdef SINGLE_PRECISION_COMPLEX
685 0 : h1_real = _mm_moveldup_ps(_mm_castpd_ps(_mm_loaddup_pd( (double *)(&hh_dbl[i*2]) )));
686 0 : h1_imag = _mm_moveldup_ps(_mm_castpd_ps(_mm_loaddup_pd( (double *)(&hh_dbl[(i*2)+1]) )));
687 : #endif
688 : #ifndef __ELPA_USE_FMA__
689 : // conjugate
690 0 : h1_imag = _SSE_XOR(h1_imag, sign);
691 : #endif
692 :
693 0 : q1 = _SSE_LOAD(&q_dbl[(2*i*ldq)+0]);
694 : #ifdef DOUBLE_PRECISION_COMPLEX
695 0 : q2 = _SSE_LOAD(&q_dbl[(2*i*ldq)+offset]);
696 : #endif
697 0 : tmp1 = _SSE_MUL(h1_imag, q1);
698 :
699 : #ifdef __ELPA_USE_FMA__
700 : x1 = _SSE_ADD(x1, _mm_msubadd_pd(h1_real, q1, _SSE_SHUFFLE(tmp1, tmp1, _SHUFFLE)));
701 : #else
702 0 : x1 = _SSE_ADD(x1, _SSE_ADDSUB( _SSE_MUL(h1_real, q1), _SSE_SHUFFLE(tmp1, tmp1, _SHUFFLE)));
703 : #endif
704 :
705 : #ifdef DOUBLE_PRECISION_COMPLEX
706 0 : tmp2 = _SSE_MUL(h1_imag, q2);
707 : #ifdef __ELPA_USE_FMA__
708 : x2 = _SSE_ADD(x2, _mm_msubadd_pd(h1_real, q2, _SSE_SHUFFLE(tmp2, tmp2, _SHUFFLE)));
709 : #else
710 0 : x2 = _SSE_ADD(x2, _SSE_ADDSUB( _SSE_MUL(h1_real, q2), _SSE_SHUFFLE(tmp2, tmp2, _SHUFFLE)));
711 : #endif
712 : #endif /* DOUBLE_PRECISION_COMPLEX */
713 : }
714 :
715 : #ifdef DOUBLE_PRECISION_COMPLEX
716 0 : h1_real = _mm_loaddup_pd(&hh_dbl[0]);
717 0 : h1_imag = _mm_loaddup_pd(&hh_dbl[1]);
718 : #endif
719 : #ifdef SINGLE_PRECISION_COMPLEX
720 0 : h1_real = _mm_moveldup_ps(_mm_castpd_ps(_mm_loaddup_pd( (double *)(&hh_dbl[0]) )));
721 0 : h1_imag = _mm_moveldup_ps(_mm_castpd_ps(_mm_loaddup_pd( (double *)(&hh_dbl[1]) )));
722 : #endif
723 0 : h1_real = _SSE_XOR(h1_real, sign);
724 0 : h1_imag = _SSE_XOR(h1_imag, sign);
725 :
726 0 : tmp1 = _SSE_MUL(h1_imag, x1);
727 :
728 : #ifdef __ELPA_USE_FMA__
729 : x1 = _SSE_MADDSUB(h1_real, x1, _SSE_SHUFFLE(tmp1, tmp1, _SHUFFLE));
730 : #else
731 0 : x1 = _SSE_ADDSUB( _SSE_MUL(h1_real, x1), _SSE_SHUFFLE(tmp1, tmp1, _SHUFFLE));
732 : #endif
733 :
734 : #ifdef DOUBLE_PRECISION_COMPLEX
735 0 : tmp2 = _SSE_MUL(h1_imag, x2);
736 : #ifdef __ELPA_USE_FMA__
737 : x2 = _SSE_MADDSUB(h1_real, x2, _SSE_SHUFFLE(tmp2, tmp2, _SHUFFLE));
738 : #else
739 0 : x2 = _SSE_ADDSUB( _SSE_MUL(h1_real, x2), _SSE_SHUFFLE(tmp2, tmp2, _SHUFFLE));
740 : #endif
741 : #endif /* DOUBLE_PRECISION_COMPLEX */
742 0 : q1 = _SSE_LOAD(&q_dbl[0]);
743 : #ifdef DOUBLE_PRECISION_COMPLEX
744 0 : q2 = _SSE_LOAD(&q_dbl[offset]);
745 : #endif
746 0 : q1 = _SSE_ADD(q1, x1);
747 : #ifdef DOUBLE_PRECISION_COMPLEX
748 0 : q2 = _SSE_ADD(q2, x2);
749 : #endif
750 : _SSE_STORE(&q_dbl[0], q1);
751 : #ifdef DOUBLE_PRECISION_COMPLEX
752 0 : _SSE_STORE(&q_dbl[offset], q2);
753 : #endif
754 0 : for (i = 1; i < nb; i++)
755 : {
756 : #ifdef DOUBLE_PRECISION_COMPLEX
757 0 : h1_real = _mm_loaddup_pd(&hh_dbl[i*2]);
758 0 : h1_imag = _mm_loaddup_pd(&hh_dbl[(i*2)+1]);
759 : #endif
760 : #ifdef SINGLE_PRECISION_COMPLEX
761 0 : h1_real = _mm_moveldup_ps(_mm_castpd_ps(_mm_loaddup_pd( (double *)(&hh_dbl[i*2]) )));
762 0 : h1_imag = _mm_moveldup_ps(_mm_castpd_ps(_mm_loaddup_pd( (double *)(&hh_dbl[(i*2)+1]) )));
763 : #endif
764 :
765 0 : q1 = _SSE_LOAD(&q_dbl[(2*i*ldq)+0]);
766 : #ifdef DOUBLE_PRECISION_COMPLEX
767 0 : q2 = _SSE_LOAD(&q_dbl[(2*i*ldq)+offset]);
768 : #endif
769 0 : tmp1 = _SSE_MUL(h1_imag, x1);
770 :
771 : #ifdef __ELPA_USE_FMA__
772 : q1 = _SSE_ADD(q1, _SSE_MADDSUB(h1_real, x1, _SSE_SHUFFLE(tmp1, tmp1, _SHUFFLE)));
773 : #else
774 0 : q1 = _SSE_ADD(q1, _SSE_ADDSUB( _SSE_MUL(h1_real, x1), _SSE_SHUFFLE(tmp1, tmp1, _SHUFFLE)));
775 : #endif
776 :
777 : #ifdef DOUBLE_PRECISION_COMPLEX
778 0 : tmp2 = _SSE_MUL(h1_imag, x2);
779 : #ifdef __ELPA_USE_FMA__
780 : q2 = _SSE_ADD(q2, _SSE_MADDSUB(h1_real, x2, _SSE_SHUFFLE(tmp2, tmp2, _SHUFFLE)));
781 : #else
782 0 : q2 = _SSE_ADD(q2, _SSE_ADDSUB( _SSE_MUL(h1_real, x2), _SSE_SHUFFLE(tmp2, tmp2, _SHUFFLE)));
783 : #endif
784 : #endif /* DOUBLE_PRECISION_COMPLEX */
785 0 : _SSE_STORE(&q_dbl[(2*i*ldq)+0], q1);
786 : #ifdef DOUBLE_PRECISION_COMPLEX
787 0 : _SSE_STORE(&q_dbl[(2*i*ldq)+offset], q2);
788 : #endif
789 : }
790 : }
|