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 #include "tensorflow/lite/delegates/gpu/common/tasks/conv_generic_test_util.h"
17
18 #include <memory>
19 #include <vector>
20
21 #include "tensorflow/lite/delegates/gpu/common/operations.h"
22 #include "tensorflow/lite/delegates/gpu/common/status.h"
23 #include "tensorflow/lite/delegates/gpu/common/task/testing_util.h"
24 #include "tensorflow/lite/delegates/gpu/common/tasks/conv_generic.h"
25
26 namespace tflite {
27 namespace gpu {
28
ConvGeneric1x1SimpleWeightsTest(TestExecutionEnvironment * env)29 absl::Status ConvGeneric1x1SimpleWeightsTest(TestExecutionEnvironment* env) {
30 TensorFloat32 src_tensor;
31 src_tensor.shape = BHWC(1, 2, 2, 2);
32 src_tensor.data = {0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f};
33
34 Convolution2DAttributes attr;
35 attr.padding.prepended = HW(0, 0);
36 attr.padding.appended = HW(0, 0);
37 attr.strides = HW(1, 1);
38 attr.dilations = HW(1, 1);
39 attr.weights.shape = OHWI(2, 1, 1, 2);
40 attr.weights.data = {1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f};
41 attr.bias.shape = Linear(1);
42 attr.bias.data = {0.0f};
43
44 for (auto precision : env->GetSupportedPrecisions()) {
45 auto data_type = DeduceDataTypeFromPrecision(precision);
46 for (auto storage : env->GetSupportedStorages(data_type)) {
47 const float eps = precision == CalculationsPrecision::F32 ? 1e-6f : 1e-3f;
48 OperationDef op_def;
49 op_def.precision = precision;
50 op_def.src_tensors.push_back({data_type, storage, Layout::HWC});
51 op_def.dst_tensors.push_back({data_type, storage, Layout::HWC});
52 TensorFloat32 dst_tensor;
53 ConvGeneric operation =
54 CreateConvGeneric(env->GetGpuInfo(), op_def, attr);
55 RETURN_IF_ERROR(env->ExecuteGPUOperation(
56 src_tensor, std::make_unique<ConvGeneric>(std::move(operation)),
57 BHWC(1, 2, 2, 2), &dst_tensor));
58 RETURN_IF_ERROR(
59 PointWiseNear({1.0f, 1.0f, 5.0f, 5.0f, 9.0f, 9.0f, 13.0f, 13.0f},
60 dst_tensor.data, eps));
61 }
62 }
63 return absl::OkStatus();
64 }
65
ConvGeneric1x1Test(TestExecutionEnvironment * env)66 absl::Status ConvGeneric1x1Test(TestExecutionEnvironment* env) {
67 TensorFloat32 src_tensor;
68 src_tensor.shape = BHWC(1, 2, 2, 2);
69 src_tensor.data = {0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f};
70
71 Convolution2DAttributes attr;
72 attr.padding.prepended = HW(0, 0);
73 attr.padding.appended = HW(0, 0);
74 attr.strides = HW(1, 1);
75 attr.dilations = HW(1, 1);
76 attr.weights.shape = OHWI(2, 1, 1, 2);
77 attr.weights.data = {1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f};
78 attr.bias.shape = Linear(2);
79 attr.bias.data = {0.5f, -0.5f};
80
81 for (auto precision : env->GetSupportedPrecisions()) {
82 auto data_type = DeduceDataTypeFromPrecision(precision);
83 for (auto storage : env->GetSupportedStorages(data_type)) {
84 const float eps = precision == CalculationsPrecision::F32 ? 1e-6f : 1e-3f;
85 OperationDef op_def;
86 op_def.precision = precision;
87 op_def.src_tensors.push_back({data_type, storage, Layout::HWC});
88 op_def.dst_tensors.push_back({data_type, storage, Layout::HWC});
89 TensorFloat32 dst_tensor;
90 ConvGeneric operation =
91 CreateConvGeneric(env->GetGpuInfo(), op_def, attr);
92 RETURN_IF_ERROR(env->ExecuteGPUOperation(
93 src_tensor, std::make_unique<ConvGeneric>(std::move(operation)),
94 BHWC(1, 2, 2, 2), &dst_tensor));
95 RETURN_IF_ERROR(
96 PointWiseNear({2.5f, 3.5f, 8.5f, 17.5f, 14.5f, 31.5f, 20.5f, 45.5f},
97 dst_tensor.data, eps));
98 }
99 }
100 return absl::OkStatus();
101 }
102
ConvGenericSimpleWeightsTest(TestExecutionEnvironment * env)103 absl::Status ConvGenericSimpleWeightsTest(TestExecutionEnvironment* env) {
104 TensorFloat32 src_tensor;
105 src_tensor.shape = BHWC(1, 2, 2, 2);
106 src_tensor.data = {0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f};
107
108 Convolution2DAttributes attr;
109 attr.padding.prepended = HW(0, 0);
110 attr.padding.appended = HW(1, 1);
111 attr.strides = HW(1, 1);
112 attr.dilations = HW(1, 1);
113 attr.weights.shape = OHWI(1, 2, 2, 2);
114 attr.weights.data = {1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f};
115 attr.bias.shape = Linear(1);
116 attr.bias.data = {0.0f};
117
118 for (auto precision : env->GetSupportedPrecisions()) {
119 auto data_type = DeduceDataTypeFromPrecision(precision);
120 for (auto storage : env->GetSupportedStorages(data_type)) {
121 const float eps = precision == CalculationsPrecision::F32 ? 1e-6f : 1e-3f;
122 OperationDef op_def;
123 op_def.precision = precision;
124 op_def.src_tensors.push_back({data_type, storage, Layout::HWC});
125 op_def.dst_tensors.push_back({data_type, storage, Layout::HWC});
126 TensorFloat32 dst_tensor;
127 ConvGeneric operation =
128 CreateConvGeneric(env->GetGpuInfo(), op_def, attr);
129 RETURN_IF_ERROR(env->ExecuteGPUOperation(
130 src_tensor, std::make_unique<ConvGeneric>(std::move(operation)),
131 BHWC(1, 2, 2, 1), &dst_tensor));
132 RETURN_IF_ERROR(
133 PointWiseNear({28.0f, 18.0f, 22.0f, 13.0f}, dst_tensor.data, eps));
134 }
135 }
136 return absl::OkStatus();
137 }
138
ConvGenericTest(TestExecutionEnvironment * env)139 absl::Status ConvGenericTest(TestExecutionEnvironment* env) {
140 TensorFloat32 src_tensor;
141 src_tensor.shape = BHWC(1, 2, 2, 2);
142 src_tensor.data = {0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f};
143
144 Convolution2DAttributes attr;
145 attr.padding.prepended = HW(0, 0);
146 attr.padding.appended = HW(1, 1);
147 attr.strides = HW(1, 1);
148 attr.dilations = HW(1, 1);
149 attr.weights.shape = OHWI(2, 2, 2, 2);
150 attr.weights.data = {1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f,
151 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f};
152 attr.bias.shape = Linear(2);
153 attr.bias.data = {0.5f, -0.5f};
154
155 for (auto precision : env->GetSupportedPrecisions()) {
156 auto data_type = DeduceDataTypeFromPrecision(precision);
157 for (auto storage : env->GetSupportedStorages(data_type)) {
158 const float eps = precision == CalculationsPrecision::F32 ? 1e-6f : 1e-3f;
159 OperationDef op_def;
160 op_def.precision = precision;
161 op_def.src_tensors.push_back({data_type, storage, Layout::HWC});
162 op_def.dst_tensors.push_back({data_type, storage, Layout::HWC});
163 TensorFloat32 dst_tensor;
164 ConvGeneric operation =
165 CreateConvGeneric(env->GetGpuInfo(), op_def, attr);
166 RETURN_IF_ERROR(env->ExecuteGPUOperation(
167 src_tensor, std::make_unique<ConvGeneric>(std::move(operation)),
168 BHWC(1, 2, 2, 2), &dst_tensor));
169 RETURN_IF_ERROR(PointWiseNear(
170 {168.5f, 391.5f, 80.5f, 223.5f, 60.5f, 235.5f, 20.5f, 123.5f},
171 dst_tensor.data, eps));
172 }
173 }
174 return absl::OkStatus();
175 }
176
ConvGenericGroupedTest(TestExecutionEnvironment * env)177 absl::Status ConvGenericGroupedTest(TestExecutionEnvironment* env) {
178 TensorFloat32 src_tensor;
179 src_tensor.shape = BHWC(1, 1, 1, 8);
180 src_tensor.data = {0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f};
181
182 Convolution2DAttributes attr;
183 attr.groups = 2;
184 attr.padding.prepended = HW(0, 0);
185 attr.padding.appended = HW(0, 0);
186 attr.strides = HW(1, 1);
187 attr.dilations = HW(1, 1);
188 attr.weights.shape = OHWI(8, 1, 1, 4);
189 attr.weights.data = {1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f,
190 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f,
191 17.0f, 18.0f, 19.0f, 20.0f, 21.0f, 22.0f, 23.0f, 24.0f,
192 25.0f, 26.0f, 27.0f, 28.0f, 29.0f, 30.0f, 31.0f, 32.0f};
193 attr.bias.shape = Linear(8);
194 attr.bias.data = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f};
195
196 for (auto precision : env->GetSupportedPrecisions()) {
197 auto data_type = DeduceDataTypeFromPrecision(precision);
198 for (auto storage : env->GetSupportedStorages(data_type)) {
199 const float eps = precision == CalculationsPrecision::F32 ? 1e-6f : 1e-3f;
200 OperationDef op_def;
201 op_def.precision = precision;
202 op_def.src_tensors.push_back({data_type, storage, Layout::HWC});
203 op_def.dst_tensors.push_back({data_type, storage, Layout::HWC});
204 TensorFloat32 dst_tensor;
205 ConvGeneric operation =
206 CreateConvGeneric(env->GetGpuInfo(), op_def, attr);
207 RETURN_IF_ERROR(env->ExecuteGPUOperation(
208 src_tensor, std::make_unique<ConvGeneric>(std::move(operation)),
209 BHWC(1, 1, 1, 8), &dst_tensor));
210 RETURN_IF_ERROR(PointWiseNear(
211 {20.0f, 44.0f, 68.0f, 92.0f, 412.0f, 500.0f, 588.0f, 676.0f},
212 dst_tensor.data, eps));
213 }
214 }
215 return absl::OkStatus();
216 }
217
218 } // namespace gpu
219 } // namespace tflite
220