| /* Copyright 2019 The TensorFlow Authors. All Rights Reserved. |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| ==============================================================================*/ |
| |
| #include "tensorflow/lite/delegates/gpu/cl/kernels/depthwise_conv.h" |
| |
| #include <vector> |
| |
| #include <gmock/gmock.h> |
| #include <gtest/gtest.h> |
| #include "tensorflow/lite/delegates/gpu/cl/kernels/cl_test.h" |
| #include "tensorflow/lite/delegates/gpu/common/operations.h" |
| #include "tensorflow/lite/delegates/gpu/common/status.h" |
| |
| using ::testing::FloatNear; |
| using ::testing::Pointwise; |
| |
| namespace tflite { |
| namespace gpu { |
| namespace cl { |
| namespace { |
| |
| TEST_F(OpenCLOperationTest, DepthwiseConvSimpleWeights) { |
| TensorFloat32 src_tensor; |
| src_tensor.shape = BHWC(1, 2, 2, 2); |
| src_tensor.data = {0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f}; |
| |
| DepthwiseConvolution2DAttributes attr; |
| attr.padding.prepended = HW(1, 0); |
| attr.padding.appended = HW(1, 0); |
| attr.strides = HW(1, 1); |
| attr.dilations = HW(1, 1); |
| attr.weights.shape = OHWI(1, 3, 1, 2); |
| attr.weights.data = {1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f}; |
| attr.bias.shape = Linear(2); |
| attr.bias.data = {0.0f, 0.0f}; |
| |
| for (auto storage : env_.GetSupportedStorages()) { |
| for (auto precision : env_.GetSupportedPrecisions()) { |
| const float eps = precision == CalculationsPrecision::F32 ? 1e-6f : 1e-3f; |
| OperationDef op_def; |
| op_def.precision = precision; |
| auto data_type = DeduceDataTypeFromPrecision(precision); |
| op_def.src_tensors.push_back({data_type, storage, Layout::HWC}); |
| op_def.dst_tensors.push_back({data_type, storage, Layout::HWC}); |
| TensorFloat32 dst_tensor; |
| DepthwiseConvolution operation; |
| ASSERT_OK(CreateDepthwiseConvolution(creation_context_, op_def, attr, |
| &operation)); |
| ASSERT_OK(ExecuteGPUOperation(src_tensor, creation_context_, &operation, |
| BHWC(1, 2, 2, 2), &dst_tensor)); |
| EXPECT_THAT(dst_tensor.data, |
| Pointwise(FloatNear(eps), {4.0f, 6.0f, 8.0f, 10.0f, 4.0f, |
| 6.0f, 8.0f, 10.0f})); |
| } |
| } |
| } |
| |
| TEST_F(OpenCLOperationTest, DepthwiseConvNoMultiplier) { |
| TensorFloat32 src_tensor; |
| src_tensor.shape = BHWC(1, 2, 2, 2); |
| src_tensor.data = {0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f}; |
| |
| DepthwiseConvolution2DAttributes attr; |
| attr.padding.prepended = HW(1, 0); |
| attr.padding.appended = HW(1, 0); |
| attr.strides = HW(1, 1); |
| attr.dilations = HW(1, 1); |
| attr.weights.shape = OHWI(1, 3, 1, 2); |
| attr.weights.data = {0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f}; |
| attr.bias.shape = Linear(2); |
| attr.bias.data = {0.5f, -0.5f}; |
| |
| for (auto storage : env_.GetSupportedStorages()) { |
| for (auto precision : env_.GetSupportedPrecisions()) { |
| const float eps = precision == CalculationsPrecision::F32 ? 1e-6f : 1e-3f; |
| OperationDef op_def; |
| op_def.precision = precision; |
| auto data_type = DeduceDataTypeFromPrecision(precision); |
| op_def.src_tensors.push_back({data_type, storage, Layout::HWC}); |
| op_def.dst_tensors.push_back({data_type, storage, Layout::HWC}); |
| TensorFloat32 dst_tensor; |
| DepthwiseConvolution operation; |
| ASSERT_OK(CreateDepthwiseConvolution(creation_context_, op_def, attr, |
| &operation)); |
| ASSERT_OK(ExecuteGPUOperation(src_tensor, creation_context_, &operation, |
| BHWC(1, 2, 2, 2), &dst_tensor)); |
| EXPECT_THAT(dst_tensor.data, |
| Pointwise(FloatNear(eps), {16.5f, 27.5f, 28.5f, 43.5f, 8.5f, |
| 15.5f, 12.5f, 23.5f})); |
| } |
| } |
| } |
| |
| TEST_F(OpenCLOperationTest, DepthwiseConvMultiplier2) { |
| TensorFloat32 src_tensor; |
| src_tensor.shape = BHWC(1, 2, 2, 2); |
| src_tensor.data = {0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f}; |
| |
| DepthwiseConvolution2DAttributes attr; |
| attr.padding.prepended = HW(1, 0); |
| attr.padding.appended = HW(1, 0); |
| attr.strides = HW(1, 1); |
| attr.dilations = HW(1, 1); |
| attr.weights.shape = OHWI(2, 3, 1, 2); |
| attr.weights.data = {0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, |
| 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f}; |
| attr.bias.shape = Linear(4); |
| attr.bias.data = {0.5f, -0.5f, 1.0f, -1.0f}; |
| |
| for (auto storage : env_.GetSupportedStorages()) { |
| for (auto precision : env_.GetSupportedPrecisions()) { |
| const float eps = precision == CalculationsPrecision::F32 ? 1e-6f : 1e-3f; |
| OperationDef op_def; |
| op_def.precision = precision; |
| auto data_type = DeduceDataTypeFromPrecision(precision); |
| op_def.src_tensors.push_back({data_type, storage, Layout::HWC}); |
| op_def.dst_tensors.push_back({data_type, storage, Layout::HWC}); |
| TensorFloat32 dst_tensor; |
| DepthwiseConvolution operation; |
| ASSERT_OK(CreateDepthwiseConvolution(creation_context_, op_def, attr, |
| &operation)); |
| ASSERT_OK(ExecuteGPUOperation(src_tensor, creation_context_, &operation, |
| BHWC(1, 2, 2, 4), &dst_tensor)); |
| EXPECT_THAT( |
| dst_tensor.data, |
| Pointwise(FloatNear(eps), |
| {16.5f, 39.5f, 29.0f, 63.0f, 28.5f, 75.5f, 45.0f, 103.0f, |
| 8.5f, 31.5f, 17.0f, 51.0f, 12.5f, 59.5f, 25.0f, 83.0f})); |
| } |
| } |
| } |
| |
| } // namespace |
| } // namespace cl |
| } // namespace gpu |
| } // namespace tflite |