ViennaCL - The Vienna Computing Library  1.2.0
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-2011, Institute for Microelectronics,
6  Institute for Analysis and Scientific Computing,
7  TU Wien.
8 
9  -----------------
10  ViennaCL - The Vienna Computing Library
11  -----------------
12 
13  Project Head: Karl Rupp rupp@iue.tuwien.ac.at
14 
15  (A list of authors and contributors can be found in the PDF manual)
16 
17  License: MIT (X11), see file LICENSE in the base directory
18 ============================================================================= */
19 
24 #include <vector>
25 #include "viennacl/ocl/context.hpp"
26 #include "viennacl/ocl/enqueue.hpp"
27 
28 namespace viennacl
29 {
30  namespace ocl
31  {
32 
34  template <bool dummy = false> //never use parameter other than default (introduced for linkage issues only)
35  class backend
36  {
37  public:
42  static void switch_context(long i)
43  {
44  current_context_id_ = i;
45  }
46 
49  {
50  if (!initialized_[current_context_id_])
51  {
52  //std::cout << "Initializing context no. " << current_context_id_ << std::endl;
53  contexts_[current_context_id_].init();
54  //create one queue per device:
55  std::vector<viennacl::ocl::device> devices = contexts_[current_context_id_].devices();
56  for (size_t j = 0; j<devices.size(); ++j)
57  contexts_[current_context_id_].add_queue(devices[j]);
58  initialized_[current_context_id_] = true;
59  /*
60  std::cout << "Context no. " << current_context_id_ << " initialized with " << devices.size() << " devices" << std::endl;
61  std::cout << "Device id: " << devices[0].id() << std::endl;
62  std::cout << "Current device id: " << contexts_[current_context_id_].current_device().id() << std::endl; */
63  }
64  return contexts_[current_context_id_];
65  }
66 
69  {
70  return current_context().get_queue();
71  }
72 
78  static void setup_context(long i,
79  std::vector<cl_device_id> const & devices)
80  {
81  if (initialized_[i])
82  std::cerr << "ViennaCL: Warning in init_context(): Providing a list of devices has no effect, because context for ViennaCL is already created!" << std::endl;
83  else
84  {
85  //set devices for context:
86  for (size_t j = 0; j<devices.size(); ++j)
87  contexts_[i].add_device(devices[j]);
88  }
89  }
90 
98  static void setup_context(long i,
99  cl_context c,
100  std::vector<cl_device_id> const & devices,
101  std::map< cl_device_id, std::vector< cl_command_queue > > const & queues)
102  {
103  assert(devices.size() == queues.size() && "ViennaCL expects one queue per device!");
104 
105  if (initialized_[i])
106  std::cerr << "ViennaCL: Warning in init_context(): Providing a list of devices has no effect, because context for ViennaCL is already created!" << std::endl;
107  else
108  {
109  //set devices for context:
110  for (size_t j = 0; j<devices.size(); ++j)
111  contexts_[i].add_device(devices[j]);
112 
113  //init context:
114  contexts_[i].init(c);
115 
116  //add queues:
117  typedef typename std::map< cl_device_id, std::vector< cl_command_queue > >::const_iterator queue_iterator;
118  for (queue_iterator qit = queues.begin();
119  qit != queues.end();
120  ++qit)
121  {
122  std::vector<cl_command_queue> const & queues_for_device = qit->second;
123  for (size_t j=0; j<queues_for_device.size(); ++j)
124  contexts_[i].add_queue(qit->first, queues_for_device[j]);
125  }
126 
127  initialized_[i] = true;
128  }
129  }
130 
138  static void setup_context(long i, cl_context c, std::vector<cl_device_id> const & devices, std::vector<cl_command_queue> const & queue)
139  {
140  assert(devices.size() == queue.size() && "ViennaCL expects one queue per device!");
141 
142  //wrap queue vector into map
143  std::map< cl_device_id, std::vector<cl_command_queue> > queues_map;
144  for (size_t j = 0; j<devices.size(); ++j)
145  queues_map[devices[j]].push_back(queue[j]);
146 
147  setup_context(i, c, devices, queues_map);
148  }
149 
151  static void set_context_device_type(long i, cl_device_type t)
152  {
153  contexts_[i].default_device_type(t);
154  }
155 
156  private:
157  static long current_context_id_;
158  static std::map<long, bool> initialized_;
159  static std::map<long, viennacl::ocl::context> contexts_;
160  };
161 
162  template <bool dummy>
163  long backend<dummy>::current_context_id_ = 0;
164 
165  template <bool dummy>
166  std::map<long, bool> backend<dummy>::initialized_;
167 
168  template <bool dummy>
169  std::map<long, viennacl::ocl::context> backend<dummy>::contexts_;
170 
172 
174  {
176  }
177 
179  inline void switch_context(long i)
180  {
182  }
183 
184 
186  inline void setup_context(long i,
187  std::vector<cl_device_id> const & devices)
188  {
190  }
191 
193  inline void setup_context(long i,
194  cl_context c,
195  std::vector<cl_device_id> const & devices,
196  std::map< cl_device_id, std::vector<cl_command_queue> > const & queues)
197  {
198  viennacl::ocl::backend<>::setup_context(i, c, devices, queues);
199  }
200 
202  inline void setup_context(long i, cl_context c, std::vector<cl_device_id> const & devices, std::vector<cl_command_queue> const & queues)
203  {
204  viennacl::ocl::backend<>::setup_context(i, c, devices, queues);
205  }
206 
208  inline void setup_context(long i, cl_context c, cl_device_id d, cl_command_queue q)
209  {
210  std::vector<cl_device_id> devices(1);
211  std::vector<cl_command_queue> queues(1);
212  devices[0] = d;
213  queues[0] = q;
214  viennacl::ocl::backend<>::setup_context(i, c, devices, queues);
215  }
216 
218  inline void set_context_device_type(long i, cl_device_type dev_type)
219  {
221  }
222 
225  {
226  set_context_device_type(i, CL_DEVICE_TYPE_GPU);
227  }
228 
231  {
232  set_context_device_type(i, CL_DEVICE_TYPE_CPU);
233  }
234 
237  {
238  set_context_device_type(i, CL_DEVICE_TYPE_DEFAULT);
239  }
240 
243  {
244  set_context_device_type(i, CL_DEVICE_TYPE_ACCELERATOR);
245  }
246 
248 
250  {
252  }
253 
255  inline viennacl::ocl::command_queue & get_queue(viennacl::ocl::device d, unsigned int queue_id = 0)
256  {
257  return viennacl::ocl::current_context().get_queue(d.id(), queue_id);
258  }
259 
261  inline viennacl::ocl::command_queue & get_queue(cl_device_id dev_id, unsigned int queue_id = 0)
262  {
263  return viennacl::ocl::current_context().get_queue(dev_id, queue_id);
264  }
265 
266 
268  inline viennacl::ocl::kernel & get_kernel(std::string const & prog_name, std::string const & kernel_name)
269  {
270  return viennacl::ocl::current_context().get_program(prog_name).get_kernel(kernel_name);
271  }
272 
275  {
277  }
278 
281  {
283  }
284 
285  } //ocl
286 } //viennacl
287 #endif