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