From 1203ea6aadeefb73ec66268d15e2f1ffe19118e8 Mon Sep 17 00:00:00 2001 From: Raman Sarokin Date: Thu, 14 Jan 2021 11:32:34 -0800 Subject: [PATCH] Add tests logic moved to add_test_util that can be reused among different backends. PiperOrigin-RevId: 351841484 Change-Id: I4520c6e75129c2a7e4ef382e2f5513408dbf9e9a --- .../lite/delegates/gpu/cl/kernels/BUILD | 2 +- .../lite/delegates/gpu/cl/kernels/add_test.cc | 96 ++------------ .../lite/delegates/gpu/common/task/BUILD | 3 + .../delegates/gpu/common/task/testing_util.cc | 42 +++++++ .../delegates/gpu/common/task/testing_util.h | 4 + .../lite/delegates/gpu/common/tasks/BUILD | 13 ++ .../gpu/common/tasks/add_test_util.cc | 118 ++++++++++++++++++ .../gpu/common/tasks/add_test_util.h | 36 ++++++ 8 files changed, 224 insertions(+), 90 deletions(-) create mode 100644 tensorflow/lite/delegates/gpu/common/task/testing_util.cc create mode 100644 tensorflow/lite/delegates/gpu/common/tasks/add_test_util.cc create mode 100644 tensorflow/lite/delegates/gpu/common/tasks/add_test_util.h diff --git a/tensorflow/lite/delegates/gpu/cl/kernels/BUILD b/tensorflow/lite/delegates/gpu/cl/kernels/BUILD index cf7d0e69e05..b68dd2cfad5 100644 --- a/tensorflow/lite/delegates/gpu/cl/kernels/BUILD +++ b/tensorflow/lite/delegates/gpu/cl/kernels/BUILD @@ -20,7 +20,7 @@ cc_test( ":cl_test", "//tensorflow/lite/delegates/gpu/common:operations", "//tensorflow/lite/delegates/gpu/common:status", - "//tensorflow/lite/delegates/gpu/common/tasks:add", + "//tensorflow/lite/delegates/gpu/common/tasks:add_test_util", "@com_google_googletest//:gtest_main", ], ) diff --git a/tensorflow/lite/delegates/gpu/cl/kernels/add_test.cc b/tensorflow/lite/delegates/gpu/cl/kernels/add_test.cc index 7bcaaf13c37..f1532b2eeee 100644 --- a/tensorflow/lite/delegates/gpu/cl/kernels/add_test.cc +++ b/tensorflow/lite/delegates/gpu/cl/kernels/add_test.cc @@ -13,8 +13,6 @@ See the License for the specific language governing permissions and limitations under the License. ==============================================================================*/ -#include "tensorflow/lite/delegates/gpu/common/tasks/add.h" - #include #include @@ -22,9 +20,7 @@ limitations under the License. #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; +#include "tensorflow/lite/delegates/gpu/common/tasks/add_test_util.h" namespace tflite { namespace gpu { @@ -32,96 +28,18 @@ namespace cl { namespace { TEST_F(OpenCLOperationTest, AddTwoEqualTensors) { - TensorFloat32 src0, src1; - src0.shape = BHWC(1, 2, 1, 2); - src0.data = {0.0f, -1.0f, -0.05f, 0.045f}; - src1.shape = BHWC(1, 2, 1, 2); - src1.data = {0.0f, 1.0f, -0.05f, -0.045f}; - std::vector channels = {2, 2}; - - 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.src_tensors.push_back({data_type, storage, Layout::HWC}); - op_def.dst_tensors.push_back({data_type, storage, Layout::HWC}); - TensorFloat32 dst_tensor; - GPUOperation operation = CreateAdd(op_def, channels, channels[0]); - ASSERT_OK(ExecuteGPUOperation( - {src0, src1}, creation_context_, - absl::make_unique(std::move(operation)), - BHWC(1, 2, 1, 2), &dst_tensor)); - EXPECT_THAT(dst_tensor.data, - Pointwise(FloatNear(eps), {0.0f, 0.0f, -0.1f, 0.0f})); - } - } + auto status = AddTwoEqualTensorsTest(&exec_env_); + ASSERT_TRUE(status.ok()) << status.error_message(); } TEST_F(OpenCLOperationTest, AddFirstTensorHasMoreChannelsThanSecond) { - TensorFloat32 src0, src1; - src0.shape = BHWC(1, 2, 1, 6); - src0.data = {0.0f, -1.0f, -0.05f, 0.045f, 1.0f, -2.0f, - -1.05f, 1.045f, 2.0f, -3.0f, -2.05f, 2.045f}; - src1.shape = BHWC(1, 2, 1, 2); - src1.data = {0.0f, 1.0f, -0.05f, -0.045f}; - std::vector channels = {6, 2}; - - 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.src_tensors.push_back({data_type, storage, Layout::HWC}); - op_def.dst_tensors.push_back({data_type, storage, Layout::HWC}); - TensorFloat32 dst_tensor; - GPUOperation operation = CreateAdd(op_def, channels, channels[0]); - ASSERT_OK(ExecuteGPUOperation( - {src0, src1}, creation_context_, - absl::make_unique(std::move(operation)), - BHWC(1, 2, 1, 6), &dst_tensor)); - EXPECT_THAT(dst_tensor.data, - Pointwise(FloatNear(eps), - {0.0f, 0.0f, -0.05f, 0.045f, 1.0f, -2.0f, -1.1f, - 1.0f, 2.0f, -3.0f, -2.05f, 2.045f})); - } - } + auto status = AddFirstTensorHasMoreChannelsThanSecondTest(&exec_env_); + ASSERT_TRUE(status.ok()) << status.error_message(); } TEST_F(OpenCLOperationTest, AddFirstTensorHasLessChannelsThanSecond) { - TensorFloat32 src0, src1; - src1.shape = BHWC(1, 2, 1, 6); - src1.data = {0.0f, -1.0f, -0.05f, 0.045f, 1.0f, -2.0f, - -1.05f, 1.045f, 2.0f, -3.0f, -2.05f, 2.045f}; - src0.shape = BHWC(1, 2, 1, 2); - src0.data = {0.0f, 1.0f, -0.05f, -0.045f}; - std::vector channels = {2, 6}; - - 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.src_tensors.push_back({data_type, storage, Layout::HWC}); - op_def.dst_tensors.push_back({data_type, storage, Layout::HWC}); - TensorFloat32 dst_tensor; - GPUOperation operation = CreateAdd(op_def, channels, 6); - ASSERT_OK(ExecuteGPUOperation( - {src0, src1}, creation_context_, - absl::make_unique(std::move(operation)), - BHWC(1, 2, 1, 6), &dst_tensor)); - EXPECT_THAT(dst_tensor.data, - Pointwise(FloatNear(eps), - {0.0f, 0.0f, -0.05f, 0.045f, 1.0f, -2.0f, -1.1f, - 1.0f, 2.0f, -3.0f, -2.05f, 2.045f})); - } - } + auto status = AddFirstTensorHasLessChannelsThanSecond(&exec_env_); + ASSERT_TRUE(status.ok()) << status.error_message(); } } // namespace diff --git a/tensorflow/lite/delegates/gpu/common/task/BUILD b/tensorflow/lite/delegates/gpu/common/task/BUILD index f8471757e67..f43952ed73d 100644 --- a/tensorflow/lite/delegates/gpu/common/task/BUILD +++ b/tensorflow/lite/delegates/gpu/common/task/BUILD @@ -133,6 +133,8 @@ cc_library( cc_library( name = "testing_util", + testonly = 1, + srcs = ["testing_util.cc"], hdrs = ["testing_util.h"], deps = [ ":gpu_operation", @@ -141,6 +143,7 @@ cc_library( "//tensorflow/lite/delegates/gpu/common:precision", "//tensorflow/lite/delegates/gpu/common:shape", "//tensorflow/lite/delegates/gpu/common:tensor", + "@com_google_absl//absl/strings", ], ) diff --git a/tensorflow/lite/delegates/gpu/common/task/testing_util.cc b/tensorflow/lite/delegates/gpu/common/task/testing_util.cc new file mode 100644 index 00000000000..de5a57a93d3 --- /dev/null +++ b/tensorflow/lite/delegates/gpu/common/task/testing_util.cc @@ -0,0 +1,42 @@ +/* Copyright 2021 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/common/task/testing_util.h" + +#include "absl/strings/str_cat.h" + +namespace tflite { +namespace gpu { + +absl::Status PointWiseNear(const std::vector& ref, + const std::vector& to_compare, float eps) { + if (ref.size() != to_compare.size()) { + return absl::InternalError(absl::StrCat("ref size(", ref.size(), + ") != to_compare size(", + to_compare.size(), ")")); + } + for (int i = 0; i < ref.size(); ++i) { + const float abs_diff = fabs(ref[i] - to_compare[i]); + if (abs_diff > eps) { + return absl::InternalError(absl::StrCat( + "ref[", i, "] = ", ref[i], ", to_compare[", i, "] = ", to_compare[i], + ", abs diff = ", abs_diff, " > ", eps, " (eps)")); + } + } + return absl::OkStatus(); +} + +} // namespace gpu +} // namespace tflite diff --git a/tensorflow/lite/delegates/gpu/common/task/testing_util.h b/tensorflow/lite/delegates/gpu/common/task/testing_util.h index 9f4609f6ca3..552ca5c3620 100644 --- a/tensorflow/lite/delegates/gpu/common/task/testing_util.h +++ b/tensorflow/lite/delegates/gpu/common/task/testing_util.h @@ -66,6 +66,10 @@ class TestExecutionEnvironment { } }; +absl::Status PointWiseNear(const std::vector& ref, + const std::vector& to_compare, + float eps = 0.0f); + } // namespace gpu } // namespace tflite diff --git a/tensorflow/lite/delegates/gpu/common/tasks/BUILD b/tensorflow/lite/delegates/gpu/common/tasks/BUILD index c78509ace50..65aa24c8413 100644 --- a/tensorflow/lite/delegates/gpu/common/tasks/BUILD +++ b/tensorflow/lite/delegates/gpu/common/tasks/BUILD @@ -16,6 +16,19 @@ cc_library( ], ) +cc_library( + name = "add_test_util", + testonly = 1, + srcs = ["add_test_util.cc"], + hdrs = ["add_test_util.h"], + deps = [ + ":add", + "//tensorflow/lite/delegates/gpu/common:operations", + "//tensorflow/lite/delegates/gpu/common:status", + "//tensorflow/lite/delegates/gpu/common/task:testing_util", + ], +) + cc_library( name = "concat_xy", srcs = ["concat_xy.cc"], diff --git a/tensorflow/lite/delegates/gpu/common/tasks/add_test_util.cc b/tensorflow/lite/delegates/gpu/common/tasks/add_test_util.cc new file mode 100644 index 00000000000..62d066f8912 --- /dev/null +++ b/tensorflow/lite/delegates/gpu/common/tasks/add_test_util.cc @@ -0,0 +1,118 @@ +/* Copyright 2021 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/common/tasks/add_test_util.h" + +#include "tensorflow/lite/delegates/gpu/common/operations.h" +#include "tensorflow/lite/delegates/gpu/common/status.h" +#include "tensorflow/lite/delegates/gpu/common/task/testing_util.h" +#include "tensorflow/lite/delegates/gpu/common/tasks/add.h" + +namespace tflite { +namespace gpu { + +absl::Status AddTwoEqualTensorsTest(TestExecutionEnvironment* env) { + TensorFloat32 src0, src1; + src0.shape = BHWC(1, 2, 1, 2); + src0.data = {0.0f, -1.0f, -0.05f, 0.045f}; + src1.shape = BHWC(1, 2, 1, 2); + src1.data = {0.0f, 1.0f, -0.05f, -0.045f}; + std::vector channels = {2, 2}; + + 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.src_tensors.push_back({data_type, storage, Layout::HWC}); + op_def.dst_tensors.push_back({data_type, storage, Layout::HWC}); + TensorFloat32 dst_tensor; + GPUOperation operation = CreateAdd(op_def, channels, channels[0]); + RETURN_IF_ERROR(env->ExecuteGPUOperation( + {src0, src1}, absl::make_unique(std::move(operation)), + BHWC(1, 2, 1, 2), &dst_tensor)); + RETURN_IF_ERROR( + PointWiseNear({0.0f, 0.0f, -0.1f, 0.0f}, dst_tensor.data, eps)); + } + } + return absl::OkStatus(); +} + +absl::Status AddFirstTensorHasMoreChannelsThanSecondTest( + TestExecutionEnvironment* env) { + TensorFloat32 src0, src1; + src0.shape = BHWC(1, 2, 1, 6); + src0.data = {0.0f, -1.0f, -0.05f, 0.045f, 1.0f, -2.0f, + -1.05f, 1.045f, 2.0f, -3.0f, -2.05f, 2.045f}; + src1.shape = BHWC(1, 2, 1, 2); + src1.data = {0.0f, 1.0f, -0.05f, -0.045f}; + std::vector channels = {6, 2}; + 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.src_tensors.push_back({data_type, storage, Layout::HWC}); + op_def.dst_tensors.push_back({data_type, storage, Layout::HWC}); + TensorFloat32 dst_tensor; + GPUOperation operation = CreateAdd(op_def, channels, channels[0]); + RETURN_IF_ERROR(env->ExecuteGPUOperation( + {src0, src1}, absl::make_unique(std::move(operation)), + BHWC(1, 2, 1, 6), &dst_tensor)); + RETURN_IF_ERROR(PointWiseNear({0.0f, 0.0f, -0.05f, 0.045f, 1.0f, -2.0f, + -1.1f, 1.0f, 2.0f, -3.0f, -2.05f, 2.045f}, + dst_tensor.data, eps)); + } + } + return absl::OkStatus(); +} + +absl::Status AddFirstTensorHasLessChannelsThanSecond( + TestExecutionEnvironment* env) { + TensorFloat32 src0, src1; + src1.shape = BHWC(1, 2, 1, 6); + src1.data = {0.0f, -1.0f, -0.05f, 0.045f, 1.0f, -2.0f, + -1.05f, 1.045f, 2.0f, -3.0f, -2.05f, 2.045f}; + src0.shape = BHWC(1, 2, 1, 2); + src0.data = {0.0f, 1.0f, -0.05f, -0.045f}; + std::vector channels = {2, 6}; + 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.src_tensors.push_back({data_type, storage, Layout::HWC}); + op_def.dst_tensors.push_back({data_type, storage, Layout::HWC}); + TensorFloat32 dst_tensor; + GPUOperation operation = CreateAdd(op_def, channels, 6); + RETURN_IF_ERROR(env->ExecuteGPUOperation( + {src0, src1}, absl::make_unique(std::move(operation)), + BHWC(1, 2, 1, 6), &dst_tensor)); + RETURN_IF_ERROR(PointWiseNear({0.0f, 0.0f, -0.05f, 0.045f, 1.0f, -2.0f, + -1.1f, 1.0f, 2.0f, -3.0f, -2.05f, 2.045f}, + dst_tensor.data, eps)); + } + } + return absl::OkStatus(); +} + +} // namespace gpu +} // namespace tflite diff --git a/tensorflow/lite/delegates/gpu/common/tasks/add_test_util.h b/tensorflow/lite/delegates/gpu/common/tasks/add_test_util.h new file mode 100644 index 00000000000..c86a8ababa4 --- /dev/null +++ b/tensorflow/lite/delegates/gpu/common/tasks/add_test_util.h @@ -0,0 +1,36 @@ +/* Copyright 2021 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. +==============================================================================*/ + +#ifndef TENSORFLOW_LITE_DELEGATES_GPU_COMMON_TASKS_ADD_TEST_UTIL_H_ +#define TENSORFLOW_LITE_DELEGATES_GPU_COMMON_TASKS_ADD_TEST_UTIL_H_ + +#include "tensorflow/lite/delegates/gpu/common/status.h" +#include "tensorflow/lite/delegates/gpu/common/task/testing_util.h" + +namespace tflite { +namespace gpu { + +absl::Status AddTwoEqualTensorsTest(TestExecutionEnvironment* env); + +absl::Status AddFirstTensorHasMoreChannelsThanSecondTest( + TestExecutionEnvironment* env); + +absl::Status AddFirstTensorHasLessChannelsThanSecond( + TestExecutionEnvironment* env); + +} // namespace gpu +} // namespace tflite + +#endif // TENSORFLOW_LITE_DELEGATES_GPU_COMMON_TASKS_ADD_TEST_UTIL_H_