summaryrefslogtreecommitdiff
path: root/media/highway/src/hwy/tests/hwy_gtest.h
diff options
context:
space:
mode:
Diffstat (limited to 'media/highway/src/hwy/tests/hwy_gtest.h')
-rw-r--r--media/highway/src/hwy/tests/hwy_gtest.h157
1 files changed, 157 insertions, 0 deletions
diff --git a/media/highway/src/hwy/tests/hwy_gtest.h b/media/highway/src/hwy/tests/hwy_gtest.h
new file mode 100644
index 0000000000..ff29823f04
--- /dev/null
+++ b/media/highway/src/hwy/tests/hwy_gtest.h
@@ -0,0 +1,157 @@
+// Copyright 2021 Google LLC
+// SPDX-License-Identifier: Apache-2.0
+//
+// 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 HWY_TESTS_HWY_GTEST_H_
+#define HWY_TESTS_HWY_GTEST_H_
+
+// Adapters for GUnit to run tests for all targets.
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <string>
+#include <utility> // std::tuple
+
+#include "gtest/gtest.h"
+#include "hwy/highway.h"
+
+namespace hwy {
+
+// googletest before 1.10 didn't define INSTANTIATE_TEST_SUITE_P() but instead
+// used INSTANTIATE_TEST_CASE_P which is now deprecated.
+#ifdef INSTANTIATE_TEST_SUITE_P
+#define HWY_GTEST_INSTANTIATE_TEST_SUITE_P INSTANTIATE_TEST_SUITE_P
+#else
+#define HWY_GTEST_INSTANTIATE_TEST_SUITE_P INSTANTIATE_TEST_CASE_P
+#endif
+
+// Helper class to run parametric tests using the hwy target as parameter. To
+// use this define the following in your test:
+// class MyTestSuite : public TestWithParamTarget {
+// ...
+// };
+// HWY_TARGET_INSTANTIATE_TEST_SUITE_P(MyTestSuite);
+// TEST_P(MyTestSuite, MyTest) { ... }
+class TestWithParamTarget : public testing::TestWithParam<uint32_t> {
+ protected:
+ void SetUp() override { SetSupportedTargetsForTest(GetParam()); }
+
+ void TearDown() override {
+ // Check that the parametric test calls SupportedTargets() when the source
+ // was compiled with more than one target. In the single-target case only
+ // static dispatch will be used anyway.
+#if (HWY_TARGETS & (HWY_TARGETS - 1)) != 0
+ EXPECT_TRUE(SupportedTargetsCalledForTest())
+ << "This hwy target parametric test doesn't use dynamic-dispatch and "
+ "doesn't need to be parametric.";
+#endif
+ SetSupportedTargetsForTest(0);
+ }
+};
+
+// Function to convert the test parameter of a TestWithParamTarget for
+// displaying it in the gtest test name.
+static inline std::string TestParamTargetName(
+ const testing::TestParamInfo<uint32_t>& info) {
+ return TargetName(info.param);
+}
+
+#define HWY_TARGET_INSTANTIATE_TEST_SUITE_P(suite) \
+ HWY_GTEST_INSTANTIATE_TEST_SUITE_P( \
+ suite##Group, suite, \
+ testing::ValuesIn(::hwy::SupportedAndGeneratedTargets()), \
+ ::hwy::TestParamTargetName)
+
+// Helper class similar to TestWithParamTarget to run parametric tests that
+// depend on the target and another parametric test. If you need to use multiple
+// extra parameters use a std::tuple<> of them and ::testing::Generate(...) as
+// the generator. To use this class define the following in your test:
+// class MyTestSuite : public TestWithParamTargetT<int> {
+// ...
+// };
+// HWY_TARGET_INSTANTIATE_TEST_SUITE_P_T(MyTestSuite, ::testing::Range(0, 9));
+// TEST_P(MyTestSuite, MyTest) { ... GetParam() .... }
+template <typename T>
+class TestWithParamTargetAndT
+ : public ::testing::TestWithParam<std::tuple<uint32_t, T>> {
+ public:
+ // Expose the parametric type here so it can be used by the
+ // HWY_TARGET_INSTANTIATE_TEST_SUITE_P_T macro.
+ using HwyParamType = T;
+
+ protected:
+ void SetUp() override {
+ SetSupportedTargetsForTest(std::get<0>(
+ ::testing::TestWithParam<std::tuple<uint32_t, T>>::GetParam()));
+ }
+
+ void TearDown() override {
+ // Check that the parametric test calls SupportedTargets() when the source
+ // was compiled with more than one target. In the single-target case only
+ // static dispatch will be used anyway.
+#if (HWY_TARGETS & (HWY_TARGETS - 1)) != 0
+ EXPECT_TRUE(SupportedTargetsCalledForTest())
+ << "This hwy target parametric test doesn't use dynamic-dispatch and "
+ "doesn't need to be parametric.";
+#endif
+ SetSupportedTargetsForTest(0);
+ }
+
+ T GetParam() {
+ return std::get<1>(
+ ::testing::TestWithParam<std::tuple<uint32_t, T>>::GetParam());
+ }
+};
+
+template <typename T>
+std::string TestParamTargetNameAndT(
+ const testing::TestParamInfo<std::tuple<uint32_t, T>>& info) {
+ return std::string(TargetName(std::get<0>(info.param))) + "_" +
+ ::testing::PrintToString(std::get<1>(info.param));
+}
+
+#define HWY_TARGET_INSTANTIATE_TEST_SUITE_P_T(suite, generator) \
+ HWY_GTEST_INSTANTIATE_TEST_SUITE_P( \
+ suite##Group, suite, \
+ ::testing::Combine( \
+ testing::ValuesIn(::hwy::SupportedAndGeneratedTargets()), \
+ generator), \
+ ::hwy::TestParamTargetNameAndT<suite::HwyParamType>)
+
+// Helper macro to export a function and define a test that tests it. This is
+// equivalent to do a HWY_EXPORT of a void(void) function and run it in a test:
+// class MyTestSuite : public TestWithParamTarget {
+// ...
+// };
+// HWY_TARGET_INSTANTIATE_TEST_SUITE_P(MyTestSuite);
+// HWY_EXPORT_AND_TEST_P(MyTestSuite, MyTest);
+#define HWY_EXPORT_AND_TEST_P(suite, func_name) \
+ HWY_EXPORT(func_name); \
+ TEST_P(suite, func_name) { HWY_DYNAMIC_DISPATCH(func_name)(); } \
+ static_assert(true, "For requiring trailing semicolon")
+
+#define HWY_EXPORT_AND_TEST_P_T(suite, func_name) \
+ HWY_EXPORT(func_name); \
+ TEST_P(suite, func_name) { HWY_DYNAMIC_DISPATCH(func_name)(GetParam()); } \
+ static_assert(true, "For requiring trailing semicolon")
+
+#define HWY_BEFORE_TEST(suite) \
+ class suite : public hwy::TestWithParamTarget {}; \
+ HWY_TARGET_INSTANTIATE_TEST_SUITE_P(suite); \
+ static_assert(true, "For requiring trailing semicolon")
+
+} // namespace hwy
+
+#endif // HWY_TESTS_HWY_GTEST_H_