]>
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 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 | ||
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 | ||
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 | ||
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 | ||
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 | ||
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 | ||
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 | ||
b32b8144 | 73 | #ifdef BOOST_COMPUTE_CL_VERSION_1_2 |
7c673cae FG |
74 | |
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) | |
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 | ||
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 | ||
b32b8144 | 114 | // partition default device into sub-devices with one compute unit each |
7c673cae | 115 | std::vector<boost::compute::device> |
b32b8144 FG |
116 | sub_devices = device.partition_equally(1); |
117 | BOOST_CHECK_EQUAL(sub_devices.size(), size_t(device.compute_units())); | |
7c673cae FG |
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 | |
b32b8144 | 132 | BOOST_CHECK_EQUAL(sub_device.compute_units(), size_t(1)); |
7c673cae FG |
133 | } |
134 | } | |
135 | ||
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) | |
139 | { | |
140 | return a.compute_units() < b.compute_units(); | |
141 | } | |
142 | ||
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 | ||
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 | } | |
b32b8144 | 219 | #endif // BOOST_COMPUTE_CL_VERSION_1_2 |
7c673cae FG |
220 | |
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 | ||
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 | } | |
b32b8144 FG |
235 | |
236 | #ifdef BOOST_COMPUTE_CL_VERSION_2_1 | |
237 | BOOST_AUTO_TEST_CASE(get_host_timer) | |
238 | { | |
239 | boost::compute::device device = boost::compute::system::default_device(); | |
92f5a8d4 TL |
240 | |
241 | REQUIRES_OPENCL_VERSION(2, 1); | |
242 | ||
b32b8144 FG |
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 | ||
256 | BOOST_AUTO_TEST_CASE(get_device_and_host_timer) | |
257 | { | |
258 | boost::compute::device device = boost::compute::system::default_device(); | |
92f5a8d4 TL |
259 | |
260 | REQUIRES_OPENCL_VERSION(2, 1); | |
261 | ||
b32b8144 FG |
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 | ||
281 | BOOST_AUTO_TEST_CASE(get_info_opencl21_queries) | |
282 | { | |
283 | boost::compute::device device = boost::compute::system::default_device(); | |
284 | ||
92f5a8d4 TL |
285 | REQUIRES_OPENCL_VERSION(2, 1); |
286 | ||
b32b8144 FG |
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 |