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