Vector Optimized Library of Kernels  3.3.0
Architecture-tuned implementations of math kernels
volk_test.h
Go to the documentation of this file.
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2022 Johannes Demel
4  *
5  * This file is part of VOLK
6  *
7  * SPDX-License-Identifier: LGPL-3.0-or-later
8  */
9 
10 #include <fmt/core.h>
11 #include <fmt/ranges.h>
12 #include <gtest/gtest.h>
13 #include <volk/volk.h>
14 #include <array>
15 #include <tuple>
16 
17 static constexpr std::array<size_t, 5> default_vector_sizes{ 7, 32, 128, 1023, 131071 };
18 
19 std::vector<std::string> get_kernel_implementation_name_list(const volk_func_desc_t desc);
20 
21 bool is_aligned_implementation_name(const std::string& name);
22 
23 std::tuple<std::vector<std::string>, std::vector<std::string>>
24 separate_implementations_by_alignment(const std::vector<std::string>& names);
25 
26 std::vector<std::string>
28 std::vector<std::string>
30 
32  template <class ParamType>
33  std::string operator()(const ::testing::TestParamInfo<ParamType>& info) const
34  {
35  return fmt::format("{}_{}", std::get<0>(info.param), std::get<1>(info.param));
36  }
37 };
38 
39 class VolkTest : public ::testing::TestWithParam<std::tuple<std::string, size_t>>
40 {
41 protected:
42  void initialize_test(const std::tuple<std::string, size_t>& param)
43  {
44  std::tie(implementation_name, vector_length) = param;
46  }
47 
48  std::string implementation_name;
50  size_t vector_length;
51 };
52 
53 
54 template <class T>
55 ::testing::AssertionResult AreComplexFloatingPointArraysAlmostEqual(const T& expected,
56  const T& actual)
57 {
58  ::testing::AssertionResult result = ::testing::AssertionFailure();
59  if (expected.size() != actual.size()) {
60  return result << "expected result size=" << expected.size()
61  << " differs from actual size=" << actual.size();
62  }
63  const unsigned long length = expected.size();
64 
65  int errorsFound = 0;
66  const char* separator = " ";
67  for (unsigned long index = 0; index < length; index++) {
68  auto expected_real = ::testing::internal::FloatingPoint(expected[index].real());
69  auto expected_imag = ::testing::internal::FloatingPoint(expected[index].imag());
70  auto actual_real = ::testing::internal::FloatingPoint(actual[index].real());
71  auto actual_imag = ::testing::internal::FloatingPoint(actual[index].imag());
72  if (not expected_real.AlmostEquals(actual_real) or
73  not expected_imag.AlmostEquals(actual_imag)) {
74  if (errorsFound == 0) {
75  result << "Differences found:";
76  }
77  if (errorsFound < 3) {
78  result << separator << expected[index] << " != " << actual[index] << " @ "
79  << index;
80  separator = ",\n";
81  }
82  errorsFound++;
83  }
84  }
85  if (errorsFound > 0) {
86  result << separator << errorsFound << " differences in total";
87  return result;
88  }
89  return ::testing::AssertionSuccess();
90 }
91 
92 template <class T>
94  const T& expected, const T& actual, const float absolute_error = 1.0e-7)
95 {
96  ::testing::AssertionResult result = ::testing::AssertionFailure();
97  if (expected.size() != actual.size()) {
98  return result << "expected result size=" << expected.size()
99  << " differs from actual size=" << actual.size();
100  }
101  const unsigned long length = expected.size();
102 
103  int errorsFound = 0;
104  const char* separator = " ";
105  for (unsigned long index = 0; index < length; index++) {
106  auto expected_real = ::testing::internal::FloatingPoint(expected[index].real());
107  auto expected_imag = ::testing::internal::FloatingPoint(expected[index].imag());
108  auto actual_real = ::testing::internal::FloatingPoint(actual[index].real());
109  auto actual_imag = ::testing::internal::FloatingPoint(actual[index].imag());
110  if (expected_real.is_nan() or actual_real.is_nan() or expected_imag.is_nan() or
111  actual_imag.is_nan() or
112  std::abs(expected[index].real() - actual[index].real()) > absolute_error or
113  std::abs(expected[index].imag() - actual[index].imag()) > absolute_error) {
114  if (errorsFound == 0) {
115  result << "Differences found:";
116  }
117  if (errorsFound < 3) {
118  result << separator << expected[index] << " != " << actual[index] << " @ "
119  << index;
120  separator = ",\n";
121  }
122  errorsFound++;
123  }
124  }
125  if (errorsFound > 0) {
126  result << separator << errorsFound << " differences in total";
127  return result;
128  }
129  return ::testing::AssertionSuccess();
130 }
131 
132 template <class T>
134  const T& expected, const T& actual, const float absolute_error = 1.0e-7)
135 {
136  ::testing::AssertionResult result = ::testing::AssertionFailure();
137  if (expected.size() != actual.size()) {
138  return result << "expected result size=" << expected.size()
139  << " differs from actual size=" << actual.size();
140  }
141  const unsigned long length = expected.size();
142 
143  int errorsFound = 0;
144  const char* separator = " ";
145  for (unsigned long index = 0; index < length; index++) {
146  auto expected_value = ::testing::internal::FloatingPoint(expected[index]);
147  auto actual_value = ::testing::internal::FloatingPoint(actual[index]);
148  if (expected_value.is_nan() or actual_value.is_nan() or
149  std::abs(expected[index] - actual[index]) > absolute_error) {
150  if (errorsFound == 0) {
151  result << "Differences found:";
152  }
153  if (errorsFound < 3) {
154  result << separator << expected[index] << " != " << actual[index] << " @ "
155  << index;
156  separator = ",\n";
157  }
158  errorsFound++;
159  }
160  }
161  if (errorsFound > 0) {
162  result << separator << errorsFound << " differences in total";
163  return result;
164  }
165  return ::testing::AssertionSuccess();
166 }
get_aligned_kernel_implementation_names
std::vector< std::string > get_aligned_kernel_implementation_names(const volk_func_desc_t desc)
Definition: volk_test.cc:89
VolkTest::implementation_name
std::string implementation_name
Definition: volk_test.h:48
VolkTest::initialize_test
void initialize_test(const std::tuple< std::string, size_t > &param)
Definition: volk_test.h:42
separate_implementations_by_alignment
std::tuple< std::vector< std::string >, std::vector< std::string > > separate_implementations_by_alignment(const std::vector< std::string > &names)
Definition: volk_test.cc:74
generate_volk_test_name::operator()
std::string operator()(const ::testing::TestParamInfo< ParamType > &info) const
Definition: volk_test.h:33
AreFloatingPointArraysEqualWithAbsoluteError
::testing::AssertionResult AreFloatingPointArraysEqualWithAbsoluteError(const T &expected, const T &actual, const float absolute_error=1.0e-7)
Definition: volk_test.h:133
VolkTest::vector_length
size_t vector_length
Definition: volk_test.h:50
VolkTest::is_aligned_implementation
bool is_aligned_implementation
Definition: volk_test.h:49
get_unaligned_kernel_implementation_names
std::vector< std::string > get_unaligned_kernel_implementation_names(const volk_func_desc_t desc)
Definition: volk_test.cc:97
is_aligned_implementation_name
bool is_aligned_implementation_name(const std::string &name)
Definition: volk_test.cc:68
default_vector_sizes
static constexpr std::array< size_t, 5 > default_vector_sizes
Definition: volk_test.h:17
volk_func_desc_t
__VOLK_DECL_BEGIN struct volk_func_desc volk_func_desc_t
Get description parameters for this kernel.
Definition: volk.tmpl.h:91
VolkTest
Definition: volk_test.h:40
AreComplexFloatingPointArraysAlmostEqual
::testing::AssertionResult AreComplexFloatingPointArraysAlmostEqual(const T &expected, const T &actual)
Definition: volk_test.h:55
generate_volk_test_name
Definition: volk_test.h:31
get_kernel_implementation_name_list
std::vector< std::string > get_kernel_implementation_name_list(const volk_func_desc_t desc)
Definition: volk_test.cc:58
volk_arch_defs.name
name
Definition: volk_arch_defs.py:56
AreComplexFloatingPointArraysEqualWithAbsoluteError
::testing::AssertionResult AreComplexFloatingPointArraysEqualWithAbsoluteError(const T &expected, const T &actual, const float absolute_error=1.0e-7)
Definition: volk_test.h:93