ViennaCL - The Vienna Computing Library: viennacl/ocl/backend.hpp Source File

ViennaCL - The Vienna Computing Library 1.7.1 Free open-source GPU-accelerated linear algebra and solver library. |

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
backend.hpp
Go to the documentation of this file.
1 #ifndef VIENNACL_OCL_BACKEND_HPP_
2 #define VIENNACL_OCL_BACKEND_HPP_
3
4 /* =========================================================================
5 Copyright (c) 2010-2016, Institute for Microelectronics,
6 Institute for Analysis and Scientific Computing,
7 TU Wien.
8 Portions of this software are copyright by UChicago Argonne, LLC.
9
10 -----------------
11 ViennaCL - The Vienna Computing Library
12 -----------------
13
14 Project Head: Karl Rupp rupp@iue.tuwien.ac.at
15
16 (A list of authors and contributors can be found in the manual)
17
18 License: MIT (X11), see file LICENSE in the base directory
19 ============================================================================= */
20
25 #include <vector>
26 #include "viennacl/ocl/context.hpp"
27 #include "viennacl/ocl/enqueue.hpp"
28
29 namespace viennacl
30 {
31 namespace ocl
32 {
33
35 template<bool dummy = false> //never use parameter other than default (introduced for linkage issues only)
36 class backend
37 {
38 public:
43 static void switch_context(long i)
44 {
45 current_context_id_ = i;
46 }
47
49 static viennacl::ocl::context & context(long id)
50 {
51 if (!initialized_[id])
52 {
53 #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT)
54 std::cout << "ViennaCL: Initializing context no. " << id << std::endl;
55 #endif
56
57 contexts_[id].init();
58 //create one queue per device:
59 std::vector<viennacl::ocl::device> devices = contexts_[id].devices();
60 for (vcl_size_t j = 0; j<devices.size(); ++j)
61 contexts_[id].add_queue(devices[j]);
62 initialized_[id] = true;
63
64 #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT)
65 std::cout << "ViennaCL: Context no. " << id << " initialized with " << devices.size() << " devices" << std::endl;
66 std::cout << "ViennaCL: Device id: " << devices[0].id() << std::endl;
67 #endif
68 }
69 return contexts_[id];
70 }
71
73 static viennacl::ocl::context & current_context()
74 {
75 #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT)
76 std::cout << "ViennaCL: Getting current_context with id " << current_context_id_ << std::endl;
77 #endif
78 #if defined(VIENNACL_NO_CURRENT_CONTEXT)
79 assert(false && bool("ViennaCL: current_context called when disabled"));
80 #endif
81 return backend<dummy>::context(current_context_id_);
82 }
83
85 static viennacl::ocl::command_queue & get_queue()
86 {
87 return current_context().get_queue();
88 }
89
95 static void setup_context(long i,
96 std::vector<cl_device_id> const & devices)
97 {
98 if (initialized_[i])
99 std::cerr << "ViennaCL: Warning in init_context(): Providing a list of devices has no effect, because context for ViennaCL is already created!" << std::endl;
100 else
101 {
102 //set devices for context:
103 for (vcl_size_t j = 0; j<devices.size(); ++j)
104 contexts_[i].add_device(devices[j]);
105 }
106 }
107
115 static void setup_context(long i,
116 cl_context c,
117 std::vector<cl_device_id> const & devices,
118 std::map< cl_device_id, std::vector< cl_command_queue > > const & queues)
119 {
120 assert(devices.size() == queues.size() && bool("ViennaCL expects one queue per device!"));
121
122 if (initialized_[i])
123 std::cerr << "ViennaCL: Warning in init_context(): Providing a list of devices has no effect, because context for ViennaCL is already created!" << std::endl;
124 else
125 {
126 //set devices for context:
127 for (vcl_size_t j = 0; j<devices.size(); ++j)
128 contexts_[i].add_device(devices[j]);
129
130 //init context:
131 contexts_[i].init(c);
132
133 //add queues:
134 typedef typename std::map< cl_device_id, std::vector< cl_command_queue > >::const_iterator queue_iterator;
135 for (queue_iterator qit = queues.begin();
136 qit != queues.end();
137 ++qit)
138 {
139 std::vector<cl_command_queue> const & queues_for_device = qit->second;
140 for (vcl_size_t j=0; j<queues_for_device.size(); ++j)
141 contexts_[i].add_queue(qit->first, queues_for_device[j]);
142 }
143
144 initialized_[i] = true;
145 }
146 }
147
155 static void setup_context(long i, cl_context c, std::vector<cl_device_id> const & devices, std::vector<cl_command_queue> const & queue)
156 {
157 assert(devices.size() == queue.size() && bool("ViennaCL expects one queue per device!"));
158
159 //wrap queue vector into map
160 std::map< cl_device_id, std::vector<cl_command_queue> > queues_map;
161 for (vcl_size_t j = 0; j<devices.size(); ++j)
162 queues_map[devices[j]].push_back(queue[j]);
163
164 setup_context(i, c, devices, queues_map);
165 }
166
168 static void add_context(long i, viennacl::ocl::context& c)
169 {
170 #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT)
171 std::cout << "ViennaCL: Adding context '" << c.handle() << "' as id " << i << std::endl;
172 std::cout << "ViennaCL: There are " << c.program_num() << " programs" << std::endl;
173 #endif
174 contexts_[i] = c;
175 initialized_[i] = true;
176 }
177
179 static void set_context_device_type(long i, cl_device_type t)
180 {
181 contexts_[i].default_device_type(t);
182 }
183
185 static void set_context_device_num(long i, vcl_size_t num)
186 {
187 contexts_[i].default_device_num(num);
188 }
189
191 static void set_context_platform_index(long i, vcl_size_t pf_index)
192 {
193 contexts_[i].platform_index(pf_index);
194 }
195
196 private:
197 static long current_context_id_;
198 static std::map<long, bool> initialized_;
199 static std::map<long, viennacl::ocl::context> contexts_;
200 };
201
202 template<bool dummy>
203 long backend<dummy>::current_context_id_ = 0;
204
205 template<bool dummy>
206 std::map<long, bool> backend<dummy>::initialized_;
207
208 template<bool dummy>
209 std::map<long, viennacl::ocl::context> backend<dummy>::contexts_;
210
212
213 inline viennacl::ocl::context & current_context()
214 {
215 return viennacl::ocl::backend<>::current_context();
216 }
217
219 inline void switch_context(long i)
220 {
221 viennacl::ocl::backend<>::switch_context(i);
222 }
223
225 inline viennacl::ocl::context & get_context(long i)
226 {
227 return viennacl::ocl::backend<>::context(i);
228 }
229
231 inline void setup_context(long i,
232 std::vector<cl_device_id> const & devices)
233 {
234 viennacl::ocl::backend<>::setup_context(i, devices);
235 }
236
238 inline void setup_context(long i,
239 viennacl::ocl::device const & device)
240 {
241 std::vector<cl_device_id> device_id_array(1);
242 device_id_array[0] = device.id();
243 viennacl::ocl::backend<>::setup_context(i, device_id_array);
244 }
245
247 inline void setup_context(long i,
248 cl_context c,
249 std::vector<cl_device_id> const & devices,
250 std::map< cl_device_id, std::vector<cl_command_queue> > const & queues)
251 {
252 viennacl::ocl::backend<>::setup_context(i, c, devices, queues);
253 }
254
256 inline void setup_context(long i, cl_context c, std::vector<cl_device_id> const & devices, std::vector<cl_command_queue> const & queues)
257 {
258 viennacl::ocl::backend<>::setup_context(i, c, devices, queues);
259 }
260
262 inline void setup_context(long i, cl_context c, cl_device_id d, cl_command_queue q)
263 {
264 std::vector<cl_device_id> devices(1);
265 std::vector<cl_command_queue> queues(1);
266 devices[0] = d;
267 queues[0] = q;
268 viennacl::ocl::backend<>::setup_context(i, c, devices, queues);
269 }
270
272 inline void set_context_device_type(long i, cl_device_type dev_type)
273 {
274 viennacl::ocl::backend<>::set_context_device_type(i, dev_type);
275 }
276
278 inline void set_context_device_type(long i, viennacl::ocl::gpu_tag)
279 {
280 set_context_device_type(i, CL_DEVICE_TYPE_GPU);
281 }
282
284 inline void set_context_device_type(long i, viennacl::ocl::cpu_tag)
285 {
286 set_context_device_type(i, CL_DEVICE_TYPE_CPU);
287 }
288
290 inline void set_context_device_type(long i, viennacl::ocl::default_tag)
291 {
292 set_context_device_type(i, CL_DEVICE_TYPE_DEFAULT);
293 }
294
296 inline void set_context_device_type(long i, viennacl::ocl::accelerator_tag)
297 {
298 set_context_device_type(i, CL_DEVICE_TYPE_ACCELERATOR);
299 }
300
302 inline void set_context_device_num(long i, vcl_size_t num)
303 {
304 viennacl::ocl::backend<>::set_context_device_num(i, num);
305 }
306
307
313 inline void set_context_platform_index(long i, vcl_size_t pf_index)
314 {
315 viennacl::ocl::backend<>::set_context_platform_index(i, pf_index);
316 }
317
319
320 inline viennacl::ocl::command_queue & get_queue()
321 {
322 return viennacl::ocl::current_context().get_queue();
323 }
324
326 inline viennacl::ocl::command_queue & get_queue(viennacl::ocl::device d, unsigned int queue_id = 0)
327 {
328 return viennacl::ocl::current_context().get_queue(d.id(), queue_id);
329 }
330
332 inline viennacl::ocl::command_queue & get_queue(cl_device_id dev_id, unsigned int queue_id = 0)
333 {
334 return viennacl::ocl::current_context().get_queue(dev_id, queue_id);
335 }
336
337
339 inline viennacl::ocl::kernel & get_kernel(std::string const & prog_name, std::string const & kernel_name)
340 {
341 return viennacl::ocl::current_context().get_program(prog_name).get_kernel(kernel_name);
342 }
343
345 inline void switch_device(viennacl::ocl::device & d)
346 {
347 viennacl::ocl::current_context().switch_device(d);
348 }
349
351 inline viennacl::ocl::device const & current_device()
352 {
353 return viennacl::ocl::current_context().current_device();
354 }
355
356 } //ocl
357 } //viennacl
358 #endif
viennacl::ocl::gpu_tag
A tag identifying OpenCL devices as GPUs.
Definition: forwards.h:35
viennacl::ocl::context::current_device
viennacl::ocl::device const & current_device() const
Returns the current device.
Definition: context.hpp:112
viennacl::ocl::device::id
cl_device_id id() const
Returns the OpenCL device id.
Definition: device.hpp:981
viennacl::ocl::get_kernel
viennacl::ocl::kernel & get_kernel(std::string const &prog_name, std::string const &kernel_name)
Convenience function for getting the kernel for a particular program from the current active context...
Definition: backend.hpp:339
viennacl::ocl::backend::setup_context
static void setup_context(long i, cl_context c, std::vector< cl_device_id > const &devices, std::vector< cl_command_queue > const &queue)
Initializes ViennaCL with an already existing context.
Definition: backend.hpp:155
viennacl::ocl::context::switch_device
void switch_device(vcl_size_t i)
Switches the current device to the i-th device in this context.
Definition: context.hpp:119
viennacl::ocl::backend::current_context
static viennacl::ocl::context & current_context()
Returns the current active context.
Definition: backend.hpp:73
viennacl::ocl::context::get_queue
viennacl::ocl::command_queue & get_queue()
Definition: context.hpp:266
viennacl::ocl::kernel
Represents an OpenCL kernel within ViennaCL.
Definition: kernel.hpp:58
viennacl::ocl::context::get_program
viennacl::ocl::program & get_program(std::string const &name)
Returns the program with the provided name.
Definition: context.hpp:532
viennacl::ocl::backend::set_context_device_num
static void set_context_device_num(long i, vcl_size_t num)
Sets the maximum number of devices per context. Ignored if a device array is provided as well...
Definition: backend.hpp:185
viennacl::ocl::current_context
viennacl::ocl::context & current_context()
Convenience function for returning the current context.
Definition: backend.hpp:213
viennacl::ocl::context
Manages an OpenCL context and provides the respective convenience functions for creating buffers...
Definition: context.hpp:55
viennacl::ocl::cpu_tag
A tag identifying OpenCL devices as CPUs.
Definition: forwards.h:37
viennacl::ocl::device
A class representing a compute device (e.g. a GPU)
Definition: device.hpp:49
viennacl::ocl::backend::switch_context
static void switch_context(long i)
Switches the current context to the context identified by i.
Definition: backend.hpp:43
viennacl::ocl::command_queue
A class representing a command queue.
Definition: command_queue.hpp:45
viennacl::ocl::current_device
viennacl::ocl::device const & current_device()
Convenience function for returning the active device in the current context.
Definition: backend.hpp:351
viennacl::ocl::context::program_num
vcl_size_t program_num()
Returns the number of programs within this context.
Definition: context.hpp:602
viennacl::ocl::backend::set_context_platform_index
static void set_context_platform_index(long i, vcl_size_t pf_index)
Sets the context device type.
Definition: backend.hpp:191
viennacl::ocl::context::handle
const viennacl::ocl::handle< cl_context > & handle() const
Returns the context handle.
Definition: context.hpp:611
viennacl::ocl::backend::add_context
static void add_context(long i, viennacl::ocl::context &c)
Add an existing context object to the backend.
Definition: backend.hpp:168
viennacl::ocl::switch_device
void switch_device(viennacl::ocl::device &d)
Convenience function for switching the active device in the current context.
Definition: backend.hpp:345
viennacl::ocl::backend::setup_context
static void setup_context(long i, std::vector< cl_device_id > const &devices)
Sets a number of devices for the context.
Definition: backend.hpp:95
viennacl::ocl::get_queue
viennacl::ocl::command_queue & get_queue()
Convenience function for getting the default queue for the currently active device in the active cont...
Definition: backend.hpp:320
viennacl::ocl::accelerator_tag
A tag identifying OpenCL devices as accelerators (e.g. Intel Xeon Phi)
Definition: forwards.h:39
viennacl::ocl::backend
A backend that provides contexts for ViennaCL objects (vector, matrix, etc.)
Definition: backend.hpp:36
viennacl::vcl_size_t
std::size_t vcl_size_t
Definition: forwards.h:75
context.hpp
Represents an OpenCL context within ViennaCL.
viennacl::ocl::backend::setup_context
static void setup_context(long i, cl_context c, std::vector< cl_device_id > const &devices, std::map< cl_device_id, std::vector< cl_command_queue > > const &queues)
Initializes ViennaCL with an already existing context.
Definition: backend.hpp:115
viennacl::ocl::backend::context
static viennacl::ocl::context & context(long id)
Returns the current active context.
Definition: backend.hpp:49
viennacl::ocl::switch_context
void switch_context(long i)
Convenience function for switching the current context.
Definition: backend.hpp:219
viennacl::ocl::backend::get_queue
static viennacl::ocl::command_queue & get_queue()
Returns the current queue for the active device in the active context.
Definition: backend.hpp:85
enqueue.hpp
Enqueues kernels into command queues.
viennacl::ocl::program::get_kernel
viennacl::ocl::kernel & get_kernel(std::string const &name)
Returns the kernel with the provided name.
Definition: context.hpp:773
viennacl::ocl::set_context_platform_index
void set_context_platform_index(long i, vcl_size_t pf_index)
Convenience function for setting the platform index.
Definition: backend.hpp:313
viennacl::ocl::default_tag
A tag denoting the default OpenCL device type (SDK-specific)
Definition: forwards.h:41
viennacl::ocl::backend::set_context_device_type
static void set_context_device_type(long i, cl_device_type t)
Sets the context device type.
Definition: backend.hpp:179
viennacl::ocl::get_context
viennacl::ocl::context & get_context(long i)
Convenience function for returning the current context.
Definition: backend.hpp:225
viennacl::ocl::set_context_device_type
void set_context_device_type(long i, cl_device_type dev_type)
Convenience function for setting the default device type for a context.
Definition: backend.hpp:272
viennacl::ocl::setup_context
void setup_context(long i, std::vector< cl_device_id > const &devices)
Convenience function for setting devices for a context.
Definition: backend.hpp:231
viennacl::ocl::set_context_device_num
void set_context_device_num(long i, vcl_size_t num)
Convenience function for setting the number of default devices per context.
Definition: backend.hpp:302