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