$darkmode
Eigen  5.0.1-dev
TypeCasting.h
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2019 Rasmus Munk Larsen <rmlarsen@google.com>
5 // Copyright (C) 2023 Chip Kerchner (chip.kerchner@ibm.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 
11 #ifndef EIGEN_TYPE_CASTING_ALTIVEC_H
12 #define EIGEN_TYPE_CASTING_ALTIVEC_H
13 
14 // IWYU pragma: private
15 #include "../../InternalHeaderCheck.h"
16 
17 namespace Eigen {
18 
19 namespace internal {
20 template <>
21 struct type_casting_traits<float, int> {
22  enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 1 };
23 };
24 
25 template <>
26 struct type_casting_traits<int, float> {
27  enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 1 };
28 };
29 
30 template <>
31 struct type_casting_traits<bfloat16, unsigned short int> {
32  enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 1 };
33 };
34 
35 template <>
36 struct type_casting_traits<unsigned short int, bfloat16> {
37  enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 1 };
38 };
39 
40 template <>
41 EIGEN_STRONG_INLINE Packet4i pcast<Packet4f, Packet4i>(const Packet4f& a) {
42  return vec_cts(a, 0);
43 }
44 
45 template <>
46 EIGEN_STRONG_INLINE Packet4ui pcast<Packet4f, Packet4ui>(const Packet4f& a) {
47  return vec_ctu(a, 0);
48 }
49 
50 template <>
51 EIGEN_STRONG_INLINE Packet4f pcast<Packet4i, Packet4f>(const Packet4i& a) {
52  return vec_ctf(a, 0);
53 }
54 
55 template <>
56 EIGEN_STRONG_INLINE Packet4f pcast<Packet4ui, Packet4f>(const Packet4ui& a) {
57  return vec_ctf(a, 0);
58 }
59 
60 template <>
61 EIGEN_STRONG_INLINE Packet8us pcast<Packet8bf, Packet8us>(const Packet8bf& a) {
62  Packet4f float_even = Bf16ToF32Even(a);
63  Packet4f float_odd = Bf16ToF32Odd(a);
64  Packet4ui int_even = pcast<Packet4f, Packet4ui>(float_even);
65  Packet4ui int_odd = pcast<Packet4f, Packet4ui>(float_odd);
66  const EIGEN_DECLARE_CONST_FAST_Packet4ui(low_mask, 0x0000FFFF);
67  Packet4ui low_even = pand<Packet4ui>(int_even, p4ui_low_mask);
68  Packet4ui low_odd = pand<Packet4ui>(int_odd, p4ui_low_mask);
69 
70  // Check values that are bigger than USHRT_MAX (0xFFFF)
71  Packet4bi overflow_selector;
72  if (vec_any_gt(int_even, p4ui_low_mask)) {
73  overflow_selector = vec_cmpgt(int_even, p4ui_low_mask);
74  low_even = vec_sel(low_even, p4ui_low_mask, overflow_selector);
75  }
76  if (vec_any_gt(int_odd, p4ui_low_mask)) {
77  overflow_selector = vec_cmpgt(int_odd, p4ui_low_mask);
78  low_odd = vec_sel(low_even, p4ui_low_mask, overflow_selector);
79  }
80 
81  return pmerge(low_even, low_odd);
82 }
83 
84 template <>
85 EIGEN_STRONG_INLINE Packet8bf pcast<Packet8us, Packet8bf>(const Packet8us& a) {
86  // short -> int -> float -> bfloat16
87  const EIGEN_DECLARE_CONST_FAST_Packet4ui(low_mask, 0x0000FFFF);
88  Packet4ui int_cast = reinterpret_cast<Packet4ui>(a);
89  Packet4ui int_even = pand<Packet4ui>(int_cast, p4ui_low_mask);
90  Packet4ui int_odd = plogical_shift_right<16>(int_cast);
91  Packet4f float_even = pcast<Packet4ui, Packet4f>(int_even);
92  Packet4f float_odd = pcast<Packet4ui, Packet4f>(int_odd);
93  return F32ToBf16(float_even, float_odd);
94 }
95 
96 template <>
97 struct type_casting_traits<bfloat16, float> {
98  enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 2 };
99 };
100 
101 template <>
102 EIGEN_STRONG_INLINE Packet4f pcast<Packet8bf, Packet4f>(const Packet8bf& a) {
103  Packet8us z = pset1<Packet8us>(0);
104 #ifdef _BIG_ENDIAN
105  return reinterpret_cast<Packet4f>(vec_mergeh(a.m_val, z));
106 #else
107  return reinterpret_cast<Packet4f>(vec_mergeh(z, a.m_val));
108 #endif
109 }
110 
111 template <>
112 struct type_casting_traits<float, bfloat16> {
113  enum { VectorizedCast = 1, SrcCoeffRatio = 2, TgtCoeffRatio = 1 };
114 };
115 
116 template <>
117 EIGEN_STRONG_INLINE Packet8bf pcast<Packet4f, Packet8bf>(const Packet4f& a, const Packet4f& b) {
118  return F32ToBf16Both(a, b);
119 }
120 
121 template <>
122 EIGEN_STRONG_INLINE Packet4i preinterpret<Packet4i, Packet4f>(const Packet4f& a) {
123  return reinterpret_cast<Packet4i>(a);
124 }
125 
126 template <>
127 EIGEN_STRONG_INLINE Packet4f preinterpret<Packet4f, Packet4i>(const Packet4i& a) {
128  return reinterpret_cast<Packet4f>(a);
129 }
130 
131 #ifdef EIGEN_VECTORIZE_VSX
132 template <>
133 inline Packet2l pcast<Packet2d, Packet2l>(const Packet2d& x) {
134  EIGEN_ALIGN_MAX double dtmp[2];
135  pstore(dtmp, x);
136  EIGEN_ALIGN_MAX long long itmp[2] = {static_cast<long long>(dtmp[0]), static_cast<long long>(dtmp[1])};
137  return vec_xl(0, itmp);
138 }
139 
140 template <>
141 inline Packet2d pcast<Packet2l, Packet2d>(const Packet2l& x) {
142  EIGEN_ALIGN_MAX long long itmp[2];
143  vec_xst(x, 0, itmp);
144  EIGEN_ALIGN_MAX double dtmp[2] = {static_cast<double>(itmp[0]), static_cast<double>(itmp[1])};
145  return pload<Packet2d>(dtmp);
146 }
147 #endif
148 
149 } // end namespace internal
150 
151 } // end namespace Eigen
152 
153 #endif // EIGEN_TYPE_CASTING_ALTIVEC_H
Namespace containing all symbols from the Eigen library.
Definition: B01_Experimental.dox:1