]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/compute/test/test_lambda.cpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / compute / test / test_lambda.cpp
CommitLineData
7c673cae
FG
1//---------------------------------------------------------------------------//
2// Copyright (c) 2013 Kyle Lutz <kyle.r.lutz@gmail.com>
3//
4// Distributed under the Boost Software License, Version 1.0
5// See accompanying file LICENSE_1_0.txt or copy at
6// http://www.boost.org/LICENSE_1_0.txt
7//
8// See http://boostorg.github.com/compute for more information.
9//---------------------------------------------------------------------------//
10
11#define BOOST_TEST_MODULE TestLambda
12#include <boost/test/unit_test.hpp>
13
14#include <boost/tuple/tuple_io.hpp>
15#include <boost/tuple/tuple_comparison.hpp>
16
17#include <boost/compute/function.hpp>
18#include <boost/compute/lambda.hpp>
19#include <boost/compute/algorithm/copy_n.hpp>
20#include <boost/compute/algorithm/for_each.hpp>
21#include <boost/compute/algorithm/transform.hpp>
22#include <boost/compute/container/vector.hpp>
23#include <boost/compute/functional/bind.hpp>
24#include <boost/compute/iterator/zip_iterator.hpp>
25#include <boost/compute/types/pair.hpp>
26#include <boost/compute/types/tuple.hpp>
27
28#include "check_macros.hpp"
29#include "context_setup.hpp"
30
31namespace bc = boost::compute;
32namespace compute = boost::compute;
33
34BOOST_AUTO_TEST_CASE(squared_plus_one)
35{
36 bc::vector<int> vector(context);
37 vector.push_back(1, queue);
38 vector.push_back(2, queue);
39 vector.push_back(3, queue);
40 vector.push_back(4, queue);
41 vector.push_back(5, queue);
42
43 // multiply each value by itself and add one
44 bc::transform(vector.begin(),
45 vector.end(),
46 vector.begin(),
47 (bc::_1 * bc::_1) + 1,
48 queue);
49 CHECK_RANGE_EQUAL(int, 5, vector, (2, 5, 10, 17, 26));
50}
51
52BOOST_AUTO_TEST_CASE(abs_int)
53{
54 bc::vector<int> vector(context);
55 vector.push_back(-1, queue);
56 vector.push_back(-2, queue);
57 vector.push_back(3, queue);
58 vector.push_back(-4, queue);
59 vector.push_back(5, queue);
60
61 bc::transform(vector.begin(),
62 vector.end(),
63 vector.begin(),
64 abs(bc::_1),
65 queue);
66 CHECK_RANGE_EQUAL(int, 5, vector, (1, 2, 3, 4, 5));
67}
68
69template<class Result, class Expr>
70void check_lambda_result(const Expr &)
71{
72 BOOST_STATIC_ASSERT((
73 boost::is_same<
74 typename ::boost::compute::lambda::result_of<Expr>::type,
75 Result
76 >::value
77 ));
78}
79
80template<class Result, class Expr, class Arg1>
81void check_lambda_result(const Expr &, const Arg1 &)
82{
83 BOOST_STATIC_ASSERT((
84 boost::is_same<
85 typename ::boost::compute::lambda::result_of<
86 Expr,
87 typename boost::tuple<Arg1>
88 >::type,
89 Result
90 >::value
91 ));
92}
93
94template<class Result, class Expr, class Arg1, class Arg2>
95void check_lambda_result(const Expr &, const Arg1 &, const Arg2 &)
96{
97 BOOST_STATIC_ASSERT((
98 boost::is_same<
99 typename ::boost::compute::lambda::result_of<
100 Expr,
101 typename boost::tuple<Arg1, Arg2>
102 >::type,
103 Result
104 >::value
105 ));
106}
107
108template<class Result, class Expr, class Arg1, class Arg2, class Arg3>
109void check_lambda_result(const Expr &, const Arg1 &, const Arg2 &, const Arg3 &)
110{
111 BOOST_STATIC_ASSERT((
112 boost::is_same<
113 typename ::boost::compute::lambda::result_of<
114 Expr,
115 typename boost::tuple<Arg1, Arg2, Arg3>
116 >::type,
117 Result
118 >::value
119 ));
120}
121
122BOOST_AUTO_TEST_CASE(result_of)
123{
124 using ::boost::compute::lambda::_1;
125 using ::boost::compute::lambda::_2;
126 using ::boost::compute::lambda::_3;
127
128 namespace proto = ::boost::proto;
129
130 check_lambda_result<int>(proto::lit(1));
131 check_lambda_result<int>(proto::lit(1) + 2);
132 check_lambda_result<float>(proto::lit(1.2f));
133 check_lambda_result<float>(proto::lit(1) + 1.2f);
134 check_lambda_result<float>(proto::lit(1) / 2 + 1.2f);
135
136 using boost::compute::float4_;
137
138 check_lambda_result<int>(_1, int(1));
139 check_lambda_result<float>(_1, float(1.2f));
140 check_lambda_result<float4_>(_1, float4_(1, 2, 3, 4));
141 check_lambda_result<float4_>(2.0f * _1, float4_(1, 2, 3, 4));
142 check_lambda_result<float4_>(_1 * 2.0f, float4_(1, 2, 3, 4));
143
144 check_lambda_result<float>(dot(_1, _2), float4_(0, 1, 2, 3), float4_(3, 2, 1, 0));
145 check_lambda_result<float>(dot(_1, float4_(3, 2, 1, 0)), float4_(0, 1, 2, 3));
146 check_lambda_result<float>(distance(_1, _2), float4_(0, 1, 2, 3), float4_(3, 2, 1, 0));
147 check_lambda_result<float>(distance(_1, float4_(3, 2, 1, 0)), float4_(0, 1, 2, 3));
148
149 check_lambda_result<float4_>(cross(_1, _2), float4_(0, 1, 2, 3), float4_(3, 2, 1, 0));
150 check_lambda_result<float4_>(cross(_1, float4_(3, 2, 1, 0)), float4_(0, 1, 2, 3));
151
152 check_lambda_result<int>(_1 + 2, int(2));
153 check_lambda_result<float>(_1 + 2, float(2.2f));
154
155 check_lambda_result<int>(_1 + _2, int(1), int(2));
156 check_lambda_result<float>(_1 + _2, int(1), float(2.2f));
157
158 check_lambda_result<int>(_1 + _1, int(1));
159 check_lambda_result<float>(_1 * _1, float(1));
160
161 using boost::compute::lambda::get;
162
163 check_lambda_result<float>(get<0>(_1), float4_(1, 2, 3, 4));
164 check_lambda_result<bool>(get<0>(_1) < 1.f, float4_(1, 2, 3, 4));
165 check_lambda_result<bool>(_1 < 1.f, float(2));
166
167 using boost::compute::lambda::make_pair;
168
169 check_lambda_result<int>(get<0>(make_pair(_1, _2)), int(1), float(1.2f));
170 check_lambda_result<float>(get<1>(make_pair(_1, _2)), int(1), float(1.2f));
171 check_lambda_result<std::pair<int, float> >(make_pair(_1, _2), int(1), float(1.2f));
172
173 using boost::compute::lambda::make_tuple;
174
175 check_lambda_result<boost::tuple<int> >(make_tuple(_1), int(1));
176 check_lambda_result<boost::tuple<int, float> >(make_tuple(_1, _2), int(1), float(1.2f));
177 check_lambda_result<boost::tuple<int, int> >(make_tuple(_1, _1), int(1));
178 check_lambda_result<boost::tuple<int, float> >(make_tuple(_1, _2), int(1), float(1.4f));
179 check_lambda_result<boost::tuple<char, int, float> >(
180 make_tuple(_1, _2, _3), char('a'), int(2), float(3.4f)
181 );
182 check_lambda_result<boost::tuple<int, int, int> >(
183 make_tuple(_1, _1, _1), int(1), float(1.4f)
184 );
185 check_lambda_result<boost::tuple<int, float, int, float, int> >(
186 make_tuple(_1, _2, _1, _2, _1), int(1), float(1.4f)
187 );
188}
189
190BOOST_AUTO_TEST_CASE(make_function_from_lamdba)
191{
192 using boost::compute::lambda::_1;
193
194 int data[] = { 2, 4, 6, 8, 10 };
195 compute::vector<int> vector(data, data + 5, queue);
196
197 compute::function<int(int)> f = _1 * 2 + 3;
198
199 compute::transform(
200 vector.begin(), vector.end(), vector.begin(), f, queue
201 );
202 CHECK_RANGE_EQUAL(int, 5, vector, (7, 11, 15, 19, 23));
203}
204
205BOOST_AUTO_TEST_CASE(make_function_from_binary_lamdba)
206{
207 using boost::compute::lambda::_1;
208 using boost::compute::lambda::_2;
209 using boost::compute::lambda::abs;
210
211 int data1[] = { 2, 4, 6, 8, 10 };
212 int data2[] = { 10, 8, 6, 4, 2 };
213 compute::vector<int> vec1(data1, data1 + 5, queue);
214 compute::vector<int> vec2(data2, data2 + 5, queue);
215 compute::vector<int> result(5, context);
216
217 compute::function<int(int, int)> f = abs(_1 - _2);
218
219 compute::transform(
220 vec1.begin(), vec1.end(), vec2.begin(), result.begin(), f, queue
221 );
222 CHECK_RANGE_EQUAL(int, 5, result, (8, 4, 0, 4, 8));
223}
224
225BOOST_AUTO_TEST_CASE(lambda_get_vector)
226{
227 using boost::compute::_1;
228 using boost::compute::int2_;
229 using boost::compute::lambda::get;
230
231 int data[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
232 compute::vector<int2_> vector(4, context);
233
234 compute::copy(
235 reinterpret_cast<int2_ *>(data),
236 reinterpret_cast<int2_ *>(data) + 4,
237 vector.begin(),
238 queue
239 );
240
241 // extract first component of each vector
242 compute::vector<int> first_component(4, context);
243 compute::transform(
244 vector.begin(),
245 vector.end(),
246 first_component.begin(),
247 get<0>(_1),
248 queue
249 );
250 CHECK_RANGE_EQUAL(int, 4, first_component, (1, 3, 5, 7));
251
252 // extract second component of each vector
253 compute::vector<int> second_component(4, context);
254 compute::transform(
255 vector.begin(),
256 vector.end(),
257 first_component.begin(),
258 get<1>(_1),
259 queue
260 );
261 CHECK_RANGE_EQUAL(int, 4, first_component, (2, 4, 6, 8));
262}
263
264BOOST_AUTO_TEST_CASE(lambda_get_pair)
265{
266 using boost::compute::_1;
267 using boost::compute::lambda::get;
268
269 compute::vector<std::pair<int, float> > vector(context);
270 vector.push_back(std::make_pair(1, 1.2f), queue);
271 vector.push_back(std::make_pair(3, 3.4f), queue);
272 vector.push_back(std::make_pair(5, 5.6f), queue);
273 vector.push_back(std::make_pair(7, 7.8f), queue);
274
275 // extract first compoenent of each pair
276 compute::vector<int> first_component(4, context);
277 compute::transform(
278 vector.begin(),
279 vector.end(),
280 first_component.begin(),
281 get<0>(_1),
282 queue
283 );
284 CHECK_RANGE_EQUAL(int, 4, first_component, (1, 3, 5, 7));
285
286 // extract second compoenent of each pair
287 compute::vector<float> second_component(4, context);
288 compute::transform(
289 vector.begin(),
290 vector.end(),
291 second_component.begin(),
292 get<1>(_1),
293 queue
294 );
295 CHECK_RANGE_EQUAL(float, 4, second_component, (1.2f, 3.4f, 5.6f, 7.8f));
296}
297
298BOOST_AUTO_TEST_CASE(lambda_get_tuple)
299{
300 using boost::compute::_1;
301 using boost::compute::lambda::get;
302
303 compute::vector<boost::tuple<int, char, float> > vector(context);
304
305 vector.push_back(boost::make_tuple(1, 'a', 1.2f), queue);
306 vector.push_back(boost::make_tuple(3, 'b', 3.4f), queue);
307 vector.push_back(boost::make_tuple(5, 'c', 5.6f), queue);
308 vector.push_back(boost::make_tuple(7, 'd', 7.8f), queue);
309
310 // extract first component of each tuple
311 compute::vector<int> first_component(4, context);
312 compute::transform(
313 vector.begin(),
314 vector.end(),
315 first_component.begin(),
316 get<0>(_1),
317 queue
318 );
319 CHECK_RANGE_EQUAL(int, 4, first_component, (1, 3, 5, 7));
320
321 // extract second component of each tuple
322 compute::vector<char> second_component(4, context);
323 compute::transform(
324 vector.begin(),
325 vector.end(),
326 second_component.begin(),
327 get<1>(_1),
328 queue
329 );
330 CHECK_RANGE_EQUAL(char, 4, second_component, ('a', 'b', 'c', 'd'));
331
332 // extract third component of each tuple
333 compute::vector<float> third_component(4, context);
334 compute::transform(
335 vector.begin(),
336 vector.end(),
337 third_component.begin(),
338 get<2>(_1),
339 queue
340 );
341 CHECK_RANGE_EQUAL(float, 4, third_component, (1.2f, 3.4f, 5.6f, 7.8f));
342}
343
344BOOST_AUTO_TEST_CASE(lambda_get_zip_iterator)
345{
346 using boost::compute::_1;
347 using boost::compute::lambda::get;
348
349 float data[] = { 1.2f, 2.3f, 3.4f, 4.5f, 5.6f, 6.7f, 7.8f, 9.0f };
350 compute::vector<float> input(8, context);
351 compute::copy(data, data + 8, input.begin(), queue);
352
353 compute::vector<float> output(8, context);
354
355 compute::for_each(
356 compute::make_zip_iterator(
357 boost::make_tuple(input.begin(), output.begin())
358 ),
359 compute::make_zip_iterator(
360 boost::make_tuple(input.end(), output.end())
361 ),
362 get<1>(_1) = get<0>(_1),
363 queue
364 );
365 CHECK_RANGE_EQUAL(float, 8, output,
366 (1.2f, 2.3f, 3.4f, 4.5f, 5.6f, 6.7f, 7.8f, 9.0f)
367 );
368}
369
370BOOST_AUTO_TEST_CASE(lambda_make_pair)
371{
372 using boost::compute::_1;
373 using boost::compute::_2;
374 using boost::compute::lambda::make_pair;
375
376 int int_data[] = { 1, 3, 5, 7 };
377 float float_data[] = { 1.2f, 2.3f, 3.4f, 4.5f };
378
379 compute::vector<int> int_vector(int_data, int_data + 4, queue);
380 compute::vector<float> float_vector(float_data, float_data + 4, queue);
381 compute::vector<std::pair<int, float> > output_vector(4, context);
382
383 compute::transform(
384 int_vector.begin(),
385 int_vector.end(),
386 float_vector.begin(),
387 output_vector.begin(),
388 make_pair(_1 - 1, 0 - _2),
389 queue
390 );
391
392 std::vector<std::pair<int, float> > host_vector(4);
393 compute::copy_n(output_vector.begin(), 4, host_vector.begin(), queue);
394 BOOST_CHECK(host_vector[0] == std::make_pair(0, -1.2f));
395 BOOST_CHECK(host_vector[1] == std::make_pair(2, -2.3f));
396 BOOST_CHECK(host_vector[2] == std::make_pair(4, -3.4f));
397 BOOST_CHECK(host_vector[3] == std::make_pair(6, -4.5f));
398}
399
400BOOST_AUTO_TEST_CASE(lambda_make_tuple)
401{
402 using boost::compute::_1;
403 using boost::compute::lambda::get;
404 using boost::compute::lambda::make_tuple;
405
406 std::vector<boost::tuple<int, float> > data;
407 data.push_back(boost::make_tuple(2, 1.2f));
408 data.push_back(boost::make_tuple(4, 2.4f));
409 data.push_back(boost::make_tuple(6, 4.6f));
410 data.push_back(boost::make_tuple(8, 6.8f));
411
412 compute::vector<boost::tuple<int, float> > input_vector(4, context);
413 compute::copy(data.begin(), data.end(), input_vector.begin(), queue);
414
415 // reverse the elements in the tuple
416 compute::vector<boost::tuple<float, int> > output_vector(4, context);
417
418 compute::transform(
419 input_vector.begin(),
420 input_vector.end(),
421 output_vector.begin(),
422 make_tuple(get<1>(_1), get<0>(_1)),
423 queue
424 );
425
426 std::vector<boost::tuple<float, int> > host_vector(4);
427 compute::copy_n(output_vector.begin(), 4, host_vector.begin(), queue);
428 BOOST_CHECK_EQUAL(host_vector[0], boost::make_tuple(1.2f, 2));
429 BOOST_CHECK_EQUAL(host_vector[1], boost::make_tuple(2.4f, 4));
430 BOOST_CHECK_EQUAL(host_vector[2], boost::make_tuple(4.6f, 6));
431 BOOST_CHECK_EQUAL(host_vector[3], boost::make_tuple(6.8f, 8));
432
433 // duplicate each element in the tuple
434 compute::vector<boost::tuple<int, int, float, float> > doubled_vector(4, context);
435 compute::transform(
436 input_vector.begin(),
437 input_vector.end(),
438 doubled_vector.begin(),
439 make_tuple(get<0>(_1), get<0>(_1), get<1>(_1), get<1>(_1)),
440 queue
441 );
442
443 std::vector<boost::tuple<int, int, float, float> > doubled_host_vector(4);
444 compute::copy_n(doubled_vector.begin(), 4, doubled_host_vector.begin(), queue);
445 BOOST_CHECK_EQUAL(doubled_host_vector[0], boost::make_tuple(2, 2, 1.2f, 1.2f));
446 BOOST_CHECK_EQUAL(doubled_host_vector[1], boost::make_tuple(4, 4, 2.4f, 2.4f));
447 BOOST_CHECK_EQUAL(doubled_host_vector[2], boost::make_tuple(6, 6, 4.6f, 4.6f));
448 BOOST_CHECK_EQUAL(doubled_host_vector[3], boost::make_tuple(8, 8, 6.8f, 6.8f));
449}
450
451BOOST_AUTO_TEST_CASE(bind_lambda_function)
452{
453 using compute::placeholders::_1;
454 namespace lambda = compute::lambda;
455
456 int data[] = { 1, 2, 3, 4 };
457 compute::vector<int> vector(data, data + 4, queue);
458
459 compute::transform(
460 vector.begin(), vector.end(), vector.begin(),
461 compute::bind(lambda::_1 * lambda::_2, _1, 2),
462 queue
463 );
464 CHECK_RANGE_EQUAL(int, 4, vector, (2, 4, 6, 8));
465}
466
467BOOST_AUTO_TEST_SUITE_END()