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 TestDevice
12 #include <boost/test/unit_test.hpp>
16 #include <boost/compute/device.hpp>
17 #include <boost/compute/system.hpp>
18 #include <boost/compute/detail/nvidia_compute_capability.hpp>
20 #include "opencl_version_check.hpp"
22 BOOST_AUTO_TEST_CASE(null_device
)
24 boost::compute::device null
;
25 BOOST_CHECK(null
.id() == cl_device_id());
26 BOOST_CHECK(null
.get() == cl_device_id());
29 BOOST_AUTO_TEST_CASE(default_device_doctest
)
32 boost::compute::device gpu
= boost::compute::system::default_device();
35 BOOST_CHECK(gpu
.id());
38 BOOST_AUTO_TEST_CASE(device_platform
)
40 boost::compute::platform p
= boost::compute::system::platforms().at(0);
41 BOOST_CHECK(p
== p
.devices().at(0).platform());
44 BOOST_AUTO_TEST_CASE(get_device_name
)
46 boost::compute::device gpu
= boost::compute::system::default_device();
48 BOOST_CHECK(!gpu
.name().empty());
52 BOOST_AUTO_TEST_CASE(equality_operator
)
54 boost::compute::device device1
= boost::compute::system::default_device();
55 BOOST_CHECK(device1
== device1
);
57 boost::compute::device device2
= device1
;
58 BOOST_CHECK(device1
== device2
);
61 BOOST_AUTO_TEST_CASE(get_max_work_item_sizes
)
63 boost::compute::device device
= boost::compute::system::default_device();
65 std::vector
<size_t> max_work_item_sizes
=
66 device
.get_info
<std::vector
<size_t> >(CL_DEVICE_MAX_WORK_ITEM_SIZES
);
67 BOOST_CHECK_GE(max_work_item_sizes
.size(), size_t(3));
68 BOOST_CHECK_GE(max_work_item_sizes
[0], size_t(1));
69 BOOST_CHECK_GE(max_work_item_sizes
[1], size_t(1));
70 BOOST_CHECK_GE(max_work_item_sizes
[2], size_t(1));
73 #ifdef BOOST_COMPUTE_CL_VERSION_1_2
75 // returns true if the device supports the partitioning type
76 bool supports_partition_type(const boost::compute::device
&device
,
77 cl_device_partition_property type
)
79 const std::vector
<cl_device_partition_property
> properties
=
80 device
.get_info
<std::vector
<cl_device_partition_property
> >(
81 CL_DEVICE_PARTITION_PROPERTIES
84 return std::find(properties
.begin(),
86 type
) != properties
.end();
89 BOOST_AUTO_TEST_CASE(partition_device_equally
)
91 // get default device and ensure it has at least two compute units
92 boost::compute::device device
= boost::compute::system::default_device();
94 REQUIRES_OPENCL_VERSION(1,2);
96 if(device
.compute_units() < 2){
97 std::cout
<< "skipping test: "
98 << "device does not have enough compute units"
103 // check that the device supports partitioning equally
104 if(!supports_partition_type(device
, CL_DEVICE_PARTITION_EQUALLY
)){
105 std::cout
<< "skipping test: "
106 << "device does not support CL_DEVICE_PARTITION_EQUALLY"
111 // ensure device is not a sub-device
112 BOOST_CHECK(device
.is_subdevice() == false);
114 // partition default device into sub-devices with one compute unit each
115 std::vector
<boost::compute::device
>
116 sub_devices
= device
.partition_equally(1);
117 BOOST_CHECK_EQUAL(sub_devices
.size(), size_t(device
.compute_units()));
119 // verify each of the sub-devices
120 for(size_t i
= 0; i
< sub_devices
.size(); i
++){
121 const boost::compute::device
&sub_device
= sub_devices
[i
];
123 // ensure parent device id is correct
124 cl_device_id parent_id
=
125 sub_device
.get_info
<cl_device_id
>(CL_DEVICE_PARENT_DEVICE
);
126 BOOST_CHECK(parent_id
== device
.id());
128 // ensure device is a sub-device
129 BOOST_CHECK(sub_device
.is_subdevice() == true);
131 // check number of compute units
132 BOOST_CHECK_EQUAL(sub_device
.compute_units(), size_t(1));
136 // used to sort devices by number of compute units
137 bool compare_compute_units(const boost::compute::device
&a
,
138 const boost::compute::device
&b
)
140 return a
.compute_units() < b
.compute_units();
143 BOOST_AUTO_TEST_CASE(partition_by_counts
)
145 // get default device and ensure it has at least four compute units
146 boost::compute::device device
= boost::compute::system::default_device();
148 REQUIRES_OPENCL_VERSION(1,2);
150 if(device
.compute_units() < 4){
151 std::cout
<< "skipping test: "
152 << "device does not have enough compute units"
157 // check that the device supports partitioning by counts
158 if(!supports_partition_type(device
, CL_DEVICE_PARTITION_BY_COUNTS
)){
159 std::cout
<< "skipping test: "
160 << "device does not support CL_DEVICE_PARTITION_BY_COUNTS"
165 // ensure device is not a sub-device
166 BOOST_CHECK(device
.is_subdevice() == false);
168 // create vector of sub-device compute unit counts
169 std::vector
<size_t> counts
;
174 // partition default device into sub-devices according to counts
175 std::vector
<boost::compute::device
>
176 sub_devices
= device
.partition_by_counts(counts
);
177 BOOST_CHECK_EQUAL(sub_devices
.size(), size_t(3));
179 // sort sub-devices by number of compute units (see issue #185)
180 std::sort(sub_devices
.begin(), sub_devices
.end(), compare_compute_units
);
182 // verify each of the sub-devices
183 BOOST_CHECK_EQUAL(sub_devices
[0].compute_units(), size_t(1));
184 BOOST_CHECK_EQUAL(sub_devices
[1].compute_units(), size_t(1));
185 BOOST_CHECK_EQUAL(sub_devices
[2].compute_units(), size_t(2));
188 BOOST_AUTO_TEST_CASE(partition_by_affinity_domain
)
190 // get default device and ensure it has at least two compute units
191 boost::compute::device device
= boost::compute::system::default_device();
193 REQUIRES_OPENCL_VERSION(1,2);
195 if(device
.compute_units() < 2){
196 std::cout
<< "skipping test: "
197 << "device does not have enough compute units"
202 // check that the device supports splitting by affinity domains
203 if(!supports_partition_type(device
, CL_DEVICE_AFFINITY_DOMAIN_NEXT_PARTITIONABLE
)){
204 std::cout
<< "skipping test: "
205 << "device does not support partitioning by affinity domain"
210 // ensure device is not a sub-device
211 BOOST_CHECK(device
.is_subdevice() == false);
213 std::vector
<boost::compute::device
> sub_devices
=
214 device
.partition_by_affinity_domain(
215 CL_DEVICE_AFFINITY_DOMAIN_NEXT_PARTITIONABLE
);
216 BOOST_CHECK(sub_devices
.size() > 0);
217 BOOST_CHECK(sub_devices
[0].is_subdevice() == true);
219 #endif // BOOST_COMPUTE_CL_VERSION_1_2
221 BOOST_AUTO_TEST_CASE(nvidia_compute_capability
)
223 boost::compute::device device
= boost::compute::system::default_device();
225 boost::compute::detail::get_nvidia_compute_capability(device
, major
, minor
);
226 boost::compute::detail::check_nvidia_compute_capability(device
, 3, 0);
229 BOOST_AUTO_TEST_CASE(get_info_specializations
)
231 boost::compute::device device
= boost::compute::system::default_device();
233 std::cout
<< device
.get_info
<CL_DEVICE_NAME
>() << std::endl
;
236 #ifdef BOOST_COMPUTE_CL_VERSION_2_1
237 BOOST_AUTO_TEST_CASE(get_host_timer
)
239 boost::compute::device device
= boost::compute::system::default_device();
240 BOOST_CHECK(device
.get_host_timer() != 0);
242 #ifndef BOOST_COMPUTE_NO_HDR_CHRONO
243 typedef std::chrono::milliseconds stdms
;
244 BOOST_CHECK(device
.get_host_timer
<stdms
>().count() != 0);
247 #ifndef BOOST_COMPUTE_NO_BOOST_CHRONO
248 typedef boost::chrono::milliseconds bms
;
249 BOOST_CHECK(device
.get_host_timer
<bms
>().count() != 0);
253 BOOST_AUTO_TEST_CASE(get_device_and_host_timer
)
255 boost::compute::device device
= boost::compute::system::default_device();
256 typedef std::pair
<boost::compute::ulong_
, boost::compute::ulong_
> dah_timer
;
258 BOOST_CHECK_NO_THROW(timer
= device
.get_device_and_host_timer());
259 BOOST_CHECK(timer
.first
!= 0);
260 BOOST_CHECK(timer
.second
!= 0);
262 #ifndef BOOST_COMPUTE_NO_HDR_CHRONO
263 typedef std::chrono::milliseconds stdms
;
264 BOOST_CHECK(device
.get_device_and_host_timer
<stdms
>().first
.count() != 0);
265 BOOST_CHECK(device
.get_device_and_host_timer
<stdms
>().second
.count() != 0);
268 #ifndef BOOST_COMPUTE_NO_BOOST_CHRONO
269 typedef boost::chrono::milliseconds bms
;
270 BOOST_CHECK(device
.get_device_and_host_timer
<bms
>().first
.count() != 0);
271 BOOST_CHECK(device
.get_device_and_host_timer
<bms
>().second
.count() != 0);
275 BOOST_AUTO_TEST_CASE(get_info_opencl21_queries
)
277 boost::compute::device device
= boost::compute::system::default_device();
279 BOOST_CHECK(!device
.get_info
<CL_DEVICE_IL_VERSION
>().empty());
280 BOOST_CHECK(device
.get_info
<CL_DEVICE_MAX_NUM_SUB_GROUPS
>() > 0);
281 BOOST_CHECK_NO_THROW(
282 device
.get_info
<CL_DEVICE_SUB_GROUP_INDEPENDENT_FORWARD_PROGRESS
>()
285 #endif // BOOST_COMPUTE_CL_VERSION_2_1