1/* Copyright 2015 The TensorFlow Authors. All Rights Reserved.
2
3Licensed under the Apache License, Version 2.0 (the "License");
4you may not use this file except in compliance with the License.
5You may obtain a copy of the License at
6
7 http://www.apache.org/licenses/LICENSE-2.0
8
9Unless required by applicable law or agreed to in writing, software
10distributed under the License is distributed on an "AS IS" BASIS,
11WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12See the License for the specific language governing permissions and
13limitations under the License.
14==============================================================================*/
15
16#ifndef TENSORFLOW_TSL_FRAMEWORK_TYPE_TRAITS_H_
17#define TENSORFLOW_TSL_FRAMEWORK_TYPE_TRAITS_H_
18
19#include <limits>
20#include <type_traits>
21#include <utility>
22
23#include "tensorflow/tsl/framework/numeric_types.h"
24#include "tensorflow/tsl/platform/types.h"
25
26namespace tsl {
27
28// Functions to define quantization attribute of types.
29struct true_type {
30 static constexpr bool value = true;
31};
32struct false_type {
33 static constexpr bool value = false;
34};
35
36// Default is_quantized is false.
37template <typename T>
38struct is_quantized : false_type {};
39
40// Specialize the quantized types.
41template <>
42struct is_quantized<qint8> : true_type {};
43template <>
44struct is_quantized<quint8> : true_type {};
45template <>
46struct is_quantized<qint32> : true_type {};
47template <>
48struct is_quantized<qint16> : true_type {};
49template <>
50struct is_quantized<quint16> : true_type {};
51
52// Default is_complex is false.
53template <typename T>
54struct is_complex : false_type {};
55
56// Specialize std::complex<float> and std::complex<double> types.
57template <>
58struct is_complex<std::complex<float>> : true_type {};
59template <>
60struct is_complex<std::complex<double>> : true_type {};
61
62// is_simple_type<T>::value if T[] can be safely constructed and destructed
63// without running T() and ~T(). We do not use std::is_trivial<T>
64// directly because std::complex<float> and std::complex<double> are
65// not trivial, but their arrays can be constructed and destructed
66// without running their default ctors and dtors.
67template <typename T>
68struct is_simple_type {
69 static constexpr bool value =
70 std::is_trivial<T>::value || std::is_same<T, Eigen::half>::value ||
71 std::is_same<T, complex64>::value || std::is_same<T, complex128>::value ||
72 is_quantized<T>::value || std::is_same<T, bfloat16>::value;
73};
74
75} // namespace tsl
76
77// Define numeric limits for our quantized as subclasses of the
78// standard types.
79namespace std {
80template <>
81class numeric_limits<tsl::qint8> : public numeric_limits<tsl::int8> {};
82template <>
83class numeric_limits<tsl::quint8> : public numeric_limits<tsl::uint8> {};
84template <>
85class numeric_limits<tsl::qint16> : public numeric_limits<tsl::int16> {};
86template <>
87class numeric_limits<tsl::quint16> : public numeric_limits<tsl::uint16> {};
88template <>
89class numeric_limits<tsl::qint32> : public numeric_limits<tsl::int32> {};
90
91// Specialize is_signed for quantized types.
92template <>
93struct is_signed<tsl::qint8> : public is_signed<tsl::int8> {};
94template <>
95struct is_signed<tsl::quint8> : public is_signed<tsl::uint8> {};
96template <>
97struct is_signed<tsl::qint16> : public is_signed<tsl::int16> {};
98template <>
99struct is_signed<tsl::quint16> : public is_signed<tsl::uint16> {};
100template <>
101struct is_signed<tsl::qint32> : public is_signed<tsl::int32> {};
102
103} // namespace std
104
105#endif // TENSORFLOW_TSL_FRAMEWORK_TYPE_TRAITS_H_
106