QDP++
qdp_scalarvecsite_sse_linalg.h
Go to the documentation of this file.
1// -*- C++ -*-
2// $Id: qdp_scalarvecsite_sse_linalg.h,v 1.8 2007-06-10 14:32:11 edwards Exp $
3
9
10#ifndef QDP_SCALARVECSITE_SSE_LINALG_H
11#define QDP_SCALARVECSITE_SSE_LINALG_H
12
13// These SSE asm instructions are only supported under GCC/G++ 3.2 or greater
14#if defined(__GNUC__) && __GNUC_MINOR__ >= 2
15
16#include "qdp_sse_intrin.h"
17
18namespace QDP {
19
20// #define QDP_SCALARVECSITE_DEBUG
21
22#define QDP_SCALARVECSITE_USE_EVALUATE
23
24
25
32
33// Use this def just to safe some typing later on in the file
34typedef IScalar<REAL32> IScalarFloat;
35typedef ILattice<REAL32,4> ILatticeFloat;
37
39
40//--------------------------------------------------------------------------------------
41// Optimized version of
42// ILatticeFloat <- ILatticeFloat + ILatticeFloat
43template<>
45operator+(const ILatticeFloat& l, const ILatticeFloat& r)
46{
48
49// cout << "I+I" << endl;
50 return Ret_t(_mm_add_ps(l.elem_v(), r.elem_v()));
51}
52
53// ILatticeFloat <- ILatticeFloat + IScalarFloat
54template<>
56operator+(const ILatticeFloat& l, const IScalarFloat& r)
57{
59
60// cout << "I+I" << endl;
61 return Ret_t(_mm_add_ps(l.elem_v(), vmk1(r.elem())));
62}
63
64// ILatticeFloat <- IScalarFloat + ILatticeFloat
65template<>
67operator+(const IScalarFloat& l, const ILatticeFloat& r)
68{
70
71// cout << "I+I" << endl;
72 return Ret_t(_mm_add_ps(vmk1(l.elem()), r.elem_v()));
73}
74
75
76// Optimized version of
77// ILatticeFloat <- ILatticeFloat - ILatticeFloat
78template<>
80operator-(const ILatticeFloat& l, const ILatticeFloat& r)
81{
83
84// cout << "I-I" << endl;
85 return Ret_t(_mm_sub_ps(l.elem_v(), r.elem_v()));
86}
87
88// ILatticeFloat <- ILatticeFloat - IScalarFloat
89template<>
91operator-(const ILatticeFloat& l, const IScalarFloat& r)
92{
94
95// cout << "I-I" << endl;
96 return Ret_t(_mm_sub_ps(l.elem_v(), vmk1(r.elem())));
97}
98
99// ILatticeFloat <- IScalarFloat - ILatticeFloat
100template<>
102operator-(const IScalarFloat& l, const ILatticeFloat& r)
103{
105
106// cout << "I-I" << endl;
107 return Ret_t(_mm_sub_ps(vmk1(l.elem()), r.elem_v()));
108}
109
110
111// Optimized version of
112// ILatticeFloat <- ILatticeFloat * ILatticeFloat
113template<>
115operator*(const ILatticeFloat& l, const ILatticeFloat& r)
116{
118
119// cout << "I*I" << endl;
120 return Ret_t(_mm_mul_ps(l.elem_v(), r.elem_v()));
121}
122
123// ILatticeFloat <- ILatticeFloat * IScalarFloat
124template<>
126operator*(const ILatticeFloat& l, const IScalarFloat& r)
127{
129
130// cout << "I*I" << endl;
131 return Ret_t(_mm_mul_ps(l.elem_v(), vmk1(r.elem())));
132}
133
134// ILatticeFloat <- IScalarFloat * ILatticeFloat
135template<>
137operator*(const IScalarFloat& l, const ILatticeFloat& r)
138{
140
141// cout << "I*I" << endl;
142 return Ret_t(_mm_mul_ps(vmk1(l.elem()), r.elem_v()));
143}
144
145
146// Optimized version of
147// ILatticeFloat <- ILatticeFloat / ILatticeFloat
148template<>
150operator/(const ILatticeFloat& l, const ILatticeFloat& r)
151{
153
154// cout << "I/I" << endl;
155 return Ret_t(_mm_div_ps(l.elem_v(), r.elem_v()));
156}
157
158// ILatticeFloat <- ILatticeFloat / IScalarFloat
159template<>
161operator/(const ILatticeFloat& l, const IScalarFloat& r)
162{
164
165// cout << "I/I" << endl;
166 return Ret_t(_mm_div_ps(l.elem_v(), vmk1(r.elem())));
167}
168
169// ILatticeFloat <- IScalarFloat / ILatticeFloat
170template<>
172operator/(const IScalarFloat& l, const ILatticeFloat& r)
173{
175
176// cout << "I/I" << endl;
177 return Ret_t(_mm_div_ps(vmk1(l.elem()), r.elem_v()));
178}
179
180
181
182//--------------------------------------------------------------------------------------
183// Optimized version of
184// RComplexFloat <- RComplexFloat + RComplexFloat
185template<>
187operator+(const RComplexFloat& l, const RComplexFloat& r)
188{
190
191// cout << "C+C" << endl;
192 return Ret_t(_mm_add_ps(l.real().elem_v(), r.real().elem_v()),
193 _mm_add_ps(l.imag().elem_v(), r.imag().elem_v()));
194}
195
196
197// Optimized version of
198// RComplexFloat <- RComplexFloat - RComplexFloat
199template<>
201operator-(const RComplexFloat& l, const RComplexFloat& r)
202{
204
205// cout << "C-C" << endl;
206 return Ret_t(_mm_sub_ps(l.real().elem_v(), r.real().elem_v()),
207 _mm_sub_ps(l.imag().elem_v(), r.imag().elem_v()));
208}
209
210
211// Optimized version of
212// RComplexFloat <- RComplexFloat * RComplexFloat
213template<>
215operator*(const RComplexFloat& l, const RComplexFloat& r)
216{
218
219// cout << "C*C" << endl;
220 return Ret_t(_mm_sub_ps(_mm_mul_ps(l.real().elem_v(), r.real().elem_v()),
221 _mm_mul_ps(l.imag().elem_v(), r.imag().elem_v())),
222 _mm_add_ps(_mm_mul_ps(l.real().elem_v(), r.imag().elem_v()),
223 _mm_mul_ps(l.imag().elem_v(), r.real().elem_v())));
224}
225
226// Optimized version of
227// RComplexFloat <- adj(RComplexFloat) * RComplexFloat
228template<>
230adjMultiply(const RComplexFloat& l, const RComplexFloat& r)
231{
233
234// cout << "adj(C)*C" << endl;
235 return Ret_t(_mm_add_ps(_mm_mul_ps(l.real().elem_v(), r.real().elem_v()),
236 _mm_mul_ps(l.imag().elem_v(), r.imag().elem_v())),
237 _mm_sub_ps(_mm_mul_ps(l.real().elem_v(), r.imag().elem_v()),
238 _mm_mul_ps(l.imag().elem_v(), r.real().elem_v())));
239}
240
241// Optimized RComplex*adj(RComplex)
242template<>
244multiplyAdj(const RComplexFloat& l, const RComplexFloat& r)
245{
247
248// cout << "C*adj(C)" << endl;
249 return Ret_t(_mm_add_ps(_mm_mul_ps(l.real().elem_v(), r.real().elem_v()),
250 _mm_mul_ps(l.imag().elem_v(), r.imag().elem_v())),
251 _mm_sub_ps(_mm_mul_ps(l.imag().elem_v(), r.real().elem_v()),
252 _mm_mul_ps(l.real().elem_v(), r.imag().elem_v())));
253}
254
255// Optimized adj(RComplex)*adj(RComplex)
256template<>
259{
261 REAL32 zero = 0.0;
262
263// cout << "adj(C)*adj(C)" << endl;
264 return Ret_t(_mm_sub_ps(_mm_mul_ps(l.real().elem_v(), r.real().elem_v()),
265 _mm_mul_ps(l.imag().elem_v(), r.imag().elem_v())),
266 _mm_sub_ps(vmk1(zero),
267 _mm_add_ps(_mm_mul_ps(l.real().elem_v(), r.imag().elem_v()),
268 _mm_mul_ps(l.imag().elem_v(), r.real().elem_v()))));
269}
270
271
272//--------------------------------------------------------------------------------------
273
274
275// Optimized version of
276// PColorMatrix<RComplexFloat,3> <- PColorMatrix<RComplexFloat,3> * PColorMatrix<RComplexFloat,3>
277template<>
282{
283// cout << "M*M" << endl;
284
287
288 REAL32 *dd = (REAL32*)&d;
289 REAL32 *ll = (REAL32*)&l;
290 REAL32 *rr = (REAL32*)&r;
291
292 _inline_ssevec_mult_su3_nn(dd,ll,rr,0);
293 _inline_ssevec_mult_su3_nn(dd,ll,rr,1);
294 _inline_ssevec_mult_su3_nn(dd,ll,rr,2);
295
296 return d;
297}
298
299
300
301#if defined(QDP_SCALARVECSITE_USE_EVALUATE)
302// Specialization to optimize the case
303// LatticeColorMatrix = LatticeColorMatrix * LatticeColorMatrix
304// NOTE: let this be a subroutine to save space
305template<>
307 const OpAssign& op,
314 const Subset& s);
315#endif
316
317
318 // end of group optimizations
320
321#if defined(QDP_SCALARVECSITE_DEBUG)
322#undef QDP_SCALARVECSITE_DEBUG
323#endif
324
325#if defined(QDP_SCALARVECSITE_USE_EVALUATE)
326#undef QDP_SCALARVECSITE_USE_EVALUATE
327#endif
328
329
330} // namespace QDP;
331
332#endif // defined(__GNUC__)
333
334#endif
Scalar inner lattice.
Definition qdp_inner.h:25
Outer grid Lattice type.
Definition qdp_outer.h:264
Primitive color Matrix class.
Primitive Matrix class.
Primitive Scalar.
Expression class for QDP.
Definition qdp_qdpexpr.h:16
QDPType - major type class/container for all QDP objects.
Definition qdp_qdptype.h:29
Reality complex.
Subsets - controls how lattices are looped.
Definition qdp_subset.h:39
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
void evaluate(OLattice< DCol > &d, const OpAssign &op, const QDPExpr< BinaryNode< OpMultiply, Reference< QDPType< DCol, OLattice< DCol > > >, Reference< QDPType< DCol, OLattice< DCol > > > >, OLattice< DCol > > &rhs, const Subset &s)
RComplex< BAGELQDPFloat > RComplexFloat
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 _inline_ssevec_mult_su3_nn(cc, aa, bb, j)
Promote< T1, T2 >::Type_t Type_t
Definition qdp.h:377