12#ifndef EIGEN_COMPLEX_RVV10_H
13#define EIGEN_COMPLEX_RVV10_H
16#include "../../InternalHeaderCheck.h"
22EIGEN_GCC_FAST_MATH_COMPLEX_VECTORIZE_WORKAROUND_PUSH
27#if EIGEN_RISCV64_DEFAULT_LMUL == 4
29#elif EIGEN_RISCV64_DEFAULT_LMUL == 2
36template <
typename RealPacketT,
int N>
37struct complex_packet_wrapper {
38 complex_packet_wrapper() =
default;
39 EIGEN_STRONG_INLINE
explicit complex_packet_wrapper(
const RealPacketT& a) : v(a) {}
44typedef complex_packet_wrapper<Packet2Xf, 29> Packet2Xcf;
45typedef complex_packet_wrapper<Packet4Xf, 30> Packet4Xcf;
46typedef complex_packet_wrapper<Packet1Xf, 31> Packet1Xcf;
48#if EIGEN_RISCV64_DEFAULT_LMUL == 1
49typedef Packet1Xcf PacketXcf;
52struct packet_traits<std::complex<float>> : default_packet_traits {
53 typedef Packet1Xcf type;
54 typedef Packet1Xcf half;
58 size = rvv_packet_size_selector<std::complex<float>, EIGEN_RISCV64_RVV_VL, 1>::size,
78#elif EIGEN_RISCV64_DEFAULT_LMUL == 2
79typedef Packet2Xcf PacketXcf;
82struct packet_traits<std::complex<float>> : default_packet_traits {
83 typedef Packet2Xcf type;
85 typedef Packet1Xcf half;
87 typedef Packet2Xcf half;
92 size = rvv_packet_size_selector<std::complex<float>, EIGEN_RISCV64_RVV_VL, 2>::size,
112#elif EIGEN_RISCV64_DEFAULT_LMUL == 4
113typedef Packet4Xcf PacketXcf;
116struct packet_traits<std::complex<float>> : default_packet_traits {
117 typedef Packet4Xcf type;
118#ifndef USE_LMUL4_ONLY
119 typedef Packet2Xcf half;
121 typedef Packet4Xcf half;
126 size = rvv_packet_size_selector<std::complex<float>, EIGEN_RISCV64_RVV_VL, 4>::size,
149struct unpacket_traits<Packet2Xcf> : default_unpacket_traits {
150 typedef std::complex<float> type;
151#ifndef USE_LMUL2_ONLY
152 typedef Packet1Xcf half;
154 typedef Packet2Xcf half;
156 typedef Packet2Xf as_real;
158 size = rvv_packet_size_selector<std::complex<float>, EIGEN_RISCV64_RVV_VL, 2>::size,
159 alignment = rvv_packet_alignment_selector<EIGEN_RISCV64_RVV_VL, 2>::alignment,
161 masked_load_available =
false,
162 masked_store_available =
false
167struct unpacket_traits<Packet4Xcf> : default_unpacket_traits {
168 typedef std::complex<float> type;
169#ifndef USE_LMUL4_ONLY
170 typedef Packet2Xcf half;
172 typedef Packet4Xcf half;
174 typedef Packet4Xf as_real;
176 size = rvv_packet_size_selector<std::complex<float>, EIGEN_RISCV64_RVV_VL, 4>::size,
177 alignment = rvv_packet_alignment_selector<EIGEN_RISCV64_RVV_VL, 4>::alignment,
179 masked_load_available =
false,
180 masked_store_available =
false
185struct unpacket_traits<Packet1Xcf> : default_unpacket_traits {
186 typedef std::complex<float> type;
187 typedef Packet1Xcf half;
188 typedef Packet1Xf as_real;
190 size = rvv_packet_size_selector<std::complex<float>, EIGEN_RISCV64_RVV_VL, 1>::size,
191 alignment = rvv_packet_alignment_selector<EIGEN_RISCV64_RVV_VL, 1>::alignment,
193 masked_load_available =
false,
194 masked_store_available =
false
199EIGEN_STRONG_INLINE Packet2Xcf pcast<Packet2Xf, Packet2Xcf>(
const Packet2Xf& a) {
200 return Packet2Xcf(a);
204EIGEN_STRONG_INLINE Packet2Xf pcast<Packet2Xcf, Packet2Xf>(
const Packet2Xcf& a) {
208EIGEN_STRONG_INLINE Packet2Xul __riscv_vreinterpret_v_f32m2_u64m2(
const Packet2Xf& a) {
209 return __riscv_vreinterpret_v_u32m2_u64m2(__riscv_vreinterpret_v_f32m2_u32m2(a));
212EIGEN_STRONG_INLINE Packet2Xl __riscv_vreinterpret_v_f32m2_i64m2(
const Packet2Xf& a) {
213 return __riscv_vreinterpret_v_u64m2_i64m2(__riscv_vreinterpret_v_u32m2_u64m2(__riscv_vreinterpret_v_f32m2_u32m2(a)));
216EIGEN_STRONG_INLINE Packet2Xf __riscv_vreinterpret_v_i64m2_f32m2(
const Packet2Xl& a) {
217 return __riscv_vreinterpret_v_u32m2_f32m2(__riscv_vreinterpret_v_u64m2_u32m2(__riscv_vreinterpret_v_i64m2_u64m2(a)));
220EIGEN_STRONG_INLINE
void prealimag2(
const Packet2Xcf& a, Packet2Xf& real, Packet2Xf& imag) {
221 const PacketMask16 mask =
222 __riscv_vreinterpret_v_i8m1_b16(__riscv_vmv_v_x_i8m1(
static_cast<char>(0xaa), unpacket_traits<Packet1Xc>::size));
223 Packet2Xu res = __riscv_vreinterpret_v_f32m2_u32m2(a.v);
224 real = __riscv_vreinterpret_v_u32m2_f32m2(
225 __riscv_vslide1up_vx_u32m2_tumu(mask, res, res, 0, unpacket_traits<Packet2Xi>::size));
226 imag = __riscv_vreinterpret_v_u32m2_f32m2(__riscv_vslide1down_vx_u32m2_tumu(
227 __riscv_vmnot_m_b16(mask, unpacket_traits<Packet1Xs>::size), res, res, 0, unpacket_traits<Packet2Xi>::size));
231EIGEN_STRONG_INLINE Packet2Xcf pset1<Packet2Xcf>(
const std::complex<float>& from) {
232 const numext::int64_t from2 = *
reinterpret_cast<const numext::int64_t*
>(
reinterpret_cast<const void*
>(&from));
233 Packet2Xf res = __riscv_vreinterpret_v_i64m2_f32m2(pset1<Packet2Xl>(from2));
234 return Packet2Xcf(res);
238EIGEN_STRONG_INLINE Packet2Xcf padd<Packet2Xcf>(
const Packet2Xcf& a,
const Packet2Xcf& b) {
239 return Packet2Xcf(padd<Packet2Xf>(a.v, b.v));
243EIGEN_STRONG_INLINE Packet2Xcf psub<Packet2Xcf>(
const Packet2Xcf& a,
const Packet2Xcf& b) {
244 return Packet2Xcf(psub<Packet2Xf>(a.v, b.v));
248EIGEN_STRONG_INLINE Packet2Xcf pnegate(
const Packet2Xcf& a) {
249 return Packet2Xcf(pnegate<Packet2Xf>(a.v));
253EIGEN_STRONG_INLINE Packet2Xcf pconj(
const Packet2Xcf& a) {
254 return Packet2Xcf(__riscv_vreinterpret_v_u64m2_f32m2(__riscv_vxor_vx_u64m2(
255 __riscv_vreinterpret_v_f32m2_u64m2(a.v), 0x8000000000000000ull, unpacket_traits<Packet2Xl>::size)));
259EIGEN_STRONG_INLINE Packet2Xcf pcplxflip<Packet2Xcf>(
const Packet2Xcf& a) {
261 Packet2Xu res = __riscv_vreinterpret_v_f32m2_u32m2(a.v);
262 const PacketMask16 mask =
263 __riscv_vreinterpret_v_i8m1_b16(__riscv_vmv_v_x_i8m1(
static_cast<char>(0xaa), unpacket_traits<Packet1Xc>::size));
264 Packet2Xu data = __riscv_vslide1down_vx_u32m2(res, 0, unpacket_traits<Packet2Xi>::size);
265 Packet2Xf res2 = __riscv_vreinterpret_v_u32m2_f32m2(
266 __riscv_vslide1up_vx_u32m2_tumu(mask, data, res, 0, unpacket_traits<Packet2Xf>::size));
267 return Packet2Xcf(res2);
269 Packet2Xf res = __riscv_vreinterpret_v_u64m2_f32m2(
270 __riscv_vror_vx_u64m2(__riscv_vreinterpret_v_f32m2_u64m2(a.v), 32, unpacket_traits<Packet2Xl>::size));
271 return Packet2Xcf(res);
276EIGEN_STRONG_INLINE Packet2Xcf pmul<Packet2Xcf>(
const Packet2Xcf& a,
const Packet2Xcf& b) {
277 Packet2Xf real, imag;
278 prealimag2(a, real, imag);
279 return Packet2Xcf(pmadd<Packet2Xf>(imag, pcplxflip<Packet2Xcf>(pconj<Packet2Xcf>(b)).v, pmul<Packet2Xf>(real, b.v)));
283EIGEN_STRONG_INLINE Packet2Xcf pmadd<Packet2Xcf>(
const Packet2Xcf& a,
const Packet2Xcf& b,
const Packet2Xcf& c) {
284 Packet2Xf real, imag;
285 prealimag2(a, real, imag);
287 pmadd<Packet2Xf>(imag, pcplxflip<Packet2Xcf>(pconj<Packet2Xcf>(b)).v, pmadd<Packet2Xf>(real, b.v, c.v)));
291EIGEN_STRONG_INLINE Packet2Xcf pmsub<Packet2Xcf>(
const Packet2Xcf& a,
const Packet2Xcf& b,
const Packet2Xcf& c) {
292 Packet2Xf real, imag;
293 prealimag2(a, real, imag);
295 pmadd<Packet2Xf>(imag, pcplxflip<Packet2Xcf>(pconj<Packet2Xcf>(b)).v, pmsub<Packet2Xf>(real, b.v, c.v)));
299EIGEN_STRONG_INLINE Packet2Xcf pcmp_eq(
const Packet2Xcf& a,
const Packet2Xcf& b) {
300 Packet2Xi c = __riscv_vundefined_i32m2();
301 PacketMask16 mask = __riscv_vmfeq_vv_f32m2_b16(a.v, b.v, unpacket_traits<Packet2Xf>::size);
302 Packet2Xl res = __riscv_vreinterpret_v_i32m2_i64m2(
303 __riscv_vmerge_vvm_i32m2(pzero<Packet2Xi>(c), ptrue<Packet2Xi>(c), mask, unpacket_traits<Packet2Xi>::size));
304 Packet2Xf res2 = __riscv_vreinterpret_v_i64m2_f32m2(
305 __riscv_vsra_vx_i64m2(__riscv_vand_vv_i64m2(__riscv_vsll_vx_i64m2(res, 32, unpacket_traits<Packet2Xl>::size), res,
306 unpacket_traits<Packet2Xl>::size),
307 32, unpacket_traits<Packet2Xl>::size));
308 return Packet2Xcf(res2);
312EIGEN_STRONG_INLINE Packet2Xcf pand<Packet2Xcf>(
const Packet2Xcf& a,
const Packet2Xcf& b) {
313 return Packet2Xcf(pand<Packet2Xf>(a.v, b.v));
317EIGEN_STRONG_INLINE Packet2Xcf por<Packet2Xcf>(
const Packet2Xcf& a,
const Packet2Xcf& b) {
318 return Packet2Xcf(por<Packet2Xf>(a.v, b.v));
322EIGEN_STRONG_INLINE Packet2Xcf pxor<Packet2Xcf>(
const Packet2Xcf& a,
const Packet2Xcf& b) {
323 return Packet2Xcf(pxor<Packet2Xf>(a.v, b.v));
327EIGEN_STRONG_INLINE Packet2Xcf pandnot<Packet2Xcf>(
const Packet2Xcf& a,
const Packet2Xcf& b) {
328 return Packet2Xcf(pandnot<Packet2Xf>(a.v, b.v));
332EIGEN_STRONG_INLINE Packet2Xcf pnot<Packet2Xcf>(
const Packet2Xcf& a) {
333 return Packet2Xcf(pnot<Packet2Xf>(a.v));
337EIGEN_STRONG_INLINE Packet2Xcf pload<Packet2Xcf>(
const std::complex<float>* from) {
338 Packet2Xf res = pload<Packet2Xf>(
reinterpret_cast<const float*
>(from));
339 EIGEN_DEBUG_ALIGNED_LOAD
return Packet2Xcf(res);
343EIGEN_STRONG_INLINE Packet2Xcf ploadu<Packet2Xcf>(
const std::complex<float>* from) {
344 Packet2Xf res = ploadu<Packet2Xf>(
reinterpret_cast<const float*
>(from));
345 EIGEN_DEBUG_UNALIGNED_LOAD
return Packet2Xcf(res);
349EIGEN_STRONG_INLINE Packet2Xcf ploaddup<Packet2Xcf>(
const std::complex<float>* from) {
350 Packet2Xl res = ploaddup<Packet2Xl>(
reinterpret_cast<const numext::int64_t*
>(
reinterpret_cast<const void*
>(from)));
351 return Packet2Xcf(__riscv_vreinterpret_v_i64m2_f32m2(res));
355EIGEN_STRONG_INLINE Packet2Xcf ploadquad<Packet2Xcf>(
const std::complex<float>* from) {
356 Packet2Xl res = ploadquad<Packet2Xl>(
reinterpret_cast<const numext::int64_t*
>(
reinterpret_cast<const void*
>(from)));
357 return Packet2Xcf(__riscv_vreinterpret_v_i64m2_f32m2(res));
361EIGEN_STRONG_INLINE
void pstore<std::complex<float>>(std::complex<float>* to,
const Packet2Xcf& from) {
362 EIGEN_DEBUG_ALIGNED_STORE pstore<float>(
reinterpret_cast<float*
>(to), from.v);
366EIGEN_STRONG_INLINE
void pstoreu<std::complex<float>>(std::complex<float>* to,
const Packet2Xcf& from) {
367 EIGEN_DEBUG_UNALIGNED_STORE pstoreu<float>(
reinterpret_cast<float*
>(to), from.v);
371EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet2Xcf
372pgather<std::complex<float>, Packet2Xcf>(
const std::complex<float>* from, Index stride) {
373 return Packet2Xcf(__riscv_vreinterpret_v_i64m2_f32m2(pgather<int64_t, Packet2Xl>(
374 reinterpret_cast<const numext::int64_t*
>(
reinterpret_cast<const void*
>(from)), stride)));
378EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
void pscatter<std::complex<float>, Packet2Xcf>(std::complex<float>* to,
379 const Packet2Xcf& from,
381 pscatter<int64_t, Packet2Xl>(
reinterpret_cast<numext::int64_t*
>(
reinterpret_cast<void*
>(to)),
382 __riscv_vreinterpret_v_f32m2_i64m2(from.v), stride);
386EIGEN_STRONG_INLINE std::complex<float> pfirst<Packet2Xcf>(
const Packet2Xcf& a) {
387 numext::int64_t res = pfirst<Packet2Xl>(__riscv_vreinterpret_v_f32m2_i64m2(a.v));
388 return numext::bit_cast<std::complex<float>>(res);
392EIGEN_STRONG_INLINE Packet2Xcf preverse(
const Packet2Xcf& a) {
393 return Packet2Xcf(__riscv_vreinterpret_v_i64m2_f32m2(preverse<Packet2Xl>(__riscv_vreinterpret_v_f32m2_i64m2(a.v))));
397EIGEN_STRONG_INLINE std::complex<float> predux<Packet2Xcf>(
const Packet2Xcf& a) {
398 Packet2Xl res = __riscv_vreinterpret_v_f32m2_i64m2(a.v);
399 Packet2Xf real = __riscv_vreinterpret_v_i64m2_f32m2(
400 __riscv_vand_vx_i64m2(res, 0x00000000ffffffffull, unpacket_traits<Packet2Xl>::size));
401 Packet2Xf imag = __riscv_vreinterpret_v_i64m2_f32m2(
402 __riscv_vand_vx_i64m2(res, 0xffffffff00000000ull, unpacket_traits<Packet2Xl>::size));
403 return std::complex<float>(predux<Packet2Xf>(real), predux<Packet2Xf>(imag));
407EIGEN_STRONG_INLINE Packet2Xcf pdiv<Packet2Xcf>(
const Packet2Xcf& a,
const Packet2Xcf& b) {
408 return pdiv_complex(a, b);
412EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
void ptranspose(PacketBlock<Packet2Xcf, N>& kernel) {
413 numext::int64_t buffer[unpacket_traits<Packet2Xl>::size * N] = {0};
416 for (i = 0; i < N; i++) {
417 __riscv_vsse64(&buffer[i], N *
sizeof(numext::int64_t), __riscv_vreinterpret_v_f32m2_i64m2(kernel.packet[i].v),
418 unpacket_traits<Packet2Xl>::size);
420 for (i = 0; i < N; i++) {
421 kernel.packet[i] = Packet2Xcf(__riscv_vreinterpret_v_i64m2_f32m2(
422 __riscv_vle64_v_i64m2(&buffer[i * unpacket_traits<Packet2Xl>::size], unpacket_traits<Packet2Xl>::size)));
427EIGEN_STRONG_INLINE Packet2Xcf psqrt<Packet2Xcf>(
const Packet2Xcf& a) {
428 return psqrt_complex(a);
432EIGEN_STRONG_INLINE Packet2Xcf plog<Packet2Xcf>(
const Packet2Xcf& a) {
433 return plog_complex(a);
437EIGEN_STRONG_INLINE Packet2Xcf pexp<Packet2Xcf>(
const Packet2Xcf& a) {
438 return pexp_complex(a);
441template <
typename Packet = Packet2Xcf>
442EIGEN_STRONG_INLINE Packet1Xcf predux_half(
const Packet2Xcf& a) {
443 return Packet1Xcf(__riscv_vfadd_vv_f32m1(__riscv_vget_v_f32m2_f32m1(a.v, 0), __riscv_vget_v_f32m2_f32m1(a.v, 1),
444 unpacket_traits<Packet1Xf>::size));
447EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(Packet2Xcf, Packet2Xf)
451typedef complex_packet_wrapper<Packet2Xd, 32> Packet2Xcd;
452typedef complex_packet_wrapper<Packet4Xd, 33> Packet4Xcd;
453typedef complex_packet_wrapper<Packet1Xd, 34> Packet1Xcd;
455#if EIGEN_RISCV64_DEFAULT_LMUL == 1
456typedef Packet1Xcd PacketXcd;
459struct packet_traits<std::complex<double>> : default_packet_traits {
460 typedef Packet1Xcd type;
461 typedef Packet1Xcd half;
465 size = rvv_packet_size_selector<std::complex<double>, EIGEN_RISCV64_RVV_VL, 1>::size,
485#elif EIGEN_RISCV64_DEFAULT_LMUL == 2
486typedef Packet2Xcd PacketXcd;
489struct packet_traits<std::complex<double>> : default_packet_traits {
490 typedef Packet2Xcd type;
491#ifndef USE_LMUL2_ONLY
492 typedef Packet1Xcd half;
494 typedef Packet2Xcd half;
499 size = rvv_packet_size_selector<std::complex<double>, EIGEN_RISCV64_RVV_VL, 2>::size,
519#elif EIGEN_RISCV64_DEFAULT_LMUL == 4
520typedef Packet4Xcd PacketXcd;
523struct packet_traits<std::complex<double>> : default_packet_traits {
524 typedef Packet4Xcd type;
525#ifndef USE_LMUL4_ONLY
526 typedef Packet2Xcd half;
528 typedef Packet4Xcd half;
533 size = rvv_packet_size_selector<std::complex<double>, EIGEN_RISCV64_RVV_VL, 4>::size,
556struct unpacket_traits<Packet2Xcd> : default_unpacket_traits {
557 typedef std::complex<double> type;
558#ifndef USE_LMUL2_ONLY
559 typedef Packet1Xcd half;
561 typedef Packet2Xcd half;
563 typedef Packet2Xd as_real;
565 size = rvv_packet_size_selector<std::complex<double>, EIGEN_RISCV64_RVV_VL, 2>::size,
566 alignment = rvv_packet_alignment_selector<EIGEN_RISCV64_RVV_VL, 2>::alignment,
568 masked_load_available =
false,
569 masked_store_available =
false
574struct unpacket_traits<Packet4Xcd> : default_unpacket_traits {
575 typedef std::complex<double> type;
576#ifndef USE_LMUL4_ONLY
577 typedef Packet2Xcd half;
579 typedef Packet4Xcd half;
581 typedef Packet4Xd as_real;
583 size = rvv_packet_size_selector<std::complex<double>, EIGEN_RISCV64_RVV_VL, 4>::size,
584 alignment = rvv_packet_alignment_selector<EIGEN_RISCV64_RVV_VL, 4>::alignment,
586 masked_load_available =
false,
587 masked_store_available =
false
592struct unpacket_traits<Packet1Xcd> : default_unpacket_traits {
593 typedef std::complex<double> type;
594 typedef Packet1Xcd half;
595 typedef Packet1Xd as_real;
597 size = rvv_packet_size_selector<std::complex<double>, EIGEN_RISCV64_RVV_VL, 1>::size,
598 alignment = rvv_packet_alignment_selector<EIGEN_RISCV64_RVV_VL, 1>::alignment,
600 masked_load_available =
false,
601 masked_store_available =
false
606EIGEN_STRONG_INLINE Packet2Xcd pcast<Packet2Xd, Packet2Xcd>(
const Packet2Xd& a) {
607 return Packet2Xcd(a);
611EIGEN_STRONG_INLINE Packet2Xd pcast<Packet2Xcd, Packet2Xd>(
const Packet2Xcd& a) {
615EIGEN_STRONG_INLINE
void prealimag2(
const Packet2Xcd& a, Packet2Xd& real, Packet2Xd& imag) {
616 const PacketMask32 mask =
617 __riscv_vreinterpret_v_i8m1_b32(__riscv_vmv_v_x_i8m1(
static_cast<char>(0xaa), unpacket_traits<Packet1Xc>::size));
618 real = __riscv_vfslide1up_vf_f64m2_tumu(mask, a.v, a.v, 0.0, unpacket_traits<Packet2Xd>::size);
619 imag = __riscv_vfslide1down_vf_f64m2_tumu(__riscv_vmnot_m_b32(mask, unpacket_traits<Packet1Xi>::size), a.v, a.v, 0.0,
620 unpacket_traits<Packet2Xd>::size);
624EIGEN_STRONG_INLINE Packet2Xcd pset1<Packet2Xcd>(
const std::complex<double>& from) {
625 const PacketMask32 mask =
626 __riscv_vreinterpret_v_i8m1_b32(__riscv_vmv_v_x_i8m1(
static_cast<char>(0xaa), unpacket_traits<Packet1Xc>::size));
627 Packet2Xd res = __riscv_vmerge_vvm_f64m2(pset1<Packet2Xd>(from.real()), pset1<Packet2Xd>(from.imag()), mask,
628 unpacket_traits<Packet2Xd>::size);
629 return Packet2Xcd(res);
633EIGEN_STRONG_INLINE Packet2Xcd padd<Packet2Xcd>(
const Packet2Xcd& a,
const Packet2Xcd& b) {
634 return Packet2Xcd(padd<Packet2Xd>(a.v, b.v));
638EIGEN_STRONG_INLINE Packet2Xcd psub<Packet2Xcd>(
const Packet2Xcd& a,
const Packet2Xcd& b) {
639 return Packet2Xcd(psub<Packet2Xd>(a.v, b.v));
643EIGEN_STRONG_INLINE Packet2Xcd pnegate(
const Packet2Xcd& a) {
644 return Packet2Xcd(pnegate<Packet2Xd>(a.v));
648EIGEN_STRONG_INLINE Packet2Xcd pconj(
const Packet2Xcd& a) {
649 const PacketMask32 mask =
650 __riscv_vreinterpret_v_i8m1_b32(__riscv_vmv_v_x_i8m1(
static_cast<char>(0xaa), unpacket_traits<Packet1Xc>::size));
651 return Packet2Xcd(__riscv_vfsgnjn_vv_f64m2_tumu(mask, a.v, a.v, a.v, unpacket_traits<Packet2Xd>::size));
655EIGEN_STRONG_INLINE Packet2Xcd pcplxflip<Packet2Xcd>(
const Packet2Xcd& a) {
656 Packet2Xul res = __riscv_vreinterpret_v_f64m2_u64m2(a.v);
657 const PacketMask32 mask =
658 __riscv_vreinterpret_v_i8m1_b32(__riscv_vmv_v_x_i8m1(
static_cast<char>(0xaa), unpacket_traits<Packet1Xc>::size));
659 Packet2Xul data = __riscv_vslide1down_vx_u64m2(res, 0, unpacket_traits<Packet2Xl>::size);
660 Packet2Xd res2 = __riscv_vreinterpret_v_u64m2_f64m2(
661 __riscv_vslide1up_vx_u64m2_tumu(mask, data, res, 0, unpacket_traits<Packet2Xl>::size));
662 return Packet2Xcd(res2);
666EIGEN_STRONG_INLINE Packet2Xcd pmul<Packet2Xcd>(
const Packet2Xcd& a,
const Packet2Xcd& b) {
667 Packet2Xd real, imag;
668 prealimag2(a, real, imag);
669 return Packet2Xcd(pmadd<Packet2Xd>(imag, pcplxflip<Packet2Xcd>(pconj<Packet2Xcd>(b)).v, pmul<Packet2Xd>(real, b.v)));
673EIGEN_STRONG_INLINE Packet2Xcd pmadd<Packet2Xcd>(
const Packet2Xcd& a,
const Packet2Xcd& b,
const Packet2Xcd& c) {
674 Packet2Xd real, imag;
675 prealimag2(a, real, imag);
677 pmadd<Packet2Xd>(imag, pcplxflip<Packet2Xcd>(pconj<Packet2Xcd>(b)).v, pmadd<Packet2Xd>(real, b.v, c.v)));
681EIGEN_STRONG_INLINE Packet2Xcd pmsub<Packet2Xcd>(
const Packet2Xcd& a,
const Packet2Xcd& b,
const Packet2Xcd& c) {
682 Packet2Xd real, imag;
683 prealimag2(a, real, imag);
685 pmadd<Packet2Xd>(imag, pcplxflip<Packet2Xcd>(pconj<Packet2Xcd>(b)).v, pmsub<Packet2Xd>(real, b.v, c.v)));
689EIGEN_STRONG_INLINE Packet2Xcd pcmp_eq(
const Packet2Xcd& a,
const Packet2Xcd& b) {
690 Packet2Xl c = __riscv_vundefined_i64m2();
692 __riscv_vreinterpret_v_b32_u32m1(__riscv_vmfeq_vv_f64m2_b32(a.v, b.v, unpacket_traits<Packet2Xd>::size));
693 Packet1Xu mask_r = __riscv_vsrl_vx_u32m1(__riscv_vand_vx_u32m1(mask, 0xaaaaaaaa, unpacket_traits<Packet1Xi>::size), 1,
694 unpacket_traits<Packet1Xi>::size);
695 mask = __riscv_vand_vv_u32m1(mask, mask_r, unpacket_traits<Packet1Xi>::size);
696 mask = __riscv_vor_vv_u32m1(__riscv_vsll_vx_u32m1(mask, 1, unpacket_traits<Packet1Xi>::size), mask,
697 unpacket_traits<Packet1Xi>::size);
698 Packet2Xd res = __riscv_vreinterpret_v_i64m2_f64m2(__riscv_vmerge_vvm_i64m2(pzero<Packet2Xl>(c), ptrue<Packet2Xl>(c),
699 __riscv_vreinterpret_v_u32m1_b32(mask),
700 unpacket_traits<Packet2Xl>::size));
701 return Packet2Xcd(res);
705EIGEN_STRONG_INLINE Packet2Xcd pand<Packet2Xcd>(
const Packet2Xcd& a,
const Packet2Xcd& b) {
706 return Packet2Xcd(pand<Packet2Xd>(a.v, b.v));
710EIGEN_STRONG_INLINE Packet2Xcd por<Packet2Xcd>(
const Packet2Xcd& a,
const Packet2Xcd& b) {
711 return Packet2Xcd(por<Packet2Xd>(a.v, b.v));
715EIGEN_STRONG_INLINE Packet2Xcd pxor<Packet2Xcd>(
const Packet2Xcd& a,
const Packet2Xcd& b) {
716 return Packet2Xcd(pxor<Packet2Xd>(a.v, b.v));
720EIGEN_STRONG_INLINE Packet2Xcd pandnot<Packet2Xcd>(
const Packet2Xcd& a,
const Packet2Xcd& b) {
721 return Packet2Xcd(pandnot<Packet2Xd>(a.v, b.v));
725EIGEN_STRONG_INLINE Packet2Xcd pnot<Packet2Xcd>(
const Packet2Xcd& a) {
726 return Packet2Xcd(pnot<Packet2Xd>(a.v));
730EIGEN_STRONG_INLINE Packet2Xcd pload<Packet2Xcd>(
const std::complex<double>* from) {
731 Packet2Xd res = pload<Packet2Xd>(
reinterpret_cast<const double*
>(from));
732 EIGEN_DEBUG_ALIGNED_LOAD
return Packet2Xcd(res);
736EIGEN_STRONG_INLINE Packet2Xcd ploadu<Packet2Xcd>(
const std::complex<double>* from) {
737 Packet2Xd res = ploadu<Packet2Xd>(
reinterpret_cast<const double*
>(from));
738 EIGEN_DEBUG_UNALIGNED_LOAD
return Packet2Xcd(res);
742EIGEN_STRONG_INLINE Packet2Xcd ploaddup<Packet2Xcd>(
const std::complex<double>* from) {
743 const PacketMask32 mask =
744 __riscv_vreinterpret_v_i8m1_b32(__riscv_vmv_v_x_i8m1(
static_cast<char>(0x66), unpacket_traits<Packet1Xc>::size));
746 __riscv_vsrl_vx_u64m2(__riscv_vid_v_u64m2(unpacket_traits<Packet2Xd>::size), 1, unpacket_traits<Packet2Xd>::size);
747 Packet2Xul idx2 = __riscv_vxor_vx_u64m2_tumu(mask, idx1, idx1, 1, unpacket_traits<Packet2Xl>::size);
748 return Packet2Xcd(__riscv_vrgather_vv_f64m2(
749 __riscv_vlmul_ext_v_f64m1_f64m2(pload<Packet1Xd>(
reinterpret_cast<const double*
>(from))), idx2,
750 unpacket_traits<Packet2Xd>::size));
754EIGEN_STRONG_INLINE Packet2Xcd ploadquad<Packet2Xcd>(
const std::complex<double>* from) {
755 const PacketMask32 mask =
756 __riscv_vreinterpret_v_i8m1_b32(__riscv_vmv_v_x_i8m1(
static_cast<char>(0x5a), unpacket_traits<Packet1Xc>::size));
758 __riscv_vsrl_vx_u64m2(__riscv_vid_v_u64m2(unpacket_traits<Packet2Xd>::size), 2, unpacket_traits<Packet2Xd>::size);
759 Packet2Xul idx2 = __riscv_vxor_vx_u64m2_tumu(mask, idx1, idx1, 1, unpacket_traits<Packet2Xl>::size);
760 return Packet2Xcd(__riscv_vrgather_vv_f64m2(
761 __riscv_vlmul_ext_v_f64m1_f64m2(pload<Packet1Xd>(
reinterpret_cast<const double*
>(from))), idx2,
762 unpacket_traits<Packet2Xd>::size));
766EIGEN_STRONG_INLINE
void pstore<std::complex<double>>(std::complex<double>* to,
const Packet2Xcd& from) {
767 EIGEN_DEBUG_ALIGNED_STORE pstore<double>(
reinterpret_cast<double*
>(to), from.v);
771EIGEN_STRONG_INLINE
void pstoreu<std::complex<double>>(std::complex<double>* to,
const Packet2Xcd& from) {
772 EIGEN_DEBUG_UNALIGNED_STORE pstoreu<double>(
reinterpret_cast<double*
>(to), from.v);
776EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet2Xcd
777pgather<std::complex<double>, Packet2Xcd>(
const std::complex<double>* from, Index stride) {
778 const PacketMask32 mask =
779 __riscv_vreinterpret_v_i8m1_b32(__riscv_vmv_v_x_i8m1(
static_cast<char>(0x55), unpacket_traits<Packet1Xc>::size));
780 const double* from2 =
reinterpret_cast<const double*
>(from);
781 Packet2Xd res = __riscv_vundefined_f64m2();
782 res = __riscv_vlse64_v_f64m2_tumu(mask, res, &from2[0 - (0 * stride)], stride *
sizeof(
double),
783 unpacket_traits<Packet2Xd>::size);
785 __riscv_vlse64_v_f64m2_tumu(__riscv_vmnot_m_b32(mask, unpacket_traits<Packet1Xi>::size), res,
786 &from2[1 - (1 * stride)], stride *
sizeof(
double), unpacket_traits<Packet2Xd>::size);
787 return Packet2Xcd(res);
791EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
void pscatter<std::complex<double>, Packet2Xcd>(std::complex<double>* to,
792 const Packet2Xcd& from,
794 const PacketMask32 mask =
795 __riscv_vreinterpret_v_i8m1_b32(__riscv_vmv_v_x_i8m1(
static_cast<char>(0x55), unpacket_traits<Packet1Xc>::size));
796 double* to2 =
reinterpret_cast<double*
>(to);
797 __riscv_vsse64_v_f64m2_m(mask, &to2[0 - (0 * stride)], stride *
sizeof(
double), from.v,
798 unpacket_traits<Packet2Xd>::size);
799 __riscv_vsse64_v_f64m2_m(__riscv_vmnot_m_b32(mask, unpacket_traits<Packet1Xi>::size), &to2[1 - (1 * stride)],
800 stride *
sizeof(
double), from.v, unpacket_traits<Packet2Xd>::size);
804EIGEN_STRONG_INLINE std::complex<double> pfirst<Packet2Xcd>(
const Packet2Xcd& a) {
805 double real = pfirst<Packet2Xd>(a.v);
806 double imag = pfirst<Packet2Xd>(__riscv_vfslide1down_vf_f64m2(a.v, 0.0, unpacket_traits<Packet2Xd>::size));
807 return std::complex<double>(real, imag);
811EIGEN_STRONG_INLINE Packet2Xcd preverse(
const Packet2Xcd& a) {
812 Packet2Xul idx = __riscv_vxor_vx_u64m2(__riscv_vid_v_u64m2(unpacket_traits<Packet2Xl>::size),
813 unpacket_traits<Packet2Xl>::size - 2, unpacket_traits<Packet2Xl>::size);
814 Packet2Xd res = __riscv_vrgather_vv_f64m2(a.v, idx, unpacket_traits<Packet2Xd>::size);
815 return Packet2Xcd(res);
819EIGEN_STRONG_INLINE std::complex<double> predux<Packet2Xcd>(
const Packet2Xcd& a) {
820 const PacketMask32 mask =
821 __riscv_vreinterpret_v_i8m1_b32(__riscv_vmv_v_x_i8m1(
static_cast<char>(0xaa), unpacket_traits<Packet1Xc>::size));
822 Packet2Xl res = __riscv_vreinterpret_v_f64m2_i64m2(a.v);
823 Packet2Xd real = __riscv_vreinterpret_v_i64m2_f64m2(
824 __riscv_vand_vx_i64m2_tumu(mask, res, res, 0, unpacket_traits<Packet2Xl>::size));
825 Packet2Xd imag = __riscv_vreinterpret_v_i64m2_f64m2(__riscv_vand_vx_i64m2_tumu(
826 __riscv_vmnot_m_b32(mask, unpacket_traits<Packet1Xi>::size), res, res, 0, unpacket_traits<Packet2Xl>::size));
827 return std::complex<double>(predux<Packet2Xd>(real), predux<Packet2Xd>(imag));
831EIGEN_STRONG_INLINE Packet2Xcd pdiv<Packet2Xcd>(
const Packet2Xcd& a,
const Packet2Xcd& b) {
832 return pdiv_complex(a, b);
836EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
void ptranspose(PacketBlock<Packet2Xcd, N>& kernel) {
837 double buffer[unpacket_traits<Packet2Xd>::size * N];
840 const PacketMask32 mask =
841 __riscv_vreinterpret_v_i8m1_b32(__riscv_vmv_v_x_i8m1(
static_cast<char>(0x55), unpacket_traits<Packet1Xc>::size));
843 for (i = 0; i < N; i++) {
844 __riscv_vsse64_v_f64m2_m(mask, &buffer[(i * 2) - (0 * N) + 0], N *
sizeof(
double), kernel.packet[i].v,
845 unpacket_traits<Packet2Xd>::size);
846 __riscv_vsse64_v_f64m2_m(__riscv_vmnot_m_b32(mask, unpacket_traits<Packet1Xi>::size),
847 &buffer[(i * 2) - (1 * N) + 1], N *
sizeof(
double), kernel.packet[i].v,
848 unpacket_traits<Packet2Xd>::size);
851 for (i = 0; i < N; i++) {
852 kernel.packet[i] = Packet2Xcd(
853 __riscv_vle64_v_f64m2(&buffer[i * unpacket_traits<Packet2Xd>::size], unpacket_traits<Packet2Xd>::size));
858EIGEN_STRONG_INLINE Packet2Xcd psqrt<Packet2Xcd>(
const Packet2Xcd& a) {
859 return psqrt_complex(a);
863EIGEN_STRONG_INLINE Packet2Xcd plog<Packet2Xcd>(
const Packet2Xcd& a) {
864 return plog_complex(a);
868EIGEN_STRONG_INLINE Packet2Xcd pexp<Packet2Xcd>(
const Packet2Xcd& a) {
869 return pexp_complex(a);
872template <
typename Packet = Packet2Xcd>
873EIGEN_STRONG_INLINE Packet1Xcd predux_half(
const Packet2Xcd& a) {
874 return Packet1Xcd(__riscv_vfadd_vv_f64m1(__riscv_vget_v_f64m2_f64m1(a.v, 0), __riscv_vget_v_f64m2_f64m1(a.v, 1),
875 unpacket_traits<Packet1Xd>::size));
878EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(Packet2Xcd, Packet2Xd)
880EIGEN_GCC_FAST_MATH_COMPLEX_VECTORIZE_WORKAROUND_POP