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 TestFill
12 #include <boost/test/unit_test.hpp>
13 #include <boost/test/test_case_template.hpp>
14 #include <boost/mpl/list.hpp>
18 #include <boost/compute/algorithm/equal.hpp>
19 #include <boost/compute/algorithm/fill.hpp>
20 #include <boost/compute/algorithm/fill_n.hpp>
21 #include <boost/compute/async/future.hpp>
22 #include <boost/compute/container/vector.hpp>
23 #include <boost/compute/svm.hpp>
24 #include <boost/compute/type_traits.hpp>
26 #include "check_macros.hpp"
27 #include "context_setup.hpp"
29 namespace bc
= boost::compute
;
31 typedef boost::mpl::list
32 <bc::char_
, bc::uchar_
, bc::int_
, bc::uint_
,
33 bc::long_
, bc::ulong_
, bc::float_
, bc::double_
>
37 inline void test_fill(T v1
, T v2
, T v3
, bc::command_queue queue
) {
38 if(boost::is_same
<typename
bc::scalar_type
<T
>::type
, bc::double_
>::value
&&
39 !queue
.get_device().supports_extension("cl_khr_fp64")) {
40 std::cerr
<< "Skipping test_fill<" << bc::type_name
<T
>() << ">() "
41 "on device which doesn't support cl_khr_fp64" << std::endl
;
45 bc::vector
<T
> vector(4, queue
.get_context());
46 bc::fill(vector
.begin(), vector
.end(), v1
, queue
);
48 CHECK_RANGE_EQUAL(T
, 4, vector
, (v1
, v1
, v1
, v1
));
50 vector
.resize(1000, queue
);
51 bc::fill(vector
.begin(), vector
.end(), v2
, queue
);
53 BOOST_CHECK_EQUAL(vector
.front(), v2
);
54 BOOST_CHECK_EQUAL(vector
.back(), v2
);
56 bc::fill(vector
.begin() + 500, vector
.end(), v3
, queue
);
58 BOOST_CHECK_EQUAL(vector
.front(), v2
);
59 BOOST_CHECK_EQUAL(vector
[499], v2
);
60 BOOST_CHECK_EQUAL(vector
[500], v3
);
61 BOOST_CHECK_EQUAL(vector
.back(), v3
);
64 BOOST_AUTO_TEST_CASE_TEMPLATE( fill_scalar
, S
, scalar_types
)
69 test_fill(v1
, v2
, v3
, queue
);
72 BOOST_AUTO_TEST_CASE_TEMPLATE( fill_vec2
, S
, scalar_types
)
74 typedef typename
bc::make_vector_type
<S
, 2>::type T
;
83 test_fill(v1
, v2
, v3
, queue
);
86 BOOST_AUTO_TEST_CASE_TEMPLATE( fill_vec4
, S
, scalar_types
)
88 typedef typename
bc::make_vector_type
<S
, 4>::type T
;
94 T v1
= T(s1
, s2
, s3
, s4
);
95 T v2
= T(s3
, s4
, s1
, s2
);
96 T v3
= T(s4
, s3
, s2
, s1
);
97 test_fill(v1
, v2
, v3
, queue
);
100 BOOST_AUTO_TEST_CASE_TEMPLATE( fill_vec8
, S
, scalar_types
)
102 typedef typename
bc::make_vector_type
<S
, 8>::type T
;
112 T v1
= T(s1
, s2
, s3
, s4
, s5
, s6
, s7
, s8
);
113 T v2
= T(s3
, s4
, s1
, s2
, s7
, s8
, s5
, s6
);
114 T v3
= T(s4
, s3
, s2
, s1
, s8
, s7
, s6
, s5
);
115 test_fill(v1
, v2
, v3
, queue
);
118 BOOST_AUTO_TEST_CASE_TEMPLATE( fill_vec16
, S
, scalar_types
)
120 typedef typename
bc::make_vector_type
<S
, 16>::type T
;
130 T v1
= T(s1
, s2
, s3
, s4
, s5
, s6
, s7
, s8
, s1
, s2
, s3
, s4
, s5
, s6
, s7
, s8
);
131 T v2
= T(s3
, s4
, s1
, s2
, s7
, s8
, s5
, s6
, s4
, s3
, s2
, s1
, s8
, s7
, s6
, s5
);
132 T v3
= T(s4
, s3
, s2
, s1
, s8
, s7
, s6
, s5
, s8
, s7
, s6
, s5
, s4
, s3
, s2
, s1
);
133 test_fill(v1
, v2
, v3
, queue
);
137 inline void test_fill_n(T v1
, T v2
, T v3
, bc::command_queue queue
) {
138 if(boost::is_same
<typename
bc::scalar_type
<T
>::type
, bc::double_
>::value
&&
139 !queue
.get_device().supports_extension("cl_khr_fp64")) {
140 std::cerr
<< "Skipping test_fill_n<" << bc::type_name
<T
>() << ">() "
141 "on device which doesn't support cl_khr_fp64" << std::endl
;
145 bc::vector
<T
> vector(4, queue
.get_context());
146 bc::fill_n(vector
.begin(), 4, v1
, queue
);
148 CHECK_RANGE_EQUAL(T
, 4, vector
, (v1
, v1
, v1
, v1
));
150 bc::fill_n(vector
.begin(), 3, v2
, queue
);
152 CHECK_RANGE_EQUAL(T
, 4, vector
, (v2
, v2
, v2
, v1
));
154 bc::fill_n(vector
.begin() + 1, 2, v3
, queue
);
156 CHECK_RANGE_EQUAL(T
, 4, vector
, (v2
, v3
, v3
, v1
));
158 bc::fill_n(vector
.begin(), 4, v2
, queue
);
160 CHECK_RANGE_EQUAL(T
, 4, vector
, (v2
, v2
, v2
, v2
));
163 bc::fill_n(vector
.end() - 1, 1, v3
, queue
);
165 CHECK_RANGE_EQUAL(T
, 4, vector
, (v2
, v2
, v2
, v3
));
167 // fill first element
168 bc::fill_n(vector
.begin(), 1, v1
, queue
);
170 CHECK_RANGE_EQUAL(T
, 4, vector
, (v1
, v2
, v2
, v3
));
173 BOOST_AUTO_TEST_CASE_TEMPLATE( fill_n_scalar
, S
, scalar_types
)
178 test_fill_n(v1
, v2
, v3
, queue
);
181 BOOST_AUTO_TEST_CASE_TEMPLATE( fill_n_vec2
, S
, scalar_types
)
183 typedef typename
bc::make_vector_type
<S
, 2>::type T
;
192 test_fill_n(v1
, v2
, v3
, queue
);
195 BOOST_AUTO_TEST_CASE_TEMPLATE( fill_n_vec4
, S
, scalar_types
)
197 typedef typename
bc::make_vector_type
<S
, 4>::type T
;
203 T v1
= T(s1
, s2
, s3
, s4
);
204 T v2
= T(s3
, s4
, s1
, s2
);
205 T v3
= T(s4
, s3
, s2
, s1
);
206 test_fill_n(v1
, v2
, v3
, queue
);
209 BOOST_AUTO_TEST_CASE_TEMPLATE( fill_n_vec8
, S
, scalar_types
)
211 typedef typename
bc::make_vector_type
<S
, 8>::type T
;
221 T v1
= T(s1
, s2
, s3
, s4
, s5
, s6
, s7
, s8
);
222 T v2
= T(s3
, s4
, s1
, s2
, s7
, s8
, s5
, s6
);
223 T v3
= T(s4
, s3
, s2
, s1
, s8
, s7
, s6
, s5
);
224 test_fill_n(v1
, v2
, v3
, queue
);
227 BOOST_AUTO_TEST_CASE_TEMPLATE( fill_n_vec16
, S
, scalar_types
)
229 typedef typename
bc::make_vector_type
<S
, 16>::type T
;
239 T v1
= T(s1
, s2
, s3
, s4
, s5
, s6
, s7
, s8
, s1
, s2
, s3
, s4
, s5
, s6
, s7
, s8
);
240 T v2
= T(s3
, s4
, s1
, s2
, s7
, s8
, s5
, s6
, s4
, s3
, s2
, s1
, s8
, s7
, s6
, s5
);
241 T v3
= T(s4
, s3
, s2
, s1
, s8
, s7
, s6
, s5
, s8
, s7
, s6
, s5
, s4
, s3
, s2
, s1
);
242 test_fill_n(v1
, v2
, v3
, queue
);
245 BOOST_AUTO_TEST_CASE(check_fill_type
)
247 bc::vector
<int> vector(5, context
);
248 bc::future
<void> future
=
249 bc::fill_async(vector
.begin(), vector
.end(), 42, queue
);
252 #ifdef BOOST_COMPUTE_CL_VERSION_1_2
254 future
.get_event().get_command_type(),
255 device
.check_version(1,2) ? CL_COMMAND_FILL_BUFFER
: CL_COMMAND_NDRANGE_KERNEL
259 future
.get_event().get_command_type() == CL_COMMAND_NDRANGE_KERNEL
264 BOOST_AUTO_TEST_CASE(fill_clone_buffer
)
266 int data
[] = { 1, 2, 3, 4 };
267 bc::vector
<int> vec(data
, data
+ 4, queue
);
268 CHECK_RANGE_EQUAL(int, 4, vec
, (1, 2, 3, 4));
270 bc::buffer cloned_buffer
= vec
.get_buffer().clone(queue
);
275 bc::make_buffer_iterator
<int>(cloned_buffer
, 0),
280 bc::fill(vec
.begin(), vec
.end(), 5, queue
);
285 bc::make_buffer_iterator
<int>(cloned_buffer
, 0),
291 bc::make_buffer_iterator
<int>(cloned_buffer
, 0),
292 bc::make_buffer_iterator
<int>(cloned_buffer
, 4),
300 bc::make_buffer_iterator
<int>(cloned_buffer
, 0),
306 #ifdef BOOST_COMPUTE_CL_VERSION_2_0
307 BOOST_AUTO_TEST_CASE(fill_svm_buffer
)
309 REQUIRES_OPENCL_VERSION(2, 0);
312 bc::svm_ptr
<cl_int
> ptr
=
313 bc::svm_alloc
<cl_int
>(context
, size
* sizeof(cl_int
));
314 bc::fill_n(ptr
, size
* sizeof(cl_int
), 42, queue
);
316 queue
.enqueue_svm_map(ptr
.get(), size
* sizeof(cl_int
), CL_MAP_READ
);
317 for(size_t i
= 0; i
< size
; i
++) {
318 BOOST_CHECK_EQUAL(static_cast<cl_int
*>(ptr
.get())[i
], 42);
320 queue
.enqueue_svm_unmap(ptr
.get());
322 bc::svm_free(context
, ptr
);
324 #endif // BOOST_COMPUTE_CL_VERSION_2_0
326 BOOST_AUTO_TEST_CASE(empty_fill
)
328 bc::vector
<int> vec(0, context
);
329 bc::fill(vec
.begin(), vec
.end(), 42, queue
);
330 bc::fill_async(vec
.begin(), vec
.end(), 42, queue
);
333 BOOST_AUTO_TEST_SUITE_END()