]>
Commit | Line | Data |
---|---|---|
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 TestFill | |
12 | #include <boost/test/unit_test.hpp> | |
13 | #include <boost/test/test_case_template.hpp> | |
14 | #include <boost/mpl/list.hpp> | |
15 | ||
16 | #include <iostream> | |
17 | ||
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> | |
25 | ||
26 | #include "check_macros.hpp" | |
27 | #include "context_setup.hpp" | |
28 | ||
29 | namespace bc = boost::compute; | |
30 | ||
31 | typedef boost::mpl::list | |
32 | <bc::char_, bc::uchar_, bc::int_, bc::uint_, | |
33 | bc::long_, bc::ulong_, bc::float_, bc::double_> | |
34 | scalar_types; | |
35 | ||
36 | template<class T> | |
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; | |
42 | return; | |
43 | } | |
44 | ||
45 | bc::vector<T> vector(4, queue.get_context()); | |
46 | bc::fill(vector.begin(), vector.end(), v1, queue); | |
47 | queue.finish(); | |
48 | CHECK_RANGE_EQUAL(T, 4, vector, (v1, v1, v1, v1)); | |
49 | ||
50 | vector.resize(1000, queue); | |
51 | bc::fill(vector.begin(), vector.end(), v2, queue); | |
52 | queue.finish(); | |
53 | BOOST_CHECK_EQUAL(vector.front(), v2); | |
54 | BOOST_CHECK_EQUAL(vector.back(), v2); | |
55 | ||
56 | bc::fill(vector.begin() + 500, vector.end(), v3, queue); | |
57 | queue.finish(); | |
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); | |
62 | } | |
63 | ||
64 | BOOST_AUTO_TEST_CASE_TEMPLATE( fill_scalar, S, scalar_types ) | |
65 | { | |
66 | S v1 = S(1.5f); | |
67 | S v2 = S(2.5f); | |
68 | S v3 = S(42.0f); | |
69 | test_fill(v1, v2, v3, queue); | |
70 | } | |
71 | ||
72 | BOOST_AUTO_TEST_CASE_TEMPLATE( fill_vec2, S, scalar_types ) | |
73 | { | |
74 | typedef typename bc::make_vector_type<S, 2>::type T; | |
75 | S s1 = S(1.5f); | |
76 | S s2 = S(2.5f); | |
77 | S s3 = S(42.0f); | |
78 | S s4 = S(84.0f); | |
79 | ||
80 | T v1 = T(s1, s2); | |
81 | T v2 = T(s3, s4); | |
82 | T v3 = T(s2, s1); | |
83 | test_fill(v1, v2, v3, queue); | |
84 | } | |
85 | ||
86 | BOOST_AUTO_TEST_CASE_TEMPLATE( fill_vec4, S, scalar_types ) | |
87 | { | |
88 | typedef typename bc::make_vector_type<S, 4>::type T; | |
89 | S s1 = S(1.5f); | |
90 | S s2 = S(2.5f); | |
91 | S s3 = S(42.0f); | |
92 | S s4 = S(84.0f); | |
93 | ||
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); | |
98 | } | |
99 | ||
100 | BOOST_AUTO_TEST_CASE_TEMPLATE( fill_vec8, S, scalar_types ) | |
101 | { | |
102 | typedef typename bc::make_vector_type<S, 8>::type T; | |
103 | S s1 = S(1.5f); | |
104 | S s2 = S(2.5f); | |
105 | S s3 = S(42.0f); | |
106 | S s4 = S(84.0f); | |
107 | S s5 = S(122.5f); | |
108 | S s6 = S(131.5f); | |
109 | S s7 = S(142.0f); | |
110 | S s8 = S(254.0f); | |
111 | ||
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); | |
116 | } | |
117 | ||
118 | BOOST_AUTO_TEST_CASE_TEMPLATE( fill_vec16, S, scalar_types ) | |
119 | { | |
120 | typedef typename bc::make_vector_type<S, 16>::type T; | |
121 | S s1 = S(1.5f); | |
122 | S s2 = S(2.5f); | |
123 | S s3 = S(42.0f); | |
124 | S s4 = S(84.0f); | |
125 | S s5 = S(122.5f); | |
126 | S s6 = S(131.5f); | |
127 | S s7 = S(142.0f); | |
128 | S s8 = S(254.0f); | |
129 | ||
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); | |
134 | } | |
135 | ||
136 | template<class T> | |
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; | |
142 | return; | |
143 | } | |
144 | ||
145 | bc::vector<T> vector(4, queue.get_context()); | |
146 | bc::fill_n(vector.begin(), 4, v1, queue); | |
147 | queue.finish(); | |
148 | CHECK_RANGE_EQUAL(T, 4, vector, (v1, v1, v1, v1)); | |
149 | ||
150 | bc::fill_n(vector.begin(), 3, v2, queue); | |
151 | queue.finish(); | |
152 | CHECK_RANGE_EQUAL(T, 4, vector, (v2, v2, v2, v1)); | |
153 | ||
154 | bc::fill_n(vector.begin() + 1, 2, v3, queue); | |
155 | queue.finish(); | |
156 | CHECK_RANGE_EQUAL(T, 4, vector, (v2, v3, v3, v1)); | |
157 | ||
158 | bc::fill_n(vector.begin(), 4, v2, queue); | |
159 | queue.finish(); | |
160 | CHECK_RANGE_EQUAL(T, 4, vector, (v2, v2, v2, v2)); | |
161 | ||
162 | // fill last element | |
163 | bc::fill_n(vector.end() - 1, 1, v3, queue); | |
164 | queue.finish(); | |
165 | CHECK_RANGE_EQUAL(T, 4, vector, (v2, v2, v2, v3)); | |
166 | ||
167 | // fill first element | |
168 | bc::fill_n(vector.begin(), 1, v1, queue); | |
169 | queue.finish(); | |
170 | CHECK_RANGE_EQUAL(T, 4, vector, (v1, v2, v2, v3)); | |
171 | } | |
172 | ||
173 | BOOST_AUTO_TEST_CASE_TEMPLATE( fill_n_scalar, S, scalar_types ) | |
174 | { | |
175 | S v1 = S(1.5f); | |
176 | S v2 = S(2.5f); | |
177 | S v3 = S(42.0f); | |
178 | test_fill_n(v1, v2, v3, queue); | |
179 | } | |
180 | ||
181 | BOOST_AUTO_TEST_CASE_TEMPLATE( fill_n_vec2, S, scalar_types ) | |
182 | { | |
183 | typedef typename bc::make_vector_type<S, 2>::type T; | |
184 | S s1 = S(1.5f); | |
185 | S s2 = S(2.5f); | |
186 | S s3 = S(42.0f); | |
187 | S s4 = S(84.0f); | |
188 | ||
189 | T v1 = T(s1, s2); | |
190 | T v2 = T(s3, s4); | |
191 | T v3 = T(s2, s1); | |
192 | test_fill_n(v1, v2, v3, queue); | |
193 | } | |
194 | ||
195 | BOOST_AUTO_TEST_CASE_TEMPLATE( fill_n_vec4, S, scalar_types ) | |
196 | { | |
197 | typedef typename bc::make_vector_type<S, 4>::type T; | |
198 | S s1 = S(1.5f); | |
199 | S s2 = S(2.5f); | |
200 | S s3 = S(42.0f); | |
201 | S s4 = S(84.0f); | |
202 | ||
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); | |
207 | } | |
208 | ||
209 | BOOST_AUTO_TEST_CASE_TEMPLATE( fill_n_vec8, S, scalar_types ) | |
210 | { | |
211 | typedef typename bc::make_vector_type<S, 8>::type T; | |
212 | S s1 = S(1.5f); | |
213 | S s2 = S(2.5f); | |
214 | S s3 = S(42.0f); | |
215 | S s4 = S(84.0f); | |
216 | S s5 = S(122.5f); | |
217 | S s6 = S(131.5f); | |
218 | S s7 = S(142.0f); | |
219 | S s8 = S(254.0f); | |
220 | ||
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); | |
225 | } | |
226 | ||
227 | BOOST_AUTO_TEST_CASE_TEMPLATE( fill_n_vec16, S, scalar_types ) | |
228 | { | |
229 | typedef typename bc::make_vector_type<S, 16>::type T; | |
230 | S s1 = S(1.5f); | |
231 | S s2 = S(2.5f); | |
232 | S s3 = S(42.0f); | |
233 | S s4 = S(84.0f); | |
234 | S s5 = S(122.5f); | |
235 | S s6 = S(131.5f); | |
236 | S s7 = S(142.0f); | |
237 | S s8 = S(254.0f); | |
238 | ||
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); | |
243 | } | |
244 | ||
245 | BOOST_AUTO_TEST_CASE(check_fill_type) | |
246 | { | |
247 | bc::vector<int> vector(5, context); | |
248 | bc::future<void> future = | |
249 | bc::fill_async(vector.begin(), vector.end(), 42, queue); | |
250 | future.wait(); | |
251 | ||
b32b8144 | 252 | #ifdef BOOST_COMPUTE_CL_VERSION_1_2 |
7c673cae FG |
253 | BOOST_CHECK_EQUAL( |
254 | future.get_event().get_command_type(), | |
255 | device.check_version(1,2) ? CL_COMMAND_FILL_BUFFER : CL_COMMAND_NDRANGE_KERNEL | |
256 | ); | |
257 | #else | |
258 | BOOST_CHECK( | |
259 | future.get_event().get_command_type() == CL_COMMAND_NDRANGE_KERNEL | |
260 | ); | |
261 | #endif | |
262 | } | |
263 | ||
264 | BOOST_AUTO_TEST_CASE(fill_clone_buffer) | |
265 | { | |
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)); | |
269 | ||
270 | bc::buffer cloned_buffer = vec.get_buffer().clone(queue); | |
271 | BOOST_CHECK( | |
272 | bc::equal( | |
273 | vec.begin(), | |
274 | vec.end(), | |
275 | bc::make_buffer_iterator<int>(cloned_buffer, 0), | |
276 | queue | |
277 | ) | |
278 | ); | |
279 | ||
280 | bc::fill(vec.begin(), vec.end(), 5, queue); | |
281 | BOOST_CHECK( | |
282 | !bc::equal( | |
283 | vec.begin(), | |
284 | vec.end(), | |
285 | bc::make_buffer_iterator<int>(cloned_buffer, 0), | |
286 | queue | |
287 | ) | |
288 | ); | |
289 | ||
290 | bc::fill( | |
291 | bc::make_buffer_iterator<int>(cloned_buffer, 0), | |
292 | bc::make_buffer_iterator<int>(cloned_buffer, 4), | |
293 | 5, | |
294 | queue | |
295 | ); | |
296 | BOOST_CHECK( | |
297 | bc::equal( | |
298 | vec.begin(), | |
299 | vec.end(), | |
300 | bc::make_buffer_iterator<int>(cloned_buffer, 0), | |
301 | queue | |
302 | ) | |
303 | ); | |
304 | } | |
305 | ||
b32b8144 | 306 | #ifdef BOOST_COMPUTE_CL_VERSION_2_0 |
7c673cae FG |
307 | BOOST_AUTO_TEST_CASE(fill_svm_buffer) |
308 | { | |
309 | REQUIRES_OPENCL_VERSION(2, 0); | |
310 | ||
311 | size_t size = 4; | |
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); | |
315 | ||
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); | |
319 | } | |
320 | queue.enqueue_svm_unmap(ptr.get()); | |
321 | ||
322 | bc::svm_free(context, ptr); | |
323 | } | |
b32b8144 | 324 | #endif // BOOST_COMPUTE_CL_VERSION_2_0 |
7c673cae FG |
325 | |
326 | BOOST_AUTO_TEST_CASE(empty_fill) | |
327 | { | |
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); | |
331 | } | |
332 | ||
333 | BOOST_AUTO_TEST_SUITE_END() |