1 /* Copyright 2021 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 // For Google-internal use only.
17 #if GOOGLE_CUDA || TENSORFLOW_USE_ROCM
18
19 #include "tensorflow/core/util/autotune_maps/autotune_serialize.h"
20
21 #include "absl/types/variant.h"
22 #include "tensorflow/core/platform/status_matchers.h"
23 #include "tensorflow/core/platform/test.h"
24 #include "tensorflow/core/util/autotune_maps/conv_autotune_maps.h"
25 #include "tensorflow/core/util/autotune_maps/conv_parameters.h"
26 #include "tensorflow/core/util/autotune_maps/conv_parameters.pb.h"
27 #include "tensorflow/core/util/tensor_format.h"
28 #include "tensorflow/stream_executor/gpu/gpu_driver.h"
29
30 namespace tensorflow {
31 namespace {
32 using stream_executor::dnn::AlgorithmConfig;
33 using stream_executor::dnn::AlgorithmDesc;
34 using stream_executor::gpu::GpuDriver;
35 using ::tensorflow::testing::StatusIs;
36 using ::testing::HasSubstr;
37
38 // Tests when there is no entry in the autotune maps.
TEST(AutotuneSerializeTest,Empty)39 TEST(AutotuneSerializeTest, Empty) {
40 TF_CHECK_OK(GpuDriver::Init());
41 ResetAutotuneMaps();
42 std::string output;
43 TF_CHECK_OK(SerializeAutotuneMaps(&output));
44 TF_CHECK_OK(LoadSerializedAutotuneMaps(output));
45 EXPECT_EQ(ConvAutotuneMap::GetInstance()->GetMap().size(), 0);
46 }
47
48 // Tests the consistency of SerializeAutotuneMaps and LoadSerializedAutotuneMaps
49 // by:
50 // 1. Insert predefined entries into the autotune maps.
51 // 2. Serialize it to string using SerializeAutotuneMaps.
52 // 3. Reset autotune maps.
53 // 4. Use MergeFromstring to load the entries from string to autotune maps.
54 // 5. Check if entries in autotune maps are equal to the predefined ones.
TEST(AutotuneSerializeTest,Consistency)55 TEST(AutotuneSerializeTest, Consistency) {
56 TF_CHECK_OK(GpuDriver::Init());
57 ResetAutotuneMaps();
58 ConvParameters conv_params_example_a = {
59 /*batch=*/1,
60 /*in_depths=*/1,
61 /*in=*/{{1, 1}},
62 /*data_format=*/TensorFormat::FORMAT_NCHW,
63 /*out_depths=*/1,
64 /*filter=*/{{1, 1}},
65 /*dilation=*/{{1, 1}},
66 /*stride=*/{{1, 1}},
67 /*padding=*/{{1, 1}},
68 /*dtype=*/DataType::DT_INT8,
69 /*device_id=*/0,
70 /*group_count=*/1};
71 ConvParameters fused_params_example_a = {
72 /*batch=*/1,
73 /*in_depths=*/1,
74 /*in=*/{{1, 1}},
75 /*data_format=*/TensorFormat::FORMAT_NCHW,
76 /*out_depths=*/1,
77 /*filter=*/{{1, 1}},
78 /*dilation=*/{{1, 1}},
79 /*stride=*/{{1, 1}},
80 /*padding=*/{{1, 1}},
81 /*dtype=*/DataType::DT_INT8,
82 /*device_id=*/0,
83 /*group_count=*/1,
84 ConvParameters::FusionInfo{1.0, 0., 0.,
85 /*activation_mode=*/
86 se::dnn::ActivationMode::kNone,
87 /*is_contrib=*/false},
88 };
89 ConvParameters contrib_fused_params_example_a = {
90 /*batch=*/1,
91 /*in_depths=*/1,
92 /*in=*/{{1, 1}},
93 /*data_format=*/TensorFormat::FORMAT_NCHW,
94 /*out_depths=*/1,
95 /*filter=*/{{1, 1}},
96 /*dilation=*/{{1, 1}},
97 /*stride=*/{{1, 1}},
98 /*padding=*/{{1, 1}},
99 /*dtype=*/DataType::DT_INT8,
100 /*device_id=*/0,
101 /*group_count=*/1,
102 ConvParameters::FusionInfo{1.0, 0., 0.,
103 /*activation_mode=*/
104 se::dnn::ActivationMode::kRelu,
105 /*is_contrib=*/true}};
106
107 AlgorithmDesc algorithm(/*algo_id=*/1, /*use_tensor_ops=*/true);
108 AlgorithmDesc algorithm_no_scratch(/*algo_id=*/1, /*use_tensor_ops=*/true);
109 AutotuneEntry<se::dnn::ConvOp> example_a(algorithm, algorithm_no_scratch);
110 ConvAutotuneMap::GetInstance()->Insert(conv_params_example_a, example_a);
111 ConvAutotuneMap::GetInstance()->Insert(fused_params_example_a, example_a);
112 ConvAutotuneMap::GetInstance()->Insert(contrib_fused_params_example_a,
113 example_a);
114 std::string serialized_string;
115 TF_CHECK_OK(SerializeAutotuneMaps(&serialized_string));
116 ResetAutotuneMaps();
117 TF_CHECK_OK(LoadSerializedAutotuneMaps(serialized_string));
118 EXPECT_EQ(ConvAutotuneMap::GetInstance()->GetMap().size(), 3);
119
120 AutotuneEntry<se::dnn::ConvOp> entry;
121 EXPECT_TRUE(
122 ConvAutotuneMap::GetInstance()->Find(conv_params_example_a, &entry));
123 EXPECT_EQ(entry, example_a);
124 EXPECT_TRUE(
125 ConvAutotuneMap::GetInstance()->Find(fused_params_example_a, &entry));
126 EXPECT_EQ(entry, example_a);
127 EXPECT_TRUE(ConvAutotuneMap::GetInstance()->Find(
128 contrib_fused_params_example_a, &entry));
129 EXPECT_EQ(entry, example_a);
130 }
131
132 // Test that LoadSerializedAutotuneMaps will reject entries with incompatible
133 // version.
TEST(AutotuneSerializeTest,VersionControl)134 TEST(AutotuneSerializeTest, VersionControl) {
135 TF_CHECK_OK(GpuDriver::Init());
136 ResetAutotuneMaps();
137
138 ConvParameters fused_params_example_a = {
139 /*batch=*/1,
140 /*in_depths=*/1,
141 /*in=*/{{1, 1}},
142 /*data_format=*/TensorFormat::FORMAT_NCHW,
143 /*out_depths=*/1,
144 /*filter=*/{{1, 1}},
145 /*dilation=*/{{1, 1}},
146 /*stride=*/{{1, 1}},
147 /*padding=*/{{1, 1}},
148 /*dtype=*/DataType::DT_INT8,
149 /*device_id=*/0,
150 /*group_count=*/1,
151 ConvParameters::FusionInfo{1.0, 0., 0.,
152 /*activation_mode=*/
153 se::dnn::ActivationMode::kNone,
154 /*is_contrib=*/false},
155 /*version=*/ConvParameters::kVersion - 1};
156
157 AlgorithmDesc algorithm(/*algo_id=*/1, /*use_tensor_ops=*/true);
158 AlgorithmDesc algorithm_no_scratch(/*algo_id=*/1, /*use_tensor_ops=*/true);
159 AlgorithmConfig algorithm_config_example_a(algorithm, /*scratch_size=*/1,
160 algorithm_no_scratch);
161
162 ConvAutotuneMap::GetInstance()->Insert(
163 fused_params_example_a,
164 AutotuneEntry<se::dnn::ConvOp>(algorithm_config_example_a));
165
166 std::string serialized_string;
167 TF_CHECK_OK(SerializeAutotuneMaps(&serialized_string));
168
169 ResetAutotuneMaps();
170 EXPECT_THAT(
171 LoadSerializedAutotuneMaps(serialized_string),
172 StatusIs(error::ABORTED,
173 HasSubstr("Aborted because the loaded autotune results")));
174 EXPECT_EQ(ConvAutotuneMap::GetInstance()->GetMap().size(), 0);
175 }
176 } // namespace
177 } // namespace tensorflow
178 #endif // GOOGLE_CUDA || TENSORFLOW_USE_ROCM
179