ViennaCL - The Vienna Computing Library  1.5.2
context.hpp
Go to the documentation of this file.
1 #ifndef VIENNACL_OCL_CONTEXT_HPP_
2 #define VIENNACL_OCL_CONTEXT_HPP_
3 
4 /* =========================================================================
5  Copyright (c) 2010-2014, 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 PDF manual)
17 
18  License: MIT (X11), see file LICENSE in the base directory
19 ============================================================================= */
20 
25 #ifdef __APPLE__
26 #include <OpenCL/cl.h>
27 #else
28 #include <CL/cl.h>
29 #endif
30 
31 #include <algorithm>
32 #include <vector>
33 #include <map>
34 #include "viennacl/ocl/forwards.h"
35 #include "viennacl/ocl/handle.hpp"
36 #include "viennacl/ocl/kernel.hpp"
37 #include "viennacl/ocl/program.hpp"
38 #include "viennacl/ocl/device.hpp"
41 
42 namespace viennacl
43 {
44  namespace ocl
45  {
51  class context
52  {
53  typedef std::vector< viennacl::ocl::program > ProgramContainer;
54 
55  public:
56  context() : initialized_(false),
57  device_type_(CL_DEVICE_TYPE_DEFAULT),
58  current_device_id_(0),
59  default_device_num_(1),
60  pf_index_(0),
61  current_queue_id_(0) {}
62 
64 
65  vcl_size_t default_device_num() const { return default_device_num_; }
66 
68  void default_device_num(vcl_size_t new_num) { default_device_num_ = new_num; }
69 
71 
72  cl_device_type default_device_type()
73  {
74  return device_type_;
75  }
76 
78  void default_device_type(cl_device_type dtype)
79  {
80  #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT)
81  std::cout << "ViennaCL: Setting new device type for context " << h_ << std::endl;
82  #endif
83  if (!initialized_)
84  device_type_ = dtype; //assume that the user provided a correct value
85  }
86 
88 
89  std::vector<viennacl::ocl::device> const & devices() const
90  {
91  return devices_;
92  }
93 
96  {
97  //std::cout << "Current device id in context: " << current_device_id_ << std::endl;
98  return devices_[current_device_id_];
99  }
100 
103  {
104  assert(i < devices_.size() && bool("Provided device index out of range!"));
105  current_device_id_ = i;
106  }
107 
110  {
111  #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT)
112  std::cout << "ViennaCL: Setting new current device for context " << h_ << std::endl;
113  #endif
114  bool found = false;
115  for (vcl_size_t i=0; i<devices_.size(); ++i)
116  {
117  if (devices_[i] == d)
118  {
119  found = true;
120  current_device_id_ = i;
121  break;
122  }
123  }
124  if (found == false)
125  std::cerr << "ViennaCL: Warning: Could not set device " << d.name() << " for context." << std::endl;
126  }
127 
130  {
131  assert(!initialized_ && bool("Device must be added to context before it is initialized!"));
132  #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT)
133  std::cout << "ViennaCL: Adding new device to context " << h_ << std::endl;
134  #endif
135  if (std::find(devices_.begin(), devices_.end(), d) == devices_.end())
136  devices_.push_back(d);
137  }
138 
140  void add_device(cl_device_id d)
141  {
142  assert(!initialized_ && bool("Device must be added to context before it is initialized!"));
144  }
145 
146 
148 
150  void init()
151  {
152  init_new();
153  }
154 
156  void init(cl_context c)
157  {
158  init_existing(c);
159  }
160 
161 /* void existing_context(cl_context context_id)
162  {
163  assert(!initialized_ && bool("ViennaCL: FATAL error: Provided a new context for an already initialized context."));
164  #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT)
165  std::cout << "ViennaCL: Reusing existing context " << h_ << std::endl;
166  #endif
167  h_ = context_id;
168  }*/
169 
171 
179  cl_mem create_memory_without_smart_handle(cl_mem_flags flags, unsigned int size, void * ptr = NULL) const
180  {
181  #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT)
182  std::cout << "ViennaCL: Creating memory of size " << size << " for context " << h_ << " (unsafe, returning cl_mem directly)" << std::endl;
183  #endif
184  if (ptr)
185  flags |= CL_MEM_COPY_HOST_PTR;
186  cl_int err;
187  cl_mem mem = clCreateBuffer(h_.get(), flags, size, ptr, &err);
188  VIENNACL_ERR_CHECK(err);
189  return mem;
190  }
191 
192 
199  viennacl::ocl::handle<cl_mem> create_memory(cl_mem_flags flags, unsigned int size, void * ptr = NULL) const
200  {
201  return viennacl::ocl::handle<cl_mem>(create_memory_without_smart_handle(flags, size, ptr), *this);
202  }
203 
209  template < typename SCALARTYPE, typename A, template <typename, typename> class VectorType >
210  viennacl::ocl::handle<cl_mem> create_memory(cl_mem_flags flags, const VectorType<SCALARTYPE, A> & buffer) const
211  {
212  return viennacl::ocl::handle<cl_mem>(create_memory_without_smart_handle(flags, static_cast<cl_uint>(sizeof(SCALARTYPE) * buffer.size()), (void*)&buffer[0]), *this);
213  }
214 
216 
218  void add_queue(cl_device_id dev, cl_command_queue q)
219  {
220  #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT)
221  std::cout << "ViennaCL: Adding existing queue " << q << " for device " << dev << " to context " << h_ << std::endl;
222  #endif
223  viennacl::ocl::handle<cl_command_queue> queue_handle(q, *this);
224  queues_[dev].push_back(viennacl::ocl::command_queue(queue_handle));
225  queues_[dev].back().handle().inc();
226  }
227 
229  void add_queue(cl_device_id dev)
230  {
231  #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT)
232  std::cout << "ViennaCL: Adding new queue for device " << dev << " to context " << h_ << std::endl;
233  #endif
234  cl_int err;
235 #ifdef VIENNACL_PROFILING_ENABLED
236  viennacl::ocl::handle<cl_command_queue> temp(clCreateCommandQueue(h_.get(), dev, CL_QUEUE_PROFILING_ENABLE, &err), *this);
237 #else
238  viennacl::ocl::handle<cl_command_queue> temp(clCreateCommandQueue(h_.get(), dev, 0, &err), *this);
239 #endif
240  VIENNACL_ERR_CHECK(err);
241 
242  queues_[dev].push_back(viennacl::ocl::command_queue(temp));
243  }
244 
247 
248  //get queue for default device:
250  {
251  return queues_[devices_[current_device_id_].id()][current_queue_id_];
252  }
253 
255  {
256  typedef std::map< cl_device_id, std::vector<viennacl::ocl::command_queue> > QueueContainer;
257 
258  // find queue:
259  QueueContainer::const_iterator it = queues_.find(devices_[current_device_id_].id());
260  if (it != queues_.end())
261  return (it->second)[current_queue_id_];
262 
263  std::cerr << "ViennaCL: FATAL ERROR: Could not obtain current command queue!" << std::endl;
264  std::cout << "Number of queues in context: " << queues_.size() << std::endl;
265  std::cout << "Number of devices in context: " << devices_.size() << std::endl;
266  throw "queue not found!";
267 
268  //return (it->second)[current_queue_id_];
269  }
270 
271  //get a particular queue:
274  {
275  assert(i < queues_.size() && bool("In class 'context': id invalid in get_queue()"));
276  #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT)
277  std::cout << "ViennaCL: Getting queue " << i << " for device " << dev << " in context " << h_ << std::endl;
278  #endif
279  unsigned int device_index;
280  for (device_index = 0; device_index < devices_.size(); ++device_index)
281  {
282  if (devices_[device_index] == dev)
283  break;
284  }
285 
286  assert(device_index < devices_.size() && bool("Device not within context"));
287 
288  return queues_[devices_[device_index].id()][i];
289  }
290 
292  // TODO: work out the const issues
294  {
295  return queues_[devices_[current_device_id_].id()][current_queue_id_];
296  }
297 
300  {
301  assert(i < queues_[devices_[current_device_id_].id()].size() && bool("In class 'context': Provided queue index out of range for device!"));
302  current_queue_id_ = i;
303  }
304 
305 #if 1
306 
308  {
309  #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT)
310  std::cout << "ViennaCL: Setting new current queue for context " << h_ << std::endl;
311  #endif
312  bool found = false;
313  typedef std::map< cl_device_id, std::vector<viennacl::ocl::command_queue> > QueueContainer;
314 
315  // For each device:
316  vcl_size_t j = 0;
317  for (QueueContainer::const_iterator it=queues_.begin(); it != queues_.end(); it++,j++)
318  {
319  const std::vector<viennacl::ocl::command_queue> & qv = (it->second);
320  // For each queue candidate
321  for (vcl_size_t i=0; i<qv.size(); ++i)
322  {
323  if (qv[i] == q)
324  {
325  found = true;
326  current_device_id_ = j;
327  current_queue_id_ = i;
328  break;
329  }
330  }
331  }
332  if (found == false)
333  std::cerr << "ViennaCL: Warning: Could not set queue " << q.handle().get() << " for context." << std::endl;
334  }
335 #endif
336 
338 
340  viennacl::ocl::program & add_program(cl_program p, std::string const & prog_name)
341  {
342  programs_.push_back(viennacl::ocl::program(p, *this, prog_name));
343  return programs_.back();
344  }
345 
348  viennacl::ocl::program & add_program(std::string const & source, std::string const & prog_name)
349  {
350  const char * source_text = source.c_str();
351  vcl_size_t source_size = source.size();
352  cl_int err;
353 
354  #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT)
355  std::cout << "ViennaCL: Adding program '" << prog_name << "' to context " << h_ << std::endl;
356  #endif
357 
358  //
359  // Build program
360  //
361  cl_program temp = clCreateProgramWithSource(h_.get(), 1, (const char **)&source_text, &source_size, &err);
362  VIENNACL_ERR_CHECK(err);
363 
364  const char * options = build_options_.c_str();
365  err = clBuildProgram(temp, 0, NULL, options, NULL, NULL);
366  if (err != CL_SUCCESS)
367  {
368  char buffer[8192];
369  cl_build_status status;
370  clGetProgramBuildInfo(temp, devices_[0].id(), CL_PROGRAM_BUILD_STATUS, sizeof(cl_build_status), &status, NULL);
371  clGetProgramBuildInfo(temp, devices_[0].id(), CL_PROGRAM_BUILD_LOG, sizeof(char)*8192, &buffer, NULL);
372  std::cout << "Build Scalar: Err = " << err << " Status = " << status << std::endl;
373  std::cout << "Log: " << buffer << std::endl;
374  std::cout << "Sources: " << source << std::endl;
375  }
376  VIENNACL_ERR_CHECK(err);
377 
378  programs_.push_back(viennacl::ocl::program(temp, *this, prog_name));
379 
380  viennacl::ocl::program & prog = programs_.back();
381 
382  //
383  // Extract kernels
384  //
385  cl_kernel kernels[1024];
386  cl_uint num_kernels_in_prog;
387  err = clCreateKernelsInProgram(prog.handle().get(), 1024, kernels, &num_kernels_in_prog);
388  VIENNACL_ERR_CHECK(err);
389 
390  for (cl_uint i=0; i<num_kernels_in_prog; ++i)
391  {
392  char kernel_name[128];
393  err = clGetKernelInfo(kernels[i], CL_KERNEL_FUNCTION_NAME, 128, kernel_name, NULL);
394  prog.add_kernel(kernels[i], std::string(kernel_name));
395  }
396 
397  return prog;
398  }
399 
401  void delete_program(std::string const & name){
402  for (ProgramContainer::iterator it = programs_.begin();
403  it != programs_.end();
404  ++it)
405  {
406  if (it->name() == name){
407  programs_.erase(it);
408  return;
409  }
410  }
411  }
412 
414  viennacl::ocl::program & get_program(std::string const & name)
415  {
416  #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT)
417  std::cout << "ViennaCL: Getting program '" << name << "' from context " << h_ << std::endl;
418  #endif
419  for (ProgramContainer::iterator it = programs_.begin();
420  it != programs_.end();
421  ++it)
422  {
423  if (it->name() == name)
424  return *it;
425  }
426  std::cerr << "Could not find program '" << name << "'" << std::endl;
427  throw "In class 'context': name invalid in get_program()";
428  //return programs_[0]; //return a defined object
429  }
430 
431  viennacl::ocl::program const & get_program(std::string const & name) const
432  {
433  #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT)
434  std::cout << "ViennaCL: Getting program '" << name << "' from context " << h_ << std::endl;
435  #endif
436  for (ProgramContainer::const_iterator it = programs_.begin();
437  it != programs_.end();
438  ++it)
439  {
440  if (it->name() == name)
441  return *it;
442  }
443  std::cerr << "Could not find program '" << name << "'" << std::endl;
444  throw "In class 'context': name invalid in get_program()";
445  //return programs_[0]; //return a defined object
446  }
447 
449  bool has_program(std::string const & name){
450  for (ProgramContainer::iterator it = programs_.begin();
451  it != programs_.end();
452  ++it)
453  {
454  if (it->name() == name) return true;
455  }
456  return false;
457  }
458 
461  {
462  assert(id < programs_.size() && bool("In class 'context': id invalid in get_program()"));
463  return programs_[id];
464  }
465 
467  vcl_size_t program_num() { return programs_.size(); }
468 
470  viennacl::ocl::kernel & get_kernel(std::string const & program_name, std::string const & kernel_name) { return get_program(program_name).get_kernel(kernel_name); }
471 
473  vcl_size_t device_num() { return devices_.size(); }
474 
476  const viennacl::ocl::handle<cl_context> & handle() const { return h_; }
477 
479  std::string build_options() const { return build_options_; }
480 
482  void build_options(std::string op) { build_options_ = op; }
483 
485  vcl_size_t platform_index() const { return pf_index_; }
486 
488  void platform_index(vcl_size_t new_index)
489  {
490  assert(!initialized_ && bool("Platform ID must be set before context is initialized!"));
491  pf_index_ = new_index;
492  }
493 
495  bool operator<(context const & other) const
496  {
497  return h_.get() < other.h_.get();
498  }
499 
500  bool operator==(context const & other) const
501  {
502  return h_.get() == other.h_.get();
503  }
504 
505  private:
507  void init_new()
508  {
509  assert(!initialized_ && bool("ViennaCL FATAL error: Context already created!"));
510 
511  #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT)
512  std::cout << "ViennaCL: Initializing new ViennaCL context." << std::endl;
513  #endif
514 
515  cl_int err;
516  std::vector<cl_device_id> device_id_array;
517  if (devices_.empty()) //get the default device if user has not yet specified a list of devices
518  {
519  //create an OpenCL context for the provided devices:
520  #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT)
521  std::cout << "ViennaCL: Setting all devices for context..." << std::endl;
522  #endif
523 
524  platform pf(pf_index_);
525  std::vector<device> devices = pf.devices(device_type_);
526  #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT)
527  std::cout << "ViennaCL: Number of devices for context: " << devices.size() << std::endl;
528  #endif
529  vcl_size_t device_num = std::min<vcl_size_t>(default_device_num_, devices.size());
530  for (vcl_size_t i=0; i<device_num; ++i)
531  devices_.push_back(devices[i]);
532 
533  if (devices.size() == 0)
534  {
535  std::cerr << "ViennaCL: FATAL ERROR: No devices of type '";
536  switch (device_type_)
537  {
538  case CL_DEVICE_TYPE_CPU: std::cout << "CPU"; break;
539  case CL_DEVICE_TYPE_GPU: std::cout << "GPU"; break;
540  case CL_DEVICE_TYPE_ACCELERATOR: std::cout << "ACCELERATOR"; break;
541  case CL_DEVICE_TYPE_DEFAULT: std::cout << "DEFAULT"; break;
542  default:
543  std::cout << "UNKNOWN" << std::endl;
544  }
545  std::cout << "' found!" << std::endl;
546  }
547  }
548 
549  //extract list of device ids:
550  for (std::vector< viennacl::ocl::device >::const_iterator iter = devices_.begin();
551  iter != devices_.end();
552  ++iter)
553  device_id_array.push_back(iter->id());
554 
555  h_ = clCreateContext(0,
556  static_cast<cl_uint>(devices_.size()),
557  &(device_id_array[0]),
558  NULL, NULL, &err);
559  VIENNACL_ERR_CHECK(err);
560 
561  initialized_ = true;
562  #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT)
563  std::cout << "ViennaCL: Initialization of new ViennaCL context done." << std::endl;
564  #endif
565  }
566 
568  void init_existing(cl_context c)
569  {
570  assert(!initialized_ && bool("ViennaCL FATAL error: Context already created!"));
571  #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT)
572  std::cout << "ViennaCL: Initialization of ViennaCL context from existing context." << std::endl;
573  #endif
574 
575  //set context handle:
576  h_ = c;
577  h_.inc(); // if the user provides the context, then the user will also call release() on the context. Without inc(), we would get a seg-fault due to double-free at program termination.
578 
579  if (devices_.empty())
580  {
581  //get devices for context:
582  cl_int err;
583  cl_uint num_devices;
584  vcl_size_t temp;
585  //Note: The obvious
586  // err = clGetContextInfo(h_, CL_CONTEXT_NUM_DEVICES, sizeof(cl_uint), &num_devices, NULL);
587  //does not work with NVIDIA OpenCL stack!
588  err = clGetContextInfo(h_.get(), CL_CONTEXT_DEVICES, VIENNACL_OCL_MAX_DEVICE_NUM * sizeof(cl_device_id), NULL, &temp);
589  VIENNACL_ERR_CHECK(err);
590  assert(temp > 0 && bool("ViennaCL: FATAL error: Provided context does not contain any devices!"));
591  num_devices = static_cast<cl_uint>(temp / sizeof(cl_device_id));
592 
593  #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT)
594  std::cout << "ViennaCL: Reusing context with " << num_devices << " devices." << std::endl;
595  #endif
596 
597  std::vector<cl_device_id> device_ids(num_devices);
598  err = clGetContextInfo(h_.get(), CL_CONTEXT_DEVICES, num_devices * sizeof(cl_device_id), &(device_ids[0]), NULL);
599  VIENNACL_ERR_CHECK(err);
600 
601  for (vcl_size_t i=0; i<num_devices; ++i)
602  devices_.push_back(viennacl::ocl::device(device_ids[i]));
603  }
604  current_device_id_ = 0;
605 
606  initialized_ = true;
607  #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT)
608  std::cout << "ViennaCL: Initialization of ViennaCL context from existing context done." << std::endl;
609  #endif
610  }
611 
612 
613  bool initialized_;
614  cl_device_type device_type_;
616  std::vector< viennacl::ocl::device > devices_;
617  vcl_size_t current_device_id_;
618  vcl_size_t default_device_num_;
619  ProgramContainer programs_;
620  std::map< cl_device_id, std::vector< viennacl::ocl::command_queue> > queues_;
621  std::string build_options_;
622  vcl_size_t pf_index_;
623  vcl_size_t current_queue_id_;
624  }; //context
625 
626 
627 
629  inline viennacl::ocl::kernel & viennacl::ocl::program::add_kernel(cl_kernel kernel_handle, std::string const & kernel_name)
630  {
631  assert(p_context_ != NULL && bool("Pointer to context invalid in viennacl::ocl::program object"));
632  viennacl::ocl::kernel temp(kernel_handle, *this, *p_context_, kernel_name);
633  kernels_.push_back(temp);
634  return kernels_.back();
635  }
636 
639  {
640  //std::cout << "Requiring kernel " << name << " from program " << name_ << std::endl;
641  for (KernelContainer::iterator it = kernels_.begin();
642  it != kernels_.end();
643  ++it)
644  {
645  if (it->name() == name)
646  return *it;
647  }
648  std::cerr << "ViennaCL: FATAL ERROR: Could not find kernel '" << name << "' from program '" << name_ << "'" << std::endl;
649  std::cout << "Number of kernels in program: " << kernels_.size() << std::endl;
650  throw "Kernel not found";
651  //return kernels_[0]; //return a defined object
652  }
653 
654 
655  inline void viennacl::ocl::kernel::set_work_size_defaults()
656  {
657  assert( p_program_ != NULL && bool("Kernel not initialized, program pointer invalid."));
658  assert( p_context_ != NULL && bool("Kernel not initialized, context pointer invalid."));
659 
660  if ( (p_context_->current_device().type() == CL_DEVICE_TYPE_GPU)
661  || (p_context_->current_device().type() == CL_DEVICE_TYPE_ACCELERATOR) // Xeon Phi
662  )
663  {
664  local_work_size_[0] = 128; local_work_size_[1] = 0; local_work_size_[2] = 0;
665  global_work_size_[0] = 128*128; global_work_size_[1] = 0; global_work_size_[2] = 0;
666  }
667  else //assume CPU type:
668  {
669  //conservative assumption: one thread per CPU core:
670  local_work_size_[0] = 1; local_work_size_[1] = 0; local_work_size_[2] = 0;
671 
672  size_type units = p_context_->current_device().max_compute_units();
673  size_type s = 1;
674 
675  while (s < units) // find next power of 2. Important to make reductions work on e.g. six-core CPUs.
676  s *= 2;
677 
678  global_work_size_[0] = s; global_work_size_[1] = 0; global_work_size_[2] = 0;
679  }
680  }
681 
682  }
683 }
684 
685 #endif
std::string name() const
Device name string.
Definition: device.hpp:566
void add_device(cl_device_id d)
Add a device to the context. Must be done before the context is initialized.
Definition: context.hpp:140
viennacl::ocl::kernel & get_kernel(std::string const &program_name, std::string const &kernel_name)
Convenience function for retrieving the kernel of a program directly from the context.
Definition: context.hpp:470
This file provides the forward declarations for the OpenCL layer of ViennaCL.
std::size_t vcl_size_t
Definition: forwards.h:58
void delete_program(std::string const &name)
Delete the program with the provided name.
Definition: context.hpp:401
bool operator<(context const &other) const
Less-than comparable for compatibility with std:map.
Definition: context.hpp:495
void inc()
Manually increment the OpenCL reference count. Typically called automatically, but is necessary if us...
Definition: handle.hpp:214
void switch_queue(viennacl::ocl::command_queue const &q)
If the supplied command_queue is used within the context, it becomes the current active command_queue...
Definition: context.hpp:307
Represents an OpenCL device within ViennaCL.
Implements a OpenCL platform within ViennaCL.
bool operator==(context const &other) const
Definition: context.hpp:500
Wrapper class for an OpenCL platform.
Definition: platform.hpp:45
viennacl::ocl::command_queue const & current_queue()
Returns the current device.
Definition: context.hpp:293
vcl_size_t device_num()
Returns the number of devices within this context.
Definition: context.hpp:473
Represents an OpenCL kernel within ViennaCL.
Definition: kernel.hpp:59
Manages an OpenCL context and provides the respective convenience functions for creating buffers...
Definition: context.hpp:51
cl_device_type default_device_type()
Returns the default device type for the context.
Definition: context.hpp:72
cl_mem create_memory_without_smart_handle(cl_mem_flags flags, unsigned int size, void *ptr=NULL) const
Creates a memory buffer within the context. Does not wrap the OpenCL handle into the smart-pointer-li...
Definition: context.hpp:179
void init(cl_context c)
Initializes the context from an existing, user-supplied context.
Definition: context.hpp:156
A class representing a compute device (e.g. a GPU)
Definition: device.hpp:49
void switch_device(vcl_size_t i)
Switches the current device to the i-th device in this context.
Definition: context.hpp:102
viennacl::ocl::program & add_program(cl_program p, std::string const &prog_name)
Adds a program to the context.
Definition: context.hpp:340
void add_queue(viennacl::ocl::device d)
Adds a queue for the given device to the context.
Definition: context.hpp:246
A class representing a command queue.
Definition: command_queue.hpp:45
void init()
Initializes a new context.
Definition: context.hpp:150
viennacl::ocl::handle< cl_command_queue > const & handle() const
Definition: command_queue.hpp:81
viennacl::ocl::program const & get_program(std::string const &name) const
Definition: context.hpp:431
viennacl::ocl::program & get_program(std::string const &name)
Returns the program with the provided name.
Definition: context.hpp:414
bool has_program(std::string const &name)
Returns whether the program with the provided name exists or not.
Definition: context.hpp:449
const viennacl::ocl::handle< cl_context > & handle() const
Returns the context handle.
Definition: context.hpp:476
Implementations of command queue representations.
viennacl::ocl::device const & current_device() const
Returns the current device.
Definition: context.hpp:95
#define VIENNACL_ERR_CHECK(err)
Definition: error.hpp:655
vcl_size_t size(VectorType const &vec)
Generic routine for obtaining the size of a vector (ViennaCL, uBLAS, etc.)
Definition: size.hpp:144
viennacl::ocl::command_queue & get_queue()
Definition: context.hpp:249
viennacl::ocl::handle< cl_mem > create_memory(cl_mem_flags flags, unsigned int size, void *ptr=NULL) const
Creates a memory buffer within the context.
Definition: context.hpp:199
const OCL_TYPE & get() const
Definition: handle.hpp:189
void switch_device(viennacl::ocl::device const &d)
If the supplied device is used within the context, it becomes the current active device.
Definition: context.hpp:109
cl_device_id id() const
Returns the OpenCL device id.
Definition: device.hpp:981
Implements an OpenCL program class for ViennaCL.
void default_device_num(vcl_size_t new_num)
Sets the maximum number of devices to be set up for the context.
Definition: context.hpp:68
Implementation of a smart-pointer-like class for handling OpenCL handles.
void add_queue(cl_device_id dev, cl_command_queue q)
Adds an existing queue for the given device to the context.
Definition: context.hpp:218
viennacl::ocl::program & get_program(vcl_size_t id)
Returns the program with the provided id.
Definition: context.hpp:460
viennacl::ocl::kernel & add_kernel(cl_kernel kernel_handle, std::string const &kernel_name)
Adds a kernel to the program.
Definition: context.hpp:629
const viennacl::ocl::handle< cl_program > & handle() const
Definition: program.hpp:68
void add_queue(cl_device_id dev)
Adds a queue for the given device to the context.
Definition: context.hpp:229
Wrapper class for an OpenCL program.
Definition: program.hpp:40
void default_device_type(cl_device_type dtype)
Sets the device type for this context.
Definition: context.hpp:78
vcl_size_t platform_index() const
Returns the platform ID of the platform to be used for the context.
Definition: context.hpp:485
#define VIENNACL_OCL_MAX_DEVICE_NUM
Definition: device_utils.hpp:25
vcl_size_t program_num()
Returns the number of programs within this context.
Definition: context.hpp:467
std::string build_options() const
Returns the current build option string.
Definition: context.hpp:479
viennacl::ocl::kernel & get_kernel(std::string const &name)
Returns the kernel with the provided name.
Definition: context.hpp:638
Representation of an OpenCL kernel in ViennaCL.
vcl_size_t default_device_num() const
Returns the maximum number of devices to be set up for the context.
Definition: context.hpp:65
void platform_index(vcl_size_t new_index)
Sets the platform ID of the platform to be used for the context.
Definition: context.hpp:488
viennacl::ocl::command_queue & get_queue(cl_device_id dev, vcl_size_t i=0)
Returns the queue with the provided index for the given device.
Definition: context.hpp:273
void build_options(std::string op)
Sets the build option string, which is passed to the OpenCL compiler in subsequent compilations...
Definition: context.hpp:482
viennacl::ocl::handle< cl_mem > create_memory(cl_mem_flags flags, const VectorType< SCALARTYPE, A > &buffer) const
Creates a memory buffer within the context initialized from the supplied data.
Definition: context.hpp:210
std::vector< viennacl::ocl::device > const & devices() const
Returns a vector with all devices in this context.
Definition: context.hpp:89
void add_device(viennacl::ocl::device const &d)
Add a device to the context. Must be done before the context is initialized.
Definition: context.hpp:129
context()
Definition: context.hpp:56
void switch_queue(vcl_size_t i)
Switches the current device to the i-th device in this context.
Definition: context.hpp:299
viennacl::ocl::command_queue const & get_queue() const
Definition: context.hpp:254
viennacl::ocl::program & add_program(std::string const &source, std::string const &prog_name)
Adds a new program with the provided source to the context. Compiles the program and extracts all ker...
Definition: context.hpp:348