GenericPacketMath.h
Go to the documentation of this file.
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
5 // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
6 //
7 // Eigen is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU Lesser General Public
9 // License as published by the Free Software Foundation; either
10 // version 3 of the License, or (at your option) any later version.
11 //
12 // Alternatively, you can redistribute it and/or
13 // modify it under the terms of the GNU General Public License as
14 // published by the Free Software Foundation; either version 2 of
15 // the License, or (at your option) any later version.
16 //
17 // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
20 // GNU General Public License for more details.
21 //
22 // You should have received a copy of the GNU Lesser General Public
23 // License and a copy of the GNU General Public License along with
24 // Eigen. If not, see <http://www.gnu.org/licenses/>.
25 
26 #ifndef EIGEN_GENERIC_PACKET_MATH_H
27 #define EIGEN_GENERIC_PACKET_MATH_H
28 
29 namespace Eigen {
30 
31 namespace internal {
32 
41 #ifndef EIGEN_DEBUG_ALIGNED_LOAD
42 #define EIGEN_DEBUG_ALIGNED_LOAD
43 #endif
44 
45 #ifndef EIGEN_DEBUG_UNALIGNED_LOAD
46 #define EIGEN_DEBUG_UNALIGNED_LOAD
47 #endif
48 
49 #ifndef EIGEN_DEBUG_ALIGNED_STORE
50 #define EIGEN_DEBUG_ALIGNED_STORE
51 #endif
52 
53 #ifndef EIGEN_DEBUG_UNALIGNED_STORE
54 #define EIGEN_DEBUG_UNALIGNED_STORE
55 #endif
56 
57 struct default_packet_traits
58 {
59  enum {
60  HasAdd = 1,
61  HasSub = 1,
62  HasMul = 1,
63  HasNegate = 1,
64  HasAbs = 1,
65  HasAbs2 = 1,
66  HasMin = 1,
67  HasMax = 1,
68  HasConj = 1,
69  HasSetLinear = 1,
70 
71  HasDiv = 0,
72  HasSqrt = 0,
73  HasExp = 0,
74  HasLog = 0,
75  HasPow = 0,
76 
77  HasSin = 0,
78  HasCos = 0,
79  HasTan = 0,
80  HasASin = 0,
81  HasACos = 0,
82  HasATan = 0
83  };
84 };
85 
86 template<typename T> struct packet_traits : default_packet_traits
87 {
88  typedef T type;
89  enum {
90  Vectorizable = 0,
91  size = 1,
92  AlignedOnScalar = 0
93  };
94  enum {
95  HasAdd = 0,
96  HasSub = 0,
97  HasMul = 0,
98  HasNegate = 0,
99  HasAbs = 0,
100  HasAbs2 = 0,
101  HasMin = 0,
102  HasMax = 0,
103  HasConj = 0,
104  HasSetLinear = 0
105  };
106 };
107 
109 template<typename Packet> inline Packet
110 padd(const Packet& a,
111  const Packet& b) { return a+b; }
112 
114 template<typename Packet> inline Packet
115 psub(const Packet& a,
116  const Packet& b) { return a-b; }
117 
119 template<typename Packet> inline Packet
120 pnegate(const Packet& a) { return -a; }
121 
123 template<typename Packet> inline Packet
124 pconj(const Packet& a) { return conj(a); }
125 
127 template<typename Packet> inline Packet
128 pmul(const Packet& a,
129  const Packet& b) { return a*b; }
130 
132 template<typename Packet> inline Packet
133 pdiv(const Packet& a,
134  const Packet& b) { return a/b; }
135 
137 template<typename Packet> inline Packet
138 pmin(const Packet& a,
139  const Packet& b) { using std::min; return (min)(a, b); }
140 
142 template<typename Packet> inline Packet
143 pmax(const Packet& a,
144  const Packet& b) { using std::max; return (max)(a, b); }
145 
147 template<typename Packet> inline Packet
148 pabs(const Packet& a) { return abs(a); }
149 
151 template<typename Packet> inline Packet
152 pand(const Packet& a, const Packet& b) { return a & b; }
153 
155 template<typename Packet> inline Packet
156 por(const Packet& a, const Packet& b) { return a | b; }
157 
159 template<typename Packet> inline Packet
160 pxor(const Packet& a, const Packet& b) { return a ^ b; }
161 
163 template<typename Packet> inline Packet
164 pandnot(const Packet& a, const Packet& b) { return a & (!b); }
165 
167 template<typename Packet> inline Packet
168 pload(const typename unpacket_traits<Packet>::type* from) { return *from; }
169 
171 template<typename Packet> inline Packet
172 ploadu(const typename unpacket_traits<Packet>::type* from) { return *from; }
173 
175 template<typename Packet> inline Packet
176 ploaddup(const typename unpacket_traits<Packet>::type* from) { return *from; }
177 
179 template<typename Packet> inline Packet
180 pset1(const typename unpacket_traits<Packet>::type& a) { return a; }
181 
183 template<typename Scalar> inline typename packet_traits<Scalar>::type
184 plset(const Scalar& a) { return a; }
185 
187 template<typename Scalar, typename Packet> inline void pstore(Scalar* to, const Packet& from)
188 { (*to) = from; }
189 
191 template<typename Scalar, typename Packet> inline void pstoreu(Scalar* to, const Packet& from)
192 { (*to) = from; }
193 
195 template<typename Scalar> inline void prefetch(const Scalar* addr)
196 {
197 #if !defined(_MSC_VER)
198 __builtin_prefetch(addr);
199 #endif
200 }
201 
203 template<typename Packet> inline typename unpacket_traits<Packet>::type pfirst(const Packet& a)
204 { return a; }
205 
207 template<typename Packet> inline Packet
208 preduxp(const Packet* vecs) { return vecs[0]; }
209 
211 template<typename Packet> inline typename unpacket_traits<Packet>::type predux(const Packet& a)
212 { return a; }
213 
215 template<typename Packet> inline typename unpacket_traits<Packet>::type predux_mul(const Packet& a)
216 { return a; }
217 
219 template<typename Packet> inline typename unpacket_traits<Packet>::type predux_min(const Packet& a)
220 { return a; }
221 
223 template<typename Packet> inline typename unpacket_traits<Packet>::type predux_max(const Packet& a)
224 { return a; }
225 
227 template<typename Packet> inline Packet preverse(const Packet& a)
228 { return a; }
229 
230 
232 template<typename Packet> inline Packet pcplxflip(const Packet& a)
233 { return Packet(imag(a),real(a)); }
234 
235 /**************************
236 * Special math functions
237 ***************************/
238 
241 Packet psin(const Packet& a) { return sin(a); }
242 
245 Packet pcos(const Packet& a) { return cos(a); }
246 
249 Packet ptan(const Packet& a) { return tan(a); }
250 
253 Packet pasin(const Packet& a) { return asin(a); }
254 
257 Packet pacos(const Packet& a) { return acos(a); }
258 
261 Packet pexp(const Packet& a) { return exp(a); }
262 
265 Packet plog(const Packet& a) { return log(a); }
266 
269 Packet psqrt(const Packet& a) { return sqrt(a); }
270 
271 /***************************************************************************
272 * The following functions might not have to be overwritten for vectorized types
273 ***************************************************************************/
274 
276 // NOTE: this function must really be templated on the packet type (think about different packet types for the same scalar type)
277 template<typename Packet>
278 inline void pstore1(typename unpacket_traits<Packet>::type* to, const typename unpacket_traits<Packet>::type& a)
279 {
280  pstore(to, pset1<Packet>(a));
281 }
282 
284 template<typename Packet> inline Packet
285 pmadd(const Packet& a,
286  const Packet& b,
287  const Packet& c)
288 { return padd(pmul(a, b),c); }
289 
292 template<typename Packet, int LoadMode>
293 inline Packet ploadt(const typename unpacket_traits<Packet>::type* from)
294 {
295  if(LoadMode == Aligned)
296  return pload<Packet>(from);
297  else
298  return ploadu<Packet>(from);
299 }
300 
303 template<typename Scalar, typename Packet, int LoadMode>
304 inline void pstoret(Scalar* to, const Packet& from)
305 {
306  if(LoadMode == Aligned)
307  pstore(to, from);
308  else
309  pstoreu(to, from);
310 }
311 
313 template<int Offset,typename PacketType>
314 struct palign_impl
315 {
316  // by default data are aligned, so there is nothing to be done :)
317  static inline void run(PacketType&, const PacketType&) {}
318 };
319 
322 template<int Offset,typename PacketType>
323 inline void palign(PacketType& first, const PacketType& second)
324 {
325  palign_impl<Offset,PacketType>::run(first,second);
326 }
327 
328 /***************************************************************************
329 * Fast complex products (GCC generates a function call which is very slow)
330 ***************************************************************************/
331 
332 template<> inline std::complex<float> pmul(const std::complex<float>& a, const std::complex<float>& b)
333 { return std::complex<float>(real(a)*real(b) - imag(a)*imag(b), imag(a)*real(b) + real(a)*imag(b)); }
334 
335 template<> inline std::complex<double> pmul(const std::complex<double>& a, const std::complex<double>& b)
336 { return std::complex<double>(real(a)*real(b) - imag(a)*imag(b), imag(a)*real(b) + real(a)*imag(b)); }
337 
338 } // end namespace internal
339 
340 } // end namespace Eigen
341 
342 #endif // EIGEN_GENERIC_PACKET_MATH_H
343