]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/compute/test/test_vector.cpp
f49a745529f91483397cf8e98ae53f3f33e00e73
[ceph.git] / ceph / src / boost / libs / compute / test / test_vector.cpp
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 TestVector
12 #include <boost/test/unit_test.hpp>
13 #include <boost/concept_check.hpp>
14
15 #include <iostream>
16
17 #include <boost/compute/system.hpp>
18 #include <boost/compute/command_queue.hpp>
19 #include <boost/compute/algorithm/copy.hpp>
20 #include <boost/compute/algorithm/fill.hpp>
21 #include <boost/compute/algorithm/find.hpp>
22 #include <boost/compute/algorithm/remove.hpp>
23 #include <boost/compute/allocator/pinned_allocator.hpp>
24 #include <boost/compute/container/vector.hpp>
25
26 #include "quirks.hpp"
27 #include "check_macros.hpp"
28 #include "context_setup.hpp"
29
30 namespace bc = boost::compute;
31 namespace compute = boost::compute;
32
33 BOOST_AUTO_TEST_CASE(concept_check)
34 {
35 BOOST_CONCEPT_ASSERT((boost::Container<bc::vector<int> >));
36 //BOOST_CONCEPT_ASSERT((boost::SequenceConcept<bc::vector<int> >));
37 BOOST_CONCEPT_ASSERT((boost::ReversibleContainer<bc::vector<int> >));
38 BOOST_CONCEPT_ASSERT((boost::RandomAccessIterator<bc::vector<int>::iterator>));
39 BOOST_CONCEPT_ASSERT((boost::RandomAccessIterator<bc::vector<int>::const_iterator>));
40 }
41
42 BOOST_AUTO_TEST_CASE(size)
43 {
44 bc::vector<int> empty_vector(context);
45 BOOST_CHECK_EQUAL(empty_vector.size(), size_t(0));
46 BOOST_CHECK_EQUAL(empty_vector.empty(), true);
47
48 bc::vector<int> int_vector(10, context);
49 BOOST_CHECK_EQUAL(int_vector.size(), size_t(10));
50 BOOST_CHECK_EQUAL(int_vector.empty(), false);
51 }
52
53 BOOST_AUTO_TEST_CASE(resize)
54 {
55 bc::vector<int> int_vector(10, context);
56 BOOST_CHECK_EQUAL(int_vector.size(), size_t(10));
57
58 int_vector.resize(20, queue);
59 BOOST_CHECK_EQUAL(int_vector.size(), size_t(20));
60
61 int_vector.resize(5, queue);
62 BOOST_CHECK_EQUAL(int_vector.size(), size_t(5));
63 }
64
65 BOOST_AUTO_TEST_CASE(array_operator)
66 {
67 bc::vector<int> vector(10, context);
68 bc::fill(vector.begin(), vector.end(), 0, queue);
69 CHECK_RANGE_EQUAL(int, 10, vector, (0, 0, 0, 0, 0, 0, 0, 0, 0, 0));
70
71 bc::fill(vector.begin(), vector.end(), 42, queue);
72 CHECK_RANGE_EQUAL(int, 10, vector, (42, 42, 42, 42, 42, 42, 42, 42, 42, 42));
73
74 vector[0] = 9;
75 CHECK_RANGE_EQUAL(int, 10, vector, (9, 42, 42, 42, 42, 42, 42, 42, 42, 42));
76 }
77
78 BOOST_AUTO_TEST_CASE(front_and_back)
79 {
80 int int_data[] = { 1, 2, 3, 4, 5 };
81 bc::vector<int> int_vector(5, context);
82 bc::copy(int_data, int_data + 5, int_vector.begin(), queue);
83 queue.finish();
84 BOOST_CHECK_EQUAL(int_vector.front(), 1);
85 BOOST_CHECK_EQUAL(int_vector.back(), 5);
86
87 bc::fill(int_vector.begin(), int_vector.end(), 10, queue);
88 queue.finish();
89 BOOST_CHECK_EQUAL(int_vector.front(), 10);
90 BOOST_CHECK_EQUAL(int_vector.back(), 10);
91
92 float float_data[] = { 1.1f, 2.2f, 3.3f, 4.4f, 5.5f };
93 bc::vector<float> float_vector(5, context);
94 bc::copy(float_data, float_data + 5, float_vector.begin(), queue);
95 queue.finish();
96 BOOST_CHECK_EQUAL(float_vector.front(), 1.1f);
97 BOOST_CHECK_EQUAL(float_vector.back(), 5.5f);
98 }
99
100 BOOST_AUTO_TEST_CASE(host_iterator_constructor)
101 {
102 std::vector<int> host_vector;
103 host_vector.push_back(10);
104 host_vector.push_back(20);
105 host_vector.push_back(30);
106 host_vector.push_back(40);
107
108 bc::vector<int> device_vector(host_vector.begin(), host_vector.end(),
109 queue);
110 CHECK_RANGE_EQUAL(int, 4, device_vector, (10, 20, 30, 40));
111 }
112
113 BOOST_AUTO_TEST_CASE(device_iterator_constructor)
114 {
115 int data[] = { 1, 5, 10, 15 };
116 bc::vector<int> a(data, data + 4, queue);
117 CHECK_RANGE_EQUAL(int, 4, a, (1, 5, 10, 15));
118
119 bc::vector<int> b(a.begin(), a.end(), queue);
120 CHECK_RANGE_EQUAL(int, 4, b, (1, 5, 10, 15));
121 }
122
123 BOOST_AUTO_TEST_CASE(push_back)
124 {
125 bc::vector<int> vector(context);
126 BOOST_VERIFY(vector.empty());
127
128 vector.push_back(12, queue);
129 BOOST_VERIFY(!vector.empty());
130 BOOST_CHECK_EQUAL(vector.size(), size_t(1));
131 CHECK_RANGE_EQUAL(int, 1, vector, (12));
132
133 vector.push_back(24, queue);
134 BOOST_CHECK_EQUAL(vector.size(), size_t(2));
135 CHECK_RANGE_EQUAL(int, 2, vector, (12, 24));
136
137 vector.push_back(36, queue);
138 BOOST_CHECK_EQUAL(vector.size(), size_t(3));
139 CHECK_RANGE_EQUAL(int, 3, vector, (12, 24, 36));
140
141 for(int i = 0; i < 100; i++){
142 vector.push_back(i, queue);
143 }
144 BOOST_CHECK_EQUAL(vector.size(), size_t(103));
145 BOOST_CHECK_EQUAL(vector[0], 12);
146 BOOST_CHECK_EQUAL(vector[1], 24);
147 BOOST_CHECK_EQUAL(vector[2], 36);
148 BOOST_CHECK_EQUAL(vector[102], 99);
149 }
150
151 BOOST_AUTO_TEST_CASE(at)
152 {
153 bc::vector<int> vector(context);
154 vector.push_back(1, queue);
155 vector.push_back(2, queue);
156 vector.push_back(3, queue);
157 BOOST_CHECK_EQUAL(vector.at(0), 1);
158 BOOST_CHECK_EQUAL(vector.at(1), 2);
159 BOOST_CHECK_EQUAL(vector.at(2), 3);
160 BOOST_CHECK_THROW(vector.at(3), std::out_of_range);
161 }
162
163 BOOST_AUTO_TEST_CASE(erase)
164 {
165 int data[] = { 1, 2, 5, 7, 9 };
166 bc::vector<int> vector(data, data + 5, queue);
167 queue.finish();
168 BOOST_CHECK_EQUAL(vector.size(), size_t(5));
169
170 vector.erase(vector.begin() + 1, queue);
171 BOOST_CHECK_EQUAL(vector.size(), size_t(4));
172 CHECK_RANGE_EQUAL(int, 4, vector, (1, 5, 7, 9));
173
174 vector.erase(vector.begin() + 2, vector.end(), queue);
175 BOOST_CHECK_EQUAL(vector.size(), size_t(2));
176 CHECK_RANGE_EQUAL(int, 2, vector, (1, 5));
177 }
178
179 BOOST_AUTO_TEST_CASE(max_size)
180 {
181 bc::vector<int> vector(100, context);
182 BOOST_CHECK_EQUAL(vector.size(), size_t(100));
183 BOOST_VERIFY(vector.max_size() > vector.size());
184 }
185
186 #ifndef BOOST_COMPUTE_NO_RVALUE_REFERENCES
187 BOOST_AUTO_TEST_CASE(move_ctor)
188 {
189 int data[] = { 11, 12, 13, 14 };
190 bc::vector<int> a(data, data + 4, queue);
191 BOOST_CHECK_EQUAL(a.size(), size_t(4));
192 CHECK_RANGE_EQUAL(int, 4, a, (11, 12, 13, 14));
193
194 bc::vector<int> b(std::move(a));
195 BOOST_CHECK(a.size() == 0);
196 BOOST_CHECK(a.get_buffer().get() == 0);
197 BOOST_CHECK_EQUAL(b.size(), size_t(4));
198 CHECK_RANGE_EQUAL(int, 4, b, (11, 12, 13, 14));
199 }
200
201 BOOST_AUTO_TEST_CASE(move_ctor_custom_alloc)
202 {
203 int data[] = { 11, 12, 13, 14 };
204 bc::vector<int, bc::pinned_allocator<int> > a(data, data + 4, queue);
205 BOOST_CHECK_EQUAL(a.size(), size_t(4));
206 CHECK_RANGE_EQUAL(int, 4, a, (11, 12, 13, 14));
207
208 bc::vector<int, bc::pinned_allocator<int> > b(std::move(a));
209 BOOST_CHECK(a.size() == 0);
210 BOOST_CHECK(a.get_buffer().get() == 0);
211 BOOST_CHECK_EQUAL(b.size(), size_t(4));
212 CHECK_RANGE_EQUAL(int, 4, b, (11, 12, 13, 14));
213 }
214 #endif // BOOST_COMPUTE_NO_RVALUE_REFERENCES
215
216 #ifdef BOOST_COMPUTE_USE_CPP11
217 BOOST_AUTO_TEST_CASE(initializer_list_ctor)
218 {
219 // ctor with std::initializer_list<T> always uses
220 // default_queue in this case
221 bc::vector<int> vector = { 2, -4, 6, 8 };
222 BOOST_CHECK_EQUAL(vector.size(), size_t(4));
223 BOOST_CHECK_EQUAL(vector[0], 2);
224 BOOST_CHECK_EQUAL(vector[1], -4);
225 BOOST_CHECK_EQUAL(vector[2], 6);
226 BOOST_CHECK_EQUAL(vector[3], 8);
227 }
228 #endif // BOOST_COMPUTE_USE_CPP11
229
230 BOOST_AUTO_TEST_CASE(vector_double)
231 {
232 if(!device.supports_extension("cl_khr_fp64")){
233 return;
234 }
235
236 bc::vector<double> vector(context);
237 vector.push_back(1.21, queue);
238 vector.push_back(3.14, queue);
239 vector.push_back(7.89, queue);
240 BOOST_CHECK_EQUAL(vector.size(), size_t(3));
241 CHECK_RANGE_EQUAL(double, 3, vector, (1.21, 3.14, 7.89));
242
243 bc::vector<double> other(vector.begin(), vector.end(), queue);
244 CHECK_RANGE_EQUAL(double, 3, other, (1.21, 3.14, 7.89));
245
246 bc::fill(other.begin(), other.end(), 8.95, queue);
247 CHECK_RANGE_EQUAL(double, 3, other, (8.95, 8.95, 8.95));
248 }
249
250 BOOST_AUTO_TEST_CASE(vector_iterator)
251 {
252 bc::vector<int> vector(context);
253 vector.push_back(2, queue);
254 vector.push_back(4, queue);
255 vector.push_back(6, queue);
256 vector.push_back(8, queue);
257 BOOST_CHECK_EQUAL(vector.size(), size_t(4));
258 BOOST_CHECK_EQUAL(vector[0], 2);
259 BOOST_CHECK_EQUAL(*vector.begin(), 2);
260 BOOST_CHECK_EQUAL(vector.begin()[0], 2);
261 BOOST_CHECK_EQUAL(vector[1], 4);
262 BOOST_CHECK_EQUAL(*(vector.begin()+1), 4);
263 BOOST_CHECK_EQUAL(vector.begin()[1], 4);
264 BOOST_CHECK_EQUAL(vector[2], 6);
265 BOOST_CHECK_EQUAL(*(vector.begin()+2), 6);
266 BOOST_CHECK_EQUAL(vector.begin()[2], 6);
267 BOOST_CHECK_EQUAL(vector[3], 8);
268 BOOST_CHECK_EQUAL(*(vector.begin()+3), 8);
269 BOOST_CHECK_EQUAL(vector.begin()[3], 8);
270 }
271
272 BOOST_AUTO_TEST_CASE(vector_erase_remove)
273 {
274 int data[] = { 2, 6, 3, 4, 2, 4, 5, 6, 1 };
275 bc::vector<int> vector(data, data + 9, queue);
276 BOOST_CHECK_EQUAL(vector.size(), size_t(9));
277
278 // remove 4's
279 vector.erase(bc::remove(vector.begin(), vector.end(), 4, queue), vector.end());
280 BOOST_CHECK_EQUAL(vector.size(), size_t(7));
281 BOOST_VERIFY(bc::find(vector.begin(), vector.end(), 4, queue) == vector.end());
282
283 // remove 2's
284 vector.erase(bc::remove(vector.begin(), vector.end(), 2, queue), vector.end());
285 BOOST_CHECK_EQUAL(vector.size(), size_t(5));
286 BOOST_VERIFY(bc::find(vector.begin(), vector.end(), 2, queue) == vector.end());
287
288 // remove 6's
289 vector.erase(bc::remove(vector.begin(), vector.end(), 6, queue), vector.end());
290 BOOST_CHECK_EQUAL(vector.size(), size_t(3));
291 BOOST_VERIFY(bc::find(vector.begin(), vector.end(), 6, queue) == vector.end());
292
293 // check the rest of the values
294 CHECK_RANGE_EQUAL(int, 3, vector, (3, 5, 1));
295 }
296
297 // see issue #132 (https://github.com/boostorg/compute/issues/132)
298 BOOST_AUTO_TEST_CASE(swap_between_contexts)
299 {
300 compute::context ctx1(device);
301 compute::context ctx2(device);
302
303 compute::vector<int> vec1(32, ctx1);
304 compute::vector<int> vec2(32, ctx2);
305
306 BOOST_CHECK(vec1.get_allocator().get_context() == ctx1);
307 BOOST_CHECK(vec2.get_allocator().get_context() == ctx2);
308
309 vec1.swap(vec2);
310
311 BOOST_CHECK(vec1.get_allocator().get_context() == ctx2);
312 BOOST_CHECK(vec2.get_allocator().get_context() == ctx1);
313
314 vec1.resize(64);
315 vec2.resize(64);
316 }
317
318 BOOST_AUTO_TEST_CASE(assign_from_std_vector)
319 {
320 std::vector<int> host_vector;
321 host_vector.push_back(1);
322 host_vector.push_back(9);
323 host_vector.push_back(7);
324 host_vector.push_back(9);
325
326 compute::vector<int> device_vector(context);
327 device_vector.assign(host_vector.begin(), host_vector.end(), queue);
328 BOOST_CHECK_EQUAL(device_vector.size(), size_t(4));
329 CHECK_RANGE_EQUAL(int, 4, device_vector, (1, 9, 7, 9));
330 }
331
332 BOOST_AUTO_TEST_CASE(assign_constant_value)
333 {
334 compute::vector<float> device_vector(10, context);
335 device_vector.assign(3, 6.28f, queue);
336 BOOST_CHECK_EQUAL(device_vector.size(), size_t(3));
337 CHECK_RANGE_EQUAL(float, 3, device_vector, (6.28f, 6.28f, 6.28f));
338 }
339
340 BOOST_AUTO_TEST_CASE(resize_throw_exception)
341 {
342 if(bug_in_clcreatebuffer(device)) {
343 std::cerr
344 << "skipping resize_throw_exception test on Apple platform"
345 << std::endl;
346 return;
347 }
348
349 // create vector with eight items
350 int data[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
351 compute::vector<int> vec(data, data + 8, queue);
352
353 // try to resize to 2x larger than the global memory size
354 BOOST_CHECK_THROW(
355 vec.resize((device.global_memory_size() / sizeof(int)) * 2),
356 boost::compute::opencl_error
357 );
358
359 // ensure vector data is still the same
360 BOOST_CHECK_EQUAL(vec.size(), size_t(8));
361 CHECK_RANGE_EQUAL(int, 8, vec, (1, 2, 3, 4, 5, 6, 7, 8));
362 }
363
364 BOOST_AUTO_TEST_CASE(copy_ctor_custom_alloc)
365 {
366 int data[] = { 11, 12, 13, 14 };
367 bc::vector<int, bc::pinned_allocator<int> > a(data, data + 4, queue);
368 BOOST_CHECK_EQUAL(a.size(), size_t(4));
369 CHECK_RANGE_EQUAL(int, 4, a, (11, 12, 13, 14));
370
371 bc::vector<int, bc::pinned_allocator<int> > b(a, queue);
372 BOOST_CHECK_EQUAL(b.size(), size_t(4));
373 CHECK_RANGE_EQUAL(int, 4, b, (11, 12, 13, 14));
374 }
375
376 BOOST_AUTO_TEST_CASE(copy_ctor_different_alloc)
377 {
378 int data[] = { 11, 12, 13, 14 };
379 bc::vector<int> a(data, data + 4, queue);
380 BOOST_CHECK_EQUAL(a.size(), size_t(4));
381 CHECK_RANGE_EQUAL(int, 4, a, (11, 12, 13, 14));
382
383 bc::vector<int, bc::pinned_allocator<int> > b(a, queue);
384 BOOST_CHECK_EQUAL(b.size(), size_t(4));
385 CHECK_RANGE_EQUAL(int, 4, b, (11, 12, 13, 14));
386
387 std::vector<int> host_vector;
388 host_vector.push_back(1);
389 host_vector.push_back(9);
390 host_vector.push_back(7);
391 host_vector.push_back(9);
392
393 bc::vector<int, bc::pinned_allocator<int> > c(host_vector, queue);
394 BOOST_CHECK_EQUAL(c.size(), size_t(4));
395 CHECK_RANGE_EQUAL(int, 4, c, (1, 9, 7, 9));
396 }
397
398 BOOST_AUTO_TEST_CASE(assignment_operator)
399 {
400 int adata[] = { 11, 12, 13, 14 };
401 bc::vector<int> a(adata, adata + 4, queue);
402 BOOST_CHECK_EQUAL(a.size(), size_t(4));
403 CHECK_RANGE_EQUAL(int, 4, a, (11, 12, 13, 14));
404
405 bc::vector<int> b = a;
406 BOOST_CHECK_EQUAL(b.size(), size_t(4));
407 CHECK_RANGE_EQUAL(int, 4, b, (11, 12, 13, 14));
408
409 bc::vector<int, bc::pinned_allocator<int> > c(context);
410 c = b;
411 BOOST_CHECK_EQUAL(c.size(), size_t(4));
412 CHECK_RANGE_EQUAL(int, 4, c, (11, 12, 13, 14));
413
414 int ddata[] = { 21, 22, 23 };
415 bc::vector<int, bc::pinned_allocator<int> > d(ddata, ddata + 3, queue);
416 BOOST_CHECK_EQUAL(d.size(), size_t(3));
417 CHECK_RANGE_EQUAL(int, 3, d, (21, 22, 23));
418
419 a = d;
420 BOOST_CHECK_EQUAL(a.size(), size_t(3));
421 CHECK_RANGE_EQUAL(int, 3, a, (21, 22, 23));
422
423 std::vector<int> host_vector;
424 host_vector.push_back(1);
425 host_vector.push_back(9);
426 host_vector.push_back(7);
427 host_vector.push_back(9);
428
429 d = host_vector;
430 BOOST_CHECK_EQUAL(d.size(), size_t(4));
431 CHECK_RANGE_EQUAL(int, 4, d, (1, 9, 7, 9));
432 }
433
434 BOOST_AUTO_TEST_CASE(swap_ctor_custom_alloc)
435 {
436 int adata[] = { 11, 12, 13, 14 };
437 bc::vector<int, bc::pinned_allocator<int> > a(adata, adata + 4, queue);
438 BOOST_CHECK_EQUAL(a.size(), size_t(4));
439 CHECK_RANGE_EQUAL(int, 4, a, (11, 12, 13, 14));
440
441 int bdata[] = { 21, 22, 23 };
442 bc::vector<int, bc::pinned_allocator<int> > b(bdata, bdata + 3, queue);
443 BOOST_CHECK_EQUAL(b.size(), size_t(3));
444 CHECK_RANGE_EQUAL(int, 3, b, (21, 22, 23));
445
446 a.swap(b);
447 BOOST_CHECK_EQUAL(a.size(), size_t(3));
448 CHECK_RANGE_EQUAL(int, 3, a, (21, 22, 23));
449 BOOST_CHECK_EQUAL(b.size(), size_t(4));
450 CHECK_RANGE_EQUAL(int, 4, b, (11, 12, 13, 14));
451 }
452
453 BOOST_AUTO_TEST_SUITE_END()