Grok  10.0.3
hwy_gtest.h
Go to the documentation of this file.
1 // Copyright 2021 Google LLC
2 // SPDX-License-Identifier: Apache-2.0
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 
16 #ifndef HWY_TESTS_HWY_GTEST_H_
17 #define HWY_TESTS_HWY_GTEST_H_
18 
19 // Adapters for GUnit to run tests for all targets.
20 
21 #include <stddef.h>
22 #include <stdint.h>
23 
24 #include <string>
25 #include <utility> // std::tuple
26 
27 #include "gtest/gtest.h"
28 #include "hwy/highway.h"
29 
30 namespace hwy {
31 
32 // googletest before 1.10 didn't define INSTANTIATE_TEST_SUITE_P() but instead
33 // used INSTANTIATE_TEST_CASE_P which is now deprecated.
34 #ifdef INSTANTIATE_TEST_SUITE_P
35 #define HWY_GTEST_INSTANTIATE_TEST_SUITE_P INSTANTIATE_TEST_SUITE_P
36 #else
37 #define HWY_GTEST_INSTANTIATE_TEST_SUITE_P INSTANTIATE_TEST_CASE_P
38 #endif
39 
40 // Helper class to run parametric tests using the hwy target as parameter. To
41 // use this define the following in your test:
42 // class MyTestSuite : public TestWithParamTarget {
43 // ...
44 // };
45 // HWY_TARGET_INSTANTIATE_TEST_SUITE_P(MyTestSuite);
46 // TEST_P(MyTestSuite, MyTest) { ... }
47 class TestWithParamTarget : public testing::TestWithParam<uint32_t> {
48  protected:
49  void SetUp() override { SetSupportedTargetsForTest(GetParam()); }
50 
51  void TearDown() override {
52  // Check that the parametric test calls SupportedTargets() when the source
53  // was compiled with more than one target. In the single-target case only
54  // static dispatch will be used anyway.
55 #if (HWY_TARGETS & (HWY_TARGETS - 1)) != 0
56  EXPECT_TRUE(GetChosenTarget().IsInitialized())
57  << "This hwy target parametric test doesn't use dynamic-dispatch and "
58  "doesn't need to be parametric.";
59 #endif
61  }
62 };
63 
64 // Function to convert the test parameter of a TestWithParamTarget for
65 // displaying it in the gtest test name.
66 static inline std::string TestParamTargetName(
67  const testing::TestParamInfo<uint32_t>& info) {
68  return TargetName(info.param);
69 }
70 
71 #define HWY_TARGET_INSTANTIATE_TEST_SUITE_P(suite) \
72  HWY_GTEST_INSTANTIATE_TEST_SUITE_P( \
73  suite##Group, suite, \
74  testing::ValuesIn(::hwy::SupportedAndGeneratedTargets()), \
75  ::hwy::TestParamTargetName)
76 
77 // Helper class similar to TestWithParamTarget to run parametric tests that
78 // depend on the target and another parametric test. If you need to use multiple
79 // extra parameters use a std::tuple<> of them and ::testing::Generate(...) as
80 // the generator. To use this class define the following in your test:
81 // class MyTestSuite : public TestWithParamTargetT<int> {
82 // ...
83 // };
84 // HWY_TARGET_INSTANTIATE_TEST_SUITE_P_T(MyTestSuite, ::testing::Range(0, 9));
85 // TEST_P(MyTestSuite, MyTest) { ... GetParam() .... }
86 template <typename T>
88  : public ::testing::TestWithParam<std::tuple<uint32_t, T>> {
89  public:
90  // Expose the parametric type here so it can be used by the
91  // HWY_TARGET_INSTANTIATE_TEST_SUITE_P_T macro.
92  using HwyParamType = T;
93 
94  protected:
95  void SetUp() override {
96  SetSupportedTargetsForTest(std::get<0>(
97  ::testing::TestWithParam<std::tuple<uint32_t, T>>::GetParam()));
98  }
99 
100  void TearDown() override {
101  // Check that the parametric test calls SupportedTargets() when the source
102  // was compiled with more than one target. In the single-target case only
103  // static dispatch will be used anyway.
104 #if (HWY_TARGETS & (HWY_TARGETS - 1)) != 0
105  EXPECT_TRUE(GetChosenTarget().IsInitialized())
106  << "This hwy target parametric test doesn't use dynamic-dispatch and "
107  "doesn't need to be parametric.";
108 #endif
110  }
111 
112  T GetParam() {
113  return std::get<1>(
114  ::testing::TestWithParam<std::tuple<uint32_t, T>>::GetParam());
115  }
116 };
117 
118 template <typename T>
120  const testing::TestParamInfo<std::tuple<uint32_t, T>>& info) {
121  return std::string(TargetName(std::get<0>(info.param))) + "_" +
122  ::testing::PrintToString(std::get<1>(info.param));
123 }
124 
125 #define HWY_TARGET_INSTANTIATE_TEST_SUITE_P_T(suite, generator) \
126  HWY_GTEST_INSTANTIATE_TEST_SUITE_P( \
127  suite##Group, suite, \
128  ::testing::Combine( \
129  testing::ValuesIn(::hwy::SupportedAndGeneratedTargets()), \
130  generator), \
131  ::hwy::TestParamTargetNameAndT<suite::HwyParamType>)
132 
133 // Helper macro to export a function and define a test that tests it. This is
134 // equivalent to do a HWY_EXPORT of a void(void) function and run it in a test:
135 // class MyTestSuite : public TestWithParamTarget {
136 // ...
137 // };
138 // HWY_TARGET_INSTANTIATE_TEST_SUITE_P(MyTestSuite);
139 // HWY_EXPORT_AND_TEST_P(MyTestSuite, MyTest);
140 #define HWY_EXPORT_AND_TEST_P(suite, func_name) \
141  HWY_EXPORT(func_name); \
142  TEST_P(suite, func_name) { HWY_DYNAMIC_DISPATCH(func_name)(); } \
143  static_assert(true, "For requiring trailing semicolon")
144 
145 #define HWY_EXPORT_AND_TEST_P_T(suite, func_name) \
146  HWY_EXPORT(func_name); \
147  TEST_P(suite, func_name) { HWY_DYNAMIC_DISPATCH(func_name)(GetParam()); } \
148  static_assert(true, "For requiring trailing semicolon")
149 
150 #define HWY_BEFORE_TEST(suite) \
151  class suite : public hwy::TestWithParamTarget {}; \
152  HWY_TARGET_INSTANTIATE_TEST_SUITE_P(suite); \
153  static_assert(true, "For requiring trailing semicolon")
154 
155 } // namespace hwy
156 
157 #endif // HWY_TESTS_HWY_GTEST_H_
Definition: hwy_gtest.h:88
void TearDown() override
Definition: hwy_gtest.h:100
T GetParam()
Definition: hwy_gtest.h:112
T HwyParamType
Definition: hwy_gtest.h:92
void SetUp() override
Definition: hwy_gtest.h:95
Definition: hwy_gtest.h:47
void TearDown() override
Definition: hwy_gtest.h:51
void SetUp() override
Definition: hwy_gtest.h:49
Definition: aligned_allocator.h:27
HWY_DLLEXPORT void SetSupportedTargetsForTest(uint32_t targets)
HWY_DLLEXPORT ChosenTarget & GetChosenTarget()
static std::string TestParamTargetName(const testing::TestParamInfo< uint32_t > &info)
Definition: hwy_gtest.h:66
static HWY_MAYBE_UNUSED const char * TargetName(uint32_t target)
Definition: targets.h:77
std::string TestParamTargetNameAndT(const testing::TestParamInfo< std::tuple< uint32_t, T >> &info)
Definition: hwy_gtest.h:119