Skip to content

Commit 5b1d1b4

Browse files
committed
Added test of basic math functions for integral batches (sse and avx)
1 parent b140981 commit 5b1d1b4

File tree

3 files changed

+135
-23
lines changed

3 files changed

+135
-23
lines changed

test/xsimd_basic_math_test.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,13 @@ namespace xsimd
3333
}
3434

3535
#if XSIMD_X86_INSTR_SET >= XSIMD_X86_SSE2_VERSION
36+
TEST(xsimd, sse_int32_basic_math)
37+
{
38+
std::ofstream out("log/sse_int32_basic_math.log", std::ios_base::out);
39+
bool res = xsimd::test_basic_math<int32_t, 4, 16>(out, "sse int32_t");
40+
EXPECT_TRUE(res);
41+
}
42+
3643
TEST(xsimd, sse_float_basic_math)
3744
{
3845
std::ofstream out("log/sse_float_basic_math.log", std::ios_base::out);
@@ -49,6 +56,13 @@ TEST(xsimd, sse_double_basic_math)
4956
#endif
5057

5158
#if XSIMD_X86_INSTR_SET >= XSIMD_X86_AVX_VERSION
59+
TEST(xsimd, avx_int32_basic_math)
60+
{
61+
std::ofstream out("log/avx_int32_basic_math.log", std::ios_base::out);
62+
bool res = xsimd::test_basic_math<int32_t, 8, 32>(out, "avx int32_t");
63+
EXPECT_TRUE(res);
64+
}
65+
5266
TEST(xsimd, avx_float_basic_math)
5367
{
5468
std::ofstream out("log/avx_float_basic_math.log", std::ios_base::out);

test/xsimd_basic_math_test.hpp

Lines changed: 74 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@ namespace xsimd
6666
clip_hi = 1.;
6767
for (size_t i = 0; i < N; ++i)
6868
{
69-
lhs_input[i] = value_type(i) / 4 + value_type(1.2) * std::sqrt(value_type(i + 0.25));
70-
rhs_input[i] = value_type(10.2) / (i + 2) + value_type(0.25);
69+
lhs_input[i] = value_type(i) / 4 + value_type(1.2) * std::sqrt(value_type(i + 0.25)) + 1.;
70+
rhs_input[i] = value_type(10.2) / (i + 2) + value_type(0.25) + 1.;
7171
from_input[i] = rhs_input[i] - value_type(1);
7272
fmod_res[i] = std::fmod(lhs_input[i], rhs_input[i]);
7373
remainder_res[i] = std::remainder(lhs_input[i], rhs_input[i]);
@@ -81,6 +81,76 @@ namespace xsimd
8181
}
8282
}
8383

84+
namespace detail
85+
{
86+
template <class T, bool is_int = std::is_integral<typename T::value_type>::value>
87+
struct infinity_tester
88+
{
89+
using tester_type = T;
90+
using vector_type = typename T::vector_type;
91+
using res_type = typename T::res_type;
92+
93+
static inline bool isfinite(std::ostream& out,
94+
const std::string& topic,
95+
tester_type& tester,
96+
res_type& res)
97+
{
98+
vector_type lhs = infinity<vector_type>();
99+
vector_type vres = select(xsimd::isfinite(lhs), vector_type(1.), vector_type(0.));
100+
detail::store_vec(vres, res);
101+
bool success = check_almost_equal(topic, res, tester.inf_res, out);
102+
typename res_type::value_type scalar_cond_res = xsimd::isfinite(lhs[0])?1.:0.;
103+
success &= check_almost_equal(topic, scalar_cond_res, tester.inf_res[0], out);
104+
return success;
105+
}
106+
107+
static inline bool isinf(std::ostream& out,
108+
const std::string& topic,
109+
tester_type& tester,
110+
res_type& res)
111+
112+
{
113+
vector_type lhs = infinity<vector_type>();
114+
vector_type vres = select(xsimd::isinf(lhs), vector_type(0.), vector_type(1.));
115+
detail::store_vec(vres, res);
116+
bool success = check_almost_equal(topic, res, tester.inf_res, out);
117+
typename res_type::value_type scalar_cond_res = xsimd::isinf(lhs[0])?0.:1.;
118+
success &= check_almost_equal(topic, scalar_cond_res, tester.inf_res[0], out);
119+
return success;
120+
}
121+
};
122+
123+
template <class T>
124+
struct infinity_tester<T, true>
125+
{
126+
using tester_type = T;
127+
using vector_type = typename T::vector_type;
128+
using res_type = typename T::res_type;
129+
130+
static inline bool isfinite(std::ostream& out,
131+
const std::string& topic,
132+
tester_type& tester,
133+
res_type&)
134+
{
135+
vector_type lhs(1.);
136+
typename res_type::value_type scalar_cond_res = xsimd::isfinite(lhs[0])?0.:1.;
137+
bool success = check_almost_equal(topic, scalar_cond_res, tester.inf_res[0], out);
138+
return true;
139+
}
140+
141+
static inline bool isinf(std::ostream& out,
142+
const std::string& topic,
143+
tester_type& tester,
144+
res_type&)
145+
{
146+
vector_type lhs(1.);
147+
typename res_type::value_type scalar_cond_res = xsimd::isfinite(lhs[0])?1.:0.;
148+
bool success = check_almost_equal(topic, scalar_cond_res, tester.inf_res[0], out);
149+
return true;
150+
}
151+
};
152+
}
153+
84154
template <class T>
85155
bool test_simd_basic_math(std::ostream& out, T& tester)
86156
{
@@ -152,28 +222,15 @@ namespace xsimd
152222
detail::store_vec(vres, res);
153223
tmp_success = check_almost_equal(topic, res, tester.finite_res, out);
154224
success = success && tmp_success;
155-
lhs = infinity<vector_type>();
156-
vres = select(isfinite(lhs), vector_type(1.), vector_type(0.));
157-
detail::store_vec(vres, res);
158-
tmp_success = check_almost_equal(topic, res, tester.inf_res, out);
159-
success = success && tmp_success;
160-
scalar_cond_res = xsimd::isfinite(lhs[0])?1.:0.;
161-
success &= check_almost_equal(topic, scalar_cond_res, tester.inf_res[0], out);
225+
success = success && detail::infinity_tester<T>::isfinite(out, topic, tester, res);
162226

163227
topic = "isinf : ";
164228
lhs = vector_type(12.);
165229
vres = select(isinf(lhs), vector_type(0.), vector_type(1.));
166230
detail::store_vec(vres, res);
167231
tmp_success = check_almost_equal(topic, res, tester.finite_res, out);
168232
success = success && tmp_success;
169-
lhs = infinity<vector_type>();
170-
vres = select(isinf(lhs), vector_type(0.), vector_type(1.));
171-
detail::store_vec(vres, res);
172-
tmp_success = check_almost_equal(topic, res, tester.inf_res, out);
173-
success = success && tmp_success;
174-
scalar_cond_res = xsimd::isinf(lhs[0])?0.:1.;
175-
success &= check_almost_equal(topic, scalar_cond_res, tester.inf_res[0], out);
176-
233+
177234
topic = "nextafter: ";
178235
detail::load_vec(lhs, tester.from_input);
179236
detail::load_vec(rhs, tester.rhs_input);

test/xsimd_test_utils.hpp

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -232,12 +232,50 @@ namespace xsimd
232232
return os;
233233
}
234234

235-
template <class T>
236-
inline bool check_almost_equal(const std::string& topic, const T& res, const T& ref, std::ostream& out)
235+
namespace detail
236+
{
237+
template <class T1, class T2>
238+
struct almost_equal_checker
239+
{
240+
static bool run_scalar(const T1& res, const T2& ref)
241+
{
242+
return almost_equal_checker<T1, T1>::run_scalar(res, T1(ref));
243+
}
244+
245+
template <class A1, class A2>
246+
static bool run_vector(const std::vector<T1, A1>& res,
247+
const std::vector<T2, A2>& ref)
248+
{
249+
std::vector<T1, A1> new_ref(ref.size());
250+
std::transform(ref.cbegin(), ref.end(), new_ref.begin(),
251+
[](const T2& v) { return static_cast<T1>(v); });
252+
return almost_equal_checker<T1, T1>::run_vector(res, new_ref);
253+
}
254+
};
255+
256+
template <class T>
257+
struct almost_equal_checker<T, T>
258+
{
259+
static bool run_scalar(const T& res, const T& ref)
260+
{
261+
return scalar_comparison<T>::run(res, ref);
262+
}
263+
264+
template <class A>
265+
static bool run_vector(const std::vector<T, A>& res,
266+
const std::vector<T, A>& ref)
267+
{
268+
return vector_comparison(res, ref);
269+
}
270+
};
271+
};
272+
273+
template <class T1, class T2>
274+
inline bool check_almost_equal(const std::string& topic, const T1& res, const T2& ref, std::ostream& out)
237275
{
238276
out << topic;
239277
out << std::setprecision(20);
240-
if (scalar_comparison<T>::run(res, ref))
278+
if (detail::almost_equal_checker<T1, T2>::run_scalar(res, ref))
241279
{
242280
out << "OK" << std::endl;
243281
return true;
@@ -255,12 +293,15 @@ namespace xsimd
255293

256294
#define PRINT_COUT
257295

258-
template <class T, class A>
259-
inline bool check_almost_equal(const std::string& topic, const std::vector<T, A>& res, const std::vector<T, A>& ref, std::ostream& out)
296+
template <class T1, class A1, class T2, class A2>
297+
inline bool check_almost_equal(const std::string& topic,
298+
const std::vector<T1, A1>& res,
299+
const std::vector<T2, A2>& ref,
300+
std::ostream& out)
260301
{
261302
out << topic;
262303
out << std::setprecision(20);
263-
int comp = vector_comparison(res, ref);
304+
int comp = detail::almost_equal_checker<T1, T2>::run_vector(res, ref);
264305
if (comp == 0)
265306
{
266307
out << "OK" << std::endl;

0 commit comments

Comments
 (0)