10#ifndef EIGEN_PACKET_MATH_GPU_H
11#define EIGEN_PACKET_MATH_GPU_H
18#if defined(EIGEN_HIP_DEVICE_COMPILE) || (defined(EIGEN_CUDA_ARCH) && EIGEN_CUDA_ARCH >= 350)
19#define EIGEN_GPU_HAS_LDG 1
23#if (defined(EIGEN_CUDA_ARCH) && EIGEN_CUDA_ARCH >= 530)
24#define EIGEN_CUDA_HAS_FP16_ARITHMETIC 1
27#if defined(EIGEN_HIP_DEVICE_COMPILE) || defined(EIGEN_CUDA_HAS_FP16_ARITHMETIC)
28#define EIGEN_GPU_HAS_FP16_ARITHMETIC 1
34#if defined(EIGEN_GPUCC) && defined(EIGEN_USE_GPU)
36template<>
struct is_arithmetic<
float4> {
enum { value =
true }; };
37template<>
struct is_arithmetic<
double2> {
enum { value =
true }; };
39template<>
struct packet_traits<float> : default_packet_traits
66 HasGammaSampleDerAlpha = 1,
75template<>
struct packet_traits<double> : default_packet_traits
100 HasGammaSampleDerAlpha = 1,
110template<>
struct unpacket_traits<
float4> {
typedef float type;
enum {size=4, alignment=
Aligned16, vectorizable=
true, masked_load_available=
false, masked_store_available=
false};
typedef float4 half; };
111template<>
struct unpacket_traits<
double2> {
typedef double type;
enum {size=2, alignment=
Aligned16, vectorizable=
true, masked_load_available=
false, masked_store_available=
false};
typedef double2 half; };
113template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
float4 pset1<float4>(
const float& from) {
114 return make_float4(from, from, from, from);
116template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
double2 pset1<double2>(
const double& from) {
117 return make_double2(from, from);
123#if defined(EIGEN_CUDA_ARCH) || defined(EIGEN_HIPCC) || (defined(EIGEN_CUDACC) && EIGEN_COMP_CLANG && !EIGEN_COMP_NVCC)
126EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
float bitwise_and(
const float& a,
128 return __int_as_float(__float_as_int(a) & __float_as_int(b));
130EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
double bitwise_and(
const double& a,
132 return __longlong_as_double(__double_as_longlong(a) &
133 __double_as_longlong(b));
136EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
float bitwise_or(
const float& a,
138 return __int_as_float(__float_as_int(a) | __float_as_int(b));
140EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
double bitwise_or(
const double& a,
142 return __longlong_as_double(__double_as_longlong(a) |
143 __double_as_longlong(b));
146EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
float bitwise_xor(
const float& a,
148 return __int_as_float(__float_as_int(a) ^ __float_as_int(b));
150EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
double bitwise_xor(
const double& a,
152 return __longlong_as_double(__double_as_longlong(a) ^
153 __double_as_longlong(b));
156EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
float bitwise_andnot(
const float& a,
158 return __int_as_float(__float_as_int(a) & ~__float_as_int(b));
160EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
double bitwise_andnot(
const double& a,
162 return __longlong_as_double(__double_as_longlong(a) &
163 ~__double_as_longlong(b));
165EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
float eq_mask(
const float& a,
167 return __int_as_float(a == b ? 0xffffffffu : 0u);
169EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
double eq_mask(
const double& a,
171 return __longlong_as_double(a == b ? 0xffffffffffffffffull : 0ull);
174EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
float lt_mask(
const float& a,
176 return __int_as_float(a < b ? 0xffffffffu : 0u);
178EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
double lt_mask(
const double& a,
180 return __longlong_as_double(a < b ? 0xffffffffffffffffull : 0ull);
186EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
float4 pand<float4>(
const float4& a,
188 return make_float4(bitwise_and(a.x, b.x), bitwise_and(a.y, b.y),
189 bitwise_and(a.z, b.z), bitwise_and(a.w, b.w));
192EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
double2 pand<double2>(
const double2& a,
194 return make_double2(bitwise_and(a.x, b.x), bitwise_and(a.y, b.y));
198EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
float4 por<float4>(
const float4& a,
200 return make_float4(bitwise_or(a.x, b.x), bitwise_or(a.y, b.y),
201 bitwise_or(a.z, b.z), bitwise_or(a.w, b.w));
204EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
double2 por<double2>(
const double2& a,
206 return make_double2(bitwise_or(a.x, b.x), bitwise_or(a.y, b.y));
210EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
float4 pxor<float4>(
const float4& a,
212 return make_float4(bitwise_xor(a.x, b.x), bitwise_xor(a.y, b.y),
213 bitwise_xor(a.z, b.z), bitwise_xor(a.w, b.w));
216EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
double2 pxor<double2>(
const double2& a,
218 return make_double2(bitwise_xor(a.x, b.x), bitwise_xor(a.y, b.y));
222EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
float4 pandnot<float4>(
const float4& a,
224 return make_float4(bitwise_andnot(a.x, b.x), bitwise_andnot(a.y, b.y),
225 bitwise_andnot(a.z, b.z), bitwise_andnot(a.w, b.w));
228EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
double2
229pandnot<double2>(
const double2& a,
const double2& b) {
230 return make_double2(bitwise_andnot(a.x, b.x), bitwise_andnot(a.y, b.y));
234EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
float4 pcmp_eq<float4>(
const float4& a,
236 return make_float4(eq_mask(a.x, b.x), eq_mask(a.y, b.y), eq_mask(a.z, b.z),
240EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
float4 pcmp_lt<float4>(
const float4& a,
242 return make_float4(lt_mask(a.x, b.x), lt_mask(a.y, b.y), lt_mask(a.z, b.z),
246EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
double2
247pcmp_eq<double2>(
const double2& a,
const double2& b) {
248 return make_double2(eq_mask(a.x, b.x), eq_mask(a.y, b.y));
251EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
double2
252pcmp_lt<double2>(
const double2& a,
const double2& b) {
253 return make_double2(lt_mask(a.x, b.x), lt_mask(a.y, b.y));
257template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
float4 plset<float4>(
const float& a) {
258 return make_float4(a, a+1, a+2, a+3);
260template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
double2 plset<double2>(
const double& a) {
261 return make_double2(a, a+1);
264template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
float4 padd<float4>(
const float4& a,
const float4& b) {
265 return make_float4(a.x+b.x, a.y+b.y, a.z+b.z, a.w+b.w);
267template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
double2 padd<double2>(
const double2& a,
const double2& b) {
268 return make_double2(a.x+b.x, a.y+b.y);
271template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
float4 psub<float4>(
const float4& a,
const float4& b) {
272 return make_float4(a.x-b.x, a.y-b.y, a.z-b.z, a.w-b.w);
274template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
double2 psub<double2>(
const double2& a,
const double2& b) {
275 return make_double2(a.x-b.x, a.y-b.y);
278template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
float4 pnegate(
const float4& a) {
279 return make_float4(-a.x, -a.y, -a.z, -a.w);
281template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
double2 pnegate(
const double2& a) {
282 return make_double2(-a.x, -a.y);
285template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
float4 pconj(
const float4& a) {
return a; }
286template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
double2 pconj(
const double2& a) {
return a; }
288template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
float4 pmul<float4>(
const float4& a,
const float4& b) {
289 return make_float4(a.x*b.x, a.y*b.y, a.z*b.z, a.w*b.w);
291template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
double2 pmul<double2>(
const double2& a,
const double2& b) {
292 return make_double2(a.x*b.x, a.y*b.y);
295template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
float4 pdiv<float4>(
const float4& a,
const float4& b) {
296 return make_float4(a.x/b.x, a.y/b.y, a.z/b.z, a.w/b.w);
298template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
double2 pdiv<double2>(
const double2& a,
const double2& b) {
299 return make_double2(a.x/b.x, a.y/b.y);
302template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
float4 pmin<float4>(
const float4& a,
const float4& b) {
303 return make_float4(fminf(a.x, b.x), fminf(a.y, b.y), fminf(a.z, b.z), fminf(a.w, b.w));
305template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
double2 pmin<double2>(
const double2& a,
const double2& b) {
306 return make_double2(
fmin(a.x, b.x),
fmin(a.y, b.y));
309template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
float4 pmax<float4>(
const float4& a,
const float4& b) {
310 return make_float4(fmaxf(a.x, b.x), fmaxf(a.y, b.y), fmaxf(a.z, b.z), fmaxf(a.w, b.w));
312template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
double2 pmax<double2>(
const double2& a,
const double2& b) {
313 return make_double2(
fmax(a.x, b.x),
fmax(a.y, b.y));
316template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
float4 pload<float4>(
const float* from) {
317 return *
reinterpret_cast<const float4*
>(from);
320template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
double2 pload<double2>(
const double* from) {
321 return *
reinterpret_cast<const double2*
>(from);
324template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
float4 ploadu<float4>(
const float* from) {
325 return make_float4(from[0], from[1], from[2], from[3]);
327template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
double2 ploadu<double2>(
const double* from) {
328 return make_double2(from[0], from[1]);
331template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
float4 ploaddup<float4>(
const float* from) {
332 return make_float4(from[0], from[0], from[1], from[1]);
334template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
double2 ploaddup<double2>(
const double* from) {
335 return make_double2(from[0], from[0]);
338template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void pstore<float>(
float* to,
const float4& from) {
339 *
reinterpret_cast<float4*
>(to) = from;
342template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void pstore<double>(
double* to,
const double2& from) {
343 *
reinterpret_cast<double2*
>(to) = from;
346template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void pstoreu<float>(
float* to,
const float4& from) {
353template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void pstoreu<double>(
double* to,
const double2& from) {
359EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
float4 ploadt_ro<float4, Aligned>(
const float* from) {
360#if defined(EIGEN_GPU_HAS_LDG)
361 return __ldg((
const float4*)from);
363 return make_float4(from[0], from[1], from[2], from[3]);
367EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
double2 ploadt_ro<double2, Aligned>(
const double* from) {
368#if defined(EIGEN_GPU_HAS_LDG)
369 return __ldg((
const double2*)from);
371 return make_double2(from[0], from[1]);
376EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
float4 ploadt_ro<float4, Unaligned>(
const float* from) {
377#if defined(EIGEN_GPU_HAS_LDG)
378 return make_float4(__ldg(from+0), __ldg(from+1), __ldg(from+2), __ldg(from+3));
380 return make_float4(from[0], from[1], from[2], from[3]);
384EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
double2 ploadt_ro<double2, Unaligned>(
const double* from) {
385#if defined(EIGEN_GPU_HAS_LDG)
386 return make_double2(__ldg(from+0), __ldg(from+1));
388 return make_double2(from[0], from[1]);
392template<> EIGEN_DEVICE_FUNC
inline float4 pgather<float, float4>(
const float* from,
Index stride) {
393 return make_float4(from[0*stride], from[1*stride], from[2*stride], from[3*stride]);
396template<> EIGEN_DEVICE_FUNC
inline double2 pgather<double, double2>(
const double* from,
Index stride) {
397 return make_double2(from[0*stride], from[1*stride]);
400template<> EIGEN_DEVICE_FUNC
inline void pscatter<float, float4>(
float* to,
const float4& from,
Index stride) {
401 to[stride*0] = from.x;
402 to[stride*1] = from.y;
403 to[stride*2] = from.z;
404 to[stride*3] = from.w;
406template<> EIGEN_DEVICE_FUNC
inline void pscatter<double, double2>(
double* to,
const double2& from,
Index stride) {
407 to[stride*0] = from.x;
408 to[stride*1] = from.y;
411template<> EIGEN_DEVICE_FUNC
inline float pfirst<float4>(
const float4& a) {
414template<> EIGEN_DEVICE_FUNC
inline double pfirst<double2>(
const double2& a) {
418template<> EIGEN_DEVICE_FUNC
inline float predux<float4>(
const float4& a) {
419 return a.x + a.y + a.z + a.w;
421template<> EIGEN_DEVICE_FUNC
inline double predux<double2>(
const double2& a) {
425template<> EIGEN_DEVICE_FUNC
inline float predux_max<float4>(
const float4& a) {
426 return fmaxf(fmaxf(a.x, a.y), fmaxf(a.z, a.w));
428template<> EIGEN_DEVICE_FUNC
inline double predux_max<double2>(
const double2& a) {
429 return fmax(a.x, a.y);
432template<> EIGEN_DEVICE_FUNC
inline float predux_min<float4>(
const float4& a) {
433 return fminf(fminf(a.x, a.y), fminf(a.z, a.w));
435template<> EIGEN_DEVICE_FUNC
inline double predux_min<double2>(
const double2& a) {
436 return fmin(a.x, a.y);
439template<> EIGEN_DEVICE_FUNC
inline float predux_mul<float4>(
const float4& a) {
440 return a.x * a.y * a.z * a.w;
442template<> EIGEN_DEVICE_FUNC
inline double predux_mul<double2>(
const double2& a) {
446template<> EIGEN_DEVICE_FUNC
inline float4 pabs<float4>(
const float4& a) {
447 return make_float4(fabsf(a.x), fabsf(a.y), fabsf(a.z), fabsf(a.w));
449template<> EIGEN_DEVICE_FUNC
inline double2 pabs<double2>(
const double2& a) {
450 return make_double2(fabs(a.x), fabs(a.y));
453template<> EIGEN_DEVICE_FUNC
inline float4 pfloor<float4>(
const float4& a) {
454 return make_float4(floorf(a.x), floorf(a.y), floorf(a.z), floorf(a.w));
456template<> EIGEN_DEVICE_FUNC
inline double2 pfloor<double2>(
const double2& a) {
457 return make_double2(floor(a.x), floor(a.y));
460EIGEN_DEVICE_FUNC
inline void
461ptranspose(PacketBlock<float4,4>& kernel) {
462 float tmp = kernel.packet[0].y;
463 kernel.packet[0].y = kernel.packet[1].x;
464 kernel.packet[1].x = tmp;
466 tmp = kernel.packet[0].z;
467 kernel.packet[0].z = kernel.packet[2].x;
468 kernel.packet[2].x = tmp;
470 tmp = kernel.packet[0].w;
471 kernel.packet[0].w = kernel.packet[3].x;
472 kernel.packet[3].x = tmp;
474 tmp = kernel.packet[1].z;
475 kernel.packet[1].z = kernel.packet[2].y;
476 kernel.packet[2].y = tmp;
478 tmp = kernel.packet[1].w;
479 kernel.packet[1].w = kernel.packet[3].y;
480 kernel.packet[3].y = tmp;
482 tmp = kernel.packet[2].w;
483 kernel.packet[2].w = kernel.packet[3].z;
484 kernel.packet[3].z = tmp;
487EIGEN_DEVICE_FUNC
inline void
488ptranspose(PacketBlock<double2,2>& kernel) {
489 double tmp = kernel.packet[0].y;
490 kernel.packet[0].y = kernel.packet[1].x;
491 kernel.packet[1].x = tmp;
499#if (defined(EIGEN_HAS_CUDA_FP16) || defined(EIGEN_HAS_HIP_FP16)) && defined(EIGEN_GPU_COMPILE_PHASE)
501typedef ulonglong2 Packet4h2;
502template<>
struct unpacket_traits<Packet4h2> {
typedef Eigen::half type;
enum {size=8, alignment=
Aligned16, vectorizable=
true, masked_load_available=
false, masked_store_available=
false};
typedef Packet4h2 half; };
503template<>
struct is_arithmetic<Packet4h2> {
enum { value =
true }; };
505template<>
struct unpacket_traits<half2> {
typedef Eigen::half type;
enum {size=2, alignment=
Aligned16, vectorizable=
true, masked_load_available=
false, masked_store_available=
false};
typedef half2 half; };
506template<>
struct is_arithmetic<half2> {
enum { value =
true }; };
508template<>
struct packet_traits<
Eigen::half> : default_packet_traits
510 typedef Packet4h2 type;
511 typedef Packet4h2 half;
531EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 pset1<half2>(
const Eigen::half& from) {
532 return __half2half2(from);
536EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet4h2
539 half2* p_alias =
reinterpret_cast<half2*
>(&r);
540 p_alias[0] = pset1<half2>(from);
541 p_alias[1] = pset1<half2>(from);
542 p_alias[2] = pset1<half2>(from);
543 p_alias[3] = pset1<half2>(from);
549EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 pload(
const Eigen::half* from) {
550 return *
reinterpret_cast<const half2*
>(from);
553EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 ploadu(
const Eigen::half* from) {
554 return __halves2half2(from[0], from[1]);
557EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 ploaddup(
const Eigen::half* from) {
558 return __halves2half2(from[0], from[0]);
561EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void pstore(
Eigen::half* to,
563 *
reinterpret_cast<half2*
>(to) = from;
566EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void pstoreu(
Eigen::half* to,
568 to[0] = __low2half(from);
569 to[1] = __high2half(from);
573EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE half2 ploadt_ro_aligned(
575#if defined(EIGEN_GPU_HAS_LDG)
577 return __ldg(
reinterpret_cast<const half2*
>(from));
579 return __halves2half2(*(from+0), *(from+1));
583EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE half2 ploadt_ro_unaligned(
585#if defined(EIGEN_GPU_HAS_LDG)
586 return __halves2half2(__ldg(from+0), __ldg(from+1));
588 return __halves2half2(*(from+0), *(from+1));
592EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 pgather(
const Eigen::half* from,
594 return __halves2half2(from[0*stride], from[1*stride]);
597EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void pscatter(
599 to[stride*0] = __low2half(from);
600 to[stride*1] = __high2half(from);
603EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
Eigen::half pfirst(
const half2& a) {
604 return __low2half(a);
607EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 pabs(
const half2& a) {
608 half a1 = __low2half(a);
609 half a2 = __high2half(a);
610 half result1 = half_impl::raw_uint16_to_half(a1.x & 0x7FFF);
611 half result2 = half_impl::raw_uint16_to_half(a2.x & 0x7FFF);
612 return __halves2half2(result1, result2);
615EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 ptrue(
const half2& ) {
616 half true_half = half_impl::raw_uint16_to_half(0xffffu);
617 return pset1<half2>(true_half);
620EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 pzero(
const half2& ) {
621 half false_half = half_impl::raw_uint16_to_half(0x0000u);
622 return pset1<half2>(false_half);
625EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void
626ptranspose(PacketBlock<half2,2>& kernel) {
627 __half a1 = __low2half(kernel.packet[0]);
628 __half a2 = __high2half(kernel.packet[0]);
629 __half b1 = __low2half(kernel.packet[1]);
630 __half b2 = __high2half(kernel.packet[1]);
631 kernel.packet[0] = __halves2half2(a1, b1);
632 kernel.packet[1] = __halves2half2(a2, b2);
635EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 plset(
const Eigen::half& a) {
636#if defined(EIGEN_GPU_HAS_FP16_ARITHMETIC)
637 return __halves2half2(a, __hadd(a, __float2half(1.0f)));
639 float f = __half2float(a) + 1.0f;
640 return __halves2half2(a, __float2half(f));
644EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 pselect(
const half2& mask,
647 half mask_low = __low2half(mask);
648 half mask_high = __high2half(mask);
649 half result_low = mask_low == half(0) ? __low2half(b) : __low2half(a);
650 half result_high = mask_high == half(0) ? __high2half(b) : __high2half(a);
651 return __halves2half2(result_low, result_high);
654EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 pcmp_eq(
const half2& a,
656 half true_half = half_impl::raw_uint16_to_half(0xffffu);
657 half false_half = half_impl::raw_uint16_to_half(0x0000u);
658 half a1 = __low2half(a);
659 half a2 = __high2half(a);
660 half b1 = __low2half(b);
661 half b2 = __high2half(b);
662 half eq1 = __half2float(a1) == __half2float(b1) ? true_half : false_half;
663 half eq2 = __half2float(a2) == __half2float(b2) ? true_half : false_half;
664 return __halves2half2(eq1, eq2);
667EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 pcmp_lt(
const half2& a,
669 half true_half = half_impl::raw_uint16_to_half(0xffffu);
670 half false_half = half_impl::raw_uint16_to_half(0x0000u);
671 half a1 = __low2half(a);
672 half a2 = __high2half(a);
673 half b1 = __low2half(b);
674 half b2 = __high2half(b);
675 half eq1 = __half2float(a1) < __half2float(b1) ? true_half : false_half;
676 half eq2 = __half2float(a2) < __half2float(b2) ? true_half : false_half;
677 return __halves2half2(eq1, eq2);
680EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 pand(
const half2& a,
682 half a1 = __low2half(a);
683 half a2 = __high2half(a);
684 half b1 = __low2half(b);
685 half b2 = __high2half(b);
686 half result1 = half_impl::raw_uint16_to_half(a1.x & b1.x);
687 half result2 = half_impl::raw_uint16_to_half(a2.x & b2.x);
688 return __halves2half2(result1, result2);
691EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 por(
const half2& a,
693 half a1 = __low2half(a);
694 half a2 = __high2half(a);
695 half b1 = __low2half(b);
696 half b2 = __high2half(b);
697 half result1 = half_impl::raw_uint16_to_half(a1.x | b1.x);
698 half result2 = half_impl::raw_uint16_to_half(a2.x | b2.x);
699 return __halves2half2(result1, result2);
702EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 pxor(
const half2& a,
704 half a1 = __low2half(a);
705 half a2 = __high2half(a);
706 half b1 = __low2half(b);
707 half b2 = __high2half(b);
708 half result1 = half_impl::raw_uint16_to_half(a1.x ^ b1.x);
709 half result2 = half_impl::raw_uint16_to_half(a2.x ^ b2.x);
710 return __halves2half2(result1, result2);
713EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 pandnot(
const half2& a,
715 half a1 = __low2half(a);
716 half a2 = __high2half(a);
717 half b1 = __low2half(b);
718 half b2 = __high2half(b);
719 half result1 = half_impl::raw_uint16_to_half(a1.x & ~b1.x);
720 half result2 = half_impl::raw_uint16_to_half(a2.x & ~b2.x);
721 return __halves2half2(result1, result2);
724EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 padd(
const half2& a,
726#if defined(EIGEN_GPU_HAS_FP16_ARITHMETIC)
727 return __hadd2(a, b);
729 float a1 = __low2float(a);
730 float a2 = __high2float(a);
731 float b1 = __low2float(b);
732 float b2 = __high2float(b);
735 return __floats2half2_rn(r1, r2);
739EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 psub(
const half2& a,
741#if defined(EIGEN_GPU_HAS_FP16_ARITHMETIC)
742 return __hsub2(a, b);
744 float a1 = __low2float(a);
745 float a2 = __high2float(a);
746 float b1 = __low2float(b);
747 float b2 = __high2float(b);
750 return __floats2half2_rn(r1, r2);
754EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 pnegate(
const half2& a) {
755#if defined(EIGEN_GPU_HAS_FP16_ARITHMETIC)
758 float a1 = __low2float(a);
759 float a2 = __high2float(a);
760 return __floats2half2_rn(-a1, -a2);
764EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 pconj(
const half2& a) {
return a; }
766EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 pmul(
const half2& a,
768#if defined(EIGEN_GPU_HAS_FP16_ARITHMETIC)
769 return __hmul2(a, b);
771 float a1 = __low2float(a);
772 float a2 = __high2float(a);
773 float b1 = __low2float(b);
774 float b2 = __high2float(b);
777 return __floats2half2_rn(r1, r2);
781EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 pmadd(
const half2& a,
784#if defined(EIGEN_GPU_HAS_FP16_ARITHMETIC)
785 return __hfma2(a, b, c);
787 float a1 = __low2float(a);
788 float a2 = __high2float(a);
789 float b1 = __low2float(b);
790 float b2 = __high2float(b);
791 float c1 = __low2float(c);
792 float c2 = __high2float(c);
793 float r1 = a1 * b1 + c1;
794 float r2 = a2 * b2 + c2;
795 return __floats2half2_rn(r1, r2);
799EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 pdiv(
const half2& a,
801#if defined(EIGEN_GPU_HAS_FP16_ARITHMETIC)
802 return __h2div(a, b);
804 float a1 = __low2float(a);
805 float a2 = __high2float(a);
806 float b1 = __low2float(b);
807 float b2 = __high2float(b);
810 return __floats2half2_rn(r1, r2);
814EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 pmin(
const half2& a,
816 float a1 = __low2float(a);
817 float a2 = __high2float(a);
818 float b1 = __low2float(b);
819 float b2 = __high2float(b);
820 __half r1 = a1 < b1 ? __low2half(a) : __low2half(b);
821 __half r2 = a2 < b2 ? __high2half(a) : __high2half(b);
822 return __halves2half2(r1, r2);
825EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 pmax(
const half2& a,
827 float a1 = __low2float(a);
828 float a2 = __high2float(a);
829 float b1 = __low2float(b);
830 float b2 = __high2float(b);
831 __half r1 = a1 > b1 ? __low2half(a) : __low2half(b);
832 __half r2 = a2 > b2 ? __high2half(a) : __high2half(b);
833 return __halves2half2(r1, r2);
836EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
Eigen::half predux(
const half2& a) {
837#if defined(EIGEN_GPU_HAS_FP16_ARITHMETIC)
838 return __hadd(__low2half(a), __high2half(a));
840 float a1 = __low2float(a);
841 float a2 = __high2float(a);
846EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
Eigen::half predux_max(
const half2& a) {
847#if defined(EIGEN_GPU_HAS_FP16_ARITHMETIC)
848 __half first = __low2half(a);
849 __half second = __high2half(a);
850 return __hgt(first, second) ? first : second;
852 float a1 = __low2float(a);
853 float a2 = __high2float(a);
854 return a1 > a2 ? __low2half(a) : __high2half(a);
858EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
Eigen::half predux_min(
const half2& a) {
859#if defined(EIGEN_GPU_HAS_FP16_ARITHMETIC)
860 __half first = __low2half(a);
861 __half second = __high2half(a);
862 return __hlt(first, second) ? first : second;
864 float a1 = __low2float(a);
865 float a2 = __high2float(a);
866 return a1 < a2 ? __low2half(a) : __high2half(a);
870EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
Eigen::half predux_mul(
const half2& a) {
871#if defined(EIGEN_GPU_HAS_FP16_ARITHMETIC)
872 return __hmul(__low2half(a), __high2half(a));
874 float a1 = __low2float(a);
875 float a2 = __high2float(a);
880EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 plog1p(
const half2& a) {
881 float a1 = __low2float(a);
882 float a2 = __high2float(a);
883 float r1 = log1pf(a1);
884 float r2 = log1pf(a2);
885 return __floats2half2_rn(r1, r2);
888EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 pexpm1(
const half2& a) {
889 float a1 = __low2float(a);
890 float a2 = __high2float(a);
891 float r1 = expm1f(a1);
892 float r2 = expm1f(a2);
893 return __floats2half2_rn(r1, r2);
896#if (EIGEN_CUDA_SDK_VER >= 80000 && defined(EIGEN_CUDA_HAS_FP16_ARITHMETIC)) || \
897 defined(EIGEN_HIP_DEVICE_COMPILE)
899EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
900half2 plog(
const half2& a) {
904 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
905half2 pexp(
const half2& a) {
909 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
910half2 psqrt(
const half2& a) {
914 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
915half2 prsqrt(
const half2& a) {
921EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 plog(
const half2& a) {
922 float a1 = __low2float(a);
923 float a2 = __high2float(a);
926 return __floats2half2_rn(r1, r2);
929EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 pexp(
const half2& a) {
930 float a1 = __low2float(a);
931 float a2 = __high2float(a);
934 return __floats2half2_rn(r1, r2);
937EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 psqrt(
const half2& a) {
938 float a1 = __low2float(a);
939 float a2 = __high2float(a);
940 float r1 = sqrtf(a1);
941 float r2 = sqrtf(a2);
942 return __floats2half2_rn(r1, r2);
945EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 prsqrt(
const half2& a) {
946 float a1 = __low2float(a);
947 float a2 = __high2float(a);
948 float r1 = rsqrtf(a1);
949 float r2 = rsqrtf(a2);
950 return __floats2half2_rn(r1, r2);
956EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet4h2
958 return *
reinterpret_cast<const Packet4h2*
>(from);
963EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet4h2
966 half2* p_alias =
reinterpret_cast<half2*
>(&r);
967 p_alias[0] = ploadu(from + 0);
968 p_alias[1] = ploadu(from + 2);
969 p_alias[2] = ploadu(from + 4);
970 p_alias[3] = ploadu(from + 6);
975EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet4h2
978 half2* p_alias =
reinterpret_cast<half2*
>(&r);
979 p_alias[0] = ploaddup(from + 0);
980 p_alias[1] = ploaddup(from + 1);
981 p_alias[2] = ploaddup(from + 2);
982 p_alias[3] = ploaddup(from + 3);
987EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void pstore<Eigen::half>(
989 *
reinterpret_cast<Packet4h2*
>(to) = from;
993EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void pstoreu<Eigen::half>(
995 const half2* from_alias =
reinterpret_cast<const half2*
>(&from);
996 pstoreu(to + 0,from_alias[0]);
997 pstoreu(to + 2,from_alias[1]);
998 pstoreu(to + 4,from_alias[2]);
999 pstoreu(to + 6,from_alias[3]);
1003EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet4h2
1004ploadt_ro<Packet4h2, Aligned>(
const Eigen::half* from) {
1005#if defined(EIGEN_GPU_HAS_LDG)
1007 r = __ldg(
reinterpret_cast<const Packet4h2*
>(from));
1011 half2* r_alias =
reinterpret_cast<half2*
>(&r);
1012 r_alias[0] = ploadt_ro_aligned(from + 0);
1013 r_alias[1] = ploadt_ro_aligned(from + 2);
1014 r_alias[2] = ploadt_ro_aligned(from + 4);
1015 r_alias[3] = ploadt_ro_aligned(from + 6);
1021EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet4h2
1022ploadt_ro<Packet4h2, Unaligned>(
const Eigen::half* from) {
1024 half2* r_alias =
reinterpret_cast<half2*
>(&r);
1025 r_alias[0] = ploadt_ro_unaligned(from + 0);
1026 r_alias[1] = ploadt_ro_unaligned(from + 2);
1027 r_alias[2] = ploadt_ro_unaligned(from + 4);
1028 r_alias[3] = ploadt_ro_unaligned(from + 6);
1033EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet4h2
1036 half2* p_alias =
reinterpret_cast<half2*
>(&r);
1037 p_alias[0] = __halves2half2(from[0 * stride], from[1 * stride]);
1038 p_alias[1] = __halves2half2(from[2 * stride], from[3 * stride]);
1039 p_alias[2] = __halves2half2(from[4 * stride], from[5 * stride]);
1040 p_alias[3] = __halves2half2(from[6 * stride], from[7 * stride]);
1045EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void pscatter<Eigen::half, Packet4h2>(
1047 const half2* from_alias =
reinterpret_cast<const half2*
>(&from);
1048 pscatter(to + stride * 0, from_alias[0], stride);
1049 pscatter(to + stride * 2, from_alias[1], stride);
1050 pscatter(to + stride * 4, from_alias[2], stride);
1051 pscatter(to + stride * 6, from_alias[3], stride);
1055EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
Eigen::half pfirst<Packet4h2>(
1056 const Packet4h2& a) {
1057 return pfirst(*(
reinterpret_cast<const half2*
>(&a)));
1061EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet4h2 pabs<Packet4h2>(
1062 const Packet4h2& a) {
1064 half2* p_alias =
reinterpret_cast<half2*
>(&r);
1065 const half2* a_alias =
reinterpret_cast<const half2*
>(&a);
1066 p_alias[0] = pabs(a_alias[0]);
1067 p_alias[1] = pabs(a_alias[1]);
1068 p_alias[2] = pabs(a_alias[2]);
1069 p_alias[3] = pabs(a_alias[3]);
1074EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet4h2 ptrue<Packet4h2>(
1075 const Packet4h2& ) {
1076 half true_half = half_impl::raw_uint16_to_half(0xffffu);
1077 return pset1<Packet4h2>(true_half);
1081EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet4h2 pzero<Packet4h2>(
const Packet4h2& ) {
1082 half false_half = half_impl::raw_uint16_to_half(0x0000u);
1083 return pset1<Packet4h2>(false_half);
1086EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void ptranspose_double(
1087 double* d_row0,
double* d_row1,
double* d_row2,
double* d_row3,
1088 double* d_row4,
double* d_row5,
double* d_row6,
double* d_row7) {
1091 d_row0[1] = d_row4[0];
1095 d_row1[1] = d_row5[0];
1099 d_row2[1] = d_row6[0];
1103 d_row3[1] = d_row7[0];
1107EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void ptranspose_half2(
1108 half2* f_row0, half2* f_row1, half2* f_row2, half2* f_row3) {
1111 f_row0[1] = f_row2[0];
1115 f_row1[1] = f_row3[0];
1119EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void
1120ptranspose_half(half2& f0, half2& f1) {
1121 __half a1 = __low2half(f0);
1122 __half a2 = __high2half(f0);
1123 __half b1 = __low2half(f1);
1124 __half b2 = __high2half(f1);
1125 f0 = __halves2half2(a1, b1);
1126 f1 = __halves2half2(a2, b2);
1129EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void
1130ptranspose(PacketBlock<Packet4h2,8>& kernel) {
1131 double* d_row0 =
reinterpret_cast<double*
>(&kernel.packet[0]);
1132 double* d_row1 =
reinterpret_cast<double*
>(&kernel.packet[1]);
1133 double* d_row2 =
reinterpret_cast<double*
>(&kernel.packet[2]);
1134 double* d_row3 =
reinterpret_cast<double*
>(&kernel.packet[3]);
1135 double* d_row4 =
reinterpret_cast<double*
>(&kernel.packet[4]);
1136 double* d_row5 =
reinterpret_cast<double*
>(&kernel.packet[5]);
1137 double* d_row6 =
reinterpret_cast<double*
>(&kernel.packet[6]);
1138 double* d_row7 =
reinterpret_cast<double*
>(&kernel.packet[7]);
1139 ptranspose_double(d_row0, d_row1, d_row2, d_row3,
1140 d_row4, d_row5, d_row6, d_row7);
1143 half2* f_row0 =
reinterpret_cast<half2*
>(d_row0);
1144 half2* f_row1 =
reinterpret_cast<half2*
>(d_row1);
1145 half2* f_row2 =
reinterpret_cast<half2*
>(d_row2);
1146 half2* f_row3 =
reinterpret_cast<half2*
>(d_row3);
1147 ptranspose_half2(f_row0, f_row1, f_row2, f_row3);
1148 ptranspose_half(f_row0[0], f_row1[0]);
1149 ptranspose_half(f_row0[1], f_row1[1]);
1150 ptranspose_half(f_row2[0], f_row3[0]);
1151 ptranspose_half(f_row2[1], f_row3[1]);
1153 f_row0 =
reinterpret_cast<half2*
>(d_row0 + 1);
1154 f_row1 =
reinterpret_cast<half2*
>(d_row1 + 1);
1155 f_row2 =
reinterpret_cast<half2*
>(d_row2 + 1);
1156 f_row3 =
reinterpret_cast<half2*
>(d_row3 + 1);
1157 ptranspose_half2(f_row0, f_row1, f_row2, f_row3);
1158 ptranspose_half(f_row0[0], f_row1[0]);
1159 ptranspose_half(f_row0[1], f_row1[1]);
1160 ptranspose_half(f_row2[0], f_row3[0]);
1161 ptranspose_half(f_row2[1], f_row3[1]);
1163 f_row0 =
reinterpret_cast<half2*
>(d_row4);
1164 f_row1 =
reinterpret_cast<half2*
>(d_row5);
1165 f_row2 =
reinterpret_cast<half2*
>(d_row6);
1166 f_row3 =
reinterpret_cast<half2*
>(d_row7);
1167 ptranspose_half2(f_row0, f_row1, f_row2, f_row3);
1168 ptranspose_half(f_row0[0], f_row1[0]);
1169 ptranspose_half(f_row0[1], f_row1[1]);
1170 ptranspose_half(f_row2[0], f_row3[0]);
1171 ptranspose_half(f_row2[1], f_row3[1]);
1173 f_row0 =
reinterpret_cast<half2*
>(d_row4 + 1);
1174 f_row1 =
reinterpret_cast<half2*
>(d_row5 + 1);
1175 f_row2 =
reinterpret_cast<half2*
>(d_row6 + 1);
1176 f_row3 =
reinterpret_cast<half2*
>(d_row7 + 1);
1177 ptranspose_half2(f_row0, f_row1, f_row2, f_row3);
1178 ptranspose_half(f_row0[0], f_row1[0]);
1179 ptranspose_half(f_row0[1], f_row1[1]);
1180 ptranspose_half(f_row2[0], f_row3[0]);
1181 ptranspose_half(f_row2[1], f_row3[1]);
1186EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet4h2
1188#if defined(EIGEN_HIP_DEVICE_COMPILE)
1191 half2* p_alias =
reinterpret_cast<half2*
>(&r);
1192 p_alias[0] = __halves2half2(a, __hadd(a, __float2half(1.0f)));
1193 p_alias[1] = __halves2half2(__hadd(a, __float2half(2.0f)),
1194 __hadd(a, __float2half(3.0f)));
1195 p_alias[2] = __halves2half2(__hadd(a, __float2half(4.0f)),
1196 __hadd(a, __float2half(5.0f)));
1197 p_alias[3] = __halves2half2(__hadd(a, __float2half(6.0f)),
1198 __hadd(a, __float2half(7.0f)));
1200#elif defined(EIGEN_CUDA_HAS_FP16_ARITHMETIC)
1202 half2* r_alias =
reinterpret_cast<half2*
>(&r);
1204 half2 b = pset1<half2>(a);
1206 half2 half_offset0 = __halves2half2(__float2half(0.0f),__float2half(2.0f));
1207 half2 half_offset1 = __halves2half2(__float2half(4.0f),__float2half(6.0f));
1209 c = __hadd2(b, half_offset0);
1210 r_alias[0] = plset(__low2half(c));
1211 r_alias[1] = plset(__high2half(c));
1213 c = __hadd2(b, half_offset1);
1214 r_alias[2] = plset(__low2half(c));
1215 r_alias[3] = plset(__high2half(c));
1220 float f = __half2float(a);
1222 half2* p_alias =
reinterpret_cast<half2*
>(&r);
1223 p_alias[0] = __halves2half2(a, __float2half(f + 1.0f));
1224 p_alias[1] = __halves2half2(__float2half(f + 2.0f), __float2half(f + 3.0f));
1225 p_alias[2] = __halves2half2(__float2half(f + 4.0f), __float2half(f + 5.0f));
1226 p_alias[3] = __halves2half2(__float2half(f + 6.0f), __float2half(f + 7.0f));
1232EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet4h2
1233pselect<Packet4h2>(
const Packet4h2& mask,
const Packet4h2& a,
1234 const Packet4h2& b) {
1236 half2* r_alias =
reinterpret_cast<half2*
>(&r);
1237 const half2* mask_alias =
reinterpret_cast<const half2*
>(&mask);
1238 const half2* a_alias =
reinterpret_cast<const half2*
>(&a);
1239 const half2* b_alias =
reinterpret_cast<const half2*
>(&b);
1240 r_alias[0] = pselect(mask_alias[0], a_alias[0], b_alias[0]);
1241 r_alias[1] = pselect(mask_alias[1], a_alias[1], b_alias[1]);
1242 r_alias[2] = pselect(mask_alias[2], a_alias[2], b_alias[2]);
1243 r_alias[3] = pselect(mask_alias[3], a_alias[3], b_alias[3]);
1248EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet4h2
1249pcmp_eq<Packet4h2>(
const Packet4h2& a,
const Packet4h2& b) {
1251 half2* r_alias =
reinterpret_cast<half2*
>(&r);
1252 const half2* a_alias =
reinterpret_cast<const half2*
>(&a);
1253 const half2* b_alias =
reinterpret_cast<const half2*
>(&b);
1254 r_alias[0] = pcmp_eq(a_alias[0], b_alias[0]);
1255 r_alias[1] = pcmp_eq(a_alias[1], b_alias[1]);
1256 r_alias[2] = pcmp_eq(a_alias[2], b_alias[2]);
1257 r_alias[3] = pcmp_eq(a_alias[3], b_alias[3]);
1262EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet4h2 pand<Packet4h2>(
1263 const Packet4h2& a,
const Packet4h2& b) {
1265 half2* r_alias =
reinterpret_cast<half2*
>(&r);
1266 const half2* a_alias =
reinterpret_cast<const half2*
>(&a);
1267 const half2* b_alias =
reinterpret_cast<const half2*
>(&b);
1268 r_alias[0] = pand(a_alias[0], b_alias[0]);
1269 r_alias[1] = pand(a_alias[1], b_alias[1]);
1270 r_alias[2] = pand(a_alias[2], b_alias[2]);
1271 r_alias[3] = pand(a_alias[3], b_alias[3]);
1276EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet4h2 por<Packet4h2>(
1277 const Packet4h2& a,
const Packet4h2& b) {
1279 half2* r_alias =
reinterpret_cast<half2*
>(&r);
1280 const half2* a_alias =
reinterpret_cast<const half2*
>(&a);
1281 const half2* b_alias =
reinterpret_cast<const half2*
>(&b);
1282 r_alias[0] = por(a_alias[0], b_alias[0]);
1283 r_alias[1] = por(a_alias[1], b_alias[1]);
1284 r_alias[2] = por(a_alias[2], b_alias[2]);
1285 r_alias[3] = por(a_alias[3], b_alias[3]);
1290EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet4h2 pxor<Packet4h2>(
1291 const Packet4h2& a,
const Packet4h2& b) {
1293 half2* r_alias =
reinterpret_cast<half2*
>(&r);
1294 const half2* a_alias =
reinterpret_cast<const half2*
>(&a);
1295 const half2* b_alias =
reinterpret_cast<const half2*
>(&b);
1296 r_alias[0] = pxor(a_alias[0], b_alias[0]);
1297 r_alias[1] = pxor(a_alias[1], b_alias[1]);
1298 r_alias[2] = pxor(a_alias[2], b_alias[2]);
1299 r_alias[3] = pxor(a_alias[3], b_alias[3]);
1304EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet4h2
1305pandnot<Packet4h2>(
const Packet4h2& a,
const Packet4h2& b) {
1307 half2* r_alias =
reinterpret_cast<half2*
>(&r);
1308 const half2* a_alias =
reinterpret_cast<const half2*
>(&a);
1309 const half2* b_alias =
reinterpret_cast<const half2*
>(&b);
1310 r_alias[0] = pandnot(a_alias[0], b_alias[0]);
1311 r_alias[1] = pandnot(a_alias[1], b_alias[1]);
1312 r_alias[2] = pandnot(a_alias[2], b_alias[2]);
1313 r_alias[3] = pandnot(a_alias[3], b_alias[3]);
1318EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet4h2 padd<Packet4h2>(
1319 const Packet4h2& a,
const Packet4h2& b) {
1321 half2* r_alias =
reinterpret_cast<half2*
>(&r);
1322 const half2* a_alias =
reinterpret_cast<const half2*
>(&a);
1323 const half2* b_alias =
reinterpret_cast<const half2*
>(&b);
1324 r_alias[0] = padd(a_alias[0], b_alias[0]);
1325 r_alias[1] = padd(a_alias[1], b_alias[1]);
1326 r_alias[2] = padd(a_alias[2], b_alias[2]);
1327 r_alias[3] = padd(a_alias[3], b_alias[3]);
1332EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet4h2 psub<Packet4h2>(
1333 const Packet4h2& a,
const Packet4h2& b) {
1335 half2* r_alias =
reinterpret_cast<half2*
>(&r);
1336 const half2* a_alias =
reinterpret_cast<const half2*
>(&a);
1337 const half2* b_alias =
reinterpret_cast<const half2*
>(&b);
1338 r_alias[0] = psub(a_alias[0], b_alias[0]);
1339 r_alias[1] = psub(a_alias[1], b_alias[1]);
1340 r_alias[2] = psub(a_alias[2], b_alias[2]);
1341 r_alias[3] = psub(a_alias[3], b_alias[3]);
1346EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet4h2 pnegate(
const Packet4h2& a) {
1348 half2* r_alias =
reinterpret_cast<half2*
>(&r);
1349 const half2* a_alias =
reinterpret_cast<const half2*
>(&a);
1350 r_alias[0] = pnegate(a_alias[0]);
1351 r_alias[1] = pnegate(a_alias[1]);
1352 r_alias[2] = pnegate(a_alias[2]);
1353 r_alias[3] = pnegate(a_alias[3]);
1358EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet4h2 pconj(
const Packet4h2& a) {
1363EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet4h2 pmul<Packet4h2>(
1364 const Packet4h2& a,
const Packet4h2& b) {
1366 half2* r_alias =
reinterpret_cast<half2*
>(&r);
1367 const half2* a_alias =
reinterpret_cast<const half2*
>(&a);
1368 const half2* b_alias =
reinterpret_cast<const half2*
>(&b);
1369 r_alias[0] = pmul(a_alias[0], b_alias[0]);
1370 r_alias[1] = pmul(a_alias[1], b_alias[1]);
1371 r_alias[2] = pmul(a_alias[2], b_alias[2]);
1372 r_alias[3] = pmul(a_alias[3], b_alias[3]);
1377EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet4h2 pmadd<Packet4h2>(
1378 const Packet4h2& a,
const Packet4h2& b,
const Packet4h2& c) {
1380 half2* r_alias =
reinterpret_cast<half2*
>(&r);
1381 const half2* a_alias =
reinterpret_cast<const half2*
>(&a);
1382 const half2* b_alias =
reinterpret_cast<const half2*
>(&b);
1383 const half2* c_alias =
reinterpret_cast<const half2*
>(&c);
1384 r_alias[0] = pmadd(a_alias[0], b_alias[0], c_alias[0]);
1385 r_alias[1] = pmadd(a_alias[1], b_alias[1], c_alias[1]);
1386 r_alias[2] = pmadd(a_alias[2], b_alias[2], c_alias[2]);
1387 r_alias[3] = pmadd(a_alias[3], b_alias[3], c_alias[3]);
1392EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet4h2 pdiv<Packet4h2>(
1393 const Packet4h2& a,
const Packet4h2& b) {
1395 half2* r_alias =
reinterpret_cast<half2*
>(&r);
1396 const half2* a_alias =
reinterpret_cast<const half2*
>(&a);
1397 const half2* b_alias =
reinterpret_cast<const half2*
>(&b);
1398 r_alias[0] = pdiv(a_alias[0], b_alias[0]);
1399 r_alias[1] = pdiv(a_alias[1], b_alias[1]);
1400 r_alias[2] = pdiv(a_alias[2], b_alias[2]);
1401 r_alias[3] = pdiv(a_alias[3], b_alias[3]);
1406EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet4h2 pmin<Packet4h2>(
1407 const Packet4h2& a,
const Packet4h2& b) {
1409 half2* r_alias =
reinterpret_cast<half2*
>(&r);
1410 const half2* a_alias =
reinterpret_cast<const half2*
>(&a);
1411 const half2* b_alias =
reinterpret_cast<const half2*
>(&b);
1412 r_alias[0] = pmin(a_alias[0], b_alias[0]);
1413 r_alias[1] = pmin(a_alias[1], b_alias[1]);
1414 r_alias[2] = pmin(a_alias[2], b_alias[2]);
1415 r_alias[3] = pmin(a_alias[3], b_alias[3]);
1420EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet4h2 pmax<Packet4h2>(
1421 const Packet4h2& a,
const Packet4h2& b) {
1423 half2* r_alias =
reinterpret_cast<half2*
>(&r);
1424 const half2* a_alias =
reinterpret_cast<const half2*
>(&a);
1425 const half2* b_alias =
reinterpret_cast<const half2*
>(&b);
1426 r_alias[0] = pmax(a_alias[0], b_alias[0]);
1427 r_alias[1] = pmax(a_alias[1], b_alias[1]);
1428 r_alias[2] = pmax(a_alias[2], b_alias[2]);
1429 r_alias[3] = pmax(a_alias[3], b_alias[3]);
1434EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
Eigen::half predux<Packet4h2>(
1435 const Packet4h2& a) {
1436 const half2* a_alias =
reinterpret_cast<const half2*
>(&a);
1438 return predux(a_alias[0]) + predux(a_alias[1]) +
1439 predux(a_alias[2]) + predux(a_alias[3]);
1443EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
Eigen::half predux_max<Packet4h2>(
1444 const Packet4h2& a) {
1445 const half2* a_alias =
reinterpret_cast<const half2*
>(&a);
1446 half2 m0 = __halves2half2(predux_max(a_alias[0]),
1447 predux_max(a_alias[1]));
1448 half2 m1 = __halves2half2(predux_max(a_alias[2]),
1449 predux_max(a_alias[3]));
1450 __half first = predux_max(m0);
1451 __half second = predux_max(m1);
1452#if defined(EIGEN_CUDA_HAS_FP16_ARITHMETIC)
1453 return (__hgt(first, second) ? first : second);
1455 float ffirst = __half2float(first);
1456 float fsecond = __half2float(second);
1457 return (ffirst > fsecond)? first: second;
1462EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
Eigen::half predux_min<Packet4h2>(
1463 const Packet4h2& a) {
1464 const half2* a_alias =
reinterpret_cast<const half2*
>(&a);
1465 half2 m0 = __halves2half2(predux_min(a_alias[0]),
1466 predux_min(a_alias[1]));
1467 half2 m1 = __halves2half2(predux_min(a_alias[2]),
1468 predux_min(a_alias[3]));
1469 __half first = predux_min(m0);
1470 __half second = predux_min(m1);
1471#if defined(EIGEN_CUDA_HAS_FP16_ARITHMETIC)
1472 return (__hlt(first, second) ? first : second);
1474 float ffirst = __half2float(first);
1475 float fsecond = __half2float(second);
1476 return (ffirst < fsecond)? first: second;
1482EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
Eigen::half predux_mul<Packet4h2>(
1483 const Packet4h2& a) {
1484 const half2* a_alias =
reinterpret_cast<const half2*
>(&a);
1485 return predux_mul(pmul(pmul(a_alias[0], a_alias[1]),
1486 pmul(a_alias[2], a_alias[3])));
1490EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet4h2
1491plog1p<Packet4h2>(
const Packet4h2& a) {
1493 half2* r_alias =
reinterpret_cast<half2*
>(&r);
1494 const half2* a_alias =
reinterpret_cast<const half2*
>(&a);
1495 r_alias[0] = plog1p(a_alias[0]);
1496 r_alias[1] = plog1p(a_alias[1]);
1497 r_alias[2] = plog1p(a_alias[2]);
1498 r_alias[3] = plog1p(a_alias[3]);
1503EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet4h2
1504pexpm1<Packet4h2>(
const Packet4h2& a) {
1506 half2* r_alias =
reinterpret_cast<half2*
>(&r);
1507 const half2* a_alias =
reinterpret_cast<const half2*
>(&a);
1508 r_alias[0] = pexpm1(a_alias[0]);
1509 r_alias[1] = pexpm1(a_alias[1]);
1510 r_alias[2] = pexpm1(a_alias[2]);
1511 r_alias[3] = pexpm1(a_alias[3]);
1516EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet4h2 plog<Packet4h2>(
const Packet4h2& a) {
1518 half2* r_alias =
reinterpret_cast<half2*
>(&r);
1519 const half2* a_alias =
reinterpret_cast<const half2*
>(&a);
1520 r_alias[0] = plog(a_alias[0]);
1521 r_alias[1] = plog(a_alias[1]);
1522 r_alias[2] = plog(a_alias[2]);
1523 r_alias[3] = plog(a_alias[3]);
1528EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet4h2 pexp<Packet4h2>(
const Packet4h2& a) {
1530 half2* r_alias =
reinterpret_cast<half2*
>(&r);
1531 const half2* a_alias =
reinterpret_cast<const half2*
>(&a);
1532 r_alias[0] = pexp(a_alias[0]);
1533 r_alias[1] = pexp(a_alias[1]);
1534 r_alias[2] = pexp(a_alias[2]);
1535 r_alias[3] = pexp(a_alias[3]);
1540EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet4h2 psqrt<Packet4h2>(
const Packet4h2& a) {
1542 half2* r_alias =
reinterpret_cast<half2*
>(&r);
1543 const half2* a_alias =
reinterpret_cast<const half2*
>(&a);
1544 r_alias[0] = psqrt(a_alias[0]);
1545 r_alias[1] = psqrt(a_alias[1]);
1546 r_alias[2] = psqrt(a_alias[2]);
1547 r_alias[3] = psqrt(a_alias[3]);
1552EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet4h2
1553prsqrt<Packet4h2>(
const Packet4h2& a) {
1555 half2* r_alias =
reinterpret_cast<half2*
>(&r);
1556 const half2* a_alias =
reinterpret_cast<const half2*
>(&a);
1557 r_alias[0] = prsqrt(a_alias[0]);
1558 r_alias[1] = prsqrt(a_alias[1]);
1559 r_alias[2] = prsqrt(a_alias[2]);
1560 r_alias[3] = prsqrt(a_alias[3]);
1567EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 padd<half2>(
const half2& a,
1569#if defined(EIGEN_GPU_HAS_FP16_ARITHMETIC)
1570 return __hadd2(a, b);
1572 float a1 = __low2float(a);
1573 float a2 = __high2float(a);
1574 float b1 = __low2float(b);
1575 float b2 = __high2float(b);
1578 return __floats2half2_rn(r1, r2);
1583EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 pmul<half2>(
const half2& a,
1585#if defined(EIGEN_GPU_HAS_FP16_ARITHMETIC)
1586 return __hmul2(a, b);
1588 float a1 = __low2float(a);
1589 float a2 = __high2float(a);
1590 float b1 = __low2float(b);
1591 float b2 = __high2float(b);
1594 return __floats2half2_rn(r1, r2);
1599EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 pdiv<half2>(
const half2& a,
1601#if defined(EIGEN_GPU_HAS_FP16_ARITHMETIC)
1602 return __h2div(a, b);
1604 float a1 = __low2float(a);
1605 float a2 = __high2float(a);
1606 float b1 = __low2float(b);
1607 float b2 = __high2float(b);
1610 return __floats2half2_rn(r1, r2);
1615EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 pmin<half2>(
const half2& a,
1617 float a1 = __low2float(a);
1618 float a2 = __high2float(a);
1619 float b1 = __low2float(b);
1620 float b2 = __high2float(b);
1621 __half r1 = a1 < b1 ? __low2half(a) : __low2half(b);
1622 __half r2 = a2 < b2 ? __high2half(a) : __high2half(b);
1623 return __halves2half2(r1, r2);
1627EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 pmax<half2>(
const half2& a,
1629 float a1 = __low2float(a);
1630 float a2 = __high2float(a);
1631 float b1 = __low2float(b);
1632 float b2 = __high2float(b);
1633 __half r1 = a1 > b1 ? __low2half(a) : __low2half(b);
1634 __half r2 = a2 > b2 ? __high2half(a) : __high2half(b);
1635 return __halves2half2(r1, r2);
1640#undef EIGEN_GPU_HAS_LDG
1641#undef EIGEN_CUDA_HAS_FP16_ARITHMETIC
1642#undef EIGEN_GPU_HAS_FP16_ARITHMETIC
@ Aligned16
Definition Constants.h:235
GLM_FUNC_DECL T fmax(T a, T b)
Definition scalar_common.inl:76
GLM_FUNC_DECL T fmin(T a, T b)
Definition scalar_common.inl:31
vec< 4, float, highp > float4
single-qualifier floating-point vector with 4 components. (From GLM_GTX_compatibility extension)
Definition compatibility.hpp:101
vec< 2, double, highp > double2
double-qualifier floating-point vector with 2 components. (From GLM_GTX_compatibility extension)
Definition compatibility.hpp:115
Namespace containing all symbols from the Eigen library.
Definition common.h:81
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition Meta.h:74