AltiVec/Complex.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) 2010 Gael Guennebaud <gael.guennebaud@inria.fr>
5 // Copyright (C) 2010-2016 Konstantinos Margaritis <markos@freevec.org>
6 //
7 // This Source Code Form is subject to the terms of the Mozilla
8 // Public License v. 2.0. If a copy of the MPL was not distributed
9 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 
11 #ifndef EIGEN_COMPLEX32_ALTIVEC_H
12 #define EIGEN_COMPLEX32_ALTIVEC_H
13 
14 #include "../../InternalHeaderCheck.h"
15 
16 namespace Eigen {
17 
18 namespace internal {
19 
20 static Packet4ui p4ui_CONJ_XOR = vec_mergeh((Packet4ui)p4i_ZERO, (Packet4ui)p4f_MZERO);//{ 0x00000000, 0x80000000, 0x00000000, 0x80000000 };
21 #ifdef EIGEN_VECTORIZE_VSX
22 #if defined(_BIG_ENDIAN)
23 static Packet2ul p2ul_CONJ_XOR1 = (Packet2ul) vec_sld((Packet4ui) p2d_MZERO, (Packet4ui) p2l_ZERO, 8);//{ 0x8000000000000000, 0x0000000000000000 };
24 static Packet2ul p2ul_CONJ_XOR2 = (Packet2ul) vec_sld((Packet4ui) p2l_ZERO, (Packet4ui) p2d_MZERO, 8);//{ 0x8000000000000000, 0x0000000000000000 };
25 #else
26 static Packet2ul p2ul_CONJ_XOR1 = (Packet2ul) vec_sld((Packet4ui) p2l_ZERO, (Packet4ui) p2d_MZERO, 8);//{ 0x8000000000000000, 0x0000000000000000 };
27 static Packet2ul p2ul_CONJ_XOR2 = (Packet2ul) vec_sld((Packet4ui) p2d_MZERO, (Packet4ui) p2l_ZERO, 8);//{ 0x8000000000000000, 0x0000000000000000 };
28 #endif
29 #endif
30 
31 //---------- float ----------
32 struct Packet2cf
33 {
34  EIGEN_STRONG_INLINE explicit Packet2cf() {}
35  EIGEN_STRONG_INLINE explicit Packet2cf(const Packet4f& a) : v(a) {}
36 
37  EIGEN_STRONG_INLINE Packet2cf pmul(const Packet2cf& a, const Packet2cf& b)
38  {
39  Packet4f v1, v2;
40 
41  // Permute and multiply the real parts of a and b
42  v1 = vec_perm(a.v, a.v, p16uc_PSET32_WODD);
43  // Get the imaginary parts of a
44  v2 = vec_perm(a.v, a.v, p16uc_PSET32_WEVEN);
45  // multiply a_re * b
46  v1 = vec_madd(v1, b.v, p4f_ZERO);
47  // multiply a_im * b and get the conjugate result
48  v2 = vec_madd(v2, b.v, p4f_ZERO);
49  v2 = reinterpret_cast<Packet4f>(pxor(v2, reinterpret_cast<Packet4f>(p4ui_CONJ_XOR)));
50  // permute back to a proper order
51  v2 = vec_perm(v2, v2, p16uc_COMPLEX32_REV);
52 
53  return Packet2cf(padd<Packet4f>(v1, v2));
54  }
55 
56  EIGEN_STRONG_INLINE Packet2cf& operator*=(const Packet2cf& b) {
57  v = pmul(Packet2cf(*this), b).v;
58  return *this;
59  }
60  EIGEN_STRONG_INLINE Packet2cf operator*(const Packet2cf& b) const {
61  return Packet2cf(*this) *= b;
62  }
63 
64  EIGEN_STRONG_INLINE Packet2cf& operator+=(const Packet2cf& b) {
65  v = padd(v, b.v);
66  return *this;
67  }
68  EIGEN_STRONG_INLINE Packet2cf operator+(const Packet2cf& b) const {
69  return Packet2cf(*this) += b;
70  }
71  EIGEN_STRONG_INLINE Packet2cf& operator-=(const Packet2cf& b) {
72  v = psub(v, b.v);
73  return *this;
74  }
75  EIGEN_STRONG_INLINE Packet2cf operator-(const Packet2cf& b) const {
76  return Packet2cf(*this) -= b;
77  }
78  EIGEN_STRONG_INLINE Packet2cf operator-(void) const {
79  return Packet2cf(-v);
80  }
81 
82  Packet4f v;
83 };
84 
85 template<> struct packet_traits<std::complex<float> > : default_packet_traits
86 {
87  typedef Packet2cf type;
88  typedef Packet2cf half;
89  typedef Packet4f as_real;
90  enum {
91  Vectorizable = 1,
92  AlignedOnScalar = 1,
93  size = 2,
94 
95  HasAdd = 1,
96  HasSub = 1,
97  HasMul = 1,
98  HasDiv = 1,
99  HasNegate = 1,
100  HasAbs = 0,
101  HasAbs2 = 0,
102  HasMin = 0,
103  HasMax = 0,
104  HasSqrt = 1,
105 #ifdef EIGEN_VECTORIZE_VSX
106  HasBlend = 1,
107 #endif
108  HasSetLinear = 0
109  };
110 };
111 
112 template<> struct unpacket_traits<Packet2cf> { typedef std::complex<float> type; enum {size=2, alignment=Aligned16, vectorizable=true, masked_load_available=false, masked_store_available=false}; typedef Packet2cf half; typedef Packet4f as_real; };
113 
114 template<> EIGEN_STRONG_INLINE Packet2cf pset1<Packet2cf>(const std::complex<float>& from)
115 {
116  Packet2cf res;
117 #ifdef EIGEN_VECTORIZE_VSX
118  // Load a single std::complex<float> from memory and duplicate
119  //
120  // Using pload would read past the end of the reference in this case
121  // Using vec_xl_len + vec_splat, generates poor assembly
122  __asm__ ("lxvdsx %x0,%y1" : "=wa" (res.v) : "Z" (from));
123 #else
124  if((std::ptrdiff_t(&from) % 16) == 0)
125  res.v = pload<Packet4f>((const float *)&from);
126  else
127  res.v = ploadu<Packet4f>((const float *)&from);
128  res.v = vec_perm(res.v, res.v, p16uc_PSET64_HI);
129 #endif
130  return res;
131 }
132 
133 template<> EIGEN_STRONG_INLINE Packet2cf pload<Packet2cf>(const std::complex<float>* from) { return Packet2cf(pload<Packet4f>((const float *) from)); }
134 template<> EIGEN_STRONG_INLINE Packet2cf ploadu<Packet2cf>(const std::complex<float>* from) { return Packet2cf(ploadu<Packet4f>((const float*) from)); }
135 template<> EIGEN_ALWAYS_INLINE Packet2cf pload_partial<Packet2cf>(const std::complex<float>* from, const Index n, const Index offset)
136 {
137  return Packet2cf(pload_partial<Packet4f>((const float *) from, n * 2, offset * 2));
138 }
139 template<> EIGEN_ALWAYS_INLINE Packet2cf ploadu_partial<Packet2cf>(const std::complex<float>* from, const Index n, const Index offset)
140 {
141  return Packet2cf(ploadu_partial<Packet4f>((const float*) from, n * 2, offset * 2));
142 }
143 template<> EIGEN_STRONG_INLINE Packet2cf ploaddup<Packet2cf>(const std::complex<float>* from) { return pset1<Packet2cf>(*from); }
144 
145 template<> EIGEN_STRONG_INLINE void pstore <std::complex<float> >(std::complex<float> * to, const Packet2cf& from) { pstore((float*)to, from.v); }
146 template<> EIGEN_STRONG_INLINE void pstoreu<std::complex<float> >(std::complex<float> * to, const Packet2cf& from) { pstoreu((float*)to, from.v); }
147 template<> EIGEN_ALWAYS_INLINE void pstore_partial <std::complex<float> >(std::complex<float> * to, const Packet2cf& from, const Index n, const Index offset) { pstore_partial((float*)to, from.v, n * 2, offset * 2); }
148 template<> EIGEN_ALWAYS_INLINE void pstoreu_partial<std::complex<float> >(std::complex<float> * to, const Packet2cf& from, const Index n, const Index offset) { pstoreu_partial((float*)to, from.v, n * 2, offset * 2); }
149 
150 EIGEN_STRONG_INLINE Packet2cf pload2(const std::complex<float>& from0, const std::complex<float>& from1)
151 {
152  Packet4f res0, res1;
153 #ifdef EIGEN_VECTORIZE_VSX
154  // Load two std::complex<float> from memory and combine
155  __asm__ ("lxsdx %x0,%y1" : "=wa" (res0) : "Z" (from0));
156  __asm__ ("lxsdx %x0,%y1" : "=wa" (res1) : "Z" (from1));
157 #ifdef _BIG_ENDIAN
158  __asm__ ("xxpermdi %x0, %x1, %x2, 0" : "=wa" (res0) : "wa" (res0), "wa" (res1));
159 #else
160  __asm__ ("xxpermdi %x0, %x2, %x1, 0" : "=wa" (res0) : "wa" (res0), "wa" (res1));
161 #endif
162 #else
163  *reinterpret_cast<std::complex<float> *>(&res0) = from0;
164  *reinterpret_cast<std::complex<float> *>(&res1) = from1;
165  res0 = vec_perm(res0, res1, p16uc_TRANSPOSE64_HI);
166 #endif
167  return Packet2cf(res0);
168 }
169 
170 template<> EIGEN_ALWAYS_INLINE Packet2cf pload_ignore<Packet2cf>(const std::complex<float>* from)
171 {
172  Packet2cf res;
173  res.v = pload_ignore<Packet4f>(reinterpret_cast<const float*>(from));
174  return res;
175 }
176 
177 template<typename Scalar, typename Packet> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet pgather_complex_size2(const Scalar* from, Index stride, const Index n = 2)
178 {
179  eigen_internal_assert(n <= unpacket_traits<Packet>::size && "number of elements will gather past end of packet");
180  EIGEN_ALIGN16 Scalar af[2];
181  for (Index i = 0; i < n; i++) {
182  af[i] = from[i*stride];
183  }
184  return pload_ignore<Packet>(af);
185 }
186 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet2cf pgather<std::complex<float>, Packet2cf>(const std::complex<float>* from, Index stride)
187 {
188  return pgather_complex_size2<std::complex<float>, Packet2cf>(from, stride);
189 }
190 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet2cf pgather_partial<std::complex<float>, Packet2cf>(const std::complex<float>* from, Index stride, const Index n)
191 {
192  return pgather_complex_size2<std::complex<float>, Packet2cf>(from, stride, n);
193 }
194 template<typename Scalar, typename Packet> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void pscatter_complex_size2(Scalar* to, const Packet& from, Index stride, const Index n = 2)
195 {
196  eigen_internal_assert(n <= unpacket_traits<Packet>::size && "number of elements will scatter past end of packet");
197  EIGEN_ALIGN16 Scalar af[2];
198  pstore<Scalar>((Scalar *) af, from);
199  for (Index i = 0; i < n; i++) {
200  to[i*stride] = af[i];
201  }
202 }
203 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void pscatter<std::complex<float>, Packet2cf>(std::complex<float>* to, const Packet2cf& from, Index stride)
204 {
205  pscatter_complex_size2<std::complex<float>, Packet2cf>(to, from, stride);
206 }
207 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void pscatter_partial<std::complex<float>, Packet2cf>(std::complex<float>* to, const Packet2cf& from, Index stride, const Index n)
208 {
209  pscatter_complex_size2<std::complex<float>, Packet2cf>(to, from, stride, n);
210 }
211 
212 template<> EIGEN_STRONG_INLINE Packet2cf padd<Packet2cf>(const Packet2cf& a, const Packet2cf& b) { return Packet2cf(a.v + b.v); }
213 template<> EIGEN_STRONG_INLINE Packet2cf psub<Packet2cf>(const Packet2cf& a, const Packet2cf& b) { return Packet2cf(a.v - b.v); }
214 template<> EIGEN_STRONG_INLINE Packet2cf pnegate(const Packet2cf& a) { return Packet2cf(pnegate(a.v)); }
215 template<> EIGEN_STRONG_INLINE Packet2cf pconj(const Packet2cf& a) { return Packet2cf(pxor<Packet4f>(a.v, reinterpret_cast<Packet4f>(p4ui_CONJ_XOR))); }
216 
217 template<> EIGEN_STRONG_INLINE Packet2cf pand <Packet2cf>(const Packet2cf& a, const Packet2cf& b) { return Packet2cf(pand<Packet4f>(a.v, b.v)); }
218 template<> EIGEN_STRONG_INLINE Packet2cf por <Packet2cf>(const Packet2cf& a, const Packet2cf& b) { return Packet2cf(por<Packet4f>(a.v, b.v)); }
219 template<> EIGEN_STRONG_INLINE Packet2cf pxor <Packet2cf>(const Packet2cf& a, const Packet2cf& b) { return Packet2cf(pxor<Packet4f>(a.v, b.v)); }
220 template<> EIGEN_STRONG_INLINE Packet2cf pandnot<Packet2cf>(const Packet2cf& a, const Packet2cf& b) { return Packet2cf(pandnot<Packet4f>(a.v, b.v)); }
221 
222 template<> EIGEN_STRONG_INLINE void prefetch<std::complex<float> >(const std::complex<float> * addr) { EIGEN_PPC_PREFETCH(addr); }
223 
224 template<> EIGEN_STRONG_INLINE std::complex<float> pfirst<Packet2cf>(const Packet2cf& a)
225 {
226  EIGEN_ALIGN16 std::complex<float> res[2];
227  pstore((float *)&res, a.v);
228 
229  return res[0];
230 }
231 
232 template<> EIGEN_STRONG_INLINE Packet2cf preverse(const Packet2cf& a)
233 {
234  Packet4f rev_a;
235  rev_a = vec_sld(a.v, a.v, 8);
236  return Packet2cf(rev_a);
237 }
238 
239 template<> EIGEN_STRONG_INLINE std::complex<float> predux<Packet2cf>(const Packet2cf& a)
240 {
241  Packet4f b;
242  b = vec_sld(a.v, a.v, 8);
243  b = padd<Packet4f>(a.v, b);
244  return pfirst<Packet2cf>(Packet2cf(b));
245 }
246 
247 template<> EIGEN_STRONG_INLINE std::complex<float> predux_mul<Packet2cf>(const Packet2cf& a)
248 {
249  Packet4f b;
250  Packet2cf prod;
251  b = vec_sld(a.v, a.v, 8);
252  prod = pmul<Packet2cf>(a, Packet2cf(b));
253 
254  return pfirst<Packet2cf>(prod);
255 }
256 
258 
259 template<> EIGEN_STRONG_INLINE Packet2cf pdiv<Packet2cf>(const Packet2cf& a, const Packet2cf& b)
260 {
261  return pdiv_complex(a, b);
262 }
263 
264 template<> EIGEN_STRONG_INLINE Packet2cf pcplxflip<Packet2cf>(const Packet2cf& x)
265 {
266  return Packet2cf(vec_perm(x.v, x.v, p16uc_COMPLEX32_REV));
267 }
268 
269 EIGEN_STRONG_INLINE void ptranspose(PacketBlock<Packet2cf,2>& kernel)
270 {
271 #ifdef EIGEN_VECTORIZE_VSX
272  Packet4f tmp = reinterpret_cast<Packet4f>(vec_mergeh(reinterpret_cast<Packet2d>(kernel.packet[0].v), reinterpret_cast<Packet2d>(kernel.packet[1].v)));
273  kernel.packet[1].v = reinterpret_cast<Packet4f>(vec_mergel(reinterpret_cast<Packet2d>(kernel.packet[0].v), reinterpret_cast<Packet2d>(kernel.packet[1].v)));
274 #else
275  Packet4f tmp = vec_perm(kernel.packet[0].v, kernel.packet[1].v, p16uc_TRANSPOSE64_HI);
276  kernel.packet[1].v = vec_perm(kernel.packet[0].v, kernel.packet[1].v, p16uc_TRANSPOSE64_LO);
277 #endif
278  kernel.packet[0].v = tmp;
279 }
280 
281 template<> EIGEN_STRONG_INLINE Packet2cf pcmp_eq(const Packet2cf& a, const Packet2cf& b) {
282  Packet4f eq = reinterpret_cast<Packet4f>(vec_cmpeq(a.v,b.v));
283  return Packet2cf(vec_and(eq, vec_perm(eq, eq, p16uc_COMPLEX32_REV)));
284 }
285 
286 #ifdef EIGEN_VECTORIZE_VSX
287 template<> EIGEN_STRONG_INLINE Packet2cf pblend(const Selector<2>& ifPacket, const Packet2cf& thenPacket, const Packet2cf& elsePacket) {
288  Packet2cf result;
289  result.v = reinterpret_cast<Packet4f>(pblend<Packet2d>(ifPacket, reinterpret_cast<Packet2d>(thenPacket.v), reinterpret_cast<Packet2d>(elsePacket.v)));
290  return result;
291 }
292 #endif
293 
294 template<> EIGEN_STRONG_INLINE Packet2cf psqrt<Packet2cf>(const Packet2cf& a)
295 {
296  return psqrt_complex<Packet2cf>(a);
297 }
298 
299 //---------- double ----------
300 #ifdef EIGEN_VECTORIZE_VSX
301 struct Packet1cd
302 {
303  EIGEN_STRONG_INLINE Packet1cd() {}
304  EIGEN_STRONG_INLINE explicit Packet1cd(const Packet2d& a) : v(a) {}
305 
306  EIGEN_STRONG_INLINE Packet1cd pmul(const Packet1cd& a, const Packet1cd& b)
307  {
308  Packet2d a_re, a_im, v1, v2;
309 
310  // Permute and multiply the real parts of a and b
311  a_re = vec_perm(a.v, a.v, p16uc_PSET64_HI);
312  // Get the imaginary parts of a
313  a_im = vec_perm(a.v, a.v, p16uc_PSET64_LO);
314  // multiply a_re * b
315  v1 = vec_madd(a_re, b.v, p2d_ZERO);
316  // multiply a_im * b and get the conjugate result
317  v2 = vec_madd(a_im, b.v, p2d_ZERO);
318  v2 = reinterpret_cast<Packet2d>(vec_sld(reinterpret_cast<Packet4ui>(v2), reinterpret_cast<Packet4ui>(v2), 8));
319  v2 = pxor(v2, reinterpret_cast<Packet2d>(p2ul_CONJ_XOR1));
320 
321  return Packet1cd(padd<Packet2d>(v1, v2));
322  }
323 
324  EIGEN_STRONG_INLINE Packet1cd& operator*=(const Packet1cd& b) {
325  v = pmul(Packet1cd(*this), b).v;
326  return *this;
327  }
328  EIGEN_STRONG_INLINE Packet1cd operator*(const Packet1cd& b) const {
329  return Packet1cd(*this) *= b;
330  }
331 
332  EIGEN_STRONG_INLINE Packet1cd& operator+=(const Packet1cd& b) {
333  v = padd(v, b.v);
334  return *this;
335  }
336  EIGEN_STRONG_INLINE Packet1cd operator+(const Packet1cd& b) const {
337  return Packet1cd(*this) += b;
338  }
339  EIGEN_STRONG_INLINE Packet1cd& operator-=(const Packet1cd& b) {
340  v = psub(v, b.v);
341  return *this;
342  }
343  EIGEN_STRONG_INLINE Packet1cd operator-(const Packet1cd& b) const {
344  return Packet1cd(*this) -= b;
345  }
346  EIGEN_STRONG_INLINE Packet1cd operator-(void) const {
347  return Packet1cd(-v);
348  }
349 
350  Packet2d v;
351 };
352 
353 template<> struct packet_traits<std::complex<double> > : default_packet_traits
354 {
355  typedef Packet1cd type;
356  typedef Packet1cd half;
357  typedef Packet2d as_real;
358  enum {
359  Vectorizable = 1,
360  AlignedOnScalar = 0,
361  size = 1,
362 
363  HasAdd = 1,
364  HasSub = 1,
365  HasMul = 1,
366  HasDiv = 1,
367  HasNegate = 1,
368  HasAbs = 0,
369  HasAbs2 = 0,
370  HasMin = 0,
371  HasMax = 0,
372  HasSqrt = 1,
373  HasSetLinear = 0
374  };
375 };
376 
377 template<> struct unpacket_traits<Packet1cd> { typedef std::complex<double> type; enum {size=1, alignment=Aligned16, vectorizable=true, masked_load_available=false, masked_store_available=false}; typedef Packet1cd half; typedef Packet2d as_real; };
378 
379 template<> EIGEN_STRONG_INLINE Packet1cd pload <Packet1cd>(const std::complex<double>* from) { return Packet1cd(pload<Packet2d>((const double*)from)); }
380 template<> EIGEN_STRONG_INLINE Packet1cd ploadu<Packet1cd>(const std::complex<double>* from) { return Packet1cd(ploadu<Packet2d>((const double*)from)); }
381 template<> EIGEN_ALWAYS_INLINE Packet1cd pload_partial<Packet1cd>(const std::complex<double>* from, const Index n, const Index offset)
382 {
383  return Packet1cd(pload_partial<Packet2d>((const double*)from, n * 2, offset * 2));
384 }
385 template<> EIGEN_ALWAYS_INLINE Packet1cd ploadu_partial<Packet1cd>(const std::complex<double>* from, const Index n, const Index offset)
386 {
387  return Packet1cd(ploadu_partial<Packet2d>((const double*)from, n * 2, offset * 2));
388 }
389 template<> EIGEN_STRONG_INLINE void pstore <std::complex<double> >(std::complex<double> * to, const Packet1cd& from) { pstore((double*)to, from.v); }
390 template<> EIGEN_STRONG_INLINE void pstoreu<std::complex<double> >(std::complex<double> * to, const Packet1cd& from) { pstoreu((double*)to, from.v); }
391 template<> EIGEN_ALWAYS_INLINE void pstore_partial <std::complex<double> >(std::complex<double> * to, const Packet1cd& from, const Index n, const Index offset) { pstore_partial((double*)to, from.v, n * 2, offset * 2); }
392 template<> EIGEN_ALWAYS_INLINE void pstoreu_partial<std::complex<double> >(std::complex<double> * to, const Packet1cd& from, const Index n, const Index offset) { pstoreu_partial((double*)to, from.v, n * 2, offset * 2); }
393 
394 template<> EIGEN_STRONG_INLINE Packet1cd pset1<Packet1cd>(const std::complex<double>& from)
395 { /* here we really have to use unaligned loads :( */ return ploadu<Packet1cd>(&from); }
396 
397 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet1cd pgather<std::complex<double>, Packet1cd>(const std::complex<double>* from, Index)
398 {
399  return pload<Packet1cd>(from);
400 }
401 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet1cd pgather_partial<std::complex<double>, Packet1cd>(const std::complex<double>* from, Index, const Index)
402 {
403  return pload<Packet1cd>(from);
404 }
405 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void pscatter<std::complex<double>, Packet1cd>(std::complex<double>* to, const Packet1cd& from, Index)
406 {
407  pstore<std::complex<double> >(to, from);
408 }
409 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void pscatter_partial<std::complex<double>, Packet1cd>(std::complex<double>* to, const Packet1cd& from, Index, const Index)
410 {
411  pstore<std::complex<double> >(to, from);
412 }
413 
414 template<> EIGEN_STRONG_INLINE Packet1cd padd<Packet1cd>(const Packet1cd& a, const Packet1cd& b) { return Packet1cd(a.v + b.v); }
415 template<> EIGEN_STRONG_INLINE Packet1cd psub<Packet1cd>(const Packet1cd& a, const Packet1cd& b) { return Packet1cd(a.v - b.v); }
416 template<> EIGEN_STRONG_INLINE Packet1cd pnegate(const Packet1cd& a) { return Packet1cd(pnegate(Packet2d(a.v))); }
417 template<> EIGEN_STRONG_INLINE Packet1cd pconj(const Packet1cd& a) { return Packet1cd(pxor(a.v, reinterpret_cast<Packet2d>(p2ul_CONJ_XOR2))); }
418 
419 template<> EIGEN_STRONG_INLINE Packet1cd pand <Packet1cd>(const Packet1cd& a, const Packet1cd& b) { return Packet1cd(pand(a.v,b.v)); }
420 template<> EIGEN_STRONG_INLINE Packet1cd por <Packet1cd>(const Packet1cd& a, const Packet1cd& b) { return Packet1cd(por(a.v,b.v)); }
421 template<> EIGEN_STRONG_INLINE Packet1cd pxor <Packet1cd>(const Packet1cd& a, const Packet1cd& b) { return Packet1cd(pxor(a.v,b.v)); }
422 template<> EIGEN_STRONG_INLINE Packet1cd pandnot<Packet1cd>(const Packet1cd& a, const Packet1cd& b) { return Packet1cd(pandnot(a.v, b.v)); }
423 
424 template<> EIGEN_STRONG_INLINE Packet1cd ploaddup<Packet1cd>(const std::complex<double>* from) { return pset1<Packet1cd>(*from); }
425 
426 template<> EIGEN_STRONG_INLINE void prefetch<std::complex<double> >(const std::complex<double> * addr) { EIGEN_PPC_PREFETCH(addr); }
427 
428 template<> EIGEN_STRONG_INLINE std::complex<double> pfirst<Packet1cd>(const Packet1cd& a)
429 {
430  EIGEN_ALIGN16 std::complex<double> res[1];
431  pstore<std::complex<double> >(res, a);
432 
433  return res[0];
434 }
435 
436 template<> EIGEN_STRONG_INLINE Packet1cd preverse(const Packet1cd& a) { return a; }
437 
438 template<> EIGEN_STRONG_INLINE std::complex<double> predux<Packet1cd>(const Packet1cd& a) { return pfirst(a); }
439 
440 template<> EIGEN_STRONG_INLINE std::complex<double> predux_mul<Packet1cd>(const Packet1cd& a) { return pfirst(a); }
441 
443 
444 template<> EIGEN_STRONG_INLINE Packet1cd pdiv<Packet1cd>(const Packet1cd& a, const Packet1cd& b)
445 {
446  return pdiv_complex(a, b);
447 }
448 
449 EIGEN_STRONG_INLINE Packet1cd pcplxflip/*<Packet1cd>*/(const Packet1cd& x)
450 {
451  return Packet1cd(preverse(Packet2d(x.v)));
452 }
453 
454 EIGEN_STRONG_INLINE void ptranspose(PacketBlock<Packet1cd,2>& kernel)
455 {
456  Packet2d tmp = vec_mergeh(kernel.packet[0].v, kernel.packet[1].v);
457  kernel.packet[1].v = vec_mergel(kernel.packet[0].v, kernel.packet[1].v);
458  kernel.packet[0].v = tmp;
459 }
460 
461 template<> EIGEN_STRONG_INLINE Packet1cd pcmp_eq(const Packet1cd& a, const Packet1cd& b) {
462  // Compare real and imaginary parts of a and b to get the mask vector:
463  // [re(a)==re(b), im(a)==im(b)]
464  Packet2d eq = reinterpret_cast<Packet2d>(vec_cmpeq(a.v,b.v));
465  // Swap real/imag elements in the mask in to get:
466  // [im(a)==im(b), re(a)==re(b)]
467  Packet2d eq_swapped = reinterpret_cast<Packet2d>(vec_sld(reinterpret_cast<Packet4ui>(eq), reinterpret_cast<Packet4ui>(eq), 8));
468  // Return re(a)==re(b) & im(a)==im(b) by computing bitwise AND of eq and eq_swapped
469  return Packet1cd(vec_and(eq, eq_swapped));
470 }
471 
472 template<> EIGEN_STRONG_INLINE Packet1cd psqrt<Packet1cd>(const Packet1cd& a)
473 {
474  return psqrt_complex<Packet1cd>(a);
475 }
476 
477 #endif // __VSX__
478 } // end namespace internal
479 
480 } // end namespace Eigen
481 
482 #endif // EIGEN_COMPLEX32_ALTIVEC_H
#define EIGEN_PPC_PREFETCH(ADDR)
Array< int, Dynamic, 1 > v
Array< int, 3, 1 > b
int n
#define EIGEN_ALIGN16
#define EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(PACKET_CPLX, PACKET_REAL)
Definition: ConjHelper.h:14
#define EIGEN_ALWAYS_INLINE
Definition: Macros.h:836
#define eigen_internal_assert(x)
Definition: Macros.h:908
#define EIGEN_DEVICE_FUNC
Definition: Macros.h:883
cout<< "Here is the matrix m:"<< endl<< m<< endl;Matrix< ptrdiff_t, 3, 1 > res
Map< RowVectorXf > v2(M2.data(), M2.size())
M1<< 1, 2, 3, 4, 5, 6, 7, 8, 9;Map< RowVectorXf > v1(M1.data(), M1.size())
@ Aligned16
Definition: Constants.h:237
bfloat16 & operator*=(bfloat16 &a, const bfloat16 &b)
Definition: BFloat16.h:286
bfloat16 & operator+=(bfloat16 &a, const bfloat16 &b)
Definition: BFloat16.h:282
bfloat16 & operator-=(bfloat16 &a, const bfloat16 &b)
Definition: BFloat16.h:290
EIGEN_ALWAYS_INLINE Packet4f pload_partial< Packet4f >(const float *from, const Index n, const Index offset)
Packet padd(const Packet &a, const Packet &b)
static Packet2ul p2ul_CONJ_XOR2
Packet1cd pxor< Packet1cd >(const Packet1cd &a, const Packet1cd &b)
Definition: MSA/Complex.h:516
Packet2cf pandnot< Packet2cf >(const Packet2cf &a, const Packet2cf &b)
void pstore(Scalar *to, const Packet &from)
std::complex< float > predux< Packet2cf >(const Packet2cf &a)
Packet1cd pload< Packet1cd >(const std::complex< double > *from)
Definition: MSA/Complex.h:446
Packet2cf padd< Packet2cf >(const Packet2cf &a, const Packet2cf &b)
Packet2cf ploaddup< Packet2cf >(const std::complex< float > *from)
std::complex< float > pfirst< Packet2cf >(const Packet2cf &a)
Packet2cf pset1< Packet2cf >(const std::complex< float > &from)
Packet4f pxor< Packet4f >(const Packet4f &a, const Packet4f &b)
Packet1cd pdiv< Packet1cd >(const Packet1cd &a, const Packet1cd &b)
Definition: MSA/Complex.h:611
Packet1cd pandnot< Packet1cd >(const Packet1cd &a, const Packet1cd &b)
Definition: MSA/Complex.h:523
Packet2cf ploadu< Packet2cf >(const std::complex< float > *from)
Packet4f por< Packet4f >(const Packet4f &a, const Packet4f &b)
static Packet16uc p16uc_TRANSPOSE64_LO
Packet4f pandnot< Packet4f >(const Packet4f &a, const Packet4f &b)
Packet8h pandnot(const Packet8h &a, const Packet8h &b)
Packet1cd padd< Packet1cd >(const Packet1cd &a, const Packet1cd &b)
Definition: MSA/Complex.h:467
void pstore_partial(Scalar *to, const Packet &from, const Index n, const Index offset=0)
Packet2cf pnegate(const Packet2cf &a)
Packet1cd ploadu< Packet1cd >(const std::complex< double > *from)
Definition: MSA/Complex.h:453
Packet4f pand< Packet4f >(const Packet4f &a, const Packet4f &b)
Packet2cf por< Packet2cf >(const Packet2cf &a, const Packet2cf &b)
Packet1cd pcplxflip(const Packet1cd &x)
Definition: MSA/Complex.h:617
static Packet16uc p16uc_PSET32_WEVEN
std::complex< double > pfirst< Packet1cd >(const Packet1cd &a)
Definition: MSA/Complex.h:581
EIGEN_ALWAYS_INLINE void pscatter_complex_size2(Scalar *to, const Packet &from, Index stride, const Index n=2)
void pstoreu(Scalar *to, const Packet &from)
Packet2cf pcmp_eq(const Packet2cf &a, const Packet2cf &b)
bfloat16 pfirst(const Packet8bf &a)
void pstoreu_partial(Scalar *to, const Packet &from, const Index n, const Index offset=0)
Packet2cf pmul< Packet2cf >(const Packet2cf &a, const Packet2cf &b)
Definition: MSA/Complex.h:171
__vector unsigned int Packet4ui
Packet pmul(const Packet &a, const Packet &b)
void ptranspose(PacketBlock< Packet2cf, 2 > &kernel)
static Packet4ui p4ui_CONJ_XOR
EIGEN_ALWAYS_INLINE Packet2cf pload_partial< Packet2cf >(const std::complex< float > *from, const Index n, const Index offset)
static Packet2ul p2ul_CONJ_XOR1
EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet pdiv_complex(const Packet &x, const Packet &y)
Packet2cf pcplxflip< Packet2cf >(const Packet2cf &x)
Packet1cd pand< Packet1cd >(const Packet1cd &a, const Packet1cd &b)
Definition: MSA/Complex.h:502
Packet2cf pxor< Packet2cf >(const Packet2cf &a, const Packet2cf &b)
Packet4f padd< Packet4f >(const Packet4f &a, const Packet4f &b)
Packet4f ploadu< Packet4f >(const float *from)
std::complex< double > predux_mul< Packet1cd >(const Packet1cd &a)
Definition: MSA/Complex.h:602
Packet2d padd< Packet2d >(const Packet2d &a, const Packet2d &b)
Packet psub(const Packet &a, const Packet &b)
static Packet4f p4f_MZERO
std::complex< double > predux< Packet1cd >(const Packet1cd &a)
Definition: MSA/Complex.h:595
Packet1cd por< Packet1cd >(const Packet1cd &a, const Packet1cd &b)
Definition: MSA/Complex.h:509
Packet8h pand(const Packet8h &a, const Packet8h &b)
Packet2d ploadu< Packet2d >(const double *from)
EIGEN_ALWAYS_INLINE Packet pgather_complex_size2(const Scalar *from, Index stride, const Index n=2)
Packet2cf pload< Packet2cf >(const std::complex< float > *from)
Packet2cf pload2(const std::complex< float > &from0, const std::complex< float > &from1)
static Packet16uc p16uc_PSET64_HI
Packet2cf pand< Packet2cf >(const Packet2cf &a, const Packet2cf &b)
Packet8h pxor(const Packet8h &a, const Packet8h &b)
Packet1cd ploaddup< Packet1cd >(const std::complex< double > *from)
Definition: MSA/Complex.h:530
Packet1cd psqrt< Packet1cd >(const Packet1cd &a)
Definition: SSE/Complex.h:319
Packet pdiv(const Packet &a, const Packet &b)
Packet4i pblend(const Selector< 4 > &ifPacket, const Packet4i &thenPacket, const Packet4i &elsePacket)
Packet1cd pset1< Packet1cd >(const std::complex< double > &from)
Definition: MSA/Complex.h:460
Packet2cf pconj(const Packet2cf &a)
EIGEN_ALWAYS_INLINE Packet2cf pload_ignore< Packet2cf >(const std::complex< float > *from)
EIGEN_ALWAYS_INLINE Packet4f ploadu_partial< Packet4f >(const float *from, const Index n, const Index offset)
Packet2d pload< Packet2d >(const double *from)
static Packet16uc p16uc_PSET32_WODD
Packet2cf preverse(const Packet2cf &a)
static Packet16uc p16uc_PSET64_LO
Packet4f pload< Packet4f >(const float *from)
static Packet16uc p16uc_COMPLEX32_REV
Packet8h por(const Packet8h &a, const Packet8h &b)
__vector float Packet4f
EIGEN_ALWAYS_INLINE Packet2cf ploadu_partial< Packet2cf >(const std::complex< float > *from, const Index n, const Index offset)
Packet2cf psub< Packet2cf >(const Packet2cf &a, const Packet2cf &b)
Packet1cd psub< Packet1cd >(const Packet1cd &a, const Packet1cd &b)
Definition: MSA/Complex.h:474
Packet2cf psqrt< Packet2cf >(const Packet2cf &a)
std::complex< float > predux_mul< Packet2cf >(const Packet2cf &a)
static Packet16uc p16uc_TRANSPOSE64_HI
: InteropHeaders
Definition: Core:139
const CwiseBinaryOp< internal::scalar_difference_op< typename DenseDerived::Scalar, typename SparseDerived::Scalar >, const DenseDerived, const SparseDerived > operator-(const MatrixBase< DenseDerived > &a, const SparseMatrixBase< SparseDerived > &b)
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:82
const Product< MatrixDerived, PermutationDerived, AliasFreeProduct > operator*(const MatrixBase< MatrixDerived > &matrix, const PermutationBase< PermutationDerived > &permutation)
const CwiseBinaryOp< internal::scalar_sum_op< typename DenseDerived::Scalar, typename SparseDerived::Scalar >, const DenseDerived, const SparseDerived > operator+(const MatrixBase< DenseDerived > &a, const SparseMatrixBase< SparseDerived > &b)
Definition: BFloat16.h:222