FairRoot/PandaRoot
P4_F32vec4.h
Go to the documentation of this file.
1 #ifndef L1Algo_F32vec4P4_H
2 #define L1Algo_F32vec4P4_H
3 
4 #include <iostream>
5 #include <cmath>
6 #include "xmmintrin.h"
7 #include "vec_arithmetic.h"
8 
9 /**********************************
10  *
11  * Vector of four single floats
12  *
13  **********************************/
14 
15 //#pragma pack(push,16)/* Must ensure class & union 16-B aligned */
16 
17 //typedef __m128 VectorFloat __attribute__ ((aligned(16)));
18 
19 const union
20 {
21  float f;
22  unsigned int i;
23 } __f_one = {1.f};
24 
25 const union
26 {
27  unsigned int i[4];
28  __m128 m;
29 }
30  __f32vec4_abs_mask_cheat = {{0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff}},
31  __f32vec4_sgn_mask_cheat = {{0x80000000, 0x80000000, 0x80000000, 0x80000000}},
32  __f32vec4_zero_cheat = {{ 0, 0, 0, 0}},
33  __f32vec4_one_cheat = {{__f_one.i , __f_one.i , __f_one.i , __f_one.i }},
34  __f32vec4_true_cheat = {{0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}},
35  __f32vec4_false_cheat = {{0x00000000, 0x00000000, 0x00000000, 0x00000000}};
36 
37 #define _f32vec4_abs_mask (static_cast<F32vec4>(__f32vec4_abs_mask_cheat.m))
38 #define _f32vec4_sgn_mask (static_cast<F32vec4>(__f32vec4_sgn_mask_cheat.m))
39 #define _f32vec4_zero (static_cast<F32vec4>(__f32vec4_zero_cheat.m))
40 #define _f32vec4_one (static_cast<F32vec4>(__f32vec4_one_cheat.m))
41 #define _f32vec4_true (static_cast<F32vec4>(__f32vec4_true_cheat.m))
42 #define _f32vec4_false (static_cast<F32vec4>(__f32vec4_false_cheat.m))
43 
44 class F32vec4
45 {
46  public:
47 
48  __m128 v;
49 
50  float & operator[]( int i ){ return (reinterpret_cast<float*>(&v))[i]; }
51  float operator[]( int i ) const { return (reinterpret_cast<const float*>(&v))[i]; }
52 
53  F32vec4( ):v(_mm_set_ps1(0)){}
54  F32vec4( const __m128 &a ):v(a) {}
55  F32vec4( const float &a ):v(_mm_set_ps1(a)) {}
56 
57  F32vec4( const float &f0, const float &f1, const float &f2, const float &f3 ):v(_mm_set_ps(f3,f2,f1,f0)) {}
58 
59  /* Conversion function */
60  operator __m128() const { return v; } /* Convert to __m128 */
61 
62  /* Arithmetic Operators */
63  friend F32vec4 operator +(const F32vec4 &a, const F32vec4 &b) { return _mm_add_ps(a,b); }
64  friend F32vec4 operator -(const F32vec4 &a, const F32vec4 &b) { return _mm_sub_ps(a,b); }
65  friend F32vec4 operator *(const F32vec4 &a, const F32vec4 &b) { return _mm_mul_ps(a,b); }
66  friend F32vec4 operator /(const F32vec4 &a, const F32vec4 &b) { return _mm_div_ps(a,b); }
67 
68  /* Functions */
69  friend F32vec4 min( const F32vec4 &a, const F32vec4 &b ){ return _mm_min_ps(a, b); }
70  friend F32vec4 max( const F32vec4 &a, const F32vec4 &b ){ return _mm_max_ps(a, b); }
71 
72  /* Square Root */
73  friend F32vec4 sqrt ( const F32vec4 &a ){ return _mm_sqrt_ps (a); }
74 
75  /* Reciprocal( inverse) Square Root */
76  friend F32vec4 rsqrt( const F32vec4 &a ){ return _mm_rsqrt_ps(a); }
77 
78  /* Reciprocal (inversion) */
79  // friend F32vec4 rcp ( const F32vec4 &a ){ return _mm_rcp_ps (a); }
80  /* Reciprocal (inversion) */
81  //friend F32vec4 rcp ( const F32vec4 &a ){ return 1. / a; }
82  /* NewtonRaphson Reciprocal
83  [2 * rcpps(x) - (x * rcpps(x) * rcpps(x))] */
84  friend F32vec4 rcp(const F32vec4 &a) {
85  F32vec4 Ra0 = _mm_rcp_ps(a);
86  return _mm_sub_ps(_mm_add_ps(Ra0, Ra0), _mm_mul_ps(_mm_mul_ps(Ra0, a), Ra0));
87  }
88 
89 
90  /* Absolute value */
91  friend F32vec4 fabs(const F32vec4 &a){ return _mm_and_ps(a, _f32vec4_abs_mask); }
92 
93  /* Sign */
94  friend F32vec4 sgn(const F32vec4 &a){ return _mm_or_ps(_mm_and_ps(a, _f32vec4_sgn_mask),_f32vec4_one); }
95  friend F32vec4 asgnb(const F32vec4 &a, const F32vec4 &b ){
96  return _mm_or_ps(_mm_and_ps(b, _f32vec4_sgn_mask),a);
97  }
98 
99  /* Logical */
100 
101  friend F32vec4 operator&( const F32vec4 &a, const F32vec4 &b ){ // mask returned
102  return _mm_and_ps(a, b);
103  }
104  friend F32vec4 operator|( const F32vec4 &a, const F32vec4 &b ){ // mask returned
105  return _mm_or_ps(a, b);
106  }
107  friend F32vec4 operator^( const F32vec4 &a, const F32vec4 &b ){ // mask returned
108  return _mm_xor_ps(a, b);
109  }
110  friend F32vec4 operator!( const F32vec4 &a ){ // mask returned
111  return _mm_xor_ps(a, _f32vec4_true);
112  }
113  // friend F32vec4 operator||( const F32vec4 &a, const F32vec4 &b ){ // mask returned
114  // return _mm_or_ps(a, b);
115  // }
116 
117  /* Comparison */
118 
119  friend F32vec4 operator<( const F32vec4 &a, const F32vec4 &b ){ // mask returned
120  return _mm_cmplt_ps(a, b);
121  }
122  friend F32vec4 operator<=( const F32vec4 &a, const F32vec4 &b ){ // mask returned
123  return _mm_cmple_ps(a, b);
124  }
125  friend F32vec4 operator>( const F32vec4 &a, const F32vec4 &b ){ // mask returned
126  return _mm_cmpgt_ps(a, b);
127  }
128  friend F32vec4 operator>=( const F32vec4 &a, const F32vec4 &b ){ // mask returned
129  return _mm_cmpge_ps(a, b);
130  }
131  friend F32vec4 operator==( const F32vec4 &a, const F32vec4 &b ){ // mask returned
132  return _mm_cmpeq_ps(a, b);
133  }
134 
135  #define if3(a, b, c) ((a)&(b)) | ((!(a))&(c)) // analog (a) ? b : c
136 
137  #define NotEmpty(a) bool((a)[0])|bool((a)[1])|bool((a)[2])|bool((a)[3])
138  #define Empty(a) !(bool((a)[0])|bool((a)[1])|bool((a)[2])|bool((a)[3]))
139  // bool NotEmpty(const F32vec4 &a) { return a[0]||a[1]||a[2]||a[3]; }
140  // bool Empty(const F32vec4 &a) { return !(a[0]||a[1]||a[2]||a[3]); } // optimize
141  friend F32vec4 bool2int( const F32vec4 &a){ // mask returned
142  return if3(a,1,0);
143  }
144 
145  /* Define all operators for consistensy */
146 
147  vec_arithmetic(F32vec4,float);
148 
149  /* Non intrinsic functions */
150 
151 #define _f1(A,F) F32vec4( F(A[0]), F(A[1]), F(A[2]), F(A[3]) )
152 
153  friend F32vec4 exp( const F32vec4 &a ){ return _f1( a, exp ); }
154  friend F32vec4 log( const F32vec4 &a ){ return _f1( a, log ); }
155  friend F32vec4 sin( const F32vec4 &a ){ return _f1( a, sin ); }
156  friend F32vec4 cos( const F32vec4 &a ){ return _f1( a, cos ); }
157  friend F32vec4 acos( const F32vec4 &a ){ return _f1( a, acos ); }
158 
159 #undef _f1
160 
161  friend F32vec4 atan2(const F32vec4 &y, const F32vec4 &x) {
162  const F32vec4 pi(3.1415926535897932);
163  const F32vec4 pi_2 = pi/2;
164  const F32vec4 zero(0);
165 
166  const F32vec4 &xZero = F32vec4(x == zero);
167  const F32vec4 &yZero = F32vec4(y == zero);
168  const F32vec4 &xNeg = F32vec4(x < zero);
169  const F32vec4 &yNeg = F32vec4(y < zero);
170 
171  const F32vec4 &absX = fabs(x);
172  const F32vec4 &absY = fabs(y);
173 
174  F32vec4 a = absY / absX;
175  const F32vec4 pi_4 = pi/4;
176  const F32vec4 &gt_tan_3pi_8 = F32vec4(a > F32vec4(2.414213562373095));
177  const F32vec4 &gt_tan_pi_8 = F32vec4(a > F32vec4(0.4142135623730950)) & F32vec4(!gt_tan_3pi_8);
178  const F32vec4 minusOne(-1);
179  F32vec4 b(zero);
180  b = (pi_2 & gt_tan_3pi_8) + (F32vec4(!gt_tan_3pi_8) & b);
181  b = (pi_4 & gt_tan_pi_8) + (F32vec4(!gt_tan_pi_8) & b);
182  a = (gt_tan_3pi_8 & (minusOne / a)) + (F32vec4(!gt_tan_3pi_8) & a);
183  a = (gt_tan_pi_8 & ((absY - absX) / (absY + absX))) + (F32vec4(!gt_tan_pi_8) & a) ;
184  const F32vec4 &a2 = a * a;
185  b += (((8.05374449538e-2 * a2
186  - 1.38776856032E-1) * a2
187  + 1.99777106478E-1) * a2
188  - 3.33329491539E-1) * a2 * a
189  + a;
190  F32vec4 xyNeg = F32vec4(xNeg ^ yNeg);
191  b = (xyNeg & (-b) ) + (F32vec4(!xyNeg) & b);
192  xyNeg = F32vec4(xNeg & !yNeg);
193  b = (xyNeg & (b+pi)) + (F32vec4(!xyNeg) & b);
194  xyNeg = F32vec4(xNeg & yNeg);
195  b = (xyNeg & (b-pi)) + (F32vec4(!xyNeg) & b);
196  xyNeg = F32vec4(xZero & yZero);
197  b = (xyNeg & zero) + (F32vec4(!xyNeg) & b);
198  xyNeg = F32vec4(xZero & yNeg);
199  b = (xyNeg & (-pi_2)) + (F32vec4(!xyNeg) & b);
200  return b;
201  }
202 
203  friend std::ostream & operator<<(std::ostream &strm, const F32vec4 &a ){
204  strm<<"["<<a[0]<<" "<<a[1]<<" "<<a[2]<<" "<<a[3]<<"]";
205  return strm;
206  }
207 
209  float tmp;
210  strm>>tmp;
211  a = tmp;
212  return strm;
213  }
214 
215 } __attribute__ ((aligned(16)));
216 
217 
218 typedef F32vec4 fvec;
219 typedef float fscal;
220 const int fvecLen = 4;
221 //#define fvec_true _f32vec4_true
222 //#define fvec_false _f32vec4_false
223 #define _fvecalignment __attribute__ ((aligned(16)))
224 
225 
226 #include "std_alloc.h"
227 
228 
229 #endif
const union @50 __f32vec4_one_cheat
friend F32vec4 operator!(const F32vec4 &a)
Definition: P4_F32vec4.h:110
friend F32vec4 log(const F32vec4 &a)
Definition: P4_F32vec4.h:154
friend F32vec4 operator==(const F32vec4 &a, const F32vec4 &b)
Definition: P4_F32vec4.h:131
__m128 m
Definition: P4_F32vec4.h:28
TTree * b
F32vec4(const float &a)
Definition: P4_F32vec4.h:55
TF1 * f1
Definition: reco_analys2.C:50
friend F32vec4 max(const F32vec4 &a, const F32vec4 &b)
Definition: P4_F32vec4.h:70
#define _f32vec4_one
Definition: P4_F32vec4.h:40
friend F32vec4 rsqrt(const F32vec4 &a)
Definition: P4_F32vec4.h:76
const union @50 __f32vec4_false_cheat
#define pi
Definition: createSTT.C:60
friend F32vec4 operator&(const F32vec4 &a, const F32vec4 &b)
Definition: P4_F32vec4.h:101
friend F32vec4 acos(const F32vec4 &a)
Definition: P4_F32vec4.h:157
friend std::ostream & operator<<(std::ostream &strm, const F32vec4 &a)
Definition: P4_F32vec4.h:203
#define _f1(A, F)
Definition: P4_F32vec4.h:107
unsigned int i
Definition: P4_F32vec4.h:22
vec_arithmetic(F32vec4, float)
friend F32vec4 operator>(const F32vec4 &a, const F32vec4 &b)
Definition: P4_F32vec4.h:125
friend F32vec4 operator+(const F32vec4 &a, const F32vec4 &b)
Definition: P4_F32vec4.h:63
friend F32vec4 exp(const F32vec4 &a)
Definition: P4_F32vec4.h:153
#define _f32vec4_true
Definition: P4_F32vec4.h:41
Int_t a
Definition: anaLmdDigi.C:126
friend F32vec4 rcp(const F32vec4 &a)
Definition: P4_F32vec4.h:84
#define _f32vec4_sgn_mask
Definition: P4_F32vec4.h:38
friend F32vec4 operator/(const F32vec4 &a, const F32vec4 &b)
Definition: P4_F32vec4.h:66
TFile * f3
friend F32vec4 asgnb(const F32vec4 &a, const F32vec4 &b)
Definition: P4_F32vec4.h:95
#define _f32vec4_abs_mask
Definition: P4_F32vec4.h:37
friend F32vec4 operator|(const F32vec4 &a, const F32vec4 &b)
Definition: P4_F32vec4.h:104
friend F32vec4 if3(const F32vec4 &a, const F32vec4 &b, const F32vec4 &c)
friend F32vec4 atan2(const F32vec4 &y, const F32vec4 &x)
Definition: P4_F32vec4.h:161
friend F32vec4 operator<(const F32vec4 &a, const F32vec4 &b)
Definition: P4_F32vec4.h:119
const union @49 __f_one
friend F32vec4 bool2int(const F32vec4 &a)
Definition: P4_F32vec4.h:141
F32vec4 fvec
Definition: P4_F32vec4.h:218
friend F32vec4 cos(const F32vec4 &a)
Definition: P4_F32vec4.h:156
friend F32vec4 operator<=(const F32vec4 &a, const F32vec4 &b)
Definition: P4_F32vec4.h:122
const union @50 __f32vec4_sgn_mask_cheat
float & operator[](int i)
Definition: P4_F32vec4.h:50
class F32vec4 __attribute__((aligned(16)))
friend F32vec4 operator^(const F32vec4 &a, const F32vec4 &b)
Definition: P4_F32vec4.h:107
const int fvecLen
Definition: P4_F32vec4.h:220
F32vec4()
Definition: P4_F32vec4.h:53
Double_t x
friend F32vec4 fabs(const F32vec4 &a)
Definition: P4_F32vec4.h:91
TFile * f2
const union @50 __f32vec4_zero_cheat
float f
Definition: P4_F32vec4.h:21
friend F32vec4 operator-(const F32vec4 &a, const F32vec4 &b)
Definition: P4_F32vec4.h:64
friend F32vec4 sgn(const F32vec4 &a)
Definition: P4_F32vec4.h:94
friend F32vec4 min(const F32vec4 &a, const F32vec4 &b)
Definition: P4_F32vec4.h:69
Double_t y
friend F32vec4 operator>=(const F32vec4 &a, const F32vec4 &b)
Definition: P4_F32vec4.h:128
friend F32vec4 sqrt(const F32vec4 &a)
Definition: P4_F32vec4.h:73
const union @50 __f32vec4_abs_mask_cheat
float fscal
Definition: P4_F32vec4.h:219
friend std::istream & operator>>(std::istream &strm, F32vec4 &a)
Definition: P4_F32vec4.h:208
F32vec4(const __m128 &a)
Definition: P4_F32vec4.h:54
friend F32vec4 operator*(const F32vec4 &a, const F32vec4 &b)
Definition: P4_F32vec4.h:65
friend F32vec4 sin(const F32vec4 &a)
Definition: P4_F32vec4.h:155
const union @50 __f32vec4_true_cheat
__m128 v
Definition: P4_F32vec4.h:48