Eigen  5.0.1
 
Loading...
Searching...
No Matches
PacketMath2.h
1// This file is part of Eigen, a lightweight C++ template library
2// for linear algebra.
3//
4// Copyright (C) 2024 Kseniya Zaytseva <kseniya.zaytseva@syntacore.com>
5// Copyright (C) 2025 Chip Kerchner <ckerchner@tenstorrent.com>
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// SPDX-License-Identifier: MPL-2.0
11
12#ifndef EIGEN_PACKET2_MATH_RVV10_H
13#define EIGEN_PACKET2_MATH_RVV10_H
14
15// IWYU pragma: private
16#include "../../InternalHeaderCheck.h"
17
18namespace Eigen {
19namespace internal {
20
21/********************************* Packet2Xi ************************************/
22
23EIGEN_STRONG_INLINE Packet2Xi __riscv_vreinterpret_v_u64m2_i32m2(const Packet2Xul& a) {
24 return __riscv_vreinterpret_v_i64m2_i32m2(__riscv_vreinterpret_v_u64m2_i64m2(a));
25}
26
27template <>
28EIGEN_STRONG_INLINE Packet2Xi pset1<Packet2Xi>(const numext::int32_t& from) {
29 return __riscv_vmv_v_x_i32m2(from, unpacket_traits<Packet2Xi>::size);
30}
31
32template <>
33EIGEN_STRONG_INLINE Packet2Xi plset<Packet2Xi>(const numext::int32_t& a) {
34 Packet2Xi idx = __riscv_vreinterpret_v_u32m2_i32m2(__riscv_vid_v_u32m2(unpacket_traits<Packet2Xi>::size));
35 return __riscv_vadd_vx_i32m2(idx, a, unpacket_traits<Packet2Xi>::size);
36}
37
38template <>
39EIGEN_STRONG_INLINE Packet2Xi pzero<Packet2Xi>(const Packet2Xi& /*a*/) {
40 return __riscv_vmv_v_x_i32m2(0, unpacket_traits<Packet2Xi>::size);
41}
42
43template <>
44EIGEN_STRONG_INLINE Packet2Xi padd<Packet2Xi>(const Packet2Xi& a, const Packet2Xi& b) {
45 return __riscv_vadd_vv_i32m2(a, b, unpacket_traits<Packet2Xi>::size);
46}
47
48template <>
49EIGEN_STRONG_INLINE Packet2Xi psub<Packet2Xi>(const Packet2Xi& a, const Packet2Xi& b) {
50 return __riscv_vsub(a, b, unpacket_traits<Packet2Xi>::size);
51}
52
53template <>
54EIGEN_STRONG_INLINE Packet2Xi pnegate(const Packet2Xi& a) {
55 return __riscv_vneg(a, unpacket_traits<Packet2Xi>::size);
56}
57
58template <>
59EIGEN_STRONG_INLINE Packet2Xi pmul<Packet2Xi>(const Packet2Xi& a, const Packet2Xi& b) {
60 return __riscv_vmul(a, b, unpacket_traits<Packet2Xi>::size);
61}
62
63template <>
64EIGEN_STRONG_INLINE Packet2Xi pdiv<Packet2Xi>(const Packet2Xi& a, const Packet2Xi& b) {
65 return __riscv_vdiv(a, b, unpacket_traits<Packet2Xi>::size);
66}
67
68template <>
69EIGEN_STRONG_INLINE Packet2Xi pmadd(const Packet2Xi& a, const Packet2Xi& b, const Packet2Xi& c) {
70 return __riscv_vmadd(a, b, c, unpacket_traits<Packet2Xi>::size);
71}
72
73template <>
74EIGEN_STRONG_INLINE Packet2Xi pmsub(const Packet2Xi& a, const Packet2Xi& b, const Packet2Xi& c) {
75 return __riscv_vmadd(a, b, pnegate(c), unpacket_traits<Packet2Xi>::size);
76}
77
78template <>
79EIGEN_STRONG_INLINE Packet2Xi pnmadd(const Packet2Xi& a, const Packet2Xi& b, const Packet2Xi& c) {
80 return __riscv_vnmsub_vv_i32m2(a, b, c, unpacket_traits<Packet2Xi>::size);
81}
82
83template <>
84EIGEN_STRONG_INLINE Packet2Xi pnmsub(const Packet2Xi& a, const Packet2Xi& b, const Packet2Xi& c) {
85 return __riscv_vnmsub_vv_i32m2(a, b, pnegate(c), unpacket_traits<Packet2Xi>::size);
86}
87
88template <>
89EIGEN_STRONG_INLINE Packet2Xi pmin<Packet2Xi>(const Packet2Xi& a, const Packet2Xi& b) {
90 return __riscv_vmin(a, b, unpacket_traits<Packet2Xi>::size);
91}
92
93template <>
94EIGEN_STRONG_INLINE Packet2Xi pmax<Packet2Xi>(const Packet2Xi& a, const Packet2Xi& b) {
95 return __riscv_vmax(a, b, unpacket_traits<Packet2Xi>::size);
96}
97
98template <>
99EIGEN_STRONG_INLINE Packet2Xi pcmp_le<Packet2Xi>(const Packet2Xi& a, const Packet2Xi& b) {
100 PacketMask16 mask = __riscv_vmsle_vv_i32m2_b16(a, b, unpacket_traits<Packet2Xi>::size);
101 return __riscv_vmerge_vxm_i32m2(pzero(a), 0xffffffff, mask, unpacket_traits<Packet2Xi>::size);
102}
103
104template <>
105EIGEN_STRONG_INLINE Packet2Xi pcmp_lt<Packet2Xi>(const Packet2Xi& a, const Packet2Xi& b) {
106 PacketMask16 mask = __riscv_vmslt_vv_i32m2_b16(a, b, unpacket_traits<Packet2Xi>::size);
107 return __riscv_vmerge_vxm_i32m2(pzero(a), 0xffffffff, mask, unpacket_traits<Packet2Xi>::size);
108}
109
110template <>
111EIGEN_STRONG_INLINE Packet2Xi pcmp_eq<Packet2Xi>(const Packet2Xi& a, const Packet2Xi& b) {
112 PacketMask16 mask = __riscv_vmseq_vv_i32m2_b16(a, b, unpacket_traits<Packet2Xi>::size);
113 return __riscv_vmerge_vxm_i32m2(pzero(a), 0xffffffff, mask, unpacket_traits<Packet2Xi>::size);
114}
115
116template <>
117EIGEN_STRONG_INLINE Packet2Xi ptrue<Packet2Xi>(const Packet2Xi& /*a*/) {
118 return __riscv_vmv_v_x_i32m2(0xffffffffu, unpacket_traits<Packet2Xi>::size);
119}
120
121template <>
122EIGEN_STRONG_INLINE Packet2Xi pand<Packet2Xi>(const Packet2Xi& a, const Packet2Xi& b) {
123 return __riscv_vand_vv_i32m2(a, b, unpacket_traits<Packet2Xi>::size);
124}
125
126template <>
127EIGEN_STRONG_INLINE Packet2Xi por<Packet2Xi>(const Packet2Xi& a, const Packet2Xi& b) {
128 return __riscv_vor_vv_i32m2(a, b, unpacket_traits<Packet2Xi>::size);
129}
130
131template <>
132EIGEN_STRONG_INLINE Packet2Xi pxor<Packet2Xi>(const Packet2Xi& a, const Packet2Xi& b) {
133 return __riscv_vxor_vv_i32m2(a, b, unpacket_traits<Packet2Xi>::size);
134}
135
136template <>
137EIGEN_STRONG_INLINE Packet2Xi pandnot<Packet2Xi>(const Packet2Xi& a, const Packet2Xi& b) {
138#ifndef __riscv_zvbb
139 return __riscv_vand_vv_i32m2(a, __riscv_vnot_v_i32m2(b, unpacket_traits<Packet2Xi>::size),
140 unpacket_traits<Packet2Xi>::size);
141#else
142 return __riscv_vreinterpret_v_u32m2_i32m2(__riscv_vandn_vv_u32m2(
143 __riscv_vreinterpret_v_i32m2_u32m2(a), __riscv_vreinterpret_v_i32m2_u32m2(b), unpacket_traits<Packet2Xi>::size));
144#endif
145}
146
147template <>
148EIGEN_STRONG_INLINE Packet2Xi pnot<Packet2Xi>(const Packet2Xi& a) {
149 return __riscv_vnot_v_i32m2(a, unpacket_traits<Packet2Xi>::size);
150}
151
152template <int N>
153EIGEN_STRONG_INLINE Packet2Xi parithmetic_shift_right(const Packet2Xi& a) {
154 return __riscv_vsra_vx_i32m2(a, N, unpacket_traits<Packet2Xi>::size);
155}
156
157template <int N>
158EIGEN_STRONG_INLINE Packet2Xi plogical_shift_right(const Packet2Xi& a) {
159 return __riscv_vreinterpret_i32m2(
160 __riscv_vsrl_vx_u32m2(__riscv_vreinterpret_u32m2(a), N, unpacket_traits<Packet2Xi>::size));
161}
162
163template <int N>
164EIGEN_STRONG_INLINE Packet2Xi plogical_shift_left(const Packet2Xi& a) {
165 return __riscv_vsll_vx_i32m2(a, N, unpacket_traits<Packet2Xi>::size);
166}
167
168template <>
169EIGEN_STRONG_INLINE Packet2Xi pload<Packet2Xi>(const numext::int32_t* from) {
170 EIGEN_DEBUG_ALIGNED_LOAD return __riscv_vle32_v_i32m2(from, unpacket_traits<Packet2Xi>::size);
171}
172
173template <>
174EIGEN_STRONG_INLINE Packet2Xi ploadu<Packet2Xi>(const numext::int32_t* from) {
175 EIGEN_DEBUG_UNALIGNED_LOAD return __riscv_vle32_v_i32m2(from, unpacket_traits<Packet2Xi>::size);
176}
177
178template <>
179EIGEN_STRONG_INLINE Packet2Xi ploaddup<Packet2Xi>(const numext::int32_t* from) {
180 Packet2Xul data = __riscv_vlmul_trunc_v_u64m4_u64m2(__riscv_vwcvtu_x_x_v_u64m4(
181 __riscv_vreinterpret_v_i32m2_u32m2(pload<Packet2Xi>(from)), unpacket_traits<Packet2Xi>::size));
182 return __riscv_vreinterpret_v_u64m2_i32m2(__riscv_vadd_vv_u64m2(
183 __riscv_vsll_vx_u64m2(data, 32, unpacket_traits<Packet2Xl>::size), data, unpacket_traits<Packet2Xl>::size));
184}
185
186template <>
187EIGEN_STRONG_INLINE Packet2Xi ploadquad<Packet2Xi>(const numext::int32_t* from) {
188 Packet2Xu idx =
189 __riscv_vsrl_vx_u32m2(__riscv_vid_v_u32m2(unpacket_traits<Packet2Xi>::size), 2, unpacket_traits<Packet2Xi>::size);
190 return __riscv_vrgather_vv_i32m2(pload<Packet2Xi>(from), idx, unpacket_traits<Packet2Xi>::size);
191}
192
193template <>
194EIGEN_STRONG_INLINE void pstore<numext::int32_t>(numext::int32_t* to, const Packet2Xi& from) {
195 EIGEN_DEBUG_ALIGNED_STORE __riscv_vse32_v_i32m2(to, from, unpacket_traits<Packet2Xi>::size);
196}
197
198template <>
199EIGEN_STRONG_INLINE void pstoreu<numext::int32_t>(numext::int32_t* to, const Packet2Xi& from) {
200 EIGEN_DEBUG_UNALIGNED_STORE __riscv_vse32_v_i32m2(to, from, unpacket_traits<Packet2Xi>::size);
201}
202
203template <>
204EIGEN_DEVICE_FUNC inline Packet2Xi pgather<numext::int32_t, Packet2Xi>(const numext::int32_t* from, Index stride) {
205 return __riscv_vlse32_v_i32m2(from, stride * sizeof(numext::int32_t), unpacket_traits<Packet2Xi>::size);
206}
207
208template <>
209EIGEN_DEVICE_FUNC inline void pscatter<numext::int32_t, Packet2Xi>(numext::int32_t* to, const Packet2Xi& from,
210 Index stride) {
211 __riscv_vsse32(to, stride * sizeof(numext::int32_t), from, unpacket_traits<Packet2Xi>::size);
212}
213
214template <>
215EIGEN_STRONG_INLINE numext::int32_t pfirst<Packet2Xi>(const Packet2Xi& a) {
216 return __riscv_vmv_x_s_i32m2_i32(a);
217}
218
219template <>
220EIGEN_STRONG_INLINE Packet2Xi preverse(const Packet2Xi& a) {
221 Packet2Xu idx = __riscv_vrsub_vx_u32m2(__riscv_vid_v_u32m2(unpacket_traits<Packet2Xi>::size),
222 unpacket_traits<Packet2Xi>::size - 1, unpacket_traits<Packet2Xi>::size);
223 return __riscv_vrgather_vv_i32m2(a, idx, unpacket_traits<Packet2Xi>::size);
224}
225
226template <>
227EIGEN_STRONG_INLINE Packet2Xi pabs(const Packet2Xi& a) {
228 Packet2Xi mask = __riscv_vsra_vx_i32m2(a, 31, unpacket_traits<Packet2Xi>::size);
229 return __riscv_vsub_vv_i32m2(__riscv_vxor_vv_i32m2(a, mask, unpacket_traits<Packet2Xi>::size), mask,
230 unpacket_traits<Packet2Xi>::size);
231}
232
233template <>
234EIGEN_STRONG_INLINE numext::int32_t predux<Packet2Xi>(const Packet2Xi& a) {
235 return __riscv_vmv_x(__riscv_vredsum_vs_i32m2_i32m1(a, __riscv_vmv_v_x_i32m1(0, unpacket_traits<Packet2Xi>::size / 2),
236 unpacket_traits<Packet2Xi>::size));
237}
238
239template <>
240EIGEN_STRONG_INLINE bool predux_all(const Packet2Xi& a) {
241 const PacketMask16 mask = __riscv_vmseq_vx_i32m2_b16(a, 0, unpacket_traits<Packet2Xi>::size);
242 return __riscv_vcpop_m_b16(mask, unpacket_traits<Packet2Xi>::size) == 0;
243}
244
245template <>
246EIGEN_STRONG_INLINE numext::int32_t predux_mul<Packet2Xi>(const Packet2Xi& a) {
247 return predux_mul<Packet1Xi>(__riscv_vmul_vv_i32m1(__riscv_vget_v_i32m2_i32m1(a, 0), __riscv_vget_v_i32m2_i32m1(a, 1),
248 unpacket_traits<Packet1Xi>::size));
249}
250
251template <>
252EIGEN_STRONG_INLINE numext::int32_t predux_min<Packet2Xi>(const Packet2Xi& a) {
253 return __riscv_vmv_x(__riscv_vredmin_vs_i32m2_i32m1(
254 a, __riscv_vmv_v_x_i32m1((std::numeric_limits<numext::int32_t>::max)(), unpacket_traits<Packet2Xi>::size / 2),
255 unpacket_traits<Packet2Xi>::size));
256}
257
258template <>
259EIGEN_STRONG_INLINE numext::int32_t predux_max<Packet2Xi>(const Packet2Xi& a) {
260 return __riscv_vmv_x(__riscv_vredmax_vs_i32m2_i32m1(
261 a, __riscv_vmv_v_x_i32m1((std::numeric_limits<numext::int32_t>::min)(), unpacket_traits<Packet2Xi>::size / 2),
262 unpacket_traits<Packet2Xi>::size));
263}
264
265template <int N>
266EIGEN_DEVICE_FUNC inline void ptranspose(PacketBlock<Packet2Xi, N>& kernel) {
267 numext::int32_t buffer[unpacket_traits<Packet2Xi>::size * N] = {0};
268 int i = 0;
269
270 for (i = 0; i < N; i++) {
271 __riscv_vsse32(&buffer[i], N * sizeof(numext::int32_t), kernel.packet[i], unpacket_traits<Packet2Xi>::size);
272 }
273 for (i = 0; i < N; i++) {
274 kernel.packet[i] =
275 __riscv_vle32_v_i32m2(&buffer[i * unpacket_traits<Packet2Xi>::size], unpacket_traits<Packet2Xi>::size);
276 }
277}
278
279template <typename Packet = Packet2Xi>
280EIGEN_STRONG_INLINE
281 std::enable_if_t<std::is_same<Packet, Packet2Xi>::value && (unpacket_traits<Packet2Xi>::size % 8) == 0, Packet1Xi>
282 predux_half(const Packet2Xi& a) {
283 return __riscv_vadd_vv_i32m1(__riscv_vget_v_i32m2_i32m1(a, 0), __riscv_vget_v_i32m2_i32m1(a, 1),
284 unpacket_traits<Packet1Xi>::size);
285}
286
287/********************************* Packet2Xf ************************************/
288
289EIGEN_STRONG_INLINE Packet4Xf __riscv_vreinterpret_v_u64m4_f32m4(const Packet4Xul& a) {
290 return __riscv_vreinterpret_v_u32m4_f32m4(__riscv_vreinterpret_v_u64m4_u32m4(a));
291}
292
293template <>
294EIGEN_STRONG_INLINE Packet2Xf ptrue<Packet2Xf>(const Packet2Xf& /*a*/) {
295 Packet2Xf r = __riscv_vreinterpret_f32m2(__riscv_vmv_v_x_u32m2(0xffffffffu, unpacket_traits<Packet2Xf>::size));
296 EIGEN_FAST_MATH_CONSTANT_BARRIER(r);
297 return r;
298}
299
300template <>
301EIGEN_STRONG_INLINE Packet2Xf pzero<Packet2Xf>(const Packet2Xf& /*a*/) {
302 return __riscv_vfmv_v_f_f32m2(0.0f, unpacket_traits<Packet2Xf>::size);
303}
304
305template <>
306EIGEN_STRONG_INLINE Packet2Xf pabs(const Packet2Xf& a) {
307 return __riscv_vfabs_v_f32m2(a, unpacket_traits<Packet2Xf>::size);
308}
309
310template <>
311EIGEN_STRONG_INLINE Packet2Xf pabsdiff(const Packet2Xf& a, const Packet2Xf& b) {
312 return __riscv_vfabs_v_f32m2(__riscv_vfsub_vv_f32m2(a, b, unpacket_traits<Packet2Xf>::size),
313 unpacket_traits<Packet2Xf>::size);
314}
315
316template <>
317EIGEN_STRONG_INLINE Packet2Xf pset1<Packet2Xf>(const float& from) {
318 return __riscv_vfmv_v_f_f32m2(from, unpacket_traits<Packet2Xf>::size);
319}
320
321template <>
322EIGEN_STRONG_INLINE Packet2Xf pset1frombits<Packet2Xf>(numext::uint32_t from) {
323 return __riscv_vreinterpret_f32m2(__riscv_vmv_v_x_u32m2(from, unpacket_traits<Packet2Xf>::size));
324}
325
326template <>
327EIGEN_STRONG_INLINE Packet2Xf plset<Packet2Xf>(const float& a) {
328 Packet2Xf idx = __riscv_vfcvt_f_x_v_f32m2(
329 __riscv_vreinterpret_v_u32m2_i32m2(__riscv_vid_v_u32m2(unpacket_traits<Packet4Xi>::size)),
330 unpacket_traits<Packet2Xf>::size);
331 return __riscv_vfadd_vf_f32m2(idx, a, unpacket_traits<Packet2Xf>::size);
332}
333
334template <>
335EIGEN_STRONG_INLINE void pbroadcast4<Packet2Xf>(const float* a, Packet2Xf& a0, Packet2Xf& a1, Packet2Xf& a2,
336 Packet2Xf& a3) {
337 Packet2Xf aa = __riscv_vlmul_ext_f32m2(__riscv_vle32_v_f32m1(a, 4));
338 a0 = __riscv_vrgather_vx_f32m2(aa, 0, unpacket_traits<Packet2Xf>::size);
339 a1 = __riscv_vrgather_vx_f32m2(aa, 1, unpacket_traits<Packet2Xf>::size);
340 a2 = __riscv_vrgather_vx_f32m2(aa, 2, unpacket_traits<Packet2Xf>::size);
341 a3 = __riscv_vrgather_vx_f32m2(aa, 3, unpacket_traits<Packet2Xf>::size);
342}
343
344template <>
345EIGEN_STRONG_INLINE Packet2Xf padd<Packet2Xf>(const Packet2Xf& a, const Packet2Xf& b) {
346 return __riscv_vfadd_vv_f32m2(a, b, unpacket_traits<Packet2Xf>::size);
347}
348
349template <>
350EIGEN_STRONG_INLINE Packet2Xf psub<Packet2Xf>(const Packet2Xf& a, const Packet2Xf& b) {
351 return __riscv_vfsub_vv_f32m2(a, b, unpacket_traits<Packet2Xf>::size);
352}
353
354template <>
355EIGEN_STRONG_INLINE Packet2Xf pnegate(const Packet2Xf& a) {
356 return __riscv_vfneg_v_f32m2(a, unpacket_traits<Packet2Xf>::size);
357}
358
359template <>
360EIGEN_STRONG_INLINE Packet2Xf psignbit(const Packet2Xf& a) {
361 return __riscv_vreinterpret_v_i32m2_f32m2(
362 __riscv_vsra_vx_i32m2(__riscv_vreinterpret_v_f32m2_i32m2(a), 31, unpacket_traits<Packet2Xi>::size));
363}
364
365template <>
366EIGEN_STRONG_INLINE Packet2Xf pmul<Packet2Xf>(const Packet2Xf& a, const Packet2Xf& b) {
367 return __riscv_vfmul_vv_f32m2(a, b, unpacket_traits<Packet2Xf>::size);
368}
369
370template <>
371EIGEN_STRONG_INLINE Packet2Xf pdiv<Packet2Xf>(const Packet2Xf& a, const Packet2Xf& b) {
372 return __riscv_vfdiv_vv_f32m2(a, b, unpacket_traits<Packet2Xf>::size);
373}
374
375template <>
376EIGEN_STRONG_INLINE Packet2Xf pmadd(const Packet2Xf& a, const Packet2Xf& b, const Packet2Xf& c) {
377 return __riscv_vfmadd_vv_f32m2(a, b, c, unpacket_traits<Packet2Xf>::size);
378}
379
380template <>
381EIGEN_STRONG_INLINE Packet2Xf pmsub(const Packet2Xf& a, const Packet2Xf& b, const Packet2Xf& c) {
382 return __riscv_vfmsub_vv_f32m2(a, b, c, unpacket_traits<Packet2Xf>::size);
383}
384
385template <>
386EIGEN_STRONG_INLINE Packet2Xf pnmadd(const Packet2Xf& a, const Packet2Xf& b, const Packet2Xf& c) {
387 return __riscv_vfnmsub_vv_f32m2(a, b, c, unpacket_traits<Packet2Xf>::size);
388}
389
390template <>
391EIGEN_STRONG_INLINE Packet2Xf pnmsub(const Packet2Xf& a, const Packet2Xf& b, const Packet2Xf& c) {
392 return __riscv_vfnmadd_vv_f32m2(a, b, c, unpacket_traits<Packet2Xf>::size);
393}
394
395template <>
396struct pminmax_propagates_nan<Packet2Xf> : bool_constant<true> {};
397
398template <>
399EIGEN_STRONG_INLINE Packet2Xf pmin<Packet2Xf>(const Packet2Xf& a, const Packet2Xf& b) {
400 Packet2Xf nans = __riscv_vfmv_v_f_f32m2((std::numeric_limits<float>::quiet_NaN)(), unpacket_traits<Packet2Xf>::size);
401 PacketMask16 mask = __riscv_vmfeq_vv_f32m2_b16(a, a, unpacket_traits<Packet2Xf>::size);
402 PacketMask16 mask2 = __riscv_vmfeq_vv_f32m2_b16(b, b, unpacket_traits<Packet2Xf>::size);
403 mask = __riscv_vmand_mm_b16(mask, mask2, unpacket_traits<Packet2Xf>::size);
404
405 return __riscv_vfmin_vv_f32m2_tumu(mask, nans, a, b, unpacket_traits<Packet2Xf>::size);
406}
407
408template <>
409EIGEN_STRONG_INLINE Packet2Xf pmin<PropagateNumbers, Packet2Xf>(const Packet2Xf& a, const Packet2Xf& b) {
410 return __riscv_vfmin_vv_f32m2(a, b, unpacket_traits<Packet2Xf>::size);
411}
412
413template <>
414EIGEN_STRONG_INLINE Packet2Xf pmax<Packet2Xf>(const Packet2Xf& a, const Packet2Xf& b) {
415 Packet2Xf nans = __riscv_vfmv_v_f_f32m2((std::numeric_limits<float>::quiet_NaN)(), unpacket_traits<Packet2Xf>::size);
416 PacketMask16 mask = __riscv_vmfeq_vv_f32m2_b16(a, a, unpacket_traits<Packet2Xf>::size);
417 PacketMask16 mask2 = __riscv_vmfeq_vv_f32m2_b16(b, b, unpacket_traits<Packet2Xf>::size);
418 mask = __riscv_vmand_mm_b16(mask, mask2, unpacket_traits<Packet2Xf>::size);
419
420 return __riscv_vfmax_vv_f32m2_tumu(mask, nans, a, b, unpacket_traits<Packet2Xf>::size);
421}
422
423template <>
424EIGEN_STRONG_INLINE Packet2Xf pmax<PropagateNumbers, Packet2Xf>(const Packet2Xf& a, const Packet2Xf& b) {
425 return __riscv_vfmax_vv_f32m2(a, b, unpacket_traits<Packet2Xf>::size);
426}
427
428template <>
429EIGEN_STRONG_INLINE Packet2Xf pcmp_le<Packet2Xf>(const Packet2Xf& a, const Packet2Xf& b) {
430 PacketMask16 mask = __riscv_vmfle_vv_f32m2_b16(a, b, unpacket_traits<Packet2Xf>::size);
431 return __riscv_vmerge_vvm_f32m2(pzero<Packet2Xf>(a), ptrue<Packet2Xf>(a), mask, unpacket_traits<Packet2Xf>::size);
432}
433
434template <>
435EIGEN_STRONG_INLINE Packet2Xf pcmp_lt<Packet2Xf>(const Packet2Xf& a, const Packet2Xf& b) {
436 PacketMask16 mask = __riscv_vmflt_vv_f32m2_b16(a, b, unpacket_traits<Packet2Xf>::size);
437 return __riscv_vmerge_vvm_f32m2(pzero<Packet2Xf>(a), ptrue<Packet2Xf>(a), mask, unpacket_traits<Packet2Xf>::size);
438}
439
440template <>
441EIGEN_STRONG_INLINE Packet2Xf pcmp_eq<Packet2Xf>(const Packet2Xf& a, const Packet2Xf& b) {
442 PacketMask16 mask = __riscv_vmfeq_vv_f32m2_b16(a, b, unpacket_traits<Packet2Xf>::size);
443 return __riscv_vmerge_vvm_f32m2(pzero<Packet2Xf>(a), ptrue<Packet2Xf>(a), mask, unpacket_traits<Packet2Xf>::size);
444}
445
446template <>
447EIGEN_STRONG_INLINE Packet2Xf pcmp_lt_or_nan<Packet2Xf>(const Packet2Xf& a, const Packet2Xf& b) {
448 PacketMask16 mask = __riscv_vmfge_vv_f32m2_b16(a, b, unpacket_traits<Packet2Xf>::size);
449 return __riscv_vfmerge_vfm_f32m2(ptrue<Packet2Xf>(a), 0.0f, mask, unpacket_traits<Packet2Xf>::size);
450}
451
452EIGEN_STRONG_INLINE Packet2Xf pselect(const PacketMask16& mask, const Packet2Xf& a, const Packet2Xf& b) {
453 return __riscv_vmerge_vvm_f32m2(b, a, mask, unpacket_traits<Packet2Xf>::size);
454}
455
456EIGEN_STRONG_INLINE Packet2Xf pselect(const Packet2Xf& mask, const Packet2Xf& a, const Packet2Xf& b) {
457 PacketMask16 mask2 =
458 __riscv_vmsne_vx_i32m2_b16(__riscv_vreinterpret_v_f32m2_i32m2(mask), 0, unpacket_traits<Packet2Xf>::size);
459 return __riscv_vmerge_vvm_f32m2(b, a, mask2, unpacket_traits<Packet2Xf>::size);
460}
461
462// Logical Operations are not supported for float, so reinterpret casts
463template <>
464EIGEN_STRONG_INLINE Packet2Xf pand<Packet2Xf>(const Packet2Xf& a, const Packet2Xf& b) {
465 return __riscv_vreinterpret_v_u32m2_f32m2(__riscv_vand_vv_u32m2(
466 __riscv_vreinterpret_v_f32m2_u32m2(a), __riscv_vreinterpret_v_f32m2_u32m2(b), unpacket_traits<Packet2Xf>::size));
467}
468
469template <>
470EIGEN_STRONG_INLINE Packet2Xf por<Packet2Xf>(const Packet2Xf& a, const Packet2Xf& b) {
471 return __riscv_vreinterpret_v_u32m2_f32m2(__riscv_vor_vv_u32m2(
472 __riscv_vreinterpret_v_f32m2_u32m2(a), __riscv_vreinterpret_v_f32m2_u32m2(b), unpacket_traits<Packet2Xf>::size));
473}
474
475template <>
476EIGEN_STRONG_INLINE Packet2Xf pxor<Packet2Xf>(const Packet2Xf& a, const Packet2Xf& b) {
477 return __riscv_vreinterpret_v_u32m2_f32m2(__riscv_vxor_vv_u32m2(
478 __riscv_vreinterpret_v_f32m2_u32m2(a), __riscv_vreinterpret_v_f32m2_u32m2(b), unpacket_traits<Packet2Xf>::size));
479}
480
481template <>
482EIGEN_STRONG_INLINE Packet2Xf pandnot<Packet2Xf>(const Packet2Xf& a, const Packet2Xf& b) {
483#ifndef __riscv_zvbb
484 return __riscv_vreinterpret_v_u32m2_f32m2(__riscv_vand_vv_u32m2(
485 __riscv_vreinterpret_v_f32m2_u32m2(a),
486 __riscv_vnot_v_u32m2(__riscv_vreinterpret_v_f32m2_u32m2(b), unpacket_traits<Packet2Xf>::size),
487 unpacket_traits<Packet2Xf>::size));
488#else
489 return __riscv_vreinterpret_v_u32m2_f32m2(__riscv_vandn_vv_u32m2(
490 __riscv_vreinterpret_v_f32m2_u32m2(a), __riscv_vreinterpret_v_f32m2_u32m2(b), unpacket_traits<Packet2Xi>::size));
491#endif
492}
493
494template <>
495EIGEN_STRONG_INLINE Packet2Xf pnot<Packet2Xf>(const Packet2Xf& a) {
496 return __riscv_vreinterpret_v_u32m2_f32m2(
497 __riscv_vnot_v_u32m2(__riscv_vreinterpret_v_f32m2_u32m2(a), unpacket_traits<Packet2Xf>::size));
498}
499
500template <>
501EIGEN_STRONG_INLINE Packet2Xf pload<Packet2Xf>(const float* from) {
502 EIGEN_DEBUG_ALIGNED_LOAD return __riscv_vle32_v_f32m2(from, unpacket_traits<Packet2Xf>::size);
503}
504
505template <>
506EIGEN_STRONG_INLINE Packet2Xf ploadu<Packet2Xf>(const float* from) {
507 EIGEN_DEBUG_UNALIGNED_LOAD return __riscv_vle32_v_f32m2(from, unpacket_traits<Packet2Xf>::size);
508}
509
510EIGEN_STRONG_INLINE Packet4Xf pdup(const Packet2Xf& a) {
511 Packet4Xul data = __riscv_vwcvtu_x_x_v_u64m4(__riscv_vreinterpret_v_f32m2_u32m2(a), unpacket_traits<Packet2Xi>::size);
512 return __riscv_vreinterpret_v_u64m4_f32m4(__riscv_vadd_vv_u64m4(
513 __riscv_vsll_vx_u64m4(data, 32, unpacket_traits<Packet4Xl>::size), data, unpacket_traits<Packet4Xl>::size));
514}
515
516template <>
517EIGEN_STRONG_INLINE Packet2Xf ploaddup<Packet2Xf>(const float* from) {
518 Packet2Xul data = __riscv_vlmul_trunc_v_u64m4_u64m2(__riscv_vwcvtu_x_x_v_u64m4(
519 __riscv_vreinterpret_v_f32m2_u32m2(pload<Packet2Xf>(from)), unpacket_traits<Packet2Xi>::size));
520 return __riscv_vreinterpret_v_u64m2_f32m2(__riscv_vadd_vv_u64m2(
521 __riscv_vsll_vx_u64m2(data, 32, unpacket_traits<Packet2Xl>::size), data, unpacket_traits<Packet2Xl>::size));
522}
523
524template <>
525EIGEN_STRONG_INLINE Packet2Xf ploadquad<Packet2Xf>(const float* from) {
526 Packet2Xu idx =
527 __riscv_vsrl_vx_u32m2(__riscv_vid_v_u32m2(unpacket_traits<Packet2Xf>::size), 2, unpacket_traits<Packet2Xf>::size);
528 return __riscv_vrgather_vv_f32m2(pload<Packet2Xf>(from), idx, unpacket_traits<Packet2Xf>::size);
529}
530
531template <>
532EIGEN_STRONG_INLINE void pstore<float>(float* to, const Packet2Xf& from) {
533 EIGEN_DEBUG_ALIGNED_STORE __riscv_vse32_v_f32m2(to, from, unpacket_traits<Packet2Xf>::size);
534}
535
536template <>
537EIGEN_STRONG_INLINE void pstoreu<float>(float* to, const Packet2Xf& from) {
538 EIGEN_DEBUG_UNALIGNED_STORE __riscv_vse32_v_f32m2(to, from, unpacket_traits<Packet2Xf>::size);
539}
540
541template <>
542EIGEN_DEVICE_FUNC inline Packet2Xf pgather<float, Packet2Xf>(const float* from, Index stride) {
543 return __riscv_vlse32_v_f32m2(from, stride * sizeof(float), unpacket_traits<Packet2Xf>::size);
544}
545
546template <>
547EIGEN_DEVICE_FUNC inline void pscatter<float, Packet2Xf>(float* to, const Packet2Xf& from, Index stride) {
548 __riscv_vsse32(to, stride * sizeof(float), from, unpacket_traits<Packet2Xf>::size);
549}
550
551template <>
552EIGEN_STRONG_INLINE float pfirst<Packet2Xf>(const Packet2Xf& a) {
553 return __riscv_vfmv_f_s_f32m2_f32(a);
554}
555
556template <>
557EIGEN_STRONG_INLINE Packet2Xf psqrt(const Packet2Xf& a) {
558 return __riscv_vfsqrt_v_f32m2(a, unpacket_traits<Packet2Xf>::size);
559}
560
561template <>
562EIGEN_STRONG_INLINE Packet2Xf print<Packet2Xf>(const Packet2Xf& a) {
563 const Packet2Xf limit = pset1<Packet2Xf>(static_cast<float>(1 << 23));
564 const Packet2Xf abs_a = pabs(a);
565
566 PacketMask16 mask = __riscv_vmfne_vv_f32m2_b16(a, a, unpacket_traits<Packet2Xf>::size);
567 const Packet2Xf x = __riscv_vfadd_vv_f32m2_tumu(mask, a, a, a, unpacket_traits<Packet2Xf>::size);
568 const Packet2Xf new_x = __riscv_vfcvt_f_x_v_f32m2(__riscv_vfcvt_x_f_v_i32m2(a, unpacket_traits<Packet2Xf>::size),
569 unpacket_traits<Packet2Xf>::size);
570
571 mask = __riscv_vmflt_vv_f32m2_b16(abs_a, limit, unpacket_traits<Packet2Xf>::size);
572 Packet2Xf signed_x = __riscv_vfsgnj_vv_f32m2(new_x, x, unpacket_traits<Packet2Xf>::size);
573 return __riscv_vmerge_vvm_f32m2(x, signed_x, mask, unpacket_traits<Packet2Xf>::size);
574}
575
576template <>
577EIGEN_STRONG_INLINE Packet2Xf pfloor<Packet2Xf>(const Packet2Xf& a) {
578 Packet2Xf tmp = print<Packet2Xf>(a);
579 // If greater, subtract one.
580 PacketMask16 mask = __riscv_vmflt_vv_f32m2_b16(a, tmp, unpacket_traits<Packet2Xf>::size);
581 return __riscv_vfsub_vf_f32m2_tumu(mask, tmp, tmp, 1.0f, unpacket_traits<Packet2Xf>::size);
582}
583
584template <>
585EIGEN_STRONG_INLINE Packet2Xf preverse(const Packet2Xf& a) {
586 Packet2Xu idx = __riscv_vrsub_vx_u32m2(__riscv_vid_v_u32m2(unpacket_traits<Packet2Xf>::size),
587 unpacket_traits<Packet2Xf>::size - 1, unpacket_traits<Packet2Xf>::size);
588 return __riscv_vrgather_vv_f32m2(a, idx, unpacket_traits<Packet2Xf>::size);
589}
590
591template <>
592EIGEN_STRONG_INLINE Packet2Xf pfrexp<Packet2Xf>(const Packet2Xf& a, Packet2Xf& exponent) {
593 return pfrexp_generic(a, exponent);
594}
595
596template <>
597EIGEN_STRONG_INLINE float predux<Packet2Xf>(const Packet2Xf& a) {
598 return __riscv_vfmv_f(__riscv_vfredusum_vs_f32m2_f32m1(
599 a, __riscv_vfmv_v_f_f32m1(0.0f, unpacket_traits<Packet2Xf>::size / 2), unpacket_traits<Packet2Xf>::size));
600}
601
602template <>
603EIGEN_STRONG_INLINE bool predux_any(const Packet2Xf& a) {
604 const PacketMask16 mask =
605 __riscv_vmsne_vx_u32m2_b16(__riscv_vreinterpret_v_f32m2_u32m2(a), 0, unpacket_traits<Packet2Xf>::size);
606 return __riscv_vcpop_m_b16(mask, unpacket_traits<Packet2Xf>::size) != 0;
607}
608
609template <>
610EIGEN_STRONG_INLINE bool predux_all(const Packet2Xf& a) {
611 const PacketMask16 mask = __riscv_vmfeq_vf_f32m2_b16(a, 0.0f, unpacket_traits<Packet2Xf>::size);
612 return __riscv_vcpop_m_b16(mask, unpacket_traits<Packet2Xf>::size) == 0;
613}
614
615template <>
616EIGEN_STRONG_INLINE Index predux_count(const Packet2Xf& a) {
617 const PacketMask16 mask = __riscv_vmfne_vf_f32m2_b16(a, 0.0f, unpacket_traits<Packet2Xf>::size);
618 return static_cast<Index>(__riscv_vcpop_m_b16(mask, unpacket_traits<Packet2Xf>::size));
619}
620
621template <>
622EIGEN_STRONG_INLINE float predux_mul<Packet2Xf>(const Packet2Xf& a) {
623 return predux_mul<Packet1Xf>(__riscv_vfmul_vv_f32m1(
624 __riscv_vget_v_f32m2_f32m1(a, 0), __riscv_vget_v_f32m2_f32m1(a, 1), unpacket_traits<Packet1Xf>::size));
625}
626
627// Reusing the first lane is exact for an idempotent reduction and avoids a NaN seed that becomes poison under
628// finite fast-math.
629template <>
630EIGEN_STRONG_INLINE float predux_min<Packet2Xf>(const Packet2Xf& a) {
631 return __riscv_vfmv_f(
632 __riscv_vfredmin_vs_f32m2_f32m1(a, __riscv_vget_v_f32m2_f32m1(a, 0), unpacket_traits<Packet2Xf>::size));
633}
634
635template <>
636EIGEN_STRONG_INLINE float predux_max<Packet2Xf>(const Packet2Xf& a) {
637 return __riscv_vfmv_f(
638 __riscv_vfredmax_vs_f32m2_f32m1(a, __riscv_vget_v_f32m2_f32m1(a, 0), unpacket_traits<Packet2Xf>::size));
639}
640
641template <>
642EIGEN_STRONG_INLINE Packet1Xf predux_half(const Packet2Xf& a) {
643 return Packet1Xf(__riscv_vfadd_vv_f32m1(__riscv_vget_v_f32m2_f32m1(a, 0), __riscv_vget_v_f32m2_f32m1(a, 1),
644 unpacket_traits<Packet1Xf>::size));
645}
646
647template <int N>
648EIGEN_DEVICE_FUNC inline void ptranspose(PacketBlock<Packet2Xf, N>& kernel) {
649 float buffer[unpacket_traits<Packet2Xf>::size * N];
650 int i = 0;
651
652 for (i = 0; i < N; i++) {
653 __riscv_vsse32(&buffer[i], N * sizeof(float), kernel.packet[i], unpacket_traits<Packet2Xf>::size);
654 }
655
656 for (i = 0; i < N; i++) {
657 kernel.packet[i] =
658 __riscv_vle32_v_f32m2(&buffer[i * unpacket_traits<Packet2Xf>::size], unpacket_traits<Packet2Xf>::size);
659 }
660}
661
662template <>
663EIGEN_STRONG_INLINE Packet2Xf pldexp<Packet2Xf>(const Packet2Xf& a, const Packet2Xf& exponent) {
664 return pldexp_generic(a, exponent);
665}
666
667template <typename Packet = Packet2Xf>
668EIGEN_STRONG_INLINE
669 std::enable_if_t<std::is_same<Packet, Packet2Xf>::value && (unpacket_traits<Packet2Xf>::size % 8) == 0, Packet1Xf>
670 predux_half(const Packet2Xf& a) {
671 return __riscv_vfadd_vv_f32m1(__riscv_vget_v_f32m2_f32m1(a, 0), __riscv_vget_v_f32m2_f32m1(a, 1),
672 unpacket_traits<Packet1Xf>::size);
673}
674
675/********************************* Packet2Xl ************************************/
676
677template <>
678EIGEN_STRONG_INLINE Packet2Xl pset1<Packet2Xl>(const numext::int64_t& from) {
679 return __riscv_vmv_v_x_i64m2(from, unpacket_traits<Packet2Xl>::size);
680}
681
682template <>
683EIGEN_STRONG_INLINE Packet2Xl plset<Packet2Xl>(const numext::int64_t& a) {
684 Packet2Xl idx = __riscv_vreinterpret_v_u64m2_i64m2(__riscv_vid_v_u64m2(unpacket_traits<Packet2Xl>::size));
685 return __riscv_vadd_vx_i64m2(idx, a, unpacket_traits<Packet2Xl>::size);
686}
687
688template <>
689EIGEN_STRONG_INLINE Packet2Xl pzero<Packet2Xl>(const Packet2Xl& /*a*/) {
690 return __riscv_vmv_v_x_i64m2(0, unpacket_traits<Packet2Xl>::size);
691}
692
693template <>
694EIGEN_STRONG_INLINE Packet2Xl padd<Packet2Xl>(const Packet2Xl& a, const Packet2Xl& b) {
695 return __riscv_vadd_vv_i64m2(a, b, unpacket_traits<Packet2Xl>::size);
696}
697
698template <>
699EIGEN_STRONG_INLINE Packet2Xl psub<Packet2Xl>(const Packet2Xl& a, const Packet2Xl& b) {
700 return __riscv_vsub(a, b, unpacket_traits<Packet2Xl>::size);
701}
702
703template <>
704EIGEN_STRONG_INLINE Packet2Xl pnegate(const Packet2Xl& a) {
705 return __riscv_vneg(a, unpacket_traits<Packet2Xl>::size);
706}
707
708template <>
709EIGEN_STRONG_INLINE Packet2Xl pmul<Packet2Xl>(const Packet2Xl& a, const Packet2Xl& b) {
710 return __riscv_vmul(a, b, unpacket_traits<Packet2Xl>::size);
711}
712
713template <>
714EIGEN_STRONG_INLINE Packet2Xl pdiv<Packet2Xl>(const Packet2Xl& a, const Packet2Xl& b) {
715 return __riscv_vdiv(a, b, unpacket_traits<Packet2Xl>::size);
716}
717
718template <>
719EIGEN_STRONG_INLINE Packet2Xl pmadd(const Packet2Xl& a, const Packet2Xl& b, const Packet2Xl& c) {
720 return __riscv_vmadd(a, b, c, unpacket_traits<Packet2Xl>::size);
721}
722
723template <>
724EIGEN_STRONG_INLINE Packet2Xl pmsub(const Packet2Xl& a, const Packet2Xl& b, const Packet2Xl& c) {
725 return __riscv_vmadd(a, b, pnegate(c), unpacket_traits<Packet2Xl>::size);
726}
727
728template <>
729EIGEN_STRONG_INLINE Packet2Xl pnmadd(const Packet2Xl& a, const Packet2Xl& b, const Packet2Xl& c) {
730 return __riscv_vnmsub_vv_i64m2(a, b, c, unpacket_traits<Packet2Xl>::size);
731}
732
733template <>
734EIGEN_STRONG_INLINE Packet2Xl pnmsub(const Packet2Xl& a, const Packet2Xl& b, const Packet2Xl& c) {
735 return __riscv_vnmsub_vv_i64m2(a, b, pnegate(c), unpacket_traits<Packet2Xl>::size);
736}
737
738template <>
739EIGEN_STRONG_INLINE Packet2Xl pmin<Packet2Xl>(const Packet2Xl& a, const Packet2Xl& b) {
740 return __riscv_vmin(a, b, unpacket_traits<Packet2Xl>::size);
741}
742
743template <>
744EIGEN_STRONG_INLINE Packet2Xl pmax<Packet2Xl>(const Packet2Xl& a, const Packet2Xl& b) {
745 return __riscv_vmax(a, b, unpacket_traits<Packet2Xl>::size);
746}
747
748template <>
749EIGEN_STRONG_INLINE Packet2Xl pcmp_le<Packet2Xl>(const Packet2Xl& a, const Packet2Xl& b) {
750 PacketMask32 mask = __riscv_vmsle_vv_i64m2_b32(a, b, unpacket_traits<Packet2Xl>::size);
751 return __riscv_vmerge_vxm_i64m2(pzero(a), 0xffffffffffffffff, mask, unpacket_traits<Packet2Xl>::size);
752}
753
754template <>
755EIGEN_STRONG_INLINE Packet2Xl pcmp_lt<Packet2Xl>(const Packet2Xl& a, const Packet2Xl& b) {
756 PacketMask32 mask = __riscv_vmslt_vv_i64m2_b32(a, b, unpacket_traits<Packet2Xl>::size);
757 return __riscv_vmerge_vxm_i64m2(pzero(a), 0xffffffffffffffff, mask, unpacket_traits<Packet2Xl>::size);
758}
759
760template <>
761EIGEN_STRONG_INLINE Packet2Xl pcmp_eq<Packet2Xl>(const Packet2Xl& a, const Packet2Xl& b) {
762 PacketMask32 mask = __riscv_vmseq_vv_i64m2_b32(a, b, unpacket_traits<Packet2Xl>::size);
763 return __riscv_vmerge_vxm_i64m2(pzero(a), 0xffffffffffffffff, mask, unpacket_traits<Packet2Xl>::size);
764}
765
766template <>
767EIGEN_STRONG_INLINE Packet2Xl ptrue<Packet2Xl>(const Packet2Xl& /*a*/) {
768 return __riscv_vmv_v_x_i64m2(0xffffffffffffffffu, unpacket_traits<Packet2Xl>::size);
769}
770
771template <>
772EIGEN_STRONG_INLINE Packet2Xl pand<Packet2Xl>(const Packet2Xl& a, const Packet2Xl& b) {
773 return __riscv_vand_vv_i64m2(a, b, unpacket_traits<Packet2Xl>::size);
774}
775
776template <>
777EIGEN_STRONG_INLINE Packet2Xl por<Packet2Xl>(const Packet2Xl& a, const Packet2Xl& b) {
778 return __riscv_vor_vv_i64m2(a, b, unpacket_traits<Packet2Xl>::size);
779}
780
781template <>
782EIGEN_STRONG_INLINE Packet2Xl pnot<Packet2Xl>(const Packet2Xl& a) {
783 return __riscv_vnot_v_i64m2(a, unpacket_traits<Packet2Xl>::size);
784}
785
786template <>
787EIGEN_STRONG_INLINE Packet2Xl pxor<Packet2Xl>(const Packet2Xl& a, const Packet2Xl& b) {
788 return __riscv_vxor_vv_i64m2(a, b, unpacket_traits<Packet2Xl>::size);
789}
790
791template <>
792EIGEN_STRONG_INLINE Packet2Xl pandnot<Packet2Xl>(const Packet2Xl& a, const Packet2Xl& b) {
793#ifndef __riscv_zvbb
794 return __riscv_vand_vv_i64m2(a, __riscv_vnot_v_i64m2(b, unpacket_traits<Packet2Xl>::size),
795 unpacket_traits<Packet2Xl>::size);
796#else
797 return __riscv_vreinterpret_v_u64m2_i64m2(__riscv_vandn_vv_u64m2(
798 __riscv_vreinterpret_v_i64m2_u64m2(a), __riscv_vreinterpret_v_i64m2_u64m2(b), unpacket_traits<Packet2Xl>::size));
799#endif
800}
801
802template <int N>
803EIGEN_STRONG_INLINE Packet2Xl parithmetic_shift_right(const Packet2Xl& a) {
804 return __riscv_vsra_vx_i64m2(a, N, unpacket_traits<Packet2Xl>::size);
805}
806
807template <int N>
808EIGEN_STRONG_INLINE Packet2Xl plogical_shift_right(const Packet2Xl& a) {
809 return __riscv_vreinterpret_i64m2(
810 __riscv_vsrl_vx_u64m2(__riscv_vreinterpret_u64m2(a), N, unpacket_traits<Packet2Xl>::size));
811}
812
813template <int N>
814EIGEN_STRONG_INLINE Packet2Xl plogical_shift_left(const Packet2Xl& a) {
815 return __riscv_vsll_vx_i64m2(a, N, unpacket_traits<Packet2Xl>::size);
816}
817
818template <>
819EIGEN_STRONG_INLINE Packet2Xl pload<Packet2Xl>(const numext::int64_t* from) {
820 EIGEN_DEBUG_ALIGNED_LOAD return __riscv_vle64_v_i64m2(from, unpacket_traits<Packet2Xl>::size);
821}
822
823template <>
824EIGEN_STRONG_INLINE Packet2Xl ploadu<Packet2Xl>(const numext::int64_t* from) {
825 EIGEN_DEBUG_UNALIGNED_LOAD return __riscv_vle64_v_i64m2(from, unpacket_traits<Packet2Xl>::size);
826}
827
828template <>
829EIGEN_STRONG_INLINE Packet2Xl ploaddup<Packet2Xl>(const numext::int64_t* from) {
830 Packet2Xul idx =
831 __riscv_vsrl_vx_u64m2(__riscv_vid_v_u64m2(unpacket_traits<Packet2Xl>::size), 1, unpacket_traits<Packet2Xl>::size);
832 return __riscv_vrgather_vv_i64m2(pload<Packet2Xl>(from), idx, unpacket_traits<Packet2Xl>::size);
833}
834
835template <>
836EIGEN_STRONG_INLINE Packet2Xl ploadquad<Packet2Xl>(const numext::int64_t* from) {
837 Packet2Xul idx =
838 __riscv_vsrl_vx_u64m2(__riscv_vid_v_u64m2(unpacket_traits<Packet2Xl>::size), 2, unpacket_traits<Packet2Xl>::size);
839 return __riscv_vrgather_vv_i64m2(pload<Packet2Xl>(from), idx, unpacket_traits<Packet2Xl>::size);
840}
841
842template <>
843EIGEN_STRONG_INLINE void pstore<numext::int64_t>(numext::int64_t* to, const Packet2Xl& from) {
844 EIGEN_DEBUG_ALIGNED_STORE __riscv_vse64_v_i64m2(to, from, unpacket_traits<Packet2Xl>::size);
845}
846
847template <>
848EIGEN_STRONG_INLINE void pstoreu<numext::int64_t>(numext::int64_t* to, const Packet2Xl& from) {
849 EIGEN_DEBUG_UNALIGNED_STORE __riscv_vse64_v_i64m2(to, from, unpacket_traits<Packet2Xl>::size);
850}
851
852template <>
853EIGEN_DEVICE_FUNC inline Packet2Xl pgather<numext::int64_t, Packet2Xl>(const numext::int64_t* from, Index stride) {
854 return __riscv_vlse64_v_i64m2(from, stride * sizeof(numext::int64_t), unpacket_traits<Packet2Xl>::size);
855}
856
857template <>
858EIGEN_DEVICE_FUNC inline void pscatter<numext::int64_t, Packet2Xl>(numext::int64_t* to, const Packet2Xl& from,
859 Index stride) {
860 __riscv_vsse64(to, stride * sizeof(numext::int64_t), from, unpacket_traits<Packet2Xl>::size);
861}
862
863template <>
864EIGEN_STRONG_INLINE numext::int64_t pfirst<Packet2Xl>(const Packet2Xl& a) {
865 return __riscv_vmv_x_s_i64m2_i64(a);
866}
867
868template <>
869EIGEN_STRONG_INLINE Packet2Xl preverse(const Packet2Xl& a) {
870 Packet2Xul idx = __riscv_vrsub_vx_u64m2(__riscv_vid_v_u64m2(unpacket_traits<Packet2Xl>::size),
871 unpacket_traits<Packet2Xl>::size - 1, unpacket_traits<Packet2Xl>::size);
872 return __riscv_vrgather_vv_i64m2(a, idx, unpacket_traits<Packet2Xl>::size);
873}
874
875template <>
876EIGEN_STRONG_INLINE Packet2Xl pabs(const Packet2Xl& a) {
877 Packet2Xl mask = __riscv_vsra_vx_i64m2(a, 63, unpacket_traits<Packet2Xl>::size);
878 return __riscv_vsub_vv_i64m2(__riscv_vxor_vv_i64m2(a, mask, unpacket_traits<Packet2Xl>::size), mask,
879 unpacket_traits<Packet2Xl>::size);
880}
881
882template <>
883EIGEN_STRONG_INLINE numext::int64_t predux<Packet2Xl>(const Packet2Xl& a) {
884 return __riscv_vmv_x(__riscv_vredsum_vs_i64m2_i64m1(a, __riscv_vmv_v_x_i64m1(0, unpacket_traits<Packet2Xl>::size / 2),
885 unpacket_traits<Packet2Xl>::size));
886}
887
888template <>
889EIGEN_STRONG_INLINE bool predux_all(const Packet2Xl& a) {
890 const PacketMask32 mask = __riscv_vmseq_vx_i64m2_b32(a, 0, unpacket_traits<Packet2Xl>::size);
891 return __riscv_vcpop_m_b32(mask, unpacket_traits<Packet2Xl>::size) == 0;
892}
893
894template <>
895EIGEN_STRONG_INLINE numext::int64_t predux_mul<Packet2Xl>(const Packet2Xl& a) {
896 return predux_mul<Packet1Xl>(__riscv_vmul_vv_i64m1(__riscv_vget_v_i64m2_i64m1(a, 0), __riscv_vget_v_i64m2_i64m1(a, 1),
897 unpacket_traits<Packet1Xl>::size));
898}
899
900template <>
901EIGEN_STRONG_INLINE numext::int64_t predux_min<Packet2Xl>(const Packet2Xl& a) {
902 return __riscv_vmv_x(__riscv_vredmin_vs_i64m2_i64m1(
903 a, __riscv_vmv_v_x_i64m1((std::numeric_limits<numext::int64_t>::max)(), unpacket_traits<Packet2Xl>::size / 2),
904 unpacket_traits<Packet2Xl>::size));
905}
906
907template <>
908EIGEN_STRONG_INLINE numext::int64_t predux_max<Packet2Xl>(const Packet2Xl& a) {
909 return __riscv_vmv_x(__riscv_vredmax_vs_i64m2_i64m1(
910 a, __riscv_vmv_v_x_i64m1((std::numeric_limits<numext::int64_t>::min)(), unpacket_traits<Packet2Xl>::size / 2),
911 unpacket_traits<Packet2Xl>::size));
912}
913
914template <int N>
915EIGEN_DEVICE_FUNC inline void ptranspose(PacketBlock<Packet2Xl, N>& kernel) {
916 numext::int64_t buffer[unpacket_traits<Packet2Xl>::size * N] = {0};
917 int i = 0;
918
919 for (i = 0; i < N; i++) {
920 __riscv_vsse64(&buffer[i], N * sizeof(numext::int64_t), kernel.packet[i], unpacket_traits<Packet2Xl>::size);
921 }
922 for (i = 0; i < N; i++) {
923 kernel.packet[i] =
924 __riscv_vle64_v_i64m2(&buffer[i * unpacket_traits<Packet2Xl>::size], unpacket_traits<Packet2Xl>::size);
925 }
926}
927
928template <typename Packet = Packet2Xl>
929EIGEN_STRONG_INLINE
930 std::enable_if_t<std::is_same<Packet, Packet2Xl>::value && (unpacket_traits<Packet2Xl>::size % 8) == 0, Packet1Xl>
931 predux_half(const Packet2Xl& a) {
932 return __riscv_vadd_vv_i64m1(__riscv_vget_v_i64m2_i64m1(a, 0), __riscv_vget_v_i64m2_i64m1(a, 1),
933 unpacket_traits<Packet1Xl>::size);
934}
935
936/********************************* Packet2Xd ************************************/
937
938template <>
939EIGEN_STRONG_INLINE Packet2Xd ptrue<Packet2Xd>(const Packet2Xd& /*a*/) {
940 Packet2Xd r =
941 __riscv_vreinterpret_f64m2(__riscv_vmv_v_x_u64m2(0xffffffffffffffffu, unpacket_traits<Packet2Xd>::size));
942 EIGEN_FAST_MATH_CONSTANT_BARRIER(r);
943 return r;
944}
945
946template <>
947EIGEN_STRONG_INLINE Packet2Xd pzero<Packet2Xd>(const Packet2Xd& /*a*/) {
948 return __riscv_vfmv_v_f_f64m2(0.0, unpacket_traits<Packet2Xd>::size);
949}
950
951template <>
952EIGEN_STRONG_INLINE Packet2Xd pabs(const Packet2Xd& a) {
953 return __riscv_vfabs_v_f64m2(a, unpacket_traits<Packet2Xd>::size);
954}
955
956template <>
957EIGEN_STRONG_INLINE Packet2Xd pabsdiff(const Packet2Xd& a, const Packet2Xd& b) {
958 return __riscv_vfabs_v_f64m2(__riscv_vfsub_vv_f64m2(a, b, unpacket_traits<Packet2Xd>::size),
959 unpacket_traits<Packet2Xd>::size);
960}
961
962template <>
963EIGEN_STRONG_INLINE Packet2Xd pset1<Packet2Xd>(const double& from) {
964 return __riscv_vfmv_v_f_f64m2(from, unpacket_traits<Packet2Xd>::size);
965}
966
967template <>
968EIGEN_STRONG_INLINE Packet2Xd pset1frombits<Packet2Xd>(numext::uint64_t from) {
969 return __riscv_vreinterpret_f64m2(__riscv_vmv_v_x_u64m2(from, unpacket_traits<Packet2Xd>::size));
970}
971
972template <>
973EIGEN_STRONG_INLINE Packet2Xd plset<Packet2Xd>(const double& a) {
974 Packet2Xd idx = __riscv_vfcvt_f_x_v_f64m2(
975 __riscv_vreinterpret_v_u64m2_i64m2(__riscv_vid_v_u64m2(unpacket_traits<Packet4Xi>::size)),
976 unpacket_traits<Packet2Xd>::size);
977 return __riscv_vfadd_vf_f64m2(idx, a, unpacket_traits<Packet2Xd>::size);
978}
979
980template <>
981EIGEN_STRONG_INLINE void pbroadcast4<Packet2Xd>(const double* a, Packet2Xd& a0, Packet2Xd& a1, Packet2Xd& a2,
982 Packet2Xd& a3) {
983 Packet2Xd aa;
984 EIGEN_IF_CONSTEXPR (EIGEN_RISCV64_RVV_VL >= 256) {
985 aa = __riscv_vlmul_ext_f64m2(__riscv_vle64_v_f64m1(a, 4));
986 } else {
987 aa = __riscv_vle64_v_f64m2(a, 4);
988 }
989 a0 = __riscv_vrgather_vx_f64m2(aa, 0, unpacket_traits<Packet2Xd>::size);
990 a1 = __riscv_vrgather_vx_f64m2(aa, 1, unpacket_traits<Packet2Xd>::size);
991 a2 = __riscv_vrgather_vx_f64m2(aa, 2, unpacket_traits<Packet2Xd>::size);
992 a3 = __riscv_vrgather_vx_f64m2(aa, 3, unpacket_traits<Packet2Xd>::size);
993}
994
995template <>
996EIGEN_STRONG_INLINE Packet2Xd padd<Packet2Xd>(const Packet2Xd& a, const Packet2Xd& b) {
997 return __riscv_vfadd_vv_f64m2(a, b, unpacket_traits<Packet2Xd>::size);
998}
999
1000template <>
1001EIGEN_STRONG_INLINE Packet2Xd psub<Packet2Xd>(const Packet2Xd& a, const Packet2Xd& b) {
1002 return __riscv_vfsub_vv_f64m2(a, b, unpacket_traits<Packet2Xd>::size);
1003}
1004
1005template <>
1006EIGEN_STRONG_INLINE Packet2Xd pnegate(const Packet2Xd& a) {
1007 return __riscv_vfneg_v_f64m2(a, unpacket_traits<Packet2Xd>::size);
1008}
1009
1010template <>
1011EIGEN_STRONG_INLINE Packet2Xd psignbit(const Packet2Xd& a) {
1012 return __riscv_vreinterpret_v_i64m2_f64m2(
1013 __riscv_vsra_vx_i64m2(__riscv_vreinterpret_v_f64m2_i64m2(a), 63, unpacket_traits<Packet2Xl>::size));
1014}
1015
1016template <>
1017EIGEN_STRONG_INLINE Packet2Xd pmul<Packet2Xd>(const Packet2Xd& a, const Packet2Xd& b) {
1018 return __riscv_vfmul_vv_f64m2(a, b, unpacket_traits<Packet2Xd>::size);
1019}
1020
1021template <>
1022EIGEN_STRONG_INLINE Packet2Xd pdiv<Packet2Xd>(const Packet2Xd& a, const Packet2Xd& b) {
1023 return __riscv_vfdiv_vv_f64m2(a, b, unpacket_traits<Packet2Xd>::size);
1024}
1025
1026template <>
1027EIGEN_STRONG_INLINE Packet2Xd pmadd(const Packet2Xd& a, const Packet2Xd& b, const Packet2Xd& c) {
1028 return __riscv_vfmadd_vv_f64m2(a, b, c, unpacket_traits<Packet2Xd>::size);
1029}
1030
1031template <>
1032EIGEN_STRONG_INLINE Packet2Xd pmsub(const Packet2Xd& a, const Packet2Xd& b, const Packet2Xd& c) {
1033 return __riscv_vfmsub_vv_f64m2(a, b, c, unpacket_traits<Packet2Xd>::size);
1034}
1035
1036template <>
1037EIGEN_STRONG_INLINE Packet2Xd pnmadd(const Packet2Xd& a, const Packet2Xd& b, const Packet2Xd& c) {
1038 return __riscv_vfnmsub_vv_f64m2(a, b, c, unpacket_traits<Packet2Xd>::size);
1039}
1040
1041template <>
1042EIGEN_STRONG_INLINE Packet2Xd pnmsub(const Packet2Xd& a, const Packet2Xd& b, const Packet2Xd& c) {
1043 return __riscv_vfnmadd_vv_f64m2(a, b, c, unpacket_traits<Packet2Xd>::size);
1044}
1045
1046template <>
1047struct pminmax_propagates_nan<Packet2Xd> : bool_constant<true> {};
1048
1049template <>
1050EIGEN_STRONG_INLINE Packet2Xd pmin<Packet2Xd>(const Packet2Xd& a, const Packet2Xd& b) {
1051 Packet2Xd nans = __riscv_vfmv_v_f_f64m2((std::numeric_limits<double>::quiet_NaN)(), unpacket_traits<Packet2Xd>::size);
1052 PacketMask32 mask = __riscv_vmfeq_vv_f64m2_b32(a, a, unpacket_traits<Packet2Xd>::size);
1053 PacketMask32 mask2 = __riscv_vmfeq_vv_f64m2_b32(b, b, unpacket_traits<Packet2Xd>::size);
1054 mask = __riscv_vmand_mm_b32(mask, mask2, unpacket_traits<Packet2Xd>::size);
1055
1056 return __riscv_vfmin_vv_f64m2_tumu(mask, nans, a, b, unpacket_traits<Packet2Xd>::size);
1057}
1058
1059template <>
1060EIGEN_STRONG_INLINE Packet2Xd pmin<PropagateNumbers, Packet2Xd>(const Packet2Xd& a, const Packet2Xd& b) {
1061 return __riscv_vfmin_vv_f64m2(a, b, unpacket_traits<Packet2Xd>::size);
1062}
1063
1064template <>
1065EIGEN_STRONG_INLINE Packet2Xd pmax<Packet2Xd>(const Packet2Xd& a, const Packet2Xd& b) {
1066 Packet2Xd nans = __riscv_vfmv_v_f_f64m2((std::numeric_limits<double>::quiet_NaN)(), unpacket_traits<Packet2Xd>::size);
1067 PacketMask32 mask = __riscv_vmfeq_vv_f64m2_b32(a, a, unpacket_traits<Packet2Xd>::size);
1068 PacketMask32 mask2 = __riscv_vmfeq_vv_f64m2_b32(b, b, unpacket_traits<Packet2Xd>::size);
1069 mask = __riscv_vmand_mm_b32(mask, mask2, unpacket_traits<Packet2Xd>::size);
1070
1071 return __riscv_vfmax_vv_f64m2_tumu(mask, nans, a, b, unpacket_traits<Packet2Xd>::size);
1072}
1073
1074template <>
1075EIGEN_STRONG_INLINE Packet2Xd pmax<PropagateNumbers, Packet2Xd>(const Packet2Xd& a, const Packet2Xd& b) {
1076 return __riscv_vfmax_vv_f64m2(a, b, unpacket_traits<Packet2Xd>::size);
1077}
1078
1079template <>
1080EIGEN_STRONG_INLINE Packet2Xd pcmp_le<Packet2Xd>(const Packet2Xd& a, const Packet2Xd& b) {
1081 PacketMask32 mask = __riscv_vmfle_vv_f64m2_b32(a, b, unpacket_traits<Packet2Xd>::size);
1082 return __riscv_vmerge_vvm_f64m2(pzero<Packet2Xd>(a), ptrue<Packet2Xd>(a), mask, unpacket_traits<Packet2Xd>::size);
1083}
1084
1085template <>
1086EIGEN_STRONG_INLINE Packet2Xd pcmp_lt<Packet2Xd>(const Packet2Xd& a, const Packet2Xd& b) {
1087 PacketMask32 mask = __riscv_vmflt_vv_f64m2_b32(a, b, unpacket_traits<Packet2Xd>::size);
1088 return __riscv_vmerge_vvm_f64m2(pzero<Packet2Xd>(a), ptrue<Packet2Xd>(a), mask, unpacket_traits<Packet2Xd>::size);
1089}
1090
1091template <>
1092EIGEN_STRONG_INLINE Packet2Xd pcmp_eq<Packet2Xd>(const Packet2Xd& a, const Packet2Xd& b) {
1093 PacketMask32 mask = __riscv_vmfeq_vv_f64m2_b32(a, b, unpacket_traits<Packet2Xd>::size);
1094 return __riscv_vmerge_vvm_f64m2(pzero<Packet2Xd>(a), ptrue<Packet2Xd>(a), mask, unpacket_traits<Packet2Xd>::size);
1095}
1096
1097template <>
1098EIGEN_STRONG_INLINE Packet2Xd pcmp_lt_or_nan<Packet2Xd>(const Packet2Xd& a, const Packet2Xd& b) {
1099 PacketMask32 mask = __riscv_vmfge_vv_f64m2_b32(a, b, unpacket_traits<Packet2Xd>::size);
1100 return __riscv_vfmerge_vfm_f64m2(ptrue<Packet2Xd>(a), 0.0, mask, unpacket_traits<Packet2Xd>::size);
1101}
1102
1103EIGEN_STRONG_INLINE Packet2Xd pselect(const PacketMask32& mask, const Packet2Xd& a, const Packet2Xd& b) {
1104 return __riscv_vmerge_vvm_f64m2(b, a, mask, unpacket_traits<Packet2Xd>::size);
1105}
1106
1107EIGEN_STRONG_INLINE Packet2Xd pselect(const Packet2Xd& mask, const Packet2Xd& a, const Packet2Xd& b) {
1108 PacketMask32 mask2 =
1109 __riscv_vmsne_vx_i64m2_b32(__riscv_vreinterpret_v_f64m2_i64m2(mask), 0, unpacket_traits<Packet2Xd>::size);
1110 return __riscv_vmerge_vvm_f64m2(b, a, mask2, unpacket_traits<Packet2Xd>::size);
1111}
1112
1113// Logical Operations are not supported for double, so reinterpret casts
1114template <>
1115EIGEN_STRONG_INLINE Packet2Xd pand<Packet2Xd>(const Packet2Xd& a, const Packet2Xd& b) {
1116 return __riscv_vreinterpret_v_u64m2_f64m2(__riscv_vand_vv_u64m2(
1117 __riscv_vreinterpret_v_f64m2_u64m2(a), __riscv_vreinterpret_v_f64m2_u64m2(b), unpacket_traits<Packet2Xd>::size));
1118}
1119
1120template <>
1121EIGEN_STRONG_INLINE Packet2Xd por<Packet2Xd>(const Packet2Xd& a, const Packet2Xd& b) {
1122 return __riscv_vreinterpret_v_u64m2_f64m2(__riscv_vor_vv_u64m2(
1123 __riscv_vreinterpret_v_f64m2_u64m2(a), __riscv_vreinterpret_v_f64m2_u64m2(b), unpacket_traits<Packet2Xd>::size));
1124}
1125
1126template <>
1127EIGEN_STRONG_INLINE Packet2Xd pxor<Packet2Xd>(const Packet2Xd& a, const Packet2Xd& b) {
1128 return __riscv_vreinterpret_v_u64m2_f64m2(__riscv_vxor_vv_u64m2(
1129 __riscv_vreinterpret_v_f64m2_u64m2(a), __riscv_vreinterpret_v_f64m2_u64m2(b), unpacket_traits<Packet2Xd>::size));
1130}
1131
1132template <>
1133EIGEN_STRONG_INLINE Packet2Xd pandnot<Packet2Xd>(const Packet2Xd& a, const Packet2Xd& b) {
1134#ifndef __riscv_zvbb
1135 return __riscv_vreinterpret_v_u64m2_f64m2(__riscv_vand_vv_u64m2(
1136 __riscv_vreinterpret_v_f64m2_u64m2(a),
1137 __riscv_vnot_v_u64m2(__riscv_vreinterpret_v_f64m2_u64m2(b), unpacket_traits<Packet2Xd>::size),
1138 unpacket_traits<Packet2Xd>::size));
1139#else
1140 return __riscv_vreinterpret_v_u64m2_f64m2(__riscv_vandn_vv_u64m2(
1141 __riscv_vreinterpret_v_f64m2_u64m2(a), __riscv_vreinterpret_v_f64m2_u64m2(b), unpacket_traits<Packet2Xl>::size));
1142#endif
1143}
1144
1145template <>
1146EIGEN_STRONG_INLINE Packet2Xd pnot<Packet2Xd>(const Packet2Xd& a) {
1147 return __riscv_vreinterpret_v_u64m2_f64m2(
1148 __riscv_vnot_v_u64m2(__riscv_vreinterpret_v_f64m2_u64m2(a), unpacket_traits<Packet2Xd>::size));
1149}
1150
1151template <>
1152EIGEN_STRONG_INLINE Packet2Xd pload<Packet2Xd>(const double* from) {
1153 EIGEN_DEBUG_ALIGNED_LOAD return __riscv_vle64_v_f64m2(from, unpacket_traits<Packet2Xd>::size);
1154}
1155
1156template <>
1157EIGEN_STRONG_INLINE Packet2Xd ploadu<Packet2Xd>(const double* from) {
1158 EIGEN_DEBUG_UNALIGNED_LOAD return __riscv_vle64_v_f64m2(from, unpacket_traits<Packet2Xd>::size);
1159}
1160
1161EIGEN_STRONG_INLINE Packet4Xd pdup(const Packet2Xd& a) {
1162 Packet4Xul idx =
1163 __riscv_vsrl_vx_u64m4(__riscv_vid_v_u64m4(unpacket_traits<Packet4Xd>::size), 1, unpacket_traits<Packet4Xd>::size);
1164 return __riscv_vrgather_vv_f64m4(__riscv_vlmul_ext_v_f64m2_f64m4(a), idx, unpacket_traits<Packet4Xd>::size);
1165}
1166
1167template <>
1168EIGEN_STRONG_INLINE Packet2Xd ploaddup<Packet2Xd>(const double* from) {
1169 Packet2Xul idx =
1170 __riscv_vsrl_vx_u64m2(__riscv_vid_v_u64m2(unpacket_traits<Packet2Xd>::size), 1, unpacket_traits<Packet2Xd>::size);
1171 return __riscv_vrgather_vv_f64m2(__riscv_vlmul_ext_v_f64m1_f64m2(pload<Packet1Xd>(from)), idx,
1172 unpacket_traits<Packet2Xd>::size);
1173}
1174
1175template <>
1176EIGEN_STRONG_INLINE Packet2Xd ploadquad<Packet2Xd>(const double* from) {
1177 Packet2Xul idx =
1178 __riscv_vsrl_vx_u64m2(__riscv_vid_v_u64m2(unpacket_traits<Packet2Xd>::size), 2, unpacket_traits<Packet2Xd>::size);
1179 return __riscv_vrgather_vv_f64m2(__riscv_vlmul_ext_v_f64m1_f64m2(pload<Packet1Xd>(from)), idx,
1180 unpacket_traits<Packet2Xd>::size);
1181}
1182
1183template <>
1184EIGEN_STRONG_INLINE void pstore<double>(double* to, const Packet2Xd& from) {
1185 EIGEN_DEBUG_ALIGNED_STORE __riscv_vse64_v_f64m2(to, from, unpacket_traits<Packet2Xd>::size);
1186}
1187
1188template <>
1189EIGEN_STRONG_INLINE void pstoreu<double>(double* to, const Packet2Xd& from) {
1190 EIGEN_DEBUG_UNALIGNED_STORE __riscv_vse64_v_f64m2(to, from, unpacket_traits<Packet2Xd>::size);
1191}
1192
1193template <>
1194EIGEN_DEVICE_FUNC inline Packet2Xd pgather<double, Packet2Xd>(const double* from, Index stride) {
1195 return __riscv_vlse64_v_f64m2(from, stride * sizeof(double), unpacket_traits<Packet2Xd>::size);
1196}
1197
1198template <>
1199EIGEN_DEVICE_FUNC inline void pscatter<double, Packet2Xd>(double* to, const Packet2Xd& from, Index stride) {
1200 __riscv_vsse64(to, stride * sizeof(double), from, unpacket_traits<Packet2Xd>::size);
1201}
1202
1203template <>
1204EIGEN_STRONG_INLINE double pfirst<Packet2Xd>(const Packet2Xd& a) {
1205 return __riscv_vfmv_f_s_f64m2_f64(a);
1206}
1207
1208template <>
1209EIGEN_STRONG_INLINE Packet2Xd psqrt(const Packet2Xd& a) {
1210 return __riscv_vfsqrt_v_f64m2(a, unpacket_traits<Packet2Xd>::size);
1211}
1212
1213template <>
1214EIGEN_STRONG_INLINE Packet2Xd print<Packet2Xd>(const Packet2Xd& a) {
1215 const Packet2Xd limit = pset1<Packet2Xd>(static_cast<double>(1ull << 52));
1216 const Packet2Xd abs_a = pabs(a);
1217
1218 PacketMask32 mask = __riscv_vmfne_vv_f64m2_b32(a, a, unpacket_traits<Packet2Xd>::size);
1219 const Packet2Xd x = __riscv_vfadd_vv_f64m2_tumu(mask, a, a, a, unpacket_traits<Packet2Xd>::size);
1220 const Packet2Xd new_x = __riscv_vfcvt_f_x_v_f64m2(__riscv_vfcvt_x_f_v_i64m2(a, unpacket_traits<Packet2Xd>::size),
1221 unpacket_traits<Packet2Xd>::size);
1222
1223 mask = __riscv_vmflt_vv_f64m2_b32(abs_a, limit, unpacket_traits<Packet2Xd>::size);
1224 Packet2Xd signed_x = __riscv_vfsgnj_vv_f64m2(new_x, x, unpacket_traits<Packet2Xd>::size);
1225 return __riscv_vmerge_vvm_f64m2(x, signed_x, mask, unpacket_traits<Packet2Xd>::size);
1226}
1227
1228template <>
1229EIGEN_STRONG_INLINE Packet2Xd pfloor<Packet2Xd>(const Packet2Xd& a) {
1230 Packet2Xd tmp = print<Packet2Xd>(a);
1231 // If greater, subtract one.
1232 PacketMask32 mask = __riscv_vmflt_vv_f64m2_b32(a, tmp, unpacket_traits<Packet2Xd>::size);
1233 return __riscv_vfsub_vf_f64m2_tumu(mask, tmp, tmp, 1.0, unpacket_traits<Packet2Xd>::size);
1234}
1235
1236template <>
1237EIGEN_STRONG_INLINE Packet2Xd preverse(const Packet2Xd& a) {
1238 Packet2Xul idx = __riscv_vrsub_vx_u64m2(__riscv_vid_v_u64m2(unpacket_traits<Packet2Xd>::size),
1239 unpacket_traits<Packet2Xd>::size - 1, unpacket_traits<Packet2Xd>::size);
1240 return __riscv_vrgather_vv_f64m2(a, idx, unpacket_traits<Packet2Xd>::size);
1241}
1242
1243template <>
1244EIGEN_STRONG_INLINE Packet2Xd pfrexp<Packet2Xd>(const Packet2Xd& a, Packet2Xd& exponent) {
1245 return pfrexp_generic(a, exponent);
1246}
1247
1248template <>
1249EIGEN_STRONG_INLINE double predux<Packet2Xd>(const Packet2Xd& a) {
1250 return __riscv_vfmv_f(__riscv_vfredusum_vs_f64m2_f64m1(
1251 a, __riscv_vfmv_v_f_f64m1(0.0, unpacket_traits<Packet2Xd>::size / 2), unpacket_traits<Packet2Xd>::size));
1252}
1253
1254template <>
1255EIGEN_STRONG_INLINE bool predux_any(const Packet2Xd& a) {
1256 const PacketMask32 mask =
1257 __riscv_vmsne_vx_u64m2_b32(__riscv_vreinterpret_v_f64m2_u64m2(a), 0, unpacket_traits<Packet2Xd>::size);
1258 return __riscv_vcpop_m_b32(mask, unpacket_traits<Packet2Xd>::size) != 0;
1259}
1260
1261template <>
1262EIGEN_STRONG_INLINE bool predux_all(const Packet2Xd& a) {
1263 const PacketMask32 mask = __riscv_vmfeq_vf_f64m2_b32(a, 0.0, unpacket_traits<Packet2Xd>::size);
1264 return __riscv_vcpop_m_b32(mask, unpacket_traits<Packet2Xd>::size) == 0;
1265}
1266
1267template <>
1268EIGEN_STRONG_INLINE Index predux_count(const Packet2Xd& a) {
1269 const PacketMask32 mask = __riscv_vmfne_vf_f64m2_b32(a, 0.0, unpacket_traits<Packet2Xd>::size);
1270 return static_cast<Index>(__riscv_vcpop_m_b32(mask, unpacket_traits<Packet2Xd>::size));
1271}
1272
1273template <>
1274EIGEN_STRONG_INLINE double predux_mul<Packet2Xd>(const Packet2Xd& a) {
1275 return predux_mul<Packet1Xd>(__riscv_vfmul_vv_f64m1(
1276 __riscv_vget_v_f64m2_f64m1(a, 0), __riscv_vget_v_f64m2_f64m1(a, 1), unpacket_traits<Packet1Xd>::size));
1277}
1278
1279template <>
1280EIGEN_STRONG_INLINE double predux_min<Packet2Xd>(const Packet2Xd& a) {
1281 return __riscv_vfmv_f(
1282 __riscv_vfredmin_vs_f64m2_f64m1(a, __riscv_vget_v_f64m2_f64m1(a, 0), unpacket_traits<Packet2Xd>::size));
1283}
1284
1285template <>
1286EIGEN_STRONG_INLINE double predux_max<Packet2Xd>(const Packet2Xd& a) {
1287 return __riscv_vfmv_f(
1288 __riscv_vfredmax_vs_f64m2_f64m1(a, __riscv_vget_v_f64m2_f64m1(a, 0), unpacket_traits<Packet2Xd>::size));
1289}
1290
1291#if __riscv_v_min_vlen >= 256
1292template <>
1293EIGEN_STRONG_INLINE Packet1Xd predux_half(const Packet2Xd& a) {
1294 return Packet1Xd(__riscv_vfadd_vv_f64m1(__riscv_vget_v_f64m2_f64m1(a, 0), __riscv_vget_v_f64m2_f64m1(a, 1),
1295 unpacket_traits<Packet1Xd>::size));
1296}
1297#endif
1298
1299template <int N>
1300EIGEN_DEVICE_FUNC inline void ptranspose(PacketBlock<Packet2Xd, N>& kernel) {
1301 double buffer[unpacket_traits<Packet2Xd>::size * N];
1302 int i = 0;
1303
1304 for (i = 0; i < N; i++) {
1305 __riscv_vsse64(&buffer[i], N * sizeof(double), kernel.packet[i], unpacket_traits<Packet2Xd>::size);
1306 }
1307
1308 for (i = 0; i < N; i++) {
1309 kernel.packet[i] =
1310 __riscv_vle64_v_f64m2(&buffer[i * unpacket_traits<Packet2Xd>::size], unpacket_traits<Packet2Xd>::size);
1311 }
1312}
1313
1314template <>
1315EIGEN_STRONG_INLINE Packet2Xd pldexp<Packet2Xd>(const Packet2Xd& a, const Packet2Xd& exponent) {
1316 return pldexp_generic(a, exponent);
1317}
1318
1319template <typename Packet = Packet2Xd>
1320EIGEN_STRONG_INLINE
1321 std::enable_if_t<std::is_same<Packet, Packet2Xd>::value && (unpacket_traits<Packet2Xd>::size % 8) == 0, Packet1Xd>
1322 predux_half(const Packet2Xd& a) {
1323 return __riscv_vfadd_vv_f64m1(__riscv_vget_v_f64m2_f64m1(a, 0), __riscv_vget_v_f64m2_f64m1(a, 1),
1324 unpacket_traits<Packet1Xd>::size);
1325}
1326
1327/********************************* Packet2Xs ************************************/
1328
1329EIGEN_STRONG_INLINE Packet2Xs __riscv_vreinterpret_v_u32m2_i16m2(const Packet2Xu& a) {
1330 return __riscv_vreinterpret_v_i32m2_i16m2(__riscv_vreinterpret_v_u32m2_i32m2(a));
1331}
1332
1333template <>
1334EIGEN_STRONG_INLINE Packet2Xs pset1<Packet2Xs>(const numext::int16_t& from) {
1335 return __riscv_vmv_v_x_i16m2(from, unpacket_traits<Packet2Xs>::size);
1336}
1337
1338template <>
1339EIGEN_STRONG_INLINE Packet2Xs plset<Packet2Xs>(const numext::int16_t& a) {
1340 Packet2Xs idx = __riscv_vreinterpret_v_u16m2_i16m2(__riscv_vid_v_u16m2(unpacket_traits<Packet2Xs>::size));
1341 return __riscv_vadd_vx_i16m2(idx, a, unpacket_traits<Packet2Xs>::size);
1342}
1343
1344template <>
1345EIGEN_STRONG_INLINE Packet2Xs pzero<Packet2Xs>(const Packet2Xs& /*a*/) {
1346 return __riscv_vmv_v_x_i16m2(0, unpacket_traits<Packet2Xs>::size);
1347}
1348
1349template <>
1350EIGEN_STRONG_INLINE Packet2Xs padd<Packet2Xs>(const Packet2Xs& a, const Packet2Xs& b) {
1351 return __riscv_vadd_vv_i16m2(a, b, unpacket_traits<Packet2Xs>::size);
1352}
1353
1354template <>
1355EIGEN_STRONG_INLINE Packet2Xs psub<Packet2Xs>(const Packet2Xs& a, const Packet2Xs& b) {
1356 return __riscv_vsub(a, b, unpacket_traits<Packet2Xs>::size);
1357}
1358
1359template <>
1360EIGEN_STRONG_INLINE Packet2Xs pnegate(const Packet2Xs& a) {
1361 return __riscv_vneg(a, unpacket_traits<Packet2Xs>::size);
1362}
1363
1364template <>
1365EIGEN_STRONG_INLINE Packet2Xs pmul<Packet2Xs>(const Packet2Xs& a, const Packet2Xs& b) {
1366 return __riscv_vmul(a, b, unpacket_traits<Packet2Xs>::size);
1367}
1368
1369template <>
1370EIGEN_STRONG_INLINE Packet2Xs pdiv<Packet2Xs>(const Packet2Xs& a, const Packet2Xs& b) {
1371 return __riscv_vdiv(a, b, unpacket_traits<Packet2Xs>::size);
1372}
1373
1374template <>
1375EIGEN_STRONG_INLINE Packet2Xs pmadd(const Packet2Xs& a, const Packet2Xs& b, const Packet2Xs& c) {
1376 return __riscv_vmadd(a, b, c, unpacket_traits<Packet2Xs>::size);
1377}
1378
1379template <>
1380EIGEN_STRONG_INLINE Packet2Xs pmsub(const Packet2Xs& a, const Packet2Xs& b, const Packet2Xs& c) {
1381 return __riscv_vmadd(a, b, pnegate(c), unpacket_traits<Packet2Xs>::size);
1382}
1383
1384template <>
1385EIGEN_STRONG_INLINE Packet2Xs pnmadd(const Packet2Xs& a, const Packet2Xs& b, const Packet2Xs& c) {
1386 return __riscv_vnmsub_vv_i16m2(a, b, c, unpacket_traits<Packet2Xs>::size);
1387}
1388
1389template <>
1390EIGEN_STRONG_INLINE Packet2Xs pnmsub(const Packet2Xs& a, const Packet2Xs& b, const Packet2Xs& c) {
1391 return __riscv_vnmsub_vv_i16m2(a, b, pnegate(c), unpacket_traits<Packet2Xs>::size);
1392}
1393
1394template <>
1395EIGEN_STRONG_INLINE Packet2Xs pmin<Packet2Xs>(const Packet2Xs& a, const Packet2Xs& b) {
1396 return __riscv_vmin(a, b, unpacket_traits<Packet2Xs>::size);
1397}
1398
1399template <>
1400EIGEN_STRONG_INLINE Packet2Xs pmax<Packet2Xs>(const Packet2Xs& a, const Packet2Xs& b) {
1401 return __riscv_vmax(a, b, unpacket_traits<Packet2Xs>::size);
1402}
1403
1404template <>
1405EIGEN_STRONG_INLINE Packet2Xs pcmp_le<Packet2Xs>(const Packet2Xs& a, const Packet2Xs& b) {
1406 PacketMask8 mask = __riscv_vmsle_vv_i16m2_b8(a, b, unpacket_traits<Packet2Xs>::size);
1407 return __riscv_vmerge_vxm_i16m2(pzero(a), static_cast<short>(0xffff), mask, unpacket_traits<Packet2Xs>::size);
1408}
1409
1410template <>
1411EIGEN_STRONG_INLINE Packet2Xs pcmp_lt<Packet2Xs>(const Packet2Xs& a, const Packet2Xs& b) {
1412 PacketMask8 mask = __riscv_vmslt_vv_i16m2_b8(a, b, unpacket_traits<Packet2Xs>::size);
1413 return __riscv_vmerge_vxm_i16m2(pzero(a), static_cast<short>(0xffff), mask, unpacket_traits<Packet2Xs>::size);
1414}
1415
1416template <>
1417EIGEN_STRONG_INLINE Packet2Xs pcmp_eq<Packet2Xs>(const Packet2Xs& a, const Packet2Xs& b) {
1418 PacketMask8 mask = __riscv_vmseq_vv_i16m2_b8(a, b, unpacket_traits<Packet2Xs>::size);
1419 return __riscv_vmerge_vxm_i16m2(pzero(a), static_cast<short>(0xffff), mask, unpacket_traits<Packet2Xs>::size);
1420}
1421
1422template <>
1423EIGEN_STRONG_INLINE Packet2Xs ptrue<Packet2Xs>(const Packet2Xs& /*a*/) {
1424 return __riscv_vmv_v_x_i16m2(static_cast<unsigned short>(0xffffu), unpacket_traits<Packet2Xs>::size);
1425}
1426
1427template <>
1428EIGEN_STRONG_INLINE Packet2Xs pand<Packet2Xs>(const Packet2Xs& a, const Packet2Xs& b) {
1429 return __riscv_vand_vv_i16m2(a, b, unpacket_traits<Packet2Xs>::size);
1430}
1431
1432template <>
1433EIGEN_STRONG_INLINE Packet2Xs por<Packet2Xs>(const Packet2Xs& a, const Packet2Xs& b) {
1434 return __riscv_vor_vv_i16m2(a, b, unpacket_traits<Packet2Xs>::size);
1435}
1436
1437template <>
1438EIGEN_STRONG_INLINE Packet2Xs pxor<Packet2Xs>(const Packet2Xs& a, const Packet2Xs& b) {
1439 return __riscv_vxor_vv_i16m2(a, b, unpacket_traits<Packet2Xs>::size);
1440}
1441
1442template <>
1443EIGEN_STRONG_INLINE Packet2Xs pandnot<Packet2Xs>(const Packet2Xs& a, const Packet2Xs& b) {
1444#ifndef __riscv_zvbb
1445 return __riscv_vand_vv_i16m2(a, __riscv_vnot_v_i16m2(b, unpacket_traits<Packet2Xs>::size),
1446 unpacket_traits<Packet2Xs>::size);
1447#else
1448 return __riscv_vreinterpret_v_u16m2_i16m2(__riscv_vandn_vv_u16m2(
1449 __riscv_vreinterpret_v_i16m2_u16m2(a), __riscv_vreinterpret_v_i16m2_u16m2(b), unpacket_traits<Packet2Xs>::size));
1450#endif
1451}
1452
1453template <>
1454EIGEN_STRONG_INLINE Packet2Xs pnot<Packet2Xs>(const Packet2Xs& a) {
1455 return __riscv_vnot_v_i16m2(a, unpacket_traits<Packet2Xs>::size);
1456}
1457
1458template <int N>
1459EIGEN_STRONG_INLINE Packet2Xs parithmetic_shift_right(const Packet2Xs& a) {
1460 return __riscv_vsra_vx_i16m2(a, N, unpacket_traits<Packet2Xs>::size);
1461}
1462
1463template <int N>
1464EIGEN_STRONG_INLINE Packet2Xs plogical_shift_right(const Packet2Xs& a) {
1465 return __riscv_vreinterpret_i16m2(
1466 __riscv_vsrl_vx_u16m2(__riscv_vreinterpret_u16m2(a), N, unpacket_traits<Packet2Xs>::size));
1467}
1468
1469template <int N>
1470EIGEN_STRONG_INLINE Packet2Xs plogical_shift_left(const Packet2Xs& a) {
1471 return __riscv_vsll_vx_i16m2(a, N, unpacket_traits<Packet2Xs>::size);
1472}
1473
1474template <>
1475EIGEN_STRONG_INLINE Packet2Xs pload<Packet2Xs>(const numext::int16_t* from) {
1476 EIGEN_DEBUG_ALIGNED_LOAD return __riscv_vle16_v_i16m2(from, unpacket_traits<Packet2Xs>::size);
1477}
1478
1479template <>
1480EIGEN_STRONG_INLINE Packet2Xs ploadu<Packet2Xs>(const numext::int16_t* from) {
1481 EIGEN_DEBUG_UNALIGNED_LOAD return __riscv_vle16_v_i16m2(from, unpacket_traits<Packet2Xs>::size);
1482}
1483
1484template <>
1485EIGEN_STRONG_INLINE Packet2Xs ploaddup<Packet2Xs>(const numext::int16_t* from) {
1486 Packet2Xu data = __riscv_vlmul_trunc_v_u32m4_u32m2(__riscv_vwcvtu_x_x_v_u32m4(
1487 __riscv_vreinterpret_v_i16m2_u16m2(pload<Packet2Xs>(from)), unpacket_traits<Packet2Xs>::size));
1488 return __riscv_vreinterpret_v_u32m2_i16m2(__riscv_vadd_vv_u32m2(
1489 __riscv_vsll_vx_u32m2(data, 16, unpacket_traits<Packet2Xi>::size), data, unpacket_traits<Packet2Xi>::size));
1490}
1491
1492template <>
1493EIGEN_STRONG_INLINE Packet2Xs ploadquad<Packet2Xs>(const numext::int16_t* from) {
1494 Packet2Xsu idx =
1495 __riscv_vsrl_vx_u16m2(__riscv_vid_v_u16m2(unpacket_traits<Packet2Xs>::size), 2, unpacket_traits<Packet2Xs>::size);
1496 return __riscv_vrgather_vv_i16m2(pload<Packet2Xs>(from), idx, unpacket_traits<Packet2Xs>::size);
1497}
1498
1499template <>
1500EIGEN_STRONG_INLINE void pstore<numext::int16_t>(numext::int16_t* to, const Packet2Xs& from) {
1501 EIGEN_DEBUG_ALIGNED_STORE __riscv_vse16_v_i16m2(to, from, unpacket_traits<Packet2Xs>::size);
1502}
1503
1504template <>
1505EIGEN_STRONG_INLINE void pstoreu<numext::int16_t>(numext::int16_t* to, const Packet2Xs& from) {
1506 EIGEN_DEBUG_UNALIGNED_STORE __riscv_vse16_v_i16m2(to, from, unpacket_traits<Packet2Xs>::size);
1507}
1508
1509template <>
1510EIGEN_DEVICE_FUNC inline Packet2Xs pgather<numext::int16_t, Packet2Xs>(const numext::int16_t* from, Index stride) {
1511 return __riscv_vlse16_v_i16m2(from, stride * sizeof(numext::int16_t), unpacket_traits<Packet2Xs>::size);
1512}
1513
1514template <>
1515EIGEN_DEVICE_FUNC inline void pscatter<numext::int16_t, Packet2Xs>(numext::int16_t* to, const Packet2Xs& from,
1516 Index stride) {
1517 __riscv_vsse16(to, stride * sizeof(numext::int16_t), from, unpacket_traits<Packet2Xs>::size);
1518}
1519
1520template <>
1521EIGEN_STRONG_INLINE numext::int16_t pfirst<Packet2Xs>(const Packet2Xs& a) {
1522 return __riscv_vmv_x_s_i16m2_i16(a);
1523}
1524
1525template <>
1526EIGEN_STRONG_INLINE Packet2Xs preverse(const Packet2Xs& a) {
1527 Packet2Xsu idx = __riscv_vrsub_vx_u16m2(__riscv_vid_v_u16m2(unpacket_traits<Packet2Xs>::size),
1528 unpacket_traits<Packet2Xs>::size - 1, unpacket_traits<Packet2Xs>::size);
1529 return __riscv_vrgather_vv_i16m2(a, idx, unpacket_traits<Packet2Xs>::size);
1530}
1531
1532template <>
1533EIGEN_STRONG_INLINE Packet2Xs pabs(const Packet2Xs& a) {
1534 Packet2Xs mask = __riscv_vsra_vx_i16m2(a, 15, unpacket_traits<Packet2Xs>::size);
1535 return __riscv_vsub_vv_i16m2(__riscv_vxor_vv_i16m2(a, mask, unpacket_traits<Packet2Xs>::size), mask,
1536 unpacket_traits<Packet2Xs>::size);
1537}
1538
1539template <>
1540EIGEN_STRONG_INLINE numext::int16_t predux<Packet2Xs>(const Packet2Xs& a) {
1541 return __riscv_vmv_x(__riscv_vredsum_vs_i16m2_i16m1(a, __riscv_vmv_v_x_i16m1(0, unpacket_traits<Packet2Xs>::size / 2),
1542 unpacket_traits<Packet2Xs>::size));
1543}
1544
1545template <>
1546EIGEN_STRONG_INLINE bool predux_all(const Packet2Xs& a) {
1547 const PacketMask8 mask = __riscv_vmseq_vx_i16m2_b8(a, 0, unpacket_traits<Packet2Xs>::size);
1548 return __riscv_vcpop_m_b8(mask, unpacket_traits<Packet2Xs>::size) == 0;
1549}
1550
1551template <>
1552EIGEN_STRONG_INLINE numext::int16_t predux_mul<Packet2Xs>(const Packet2Xs& a) {
1553 return predux_mul<Packet1Xs>(__riscv_vmul_vv_i16m1(__riscv_vget_v_i16m2_i16m1(a, 0), __riscv_vget_v_i16m2_i16m1(a, 1),
1554 unpacket_traits<Packet1Xs>::size));
1555}
1556
1557template <>
1558EIGEN_STRONG_INLINE numext::int16_t predux_min<Packet2Xs>(const Packet2Xs& a) {
1559 return __riscv_vmv_x(__riscv_vredmin_vs_i16m2_i16m1(
1560 a, __riscv_vmv_v_x_i16m1((std::numeric_limits<numext::int16_t>::max)(), unpacket_traits<Packet2Xs>::size / 2),
1561 unpacket_traits<Packet2Xs>::size));
1562}
1563
1564template <>
1565EIGEN_STRONG_INLINE numext::int16_t predux_max<Packet2Xs>(const Packet2Xs& a) {
1566 return __riscv_vmv_x(__riscv_vredmax_vs_i16m2_i16m1(
1567 a, __riscv_vmv_v_x_i16m1((std::numeric_limits<numext::int16_t>::min)(), unpacket_traits<Packet2Xs>::size / 2),
1568 unpacket_traits<Packet2Xs>::size));
1569}
1570
1571template <int N>
1572EIGEN_DEVICE_FUNC inline void ptranspose(PacketBlock<Packet2Xs, N>& kernel) {
1573 numext::int16_t buffer[unpacket_traits<Packet2Xs>::size * N] = {0};
1574 int i = 0;
1575
1576 for (i = 0; i < N; i++) {
1577 __riscv_vsse16(&buffer[i], N * sizeof(numext::int16_t), kernel.packet[i], unpacket_traits<Packet2Xs>::size);
1578 }
1579 for (i = 0; i < N; i++) {
1580 kernel.packet[i] =
1581 __riscv_vle16_v_i16m2(&buffer[i * unpacket_traits<Packet2Xs>::size], unpacket_traits<Packet2Xs>::size);
1582 }
1583}
1584
1585template <typename Packet = Packet2Xs>
1586EIGEN_STRONG_INLINE
1587 std::enable_if_t<std::is_same<Packet, Packet2Xs>::value && (unpacket_traits<Packet2Xs>::size % 8) == 0, Packet1Xs>
1588 predux_half(const Packet2Xs& a) {
1589 return __riscv_vadd_vv_i16m1(__riscv_vget_v_i16m2_i16m1(a, 0), __riscv_vget_v_i16m2_i16m1(a, 1),
1590 unpacket_traits<Packet1Xs>::size);
1591}
1592
1593} // namespace internal
1594} // namespace Eigen
1595
1596#endif // EIGEN_PACKET2_MATH_RVV10_H