Grok 10.0.1
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
30namespace 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) { ... }
47class 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.
66static 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() .... }
86template <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 {
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
113 return std::get<1>(
114 ::testing::TestWithParam<std::tuple<uint32_t, T>>::GetParam());
115 }
116};
117
118template <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
static HWY_MAYBE_UNUSED const char * TargetName(uint32_t target)
Definition: targets.h:77
HWY_DLLEXPORT void SetSupportedTargetsForTest(uint32_t targets)
std::string TestParamTargetNameAndT(const testing::TestParamInfo< std::tuple< uint32_t, T > > &info)
Definition: hwy_gtest.h:119
static std::string TestParamTargetName(const testing::TestParamInfo< uint32_t > &info)
Definition: hwy_gtest.h:66
HWY_DLLEXPORT ChosenTarget & GetChosenTarget()