Vector Optimized Library of Kernels 3.3.0
Architecture-tuned implementations of math kernels
Loading...
Searching...
No Matches
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
17static constexpr std::array<size_t, 5> default_vector_sizes{ 7, 32, 128, 1023, 131071 };
18
19std::vector<std::string> get_kernel_implementation_name_list(const volk_func_desc_t desc);
20
21bool is_aligned_implementation_name(const std::string& name);
22
23std::tuple<std::vector<std::string>, std::vector<std::string>>
24separate_implementations_by_alignment(const std::vector<std::string>& names);
25
26std::vector<std::string>
27get_aligned_kernel_implementation_names(const volk_func_desc_t desc);
28std::vector<std::string>
29get_unaligned_kernel_implementation_names(const volk_func_desc_t desc);
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
39class VolkTest : public ::testing::TestWithParam<std::tuple<std::string, size_t>>
40{
41protected:
42 void initialize_test(const std::tuple<std::string, size_t>& param)
43 {
44 std::tie(implementation_name, vector_length) = param;
46 }
47
51};
52
53
54template <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
92template <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
132template <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}