Grok  9.5.0
test_util.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_TEST_UTIL_H_
16 #define HWY_TESTS_TEST_UTIL_H_
17 
18 // Target-independent helper functions for use by *_test.cc.
19 
20 #include <stddef.h>
21 #include <stdint.h>
22 #include <string.h>
23 
24 #include <string>
25 
26 #include "hwy/aligned_allocator.h"
27 #include "hwy/base.h"
28 #include "hwy/highway.h"
29 
30 namespace hwy {
31 
32 // The maximum vector size used in tests when defining test data. DEPRECATED.
33 constexpr size_t kTestMaxVectorSize = 64;
34 
35 // 64-bit random generator (Xorshift128+). Much smaller state than std::mt19937,
36 // which triggers a compiler bug.
37 class RandomState {
38  public:
39  explicit RandomState(const uint64_t seed = 0x123456789ull) {
40  s0_ = SplitMix64(seed + 0x9E3779B97F4A7C15ull);
41  s1_ = SplitMix64(s0_);
42  }
43 
44  HWY_INLINE uint64_t operator()() {
45  uint64_t s1 = s0_;
46  const uint64_t s0 = s1_;
47  const uint64_t bits = s1 + s0;
48  s0_ = s0;
49  s1 ^= s1 << 23;
50  s1 ^= s0 ^ (s1 >> 18) ^ (s0 >> 5);
51  s1_ = s1;
52  return bits;
53  }
54 
55  private:
56  static uint64_t SplitMix64(uint64_t z) {
57  z = (z ^ (z >> 30)) * 0xBF58476D1CE4E5B9ull;
58  z = (z ^ (z >> 27)) * 0x94D049BB133111EBull;
59  return z ^ (z >> 31);
60  }
61 
62  uint64_t s0_;
63  uint64_t s1_;
64 };
65 
66 static HWY_INLINE uint32_t Random32(RandomState* rng) {
67  return static_cast<uint32_t>((*rng)());
68 }
69 
70 static HWY_INLINE uint64_t Random64(RandomState* rng) {
71  return (*rng)();
72 }
73 
74 // Prevents the compiler from eliding the computations that led to "output".
75 // Works by indicating to the compiler that "output" is being read and modified.
76 // The +r constraint avoids unnecessary writes to memory, but only works for
77 // built-in types.
78 template <class T>
79 inline void PreventElision(T&& output) {
80 #if HWY_COMPILER_MSVC
81  (void)output;
82 #else // HWY_COMPILER_MSVC
83  asm volatile("" : "+r"(output) : : "memory");
84 #endif // HWY_COMPILER_MSVC
85 }
86 
87 bool BytesEqual(const void* p1, const void* p2, const size_t size,
88  size_t* pos = nullptr);
89 
90 void AssertStringEqual(const char* expected, const char* actual,
91  const char* target_name, const char* filename, int line);
92 
93 namespace detail {
94 
95 template <typename T, typename TU = MakeUnsigned<T>>
96 TU ComputeUlpDelta(const T expected, const T actual) {
97  // Handle -0 == 0 and infinities.
98  if (expected == actual) return 0;
99 
100  // Consider "equal" if both are NaN, so we can verify an expected NaN.
101  // Needs a special case because there are many possible NaN representations.
102  if (std::isnan(expected) && std::isnan(actual)) return 0;
103 
104  // Compute the difference in units of last place. We do not need to check for
105  // differing signs; they will result in large differences, which is fine.
106  TU ux, uy;
107  CopyBytes<sizeof(T)>(&expected, &ux);
108  CopyBytes<sizeof(T)>(&actual, &uy);
109 
110  // Avoid unsigned->signed cast: 2's complement is only guaranteed by C++20.
111  const TU ulp = HWY_MAX(ux, uy) - HWY_MIN(ux, uy);
112  return ulp;
113 }
114 
115 // For implementing value comparisons etc. as type-erased functions to reduce
116 // template bloat.
117 struct TypeInfo {
118  size_t sizeof_t;
119  bool is_float;
120  bool is_signed;
121 };
122 
123 template <typename T>
125  TypeInfo info;
126  info.sizeof_t = sizeof(T);
127  info.is_float = IsFloat<T>();
128  info.is_signed = IsSigned<T>();
129  return info;
130 }
131 
132 bool IsEqual(const TypeInfo& info, const void* expected_ptr,
133  const void* actual_ptr);
134 
135 void TypeName(const TypeInfo& info, size_t N, char* string100);
136 
137 void PrintArray(const TypeInfo& info, const char* caption,
138  const void* array_void, size_t N, size_t lane_u = 0,
139  size_t max_lanes = 7);
140 
142  const void* expected_ptr,
143  const void* actual_ptr,
144  const char* target_name,
145  const char* filename, int line,
146  size_t lane = 0, size_t num_lanes = 1);
147 
148 void AssertArrayEqual(const TypeInfo& info, const void* expected_void,
149  const void* actual_void, size_t N,
150  const char* target_name, const char* filename, int line);
151 
152 } // namespace detail
153 
154 // Returns a name for the vector/part/scalar. The type prefix is u/i/f for
155 // unsigned/signed/floating point, followed by the number of bits per lane;
156 // then 'x' followed by the number of lanes. Example: u8x16. This is useful for
157 // understanding which instantiation of a generic test failed.
158 template <typename T>
159 std::string TypeName(T /*unused*/, size_t N) {
160  char string100[100];
161  detail::TypeName(detail::MakeTypeInfo<T>(), N, string100);
162  return string100;
163 }
164 
165 // Compare non-vector, non-string T.
166 template <typename T>
167 HWY_INLINE bool IsEqual(const T expected, const T actual) {
168  const auto info = detail::MakeTypeInfo<T>();
169  return detail::IsEqual(info, &expected, &actual);
170 }
171 
172 template <typename T>
173 HWY_INLINE void AssertEqual(const T expected, const T actual,
174  const char* target_name, const char* filename,
175  int line, size_t lane = 0) {
176  const auto info = detail::MakeTypeInfo<T>();
177  if (!detail::IsEqual(info, &expected, &actual)) {
178  detail::PrintMismatchAndAbort(info, &expected, &actual, target_name,
179  filename, line, lane);
180  }
181 }
182 
183 } // namespace hwy
184 
185 #endif // HWY_TESTS_TEST_UTIL_H_
#define HWY_MAX(a, b)
Definition: base.h:123
#define HWY_NORETURN
Definition: base.h:62
#define HWY_MIN(a, b)
Definition: base.h:122
#define HWY_INLINE
Definition: base.h:59
Definition: test_util.h:37
static uint64_t SplitMix64(uint64_t z)
Definition: test_util.h:56
HWY_INLINE uint64_t operator()()
Definition: test_util.h:44
uint64_t s0_
Definition: test_util.h:62
uint64_t s1_
Definition: test_util.h:63
RandomState(const uint64_t seed=0x123456789ull)
Definition: test_util.h:39
void AssertArrayEqual(const TypeInfo &info, const void *expected_void, const void *actual_void, size_t N, const char *target_name, const char *filename, int line)
void PrintArray(const TypeInfo &info, const char *caption, const void *array_void, size_t N, size_t lane_u=0, size_t max_lanes=7)
void TypeName(const TypeInfo &info, size_t N, char *string100)
bool IsEqual(const TypeInfo &info, const void *expected_ptr, const void *actual_ptr)
TU ComputeUlpDelta(const T expected, const T actual)
Definition: test_util.h:96
HWY_NORETURN void PrintMismatchAndAbort(const TypeInfo &info, const void *expected_ptr, const void *actual_ptr, const char *target_name, const char *filename, int line, size_t lane=0, size_t num_lanes=1)
HWY_INLINE TypeInfo MakeTypeInfo()
Definition: test_util.h:124
Definition: aligned_allocator.h:23
void AssertStringEqual(const char *expected, const char *actual, const char *target_name, const char *filename, int line)
constexpr size_t kTestMaxVectorSize
Definition: test_util.h:33
HWY_INLINE bool IsEqual(const T expected, const T actual)
Definition: test_util.h:167
bool BytesEqual(const void *p1, const void *p2, const size_t size, size_t *pos=nullptr)
static HWY_INLINE uint64_t Random64(RandomState *rng)
Definition: test_util.h:70
std::string TypeName(T, size_t N)
Definition: test_util.h:159
HWY_INLINE void AssertEqual(const T expected, const T actual, const char *target_name, const char *filename, int line, size_t lane=0)
Definition: test_util.h:173
static HWY_INLINE uint32_t Random32(RandomState *rng)
Definition: test_util.h:66
HWY_NORETURN void int line
Definition: base.h:665
void PreventElision(T &&output)
Definition: test_util.h:79
message_info info
Definition: ojph_message.cpp:50
Definition: test_util.h:117
bool is_float
Definition: test_util.h:119
bool is_signed
Definition: test_util.h:120
size_t sizeof_t
Definition: test_util.h:118