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 TestKernel
12 #include <boost/test/unit_test.hpp>
14 #include <boost/compute/buffer.hpp>
15 #include <boost/compute/kernel.hpp>
16 #include <boost/compute/types.hpp>
17 #include <boost/compute/system.hpp>
18 #include <boost/compute/utility/source.hpp>
20 #include "context_setup.hpp"
21 #include "check_macros.hpp"
23 namespace compute
= boost::compute
;
25 BOOST_AUTO_TEST_CASE(name
)
27 compute::kernel foo
= compute::kernel::create_with_source(
28 "__kernel void foo(int x) { }", "foo", context
30 BOOST_CHECK_EQUAL(foo
.name(), "foo");
32 compute::kernel bar
= compute::kernel::create_with_source(
33 "__kernel void bar(float x) { }", "bar", context
35 BOOST_CHECK_EQUAL(bar
.name(), "bar");
38 BOOST_AUTO_TEST_CASE(arity
)
40 compute::kernel foo
= compute::kernel::create_with_source(
41 "__kernel void foo(int x) { }", "foo", context
43 BOOST_CHECK_EQUAL(foo
.arity(), size_t(1));
45 compute::kernel bar
= compute::kernel::create_with_source(
46 "__kernel void bar(float x, float y) { }", "bar", context
48 BOOST_CHECK_EQUAL(bar
.arity(), size_t(2));
50 compute::kernel baz
= compute::kernel::create_with_source(
51 "__kernel void baz(char x, char y, char z) { }", "baz", context
53 BOOST_CHECK_EQUAL(baz
.arity(), size_t(3));
56 BOOST_AUTO_TEST_CASE(set_buffer_arg
)
58 const char source
[] = BOOST_COMPUTE_STRINGIZE_SOURCE(
59 __kernel
void foo(__global
int *x
, __global
int *y
)
61 x
[get_global_id(0)] = -y
[get_global_id(0)];
66 compute::kernel::create_with_source(source
, "foo", context
);
68 compute::buffer
x(context
, 16);
69 compute::buffer
y(context
, 16);
72 foo
.set_arg(1, y
.get());
75 BOOST_AUTO_TEST_CASE(get_work_group_info
)
78 "__kernel void sum(__global const float *input,\n"
79 " __global float *output)\n"
81 " __local float scratch[16];\n"
82 " const uint gid = get_global_id(0);\n"
83 " const uint lid = get_local_id(0);\n"
85 " scratch[lid] = input[gid];\n"
88 compute::program program
=
89 compute::program::create_with_source(source
, context
);
93 compute::kernel kernel
= program
.create_kernel("sum");
95 using compute::ulong_
;
97 // get local memory size
98 kernel
.get_work_group_info
<ulong_
>(device
, CL_KERNEL_LOCAL_MEM_SIZE
);
100 // check work group size
101 size_t work_group_size
=
102 kernel
.get_work_group_info
<size_t>(device
, CL_KERNEL_WORK_GROUP_SIZE
);
103 BOOST_CHECK(work_group_size
>= 1);
106 #ifndef BOOST_COMPUTE_NO_VARIADIC_TEMPLATES
107 BOOST_AUTO_TEST_CASE(kernel_set_args
)
109 compute::kernel k
= compute::kernel::create_with_source(
110 "__kernel void test(int x, float y, char z) { }", "test", context
113 k
.set_args(4, 2.4f
, 'a');
115 #endif // BOOST_COMPUTE_NO_VARIADIC_TEMPLATES
117 // Originally failed to compile on macOS (several types are resolved differently)
118 BOOST_AUTO_TEST_CASE(kernel_set_args_mac
)
120 compute::kernel k
= compute::kernel::create_with_source(
121 "__kernel void test(unsigned int a, unsigned long b) { }", "test", context
132 #ifdef BOOST_COMPUTE_CL_VERSION_1_2
133 BOOST_AUTO_TEST_CASE(get_arg_info
)
135 REQUIRES_OPENCL_VERSION(1, 2);
137 const char source
[] = BOOST_COMPUTE_STRINGIZE_SOURCE(
138 __kernel
void sum_kernel(__global
const int *input
,
140 __global
int *result
)
143 for(uint i
= 0; i
< size
; i
++){
150 compute::program program
=
151 compute::program::create_with_source(source
, context
);
153 program
.build("-cl-kernel-arg-info");
155 compute::kernel kernel
= program
.create_kernel("sum_kernel");
157 BOOST_CHECK_EQUAL(kernel
.get_info
<CL_KERNEL_NUM_ARGS
>(), compute::uint_(3));
159 BOOST_CHECK_EQUAL(kernel
.get_arg_info
<std::string
>(0, CL_KERNEL_ARG_TYPE_NAME
), "int*");
160 BOOST_CHECK_EQUAL(kernel
.get_arg_info
<std::string
>(0, CL_KERNEL_ARG_NAME
), "input");
161 BOOST_CHECK_EQUAL(kernel
.get_arg_info
<std::string
>(1, CL_KERNEL_ARG_TYPE_NAME
), "uint");
162 BOOST_CHECK_EQUAL(kernel
.get_arg_info
<std::string
>(1, CL_KERNEL_ARG_NAME
), "size");
163 BOOST_CHECK_EQUAL(kernel
.get_arg_info
<std::string
>(2, CL_KERNEL_ARG_TYPE_NAME
), "int*");
164 BOOST_CHECK_EQUAL(kernel
.get_arg_info
<std::string
>(2, CL_KERNEL_ARG_NAME
), "result");
166 BOOST_CHECK_EQUAL(kernel
.get_arg_info
<CL_KERNEL_ARG_TYPE_NAME
>(0), "int*");
167 BOOST_CHECK_EQUAL(kernel
.get_arg_info
<CL_KERNEL_ARG_NAME
>(0), "input");
168 BOOST_CHECK_EQUAL(kernel
.get_arg_info
<CL_KERNEL_ARG_TYPE_NAME
>(1), "uint");
169 BOOST_CHECK_EQUAL(kernel
.get_arg_info
<CL_KERNEL_ARG_NAME
>(1), "size");
170 BOOST_CHECK_EQUAL(kernel
.get_arg_info
<CL_KERNEL_ARG_TYPE_NAME
>(2), "int*");
171 BOOST_CHECK_EQUAL(kernel
.get_arg_info
<CL_KERNEL_ARG_NAME
>(2), "result");
173 #endif // BOOST_COMPUTE_CL_VERSION_1_2
175 #ifdef BOOST_COMPUTE_CL_VERSION_2_0
176 #ifndef CL_KERNEL_MAX_SUB_GROUP_SIZE_FOR_NDRANGE_KHR
177 #define CL_KERNEL_MAX_SUB_GROUP_SIZE_FOR_NDRANGE_KHR CL_KERNEL_MAX_SUB_GROUP_SIZE_FOR_NDRANGE
179 #ifndef CL_KERNEL_SUB_GROUP_COUNT_FOR_NDRANGE_KHR
180 #define CL_KERNEL_SUB_GROUP_COUNT_FOR_NDRANGE_KHR CL_KERNEL_SUB_GROUP_COUNT_FOR_NDRANGE
182 BOOST_AUTO_TEST_CASE(get_sub_group_info_ext
)
184 compute::kernel k
= compute::kernel::create_with_source(
185 "__kernel void test(float x) { }", "test", context
188 // get_sub_group_info(const device&, cl_kernel_sub_group_info, const std::vector<size_t>)
189 std::vector
<size_t> local_work_size(2, size_t(64));
190 boost::optional
<size_t> count
= k
.get_sub_group_info
<size_t>(
192 CL_KERNEL_SUB_GROUP_COUNT_FOR_NDRANGE_KHR
,
196 #ifdef BOOST_COMPUTE_CL_VERSION_2_1
197 if(device
.check_version(2, 1))
202 #endif // BOOST_COMPUTE_CL_VERSION_2_1
203 if(device
.check_version(2, 0) && device
.supports_extension("cl_khr_subgroups"))
205 // for device with cl_khr_subgroups it should return some value
210 // for device without cl_khr_subgroups ext it should return null optional
211 BOOST_CHECK(count
== boost::none
);
214 // get_sub_group_info(const device&, cl_kernel_sub_group_info, const size_t, const void *)
215 count
= k
.get_sub_group_info
<size_t>(
217 CL_KERNEL_SUB_GROUP_COUNT_FOR_NDRANGE_KHR
,
222 #ifdef BOOST_COMPUTE_CL_VERSION_2_1
223 if(device
.check_version(2, 1))
228 #endif // BOOST_COMPUTE_CL_VERSION_2_1
229 if(device
.check_version(2, 0) && device
.supports_extension("cl_khr_subgroups"))
231 // for device with cl_khr_subgroups it should return some value
236 // for device without cl_khr_subgroups ext it should return null optional
237 BOOST_CHECK(count
== boost::none
);
240 #endif // BOOST_COMPUTE_CL_VERSION_2_0
242 #ifdef BOOST_COMPUTE_CL_VERSION_2_1
243 BOOST_AUTO_TEST_CASE(get_sub_group_info_core
)
245 compute::kernel k
= compute::kernel::create_with_source(
246 "__kernel void test(float x) { }", "test", context
249 // get_sub_group_info(const device&, cl_kernel_sub_group_info, const size_t)
250 boost::optional
<std::vector
<size_t>> local_size
=
251 k
.get_sub_group_info
<std::vector
<size_t> >(
253 CL_KERNEL_LOCAL_SIZE_FOR_SUB_GROUP_COUNT
,
257 if(device
.check_version(2, 1))
259 // for 2.1 devices it should return some value
260 BOOST_CHECK(local_size
);
261 BOOST_CHECK(local_size
.value().size() == 3);
265 // for 1.x and 2.0 devices it should return null optional,
266 // because CL_KERNEL_LOCAL_SIZE_FOR_SUB_GROUP_COUNT is not
267 // supported by cl_khr_subgroups (2.0 ext)
268 BOOST_CHECK(local_size
== boost::none
);
271 // get_sub_group_info(const device&, cl_kernel_sub_group_info, const size_t)
272 boost::optional
<size_t> local_size_simple
=
273 k
.get_sub_group_info
<size_t>(
275 CL_KERNEL_LOCAL_SIZE_FOR_SUB_GROUP_COUNT
,
279 if(device
.check_version(2, 1))
281 // for 2.1 devices it should return some value
282 BOOST_CHECK(local_size_simple
);
286 // for 1.x and 2.0 devices it should return null optional,
287 // because CL_KERNEL_LOCAL_SIZE_FOR_SUB_GROUP_COUNT is not
288 // supported by cl_khr_subgroups (2.0 ext)
289 BOOST_CHECK(local_size_simple
== boost::none
);
292 // get_sub_group_info(const device&, cl_kernel_sub_group_info)
293 boost::optional
<size_t> max
=
294 k
.get_sub_group_info
<size_t>(
296 CL_KERNEL_MAX_NUM_SUB_GROUPS
299 if(device
.check_version(2, 1))
301 // for 2.1 devices it should return some value
306 // for 1.x and 2.0 devices it should return null optional,
307 // because CL_KERNEL_MAX_NUM_SUB_GROUPS is not
308 // supported by cl_khr_subgroups (2.0 ext)
309 BOOST_CHECK(max
== boost::none
);
312 #endif // BOOST_COMPUTE_CL_VERSION_2_1
314 #ifdef BOOST_COMPUTE_CL_VERSION_2_1
315 BOOST_AUTO_TEST_CASE(clone_kernel
)
317 REQUIRES_OPENCL_PLATFORM_VERSION(2, 1);
319 compute::kernel k1
= compute::kernel::create_with_source(
320 "__kernel void test(__global int * x) { x[get_global_id(0)] = get_global_id(0); }",
324 compute::buffer
x(context
, 5 * sizeof(compute::int_
));
328 compute::kernel k2
= k1
.clone();
329 // After clone k2 0th argument (__global float * x) should be set,
330 // so we should be able to enqueue k2 kernel without problems
331 queue
.enqueue_1d_range_kernel(k2
, 0, x
.size() / sizeof(compute::int_
), 0).wait();
333 #endif // BOOST_COMPUTE_CL_VERSION_2_1
335 BOOST_AUTO_TEST_SUITE_END()