Eigen  5.0.1
 
Loading...
Searching...
No Matches
PacketMath4.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_PACKET4_MATH_RVV10_H
13#define EIGEN_PACKET4_MATH_RVV10_H
14
15// IWYU pragma: private
16#include "../../InternalHeaderCheck.h"
17
18namespace Eigen {
19namespace internal {
20
21/********************************* Packet4Xi ************************************/
22
23EIGEN_STRONG_INLINE Packet4Xi __riscv_vreinterpret_v_u64m4_i32m4(const Packet4Xul& a) {
24 return __riscv_vreinterpret_v_i64m4_i32m4(__riscv_vreinterpret_v_u64m4_i64m4(a));
25}
26
27template <>
28EIGEN_STRONG_INLINE Packet4Xi pset1<Packet4Xi>(const numext::int32_t& from) {
29 return __riscv_vmv_v_x_i32m4(from, unpacket_traits<Packet4Xi>::size);
30}
31
32template <>
33EIGEN_STRONG_INLINE Packet4Xi plset<Packet4Xi>(const numext::int32_t& a) {
34 Packet4Xi idx = __riscv_vreinterpret_v_u32m4_i32m4(__riscv_vid_v_u32m4(unpacket_traits<Packet4Xi>::size));
35 return __riscv_vadd_vx_i32m4(idx, a, unpacket_traits<Packet4Xi>::size);
36}
37
38template <>
39EIGEN_STRONG_INLINE Packet4Xi pzero<Packet4Xi>(const Packet4Xi& /*a*/) {
40 return __riscv_vmv_v_x_i32m4(0, unpacket_traits<Packet4Xi>::size);
41}
42
43template <>
44EIGEN_STRONG_INLINE Packet4Xi padd<Packet4Xi>(const Packet4Xi& a, const Packet4Xi& b) {
45 return __riscv_vadd_vv_i32m4(a, b, unpacket_traits<Packet4Xi>::size);
46}
47
48template <>
49EIGEN_STRONG_INLINE Packet4Xi psub<Packet4Xi>(const Packet4Xi& a, const Packet4Xi& b) {
50 return __riscv_vsub(a, b, unpacket_traits<Packet4Xi>::size);
51}
52
53template <>
54EIGEN_STRONG_INLINE Packet4Xi pnegate(const Packet4Xi& a) {
55 return __riscv_vneg(a, unpacket_traits<Packet4Xi>::size);
56}
57
58template <>
59EIGEN_STRONG_INLINE Packet4Xi pmul<Packet4Xi>(const Packet4Xi& a, const Packet4Xi& b) {
60 return __riscv_vmul(a, b, unpacket_traits<Packet4Xi>::size);
61}
62
63template <>
64EIGEN_STRONG_INLINE Packet4Xi pdiv<Packet4Xi>(const Packet4Xi& a, const Packet4Xi& b) {
65 return __riscv_vdiv(a, b, unpacket_traits<Packet4Xi>::size);
66}
67
68template <>
69EIGEN_STRONG_INLINE Packet4Xi pmadd(const Packet4Xi& a, const Packet4Xi& b, const Packet4Xi& c) {
70 return __riscv_vmadd(a, b, c, unpacket_traits<Packet4Xi>::size);
71}
72
73template <>
74EIGEN_STRONG_INLINE Packet4Xi pmsub(const Packet4Xi& a, const Packet4Xi& b, const Packet4Xi& c) {
75 return __riscv_vmadd(a, b, pnegate(c), unpacket_traits<Packet4Xi>::size);
76}
77
78template <>
79EIGEN_STRONG_INLINE Packet4Xi pnmadd(const Packet4Xi& a, const Packet4Xi& b, const Packet4Xi& c) {
80 return __riscv_vnmsub_vv_i32m4(a, b, c, unpacket_traits<Packet4Xi>::size);
81}
82
83template <>
84EIGEN_STRONG_INLINE Packet4Xi pnmsub(const Packet4Xi& a, const Packet4Xi& b, const Packet4Xi& c) {
85 return __riscv_vnmsub_vv_i32m4(a, b, pnegate(c), unpacket_traits<Packet4Xi>::size);
86}
87
88template <>
89EIGEN_STRONG_INLINE Packet4Xi pmin<Packet4Xi>(const Packet4Xi& a, const Packet4Xi& b) {
90 return __riscv_vmin(a, b, unpacket_traits<Packet4Xi>::size);
91}
92
93template <>
94EIGEN_STRONG_INLINE Packet4Xi pmax<Packet4Xi>(const Packet4Xi& a, const Packet4Xi& b) {
95 return __riscv_vmax(a, b, unpacket_traits<Packet4Xi>::size);
96}
97
98template <>
99EIGEN_STRONG_INLINE Packet4Xi pcmp_le<Packet4Xi>(const Packet4Xi& a, const Packet4Xi& b) {
100 PacketMask8 mask = __riscv_vmsle_vv_i32m4_b8(a, b, unpacket_traits<Packet4Xi>::size);
101 return __riscv_vmerge_vxm_i32m4(pzero(a), 0xffffffff, mask, unpacket_traits<Packet4Xi>::size);
102}
103
104template <>
105EIGEN_STRONG_INLINE Packet4Xi pcmp_lt<Packet4Xi>(const Packet4Xi& a, const Packet4Xi& b) {
106 PacketMask8 mask = __riscv_vmslt_vv_i32m4_b8(a, b, unpacket_traits<Packet4Xi>::size);
107 return __riscv_vmerge_vxm_i32m4(pzero(a), 0xffffffff, mask, unpacket_traits<Packet4Xi>::size);
108}
109
110template <>
111EIGEN_STRONG_INLINE Packet4Xi pcmp_eq<Packet4Xi>(const Packet4Xi& a, const Packet4Xi& b) {
112 PacketMask8 mask = __riscv_vmseq_vv_i32m4_b8(a, b, unpacket_traits<Packet4Xi>::size);
113 return __riscv_vmerge_vxm_i32m4(pzero(a), 0xffffffff, mask, unpacket_traits<Packet4Xi>::size);
114}
115
116template <>
117EIGEN_STRONG_INLINE Packet4Xi ptrue<Packet4Xi>(const Packet4Xi& /*a*/) {
118 return __riscv_vmv_v_x_i32m4(0xffffffffu, unpacket_traits<Packet4Xi>::size);
119}
120
121template <>
122EIGEN_STRONG_INLINE Packet4Xi pand<Packet4Xi>(const Packet4Xi& a, const Packet4Xi& b) {
123 return __riscv_vand_vv_i32m4(a, b, unpacket_traits<Packet4Xi>::size);
124}
125
126template <>
127EIGEN_STRONG_INLINE Packet4Xi por<Packet4Xi>(const Packet4Xi& a, const Packet4Xi& b) {
128 return __riscv_vor_vv_i32m4(a, b, unpacket_traits<Packet4Xi>::size);
129}
130
131template <>
132EIGEN_STRONG_INLINE Packet4Xi pxor<Packet4Xi>(const Packet4Xi& a, const Packet4Xi& b) {
133 return __riscv_vxor_vv_i32m4(a, b, unpacket_traits<Packet4Xi>::size);
134}
135
136template <>
137EIGEN_STRONG_INLINE Packet4Xi pandnot<Packet4Xi>(const Packet4Xi& a, const Packet4Xi& b) {
138#ifndef __riscv_zvbb
139 return __riscv_vand_vv_i32m4(a, __riscv_vnot_v_i32m4(b, unpacket_traits<Packet4Xi>::size),
140 unpacket_traits<Packet4Xi>::size);
141#else
142 return __riscv_vreinterpret_v_u32m4_i32m4(__riscv_vandn_vv_u32m4(
143 __riscv_vreinterpret_v_i32m4_u32m4(a), __riscv_vreinterpret_v_i32m4_u32m4(b), unpacket_traits<Packet4Xi>::size));
144#endif
145}
146
147template <>
148EIGEN_STRONG_INLINE Packet4Xi pnot<Packet4Xi>(const Packet4Xi& a) {
149 return __riscv_vnot_v_i32m4(a, unpacket_traits<Packet4Xi>::size);
150}
151
152template <int N>
153EIGEN_STRONG_INLINE Packet4Xi parithmetic_shift_right(const Packet4Xi& a) {
154 return __riscv_vsra_vx_i32m4(a, N, unpacket_traits<Packet4Xi>::size);
155}
156
157template <int N>
158EIGEN_STRONG_INLINE Packet4Xi plogical_shift_right(const Packet4Xi& a) {
159 return __riscv_vreinterpret_i32m4(
160 __riscv_vsrl_vx_u32m4(__riscv_vreinterpret_u32m4(a), N, unpacket_traits<Packet4Xi>::size));
161}
162
163template <int N>
164EIGEN_STRONG_INLINE Packet4Xi plogical_shift_left(const Packet4Xi& a) {
165 return __riscv_vsll_vx_i32m4(a, N, unpacket_traits<Packet4Xi>::size);
166}
167
168template <>
169EIGEN_STRONG_INLINE Packet4Xi pload<Packet4Xi>(const numext::int32_t* from) {
170 EIGEN_DEBUG_ALIGNED_LOAD return __riscv_vle32_v_i32m4(from, unpacket_traits<Packet4Xi>::size);
171}
172
173template <>
174EIGEN_STRONG_INLINE Packet4Xi ploadu<Packet4Xi>(const numext::int32_t* from) {
175 EIGEN_DEBUG_UNALIGNED_LOAD return __riscv_vle32_v_i32m4(from, unpacket_traits<Packet4Xi>::size);
176}
177
178template <>
179EIGEN_STRONG_INLINE Packet4Xi ploaddup<Packet4Xi>(const numext::int32_t* from) {
180 Packet4Xul data = __riscv_vwcvtu_x_x_v_u64m4(__riscv_vreinterpret_v_i32m2_u32m2(pload<Packet2Xi>(from)),
181 unpacket_traits<Packet2Xi>::size);
182 return __riscv_vreinterpret_v_u64m4_i32m4(__riscv_vadd_vv_u64m4(
183 __riscv_vsll_vx_u64m4(data, 32, unpacket_traits<Packet4Xl>::size), data, unpacket_traits<Packet4Xl>::size));
184}
185
186template <>
187EIGEN_STRONG_INLINE Packet4Xi ploadquad<Packet4Xi>(const numext::int32_t* from) {
188 Packet4Xu idx =
189 __riscv_vsrl_vx_u32m4(__riscv_vid_v_u32m4(unpacket_traits<Packet4Xi>::size), 2, unpacket_traits<Packet4Xi>::size);
190 return __riscv_vrgather_vv_i32m4(__riscv_vlmul_ext_v_i32m1_i32m4(pload<Packet1Xi>(from)), idx,
191 unpacket_traits<Packet4Xi>::size);
192}
193
194template <>
195EIGEN_STRONG_INLINE void pstore<numext::int32_t>(numext::int32_t* to, const Packet4Xi& from) {
196 EIGEN_DEBUG_ALIGNED_STORE __riscv_vse32_v_i32m4(to, from, unpacket_traits<Packet4Xi>::size);
197}
198
199template <>
200EIGEN_STRONG_INLINE void pstoreu<numext::int32_t>(numext::int32_t* to, const Packet4Xi& from) {
201 EIGEN_DEBUG_UNALIGNED_STORE __riscv_vse32_v_i32m4(to, from, unpacket_traits<Packet4Xi>::size);
202}
203
204template <>
205EIGEN_DEVICE_FUNC inline Packet4Xi pgather<numext::int32_t, Packet4Xi>(const numext::int32_t* from, Index stride) {
206 return __riscv_vlse32_v_i32m4(from, stride * sizeof(numext::int32_t), unpacket_traits<Packet4Xi>::size);
207}
208
209template <>
210EIGEN_DEVICE_FUNC inline void pscatter<numext::int32_t, Packet4Xi>(numext::int32_t* to, const Packet4Xi& from,
211 Index stride) {
212 __riscv_vsse32(to, stride * sizeof(numext::int32_t), from, unpacket_traits<Packet4Xi>::size);
213}
214
215template <>
216EIGEN_STRONG_INLINE numext::int32_t pfirst<Packet4Xi>(const Packet4Xi& a) {
217 return __riscv_vmv_x_s_i32m4_i32(a);
218}
219
220template <>
221EIGEN_STRONG_INLINE Packet4Xi preverse(const Packet4Xi& a) {
222 Packet4Xu idx = __riscv_vrsub_vx_u32m4(__riscv_vid_v_u32m4(unpacket_traits<Packet4Xi>::size),
223 unpacket_traits<Packet4Xi>::size - 1, unpacket_traits<Packet4Xi>::size);
224 return __riscv_vrgather_vv_i32m4(a, idx, unpacket_traits<Packet4Xi>::size);
225}
226
227template <>
228EIGEN_STRONG_INLINE Packet4Xi pabs(const Packet4Xi& a) {
229 Packet4Xi mask = __riscv_vsra_vx_i32m4(a, 31, unpacket_traits<Packet4Xi>::size);
230 return __riscv_vsub_vv_i32m4(__riscv_vxor_vv_i32m4(a, mask, unpacket_traits<Packet4Xi>::size), mask,
231 unpacket_traits<Packet4Xi>::size);
232}
233
234template <>
235EIGEN_STRONG_INLINE numext::int32_t predux<Packet4Xi>(const Packet4Xi& a) {
236 return __riscv_vmv_x(__riscv_vredsum_vs_i32m4_i32m1(a, __riscv_vmv_v_x_i32m1(0, unpacket_traits<Packet4Xi>::size / 4),
237 unpacket_traits<Packet4Xi>::size));
238}
239
240template <>
241EIGEN_STRONG_INLINE bool predux_all(const Packet4Xi& a) {
242 const PacketMask8 mask = __riscv_vmseq_vx_i32m4_b8(a, 0, unpacket_traits<Packet4Xi>::size);
243 return __riscv_vcpop_m_b8(mask, unpacket_traits<Packet4Xi>::size) == 0;
244}
245
246template <>
247EIGEN_STRONG_INLINE numext::int32_t predux_mul<Packet4Xi>(const Packet4Xi& a) {
248 Packet1Xi half1 = __riscv_vmul_vv_i32m1(__riscv_vget_v_i32m4_i32m1(a, 0), __riscv_vget_v_i32m4_i32m1(a, 1),
249 unpacket_traits<Packet1Xi>::size);
250 Packet1Xi half2 = __riscv_vmul_vv_i32m1(__riscv_vget_v_i32m4_i32m1(a, 2), __riscv_vget_v_i32m4_i32m1(a, 3),
251 unpacket_traits<Packet1Xi>::size);
252 return predux_mul<Packet1Xi>(__riscv_vmul_vv_i32m1(half1, half2, unpacket_traits<Packet1Xi>::size));
253}
254
255template <>
256EIGEN_STRONG_INLINE numext::int32_t predux_min<Packet4Xi>(const Packet4Xi& a) {
257 return __riscv_vmv_x(__riscv_vredmin_vs_i32m4_i32m1(
258 a, __riscv_vmv_v_x_i32m1((std::numeric_limits<numext::int32_t>::max)(), unpacket_traits<Packet4Xi>::size / 4),
259 unpacket_traits<Packet4Xi>::size));
260}
261
262template <>
263EIGEN_STRONG_INLINE numext::int32_t predux_max<Packet4Xi>(const Packet4Xi& a) {
264 return __riscv_vmv_x(__riscv_vredmax_vs_i32m4_i32m1(
265 a, __riscv_vmv_v_x_i32m1((std::numeric_limits<numext::int32_t>::min)(), unpacket_traits<Packet4Xi>::size / 4),
266 unpacket_traits<Packet4Xi>::size));
267}
268
269template <int N>
270EIGEN_DEVICE_FUNC inline void ptranspose(PacketBlock<Packet4Xi, N>& kernel) {
271 numext::int32_t buffer[unpacket_traits<Packet4Xi>::size * N] = {0};
272 int i = 0;
273
274 for (i = 0; i < N; i++) {
275 __riscv_vsse32(&buffer[i], N * sizeof(numext::int32_t), kernel.packet[i], unpacket_traits<Packet4Xi>::size);
276 }
277 for (i = 0; i < N; i++) {
278 kernel.packet[i] =
279 __riscv_vle32_v_i32m4(&buffer[i * unpacket_traits<Packet4Xi>::size], unpacket_traits<Packet4Xi>::size);
280 }
281}
282
283template <typename Packet = Packet4Xi>
284EIGEN_STRONG_INLINE
285 std::enable_if_t<std::is_same<Packet, Packet4Xi>::value && (unpacket_traits<Packet4Xi>::size % 8) == 0, Packet2Xi>
286 predux_half(const Packet4Xi& a) {
287 return __riscv_vadd_vv_i32m2(__riscv_vget_v_i32m4_i32m2(a, 0), __riscv_vget_v_i32m4_i32m2(a, 1),
288 unpacket_traits<Packet2Xi>::size);
289}
290
291/********************************* Packet4Xf ************************************/
292
293template <>
294EIGEN_STRONG_INLINE Packet4Xf ptrue<Packet4Xf>(const Packet4Xf& /*a*/) {
295 Packet4Xf r = __riscv_vreinterpret_f32m4(__riscv_vmv_v_x_u32m4(0xffffffffu, unpacket_traits<Packet4Xf>::size));
296 EIGEN_FAST_MATH_CONSTANT_BARRIER(r);
297 return r;
298}
299
300template <>
301EIGEN_STRONG_INLINE Packet4Xf pzero<Packet4Xf>(const Packet4Xf& /*a*/) {
302 return __riscv_vfmv_v_f_f32m4(0.0f, unpacket_traits<Packet4Xf>::size);
303}
304
305template <>
306EIGEN_STRONG_INLINE Packet4Xf pabs(const Packet4Xf& a) {
307 return __riscv_vfabs_v_f32m4(a, unpacket_traits<Packet4Xf>::size);
308}
309
310template <>
311EIGEN_STRONG_INLINE Packet4Xf pabsdiff(const Packet4Xf& a, const Packet4Xf& b) {
312 return __riscv_vfabs_v_f32m4(__riscv_vfsub_vv_f32m4(a, b, unpacket_traits<Packet4Xf>::size),
313 unpacket_traits<Packet4Xf>::size);
314}
315
316template <>
317EIGEN_STRONG_INLINE Packet4Xf pset1<Packet4Xf>(const float& from) {
318 return __riscv_vfmv_v_f_f32m4(from, unpacket_traits<Packet4Xf>::size);
319}
320
321template <>
322EIGEN_STRONG_INLINE Packet4Xf pset1frombits<Packet4Xf>(numext::uint32_t from) {
323 return __riscv_vreinterpret_f32m4(__riscv_vmv_v_x_u32m4(from, unpacket_traits<Packet4Xf>::size));
324}
325
326template <>
327EIGEN_STRONG_INLINE Packet4Xf plset<Packet4Xf>(const float& a) {
328 Packet4Xf idx = __riscv_vfcvt_f_x_v_f32m4(
329 __riscv_vreinterpret_v_u32m4_i32m4(__riscv_vid_v_u32m4(unpacket_traits<Packet4Xi>::size)),
330 unpacket_traits<Packet4Xf>::size);
331 return __riscv_vfadd_vf_f32m4(idx, a, unpacket_traits<Packet4Xf>::size);
332}
333
334template <>
335EIGEN_STRONG_INLINE void pbroadcast4<Packet4Xf>(const float* a, Packet4Xf& a0, Packet4Xf& a1, Packet4Xf& a2,
336 Packet4Xf& a3) {
337 Packet4Xf aa = __riscv_vlmul_ext_f32m4(__riscv_vle32_v_f32m1(a, 4));
338 a0 = __riscv_vrgather_vx_f32m4(aa, 0, unpacket_traits<Packet4Xf>::size);
339 a1 = __riscv_vrgather_vx_f32m4(aa, 1, unpacket_traits<Packet4Xf>::size);
340 a2 = __riscv_vrgather_vx_f32m4(aa, 2, unpacket_traits<Packet4Xf>::size);
341 a3 = __riscv_vrgather_vx_f32m4(aa, 3, unpacket_traits<Packet4Xf>::size);
342}
343
344template <>
345EIGEN_STRONG_INLINE Packet4Xf padd<Packet4Xf>(const Packet4Xf& a, const Packet4Xf& b) {
346 return __riscv_vfadd_vv_f32m4(a, b, unpacket_traits<Packet4Xf>::size);
347}
348
349template <>
350EIGEN_STRONG_INLINE Packet4Xf psub<Packet4Xf>(const Packet4Xf& a, const Packet4Xf& b) {
351 return __riscv_vfsub_vv_f32m4(a, b, unpacket_traits<Packet4Xf>::size);
352}
353
354template <>
355EIGEN_STRONG_INLINE Packet4Xf pnegate(const Packet4Xf& a) {
356 return __riscv_vfneg_v_f32m4(a, unpacket_traits<Packet4Xf>::size);
357}
358
359template <>
360EIGEN_STRONG_INLINE Packet4Xf psignbit(const Packet4Xf& a) {
361 return __riscv_vreinterpret_v_i32m4_f32m4(
362 __riscv_vsra_vx_i32m4(__riscv_vreinterpret_v_f32m4_i32m4(a), 31, unpacket_traits<Packet4Xi>::size));
363}
364
365template <>
366EIGEN_STRONG_INLINE Packet4Xf pmul<Packet4Xf>(const Packet4Xf& a, const Packet4Xf& b) {
367 return __riscv_vfmul_vv_f32m4(a, b, unpacket_traits<Packet4Xf>::size);
368}
369
370template <>
371EIGEN_STRONG_INLINE Packet4Xf pdiv<Packet4Xf>(const Packet4Xf& a, const Packet4Xf& b) {
372 return __riscv_vfdiv_vv_f32m4(a, b, unpacket_traits<Packet4Xf>::size);
373}
374
375template <>
376EIGEN_STRONG_INLINE Packet4Xf pmadd(const Packet4Xf& a, const Packet4Xf& b, const Packet4Xf& c) {
377 return __riscv_vfmadd_vv_f32m4(a, b, c, unpacket_traits<Packet4Xf>::size);
378}
379
380template <>
381EIGEN_STRONG_INLINE Packet4Xf pmsub(const Packet4Xf& a, const Packet4Xf& b, const Packet4Xf& c) {
382 return __riscv_vfmsub_vv_f32m4(a, b, c, unpacket_traits<Packet4Xf>::size);
383}
384
385template <>
386EIGEN_STRONG_INLINE Packet4Xf pnmadd(const Packet4Xf& a, const Packet4Xf& b, const Packet4Xf& c) {
387 return __riscv_vfnmsub_vv_f32m4(a, b, c, unpacket_traits<Packet4Xf>::size);
388}
389
390template <>
391EIGEN_STRONG_INLINE Packet4Xf pnmsub(const Packet4Xf& a, const Packet4Xf& b, const Packet4Xf& c) {
392 return __riscv_vfnmadd_vv_f32m4(a, b, c, unpacket_traits<Packet4Xf>::size);
393}
394
395template <>
396struct pminmax_propagates_nan<Packet4Xf> : bool_constant<true> {};
397
398template <>
399EIGEN_STRONG_INLINE Packet4Xf pmin<Packet4Xf>(const Packet4Xf& a, const Packet4Xf& b) {
400 Packet4Xf nans = __riscv_vfmv_v_f_f32m4((std::numeric_limits<float>::quiet_NaN)(), unpacket_traits<Packet4Xf>::size);
401 PacketMask8 mask = __riscv_vmfeq_vv_f32m4_b8(a, a, unpacket_traits<Packet4Xf>::size);
402 PacketMask8 mask2 = __riscv_vmfeq_vv_f32m4_b8(b, b, unpacket_traits<Packet4Xf>::size);
403 mask = __riscv_vmand_mm_b8(mask, mask2, unpacket_traits<Packet4Xf>::size);
404
405 return __riscv_vfmin_vv_f32m4_tumu(mask, nans, a, b, unpacket_traits<Packet4Xf>::size);
406}
407
408template <>
409EIGEN_STRONG_INLINE Packet4Xf pmin<PropagateNumbers, Packet4Xf>(const Packet4Xf& a, const Packet4Xf& b) {
410 return __riscv_vfmin_vv_f32m4(a, b, unpacket_traits<Packet4Xf>::size);
411}
412
413template <>
414EIGEN_STRONG_INLINE Packet4Xf pmax<Packet4Xf>(const Packet4Xf& a, const Packet4Xf& b) {
415 Packet4Xf nans = __riscv_vfmv_v_f_f32m4((std::numeric_limits<float>::quiet_NaN)(), unpacket_traits<Packet4Xf>::size);
416 PacketMask8 mask = __riscv_vmfeq_vv_f32m4_b8(a, a, unpacket_traits<Packet4Xf>::size);
417 PacketMask8 mask2 = __riscv_vmfeq_vv_f32m4_b8(b, b, unpacket_traits<Packet4Xf>::size);
418 mask = __riscv_vmand_mm_b8(mask, mask2, unpacket_traits<Packet4Xf>::size);
419
420 return __riscv_vfmax_vv_f32m4_tumu(mask, nans, a, b, unpacket_traits<Packet4Xf>::size);
421}
422
423template <>
424EIGEN_STRONG_INLINE Packet4Xf pmax<PropagateNumbers, Packet4Xf>(const Packet4Xf& a, const Packet4Xf& b) {
425 return __riscv_vfmax_vv_f32m4(a, b, unpacket_traits<Packet4Xf>::size);
426}
427
428template <>
429EIGEN_STRONG_INLINE Packet4Xf pcmp_le<Packet4Xf>(const Packet4Xf& a, const Packet4Xf& b) {
430 PacketMask8 mask = __riscv_vmfle_vv_f32m4_b8(a, b, unpacket_traits<Packet4Xf>::size);
431 return __riscv_vmerge_vvm_f32m4(pzero<Packet4Xf>(a), ptrue<Packet4Xf>(a), mask, unpacket_traits<Packet4Xf>::size);
432}
433
434template <>
435EIGEN_STRONG_INLINE Packet4Xf pcmp_lt<Packet4Xf>(const Packet4Xf& a, const Packet4Xf& b) {
436 PacketMask8 mask = __riscv_vmflt_vv_f32m4_b8(a, b, unpacket_traits<Packet4Xf>::size);
437 return __riscv_vmerge_vvm_f32m4(pzero<Packet4Xf>(a), ptrue<Packet4Xf>(a), mask, unpacket_traits<Packet4Xf>::size);
438}
439
440template <>
441EIGEN_STRONG_INLINE Packet4Xf pcmp_eq<Packet4Xf>(const Packet4Xf& a, const Packet4Xf& b) {
442 PacketMask8 mask = __riscv_vmfeq_vv_f32m4_b8(a, b, unpacket_traits<Packet4Xf>::size);
443 return __riscv_vmerge_vvm_f32m4(pzero<Packet4Xf>(a), ptrue<Packet4Xf>(a), mask, unpacket_traits<Packet4Xf>::size);
444}
445
446template <>
447EIGEN_STRONG_INLINE Packet4Xf pcmp_lt_or_nan<Packet4Xf>(const Packet4Xf& a, const Packet4Xf& b) {
448 PacketMask8 mask = __riscv_vmfge_vv_f32m4_b8(a, b, unpacket_traits<Packet4Xf>::size);
449 return __riscv_vfmerge_vfm_f32m4(ptrue<Packet4Xf>(a), 0.0f, mask, unpacket_traits<Packet4Xf>::size);
450}
451
452EIGEN_STRONG_INLINE Packet4Xf pselect(const PacketMask8& mask, const Packet4Xf& a, const Packet4Xf& b) {
453 return __riscv_vmerge_vvm_f32m4(b, a, mask, unpacket_traits<Packet4Xf>::size);
454}
455
456EIGEN_STRONG_INLINE Packet4Xf pselect(const Packet4Xf& mask, const Packet4Xf& a, const Packet4Xf& b) {
457 PacketMask8 mask2 =
458 __riscv_vmsne_vx_i32m4_b8(__riscv_vreinterpret_v_f32m4_i32m4(mask), 0, unpacket_traits<Packet4Xf>::size);
459 return __riscv_vmerge_vvm_f32m4(b, a, mask2, unpacket_traits<Packet4Xf>::size);
460}
461
462// Logical Operations are not supported for float, so reinterpret casts
463template <>
464EIGEN_STRONG_INLINE Packet4Xf pand<Packet4Xf>(const Packet4Xf& a, const Packet4Xf& b) {
465 return __riscv_vreinterpret_v_u32m4_f32m4(__riscv_vand_vv_u32m4(
466 __riscv_vreinterpret_v_f32m4_u32m4(a), __riscv_vreinterpret_v_f32m4_u32m4(b), unpacket_traits<Packet4Xf>::size));
467}
468
469template <>
470EIGEN_STRONG_INLINE Packet4Xf por<Packet4Xf>(const Packet4Xf& a, const Packet4Xf& b) {
471 return __riscv_vreinterpret_v_u32m4_f32m4(__riscv_vor_vv_u32m4(
472 __riscv_vreinterpret_v_f32m4_u32m4(a), __riscv_vreinterpret_v_f32m4_u32m4(b), unpacket_traits<Packet4Xf>::size));
473}
474
475template <>
476EIGEN_STRONG_INLINE Packet4Xf pxor<Packet4Xf>(const Packet4Xf& a, const Packet4Xf& b) {
477 return __riscv_vreinterpret_v_u32m4_f32m4(__riscv_vxor_vv_u32m4(
478 __riscv_vreinterpret_v_f32m4_u32m4(a), __riscv_vreinterpret_v_f32m4_u32m4(b), unpacket_traits<Packet4Xf>::size));
479}
480
481template <>
482EIGEN_STRONG_INLINE Packet4Xf pandnot<Packet4Xf>(const Packet4Xf& a, const Packet4Xf& b) {
483#ifndef __riscv_zvbb
484 return __riscv_vreinterpret_v_u32m4_f32m4(__riscv_vand_vv_u32m4(
485 __riscv_vreinterpret_v_f32m4_u32m4(a),
486 __riscv_vnot_v_u32m4(__riscv_vreinterpret_v_f32m4_u32m4(b), unpacket_traits<Packet4Xf>::size),
487 unpacket_traits<Packet4Xf>::size));
488#else
489 return __riscv_vreinterpret_v_u32m4_f32m4(__riscv_vandn_vv_u32m4(
490 __riscv_vreinterpret_v_f32m4_u32m4(a), __riscv_vreinterpret_v_f32m4_u32m4(b), unpacket_traits<Packet4Xi>::size));
491#endif
492}
493
494template <>
495EIGEN_STRONG_INLINE Packet4Xf pnot<Packet4Xf>(const Packet4Xf& a) {
496 return __riscv_vreinterpret_v_u32m4_f32m4(
497 __riscv_vnot_v_u32m4(__riscv_vreinterpret_v_f32m4_u32m4(a), unpacket_traits<Packet4Xf>::size));
498}
499
500template <>
501EIGEN_STRONG_INLINE Packet4Xs pnot<Packet4Xs>(const Packet4Xs& a) {
502 return __riscv_vnot_v_i16m4(a, unpacket_traits<Packet4Xs>::size);
503}
504
505template <>
506EIGEN_STRONG_INLINE Packet4Xf pload<Packet4Xf>(const float* from) {
507 EIGEN_DEBUG_ALIGNED_LOAD return __riscv_vle32_v_f32m4(from, unpacket_traits<Packet4Xf>::size);
508}
509
510template <>
511EIGEN_STRONG_INLINE Packet4Xf ploadu<Packet4Xf>(const float* from) {
512 EIGEN_DEBUG_UNALIGNED_LOAD return __riscv_vle32_v_f32m4(from, unpacket_traits<Packet4Xf>::size);
513}
514
515template <>
516EIGEN_STRONG_INLINE Packet4Xf ploaddup<Packet4Xf>(const float* from) {
517 Packet4Xul data = __riscv_vwcvtu_x_x_v_u64m4(__riscv_vreinterpret_v_f32m2_u32m2(pload<Packet2Xf>(from)),
518 unpacket_traits<Packet2Xi>::size);
519 return __riscv_vreinterpret_v_u64m4_f32m4(__riscv_vadd_vv_u64m4(
520 __riscv_vsll_vx_u64m4(data, 32, unpacket_traits<Packet4Xl>::size), data, unpacket_traits<Packet4Xl>::size));
521}
522
523template <>
524EIGEN_STRONG_INLINE Packet4Xf ploadquad<Packet4Xf>(const float* from) {
525 Packet4Xu idx =
526 __riscv_vsrl_vx_u32m4(__riscv_vid_v_u32m4(unpacket_traits<Packet4Xf>::size), 2, unpacket_traits<Packet4Xf>::size);
527 return __riscv_vrgather_vv_f32m4(__riscv_vlmul_ext_v_f32m1_f32m4(pload<Packet1Xf>(from)), idx,
528 unpacket_traits<Packet4Xf>::size);
529}
530
531template <>
532EIGEN_STRONG_INLINE void pstore<float>(float* to, const Packet4Xf& from) {
533 EIGEN_DEBUG_ALIGNED_STORE __riscv_vse32_v_f32m4(to, from, unpacket_traits<Packet4Xf>::size);
534}
535
536template <>
537EIGEN_STRONG_INLINE void pstoreu<float>(float* to, const Packet4Xf& from) {
538 EIGEN_DEBUG_UNALIGNED_STORE __riscv_vse32_v_f32m4(to, from, unpacket_traits<Packet4Xf>::size);
539}
540
541template <>
542EIGEN_DEVICE_FUNC inline Packet4Xf pgather<float, Packet4Xf>(const float* from, Index stride) {
543 return __riscv_vlse32_v_f32m4(from, stride * sizeof(float), unpacket_traits<Packet4Xf>::size);
544}
545
546template <>
547EIGEN_DEVICE_FUNC inline void pscatter<float, Packet4Xf>(float* to, const Packet4Xf& from, Index stride) {
548 __riscv_vsse32(to, stride * sizeof(float), from, unpacket_traits<Packet4Xf>::size);
549}
550
551template <>
552EIGEN_STRONG_INLINE float pfirst<Packet4Xf>(const Packet4Xf& a) {
553 return __riscv_vfmv_f_s_f32m4_f32(a);
554}
555
556template <>
557EIGEN_STRONG_INLINE Packet4Xf psqrt(const Packet4Xf& a) {
558 return __riscv_vfsqrt_v_f32m4(a, unpacket_traits<Packet4Xf>::size);
559}
560
561template <>
562EIGEN_STRONG_INLINE Packet4Xf print<Packet4Xf>(const Packet4Xf& a) {
563 const Packet4Xf limit = pset1<Packet4Xf>(static_cast<float>(1 << 23));
564 const Packet4Xf abs_a = pabs(a);
565
566 PacketMask8 mask = __riscv_vmfne_vv_f32m4_b8(a, a, unpacket_traits<Packet4Xf>::size);
567 const Packet4Xf x = __riscv_vfadd_vv_f32m4_tumu(mask, a, a, a, unpacket_traits<Packet4Xf>::size);
568 const Packet4Xf new_x = __riscv_vfcvt_f_x_v_f32m4(__riscv_vfcvt_x_f_v_i32m4(a, unpacket_traits<Packet4Xf>::size),
569 unpacket_traits<Packet4Xf>::size);
570
571 mask = __riscv_vmflt_vv_f32m4_b8(abs_a, limit, unpacket_traits<Packet4Xf>::size);
572 Packet4Xf signed_x = __riscv_vfsgnj_vv_f32m4(new_x, x, unpacket_traits<Packet4Xf>::size);
573 return __riscv_vmerge_vvm_f32m4(x, signed_x, mask, unpacket_traits<Packet4Xf>::size);
574}
575
576template <>
577EIGEN_STRONG_INLINE Packet4Xf pfloor<Packet4Xf>(const Packet4Xf& a) {
578 Packet4Xf tmp = print<Packet4Xf>(a);
579 // If greater, subtract one.
580 PacketMask8 mask = __riscv_vmflt_vv_f32m4_b8(a, tmp, unpacket_traits<Packet4Xf>::size);
581 return __riscv_vfsub_vf_f32m4_tumu(mask, tmp, tmp, 1.0f, unpacket_traits<Packet4Xf>::size);
582}
583
584template <>
585EIGEN_STRONG_INLINE Packet4Xf preverse(const Packet4Xf& a) {
586 Packet4Xu idx = __riscv_vrsub_vx_u32m4(__riscv_vid_v_u32m4(unpacket_traits<Packet4Xf>::size),
587 unpacket_traits<Packet4Xf>::size - 1, unpacket_traits<Packet4Xf>::size);
588 return __riscv_vrgather_vv_f32m4(a, idx, unpacket_traits<Packet4Xf>::size);
589}
590
591template <>
592EIGEN_STRONG_INLINE Packet4Xf pfrexp<Packet4Xf>(const Packet4Xf& a, Packet4Xf& exponent) {
593 return pfrexp_generic(a, exponent);
594}
595
596template <>
597EIGEN_STRONG_INLINE float predux<Packet4Xf>(const Packet4Xf& a) {
598 return __riscv_vfmv_f(__riscv_vfredusum_vs_f32m4_f32m1(
599 a, __riscv_vfmv_v_f_f32m1(0.0f, unpacket_traits<Packet4Xf>::size / 4), unpacket_traits<Packet4Xf>::size));
600}
601
602template <>
603EIGEN_STRONG_INLINE bool predux_any(const Packet4Xf& a) {
604 const PacketMask8 mask =
605 __riscv_vmsne_vx_u32m4_b8(__riscv_vreinterpret_v_f32m4_u32m4(a), 0, unpacket_traits<Packet4Xf>::size);
606 return __riscv_vcpop_m_b8(mask, unpacket_traits<Packet4Xf>::size) != 0;
607}
608
609template <>
610EIGEN_STRONG_INLINE bool predux_all(const Packet4Xf& a) {
611 const PacketMask8 mask = __riscv_vmfeq_vf_f32m4_b8(a, 0.0f, unpacket_traits<Packet4Xf>::size);
612 return __riscv_vcpop_m_b8(mask, unpacket_traits<Packet4Xf>::size) == 0;
613}
614
615template <>
616EIGEN_STRONG_INLINE Index predux_count(const Packet4Xf& a) {
617 const PacketMask8 mask = __riscv_vmfne_vf_f32m4_b8(a, 0.0f, unpacket_traits<Packet4Xf>::size);
618 return static_cast<Index>(__riscv_vcpop_m_b8(mask, unpacket_traits<Packet4Xf>::size));
619}
620
621template <>
622EIGEN_STRONG_INLINE float predux_mul<Packet4Xf>(const Packet4Xf& a) {
623 Packet1Xf half1 = __riscv_vfmul_vv_f32m1(__riscv_vget_v_f32m4_f32m1(a, 0), __riscv_vget_v_f32m4_f32m1(a, 1),
624 unpacket_traits<Packet1Xf>::size);
625 Packet1Xf half2 = __riscv_vfmul_vv_f32m1(__riscv_vget_v_f32m4_f32m1(a, 2), __riscv_vget_v_f32m4_f32m1(a, 3),
626 unpacket_traits<Packet1Xf>::size);
627 return predux_mul<Packet1Xf>(__riscv_vfmul_vv_f32m1(half1, half2, unpacket_traits<Packet1Xf>::size));
628}
629
630// Reusing the first lane is exact for an idempotent reduction and avoids a NaN seed that becomes poison under
631// finite fast-math.
632template <>
633EIGEN_STRONG_INLINE float predux_min<Packet4Xf>(const Packet4Xf& a) {
634 return __riscv_vfmv_f(
635 __riscv_vfredmin_vs_f32m4_f32m1(a, __riscv_vget_v_f32m4_f32m1(a, 0), unpacket_traits<Packet4Xf>::size));
636}
637
638template <>
639EIGEN_STRONG_INLINE float predux_max<Packet4Xf>(const Packet4Xf& a) {
640 return __riscv_vfmv_f(
641 __riscv_vfredmax_vs_f32m4_f32m1(a, __riscv_vget_v_f32m4_f32m1(a, 0), unpacket_traits<Packet4Xf>::size));
642}
643
644template <>
645EIGEN_STRONG_INLINE Packet2Xf predux_half(const Packet4Xf& a) {
646 return Packet2Xf(__riscv_vfadd_vv_f32m2(__riscv_vget_v_f32m4_f32m2(a, 0), __riscv_vget_v_f32m4_f32m2(a, 1),
647 unpacket_traits<Packet2Xf>::size));
648}
649
650template <int N>
651EIGEN_DEVICE_FUNC inline void ptranspose(PacketBlock<Packet4Xf, N>& kernel) {
652 float buffer[unpacket_traits<Packet4Xf>::size * N];
653 int i = 0;
654
655 for (i = 0; i < N; i++) {
656 __riscv_vsse32(&buffer[i], N * sizeof(float), kernel.packet[i], unpacket_traits<Packet4Xf>::size);
657 }
658
659 for (i = 0; i < N; i++) {
660 kernel.packet[i] =
661 __riscv_vle32_v_f32m4(&buffer[i * unpacket_traits<Packet4Xf>::size], unpacket_traits<Packet4Xf>::size);
662 }
663}
664
665template <>
666EIGEN_STRONG_INLINE Packet4Xf pldexp<Packet4Xf>(const Packet4Xf& a, const Packet4Xf& exponent) {
667 return pldexp_generic(a, exponent);
668}
669
670template <typename Packet = Packet4Xf>
671EIGEN_STRONG_INLINE
672 std::enable_if_t<std::is_same<Packet, Packet4Xf>::value && (unpacket_traits<Packet4Xf>::size % 8) == 0, Packet2Xf>
673 predux_half(const Packet4Xf& a) {
674 return __riscv_vfadd_vv_f32m2(__riscv_vget_v_f32m4_f32m2(a, 0), __riscv_vget_v_f32m4_f32m2(a, 1),
675 unpacket_traits<Packet2Xf>::size);
676}
677
678/********************************* Packet4Xl ************************************/
679
680template <>
681EIGEN_STRONG_INLINE Packet4Xl pset1<Packet4Xl>(const numext::int64_t& from) {
682 return __riscv_vmv_v_x_i64m4(from, unpacket_traits<Packet4Xl>::size);
683}
684
685template <>
686EIGEN_STRONG_INLINE Packet4Xl plset<Packet4Xl>(const numext::int64_t& a) {
687 Packet4Xl idx = __riscv_vreinterpret_v_u64m4_i64m4(__riscv_vid_v_u64m4(unpacket_traits<Packet4Xl>::size));
688 return __riscv_vadd_vx_i64m4(idx, a, unpacket_traits<Packet4Xl>::size);
689}
690
691template <>
692EIGEN_STRONG_INLINE Packet4Xl pzero<Packet4Xl>(const Packet4Xl& /*a*/) {
693 return __riscv_vmv_v_x_i64m4(0, unpacket_traits<Packet4Xl>::size);
694}
695
696template <>
697EIGEN_STRONG_INLINE Packet4Xl padd<Packet4Xl>(const Packet4Xl& a, const Packet4Xl& b) {
698 return __riscv_vadd_vv_i64m4(a, b, unpacket_traits<Packet4Xl>::size);
699}
700
701template <>
702EIGEN_STRONG_INLINE Packet4Xl psub<Packet4Xl>(const Packet4Xl& a, const Packet4Xl& b) {
703 return __riscv_vsub(a, b, unpacket_traits<Packet4Xl>::size);
704}
705
706template <>
707EIGEN_STRONG_INLINE Packet4Xl pnegate(const Packet4Xl& a) {
708 return __riscv_vneg(a, unpacket_traits<Packet4Xl>::size);
709}
710
711template <>
712EIGEN_STRONG_INLINE Packet4Xl pmul<Packet4Xl>(const Packet4Xl& a, const Packet4Xl& b) {
713 return __riscv_vmul(a, b, unpacket_traits<Packet4Xl>::size);
714}
715
716template <>
717EIGEN_STRONG_INLINE Packet4Xl pdiv<Packet4Xl>(const Packet4Xl& a, const Packet4Xl& b) {
718 return __riscv_vdiv(a, b, unpacket_traits<Packet4Xl>::size);
719}
720
721template <>
722EIGEN_STRONG_INLINE Packet4Xl pmadd(const Packet4Xl& a, const Packet4Xl& b, const Packet4Xl& c) {
723 return __riscv_vmadd(a, b, c, unpacket_traits<Packet4Xl>::size);
724}
725
726template <>
727EIGEN_STRONG_INLINE Packet4Xl pmsub(const Packet4Xl& a, const Packet4Xl& b, const Packet4Xl& c) {
728 return __riscv_vmadd(a, b, pnegate(c), unpacket_traits<Packet4Xl>::size);
729}
730
731template <>
732EIGEN_STRONG_INLINE Packet4Xl pnmadd(const Packet4Xl& a, const Packet4Xl& b, const Packet4Xl& c) {
733 return __riscv_vnmsub_vv_i64m4(a, b, c, unpacket_traits<Packet4Xl>::size);
734}
735
736template <>
737EIGEN_STRONG_INLINE Packet4Xl pnmsub(const Packet4Xl& a, const Packet4Xl& b, const Packet4Xl& c) {
738 return __riscv_vnmsub_vv_i64m4(a, b, pnegate(c), unpacket_traits<Packet4Xl>::size);
739}
740
741template <>
742EIGEN_STRONG_INLINE Packet4Xl pmin<Packet4Xl>(const Packet4Xl& a, const Packet4Xl& b) {
743 return __riscv_vmin(a, b, unpacket_traits<Packet4Xl>::size);
744}
745
746template <>
747EIGEN_STRONG_INLINE Packet4Xl pmax<Packet4Xl>(const Packet4Xl& a, const Packet4Xl& b) {
748 return __riscv_vmax(a, b, unpacket_traits<Packet4Xl>::size);
749}
750
751template <>
752EIGEN_STRONG_INLINE Packet4Xl pcmp_le<Packet4Xl>(const Packet4Xl& a, const Packet4Xl& b) {
753 PacketMask16 mask = __riscv_vmsle_vv_i64m4_b16(a, b, unpacket_traits<Packet4Xl>::size);
754 return __riscv_vmerge_vxm_i64m4(pzero(a), 0xffffffffffffffff, mask, unpacket_traits<Packet4Xl>::size);
755}
756
757template <>
758EIGEN_STRONG_INLINE Packet4Xl pcmp_lt<Packet4Xl>(const Packet4Xl& a, const Packet4Xl& b) {
759 PacketMask16 mask = __riscv_vmslt_vv_i64m4_b16(a, b, unpacket_traits<Packet4Xl>::size);
760 return __riscv_vmerge_vxm_i64m4(pzero(a), 0xffffffffffffffff, mask, unpacket_traits<Packet4Xl>::size);
761}
762
763template <>
764EIGEN_STRONG_INLINE Packet4Xl pcmp_eq<Packet4Xl>(const Packet4Xl& a, const Packet4Xl& b) {
765 PacketMask16 mask = __riscv_vmseq_vv_i64m4_b16(a, b, unpacket_traits<Packet4Xl>::size);
766 return __riscv_vmerge_vxm_i64m4(pzero(a), 0xffffffffffffffff, mask, unpacket_traits<Packet4Xl>::size);
767}
768
769template <>
770EIGEN_STRONG_INLINE Packet4Xl ptrue<Packet4Xl>(const Packet4Xl& /*a*/) {
771 return __riscv_vmv_v_x_i64m4(0xffffffffffffffffu, unpacket_traits<Packet4Xl>::size);
772}
773
774template <>
775EIGEN_STRONG_INLINE Packet4Xl pand<Packet4Xl>(const Packet4Xl& a, const Packet4Xl& b) {
776 return __riscv_vand_vv_i64m4(a, b, unpacket_traits<Packet4Xl>::size);
777}
778
779template <>
780EIGEN_STRONG_INLINE Packet4Xl por<Packet4Xl>(const Packet4Xl& a, const Packet4Xl& b) {
781 return __riscv_vor_vv_i64m4(a, b, unpacket_traits<Packet4Xl>::size);
782}
783
784template <>
785EIGEN_STRONG_INLINE Packet4Xl pnot<Packet4Xl>(const Packet4Xl& a) {
786 return __riscv_vnot_v_i64m4(a, unpacket_traits<Packet4Xl>::size);
787}
788
789template <>
790EIGEN_STRONG_INLINE Packet4Xl pxor<Packet4Xl>(const Packet4Xl& a, const Packet4Xl& b) {
791 return __riscv_vxor_vv_i64m4(a, b, unpacket_traits<Packet4Xl>::size);
792}
793
794template <>
795EIGEN_STRONG_INLINE Packet4Xl pandnot<Packet4Xl>(const Packet4Xl& a, const Packet4Xl& b) {
796#ifndef __riscv_zvbb
797 return __riscv_vand_vv_i64m4(a, __riscv_vnot_v_i64m4(b, unpacket_traits<Packet4Xl>::size),
798 unpacket_traits<Packet4Xl>::size);
799#else
800 return __riscv_vreinterpret_v_u64m4_i64m4(__riscv_vandn_vv_u64m4(
801 __riscv_vreinterpret_v_i64m4_u64m4(a), __riscv_vreinterpret_v_i64m4_u64m4(b), unpacket_traits<Packet4Xl>::size));
802#endif
803}
804
805template <int N>
806EIGEN_STRONG_INLINE Packet4Xl parithmetic_shift_right(const Packet4Xl& a) {
807 return __riscv_vsra_vx_i64m4(a, N, unpacket_traits<Packet4Xl>::size);
808}
809
810template <int N>
811EIGEN_STRONG_INLINE Packet4Xl plogical_shift_right(const Packet4Xl& a) {
812 return __riscv_vreinterpret_i64m4(
813 __riscv_vsrl_vx_u64m4(__riscv_vreinterpret_u64m4(a), N, unpacket_traits<Packet4Xl>::size));
814}
815
816template <int N>
817EIGEN_STRONG_INLINE Packet4Xl plogical_shift_left(const Packet4Xl& a) {
818 return __riscv_vsll_vx_i64m4(a, N, unpacket_traits<Packet4Xl>::size);
819}
820
821template <>
822EIGEN_STRONG_INLINE Packet4Xl pload<Packet4Xl>(const numext::int64_t* from) {
823 EIGEN_DEBUG_ALIGNED_LOAD return __riscv_vle64_v_i64m4(from, unpacket_traits<Packet4Xl>::size);
824}
825
826template <>
827EIGEN_STRONG_INLINE Packet4Xl ploadu<Packet4Xl>(const numext::int64_t* from) {
828 EIGEN_DEBUG_UNALIGNED_LOAD return __riscv_vle64_v_i64m4(from, unpacket_traits<Packet4Xl>::size);
829}
830
831template <>
832EIGEN_STRONG_INLINE Packet4Xl ploaddup<Packet4Xl>(const numext::int64_t* from) {
833 Packet4Xul idx =
834 __riscv_vsrl_vx_u64m4(__riscv_vid_v_u64m4(unpacket_traits<Packet4Xl>::size), 1, unpacket_traits<Packet4Xl>::size);
835 return __riscv_vrgather_vv_i64m4(__riscv_vlmul_ext_v_i64m2_i64m4(pload<Packet2Xl>(from)), idx,
836 unpacket_traits<Packet4Xl>::size);
837}
838
839template <>
840EIGEN_STRONG_INLINE Packet4Xl ploadquad<Packet4Xl>(const numext::int64_t* from) {
841 Packet4Xul idx =
842 __riscv_vsrl_vx_u64m4(__riscv_vid_v_u64m4(unpacket_traits<Packet4Xl>::size), 2, unpacket_traits<Packet4Xl>::size);
843 return __riscv_vrgather_vv_i64m4(__riscv_vlmul_ext_v_i64m1_i64m4(pload<Packet1Xl>(from)), idx,
844 unpacket_traits<Packet4Xl>::size);
845}
846
847template <>
848EIGEN_STRONG_INLINE void pstore<numext::int64_t>(numext::int64_t* to, const Packet4Xl& from) {
849 EIGEN_DEBUG_ALIGNED_STORE __riscv_vse64_v_i64m4(to, from, unpacket_traits<Packet4Xl>::size);
850}
851
852template <>
853EIGEN_STRONG_INLINE void pstoreu<numext::int64_t>(numext::int64_t* to, const Packet4Xl& from) {
854 EIGEN_DEBUG_UNALIGNED_STORE __riscv_vse64_v_i64m4(to, from, unpacket_traits<Packet4Xl>::size);
855}
856
857template <>
858EIGEN_DEVICE_FUNC inline Packet4Xl pgather<numext::int64_t, Packet4Xl>(const numext::int64_t* from, Index stride) {
859 return __riscv_vlse64_v_i64m4(from, stride * sizeof(numext::int64_t), unpacket_traits<Packet4Xl>::size);
860}
861
862template <>
863EIGEN_DEVICE_FUNC inline void pscatter<numext::int64_t, Packet4Xl>(numext::int64_t* to, const Packet4Xl& from,
864 Index stride) {
865 __riscv_vsse64(to, stride * sizeof(numext::int64_t), from, unpacket_traits<Packet4Xl>::size);
866}
867
868template <>
869EIGEN_STRONG_INLINE numext::int64_t pfirst<Packet4Xl>(const Packet4Xl& a) {
870 return __riscv_vmv_x_s_i64m4_i64(a);
871}
872
873template <>
874EIGEN_STRONG_INLINE Packet4Xl preverse(const Packet4Xl& a) {
875 Packet4Xul idx = __riscv_vrsub_vx_u64m4(__riscv_vid_v_u64m4(unpacket_traits<Packet4Xl>::size),
876 unpacket_traits<Packet4Xl>::size - 1, unpacket_traits<Packet4Xl>::size);
877 return __riscv_vrgather_vv_i64m4(a, idx, unpacket_traits<Packet4Xl>::size);
878}
879
880template <>
881EIGEN_STRONG_INLINE Packet4Xl pabs(const Packet4Xl& a) {
882 Packet4Xl mask = __riscv_vsra_vx_i64m4(a, 63, unpacket_traits<Packet4Xl>::size);
883 return __riscv_vsub_vv_i64m4(__riscv_vxor_vv_i64m4(a, mask, unpacket_traits<Packet4Xl>::size), mask,
884 unpacket_traits<Packet4Xl>::size);
885}
886
887template <>
888EIGEN_STRONG_INLINE numext::int64_t predux<Packet4Xl>(const Packet4Xl& a) {
889 return __riscv_vmv_x(__riscv_vredsum_vs_i64m4_i64m1(a, __riscv_vmv_v_x_i64m1(0, unpacket_traits<Packet4Xl>::size / 4),
890 unpacket_traits<Packet4Xl>::size));
891}
892
893template <>
894EIGEN_STRONG_INLINE bool predux_all(const Packet4Xl& a) {
895 const PacketMask16 mask = __riscv_vmseq_vx_i64m4_b16(a, 0, unpacket_traits<Packet4Xl>::size);
896 return __riscv_vcpop_m_b16(mask, unpacket_traits<Packet4Xl>::size) == 0;
897}
898
899template <>
900EIGEN_STRONG_INLINE numext::int64_t predux_mul<Packet4Xl>(const Packet4Xl& a) {
901 Packet1Xl half1 = __riscv_vmul_vv_i64m1(__riscv_vget_v_i64m4_i64m1(a, 0), __riscv_vget_v_i64m4_i64m1(a, 1),
902 unpacket_traits<Packet1Xl>::size);
903 Packet1Xl half2 = __riscv_vmul_vv_i64m1(__riscv_vget_v_i64m4_i64m1(a, 2), __riscv_vget_v_i64m4_i64m1(a, 3),
904 unpacket_traits<Packet1Xl>::size);
905 return predux_mul<Packet1Xl>(__riscv_vmul_vv_i64m1(half1, half2, unpacket_traits<Packet1Xl>::size));
906}
907
908template <>
909EIGEN_STRONG_INLINE numext::int64_t predux_min<Packet4Xl>(const Packet4Xl& a) {
910 return __riscv_vmv_x(__riscv_vredmin_vs_i64m4_i64m1(
911 a, __riscv_vmv_v_x_i64m1((std::numeric_limits<numext::int64_t>::max)(), unpacket_traits<Packet4Xl>::size / 4),
912 unpacket_traits<Packet4Xl>::size));
913}
914
915template <>
916EIGEN_STRONG_INLINE numext::int64_t predux_max<Packet4Xl>(const Packet4Xl& a) {
917 return __riscv_vmv_x(__riscv_vredmax_vs_i64m4_i64m1(
918 a, __riscv_vmv_v_x_i64m1((std::numeric_limits<numext::int64_t>::min)(), unpacket_traits<Packet4Xl>::size / 4),
919 unpacket_traits<Packet4Xl>::size));
920}
921
922template <int N>
923EIGEN_DEVICE_FUNC inline void ptranspose(PacketBlock<Packet4Xl, N>& kernel) {
924 numext::int64_t buffer[unpacket_traits<Packet4Xl>::size * N] = {0};
925 int i = 0;
926
927 for (i = 0; i < N; i++) {
928 __riscv_vsse64(&buffer[i], N * sizeof(numext::int64_t), kernel.packet[i], unpacket_traits<Packet4Xl>::size);
929 }
930 for (i = 0; i < N; i++) {
931 kernel.packet[i] =
932 __riscv_vle64_v_i64m4(&buffer[i * unpacket_traits<Packet4Xl>::size], unpacket_traits<Packet4Xl>::size);
933 }
934}
935
936template <typename Packet = Packet4Xl>
937EIGEN_STRONG_INLINE
938 std::enable_if_t<std::is_same<Packet, Packet4Xl>::value && (unpacket_traits<Packet4Xl>::size % 8) == 0, Packet2Xl>
939 predux_half(const Packet4Xl& a) {
940 return __riscv_vadd_vv_i64m2(__riscv_vget_v_i64m4_i64m2(a, 0), __riscv_vget_v_i64m4_i64m2(a, 1),
941 unpacket_traits<Packet2Xl>::size);
942}
943
944/********************************* Packet4Xd ************************************/
945
946template <>
947EIGEN_STRONG_INLINE Packet4Xd ptrue<Packet4Xd>(const Packet4Xd& /*a*/) {
948 Packet4Xd r =
949 __riscv_vreinterpret_f64m4(__riscv_vmv_v_x_u64m4(0xffffffffffffffffu, unpacket_traits<Packet4Xd>::size));
950 EIGEN_FAST_MATH_CONSTANT_BARRIER(r);
951 return r;
952}
953
954template <>
955EIGEN_STRONG_INLINE Packet4Xd pzero<Packet4Xd>(const Packet4Xd& /*a*/) {
956 return __riscv_vfmv_v_f_f64m4(0.0, unpacket_traits<Packet4Xd>::size);
957}
958
959template <>
960EIGEN_STRONG_INLINE Packet4Xd pabs(const Packet4Xd& a) {
961 return __riscv_vfabs_v_f64m4(a, unpacket_traits<Packet4Xd>::size);
962}
963
964template <>
965EIGEN_STRONG_INLINE Packet4Xd pabsdiff(const Packet4Xd& a, const Packet4Xd& b) {
966 return __riscv_vfabs_v_f64m4(__riscv_vfsub_vv_f64m4(a, b, unpacket_traits<Packet4Xd>::size),
967 unpacket_traits<Packet4Xd>::size);
968}
969
970template <>
971EIGEN_STRONG_INLINE Packet4Xd pset1<Packet4Xd>(const double& from) {
972 return __riscv_vfmv_v_f_f64m4(from, unpacket_traits<Packet4Xd>::size);
973}
974
975template <>
976EIGEN_STRONG_INLINE Packet4Xd pset1frombits<Packet4Xd>(numext::uint64_t from) {
977 return __riscv_vreinterpret_f64m4(__riscv_vmv_v_x_u64m4(from, unpacket_traits<Packet4Xd>::size));
978}
979
980template <>
981EIGEN_STRONG_INLINE Packet4Xd plset<Packet4Xd>(const double& a) {
982 Packet4Xd idx = __riscv_vfcvt_f_x_v_f64m4(
983 __riscv_vreinterpret_v_u64m4_i64m4(__riscv_vid_v_u64m4(unpacket_traits<Packet4Xi>::size)),
984 unpacket_traits<Packet4Xd>::size);
985 return __riscv_vfadd_vf_f64m4(idx, a, unpacket_traits<Packet4Xd>::size);
986}
987
988template <>
989EIGEN_STRONG_INLINE void pbroadcast4<Packet4Xd>(const double* a, Packet4Xd& a0, Packet4Xd& a1, Packet4Xd& a2,
990 Packet4Xd& a3) {
991 Packet4Xd aa;
992 EIGEN_IF_CONSTEXPR (EIGEN_RISCV64_RVV_VL >= 256) {
993 aa = __riscv_vlmul_ext_f64m4(__riscv_vle64_v_f64m1(a, 4));
994 } else {
995 aa = __riscv_vlmul_ext_f64m4(__riscv_vle64_v_f64m2(a, 4));
996 }
997 a0 = __riscv_vrgather_vx_f64m4(aa, 0, unpacket_traits<Packet4Xd>::size);
998 a1 = __riscv_vrgather_vx_f64m4(aa, 1, unpacket_traits<Packet4Xd>::size);
999 a2 = __riscv_vrgather_vx_f64m4(aa, 2, unpacket_traits<Packet4Xd>::size);
1000 a3 = __riscv_vrgather_vx_f64m4(aa, 3, unpacket_traits<Packet4Xd>::size);
1001}
1002
1003template <>
1004EIGEN_STRONG_INLINE Packet4Xd padd<Packet4Xd>(const Packet4Xd& a, const Packet4Xd& b) {
1005 return __riscv_vfadd_vv_f64m4(a, b, unpacket_traits<Packet4Xd>::size);
1006}
1007
1008template <>
1009EIGEN_STRONG_INLINE Packet4Xd psub<Packet4Xd>(const Packet4Xd& a, const Packet4Xd& b) {
1010 return __riscv_vfsub_vv_f64m4(a, b, unpacket_traits<Packet4Xd>::size);
1011}
1012
1013template <>
1014EIGEN_STRONG_INLINE Packet4Xd pnegate(const Packet4Xd& a) {
1015 return __riscv_vfneg_v_f64m4(a, unpacket_traits<Packet4Xd>::size);
1016}
1017
1018template <>
1019EIGEN_STRONG_INLINE Packet4Xd psignbit(const Packet4Xd& a) {
1020 return __riscv_vreinterpret_v_i64m4_f64m4(
1021 __riscv_vsra_vx_i64m4(__riscv_vreinterpret_v_f64m4_i64m4(a), 63, unpacket_traits<Packet4Xl>::size));
1022}
1023
1024template <>
1025EIGEN_STRONG_INLINE Packet4Xd pmul<Packet4Xd>(const Packet4Xd& a, const Packet4Xd& b) {
1026 return __riscv_vfmul_vv_f64m4(a, b, unpacket_traits<Packet4Xd>::size);
1027}
1028
1029template <>
1030EIGEN_STRONG_INLINE Packet4Xd pdiv<Packet4Xd>(const Packet4Xd& a, const Packet4Xd& b) {
1031 return __riscv_vfdiv_vv_f64m4(a, b, unpacket_traits<Packet4Xd>::size);
1032}
1033
1034template <>
1035EIGEN_STRONG_INLINE Packet4Xd pmadd(const Packet4Xd& a, const Packet4Xd& b, const Packet4Xd& c) {
1036 return __riscv_vfmadd_vv_f64m4(a, b, c, unpacket_traits<Packet4Xd>::size);
1037}
1038
1039template <>
1040EIGEN_STRONG_INLINE Packet4Xd pmsub(const Packet4Xd& a, const Packet4Xd& b, const Packet4Xd& c) {
1041 return __riscv_vfmsub_vv_f64m4(a, b, c, unpacket_traits<Packet4Xd>::size);
1042}
1043
1044template <>
1045EIGEN_STRONG_INLINE Packet4Xd pnmadd(const Packet4Xd& a, const Packet4Xd& b, const Packet4Xd& c) {
1046 return __riscv_vfnmsub_vv_f64m4(a, b, c, unpacket_traits<Packet4Xd>::size);
1047}
1048
1049template <>
1050EIGEN_STRONG_INLINE Packet4Xd pnmsub(const Packet4Xd& a, const Packet4Xd& b, const Packet4Xd& c) {
1051 return __riscv_vfnmadd_vv_f64m4(a, b, c, unpacket_traits<Packet4Xd>::size);
1052}
1053
1054template <>
1055struct pminmax_propagates_nan<Packet4Xd> : bool_constant<true> {};
1056
1057template <>
1058EIGEN_STRONG_INLINE Packet4Xd pmin<Packet4Xd>(const Packet4Xd& a, const Packet4Xd& b) {
1059 Packet4Xd nans = __riscv_vfmv_v_f_f64m4((std::numeric_limits<double>::quiet_NaN)(), unpacket_traits<Packet4Xd>::size);
1060 PacketMask16 mask = __riscv_vmfeq_vv_f64m4_b16(a, a, unpacket_traits<Packet4Xd>::size);
1061 PacketMask16 mask2 = __riscv_vmfeq_vv_f64m4_b16(b, b, unpacket_traits<Packet4Xd>::size);
1062 mask = __riscv_vmand_mm_b16(mask, mask2, unpacket_traits<Packet4Xd>::size);
1063
1064 return __riscv_vfmin_vv_f64m4_tumu(mask, nans, a, b, unpacket_traits<Packet4Xd>::size);
1065}
1066
1067template <>
1068EIGEN_STRONG_INLINE Packet4Xd pmin<PropagateNumbers, Packet4Xd>(const Packet4Xd& a, const Packet4Xd& b) {
1069 return __riscv_vfmin_vv_f64m4(a, b, unpacket_traits<Packet4Xd>::size);
1070}
1071
1072template <>
1073EIGEN_STRONG_INLINE Packet4Xd pmax<Packet4Xd>(const Packet4Xd& a, const Packet4Xd& b) {
1074 Packet4Xd nans = __riscv_vfmv_v_f_f64m4((std::numeric_limits<double>::quiet_NaN)(), unpacket_traits<Packet4Xd>::size);
1075 PacketMask16 mask = __riscv_vmfeq_vv_f64m4_b16(a, a, unpacket_traits<Packet4Xd>::size);
1076 PacketMask16 mask2 = __riscv_vmfeq_vv_f64m4_b16(b, b, unpacket_traits<Packet4Xd>::size);
1077 mask = __riscv_vmand_mm_b16(mask, mask2, unpacket_traits<Packet4Xd>::size);
1078
1079 return __riscv_vfmax_vv_f64m4_tumu(mask, nans, a, b, unpacket_traits<Packet4Xd>::size);
1080}
1081
1082template <>
1083EIGEN_STRONG_INLINE Packet4Xd pmax<PropagateNumbers, Packet4Xd>(const Packet4Xd& a, const Packet4Xd& b) {
1084 return __riscv_vfmax_vv_f64m4(a, b, unpacket_traits<Packet4Xd>::size);
1085}
1086
1087template <>
1088EIGEN_STRONG_INLINE Packet4Xd pcmp_le<Packet4Xd>(const Packet4Xd& a, const Packet4Xd& b) {
1089 PacketMask16 mask = __riscv_vmfle_vv_f64m4_b16(a, b, unpacket_traits<Packet4Xd>::size);
1090 return __riscv_vmerge_vvm_f64m4(pzero<Packet4Xd>(a), ptrue<Packet4Xd>(a), mask, unpacket_traits<Packet4Xd>::size);
1091}
1092
1093template <>
1094EIGEN_STRONG_INLINE Packet4Xd pcmp_lt<Packet4Xd>(const Packet4Xd& a, const Packet4Xd& b) {
1095 PacketMask16 mask = __riscv_vmflt_vv_f64m4_b16(a, b, unpacket_traits<Packet4Xd>::size);
1096 return __riscv_vmerge_vvm_f64m4(pzero<Packet4Xd>(a), ptrue<Packet4Xd>(a), mask, unpacket_traits<Packet4Xd>::size);
1097}
1098
1099template <>
1100EIGEN_STRONG_INLINE Packet4Xd pcmp_eq<Packet4Xd>(const Packet4Xd& a, const Packet4Xd& b) {
1101 PacketMask16 mask = __riscv_vmfeq_vv_f64m4_b16(a, b, unpacket_traits<Packet4Xd>::size);
1102 return __riscv_vmerge_vvm_f64m4(pzero<Packet4Xd>(a), ptrue<Packet4Xd>(a), mask, unpacket_traits<Packet4Xd>::size);
1103}
1104
1105template <>
1106EIGEN_STRONG_INLINE Packet4Xd pcmp_lt_or_nan<Packet4Xd>(const Packet4Xd& a, const Packet4Xd& b) {
1107 PacketMask16 mask = __riscv_vmfge_vv_f64m4_b16(a, b, unpacket_traits<Packet4Xd>::size);
1108 return __riscv_vfmerge_vfm_f64m4(ptrue<Packet4Xd>(a), 0.0, mask, unpacket_traits<Packet4Xd>::size);
1109}
1110
1111EIGEN_STRONG_INLINE Packet4Xd pselect(const PacketMask16& mask, const Packet4Xd& a, const Packet4Xd& b) {
1112 return __riscv_vmerge_vvm_f64m4(b, a, mask, unpacket_traits<Packet4Xd>::size);
1113}
1114
1115EIGEN_STRONG_INLINE Packet4Xd pselect(const Packet4Xd& mask, const Packet4Xd& a, const Packet4Xd& b) {
1116 PacketMask16 mask2 =
1117 __riscv_vmsne_vx_i64m4_b16(__riscv_vreinterpret_v_f64m4_i64m4(mask), 0, unpacket_traits<Packet4Xd>::size);
1118 return __riscv_vmerge_vvm_f64m4(b, a, mask2, unpacket_traits<Packet4Xd>::size);
1119}
1120
1121// Logical Operations are not supported for double, so reinterpret casts
1122template <>
1123EIGEN_STRONG_INLINE Packet4Xd pand<Packet4Xd>(const Packet4Xd& a, const Packet4Xd& b) {
1124 return __riscv_vreinterpret_v_u64m4_f64m4(__riscv_vand_vv_u64m4(
1125 __riscv_vreinterpret_v_f64m4_u64m4(a), __riscv_vreinterpret_v_f64m4_u64m4(b), unpacket_traits<Packet4Xd>::size));
1126}
1127
1128template <>
1129EIGEN_STRONG_INLINE Packet4Xd por<Packet4Xd>(const Packet4Xd& a, const Packet4Xd& b) {
1130 return __riscv_vreinterpret_v_u64m4_f64m4(__riscv_vor_vv_u64m4(
1131 __riscv_vreinterpret_v_f64m4_u64m4(a), __riscv_vreinterpret_v_f64m4_u64m4(b), unpacket_traits<Packet4Xd>::size));
1132}
1133
1134template <>
1135EIGEN_STRONG_INLINE Packet4Xd pxor<Packet4Xd>(const Packet4Xd& a, const Packet4Xd& b) {
1136 return __riscv_vreinterpret_v_u64m4_f64m4(__riscv_vxor_vv_u64m4(
1137 __riscv_vreinterpret_v_f64m4_u64m4(a), __riscv_vreinterpret_v_f64m4_u64m4(b), unpacket_traits<Packet4Xd>::size));
1138}
1139
1140template <>
1141EIGEN_STRONG_INLINE Packet4Xd pandnot<Packet4Xd>(const Packet4Xd& a, const Packet4Xd& b) {
1142#ifndef __riscv_zvbb
1143 return __riscv_vreinterpret_v_u64m4_f64m4(__riscv_vand_vv_u64m4(
1144 __riscv_vreinterpret_v_f64m4_u64m4(a),
1145 __riscv_vnot_v_u64m4(__riscv_vreinterpret_v_f64m4_u64m4(b), unpacket_traits<Packet4Xd>::size),
1146 unpacket_traits<Packet4Xd>::size));
1147#else
1148 return __riscv_vreinterpret_v_u64m4_f64m4(__riscv_vandn_vv_u64m4(
1149 __riscv_vreinterpret_v_f64m4_u64m4(a), __riscv_vreinterpret_v_f64m4_u64m4(b), unpacket_traits<Packet4Xl>::size));
1150#endif
1151}
1152
1153template <>
1154EIGEN_STRONG_INLINE Packet4Xd pnot<Packet4Xd>(const Packet4Xd& a) {
1155 return __riscv_vreinterpret_v_u64m4_f64m4(
1156 __riscv_vnot_v_u64m4(__riscv_vreinterpret_v_f64m4_u64m4(a), unpacket_traits<Packet4Xd>::size));
1157}
1158
1159template <>
1160EIGEN_STRONG_INLINE Packet4Xd pload<Packet4Xd>(const double* from) {
1161 EIGEN_DEBUG_ALIGNED_LOAD return __riscv_vle64_v_f64m4(from, unpacket_traits<Packet4Xd>::size);
1162}
1163
1164template <>
1165EIGEN_STRONG_INLINE Packet4Xd ploadu<Packet4Xd>(const double* from) {
1166 EIGEN_DEBUG_UNALIGNED_LOAD return __riscv_vle64_v_f64m4(from, unpacket_traits<Packet4Xd>::size);
1167}
1168
1169template <>
1170EIGEN_STRONG_INLINE Packet4Xd ploaddup<Packet4Xd>(const double* from) {
1171 Packet4Xul idx =
1172 __riscv_vsrl_vx_u64m4(__riscv_vid_v_u64m4(unpacket_traits<Packet4Xd>::size), 1, unpacket_traits<Packet4Xd>::size);
1173 return __riscv_vrgather_vv_f64m4(__riscv_vlmul_ext_v_f64m2_f64m4(pload<Packet2Xd>(from)), idx,
1174 unpacket_traits<Packet4Xd>::size);
1175}
1176
1177template <>
1178EIGEN_STRONG_INLINE Packet4Xd ploadquad<Packet4Xd>(const double* from) {
1179 Packet4Xul idx =
1180 __riscv_vsrl_vx_u64m4(__riscv_vid_v_u64m4(unpacket_traits<Packet4Xd>::size), 2, unpacket_traits<Packet4Xd>::size);
1181 return __riscv_vrgather_vv_f64m4(__riscv_vlmul_ext_v_f64m1_f64m4(pload<Packet1Xd>(from)), idx,
1182 unpacket_traits<Packet4Xd>::size);
1183}
1184
1185template <>
1186EIGEN_STRONG_INLINE void pstore<double>(double* to, const Packet4Xd& from) {
1187 EIGEN_DEBUG_ALIGNED_STORE __riscv_vse64_v_f64m4(to, from, unpacket_traits<Packet4Xd>::size);
1188}
1189
1190template <>
1191EIGEN_STRONG_INLINE void pstoreu<double>(double* to, const Packet4Xd& from) {
1192 EIGEN_DEBUG_UNALIGNED_STORE __riscv_vse64_v_f64m4(to, from, unpacket_traits<Packet4Xd>::size);
1193}
1194
1195template <>
1196EIGEN_DEVICE_FUNC inline Packet4Xd pgather<double, Packet4Xd>(const double* from, Index stride) {
1197 return __riscv_vlse64_v_f64m4(from, stride * sizeof(double), unpacket_traits<Packet4Xd>::size);
1198}
1199
1200template <>
1201EIGEN_DEVICE_FUNC inline void pscatter<double, Packet4Xd>(double* to, const Packet4Xd& from, Index stride) {
1202 __riscv_vsse64(to, stride * sizeof(double), from, unpacket_traits<Packet4Xd>::size);
1203}
1204
1205template <>
1206EIGEN_STRONG_INLINE double pfirst<Packet4Xd>(const Packet4Xd& a) {
1207 return __riscv_vfmv_f_s_f64m4_f64(a);
1208}
1209
1210template <>
1211EIGEN_STRONG_INLINE Packet4Xd psqrt(const Packet4Xd& a) {
1212 return __riscv_vfsqrt_v_f64m4(a, unpacket_traits<Packet4Xd>::size);
1213}
1214
1215template <>
1216EIGEN_STRONG_INLINE Packet4Xd print<Packet4Xd>(const Packet4Xd& a) {
1217 const Packet4Xd limit = pset1<Packet4Xd>(static_cast<double>(1ull << 52));
1218 const Packet4Xd abs_a = pabs(a);
1219
1220 PacketMask16 mask = __riscv_vmfne_vv_f64m4_b16(a, a, unpacket_traits<Packet4Xd>::size);
1221 const Packet4Xd x = __riscv_vfadd_vv_f64m4_tumu(mask, a, a, a, unpacket_traits<Packet4Xd>::size);
1222 const Packet4Xd new_x = __riscv_vfcvt_f_x_v_f64m4(__riscv_vfcvt_x_f_v_i64m4(a, unpacket_traits<Packet4Xd>::size),
1223 unpacket_traits<Packet4Xd>::size);
1224
1225 mask = __riscv_vmflt_vv_f64m4_b16(abs_a, limit, unpacket_traits<Packet4Xd>::size);
1226 Packet4Xd signed_x = __riscv_vfsgnj_vv_f64m4(new_x, x, unpacket_traits<Packet4Xd>::size);
1227 return __riscv_vmerge_vvm_f64m4(x, signed_x, mask, unpacket_traits<Packet4Xd>::size);
1228}
1229
1230template <>
1231EIGEN_STRONG_INLINE Packet4Xd pfloor<Packet4Xd>(const Packet4Xd& a) {
1232 Packet4Xd tmp = print<Packet4Xd>(a);
1233 // If greater, subtract one.
1234 PacketMask16 mask = __riscv_vmflt_vv_f64m4_b16(a, tmp, unpacket_traits<Packet4Xd>::size);
1235 return __riscv_vfsub_vf_f64m4_tumu(mask, tmp, tmp, 1.0, unpacket_traits<Packet4Xd>::size);
1236}
1237
1238template <>
1239EIGEN_STRONG_INLINE Packet4Xd preverse(const Packet4Xd& a) {
1240 Packet4Xul idx = __riscv_vrsub_vx_u64m4(__riscv_vid_v_u64m4(unpacket_traits<Packet4Xd>::size),
1241 unpacket_traits<Packet4Xd>::size - 1, unpacket_traits<Packet4Xd>::size);
1242 return __riscv_vrgather_vv_f64m4(a, idx, unpacket_traits<Packet4Xd>::size);
1243}
1244
1245template <>
1246EIGEN_STRONG_INLINE Packet4Xd pfrexp<Packet4Xd>(const Packet4Xd& a, Packet4Xd& exponent) {
1247 return pfrexp_generic(a, exponent);
1248}
1249
1250template <>
1251EIGEN_STRONG_INLINE double predux<Packet4Xd>(const Packet4Xd& a) {
1252 return __riscv_vfmv_f(__riscv_vfredusum_vs_f64m4_f64m1(
1253 a, __riscv_vfmv_v_f_f64m1(0.0, unpacket_traits<Packet4Xd>::size / 4), unpacket_traits<Packet4Xd>::size));
1254}
1255
1256template <>
1257EIGEN_STRONG_INLINE bool predux_any(const Packet4Xd& a) {
1258 const PacketMask16 mask =
1259 __riscv_vmsne_vx_u64m4_b16(__riscv_vreinterpret_v_f64m4_u64m4(a), 0, unpacket_traits<Packet4Xd>::size);
1260 return __riscv_vcpop_m_b16(mask, unpacket_traits<Packet4Xd>::size) != 0;
1261}
1262
1263template <>
1264EIGEN_STRONG_INLINE bool predux_all(const Packet4Xd& a) {
1265 const PacketMask16 mask = __riscv_vmfeq_vf_f64m4_b16(a, 0.0, unpacket_traits<Packet4Xd>::size);
1266 return __riscv_vcpop_m_b16(mask, unpacket_traits<Packet4Xd>::size) == 0;
1267}
1268
1269template <>
1270EIGEN_STRONG_INLINE Index predux_count(const Packet4Xd& a) {
1271 const PacketMask16 mask = __riscv_vmfne_vf_f64m4_b16(a, 0.0, unpacket_traits<Packet4Xd>::size);
1272 return static_cast<Index>(__riscv_vcpop_m_b16(mask, unpacket_traits<Packet4Xd>::size));
1273}
1274
1275template <>
1276EIGEN_STRONG_INLINE double predux_mul<Packet4Xd>(const Packet4Xd& a) {
1277 Packet1Xd half1 = __riscv_vfmul_vv_f64m1(__riscv_vget_v_f64m4_f64m1(a, 0), __riscv_vget_v_f64m4_f64m1(a, 1),
1278 unpacket_traits<Packet1Xd>::size);
1279 Packet1Xd half2 = __riscv_vfmul_vv_f64m1(__riscv_vget_v_f64m4_f64m1(a, 2), __riscv_vget_v_f64m4_f64m1(a, 3),
1280 unpacket_traits<Packet1Xd>::size);
1281 return predux_mul<Packet1Xd>(__riscv_vfmul_vv_f64m1(half1, half2, unpacket_traits<Packet1Xd>::size));
1282}
1283
1284template <>
1285EIGEN_STRONG_INLINE double predux_min<Packet4Xd>(const Packet4Xd& a) {
1286 return __riscv_vfmv_f(
1287 __riscv_vfredmin_vs_f64m4_f64m1(a, __riscv_vget_v_f64m4_f64m1(a, 0), unpacket_traits<Packet4Xd>::size));
1288}
1289
1290template <>
1291EIGEN_STRONG_INLINE double predux_max<Packet4Xd>(const Packet4Xd& a) {
1292 return __riscv_vfmv_f(
1293 __riscv_vfredmax_vs_f64m4_f64m1(a, __riscv_vget_v_f64m4_f64m1(a, 0), unpacket_traits<Packet4Xd>::size));
1294}
1295
1296template <>
1297EIGEN_STRONG_INLINE Packet2Xd predux_half(const Packet4Xd& a) {
1298 return Packet2Xd(__riscv_vfadd_vv_f64m2(__riscv_vget_v_f64m4_f64m2(a, 0), __riscv_vget_v_f64m4_f64m2(a, 1),
1299 unpacket_traits<Packet2Xd>::size));
1300}
1301
1302template <int N>
1303EIGEN_DEVICE_FUNC inline void ptranspose(PacketBlock<Packet4Xd, N>& kernel) {
1304 double buffer[unpacket_traits<Packet4Xd>::size * N];
1305 int i = 0;
1306
1307 for (i = 0; i < N; i++) {
1308 __riscv_vsse64(&buffer[i], N * sizeof(double), kernel.packet[i], unpacket_traits<Packet4Xd>::size);
1309 }
1310
1311 for (i = 0; i < N; i++) {
1312 kernel.packet[i] =
1313 __riscv_vle64_v_f64m4(&buffer[i * unpacket_traits<Packet4Xd>::size], unpacket_traits<Packet4Xd>::size);
1314 }
1315}
1316
1317template <>
1318EIGEN_STRONG_INLINE Packet4Xd pldexp<Packet4Xd>(const Packet4Xd& a, const Packet4Xd& exponent) {
1319 return pldexp_generic(a, exponent);
1320}
1321
1322template <typename Packet = Packet4Xd>
1323EIGEN_STRONG_INLINE
1324 std::enable_if_t<std::is_same<Packet, Packet4Xd>::value && (unpacket_traits<Packet4Xd>::size % 8) == 0, Packet2Xd>
1325 predux_half(const Packet4Xd& a) {
1326 return __riscv_vfadd_vv_f64m2(__riscv_vget_v_f64m4_f64m2(a, 0), __riscv_vget_v_f64m4_f64m2(a, 1),
1327 unpacket_traits<Packet2Xd>::size);
1328}
1329
1330/********************************* Packet4Xs ************************************/
1331
1332EIGEN_STRONG_INLINE Packet4Xs __riscv_vreinterpret_v_u32m4_i16m4(const Packet4Xu& a) {
1333 return __riscv_vreinterpret_v_i32m4_i16m4(__riscv_vreinterpret_v_u32m4_i32m4(a));
1334}
1335
1336template <>
1337EIGEN_STRONG_INLINE Packet4Xs pset1<Packet4Xs>(const numext::int16_t& from) {
1338 return __riscv_vmv_v_x_i16m4(from, unpacket_traits<Packet4Xs>::size);
1339}
1340
1341template <>
1342EIGEN_STRONG_INLINE Packet4Xs plset<Packet4Xs>(const numext::int16_t& a) {
1343 Packet4Xs idx = __riscv_vreinterpret_v_u16m4_i16m4(__riscv_vid_v_u16m4(unpacket_traits<Packet4Xs>::size));
1344 return __riscv_vadd_vx_i16m4(idx, a, unpacket_traits<Packet4Xs>::size);
1345}
1346
1347template <>
1348EIGEN_STRONG_INLINE Packet4Xs pzero<Packet4Xs>(const Packet4Xs& /*a*/) {
1349 return __riscv_vmv_v_x_i16m4(0, unpacket_traits<Packet4Xs>::size);
1350}
1351
1352template <>
1353EIGEN_STRONG_INLINE Packet4Xs padd<Packet4Xs>(const Packet4Xs& a, const Packet4Xs& b) {
1354 return __riscv_vadd_vv_i16m4(a, b, unpacket_traits<Packet4Xs>::size);
1355}
1356
1357template <>
1358EIGEN_STRONG_INLINE Packet4Xs psub<Packet4Xs>(const Packet4Xs& a, const Packet4Xs& b) {
1359 return __riscv_vsub(a, b, unpacket_traits<Packet4Xs>::size);
1360}
1361
1362template <>
1363EIGEN_STRONG_INLINE Packet4Xs pnegate(const Packet4Xs& a) {
1364 return __riscv_vneg(a, unpacket_traits<Packet4Xs>::size);
1365}
1366
1367template <>
1368EIGEN_STRONG_INLINE Packet4Xs pmul<Packet4Xs>(const Packet4Xs& a, const Packet4Xs& b) {
1369 return __riscv_vmul(a, b, unpacket_traits<Packet4Xs>::size);
1370}
1371
1372template <>
1373EIGEN_STRONG_INLINE Packet4Xs pdiv<Packet4Xs>(const Packet4Xs& a, const Packet4Xs& b) {
1374 return __riscv_vdiv(a, b, unpacket_traits<Packet4Xs>::size);
1375}
1376
1377template <>
1378EIGEN_STRONG_INLINE Packet4Xs pmadd(const Packet4Xs& a, const Packet4Xs& b, const Packet4Xs& c) {
1379 return __riscv_vmadd(a, b, c, unpacket_traits<Packet4Xs>::size);
1380}
1381
1382template <>
1383EIGEN_STRONG_INLINE Packet4Xs pmsub(const Packet4Xs& a, const Packet4Xs& b, const Packet4Xs& c) {
1384 return __riscv_vmadd(a, b, pnegate(c), unpacket_traits<Packet4Xs>::size);
1385}
1386
1387template <>
1388EIGEN_STRONG_INLINE Packet4Xs pnmadd(const Packet4Xs& a, const Packet4Xs& b, const Packet4Xs& c) {
1389 return __riscv_vnmsub_vv_i16m4(a, b, c, unpacket_traits<Packet4Xs>::size);
1390}
1391
1392template <>
1393EIGEN_STRONG_INLINE Packet4Xs pnmsub(const Packet4Xs& a, const Packet4Xs& b, const Packet4Xs& c) {
1394 return __riscv_vnmsub_vv_i16m4(a, b, pnegate(c), unpacket_traits<Packet4Xs>::size);
1395}
1396
1397template <>
1398EIGEN_STRONG_INLINE Packet4Xs pmin<Packet4Xs>(const Packet4Xs& a, const Packet4Xs& b) {
1399 return __riscv_vmin(a, b, unpacket_traits<Packet4Xs>::size);
1400}
1401
1402template <>
1403EIGEN_STRONG_INLINE Packet4Xs pmax<Packet4Xs>(const Packet4Xs& a, const Packet4Xs& b) {
1404 return __riscv_vmax(a, b, unpacket_traits<Packet4Xs>::size);
1405}
1406
1407template <>
1408EIGEN_STRONG_INLINE Packet4Xs pcmp_le<Packet4Xs>(const Packet4Xs& a, const Packet4Xs& b) {
1409 PacketMask4 mask = __riscv_vmsle_vv_i16m4_b4(a, b, unpacket_traits<Packet4Xs>::size);
1410 return __riscv_vmerge_vxm_i16m4(pzero(a), static_cast<short>(0xffff), mask, unpacket_traits<Packet4Xs>::size);
1411}
1412
1413template <>
1414EIGEN_STRONG_INLINE Packet4Xs pcmp_lt<Packet4Xs>(const Packet4Xs& a, const Packet4Xs& b) {
1415 PacketMask4 mask = __riscv_vmslt_vv_i16m4_b4(a, b, unpacket_traits<Packet4Xs>::size);
1416 return __riscv_vmerge_vxm_i16m4(pzero(a), static_cast<short>(0xffff), mask, unpacket_traits<Packet4Xs>::size);
1417}
1418
1419template <>
1420EIGEN_STRONG_INLINE Packet4Xs pcmp_eq<Packet4Xs>(const Packet4Xs& a, const Packet4Xs& b) {
1421 PacketMask4 mask = __riscv_vmseq_vv_i16m4_b4(a, b, unpacket_traits<Packet4Xs>::size);
1422 return __riscv_vmerge_vxm_i16m4(pzero(a), static_cast<short>(0xffff), mask, unpacket_traits<Packet4Xs>::size);
1423}
1424
1425template <>
1426EIGEN_STRONG_INLINE Packet4Xs ptrue<Packet4Xs>(const Packet4Xs& /*a*/) {
1427 return __riscv_vmv_v_x_i16m4(static_cast<unsigned short>(0xffffu), unpacket_traits<Packet4Xs>::size);
1428}
1429
1430template <>
1431EIGEN_STRONG_INLINE Packet4Xs pand<Packet4Xs>(const Packet4Xs& a, const Packet4Xs& b) {
1432 return __riscv_vand_vv_i16m4(a, b, unpacket_traits<Packet4Xs>::size);
1433}
1434
1435template <>
1436EIGEN_STRONG_INLINE Packet4Xs por<Packet4Xs>(const Packet4Xs& a, const Packet4Xs& b) {
1437 return __riscv_vor_vv_i16m4(a, b, unpacket_traits<Packet4Xs>::size);
1438}
1439
1440template <>
1441EIGEN_STRONG_INLINE Packet4Xs pxor<Packet4Xs>(const Packet4Xs& a, const Packet4Xs& b) {
1442 return __riscv_vxor_vv_i16m4(a, b, unpacket_traits<Packet4Xs>::size);
1443}
1444
1445template <>
1446EIGEN_STRONG_INLINE Packet4Xs pandnot<Packet4Xs>(const Packet4Xs& a, const Packet4Xs& b) {
1447#ifndef __riscv_zvbb
1448 return __riscv_vand_vv_i16m4(a, __riscv_vnot_v_i16m4(b, unpacket_traits<Packet4Xs>::size),
1449 unpacket_traits<Packet4Xs>::size);
1450#else
1451 return __riscv_vreinterpret_v_u16m4_i16m4(__riscv_vandn_vv_u16m4(
1452 __riscv_vreinterpret_v_i16m4_u16m4(a), __riscv_vreinterpret_v_i16m4_u16m4(b), unpacket_traits<Packet4Xs>::size));
1453#endif
1454}
1455
1456template <int N>
1457EIGEN_STRONG_INLINE Packet4Xs parithmetic_shift_right(const Packet4Xs& a) {
1458 return __riscv_vsra_vx_i16m4(a, N, unpacket_traits<Packet4Xs>::size);
1459}
1460
1461template <int N>
1462EIGEN_STRONG_INLINE Packet4Xs plogical_shift_right(const Packet4Xs& a) {
1463 return __riscv_vreinterpret_i16m4(
1464 __riscv_vsrl_vx_u16m4(__riscv_vreinterpret_u16m4(a), N, unpacket_traits<Packet4Xs>::size));
1465}
1466
1467template <int N>
1468EIGEN_STRONG_INLINE Packet4Xs plogical_shift_left(const Packet4Xs& a) {
1469 return __riscv_vsll_vx_i16m4(a, N, unpacket_traits<Packet4Xs>::size);
1470}
1471
1472template <>
1473EIGEN_STRONG_INLINE Packet4Xs pload<Packet4Xs>(const numext::int16_t* from) {
1474 EIGEN_DEBUG_ALIGNED_LOAD return __riscv_vle16_v_i16m4(from, unpacket_traits<Packet4Xs>::size);
1475}
1476
1477template <>
1478EIGEN_STRONG_INLINE Packet4Xs ploadu<Packet4Xs>(const numext::int16_t* from) {
1479 EIGEN_DEBUG_UNALIGNED_LOAD return __riscv_vle16_v_i16m4(from, unpacket_traits<Packet4Xs>::size);
1480}
1481
1482template <>
1483EIGEN_STRONG_INLINE Packet4Xs ploaddup<Packet4Xs>(const numext::int16_t* from) {
1484 Packet4Xu data = __riscv_vwcvtu_x_x_v_u32m4(__riscv_vreinterpret_v_i16m2_u16m2(pload<Packet2Xs>(from)),
1485 unpacket_traits<Packet2Xs>::size);
1486 return __riscv_vreinterpret_v_u32m4_i16m4(__riscv_vadd_vv_u32m4(
1487 __riscv_vsll_vx_u32m4(data, 16, unpacket_traits<Packet4Xi>::size), data, unpacket_traits<Packet4Xi>::size));
1488}
1489
1490template <>
1491EIGEN_STRONG_INLINE Packet4Xs ploadquad<Packet4Xs>(const numext::int16_t* from) {
1492 Packet4Xsu idx =
1493 __riscv_vsrl_vx_u16m4(__riscv_vid_v_u16m4(unpacket_traits<Packet4Xs>::size), 2, unpacket_traits<Packet4Xs>::size);
1494 return __riscv_vrgather_vv_i16m4(__riscv_vlmul_ext_v_i16m1_i16m4(pload<Packet1Xs>(from)), idx,
1495 unpacket_traits<Packet4Xs>::size);
1496}
1497
1498template <>
1499EIGEN_STRONG_INLINE void pstore<numext::int16_t>(numext::int16_t* to, const Packet4Xs& from) {
1500 EIGEN_DEBUG_ALIGNED_STORE __riscv_vse16_v_i16m4(to, from, unpacket_traits<Packet4Xs>::size);
1501}
1502
1503template <>
1504EIGEN_STRONG_INLINE void pstoreu<numext::int16_t>(numext::int16_t* to, const Packet4Xs& from) {
1505 EIGEN_DEBUG_UNALIGNED_STORE __riscv_vse16_v_i16m4(to, from, unpacket_traits<Packet4Xs>::size);
1506}
1507
1508template <>
1509EIGEN_DEVICE_FUNC inline Packet4Xs pgather<numext::int16_t, Packet4Xs>(const numext::int16_t* from, Index stride) {
1510 return __riscv_vlse16_v_i16m4(from, stride * sizeof(numext::int16_t), unpacket_traits<Packet4Xs>::size);
1511}
1512
1513template <>
1514EIGEN_DEVICE_FUNC inline void pscatter<numext::int16_t, Packet4Xs>(numext::int16_t* to, const Packet4Xs& from,
1515 Index stride) {
1516 __riscv_vsse16(to, stride * sizeof(numext::int16_t), from, unpacket_traits<Packet4Xs>::size);
1517}
1518
1519template <>
1520EIGEN_STRONG_INLINE numext::int16_t pfirst<Packet4Xs>(const Packet4Xs& a) {
1521 return __riscv_vmv_x_s_i16m4_i16(a);
1522}
1523
1524template <>
1525EIGEN_STRONG_INLINE Packet4Xs preverse(const Packet4Xs& a) {
1526 Packet4Xsu idx = __riscv_vrsub_vx_u16m4(__riscv_vid_v_u16m4(unpacket_traits<Packet4Xs>::size),
1527 unpacket_traits<Packet4Xs>::size - 1, unpacket_traits<Packet4Xs>::size);
1528 return __riscv_vrgather_vv_i16m4(a, idx, unpacket_traits<Packet4Xs>::size);
1529}
1530
1531template <>
1532EIGEN_STRONG_INLINE Packet4Xs pabs(const Packet4Xs& a) {
1533 Packet4Xs mask = __riscv_vsra_vx_i16m4(a, 15, unpacket_traits<Packet4Xs>::size);
1534 return __riscv_vsub_vv_i16m4(__riscv_vxor_vv_i16m4(a, mask, unpacket_traits<Packet4Xs>::size), mask,
1535 unpacket_traits<Packet4Xs>::size);
1536}
1537
1538template <>
1539EIGEN_STRONG_INLINE numext::int16_t predux<Packet4Xs>(const Packet4Xs& a) {
1540 return __riscv_vmv_x(__riscv_vredsum_vs_i16m4_i16m1(a, __riscv_vmv_v_x_i16m1(0, unpacket_traits<Packet4Xs>::size / 4),
1541 unpacket_traits<Packet4Xs>::size));
1542}
1543
1544template <>
1545EIGEN_STRONG_INLINE bool predux_all(const Packet4Xs& a) {
1546 const PacketMask4 mask = __riscv_vmseq_vx_i16m4_b4(a, 0, unpacket_traits<Packet4Xs>::size);
1547 return __riscv_vcpop_m_b4(mask, unpacket_traits<Packet4Xs>::size) == 0;
1548}
1549
1550template <>
1551EIGEN_STRONG_INLINE numext::int16_t predux_mul<Packet4Xs>(const Packet4Xs& a) {
1552 Packet1Xs half1 = __riscv_vmul_vv_i16m1(__riscv_vget_v_i16m4_i16m1(a, 0), __riscv_vget_v_i16m4_i16m1(a, 1),
1553 unpacket_traits<Packet1Xs>::size);
1554 Packet1Xs half2 = __riscv_vmul_vv_i16m1(__riscv_vget_v_i16m4_i16m1(a, 2), __riscv_vget_v_i16m4_i16m1(a, 3),
1555 unpacket_traits<Packet1Xs>::size);
1556 return predux_mul<Packet1Xs>(__riscv_vmul_vv_i16m1(half1, half2, unpacket_traits<Packet1Xs>::size));
1557}
1558
1559template <>
1560EIGEN_STRONG_INLINE numext::int16_t predux_min<Packet4Xs>(const Packet4Xs& a) {
1561 return __riscv_vmv_x(__riscv_vredmin_vs_i16m4_i16m1(
1562 a, __riscv_vmv_v_x_i16m1((std::numeric_limits<numext::int16_t>::max)(), unpacket_traits<Packet4Xs>::size / 4),
1563 unpacket_traits<Packet4Xs>::size));
1564}
1565
1566template <>
1567EIGEN_STRONG_INLINE numext::int16_t predux_max<Packet4Xs>(const Packet4Xs& a) {
1568 return __riscv_vmv_x(__riscv_vredmax_vs_i16m4_i16m1(
1569 a, __riscv_vmv_v_x_i16m1((std::numeric_limits<numext::int16_t>::min)(), unpacket_traits<Packet4Xs>::size / 4),
1570 unpacket_traits<Packet4Xs>::size));
1571}
1572
1573template <int N>
1574EIGEN_DEVICE_FUNC inline void ptranspose(PacketBlock<Packet4Xs, N>& kernel) {
1575 numext::int16_t buffer[unpacket_traits<Packet4Xs>::size * N] = {0};
1576 int i = 0;
1577
1578 for (i = 0; i < N; i++) {
1579 __riscv_vsse16(&buffer[i], N * sizeof(numext::int16_t), kernel.packet[i], unpacket_traits<Packet4Xs>::size);
1580 }
1581 for (i = 0; i < N; i++) {
1582 kernel.packet[i] =
1583 __riscv_vle16_v_i16m4(&buffer[i * unpacket_traits<Packet4Xs>::size], unpacket_traits<Packet4Xs>::size);
1584 }
1585}
1586
1587template <typename Packet = Packet4Xs>
1588EIGEN_STRONG_INLINE
1589 std::enable_if_t<std::is_same<Packet, Packet4Xs>::value && (unpacket_traits<Packet4Xs>::size % 8) == 0, Packet2Xs>
1590 predux_half(const Packet4Xs& a) {
1591 return __riscv_vadd_vv_i16m2(__riscv_vget_v_i16m4_i16m2(a, 0), __riscv_vget_v_i16m4_i16m2(a, 1),
1592 unpacket_traits<Packet2Xs>::size);
1593}
1594
1595} // namespace internal
1596} // namespace Eigen
1597
1598#endif // EIGEN_PACKET4_MATH_RVV10_H