QDP++
qdp_scalarsite_sse_vector.h
Go to the documentation of this file.
1// -*- C++ -*-
2// $Id: qdp_scalarsite_sse_vector.h,v 1.5 2007-08-20 17:08:14 uid4709 Exp $
3
11
12#ifndef QDP_SCALARSITE_SSE_VECTOR_H
13#define QDP_SCALARSITE_SSE_VECTOR_H
14
15#error "THIS IS UNUSED AT THE MOMENT"
16
17// These SSE asm instructions are only supported under GCC/G++
18#if defined(__GNUC__)
19
20#include "qdp_sse_intrin.h"
21
22namespace QDP {
23
30
31// Use this def just to safe some typing later on in the file
33typedef PDWVector<float,4> PDWVectorFloat4;
34typedef RComplex<PDWVectorFloat4> RComplexFloat4;
35
36//-------------------------------------------------------------------------
37// Start of PDWVector optimizations
38#if 0
39
40
41// Use this def just to safe some typing later on in the file
42//#define PVectorFloat PDWVector<float,4>
43//#define RComplexFloat RComplex<ILattice<float,4> >
44
45
46#if 0
47// NOTE: the operator+(v4sf,v4sf) first exists in gcc 3.3.X, not 3.2.X
48
49// v4sf + v4sf
50inline v4sf
51operator+(v4sf l, v4sf r)
52{
53 v4sf tmp = _mm_add_ps(l, r);
54 return tmp;
55}
56
57
58// v4sf - v4sf
59inline v4sf
60operator-(v4sf l, v4sf r)
61{
62 return _mm_sub_ps(l, r);
63}
64
65
66// v4sf * v4sf
67inline v4sf
68operator*(v4sf l, v4sf r)
69{
70 return _mm_mul_ps(l, r);
71}
72
73
74// v4sf / v4sf
75inline v4sf
76operator/(v4sf l, v4sf r)
77{
78 return _mm_div_ps(l, r);
79}
80#endif
81
82
83
84
85
86#if 1
88
91template<> class PDWVector<float,4> : public PVector<float, 4, PDWVector>
92{
93public:
94 typedef float T;
95 static const int N = 4;
96
97 PDWVector() {}
98 ~PDWVector() {}
99
100 //---------------------------------------------------------
102 PDWVector(const WordType<float>::Type_t& rhs)
103 {
104 for(int i=0; i < N; ++i)
105 elem(i) = rhs;
106 }
107
109 template<class T1>
110 PDWVector(const PDWVector<T1,N>& rhs)
111 {
112 for(int i=0; i < N; ++i)
113 elem(i) = rhs.elem(i);
114 }
115
117 template<class T1>
118 PDWVector(const T1& rhs)
119 {
120 for(int i=0; i < N; ++i)
121 elem(i) = rhs;
122 }
123
124
126 PDWVector(const v4sf& rhs)
127 {
128 F.v = rhs;
129 }
130
131
132 //---------------------------------------------------------
134
135 template<class T1>
136 inline
137 PDWVector& operator=(const PScalar<T1>& rhs)
138 {
139 for(int i=0; i < N; ++i)
140 elem(i) = rhs.elem();
141
142 return *this;
143 }
144
146 template<class T1>
147 inline
148 PDWVector& operator+=(const PScalar<T1>& rhs)
149 {
150 for(int i=0; i < N; ++i)
151 elem(i) += rhs.elem();
152
153 return *this;
154 }
155
157 template<class T1>
158 inline
159 PDWVector& operator-=(const PScalar<T1>& rhs)
160 {
161 for(int i=0; i < N; ++i)
162 elem(i) -= rhs.elem();
163
164 return *this;
165 }
166
168 template<class T1>
169 inline
170 PDWVector& operator*=(const PScalar<T1>& rhs)
171 {
172 for(int i=0; i < N; ++i)
173 elem(i) *= rhs.elem();
174
175 return *this;
176 }
177
179 template<class T1>
180 inline
181 PDWVector& operator/=(const PScalar<T1>& rhs)
182 {
183 for(int i=0; i < N; ++i)
184 elem(i) /= rhs.elem();
185
186 return *this;
187 }
188
189
190 //---------------------------------------------------------
192
193 inline
194 PDWVector& operator=(const PDWVector& rhs)
195 {
196 F.v = rhs.F.v;
197 return *this;
198 }
199
201 inline
202 PDWVector& operator+=(const PDWVector& rhs)
203 {
204 F.v = _mm_add_ps(F.v, rhs.F.v);
205 return *this;
206 }
207
209 inline
210 PDWVector& operator-=(const PDWVector& rhs)
211 {
212 F.v = _mm_sub_ps(F.v, rhs.F.v);
213 return *this;
214 }
215
217 inline
218 PDWVector& operator*=(const PDWVector& rhs)
219 {
220 F.v = _mm_mul_ps(F.v, rhs.F.v);
221 return *this;
222 }
223
225 inline
226 PDWVector& operator/=(const PDWVector& rhs)
227 {
228 F.v = _mm_div_ps(F.v, rhs.F.v);
229 return *this;
230 }
231
232
234 PDWVector(const PDWVector& a)
235 {
236 // fprintf(stderr,"copy PDWVector\n");
237 F.v = a.F.v;
238 }
239
240
241public:
243
247 inline T* data() {return F.a;}
248
249
250public:
251 T& elem(int i) {return F.a[i];}
252 const T& elem(int i) const {return F.a[i];}
253
254 v4sf& elem_v() {return F.v;}
255 const v4sf elem_v() const {return F.v;}
256
257private:
258 // SSE attributes
259 union {
260 v4sf v;
261 T a[4];
262 } F QDP_ALIGN16;
263
264};
265#endif
266
267
268
269
270//--------------------------------------------------------------------------------------
271// Optimized version of
272// PDWVectorFloat4 <- PDWVectorFloat4 + PDWVectorFloat4
273//template<>
274inline PDWVectorFloat4
275operator+(const PDWVectorFloat4& l, const PDWVectorFloat4& r)
276{
277#if defined(QDP_SCALARSITE_DEBUG)
278 cout << "DWV+DWV" << endl;
279#endif
280
281 return _mm_add_ps(l.elem_v(), r.elem_v());
282}
283
284
285// Optimized version of
286// PDWVectorFloat4 <- PDWVectorFloat4 - PDWVectorFloat4
287//template<>
288inline PDWVectorFloat4
289operator-(const PDWVectorFloat4& l, const PDWVectorFloat4& r)
290{
291#if defined(QDP_SCALARSITE_DEBUG)
292 cout << "DWV-DWV" << endl;
293#endif
294
295 return _mm_sub_ps(l.elem_v(), r.elem_v());
296}
297
298
299// Optimized version of
300// PDWVectorFloat4 <- PDWVectorFloat4 * PDWVectorFloat4
301//template<>
302inline PDWVectorFloat4
303operator*(const PDWVectorFloat4& l, const PDWVectorFloat4& r)
304{
305#if defined(QDP_SCALARSITE_DEBUG)
306 cout << "DWV * DWV" << endl;
307#endif
308
309 return _mm_mul_ps(l.elem_v(), r.elem_v());
310}
311
312// Optimized version of
313// PDWVectorFloat4 <- PScalar * PDWVectorFloat4
314inline PDWVectorFloat4
315operator*(const PScalar<float>& l, const PDWVectorFloat4& r)
316{
317#if defined(QDP_SCALARSITE_DEBUG)
318 cout << "P * DWV" << endl;
319#endif
320
321 v4sf x = _mm_load_ss((float*)&(l.elem()));
322 x = _mm_shuffle_ps(x,x,0);
323
324 return _mm_mul_ps(x, r.elem_v());
325}
326
327// Optimized version of
328// PDWVectorFloat4 <- PDWVectorFloat4 * PScalar
329inline PDWVectorFloat4
330operator*(const PDWVectorFloat4& l, const PScalar<float>& r)
331{
332#if defined(QDP_SCALARSITE_DEBUG)
333 cout << "DWV * P" << endl;
334#endif
335
336 v4sf x = _mm_load_ss((float*)&(r.elem()));
337
338 x = _mm_shuffle_ps(x,x,0);
339 return _mm_mul_ps(l.elem_v(), x);
340}
341
342
343
344// Optimized version of
345// PDWVectorFloat4 <- PDWVectorFloat4 / PDWVectorFloat4
346//template<>
347inline PDWVectorFloat4
348operator/(const PDWVectorFloat4& l, const PDWVectorFloat4& r)
349{
350#if defined(QDP_SCALARSITE_DEBUG)
351 cout << "DWV / DWV" << endl;
352#endif
353
354 return _mm_mul_ps(l.elem_v(), r.elem_v());
355}
356
357
358//--------------------------------------------------------------------------------------
359// Optimized version of
360// RComplexFloat4 <- RComplexFloat4 + RComplexFloat4
361template<>
362inline RComplexFloat4
363operator+(const RComplexFloat4& l, const RComplexFloat4& r)
364{
365#if defined(QDP_SCALARSITE_DEBUG)
366 cout << "C<DWV> + C<DWV>" << endl;
367#endif
368
369 return RComplexFloat4(_mm_add_ps(l.real().elem_v(), r.real().elem_v()),
370 _mm_add_ps(l.imag().elem_v(), r.imag().elem_v()));
371}
372
373
374// Optimized version of
375// RComplexFloat4 <- RComplexFloat4 - RComplexFloat4
376template<>
377inline RComplexFloat4
378operator-(const RComplexFloat4& l, const RComplexFloat4& r)
379{
380#if defined(QDP_SCALARSITE_DEBUG)
381 cout << "C<DWV> - C<DWV" << endl;
382#endif
383
384 return RComplexFloat4(_mm_sub_ps(l.real().elem_v(), r.real().elem_v()),
385 _mm_sub_ps(l.imag().elem_v(), r.imag().elem_v()));
386}
387
388
389// Optimized version of
390// RComplexFloat4 <- RComplexFloat4 * RComplexFloat4
391template<>
392inline RComplexFloat4
393operator*(const RComplexFloat4& l, const RComplexFloat4& r)
394{
395 RComplexFloat4 d;
396
397#if defined(QDP_SCALARSITE_DEBUG)
398 cout << "C<DWV> * C<DWV>" << endl;
399#endif
400
401 v4sf tmp1 = _mm_mul_ps(l.real().elem_v(), r.real().elem_v());
402 v4sf tmp2 = _mm_mul_ps(l.imag().elem_v(), r.imag().elem_v());
403 d.real().elem_v() = _mm_sub_ps(tmp1, tmp2);
404
405 v4sf tmp3 = _mm_mul_ps(l.real().elem_v(), r.imag().elem_v());
406 v4sf tmp4 = _mm_mul_ps(l.imag().elem_v(), r.real().elem_v());
407 d.imag().elem_v() = _mm_add_ps(tmp3, tmp4);
408
409 return d;
410}
411
412// Optimized version of
413// RComplexFloat4 <- adj(RComplexFloat4) * RComplexFloat4
414template<>
416adjMultiply(const RComplexFloat4& l, const RComplexFloat4& r)
417{
418#if defined(QDP_SCALARSITE_DEBUG)
419 cout << "adj(C<DWV>) * C<DWV>" << endl;
420#endif
421
423
424 v4sf tmp1 = _mm_mul_ps(l.real().elem_v(), r.real().elem_v());
425 v4sf tmp2 = _mm_mul_ps(l.imag().elem_v(), r.imag().elem_v());
426 d.real().elem_v() = _mm_add_ps(tmp1, tmp2);
427
428 v4sf tmp3 = _mm_mul_ps(l.real().elem_v(), r.imag().elem_v());
429 v4sf tmp4 = _mm_mul_ps(l.imag().elem_v(), r.real().elem_v());
430 d.imag().elem_v() = _mm_sub_ps(tmp3, tmp4);
431
432 return d;
433}
434
435// Optimized RComplex*adj(RComplex)
436template<>
438multiplyAdj(const RComplexFloat4& l, const RComplexFloat4& r)
439{
441
442 v4sf tmp1 = _mm_mul_ps(l.real().elem_v(), r.real().elem_v());
443 v4sf tmp2 = _mm_mul_ps(l.imag().elem_v(), r.imag().elem_v());
444 d.real().elem_v() = _mm_add_ps(tmp1, tmp2);
445
446 v4sf tmp3 = _mm_mul_ps(l.imag().elem_v(), r.real().elem_v());
447 v4sf tmp4 = _mm_mul_ps(l.real().elem_v(), r.imag().elem_v());
448 d.imag().elem_v() = _mm_sub_ps(tmp3, tmp4);
449
450 return d;
451}
452
453// Optimized adj(RComplex)*adj(RComplex)
454template<>
456adjMultiplyAdj(const RComplexFloat4& l, const RComplexFloat4& r)
457{
459
460 typedef struct
461 {
462 unsigned int c[4];
463 } sse_mask __attribute__ ((aligned (16)));
464
465 static sse_mask _sse_sgn __attribute__ ((unused)) ={0x80000000, 0x80000000, 0x80000000, 0x80000000};
466
467 v4sf tmp1 = _mm_mul_ps(l.real().elem_v(), r.real().elem_v());
468 v4sf tmp2 = _mm_mul_ps(l.imag().elem_v(), r.imag().elem_v());
469 d.real().elem_v() = _mm_sub_ps(tmp1, tmp2);
470
471 v4sf tmp3 = _mm_mul_ps(l.real().elem_v(), r.imag().elem_v());
472 v4sf tmp4 = _mm_mul_ps(l.imag().elem_v(), r.real().elem_v());
473 v4sf tmp5 = _mm_add_ps(tmp3, tmp4);
474// d.imag().elem_v() = _mm_xor_ps(tmp5, _sse_sgn.v);
475 v4sf tmp6 = _mm_load_ps((float*)&_sse_sgn);
476 d.imag().elem_v() = _mm_xor_ps(tmp5, tmp6);
477
478 return d;
479}
480
481#endif
482
483 // end of group optimizations
485
486#if defined(QDP_SCALARSITE_DEBUG)
487#undef QDP_SCALARSITE_DEBUG
488#endif
489
490} // namespace QDP;
491
492#endif // defined(__GNUC__)
493
494#endif
Primitive Scalar.
Primitive Vector class.
Reality complex.
BinaryReturn< IScalar< T1 >, IScalar< T2 >, OpAdjMultiplyAdj >::Type_t adjMultiplyAdj(const IScalar< T1 > &l, const IScalar< T2 > &r)
Definition qdp_inner.h:1198
BinaryReturn< IScalar< T1 >, IScalar< T2 >, OpMultiplyAdj >::Type_t multiplyAdj(const IScalar< T1 > &l, const IScalar< T2 > &r)
Definition qdp_inner.h:1189
BinaryReturn< IScalar< T1 >, IScalar< T2 >, OpAdjMultiply >::Type_t adjMultiply(const IScalar< T1 > &l, const IScalar< T2 > &r)
Definition qdp_inner.h:1180
RComplex< BAGELQDPFloat > RComplexFloat
StandardOutputStream cout
Definition qdp_stdio.cc:21
Yet another random number generator.
MakeReturn< BinaryNode< OpMultiply, typenameCreateLeaf< QDPType< T1, C1 > >::Leaf_t, typenameCreateLeaf< QDPExpr< T2, C2 > >::Leaf_t >, typenameBinaryReturn< C1, C2, OpMultiply >::Type_t >::Expression_t operator*(const QDPType< T1, C1 > &l, const QDPExpr< T2, C2 > &r)
Definition qdp.h:2588
MakeReturn< BinaryNode< OpAdd, typenameCreateLeaf< QDPType< T1, C1 > >::Leaf_t, typenameCreateLeaf< QDPExpr< T2, C2 > >::Leaf_t >, typenameBinaryReturn< C1, C2, OpAdd >::Type_t >::Expression_t operator+(const QDPType< T1, C1 > &l, const QDPExpr< T2, C2 > &r)
Definition qdp.h:2556
MakeReturn< BinaryNode< OpSubtract, typenameCreateLeaf< QDPType< T1, C1 > >::Leaf_t, typenameCreateLeaf< QDPExpr< T2, C2 > >::Leaf_t >, typenameBinaryReturn< C1, C2, OpSubtract >::Type_t >::Expression_t operator-(const QDPType< T1, C1 > &l, const QDPExpr< T2, C2 > &r)
Definition qdp.h:2572
MakeReturn< BinaryNode< OpDivide, typenameCreateLeaf< QDPType< T1, C1 > >::Leaf_t, typenameCreateLeaf< QDPExpr< T2, C2 > >::Leaf_t >, typenameBinaryReturn< C1, C2, OpDivide >::Type_t >::Expression_t operator/(const QDPType< T1, C1 > &l, const QDPExpr< T2, C2 > &r)
Definition qdp.h:2604
#define QDP_ALIGN16
Definition qdp.h:61
Promote< T1, T2 >::Type_t Type_t
Definition qdp.h:377