• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 TestDevice
12 #include <boost/test/unit_test.hpp>
13 
14 #include <iostream>
15 
16 #include <boost/compute/device.hpp>
17 #include <boost/compute/system.hpp>
18 #include <boost/compute/detail/nvidia_compute_capability.hpp>
19 
20 #include "opencl_version_check.hpp"
21 
BOOST_AUTO_TEST_CASE(null_device)22 BOOST_AUTO_TEST_CASE(null_device)
23 {
24     boost::compute::device null;
25     BOOST_CHECK(null.id() == cl_device_id());
26     BOOST_CHECK(null.get() == cl_device_id());
27 }
28 
BOOST_AUTO_TEST_CASE(default_device_doctest)29 BOOST_AUTO_TEST_CASE(default_device_doctest)
30 {
31 //! [default_gpu]
32 boost::compute::device gpu = boost::compute::system::default_device();
33 //! [default_gpu]
34 
35     BOOST_CHECK(gpu.id());
36 }
37 
BOOST_AUTO_TEST_CASE(device_platform)38 BOOST_AUTO_TEST_CASE(device_platform)
39 {
40     boost::compute::platform p = boost::compute::system::platforms().at(0);
41     BOOST_CHECK(p == p.devices().at(0).platform());
42 }
43 
BOOST_AUTO_TEST_CASE(get_device_name)44 BOOST_AUTO_TEST_CASE(get_device_name)
45 {
46     boost::compute::device gpu = boost::compute::system::default_device();
47     if(gpu.id()){
48         BOOST_CHECK(!gpu.name().empty());
49     }
50 }
51 
BOOST_AUTO_TEST_CASE(equality_operator)52 BOOST_AUTO_TEST_CASE(equality_operator)
53 {
54     boost::compute::device device1 = boost::compute::system::default_device();
55     BOOST_CHECK(device1 == device1);
56 
57     boost::compute::device device2 = device1;
58     BOOST_CHECK(device1 == device2);
59 }
60 
BOOST_AUTO_TEST_CASE(get_max_work_item_sizes)61 BOOST_AUTO_TEST_CASE(get_max_work_item_sizes)
62 {
63     boost::compute::device device = boost::compute::system::default_device();
64 
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));
71 }
72 
73 #ifdef BOOST_COMPUTE_CL_VERSION_1_2
74 
75 // returns true if the device supports the partitioning type
supports_partition_type(const boost::compute::device & device,cl_device_partition_property type)76 bool supports_partition_type(const boost::compute::device &device,
77                              cl_device_partition_property type)
78 {
79     const std::vector<cl_device_partition_property> properties =
80         device.get_info<std::vector<cl_device_partition_property> >(
81             CL_DEVICE_PARTITION_PROPERTIES
82         );
83 
84     return std::find(properties.begin(),
85                      properties.end(),
86                      type) != properties.end();
87 }
88 
BOOST_AUTO_TEST_CASE(partition_device_equally)89 BOOST_AUTO_TEST_CASE(partition_device_equally)
90 {
91     // get default device and ensure it has at least two compute units
92     boost::compute::device device = boost::compute::system::default_device();
93 
94     REQUIRES_OPENCL_VERSION(1,2);
95 
96     if(device.compute_units() < 2){
97         std::cout << "skipping test: "
98                   << "device does not have enough compute units"
99                   << std::endl;
100         return;
101     }
102 
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"
107                   << std::endl;
108         return;
109     }
110 
111     // ensure device is not a sub-device
112     BOOST_CHECK(device.is_subdevice() == false);
113 
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()));
118 
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];
122 
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());
127 
128         // ensure device is a sub-device
129         BOOST_CHECK(sub_device.is_subdevice() == true);
130 
131         // check number of compute units
132         BOOST_CHECK_EQUAL(sub_device.compute_units(), size_t(1));
133     }
134 }
135 
136 // used to sort devices by number of compute units
compare_compute_units(const boost::compute::device & a,const boost::compute::device & b)137 bool compare_compute_units(const boost::compute::device &a,
138                            const boost::compute::device &b)
139 {
140     return a.compute_units() < b.compute_units();
141 }
142 
BOOST_AUTO_TEST_CASE(partition_by_counts)143 BOOST_AUTO_TEST_CASE(partition_by_counts)
144 {
145     // get default device and ensure it has at least four compute units
146     boost::compute::device device = boost::compute::system::default_device();
147 
148     REQUIRES_OPENCL_VERSION(1,2);
149 
150     if(device.compute_units() < 4){
151         std::cout << "skipping test: "
152                   << "device does not have enough compute units"
153                   << std::endl;
154         return;
155     }
156 
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"
161                   << std::endl;
162         return;
163     }
164 
165     // ensure device is not a sub-device
166     BOOST_CHECK(device.is_subdevice() == false);
167 
168     // create vector of sub-device compute unit counts
169     std::vector<size_t> counts;
170     counts.push_back(2);
171     counts.push_back(1);
172     counts.push_back(1);
173 
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));
178 
179     // sort sub-devices by number of compute units (see issue #185)
180     std::sort(sub_devices.begin(), sub_devices.end(), compare_compute_units);
181 
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));
186 }
187 
BOOST_AUTO_TEST_CASE(partition_by_affinity_domain)188 BOOST_AUTO_TEST_CASE(partition_by_affinity_domain)
189 {
190     // get default device and ensure it has at least two compute units
191     boost::compute::device device = boost::compute::system::default_device();
192 
193     REQUIRES_OPENCL_VERSION(1,2);
194 
195     if(device.compute_units() < 2){
196         std::cout << "skipping test: "
197                   << "device does not have enough compute units"
198                   << std::endl;
199         return;
200     }
201 
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"
206                   << std::endl;
207         return;
208     }
209 
210     // ensure device is not a sub-device
211     BOOST_CHECK(device.is_subdevice() == false);
212 
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);
218 }
219 #endif // BOOST_COMPUTE_CL_VERSION_1_2
220 
BOOST_AUTO_TEST_CASE(nvidia_compute_capability)221 BOOST_AUTO_TEST_CASE(nvidia_compute_capability)
222 {
223     boost::compute::device device = boost::compute::system::default_device();
224     int major, minor;
225     boost::compute::detail::get_nvidia_compute_capability(device, major, minor);
226     boost::compute::detail::check_nvidia_compute_capability(device, 3, 0);
227 }
228 
BOOST_AUTO_TEST_CASE(get_info_specializations)229 BOOST_AUTO_TEST_CASE(get_info_specializations)
230 {
231     boost::compute::device device = boost::compute::system::default_device();
232 
233     std::cout << device.get_info<CL_DEVICE_NAME>() << std::endl;
234 }
235 
236 #ifdef BOOST_COMPUTE_CL_VERSION_2_1
BOOST_AUTO_TEST_CASE(get_host_timer)237 BOOST_AUTO_TEST_CASE(get_host_timer)
238 {
239     boost::compute::device device = boost::compute::system::default_device();
240 
241     REQUIRES_OPENCL_VERSION(2, 1);
242 
243     BOOST_CHECK(device.get_host_timer() != 0);
244 
245     #ifndef BOOST_COMPUTE_NO_HDR_CHRONO
246     typedef std::chrono::milliseconds stdms;
247     BOOST_CHECK(device.get_host_timer<stdms>().count() != 0);
248     #endif
249 
250     #ifndef BOOST_COMPUTE_NO_BOOST_CHRONO
251     typedef boost::chrono::milliseconds bms;
252     BOOST_CHECK(device.get_host_timer<bms>().count() != 0);
253     #endif
254 }
255 
BOOST_AUTO_TEST_CASE(get_device_and_host_timer)256 BOOST_AUTO_TEST_CASE(get_device_and_host_timer)
257 {
258     boost::compute::device device = boost::compute::system::default_device();
259 
260     REQUIRES_OPENCL_VERSION(2, 1);
261 
262     typedef std::pair<boost::compute::ulong_, boost::compute::ulong_> dah_timer;
263     dah_timer timer;
264     BOOST_CHECK_NO_THROW(timer = device.get_device_and_host_timer());
265     BOOST_CHECK(timer.first != 0);
266     BOOST_CHECK(timer.second != 0);
267 
268     #ifndef BOOST_COMPUTE_NO_HDR_CHRONO
269     typedef std::chrono::milliseconds stdms;
270     BOOST_CHECK(device.get_device_and_host_timer<stdms>().first.count() != 0);
271     BOOST_CHECK(device.get_device_and_host_timer<stdms>().second.count() != 0);
272     #endif
273 
274     #ifndef BOOST_COMPUTE_NO_BOOST_CHRONO
275     typedef boost::chrono::milliseconds bms;
276     BOOST_CHECK(device.get_device_and_host_timer<bms>().first.count() != 0);
277     BOOST_CHECK(device.get_device_and_host_timer<bms>().second.count() != 0);
278     #endif
279 }
280 
BOOST_AUTO_TEST_CASE(get_info_opencl21_queries)281 BOOST_AUTO_TEST_CASE(get_info_opencl21_queries)
282 {
283     boost::compute::device device = boost::compute::system::default_device();
284 
285     REQUIRES_OPENCL_VERSION(2, 1);
286 
287     BOOST_CHECK(!device.get_info<CL_DEVICE_IL_VERSION>().empty());
288     BOOST_CHECK(device.get_info<CL_DEVICE_MAX_NUM_SUB_GROUPS>() > 0);
289     BOOST_CHECK_NO_THROW(
290         device.get_info<CL_DEVICE_SUB_GROUP_INDEPENDENT_FORWARD_PROGRESS>()
291     );
292 }
293 #endif // BOOST_COMPUTE_CL_VERSION_2_1
294