12#ifndef EIGEN_RVV10_GENERAL_BLOCK_KERNEL_H
13#define EIGEN_RVV10_GENERAL_BLOCK_KERNEL_H
16#include "../../InternalHeaderCheck.h"
24struct gebp_traits<float, float, false, false, Architecture::RVV10, GEBPPacketFull>
25 : gebp_traits<float, float, false, false, Architecture::Generic, GEBPPacketFull> {
26 typedef float RhsPacket;
27 typedef QuadPacket<float> RhsPacketx4;
28 EIGEN_STRONG_INLINE
void loadRhs(
const RhsScalar* b, RhsPacket& dest)
const { dest = pset1<RhsPacket>(*b); }
29 EIGEN_STRONG_INLINE
void loadRhs(
const RhsScalar* b, RhsPacketx4& dest)
const {
30 pbroadcast4(b, dest.B_0, dest.B1, dest.B2, dest.B3);
33 EIGEN_STRONG_INLINE
void updateRhs(
const RhsScalar* b, RhsPacket& dest)
const { loadRhs(b, dest); }
35 EIGEN_STRONG_INLINE
void updateRhs(
const RhsScalar*, RhsPacketx4&)
const {}
37 EIGEN_STRONG_INLINE
void loadRhsQuad(
const RhsScalar* b, RhsPacket& dest)
const { dest = ploadquad<RhsPacket>(b); }
39 EIGEN_STRONG_INLINE
void madd(
const LhsPacket& a,
const RhsPacket& b, AccPacket& c, RhsPacket& ,
40 const FixedInt<0>&)
const {
41#if EIGEN_RISCV64_DEFAULT_LMUL == 1
42 c = __riscv_vfmadd_vf_f32m1(a, b, c, unpacket_traits<AccPacket>::size);
43#elif EIGEN_RISCV64_DEFAULT_LMUL == 2
44 c = __riscv_vfmadd_vf_f32m2(a, b, c, unpacket_traits<AccPacket>::size);
45#elif EIGEN_RISCV64_DEFAULT_LMUL == 4
46 c = __riscv_vfmadd_vf_f32m4(a, b, c, unpacket_traits<AccPacket>::size);
50#if EIGEN_RISCV64_DEFAULT_LMUL >= 2
51 EIGEN_STRONG_INLINE
void madd(
const Packet1Xf& a,
const RhsPacket& b, Packet1Xf& c, RhsPacket& ,
52 const FixedInt<0>&)
const {
53 c = __riscv_vfmadd_vf_f32m1(a, b, c, unpacket_traits<Packet1Xf>::size);
56#if EIGEN_RISCV64_DEFAULT_LMUL == 4
57 EIGEN_STRONG_INLINE
void madd(
const Packet2Xf& a,
const RhsPacket& b, Packet2Xf& c, RhsPacket& ,
58 const FixedInt<0>&)
const {
59 c = __riscv_vfmadd_vf_f32m2(a, b, c, unpacket_traits<Packet2Xf>::size);
63 template <
typename LaneIdType>
64 EIGEN_STRONG_INLINE
void madd(
const LhsPacket& a,
const RhsPacketx4& b, AccPacket& c, RhsPacket& ,
65 const LaneIdType& lane)
const {
66#if EIGEN_RISCV64_DEFAULT_LMUL == 1
67 c = __riscv_vfmadd_vf_f32m1(a, b.get(lane), c, unpacket_traits<AccPacket>::size);
68#elif EIGEN_RISCV64_DEFAULT_LMUL == 2
69 c = __riscv_vfmadd_vf_f32m2(a, b.get(lane), c, unpacket_traits<AccPacket>::size);
70#elif EIGEN_RISCV64_DEFAULT_LMUL == 4
71 c = __riscv_vfmadd_vf_f32m4(a, b.get(lane), c, unpacket_traits<AccPacket>::size);
77struct gebp_traits<double, double, false, false, Architecture::RVV10, GEBPPacketFull>
78 : gebp_traits<double, double, false, false, Architecture::Generic, GEBPPacketFull> {
79 typedef double RhsPacket;
80 typedef QuadPacket<double> RhsPacketx4;
81 EIGEN_STRONG_INLINE
void loadRhs(
const RhsScalar* b, RhsPacket& dest)
const { dest = pset1<RhsPacket>(*b); }
82 EIGEN_STRONG_INLINE
void loadRhs(
const RhsScalar* b, RhsPacketx4& dest)
const {
83 pbroadcast4(b, dest.B_0, dest.B1, dest.B2, dest.B3);
86 EIGEN_STRONG_INLINE
void updateRhs(
const RhsScalar* b, RhsPacket& dest)
const { loadRhs(b, dest); }
88 EIGEN_STRONG_INLINE
void updateRhs(
const RhsScalar*, RhsPacketx4&)
const {}
90 EIGEN_STRONG_INLINE
void loadRhsQuad(
const RhsScalar* b, RhsPacket& dest)
const { dest = ploadquad<RhsPacket>(b); }
92 EIGEN_STRONG_INLINE
void madd(
const LhsPacket& a,
const RhsPacket& b, AccPacket& c, RhsPacket& ,
93 const FixedInt<0>&)
const {
94#if EIGEN_RISCV64_DEFAULT_LMUL == 1
95 c = __riscv_vfmadd_vf_f64m1(a, b, c, unpacket_traits<AccPacket>::size);
96#elif EIGEN_RISCV64_DEFAULT_LMUL == 2
97 c = __riscv_vfmadd_vf_f64m2(a, b, c, unpacket_traits<AccPacket>::size);
98#elif EIGEN_RISCV64_DEFAULT_LMUL == 4
99 c = __riscv_vfmadd_vf_f64m4(a, b, c, unpacket_traits<AccPacket>::size);
103#if EIGEN_RISCV64_DEFAULT_LMUL >= 2
104 EIGEN_STRONG_INLINE
void madd(
const Packet1Xd& a,
const RhsPacket& b, Packet1Xd& c, RhsPacket& ,
105 const FixedInt<0>&)
const {
106 c = __riscv_vfmadd_vf_f64m1(a, b, c, unpacket_traits<Packet1Xd>::size);
109#if EIGEN_RISCV64_DEFAULT_LMUL == 4
110 EIGEN_STRONG_INLINE
void madd(
const Packet2Xd& a,
const RhsPacket& b, Packet2Xd& c, RhsPacket& ,
111 const FixedInt<0>&)
const {
112 c = __riscv_vfmadd_vf_f64m2(a, b, c, unpacket_traits<Packet2Xd>::size);
116 template <
typename LaneIdType>
117 EIGEN_STRONG_INLINE
void madd(
const LhsPacket& a,
const RhsPacketx4& b, AccPacket& c, RhsPacket& ,
118 const LaneIdType& lane)
const {
119#if EIGEN_RISCV64_DEFAULT_LMUL == 1
120 c = __riscv_vfmadd_vf_f64m1(a, b.get(lane), c, unpacket_traits<AccPacket>::size);
121#elif EIGEN_RISCV64_DEFAULT_LMUL == 2
122 c = __riscv_vfmadd_vf_f64m2(a, b.get(lane), c, unpacket_traits<AccPacket>::size);
123#elif EIGEN_RISCV64_DEFAULT_LMUL == 4
124 c = __riscv_vfmadd_vf_f64m4(a, b.get(lane), c, unpacket_traits<AccPacket>::size);
129#if defined(EIGEN_VECTORIZE_RVV10FP16)
132struct gebp_traits<half, half, false, false, Architecture::RVV10>
133 : gebp_traits<half, half, false, false, Architecture::Generic> {
134 typedef half RhsPacket;
135 typedef PacketXh LhsPacket;
136 typedef PacketXh AccPacket;
137 typedef QuadPacket<half> RhsPacketx4;
139 EIGEN_STRONG_INLINE
void loadRhs(
const RhsScalar* b, RhsPacket& dest)
const { dest = pset1<RhsPacket>(*b); }
140 EIGEN_STRONG_INLINE
void loadRhs(
const RhsScalar* b, RhsPacketx4& dest)
const {
141 pbroadcast4(b, dest.B_0, dest.B1, dest.B2, dest.B3);
144 EIGEN_STRONG_INLINE
void updateRhs(
const RhsScalar* b, RhsPacket& dest)
const { loadRhs(b, dest); }
146 EIGEN_STRONG_INLINE
void updateRhs(
const RhsScalar*, RhsPacketx4&)
const {}
148 EIGEN_STRONG_INLINE
void loadRhsQuad(
const RhsScalar* b, RhsPacket& dest)
const { dest = pload<RhsPacket>(b); }
150 EIGEN_STRONG_INLINE
void madd(
const LhsPacket& a,
const RhsPacket& b, AccPacket& c, RhsPacket& ,
151 const FixedInt<0>&)
const {
152#if EIGEN_RISCV64_DEFAULT_LMUL == 1
153 c = __riscv_vfmadd_vf_f16m1(a, numext::bit_cast<_Float16>(b), c, unpacket_traits<AccPacket>::size);
155 c = __riscv_vfmadd_vf_f16m2(a, numext::bit_cast<_Float16>(b), c, unpacket_traits<AccPacket>::size);
159#if EIGEN_RISCV64_DEFAULT_LMUL >= 2
160 EIGEN_STRONG_INLINE
void madd(
const Packet1Xh& a,
const RhsPacket& b, Packet1Xh& c, RhsPacket& ,
161 const FixedInt<0>&)
const {
162 c = __riscv_vfmadd_vf_f16m1(a, numext::bit_cast<_Float16>(b), c, unpacket_traits<Packet1Xh>::size);
166 template <
typename LaneIdType>
167 EIGEN_STRONG_INLINE
void madd(
const LhsPacket& a,
const RhsPacketx4& b, AccPacket& c, RhsPacket& ,
168 const LaneIdType& lane)
const {
169#if EIGEN_RISCV64_DEFAULT_LMUL == 1
170 c = __riscv_vfmadd_vf_f16m1(a, numext::bit_cast<_Float16>(b.get(lane)), c, unpacket_traits<AccPacket>::size);
172 c = __riscv_vfmadd_vf_f16m2(a, numext::bit_cast<_Float16>(b.get(lane)), c, unpacket_traits<AccPacket>::size);
179#if defined(EIGEN_VECTORIZE_RVV10BF16)
182struct gebp_traits<bfloat16, bfloat16, false, false, Architecture::RVV10>
183 : gebp_traits<bfloat16, bfloat16, false, false, Architecture::Generic> {
184 typedef bfloat16 RhsPacket;
185 typedef PacketXbf LhsPacket;
186 typedef PacketXbf AccPacket;
187 typedef QuadPacket<bfloat16> RhsPacketx4;
189 EIGEN_STRONG_INLINE
void loadRhs(
const RhsScalar* b, RhsPacket& dest)
const { dest = pset1<RhsPacket>(*b); }
190 EIGEN_STRONG_INLINE
void loadRhs(
const RhsScalar* b, RhsPacketx4& dest)
const {
191 pbroadcast4(b, dest.B_0, dest.B1, dest.B2, dest.B3);
194 EIGEN_STRONG_INLINE
void updateRhs(
const RhsScalar* b, RhsPacket& dest)
const { loadRhs(b, dest); }
196 EIGEN_STRONG_INLINE
void updateRhs(
const RhsScalar*, RhsPacketx4&)
const {}
198 EIGEN_STRONG_INLINE
void loadRhsQuad(
const RhsScalar* b, RhsPacket& dest)
const { dest = pload<RhsPacket>(b); }
200 EIGEN_STRONG_INLINE
void madd(
const LhsPacket& a,
const RhsPacket& b, AccPacket& c, RhsPacket& ,
201 const FixedInt<0>&)
const {
202#if EIGEN_RISCV64_DEFAULT_LMUL == 1
204 __riscv_vfwmaccbf16_vf_f32m2(Bf16ToF32(c), numext::bit_cast<__bf16>(b), a, unpacket_traits<AccPacket>::size));
207 __riscv_vfwmaccbf16_vf_f32m4(Bf16ToF32(c), numext::bit_cast<__bf16>(b), a, unpacket_traits<AccPacket>::size));
211#if EIGEN_RISCV64_DEFAULT_LMUL >= 2
212 EIGEN_STRONG_INLINE
void madd(
const Packet1Xbf& a,
const RhsPacket& b, Packet1Xbf& c, RhsPacket& ,
213 const FixedInt<0>&)
const {
215 __riscv_vfwmaccbf16_vf_f32m2(Bf16ToF32(c), numext::bit_cast<__bf16>(b), a, unpacket_traits<Packet1Xbf>::size));
219 template <
typename LaneIdType>
220 EIGEN_STRONG_INLINE
void madd(
const LhsPacket& a,
const RhsPacketx4& b, AccPacket& c, RhsPacket& ,
221 const LaneIdType& lane)
const {
222#if EIGEN_RISCV64_DEFAULT_LMUL == 1
223 c = F32ToBf16(__riscv_vfwmaccbf16_vf_f32m2(Bf16ToF32(c), numext::bit_cast<__bf16>(b.get(lane)), a,
224 unpacket_traits<AccPacket>::size));
226 c = F32ToBf16(__riscv_vfwmaccbf16_vf_f32m4(Bf16ToF32(c), numext::bit_cast<__bf16>(b.get(lane)), a,
227 unpacket_traits<AccPacket>::size));
234#if EIGEN_RISCV64_DEFAULT_LMUL == 1
237#define PACKET_DECL_COND_POSTFIX(postfix, name, packet_size) \
238 typedef typename packet_conditional< \
239 packet_size, typename packet_traits<name##Scalar>::type, typename packet_traits<name##Scalar>::half, \
240 typename unpacket_traits<typename packet_traits<name##Scalar>::half>::half>::type name##Packet##postfix
242#define RISCV_COMPLEX_PACKET_DECL_COND_SCALAR(packet_size) \
243 typedef typename packet_conditional< \
244 packet_size, typename packet_traits<Scalar>::type, typename packet_traits<Scalar>::half, \
245 typename unpacket_traits<typename packet_traits<Scalar>::half>::half>::type ScalarPacket
247template <
typename RealScalar,
bool ConjLhs_,
bool ConjRhs_,
int PacketSize_>
248struct gebp_traits<std::complex<RealScalar>, std::complex<RealScalar>, ConjLhs_, ConjRhs_, Architecture::RVV10,
249 PacketSize_> : gebp_traits<std::complex<RealScalar>, std::complex<RealScalar>, ConjLhs_, ConjRhs_,
250 Architecture::Generic, PacketSize_> {
251 typedef std::complex<RealScalar> Scalar;
252 typedef std::complex<RealScalar> LhsScalar;
253 typedef std::complex<RealScalar> RhsScalar;
254 typedef std::complex<RealScalar> ResScalar;
255 typedef typename packet_traits<std::complex<RealScalar>>::type RealPacket;
257 PACKET_DECL_COND_POSTFIX(_, Lhs, PacketSize_);
258 PACKET_DECL_COND_POSTFIX(_, Rhs, PacketSize_);
259 PACKET_DECL_COND_POSTFIX(_, Res, PacketSize_);
260 RISCV_COMPLEX_PACKET_DECL_COND_SCALAR(PacketSize_);
261#undef RISCV_COMPLEX_PACKET_DECL_COND_SCALAR
266 Vectorizable = unpacket_traits<RealPacket>::vectorizable && unpacket_traits<ScalarPacket>::vectorizable,
267 ResPacketSize = Vectorizable ? unpacket_traits<ResPacket_>::size : 1,
268 LhsPacketSize = Vectorizable ? unpacket_traits<LhsPacket_>::size : 1,
269 RhsPacketSize = Vectorizable ? unpacket_traits<RhsScalar>::size : 1,
270 RealPacketSize = Vectorizable ? unpacket_traits<RealPacket>::size : 1,
275 LhsProgress = ResPacketSize,
279 typedef DoublePacket<RealPacket> DoublePacketType;
281 typedef std::conditional_t<Vectorizable, ScalarPacket, Scalar> LhsPacket4Packing;
282 typedef std::conditional_t<Vectorizable, RealPacket, Scalar> LhsPacket;
283 typedef std::conditional_t<Vectorizable, DoublePacket<RealScalar>, Scalar> RhsPacket;
284 typedef std::conditional_t<Vectorizable, ScalarPacket, Scalar> ResPacket;
285 typedef std::conditional_t<Vectorizable, DoublePacketType, Scalar> AccPacket;
287 typedef QuadPacket<RhsPacket> RhsPacketx4;
289 EIGEN_STRONG_INLINE
void initAcc(Scalar& p) { p = Scalar(0); }
291 EIGEN_STRONG_INLINE
void initAcc(DoublePacketType& p) {
292 p.first = pset1<RealPacket>(RealScalar(0));
293 p.second = pset1<RealPacket>(RealScalar(0));
297 EIGEN_STRONG_INLINE
void loadRhs(
const RhsScalar* b, ScalarPacket& dest)
const { dest = pset1<ScalarPacket>(*b); }
300 template <
typename RealPacketType>
301 EIGEN_STRONG_INLINE
void loadRhs(
const RhsScalar* b, DoublePacket<RealPacketType>& dest)
const {
302 dest.first = pset1<RealPacketType>(numext::real(*b));
303 dest.second = pset1<RealPacketType>(numext::imag(*b));
306 EIGEN_STRONG_INLINE
void loadRhs(
const RhsScalar* b, RhsPacketx4& dest)
const {
307 loadRhs(b, dest.B_0);
308 loadRhs(b + 1, dest.B1);
309 loadRhs(b + 2, dest.B2);
310 loadRhs(b + 3, dest.B3);
314 EIGEN_STRONG_INLINE
void updateRhs(
const RhsScalar* b, ScalarPacket& dest)
const { loadRhs(b, dest); }
317 template <
typename RealPacketType>
318 EIGEN_STRONG_INLINE
void updateRhs(
const RhsScalar* b, DoublePacket<RealPacketType>& dest)
const {
322 EIGEN_STRONG_INLINE
void updateRhs(
const RhsScalar*, RhsPacketx4&)
const {}
324 EIGEN_STRONG_INLINE
void loadRhsQuad(
const RhsScalar* b, ResPacket& dest)
const { loadRhs(b, dest); }
325 EIGEN_STRONG_INLINE
void loadRhsQuad(
const RhsScalar* b, DoublePacket<RealScalar>& dest)
const {
326 loadQuadToDoublePacket(b, dest);
330 EIGEN_STRONG_INLINE
void loadLhs(
const LhsScalar* a, LhsPacket& dest)
const {
331 dest = pload<LhsPacket>((
const typename unpacket_traits<LhsPacket>::type*)(a));
334 template <
typename LhsPacketType>
335 EIGEN_STRONG_INLINE
void loadLhsUnaligned(
const LhsScalar* a, LhsPacketType& dest)
const {
336 dest = ploadu<LhsPacketType>((
const typename unpacket_traits<LhsPacketType>::type*)(a));
339 EIGEN_STRONG_INLINE Packet1Xcf pmadd_scalar(
const Packet1Xcf& a,
float b,
const Packet1Xcf& c)
const {
340 return Packet1Xcf(__riscv_vfmadd_vf_f32m1(a.v, b, c.v, unpacket_traits<Packet1Xf>::size));
343 EIGEN_STRONG_INLINE Packet1Xcd pmadd_scalar(
const Packet1Xcd& a,
double b,
const Packet1Xcd& c)
const {
344 return Packet1Xcd(__riscv_vfmadd_vf_f64m1(a.v, b, c.v, unpacket_traits<Packet1Xd>::size));
347#if EIGEN_RISCV64_DEFAULT_LMUL >= 2
348 EIGEN_STRONG_INLINE Packet2Xcf pmadd_scalar(
const Packet2Xcf& a,
float b,
const Packet2Xcf& c)
const {
349 return Packet2Xcf(__riscv_vfmadd_vf_f32m2(a.v, b, c.v, unpacket_traits<Packet2Xf>::size));
352 EIGEN_STRONG_INLINE Packet2Xcd pmadd_scalar(
const Packet2Xcd& a,
double b,
const Packet2Xcd& c)
const {
353 return Packet2Xcd(__riscv_vfmadd_vf_f64m2(a.v, b, c.v, unpacket_traits<Packet2Xd>::size));
357#if EIGEN_RISCV64_DEFAULT_LMUL == 4
358 EIGEN_STRONG_INLINE Packet4Xcf pmadd_scalar(
const Packet4Xcf& a,
float b,
const Packet4Xcf& c)
const {
359 return Packet4Xcf(__riscv_vfmadd_vf_f32m4(a.v, b, c.v, unpacket_traits<Packet4Xf>::size));
362 EIGEN_STRONG_INLINE Packet4Xcd pmadd_scalar(
const Packet4Xcd& a,
double b,
const Packet4Xcd& c)
const {
363 return Packet4Xcd(__riscv_vfmadd_vf_f64m4(a.v, b, c.v, unpacket_traits<Packet4Xd>::size));
367 template <
typename LhsPacketType,
typename RhsPacketType,
typename ResPacketType,
typename TmpType,
369 EIGEN_STRONG_INLINE std::enable_if_t<!is_same<RhsPacketType, RhsPacketx4>::value> madd(
const LhsPacketType& a,
370 const RhsPacketType& b,
371 DoublePacket<ResPacketType>& c,
373 const LaneIdType&)
const {
374 c.first = pmadd_scalar(a, b.first, c.first);
375 c.second = pmadd_scalar(a, b.second, c.second);
378 template <
typename LhsPacketType,
typename AccPacketType,
typename LaneIdType>
379 EIGEN_STRONG_INLINE
void madd(
const LhsPacketType& a,
const RhsPacketx4& b, AccPacketType& c, RhsPacket& tmp,
380 const LaneIdType& lane)
const {
381 madd(a, b.get(lane), c, tmp, lane);
384 template <
typename LaneIdType>
385 EIGEN_STRONG_INLINE
void madd(
const LhsPacket& a,
const RhsPacket& b, ResPacket& c, RhsPacket& ,
386 const LaneIdType&)
const {
387 c = cj.pmadd(a, b, c);
390 template <
typename RealPacketType,
typename ResPacketType>
391 EIGEN_STRONG_INLINE
void acc(
const DoublePacket<RealPacketType>& c,
const ResPacketType& alpha,
392 ResPacketType& r)
const {
395 EIGEN_IF_CONSTEXPR ((!ConjLhs) && (!ConjRhs)) {
396 tmp = pcplxflip(pconj(ResPacketType(c.second)));
397 tmp = padd(ResPacketType(c.first), tmp);
398 }
else EIGEN_IF_CONSTEXPR ((!ConjLhs) && (ConjRhs)) {
399 tmp = pconj(pcplxflip(ResPacketType(c.second)));
400 tmp = padd(ResPacketType(c.first), tmp);
401 }
else EIGEN_IF_CONSTEXPR ((ConjLhs) && (!ConjRhs)) {
402 tmp = pcplxflip(ResPacketType(c.second));
403 tmp = padd(pconj(ResPacketType(c.first)), tmp);
404 }
else EIGEN_IF_CONSTEXPR ((ConjLhs) && (ConjRhs)) {
405 tmp = pcplxflip(ResPacketType(c.second));
406 tmp = psub(pconj(ResPacketType(c.first)), tmp);
409 r = pmadd(tmp, alpha, r);
413 EIGEN_STRONG_INLINE
void acc(
const Scalar& c,
const Scalar& alpha, Scalar& r)
const { r += alpha * c; }
416 conj_helper<LhsScalar, RhsScalar, ConjLhs, ConjRhs> cj;
419#define PACKET_DECL_COND_SCALAR_POSTFIX(postfix, packet_size) \
420 typedef typename packet_conditional< \
421 packet_size, typename packet_traits<Scalar>::type, typename packet_traits<Scalar>::half, \
422 typename unpacket_traits<typename packet_traits<Scalar>::half>::half>::type ScalarPacket##postfix
424template <
typename RealScalar,
bool ConjRhs_,
int PacketSize_>
425class gebp_traits<RealScalar, std::complex<RealScalar>, false, ConjRhs_, Architecture::RVV10, PacketSize_>
426 :
public gebp_traits<RealScalar, std::complex<RealScalar>, false, ConjRhs_, Architecture::Generic, PacketSize_> {
428 typedef std::complex<RealScalar> Scalar;
429 typedef RealScalar LhsScalar;
430 typedef Scalar RhsScalar;
431 typedef Scalar ResScalar;
432 PACKET_DECL_COND_POSTFIX(_, Lhs, PacketSize_);
433 PACKET_DECL_COND_POSTFIX(_, Rhs, PacketSize_);
434 PACKET_DECL_COND_POSTFIX(_, Res, PacketSize_);
435 PACKET_DECL_COND_POSTFIX(_, Real, PacketSize_);
436 PACKET_DECL_COND_SCALAR_POSTFIX(_, PacketSize_);
437#undef PACKET_DECL_COND_SCALAR_POSTFIX
442 Vectorizable = unpacket_traits<RealPacket_>::vectorizable && unpacket_traits<ScalarPacket_>::vectorizable,
443 LhsPacketSize = Vectorizable ? unpacket_traits<LhsPacket_>::size : 1,
444 RhsPacketSize = Vectorizable ? unpacket_traits<RhsPacket_>::size : 1,
445 ResPacketSize = Vectorizable ? unpacket_traits<ResPacket_>::size : 1,
447 NumberOfRegisters = EIGEN_ARCH_DEFAULT_NUMBER_OF_REGISTERS,
450 mr = (plain_enum_min(16, NumberOfRegisters) / 2 / nr) * ResPacketSize,
452 LhsProgress = ResPacketSize,
456 typedef std::conditional_t<Vectorizable, LhsPacket_, LhsScalar> LhsPacket;
457 typedef RhsScalar RhsPacket;
458 typedef std::conditional_t<Vectorizable, ResPacket_, ResScalar> ResPacket;
459 typedef LhsPacket LhsPacket4Packing;
460 typedef QuadPacket<RhsPacket> RhsPacketx4;
461 typedef ResPacket AccPacket;
463 EIGEN_STRONG_INLINE
void initAcc(AccPacket& p)
const { p = pset1<ResPacket>(ResScalar(0)); }
465 template <
typename RhsPacketType>
466 EIGEN_STRONG_INLINE
void loadRhs(
const RhsScalar* b, RhsPacketType& dest)
const {
467 dest = pset1<RhsPacketType>(*b);
470 EIGEN_STRONG_INLINE
void loadRhs(
const RhsScalar* b, RhsPacketx4& dest)
const {
471 pbroadcast4(b, dest.B_0, dest.B1, dest.B2, dest.B3);
474 template <
typename RhsPacketType>
475 EIGEN_STRONG_INLINE
void updateRhs(
const RhsScalar* b, RhsPacketType& dest)
const {
479 EIGEN_STRONG_INLINE
void updateRhs(
const RhsScalar*, RhsPacketx4&)
const {}
481 EIGEN_STRONG_INLINE
void loadLhs(
const LhsScalar* a, LhsPacket& dest)
const { dest = ploaddup<LhsPacket>(a); }
483 EIGEN_STRONG_INLINE
void loadRhsQuad(
const RhsScalar* b, RhsPacket& dest)
const { dest = ploadquad<RhsPacket>(b); }
485 template <
typename LhsPacketType>
486 EIGEN_STRONG_INLINE
void loadLhsUnaligned(
const LhsScalar* a, LhsPacketType& dest)
const {
487 dest = ploaddup<LhsPacketType>(a);
490 template <
typename LhsPacketType,
typename RhsPacketType,
typename AccPacketType,
typename LaneIdType>
491 EIGEN_STRONG_INLINE
void madd(
const LhsPacketType& a,
const RhsPacketType& b, AccPacketType& c, RhsPacketType& tmp,
492 const LaneIdType&)
const {
493 madd_impl(a, b, c, tmp, std::conditional_t<Vectorizable, std::true_type, std::false_type>());
496 EIGEN_STRONG_INLINE Packet1Xcf pmadd_scalar(
const Packet1Xf& a, std::complex<float> b,
const Packet1Xcf& c)
const {
497 Packet1Xcf bp = pset1<Packet1Xcf>(b);
498 return Packet1Xcf(__riscv_vfmadd_vv_f32m1(a, bp.v, c.v, unpacket_traits<Packet1Xf>::size));
501 EIGEN_STRONG_INLINE Packet1Xcd pmadd_scalar(
const Packet1Xd& a, std::complex<double> b,
const Packet1Xcd& c)
const {
502 Packet1Xcd bp = pset1<Packet1Xcd>(b);
503 return Packet1Xcd(__riscv_vfmadd_vv_f64m1(a, bp.v, c.v, unpacket_traits<Packet1Xd>::size));
506#if EIGEN_RISCV64_DEFAULT_LMUL >= 2
507 EIGEN_STRONG_INLINE Packet2Xcf pmadd_scalar(
const Packet2Xf& a, std::complex<float> b,
const Packet2Xcf& c)
const {
508 Packet2Xcf bp = pset1<Packet2Xcf>(b);
509 return Packet2Xcf(__riscv_vfmadd_vv_f32m2(a, bp.v, c.v, unpacket_traits<Packet2Xf>::size));
512 EIGEN_STRONG_INLINE Packet2Xcd pmadd_scalar(
const Packet2Xd& a, std::complex<double> b,
const Packet2Xcd& c)
const {
513 Packet2Xcd bp = pset1<Packet2Xcd>(b);
514 return Packet2Xcd(__riscv_vfmadd_vv_f64m2(a, bp.v, c.v, unpacket_traits<Packet2Xd>::size));
518#if EIGEN_RISCV64_DEFAULT_LMUL == 4
519 EIGEN_STRONG_INLINE Packet4Xcf pmadd_scalar(
const Packet4Xf& a, std::complex<float> b,
const Packet4Xcf& c)
const {
520 Packet4Xcf bp = pset1<Packet4Xcf>(b);
521 return Packet4Xcf(__riscv_vfmadd_vv_f32m4(a, bp.v, c.v, unpacket_traits<Packet4Xf>::size));
524 EIGEN_STRONG_INLINE Packet4Xcd pmadd_scalar(
const Packet4Xd& a, std::complex<double> b,
const Packet4Xcd& c)
const {
525 Packet4Xcd bp = pset1<Packet4Xcd>(b);
526 return Packet4Xcd(__riscv_vfmadd_vv_f64m4(a, bp.v, c.v, unpacket_traits<Packet4Xd>::size));
530 template <
typename LhsPacketType,
typename RhsPacketType,
typename AccPacketType>
531 EIGEN_STRONG_INLINE
void madd_impl(
const LhsPacketType& a,
const RhsPacketType& b, AccPacketType& c,
532 RhsPacketType& tmp,
const std::true_type&)
const {
533 EIGEN_UNUSED_VARIABLE(tmp);
534 c = pmadd_scalar(a, b, c);
537 EIGEN_STRONG_INLINE
void madd_impl(
const LhsScalar& a,
const RhsScalar& b, ResScalar& c, RhsScalar& ,
538 const std::false_type&)
const {
542 template <
typename LhsPacketType,
typename AccPacketType,
typename LaneIdType>
543 EIGEN_STRONG_INLINE
void madd(
const LhsPacketType& a,
const RhsPacketx4& b, AccPacketType& c, RhsPacket& tmp,
544 const LaneIdType& lane)
const {
545 madd(a, b.get(lane), c, tmp, lane);
548 template <
typename ResPacketType,
typename AccPacketType>
549 EIGEN_STRONG_INLINE
void acc(
const AccPacketType& c,
const ResPacketType& alpha, ResPacketType& r)
const {
550 conj_helper<ResPacketType, ResPacketType, false, ConjRhs> cj;
551 r = cj.pmadd(alpha, c, r);
555template <
typename RealScalar,
bool ConjLhs_,
int PacketSize_>
556class gebp_traits<std::complex<RealScalar>, RealScalar, ConjLhs_, false, Architecture::RVV10, PacketSize_>
557 :
public gebp_traits<RealScalar, std::complex<RealScalar>, ConjLhs_, false, Architecture::Generic, PacketSize_> {
559 typedef std::complex<RealScalar> LhsScalar;
560 typedef RealScalar RhsScalar;
561 typedef typename ScalarBinaryOpTraits<LhsScalar, RhsScalar>::ReturnType ResScalar;
563 PACKET_DECL_COND_POSTFIX(_, Lhs, PacketSize_);
564 PACKET_DECL_COND_POSTFIX(_, Rhs, PacketSize_);
565 PACKET_DECL_COND_POSTFIX(_, Res, PacketSize_);
566#undef PACKET_DECL_COND_POSTFIX
571 Vectorizable = unpacket_traits<LhsPacket_>::vectorizable && unpacket_traits<RhsPacket_>::vectorizable,
572 LhsPacketSize = Vectorizable ? unpacket_traits<LhsPacket_>::size : 1,
573 RhsPacketSize = Vectorizable ? unpacket_traits<RhsPacket_>::size : 1,
574 ResPacketSize = Vectorizable ? unpacket_traits<ResPacket_>::size : 1,
577 mr = 3 * LhsPacketSize,
579 LhsProgress = LhsPacketSize,
583 typedef std::conditional_t<Vectorizable, LhsPacket_, LhsScalar> LhsPacket;
584 typedef RhsScalar RhsPacket;
585 typedef std::conditional_t<Vectorizable, ResPacket_, ResScalar> ResPacket;
586 typedef LhsPacket LhsPacket4Packing;
588 typedef QuadPacket<RhsPacket> RhsPacketx4;
590 typedef ResPacket AccPacket;
592 EIGEN_STRONG_INLINE
void initAcc(AccPacket& p) { p = pset1<ResPacket>(ResScalar(0)); }
594 template <
typename RhsPacketType>
595 EIGEN_STRONG_INLINE
void loadRhs(
const RhsScalar* b, RhsPacketType& dest)
const {
596 dest = pset1<RhsPacketType>(*b);
599 EIGEN_STRONG_INLINE
void loadRhs(
const RhsScalar* b, RhsPacketx4& dest)
const {
600 pbroadcast4(b, dest.B_0, dest.B1, dest.B2, dest.B3);
603 template <
typename RhsPacketType>
604 EIGEN_STRONG_INLINE
void updateRhs(
const RhsScalar* b, RhsPacketType& dest)
const {
608 EIGEN_STRONG_INLINE
void updateRhs(
const RhsScalar*, RhsPacketx4&)
const {}
610 EIGEN_STRONG_INLINE
void loadRhsQuad(
const RhsScalar* b, RhsPacket& dest)
const {
611 loadRhsQuad_impl(b, dest, std::conditional_t<RhsPacketSize == 16, std::true_type, std::false_type>());
614 EIGEN_STRONG_INLINE
void loadRhsQuad_impl(
const RhsScalar* b, RhsPacket& dest,
const std::true_type&)
const {
617 RhsScalar tmp[4] = {b[0], b[0], b[1], b[1]};
618 dest = ploadquad<RhsPacket>(tmp);
621 EIGEN_STRONG_INLINE
void loadRhsQuad_impl(
const RhsScalar* b, RhsPacket& dest,
const std::false_type&)
const {
622 eigen_internal_assert(RhsPacketSize <= 8);
623 dest = pset1<RhsPacket>(*b);
626 EIGEN_STRONG_INLINE
void loadLhs(
const LhsScalar* a, LhsPacket& dest)
const { dest = pload<LhsPacket>(a); }
628 template <
typename LhsPacketType>
629 EIGEN_STRONG_INLINE
void loadLhsUnaligned(
const LhsScalar* a, LhsPacketType& dest)
const {
630 dest = ploadu<LhsPacketType>(a);
633 template <
typename LhsPacketType,
typename RhsPacketType,
typename AccPacketType,
typename LaneIdType>
634 EIGEN_STRONG_INLINE
void madd(
const LhsPacketType& a,
const RhsPacketType& b, AccPacketType& c, RhsPacketType& tmp,
635 const LaneIdType&)
const {
636 madd_impl(a, b, c, tmp, std::conditional_t<Vectorizable, std::true_type, std::false_type>());
639 EIGEN_STRONG_INLINE Packet1Xcf pmadd_scalar(
const Packet1Xcf& a,
float b,
const Packet1Xcf& c)
const {
640 return Packet1Xcf(__riscv_vfmadd_vf_f32m1(a.v, b, c.v, unpacket_traits<Packet1Xf>::size));
643 EIGEN_STRONG_INLINE Packet1Xcd pmadd_scalar(
const Packet1Xcd& a,
double b,
const Packet1Xcd& c)
const {
644 return Packet1Xcd(__riscv_vfmadd_vf_f64m1(a.v, b, c.v, unpacket_traits<Packet1Xd>::size));
647#if EIGEN_RISCV64_DEFAULT_LMUL >= 2
648 EIGEN_STRONG_INLINE Packet2Xcf pmadd_scalar(
const Packet2Xcf& a,
float b,
const Packet2Xcf& c)
const {
649 return Packet2Xcf(__riscv_vfmadd_vf_f32m2(a.v, b, c.v, unpacket_traits<Packet2Xf>::size));
652 EIGEN_STRONG_INLINE Packet2Xcd pmadd_scalar(
const Packet2Xcd& a,
double b,
const Packet2Xcd& c)
const {
653 return Packet2Xcd(__riscv_vfmadd_vf_f64m2(a.v, b, c.v, unpacket_traits<Packet2Xd>::size));
657#if EIGEN_RISCV64_DEFAULT_LMUL == 4
658 EIGEN_STRONG_INLINE Packet4Xcf pmadd_scalar(
const Packet4Xcf& a,
float b,
const Packet4Xcf& c)
const {
659 return Packet4Xcf(__riscv_vfmadd_vf_f32m4(a.v, b, c.v, unpacket_traits<Packet4Xf>::size));
662 EIGEN_STRONG_INLINE Packet4Xcd pmadd_scalar(
const Packet4Xcd& a,
double b,
const Packet4Xcd& c)
const {
663 return Packet4Xcd(__riscv_vfmadd_vf_f64m4(a.v, b, c.v, unpacket_traits<Packet4Xd>::size));
667 template <
typename LhsPacketType,
typename RhsPacketType,
typename AccPacketType>
668 EIGEN_STRONG_INLINE
void madd_impl(
const LhsPacketType& a,
const RhsPacketType& b, AccPacketType& c,
669 RhsPacketType& tmp,
const std::true_type&)
const {
670 EIGEN_UNUSED_VARIABLE(tmp);
671 c = pmadd_scalar(a, b, c);
674 EIGEN_STRONG_INLINE
void madd_impl(
const LhsScalar& a,
const RhsScalar& b, ResScalar& c, RhsScalar& ,
675 const std::false_type&)
const {
679 template <
typename LhsPacketType,
typename AccPacketType,
typename LaneIdType>
680 EIGEN_STRONG_INLINE
void madd(
const LhsPacketType& a,
const RhsPacketx4& b, AccPacketType& c, RhsPacket& tmp,
681 const LaneIdType& lane)
const {
682 madd(a, b.get(lane), c, tmp, lane);
685 template <
typename ResPacketType,
typename AccPacketType>
686 EIGEN_STRONG_INLINE
void acc(
const AccPacketType& c,
const ResPacketType& alpha, ResPacketType& r)
const {
687 conj_helper<ResPacketType, ResPacketType, ConjLhs, false> cj;
688 r = cj.pmadd(c, alpha, r);