Nektar++
TestVmathSIMD.cpp
Go to the documentation of this file.
1///////////////////////////////////////////////////////////////////////////////
2//
3// File: TestVmathSIMD.cpp
4//
5// For more information, please see: http://www.nektar.info
6//
7// The MIT License
8//
9// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
10// Department of Aeronautics, Imperial College London (UK), and Scientific
11// Computing and Imaging Institute, University of Utah (USA).
12//
13// Permission is hereby granted, free of charge, to any person obtaining a
14// copy of this software and associated documentation files (the "Software"),
15// to deal in the Software without restriction, including without limitation
16// the rights to use, copy, modify, merge, publish, distribute, sublicense,
17// and/or sell copies of the Software, and to permit persons to whom the
18// Software is furnished to do so, subject to the following conditions:
19//
20// The above copyright notice and this permission notice shall be included
21// in all copies or substantial portions of the Software.
22//
23// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29// DEALINGS IN THE SOFTWARE.
30//
31// Description:
32//
33///////////////////////////////////////////////////////////////////////////////
34
36#include <array>
37
38#include <boost/test/tools/floating_point_comparison.hpp>
39#include <boost/test/unit_test.hpp>
40
42{
44{
45 using dataType = double;
46 constexpr size_t n = 31;
47 alignas(tinysimd::simd<dataType>::alignment) std::array<dataType, n> x, y,
48 z;
49 dataType epsilon = std::numeric_limits<dataType>::epsilon();
50
51 // init
52 for (size_t i = 0; i < n; ++i)
53 {
54 x[i] = 1.0;
55 y[i] = 1.0;
56 }
57 // test z = x + y
58 Vmath::SIMD::Vadd(n, x.data(), y.data(), z.data());
59
60 for (size_t i = 0; i < n; ++i)
61 {
62 BOOST_CHECK_CLOSE(z[i], 2.0, epsilon);
63 }
64
65 // ---------------------------------------------------------------------
66
67 // init
68 for (size_t i = 0; i < n; ++i)
69 {
70 x[i] = 2.0;
71 y[i] = 0.0;
72 }
73 // test z = x + y
74 Vmath::SIMD::Vadd(n, x.data(), y.data(), z.data());
75
76 for (size_t i = 0; i < n; ++i)
77 {
78 BOOST_CHECK_CLOSE(z[i], 2.0, epsilon);
79 }
80
81 // ---------------------------------------------------------------------
82
83 // init
84 for (size_t i = 0; i < n; ++i)
85 {
86 x[i] = 0.0;
87 y[i] = -2.0;
88 }
89 // test z = x + y
90 Vmath::SIMD::Vadd(n, x.data(), y.data(), z.data());
91
92 for (size_t i = 0; i < n; ++i)
93 {
94 BOOST_CHECK_CLOSE(z[i], -2.0, epsilon);
95 }
96}
97
99{
100 using dataType = double;
101 constexpr size_t n = 31;
102 alignas(tinysimd::simd<dataType>::alignment) std::array<dataType, n> x, y,
103 z;
104 dataType epsilon = std::numeric_limits<dataType>::epsilon();
105
106 // init
107 for (size_t i = 0; i < n; ++i)
108 {
109 x[i] = 1.0;
110 y[i] = i;
111 }
112 // test z = x + y
113 Vmath::SIMD::Vmul(n, x.data(), y.data(), z.data());
114
115 for (size_t i = 0; i < n; ++i)
116 {
117 BOOST_CHECK_CLOSE(z[i], i, epsilon);
118 }
119
120 // ---------------------------------------------------------------------
121
122 // init
123 for (size_t i = 0; i < n; ++i)
124 {
125 x[i] = 2.0;
126 y[i] = 0.0;
127 }
128 // test z = x + y
129 Vmath::SIMD::Vmul(n, x.data(), y.data(), z.data());
130
131 for (size_t i = 0; i < n; ++i)
132 {
133 BOOST_CHECK_CLOSE(z[i], 0.0, epsilon);
134 }
135
136 // ---------------------------------------------------------------------
137
138 // init
139 for (size_t i = 0; i < n; ++i)
140 {
141 x[i] = -1.0;
142 y[i] = 2.0;
143 }
144 // test z = x + y
145 Vmath::SIMD::Vmul(n, x.data(), y.data(), z.data());
146
147 for (size_t i = 0; i < n; ++i)
148 {
149 BOOST_CHECK_CLOSE(z[i], -2.0, epsilon);
150 }
151}
152
154{
155 using dataType = double;
156 constexpr size_t n = 11;
157 alignas(tinysimd::simd<dataType>::alignment) std::array<dataType, n> w, x,
158 y, z;
159 dataType epsilon = std::numeric_limits<dataType>::epsilon();
160
161 // init
162 for (size_t i = 0; i < n; ++i)
163 {
164 w[i] = 1.0;
165 x[i] = 1.0;
166 y[i] = 1.0;
167 }
168 // test z = w * x + y
169 Vmath::SIMD::Vvtvp(n, w.data(), x.data(), y.data(), z.data());
170
171 for (size_t i = 0; i < n; ++i)
172 {
173 BOOST_CHECK_CLOSE(z[i], 2.0, epsilon);
174 }
175
176 // ---------------------------------------------------------------------
177
178 // init
179 for (size_t i = 0; i < n; ++i)
180 {
181 w[i] = 0.0;
182 x[i] = 1.5;
183 y[i] = 0.5;
184 }
185 // test z = w * x + y
186 Vmath::SIMD::Vvtvp(n, w.data(), x.data(), y.data(), z.data());
187
188 for (size_t i = 0; i < n; ++i)
189 {
190 BOOST_CHECK_CLOSE(z[i], 0.5, epsilon);
191 }
192
193 // ---------------------------------------------------------------------
194
195 // init
196 for (size_t i = 0; i < n; ++i)
197 {
198 w[i] = 1.0;
199 x[i] = 0.5;
200 y[i] = 0.0;
201 }
202 // test z = w * x + y
203 Vmath::SIMD::Vvtvp(n, w.data(), x.data(), y.data(), z.data());
204
205 for (size_t i = 0; i < n; ++i)
206 {
207 BOOST_CHECK_CLOSE(z[i], 0.5, epsilon);
208 }
209}
210
212{
213 using dataType = double;
214 constexpr size_t n = 11;
215 alignas(tinysimd::simd<dataType>::alignment) std::array<dataType, n> v, w,
216 x, y, z;
217 dataType epsilon = std::numeric_limits<dataType>::epsilon();
218
219 // init
220 for (size_t i = 0; i < n; ++i)
221 {
222 v[i] = 1.0;
223 w[i] = 1.0;
224 x[i] = 1.0;
225 y[i] = 1.0;
226 }
227 // test z = v * w + y * z;
228 Vmath::SIMD::Vvtvvtp(n, v.data(), w.data(), x.data(), y.data(), z.data());
229
230 for (size_t i = 0; i < n; ++i)
231 {
232 BOOST_CHECK_CLOSE(z[i], 2.0, epsilon);
233 }
234
235 // ---------------------------------------------------------------------
236
237 // init
238 for (size_t i = 0; i < n; ++i)
239 {
240 v[i] = 1.0;
241 w[i] = 0.0;
242 x[i] = 0.5;
243 y[i] = 1.0;
244 }
245 // test z = v * w + y * z;
246 Vmath::SIMD::Vvtvvtp(n, v.data(), w.data(), x.data(), y.data(), z.data());
247
248 for (size_t i = 0; i < n; ++i)
249 {
250 BOOST_CHECK_CLOSE(z[i], 0.5, epsilon);
251 }
252
253 // ---------------------------------------------------------------------
254
255 // init
256 for (size_t i = 0; i < n; ++i)
257 {
258 v[i] = 0.5;
259 w[i] = 1.0;
260 x[i] = 0.0;
261 y[i] = 1.0;
262 }
263 // test z = v * w + y * z;
264 Vmath::SIMD::Vvtvvtp(n, v.data(), w.data(), x.data(), y.data(), z.data());
265
266 for (size_t i = 0; i < n; ++i)
267 {
268 BOOST_CHECK_CLOSE(z[i], 0.5, epsilon);
269 }
270}
271
272BOOST_AUTO_TEST_CASE(TestGathrSizet)
273{
274 using dataType = double;
275 constexpr size_t n = 11;
276 std::array<dataType, n> x;
277 constexpr size_t ni = 5;
278 std::array<size_t, ni> y;
279 std::array<dataType, ni> z;
280
281 dataType epsilon = std::numeric_limits<dataType>::epsilon();
282
283 // init
284 for (size_t i = 0; i < n; ++i)
285 {
286 x[i] = i;
287 }
288
289 y[0] = 0;
290 y[1] = 3;
291 y[2] = 4;
292 y[3] = 7;
293 y[4] = 10;
294
295 // test z = x[y]
296 Vmath::SIMD::Gathr(ni, x.data(), y.data(), z.data());
297
298 for (size_t i = 0; i < ni; ++i)
299 {
300 BOOST_CHECK_CLOSE(z[i], x[y[i]], epsilon);
301 }
302}
303
305{
306 using dataType = double;
307 constexpr size_t n = 30;
308 std::array<dataType, n> x;
309 constexpr int ni = 13;
310 std::array<int, ni> y;
311 std::array<dataType, ni> z;
312
313 dataType epsilon = std::numeric_limits<dataType>::epsilon();
314
315 // init
316 for (size_t i = 0; i < n; ++i)
317 {
318 x[i] = i;
319 }
320
321 y[0] = 0;
322 y[1] = 3;
323 y[2] = 4;
324 y[3] = 7;
325 y[4] = 10;
326 y[5] = 11;
327 y[6] = 12;
328 y[7] = 15;
329 y[8] = 16;
330 y[9] = 20;
331 y[10] = 21;
332 y[11] = 22;
333 y[12] = 27;
334
335 // test z = x[y]
336 Vmath::SIMD::Gathr(ni, x.data(), y.data(), z.data());
337
338 for (size_t i = 0; i < ni; ++i)
339 {
340 BOOST_CHECK_CLOSE(z[i], x[y[i]], epsilon);
341 }
342}
343
344} // namespace Nektar::VmathSIMDUnitTests
std::vector< double > w(NPUPPER)
std::vector< double > z(NPUPPER)
void Vvtvp(const size_t n, const T *w, const T *x, const T *y, T *z)
vvtvp (vector times vector plus vector): z = w*x + y
Definition: VmathSIMD.hpp:259
void Vadd(const size_t n, const T *x, const T *y, T *z)
Add vector z = x + y.
Definition: VmathSIMD.hpp:47
void Gathr(const I n, const T *x, const I *y, T *z)
Gather vector z[i] = x[y[i]].
Definition: VmathSIMD.hpp:472
void Vvtvvtp(const size_t n, const T *v, const T *w, const T *x, const T *y, T *z)
vvtvvtp (vector times vector plus vector times vector):
Definition: VmathSIMD.hpp:356
void Vmul(const size_t n, const T *x, const T *y, T *z)
Multiply vector z = x * y.
Definition: VmathSIMD.hpp:153
typename abi< ScalarType, width >::type simd
Definition: tinysimd.hpp:80