1 //---------------------------------------------------------------------------//
2 // Copyright (c) 2013 Kyle Lutz <kyle.r.lutz@gmail.com>
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
8 // See http://boostorg.github.com/compute for more information.
9 //---------------------------------------------------------------------------//
11 #define BOOST_TEST_MODULE TestVector
12 #include <boost/test/unit_test.hpp>
13 #include <boost/concept_check.hpp>
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>
27 #include "check_macros.hpp"
28 #include "context_setup.hpp"
30 namespace bc
= boost::compute
;
31 namespace compute
= boost::compute
;
33 BOOST_AUTO_TEST_CASE(concept_check
)
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
>));
42 BOOST_AUTO_TEST_CASE(size
)
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);
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);
53 BOOST_AUTO_TEST_CASE(resize
)
55 bc::vector
<int> int_vector(10, context
);
56 BOOST_CHECK_EQUAL(int_vector
.size(), size_t(10));
58 int_vector
.resize(20, queue
);
59 BOOST_CHECK_EQUAL(int_vector
.size(), size_t(20));
61 int_vector
.resize(5, queue
);
62 BOOST_CHECK_EQUAL(int_vector
.size(), size_t(5));
65 BOOST_AUTO_TEST_CASE(reserve
)
67 const float growth_factor
= 1.5f
;
69 bc::vector
<int> int_vector(10, context
);
70 BOOST_CHECK_EQUAL(int_vector
.size(), size_t(10));
71 BOOST_CHECK_EQUAL(int_vector
.capacity(), size_t(10));
73 int_vector
.reserve(20, queue
);
74 BOOST_CHECK_EQUAL(int_vector
.size(), size_t(10));
75 BOOST_CHECK_EQUAL(int_vector
.capacity(), size_t(20 * growth_factor
));
77 int_vector
.reserve(5, queue
);
78 BOOST_CHECK_EQUAL(int_vector
.size(), size_t(10));
79 BOOST_CHECK_EQUAL(int_vector
.capacity(), size_t(20 * growth_factor
));
82 BOOST_AUTO_TEST_CASE(array_operator
)
84 bc::vector
<int> vector(10, context
);
85 bc::fill(vector
.begin(), vector
.end(), 0, queue
);
86 CHECK_RANGE_EQUAL(int, 10, vector
, (0, 0, 0, 0, 0, 0, 0, 0, 0, 0));
88 bc::fill(vector
.begin(), vector
.end(), 42, queue
);
89 CHECK_RANGE_EQUAL(int, 10, vector
, (42, 42, 42, 42, 42, 42, 42, 42, 42, 42));
92 CHECK_RANGE_EQUAL(int, 10, vector
, (9, 42, 42, 42, 42, 42, 42, 42, 42, 42));
95 BOOST_AUTO_TEST_CASE(front_and_back
)
97 int int_data
[] = { 1, 2, 3, 4, 5 };
98 bc::vector
<int> int_vector(5, context
);
99 bc::copy(int_data
, int_data
+ 5, int_vector
.begin(), queue
);
101 BOOST_CHECK_EQUAL(int_vector
.front(), 1);
102 BOOST_CHECK_EQUAL(int_vector
.back(), 5);
104 bc::fill(int_vector
.begin(), int_vector
.end(), 10, queue
);
106 BOOST_CHECK_EQUAL(int_vector
.front(), 10);
107 BOOST_CHECK_EQUAL(int_vector
.back(), 10);
109 float float_data
[] = { 1.1f
, 2.2f
, 3.3f
, 4.4f
, 5.5f
};
110 bc::vector
<float> float_vector(5, context
);
111 bc::copy(float_data
, float_data
+ 5, float_vector
.begin(), queue
);
113 BOOST_CHECK_EQUAL(float_vector
.front(), 1.1f
);
114 BOOST_CHECK_EQUAL(float_vector
.back(), 5.5f
);
117 BOOST_AUTO_TEST_CASE(host_iterator_constructor
)
119 std::vector
<int> host_vector
;
120 host_vector
.push_back(10);
121 host_vector
.push_back(20);
122 host_vector
.push_back(30);
123 host_vector
.push_back(40);
125 bc::vector
<int> device_vector(host_vector
.begin(), host_vector
.end(),
127 CHECK_RANGE_EQUAL(int, 4, device_vector
, (10, 20, 30, 40));
130 BOOST_AUTO_TEST_CASE(device_iterator_constructor
)
132 int data
[] = { 1, 5, 10, 15 };
133 bc::vector
<int> a(data
, data
+ 4, queue
);
134 CHECK_RANGE_EQUAL(int, 4, a
, (1, 5, 10, 15));
136 bc::vector
<int> b(a
.begin(), a
.end(), queue
);
137 CHECK_RANGE_EQUAL(int, 4, b
, (1, 5, 10, 15));
140 BOOST_AUTO_TEST_CASE(push_back
)
142 bc::vector
<int> vector(context
);
143 BOOST_VERIFY(vector
.empty());
145 vector
.push_back(12, queue
);
146 BOOST_VERIFY(!vector
.empty());
147 BOOST_CHECK_EQUAL(vector
.size(), size_t(1));
148 CHECK_RANGE_EQUAL(int, 1, vector
, (12));
150 vector
.push_back(24, queue
);
151 BOOST_CHECK_EQUAL(vector
.size(), size_t(2));
152 CHECK_RANGE_EQUAL(int, 2, vector
, (12, 24));
154 vector
.push_back(36, queue
);
155 BOOST_CHECK_EQUAL(vector
.size(), size_t(3));
156 CHECK_RANGE_EQUAL(int, 3, vector
, (12, 24, 36));
158 for(int i
= 0; i
< 100; i
++){
159 vector
.push_back(i
, queue
);
162 BOOST_CHECK_EQUAL(vector
.size(), size_t(103));
163 BOOST_CHECK_EQUAL(vector
[0], 12);
164 BOOST_CHECK_EQUAL(vector
[1], 24);
165 BOOST_CHECK_EQUAL(vector
[2], 36);
166 BOOST_CHECK_EQUAL(vector
[102], 99);
169 BOOST_AUTO_TEST_CASE(at
)
171 bc::vector
<int> vector(context
);
172 vector
.push_back(1, queue
);
173 vector
.push_back(2, queue
);
174 vector
.push_back(3, queue
);
176 BOOST_CHECK_EQUAL(vector
.at(0), 1);
177 BOOST_CHECK_EQUAL(vector
.at(1), 2);
178 BOOST_CHECK_EQUAL(vector
.at(2), 3);
179 BOOST_CHECK_THROW(vector
.at(3), std::out_of_range
);
182 BOOST_AUTO_TEST_CASE(erase
)
184 int data
[] = { 1, 2, 5, 7, 9 };
185 bc::vector
<int> vector(data
, data
+ 5, queue
);
187 BOOST_CHECK_EQUAL(vector
.size(), size_t(5));
189 vector
.erase(vector
.begin() + 1, queue
);
190 BOOST_CHECK_EQUAL(vector
.size(), size_t(4));
191 CHECK_RANGE_EQUAL(int, 4, vector
, (1, 5, 7, 9));
193 vector
.erase(vector
.begin() + 2, vector
.end(), queue
);
194 BOOST_CHECK_EQUAL(vector
.size(), size_t(2));
195 CHECK_RANGE_EQUAL(int, 2, vector
, (1, 5));
198 BOOST_AUTO_TEST_CASE(max_size
)
200 bc::vector
<int> vector(100, context
);
201 BOOST_CHECK_EQUAL(vector
.size(), size_t(100));
202 BOOST_VERIFY(vector
.max_size() > vector
.size());
205 #ifndef BOOST_COMPUTE_NO_RVALUE_REFERENCES
206 BOOST_AUTO_TEST_CASE(move_ctor
)
208 int data
[] = { 11, 12, 13, 14 };
209 bc::vector
<int> a(data
, data
+ 4, queue
);
210 BOOST_CHECK_EQUAL(a
.size(), size_t(4));
211 CHECK_RANGE_EQUAL(int, 4, a
, (11, 12, 13, 14));
213 bc::vector
<int> b(std::move(a
));
214 BOOST_CHECK(a
.size() == 0);
215 BOOST_CHECK(a
.get_buffer().get() == 0);
216 BOOST_CHECK_EQUAL(b
.size(), size_t(4));
217 CHECK_RANGE_EQUAL(int, 4, b
, (11, 12, 13, 14));
220 BOOST_AUTO_TEST_CASE(move_ctor_custom_alloc
)
222 int data
[] = { 11, 12, 13, 14 };
223 bc::vector
<int, bc::pinned_allocator
<int> > a(data
, data
+ 4, queue
);
224 BOOST_CHECK_EQUAL(a
.size(), size_t(4));
225 CHECK_RANGE_EQUAL(int, 4, a
, (11, 12, 13, 14));
227 bc::vector
<int, bc::pinned_allocator
<int> > b(std::move(a
));
228 BOOST_CHECK(a
.size() == 0);
229 BOOST_CHECK(a
.get_buffer().get() == 0);
230 BOOST_CHECK_EQUAL(b
.size(), size_t(4));
231 CHECK_RANGE_EQUAL(int, 4, b
, (11, 12, 13, 14));
233 #endif // BOOST_COMPUTE_NO_RVALUE_REFERENCES
235 #ifdef BOOST_COMPUTE_USE_CPP11
236 #ifndef BOOST_COMPUTE_NO_HDR_INITIALIZER_LIST
237 BOOST_AUTO_TEST_CASE(initializer_list_ctor
)
239 // ctor with std::initializer_list<T> always uses
240 // default_queue in this case
241 bc::vector
<int> vector
= { 2, -4, 6, 8 };
242 BOOST_CHECK_EQUAL(vector
.size(), size_t(4));
243 BOOST_CHECK_EQUAL(vector
[0], 2);
244 BOOST_CHECK_EQUAL(vector
[1], -4);
245 BOOST_CHECK_EQUAL(vector
[2], 6);
246 BOOST_CHECK_EQUAL(vector
[3], 8);
248 #endif // BOOST_COMPUTE_NO_HDR_INITIALIZER_LIST
249 #endif // BOOST_COMPUTE_USE_CPP11
251 BOOST_AUTO_TEST_CASE(vector_double
)
253 if(!device
.supports_extension("cl_khr_fp64")){
257 bc::vector
<double> vector(context
);
258 vector
.push_back(1.21, queue
);
259 vector
.push_back(3.14, queue
);
260 vector
.push_back(7.89, queue
);
261 BOOST_CHECK_EQUAL(vector
.size(), size_t(3));
262 CHECK_RANGE_EQUAL(double, 3, vector
, (1.21, 3.14, 7.89));
264 bc::vector
<double> other(vector
.begin(), vector
.end(), queue
);
265 CHECK_RANGE_EQUAL(double, 3, other
, (1.21, 3.14, 7.89));
267 bc::fill(other
.begin(), other
.end(), 8.95, queue
);
268 CHECK_RANGE_EQUAL(double, 3, other
, (8.95, 8.95, 8.95));
271 BOOST_AUTO_TEST_CASE(vector_iterator
)
273 bc::vector
<int> vector(context
);
274 vector
.push_back(2, queue
);
275 vector
.push_back(4, queue
);
276 vector
.push_back(6, queue
);
277 vector
.push_back(8, queue
);
279 BOOST_CHECK_EQUAL(vector
.size(), size_t(4));
280 BOOST_CHECK_EQUAL(vector
[0], 2);
281 BOOST_CHECK_EQUAL(*vector
.begin(), 2);
282 BOOST_CHECK_EQUAL(vector
.begin()[0], 2);
283 BOOST_CHECK_EQUAL(vector
[1], 4);
284 BOOST_CHECK_EQUAL(*(vector
.begin()+1), 4);
285 BOOST_CHECK_EQUAL(vector
.begin()[1], 4);
286 BOOST_CHECK_EQUAL(vector
[2], 6);
287 BOOST_CHECK_EQUAL(*(vector
.begin()+2), 6);
288 BOOST_CHECK_EQUAL(vector
.begin()[2], 6);
289 BOOST_CHECK_EQUAL(vector
[3], 8);
290 BOOST_CHECK_EQUAL(*(vector
.begin()+3), 8);
291 BOOST_CHECK_EQUAL(vector
.begin()[3], 8);
294 BOOST_AUTO_TEST_CASE(vector_erase_remove
)
296 int data
[] = { 2, 6, 3, 4, 2, 4, 5, 6, 1 };
297 bc::vector
<int> vector(data
, data
+ 9, queue
);
298 BOOST_CHECK_EQUAL(vector
.size(), size_t(9));
301 vector
.erase(bc::remove(vector
.begin(), vector
.end(), 4, queue
), vector
.end());
302 BOOST_CHECK_EQUAL(vector
.size(), size_t(7));
303 BOOST_VERIFY(bc::find(vector
.begin(), vector
.end(), 4, queue
) == vector
.end());
306 vector
.erase(bc::remove(vector
.begin(), vector
.end(), 2, queue
), vector
.end());
307 BOOST_CHECK_EQUAL(vector
.size(), size_t(5));
308 BOOST_VERIFY(bc::find(vector
.begin(), vector
.end(), 2, queue
) == vector
.end());
311 vector
.erase(bc::remove(vector
.begin(), vector
.end(), 6, queue
), vector
.end());
312 BOOST_CHECK_EQUAL(vector
.size(), size_t(3));
313 BOOST_VERIFY(bc::find(vector
.begin(), vector
.end(), 6, queue
) == vector
.end());
315 // check the rest of the values
316 CHECK_RANGE_EQUAL(int, 3, vector
, (3, 5, 1));
319 // see issue #132 (https://github.com/boostorg/compute/issues/132)
320 BOOST_AUTO_TEST_CASE(swap_between_contexts
)
322 compute::context
ctx1(device
);
323 compute::context
ctx2(device
);
325 compute::vector
<int> vec1(32, ctx1
);
326 compute::vector
<int> vec2(32, ctx2
);
328 BOOST_CHECK(vec1
.get_allocator().get_context() == ctx1
);
329 BOOST_CHECK(vec2
.get_allocator().get_context() == ctx2
);
333 BOOST_CHECK(vec1
.get_allocator().get_context() == ctx2
);
334 BOOST_CHECK(vec2
.get_allocator().get_context() == ctx1
);
340 BOOST_AUTO_TEST_CASE(assign_from_std_vector
)
342 std::vector
<int> host_vector
;
343 host_vector
.push_back(1);
344 host_vector
.push_back(9);
345 host_vector
.push_back(7);
346 host_vector
.push_back(9);
348 compute::vector
<int> device_vector(context
);
349 device_vector
.assign(host_vector
.begin(), host_vector
.end(), queue
);
350 BOOST_CHECK_EQUAL(device_vector
.size(), size_t(4));
351 CHECK_RANGE_EQUAL(int, 4, device_vector
, (1, 9, 7, 9));
354 BOOST_AUTO_TEST_CASE(assign_constant_value
)
356 compute::vector
<float> device_vector(10, context
);
357 device_vector
.assign(3, 6.28f
, queue
);
358 BOOST_CHECK_EQUAL(device_vector
.size(), size_t(3));
359 CHECK_RANGE_EQUAL(float, 3, device_vector
, (6.28f
, 6.28f
, 6.28f
));
362 BOOST_AUTO_TEST_CASE(resize_throw_exception
)
364 if(bug_in_clcreatebuffer(device
)) {
366 << "skipping resize_throw_exception test on Apple platform"
371 // create vector with eight items
372 int data
[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
373 compute::vector
<int> vec(data
, data
+ 8, queue
);
375 // try to resize to 2x larger than the global memory size
377 vec
.resize((device
.global_memory_size() / sizeof(int)) * 2),
378 boost::compute::opencl_error
381 // ensure vector data is still the same
382 BOOST_CHECK_EQUAL(vec
.size(), size_t(8));
383 CHECK_RANGE_EQUAL(int, 8, vec
, (1, 2, 3, 4, 5, 6, 7, 8));
386 BOOST_AUTO_TEST_CASE(copy_ctor_custom_alloc
)
388 int data
[] = { 11, 12, 13, 14 };
389 bc::vector
<int, bc::pinned_allocator
<int> > a(data
, data
+ 4, queue
);
390 BOOST_CHECK_EQUAL(a
.size(), size_t(4));
391 CHECK_RANGE_EQUAL(int, 4, a
, (11, 12, 13, 14));
393 bc::vector
<int, bc::pinned_allocator
<int> > b(a
, queue
);
394 BOOST_CHECK_EQUAL(b
.size(), size_t(4));
395 CHECK_RANGE_EQUAL(int, 4, b
, (11, 12, 13, 14));
398 BOOST_AUTO_TEST_CASE(copy_ctor_different_alloc
)
400 int data
[] = { 11, 12, 13, 14 };
401 bc::vector
<int> a(data
, data
+ 4, queue
);
402 BOOST_CHECK_EQUAL(a
.size(), size_t(4));
403 CHECK_RANGE_EQUAL(int, 4, a
, (11, 12, 13, 14));
405 bc::vector
<int, bc::pinned_allocator
<int> > b(a
, queue
);
406 BOOST_CHECK_EQUAL(b
.size(), size_t(4));
407 CHECK_RANGE_EQUAL(int, 4, b
, (11, 12, 13, 14));
409 std::vector
<int> host_vector
;
410 host_vector
.push_back(1);
411 host_vector
.push_back(9);
412 host_vector
.push_back(7);
413 host_vector
.push_back(9);
415 bc::vector
<int, bc::pinned_allocator
<int> > c(host_vector
, queue
);
416 BOOST_CHECK_EQUAL(c
.size(), size_t(4));
417 CHECK_RANGE_EQUAL(int, 4, c
, (1, 9, 7, 9));
420 BOOST_AUTO_TEST_CASE(assignment_operator
)
422 int adata
[] = { 11, 12, 13, 14 };
423 bc::vector
<int> a(adata
, adata
+ 4, queue
);
424 BOOST_CHECK_EQUAL(a
.size(), size_t(4));
425 CHECK_RANGE_EQUAL(int, 4, a
, (11, 12, 13, 14));
427 bc::vector
<int> b
= a
;
428 BOOST_CHECK_EQUAL(b
.size(), size_t(4));
429 CHECK_RANGE_EQUAL(int, 4, b
, (11, 12, 13, 14));
431 bc::vector
<int, bc::pinned_allocator
<int> > c(context
);
433 BOOST_CHECK_EQUAL(c
.size(), size_t(4));
434 CHECK_RANGE_EQUAL(int, 4, c
, (11, 12, 13, 14));
436 int ddata
[] = { 21, 22, 23 };
437 bc::vector
<int, bc::pinned_allocator
<int> > d(ddata
, ddata
+ 3, queue
);
438 BOOST_CHECK_EQUAL(d
.size(), size_t(3));
439 CHECK_RANGE_EQUAL(int, 3, d
, (21, 22, 23));
442 BOOST_CHECK_EQUAL(a
.size(), size_t(3));
443 CHECK_RANGE_EQUAL(int, 3, a
, (21, 22, 23));
445 std::vector
<int> host_vector
;
446 host_vector
.push_back(1);
447 host_vector
.push_back(9);
448 host_vector
.push_back(7);
449 host_vector
.push_back(9);
452 BOOST_CHECK_EQUAL(d
.size(), size_t(4));
453 CHECK_RANGE_EQUAL(int, 4, d
, (1, 9, 7, 9));
456 BOOST_AUTO_TEST_CASE(swap_ctor_custom_alloc
)
458 int adata
[] = { 11, 12, 13, 14 };
459 bc::vector
<int, bc::pinned_allocator
<int> > a(adata
, adata
+ 4, queue
);
460 BOOST_CHECK_EQUAL(a
.size(), size_t(4));
461 CHECK_RANGE_EQUAL(int, 4, a
, (11, 12, 13, 14));
463 int bdata
[] = { 21, 22, 23 };
464 bc::vector
<int, bc::pinned_allocator
<int> > b(bdata
, bdata
+ 3, queue
);
465 BOOST_CHECK_EQUAL(b
.size(), size_t(3));
466 CHECK_RANGE_EQUAL(int, 3, b
, (21, 22, 23));
469 BOOST_CHECK_EQUAL(a
.size(), size_t(3));
470 CHECK_RANGE_EQUAL(int, 3, a
, (21, 22, 23));
471 BOOST_CHECK_EQUAL(b
.size(), size_t(4));
472 CHECK_RANGE_EQUAL(int, 4, b
, (11, 12, 13, 14));
475 BOOST_AUTO_TEST_CASE(shrink_to_fit
)
477 bc::vector
<bc::int_
> int_vector(5, context
);
478 BOOST_CHECK_EQUAL(int_vector
.size(), 5);
479 BOOST_CHECK(int_vector
.capacity() >= 5);
481 int_vector
.reserve(15);
482 BOOST_CHECK_EQUAL(int_vector
.size(), 5);
483 BOOST_CHECK(int_vector
.capacity() >= 15);
485 int_vector
.shrink_to_fit();
486 BOOST_CHECK_EQUAL(int_vector
.size(), 5);
487 BOOST_CHECK_EQUAL(int_vector
.capacity(), 5);
490 BOOST_CHECK_EQUAL(int_vector
.size(), 0);
491 BOOST_CHECK_EQUAL(int_vector
.capacity(), 5);
493 int_vector
.shrink_to_fit();
494 BOOST_CHECK_EQUAL(int_vector
.size(), 0);
495 BOOST_CHECK_EQUAL(int_vector
.capacity(), 0);
497 int_vector
.reserve(15);
498 BOOST_CHECK_EQUAL(int_vector
.size(), 0);
499 BOOST_CHECK(int_vector
.capacity() >= 15);
502 BOOST_AUTO_TEST_SUITE_END()