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/depthwise_conv_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/depthwise_conv.h"
25
26 namespace tflite {
27 namespace gpu {
28
DepthwiseConvSimpleWeightsTest(TestExecutionEnvironment * env)29 absl::Status DepthwiseConvSimpleWeightsTest(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 DepthwiseConvolution2DAttributes attr;
35 attr.padding.prepended = HW(1, 0);
36 attr.padding.appended = HW(1, 0);
37 attr.strides = HW(1, 1);
38 attr.dilations = HW(1, 1);
39 attr.weights.shape = OHWI(1, 3, 1, 2);
40 attr.weights.data = {1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f};
41 attr.bias.shape = Linear(2);
42 attr.bias.data = {0.0f, 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 DepthwiseConv operation =
54 CreateDepthwiseConvolution2D(env->GetGpuInfo(), op_def, attr);
55 RETURN_IF_ERROR(env->ExecuteGPUOperation(
56 src_tensor, std::make_unique<DepthwiseConv>(std::move(operation)),
57 BHWC(1, 2, 2, 2), &dst_tensor));
58 RETURN_IF_ERROR(
59 PointWiseNear({4.0f, 6.0f, 8.0f, 10.0f, 4.0f, 6.0f, 8.0f, 10.0f},
60 dst_tensor.data, eps));
61 }
62 }
63 return absl::OkStatus();
64 }
65
DepthwiseConvNoMultiplierTest(TestExecutionEnvironment * env)66 absl::Status DepthwiseConvNoMultiplierTest(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 DepthwiseConvolution2DAttributes attr;
72 attr.padding.prepended = HW(1, 0);
73 attr.padding.appended = HW(1, 0);
74 attr.strides = HW(1, 1);
75 attr.dilations = HW(1, 1);
76 attr.weights.shape = OHWI(1, 3, 1, 2);
77 attr.weights.data = {0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.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 DepthwiseConv operation =
91 CreateDepthwiseConvolution2D(env->GetGpuInfo(), op_def, attr);
92 RETURN_IF_ERROR(env->ExecuteGPUOperation(
93 src_tensor, std::make_unique<DepthwiseConv>(std::move(operation)),
94 BHWC(1, 2, 2, 2), &dst_tensor));
95 RETURN_IF_ERROR(
96 PointWiseNear({16.5f, 27.5f, 28.5f, 43.5f, 8.5f, 15.5f, 12.5f, 23.5f},
97 dst_tensor.data, eps));
98 }
99 }
100 return absl::OkStatus();
101 }
102
DepthwiseConvMultiplier2Test(TestExecutionEnvironment * env)103 absl::Status DepthwiseConvMultiplier2Test(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 DepthwiseConvolution2DAttributes attr;
109 attr.padding.prepended = HW(1, 0);
110 attr.padding.appended = HW(1, 0);
111 attr.strides = HW(1, 1);
112 attr.dilations = HW(1, 1);
113 attr.weights.shape = OHWI(2, 3, 1, 2);
114 attr.weights.data = {0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f,
115 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f};
116 attr.bias.shape = Linear(4);
117 attr.bias.data = {0.5f, -0.5f, 1.0f, -1.0f};
118
119 for (auto precision : env->GetSupportedPrecisions()) {
120 auto data_type = DeduceDataTypeFromPrecision(precision);
121 for (auto storage : env->GetSupportedStorages(data_type)) {
122 const float eps = precision == CalculationsPrecision::F32 ? 1e-6f : 1e-3f;
123 OperationDef op_def;
124 op_def.precision = precision;
125 op_def.src_tensors.push_back({data_type, storage, Layout::HWC});
126 op_def.dst_tensors.push_back({data_type, storage, Layout::HWC});
127 TensorFloat32 dst_tensor;
128 DepthwiseConv operation =
129 CreateDepthwiseConvolution2D(env->GetGpuInfo(), op_def, attr);
130 RETURN_IF_ERROR(env->ExecuteGPUOperation(
131 src_tensor, std::make_unique<DepthwiseConv>(std::move(operation)),
132 BHWC(1, 2, 2, 4), &dst_tensor));
133 RETURN_IF_ERROR(PointWiseNear(
134 {16.5f, 39.5f, 29.0f, 63.0f, 28.5f, 75.5f, 45.0f, 103.0f, 8.5f, 31.5f,
135 17.0f, 51.0f, 12.5f, 59.5f, 25.0f, 83.0f},
136 dst_tensor.data, eps));
137 }
138 }
139 return absl::OkStatus();
140 }
141
142 } // namespace gpu
143 } // namespace tflite
144