1 /* Copyright 2015 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 #include "tensorflow/core/framework/types.h"
17
18 #include "tensorflow/core/framework/type_traits.h"
19 #include "tensorflow/core/lib/strings/str_util.h"
20 #include "tensorflow/core/platform/protobuf.h"
21 #include "tensorflow/core/platform/test.h"
22
23 namespace tensorflow {
24 namespace {
25
TEST(TypesTest,DeviceTypeName)26 TEST(TypesTest, DeviceTypeName) {
27 EXPECT_EQ("CPU", DeviceTypeString(DeviceType(DEVICE_CPU)));
28 EXPECT_EQ("GPU", DeviceTypeString(DeviceType(DEVICE_GPU)));
29 EXPECT_EQ("SYCL", DeviceTypeString(DeviceType(DEVICE_SYCL)));
30 }
31
TEST(TypesTest,kDataTypeRefOffset)32 TEST(TypesTest, kDataTypeRefOffset) {
33 // Basic sanity check
34 EXPECT_EQ(DT_FLOAT + kDataTypeRefOffset, DT_FLOAT_REF);
35
36 // Use the meta-data provided by proto2 to iterate through the basic
37 // types and validate that adding kDataTypeRefOffset gives the
38 // corresponding reference type.
39 const auto* enum_descriptor = DataType_descriptor();
40 int e = DataType_MIN;
41 if (e == DT_INVALID) ++e;
42 int e_ref = e + kDataTypeRefOffset;
43 EXPECT_FALSE(DataType_IsValid(e_ref - 1))
44 << "Reference enum "
45 << enum_descriptor->FindValueByNumber(e_ref - 1)->name()
46 << " without corresponding base enum with value " << e - 1;
47 for (;
48 DataType_IsValid(e) && DataType_IsValid(e_ref) && e_ref <= DataType_MAX;
49 ++e, ++e_ref) {
50 string enum_name = enum_descriptor->FindValueByNumber(e)->name();
51 string enum_ref_name = enum_descriptor->FindValueByNumber(e_ref)->name();
52 EXPECT_EQ(enum_name + "_REF", enum_ref_name)
53 << enum_name << "_REF should have value " << e_ref << " not "
54 << enum_ref_name;
55 // Validate DataTypeString() as well.
56 DataType dt_e = static_cast<DataType>(e);
57 DataType dt_e_ref = static_cast<DataType>(e_ref);
58 EXPECT_EQ(DataTypeString(dt_e) + "_ref", DataTypeString(dt_e_ref));
59
60 // Test DataTypeFromString reverse conversion
61 DataType dt_e2, dt_e2_ref;
62 EXPECT_TRUE(DataTypeFromString(DataTypeString(dt_e), &dt_e2));
63 EXPECT_EQ(dt_e, dt_e2);
64 EXPECT_TRUE(DataTypeFromString(DataTypeString(dt_e_ref), &dt_e2_ref));
65 EXPECT_EQ(dt_e_ref, dt_e2_ref);
66 }
67 ASSERT_FALSE(DataType_IsValid(e))
68 << "Should define " << enum_descriptor->FindValueByNumber(e)->name()
69 << "_REF to be " << e_ref;
70 ASSERT_FALSE(DataType_IsValid(e_ref))
71 << "Extra reference enum "
72 << enum_descriptor->FindValueByNumber(e_ref)->name()
73 << " without corresponding base enum with value " << e;
74 ASSERT_LT(DataType_MAX, e_ref)
75 << "Gap in reference types, missing value for " << e_ref;
76
77 // Make sure there are no enums defined after the last regular type before
78 // the first reference type.
79 for (; e < DataType_MIN + kDataTypeRefOffset; ++e) {
80 EXPECT_FALSE(DataType_IsValid(e))
81 << "Discontinuous enum value "
82 << enum_descriptor->FindValueByNumber(e)->name() << " = " << e;
83 }
84 }
85
TEST(TypesTest,DataTypeFromString)86 TEST(TypesTest, DataTypeFromString) {
87 DataType dt;
88 ASSERT_TRUE(DataTypeFromString("int32", &dt));
89 EXPECT_EQ(DT_INT32, dt);
90 ASSERT_TRUE(DataTypeFromString("int32_ref", &dt));
91 EXPECT_EQ(DT_INT32_REF, dt);
92 EXPECT_FALSE(DataTypeFromString("int32_ref_ref", &dt));
93 EXPECT_FALSE(DataTypeFromString("foo", &dt));
94 EXPECT_FALSE(DataTypeFromString("foo_ref", &dt));
95 ASSERT_TRUE(DataTypeFromString("int64", &dt));
96 EXPECT_EQ(DT_INT64, dt);
97 ASSERT_TRUE(DataTypeFromString("int64_ref", &dt));
98 EXPECT_EQ(DT_INT64_REF, dt);
99 ASSERT_TRUE(DataTypeFromString("quint8_ref", &dt));
100 EXPECT_EQ(DT_QUINT8_REF, dt);
101 ASSERT_TRUE(DataTypeFromString("bfloat16", &dt));
102 EXPECT_EQ(DT_BFLOAT16, dt);
103 }
104
105 template <typename T>
GetQuantized()106 static bool GetQuantized() {
107 return is_quantized<T>::value;
108 }
109
TEST(TypesTest,QuantizedTypes)110 TEST(TypesTest, QuantizedTypes) {
111 // NOTE: GUnit cannot parse is::quantized<TYPE>::value() within the
112 // EXPECT_TRUE() clause, so we delegate through a template function.
113 EXPECT_TRUE(GetQuantized<qint8>());
114 EXPECT_TRUE(GetQuantized<quint8>());
115 EXPECT_TRUE(GetQuantized<qint32>());
116
117 EXPECT_FALSE(GetQuantized<int8>());
118 EXPECT_FALSE(GetQuantized<uint8>());
119 EXPECT_FALSE(GetQuantized<int16>());
120 EXPECT_FALSE(GetQuantized<int32>());
121
122 EXPECT_TRUE(DataTypeIsQuantized(DT_QINT8));
123 EXPECT_TRUE(DataTypeIsQuantized(DT_QUINT8));
124 EXPECT_TRUE(DataTypeIsQuantized(DT_QINT32));
125
126 EXPECT_FALSE(DataTypeIsQuantized(DT_INT8));
127 EXPECT_FALSE(DataTypeIsQuantized(DT_UINT8));
128 EXPECT_FALSE(DataTypeIsQuantized(DT_UINT16));
129 EXPECT_FALSE(DataTypeIsQuantized(DT_INT16));
130 EXPECT_FALSE(DataTypeIsQuantized(DT_INT32));
131 EXPECT_FALSE(DataTypeIsQuantized(DT_BFLOAT16));
132 }
133
TEST(TypesTest,ComplexTypes)134 TEST(TypesTest, ComplexTypes) {
135 EXPECT_TRUE(DataTypeIsComplex(DT_COMPLEX64));
136 EXPECT_TRUE(DataTypeIsComplex(DT_COMPLEX128));
137 EXPECT_FALSE(DataTypeIsComplex(DT_FLOAT));
138 EXPECT_FALSE(DataTypeIsComplex(DT_DOUBLE));
139 }
140
TEST(TypesTest,IntegerTypes)141 TEST(TypesTest, IntegerTypes) {
142 for (auto dt : AllTypes()) {
143 const string name = DataTypeString(dt);
144 EXPECT_EQ(DataTypeIsInteger(dt), str_util::StartsWith(name, "int") ||
145 str_util::StartsWith(name, "uint"))
146 << "DataTypeInteger failed for " << name;
147 }
148 }
149
150 } // namespace
151 } // namespace tensorflow
152