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 
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 
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 
214 {
216 }
217 
219 inline void switch_context(long i)
220 {
222 }
223 
226 {
228 }
229 
231 inline void setup_context(long i,
232  std::vector<cl_device_id> const & devices)
233 {
235 }
236 
238 inline void setup_context(long i,
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 {
275 }
276 
279 {
280  set_context_device_type(i, CL_DEVICE_TYPE_GPU);
281 }
282 
285 {
286  set_context_device_type(i, CL_DEVICE_TYPE_CPU);
287 }
288 
291 {
292  set_context_device_type(i, CL_DEVICE_TYPE_DEFAULT);
293 }
294 
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 {
305 }
306 
307 
313 inline void set_context_platform_index(long i, vcl_size_t pf_index)
314 {
316 }
317 
319 
321 {
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 
346 {
348 }
349 
352 {
354 }
355 
356 } //ocl
357 } //viennacl
358 #endif
A tag identifying OpenCL devices as GPUs.
Definition: forwards.h:35
viennacl::ocl::device const & current_device() const
Returns the current device.
Definition: context.hpp:112
cl_device_id id() const
Returns the OpenCL device id.
Definition: device.hpp:981
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
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
void switch_device(vcl_size_t i)
Switches the current device to the i-th device in this context.
Definition: context.hpp:119
static viennacl::ocl::context & current_context()
Returns the current active context.
Definition: backend.hpp:73
viennacl::ocl::command_queue & get_queue()
Definition: context.hpp:266
Represents an OpenCL kernel within ViennaCL.
Definition: kernel.hpp:58
viennacl::ocl::program & get_program(std::string const &name)
Returns the program with the provided name.
Definition: context.hpp:532
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::context & current_context()
Convenience function for returning the current context.
Definition: backend.hpp:213
Manages an OpenCL context and provides the respective convenience functions for creating buffers...
Definition: context.hpp:55
A tag identifying OpenCL devices as CPUs.
Definition: forwards.h:37
A class representing a compute device (e.g. a GPU)
Definition: device.hpp:49
static void switch_context(long i)
Switches the current context to the context identified by i.
Definition: backend.hpp:43
A class representing a command queue.
viennacl::ocl::device const & current_device()
Convenience function for returning the active device in the current context.
Definition: backend.hpp:351
vcl_size_t program_num()
Returns the number of programs within this context.
Definition: context.hpp:602
static void set_context_platform_index(long i, vcl_size_t pf_index)
Sets the context device type.
Definition: backend.hpp:191
const viennacl::ocl::handle< cl_context > & handle() const
Returns the context handle.
Definition: context.hpp:611
static void add_context(long i, viennacl::ocl::context &c)
Add an existing context object to the backend.
Definition: backend.hpp:168
void switch_device(viennacl::ocl::device &d)
Convenience function for switching the active device in the current context.
Definition: backend.hpp:345
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::command_queue & get_queue()
Convenience function for getting the default queue for the currently active device in the active cont...
Definition: backend.hpp:320
A tag identifying OpenCL devices as accelerators (e.g. Intel Xeon Phi)
Definition: forwards.h:39
A backend that provides contexts for ViennaCL objects (vector, matrix, etc.)
Definition: backend.hpp:36
std::size_t vcl_size_t
Definition: forwards.h:75
Represents an OpenCL context within ViennaCL.
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
static viennacl::ocl::context & context(long id)
Returns the current active context.
Definition: backend.hpp:49
void switch_context(long i)
Convenience function for switching the current context.
Definition: backend.hpp:219
static viennacl::ocl::command_queue & get_queue()
Returns the current queue for the active device in the active context.
Definition: backend.hpp:85
Enqueues kernels into command queues.
viennacl::ocl::kernel & get_kernel(std::string const &name)
Returns the kernel with the provided name.
Definition: context.hpp:773
void set_context_platform_index(long i, vcl_size_t pf_index)
Convenience function for setting the platform index.
Definition: backend.hpp:313
A tag denoting the default OpenCL device type (SDK-specific)
Definition: forwards.h:41
static void set_context_device_type(long i, cl_device_type t)
Sets the context device type.
Definition: backend.hpp:179
viennacl::ocl::context & get_context(long i)
Convenience function for returning the current context.
Definition: backend.hpp:225
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
void setup_context(long i, std::vector< cl_device_id > const &devices)
Convenience function for setting devices for a context.
Definition: backend.hpp:231
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