]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/compute/include/boost/compute/system.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / compute / include / boost / compute / system.hpp
CommitLineData
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#ifndef BOOST_COMPUTE_SYSTEM_HPP
12#define BOOST_COMPUTE_SYSTEM_HPP
13
14#include <string>
15#include <vector>
16#include <cstdlib>
17
18#include <boost/throw_exception.hpp>
19
20#include <boost/compute/cl.hpp>
21#include <boost/compute/device.hpp>
22#include <boost/compute/context.hpp>
23#include <boost/compute/platform.hpp>
24#include <boost/compute/command_queue.hpp>
25#include <boost/compute/detail/getenv.hpp>
26#include <boost/compute/exception/no_device_found.hpp>
27
28namespace boost {
29namespace compute {
30
31/// \class system
32/// \brief Provides access to platforms and devices on the system.
33///
34/// The system class contains a set of static functions which provide access to
35/// the OpenCL platforms and compute devices on the host system.
36///
37/// The default_device() convenience method automatically selects and returns
38/// the "best" compute device for the system following a set of heuristics and
39/// environment variables. This simplifies setup of the OpenCL enviornment.
40///
41/// \see platform, device, context
42class system
43{
44public:
45 /// Returns the default compute device for the system.
46 ///
47 /// The default device is selected based on a set of heuristics and can be
48 /// influenced using one of the following environment variables:
49 ///
50 /// \li \c BOOST_COMPUTE_DEFAULT_DEVICE -
51 /// name of the compute device (e.g. "GTX TITAN")
52 /// \li \c BOOST_COMPUTE_DEFAULT_DEVICE_TYPE
53 /// type of the compute device (e.g. "GPU" or "CPU")
54 /// \li \c BOOST_COMPUTE_DEFAULT_PLATFORM -
55 /// name of the platform (e.g. "NVIDIA CUDA")
56 /// \li \c BOOST_COMPUTE_DEFAULT_VENDOR -
57 /// name of the device vendor (e.g. "NVIDIA")
58 ///
59 /// The default device is determined once on the first time this function
60 /// is called. Calling this function multiple times will always result in
61 /// the same device being returned.
62 ///
63 /// If no OpenCL device is found on the system, a no_device_found exception
64 /// is thrown.
65 ///
66 /// For example, to print the name of the default compute device on the
67 /// system:
68 /// \code
69 /// // get the default compute device
70 /// boost::compute::device device = boost::compute::system::default_device();
71 ///
72 /// // print the name of the device
73 /// std::cout << "default device: " << device.name() << std::endl;
74 /// \endcode
75 static device default_device()
76 {
77 static device default_device = find_default_device();
78
79 return default_device;
80 }
81
82 /// Returns the device with \p name.
83 ///
84 /// \throws no_device_found if no device with \p name is found.
85 static device find_device(const std::string &name)
86 {
87 const std::vector<device> devices = system::devices();
88 for(size_t i = 0; i < devices.size(); i++){
89 const device& device = devices[i];
90
91 if(device.name() == name){
92 return device;
93 }
94 }
95
96 BOOST_THROW_EXCEPTION(no_device_found());
97 }
98
99 /// Returns a vector containing all of the compute devices on
100 /// the system.
101 ///
102 /// For example, to print out the name of each OpenCL-capable device
103 /// available on the system:
104 /// \code
105 /// for(const auto &device : boost::compute::system::devices()){
106 /// std::cout << device.name() << std::endl;
107 /// }
108 /// \endcode
109 static std::vector<device> devices()
110 {
111 std::vector<device> devices;
112
113 const std::vector<platform> platforms = system::platforms();
114 for(size_t i = 0; i < platforms.size(); i++){
115 const std::vector<device> platform_devices = platforms[i].devices();
116
117 devices.insert(
118 devices.end(), platform_devices.begin(), platform_devices.end()
119 );
120 }
121
122 return devices;
123 }
124
125 /// Returns the number of compute devices on the system.
126 static size_t device_count()
127 {
128 size_t count = 0;
129
130 const std::vector<platform> platforms = system::platforms();
131 for(size_t i = 0; i < platforms.size(); i++){
132 count += platforms[i].device_count();
133 }
134
135 return count;
136 }
137
138 /// Returns the default context for the system.
139 ///
140 /// The default context is created for the default device on the system
141 /// (as returned by default_device()).
142 ///
143 /// The default context is created once on the first time this function is
144 /// called. Calling this function multiple times will always result in the
145 /// same context object being returned.
146 static context default_context()
147 {
148 static context default_context(default_device());
149
150 return default_context;
151 }
152
153 /// Returns the default command queue for the system.
154 static command_queue& default_queue()
155 {
156 static command_queue queue(default_context(), default_device());
157
158 return queue;
159 }
160
161 /// Blocks until all outstanding computations on the default
162 /// command queue are complete.
163 ///
164 /// This is equivalent to:
165 /// \code
166 /// system::default_queue().finish();
167 /// \endcode
168 static void finish()
169 {
170 default_queue().finish();
171 }
172
173 /// Returns a vector containing each of the OpenCL platforms on the system.
174 ///
175 /// For example, to print out the name of each OpenCL platform present on
176 /// the system:
177 /// \code
178 /// for(const auto &platform : boost::compute::system::platforms()){
179 /// std::cout << platform.name() << std::endl;
180 /// }
181 /// \endcode
182 static std::vector<platform> platforms()
183 {
184 cl_uint count = 0;
185 clGetPlatformIDs(0, 0, &count);
186
187 std::vector<platform> platforms;
188 if(count > 0)
189 {
190 std::vector<cl_platform_id> platform_ids(count);
191 clGetPlatformIDs(count, &platform_ids[0], 0);
192
193 for(size_t i = 0; i < platform_ids.size(); i++){
194 platforms.push_back(platform(platform_ids[i]));
195 }
196 }
197 return platforms;
198 }
199
200 /// Returns the number of compute platforms on the system.
201 static size_t platform_count()
202 {
203 cl_uint count = 0;
204 clGetPlatformIDs(0, 0, &count);
205 return static_cast<size_t>(count);
206 }
207
208private:
209 /// \internal_
210 static device find_default_device()
211 {
212 // get a list of all devices on the system
213 const std::vector<device> devices_ = devices();
214 if(devices_.empty()){
215 BOOST_THROW_EXCEPTION(no_device_found());
216 }
217
218 // check for device from environment variable
219 const char *name = detail::getenv("BOOST_COMPUTE_DEFAULT_DEVICE");
220 const char *type = detail::getenv("BOOST_COMPUTE_DEFAULT_DEVICE_TYPE");
221 const char *platform = detail::getenv("BOOST_COMPUTE_DEFAULT_PLATFORM");
222 const char *vendor = detail::getenv("BOOST_COMPUTE_DEFAULT_VENDOR");
223
224 if(name || type || platform || vendor){
225 for(size_t i = 0; i < devices_.size(); i++){
226 const device& device = devices_[i];
227 if (name && !matches(device.name(), name))
228 continue;
229
230 if (type && matches(std::string("GPU"), type))
231 if (!(device.type() & device::gpu))
232 continue;
233
234 if (type && matches(std::string("CPU"), type))
235 if (!(device.type() & device::cpu))
236 continue;
237
238 if (platform && !matches(device.platform().name(), platform))
239 continue;
240
241 if (vendor && !matches(device.vendor(), vendor))
242 continue;
243
244 return device;
245 }
246 }
247
248 // find the first gpu device
249 for(size_t i = 0; i < devices_.size(); i++){
250 const device& device = devices_[i];
251
252 if(device.type() & device::gpu){
253 return device;
254 }
255 }
256
257 // find the first cpu device
258 for(size_t i = 0; i < devices_.size(); i++){
259 const device& device = devices_[i];
260
261 if(device.type() & device::cpu){
262 return device;
263 }
264 }
265
266 // return the first device found
267 return devices_[0];
268 }
269
270 /// \internal_
271 static bool matches(const std::string &str, const std::string &pattern)
272 {
273 return str.find(pattern) != std::string::npos;
274 }
275};
276
277} // end compute namespace
278} // end boost namespace
279
280#endif // BOOST_COMPUTE_SYSTEM_HPP