1 /* Copyright 2017 The TensorFlow Authors. All Rights Reserved.
2
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
6
7 http://www.apache.org/licenses/LICENSE-2.0
8
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
14 ==============================================================================*/
15
16 // Utilities for dealing with XLA primitive types.
17
18 #ifndef TENSORFLOW_COMPILER_XLA_PRIMITIVE_UTIL_H_
19 #define TENSORFLOW_COMPILER_XLA_PRIMITIVE_UTIL_H_
20
21 #include <type_traits>
22
23 #include "tensorflow/compiler/xla/types.h"
24 #include "tensorflow/compiler/xla/xla_data.pb.h"
25
26 namespace xla {
27 namespace primitive_util {
28
29 // The number of exponent bits in a BF16 value.
30 const int kBFloat16ExponentBits = 8;
31
32 // The number of mantissa bits in a BF16 value. There is an implicit leading
33 // 1, so there is an implicit additional bit of precision.
34 const int kBFloat16MantissaBits = 7;
35
36 // Returns the XLA primitive type (eg, F32) corresponding to the given
37 // template parameter native type (eg, float).
38 template <typename NativeT>
NativeToPrimitiveType()39 PrimitiveType NativeToPrimitiveType() {
40 // Make the expression depend on the template parameter NativeT so
41 // that this compile-time error only apperas if this function is
42 // instantiated with some concrete type that is not specialized
43 // below.
44 static_assert(!std::is_same<NativeT, NativeT>::value,
45 "Cannot map native type to primitive type.");
46 return PRIMITIVE_TYPE_INVALID;
47 }
48
49 // Declarations of specializations for each native type which correspond to a
50 // XLA primitive type. As an optimization, these are declared inline in the
51 // header.
52 template <>
53 inline PrimitiveType NativeToPrimitiveType<bool>() {
54 return PRED;
55 }
56
57 // Unsigned integer
58 template <>
59 inline PrimitiveType NativeToPrimitiveType<uint8>() {
60 return U8;
61 }
62
63 template <>
64 inline PrimitiveType NativeToPrimitiveType<uint16>() {
65 return U16;
66 }
67
68 template <>
69 inline PrimitiveType NativeToPrimitiveType<uint32>() {
70 return U32;
71 }
72
73 template <>
74 inline PrimitiveType NativeToPrimitiveType<uint64>() {
75 return U64;
76 }
77
78 // Signed integer
79 template <>
80 inline PrimitiveType NativeToPrimitiveType<int8>() {
81 return S8;
82 }
83
84 template <>
85 inline PrimitiveType NativeToPrimitiveType<int16>() {
86 return S16;
87 }
88
89 template <>
90 inline PrimitiveType NativeToPrimitiveType<int32>() {
91 return S32;
92 }
93
94 template <>
95 inline PrimitiveType NativeToPrimitiveType<int64>() {
96 return S64;
97 }
98
99 // Floating point
100 template <>
101 inline PrimitiveType NativeToPrimitiveType<float>() {
102 return F32;
103 }
104
105 template <>
106 inline PrimitiveType NativeToPrimitiveType<double>() {
107 return F64;
108 }
109
110 template <>
111 inline PrimitiveType NativeToPrimitiveType<half>() {
112 return F16;
113 }
114
115 template <>
116 inline PrimitiveType NativeToPrimitiveType<bfloat16>() {
117 return BF16;
118 }
119
120 // Complex
121 template <>
122 inline PrimitiveType NativeToPrimitiveType<complex64>() {
123 return C64;
124 }
125
126 bool IsFloatingPointType(PrimitiveType type);
127
128 bool IsComplexType(PrimitiveType type);
129
130 bool IsSignedIntegralType(PrimitiveType type);
131
132 bool IsUnsignedIntegralType(PrimitiveType type);
133
134 bool IsIntegralType(PrimitiveType type);
135
136 // Returns the number of bits in the representation for a given type.
137 int BitWidth(PrimitiveType type);
138
139 // Returns the real, imag component type underlying the given complex type.
140 // LOG(FATAL)'s if complex_type is not complex.
141 PrimitiveType ComplexComponentType(PrimitiveType complex_type);
142
143 // Returns the native type (eg, float) corresponding to the given template
144 // parameter XLA primitive type (eg, F32).
145 template <PrimitiveType>
146 struct PrimitiveTypeToNative;
147
148 // Declarations of specializations for each native type which correspond to a
149 // XLA primitive type.
150 template <>
151 struct PrimitiveTypeToNative<PRED> {
152 using type = bool;
153 };
154
155 // Unsigned integer
156 template <>
157 struct PrimitiveTypeToNative<U8> {
158 using type = uint8;
159 };
160
161 template <>
162 struct PrimitiveTypeToNative<U16> {
163 using type = uint16;
164 };
165
166 template <>
167 struct PrimitiveTypeToNative<U32> {
168 using type = uint32;
169 };
170
171 template <>
172 struct PrimitiveTypeToNative<U64> {
173 using type = uint64;
174 };
175
176 // Signed integer
177 template <>
178 struct PrimitiveTypeToNative<S8> {
179 using type = int8;
180 };
181
182 template <>
183 struct PrimitiveTypeToNative<S16> {
184 using type = int16;
185 };
186
187 template <>
188 struct PrimitiveTypeToNative<S32> {
189 using type = int32;
190 };
191
192 template <>
193 struct PrimitiveTypeToNative<S64> {
194 using type = int64;
195 };
196
197 // Floating point
198 template <>
199 struct PrimitiveTypeToNative<F32> {
200 using type = float;
201 };
202 template <>
203 struct PrimitiveTypeToNative<F64> {
204 using type = double;
205 };
206 template <>
207 struct PrimitiveTypeToNative<F16> {
208 using type = half;
209 };
210
211 template <>
212 struct PrimitiveTypeToNative<BF16> {
213 using type = bfloat16;
214 };
215
216 // Complex
217 template <>
218 struct PrimitiveTypeToNative<C64> {
219 using type = complex64;
220 };
221 } // namespace primitive_util
222 } // namespace xla
223
224 #endif // TENSORFLOW_COMPILER_XLA_PRIMITIVE_UTIL_H_
225