1 #ifndef VIENNACL_OCL_CONTEXT_HPP_ 
    2 #define VIENNACL_OCL_CONTEXT_HPP_ 
   26 #include <OpenCL/cl.h> 
   57   typedef std::vector< tools::shared_ptr<viennacl::ocl::program> >   program_container_type;
 
   61     device_type_(CL_DEVICE_TYPE_DEFAULT),
 
   62     current_device_id_(0),
 
   63     default_device_num_(1),
 
   67     if (std::getenv(
"VIENNACL_CACHE_PATH"))
 
   68       cache_path_ = std::getenv(
"VIENNACL_CACHE_PATH");
 
   78   void cache_path(std::string new_path) { cache_path_ = new_path; }
 
   97 #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT) 
   98     std::cout << 
"ViennaCL: Setting new device type for context " << h_ << std::endl;
 
  101       device_type_ = dtype; 
 
  106   std::vector<viennacl::ocl::device> 
const & 
devices()
 const 
  115     return devices_[current_device_id_];
 
  121     assert(i < devices_.size() && bool(
"Provided device index out of range!"));
 
  122     current_device_id_ = i;
 
  128 #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT) 
  129     std::cout << 
"ViennaCL: Setting new current device for context " << h_ << std::endl;
 
  134       if (devices_[i] == d)
 
  137         current_device_id_ = i;
 
  142       std::cerr << 
"ViennaCL: Warning: Could not set device " << d.
name() << 
" for context." << std::endl;
 
  148     assert(!initialized_ && 
bool(
"Device must be added to context before it is initialized!"));
 
  149 #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT) 
  150     std::cout << 
"ViennaCL: Adding new device to context " << h_ << std::endl;
 
  152     if (std::find(devices_.begin(), devices_.end(), d) == devices_.end())
 
  153       devices_.push_back(d);
 
  159     assert(!initialized_ && 
bool(
"Device must be added to context before it is initialized!"));
 
  198 #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT) 
  199     std::cout << 
"ViennaCL: Creating memory of size " << size << 
" for context " << h_ << 
" (unsafe, returning cl_mem directly)" << std::endl;
 
  202       flags |= CL_MEM_COPY_HOST_PTR;
 
  204     cl_mem mem = clCreateBuffer(h_.
get(), flags, 
size, ptr, &err);
 
  226   template< 
typename NumericT, 
typename A, 
template<
typename, 
typename> 
class VectorType >
 
  237 #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT) 
  238     std::cout << 
"ViennaCL: Adding existing queue " << q << 
" for device " << dev << 
" to context " << h_ << std::endl;
 
  242     queues_[dev].back().handle().inc();
 
  248 #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT) 
  249     std::cout << 
"ViennaCL: Adding new queue for device " << dev << 
" to context " << h_ << std::endl;
 
  252 #ifdef VIENNACL_PROFILING_ENABLED 
  268 #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT) 
  269     std::cout << 
"ViennaCL: Getting queue for device " << devices_[current_device_id_].name() << 
" in context " << h_ << std::endl;
 
  270     std::cout << 
"ViennaCL: Current queue id " << current_queue_id_ << std::endl;
 
  273     return queues_[devices_[current_device_id_].id()][current_queue_id_];
 
  278     typedef std::map< cl_device_id, std::vector<viennacl::ocl::command_queue> >    QueueContainer;
 
  280 #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT) 
  281     std::cout << 
"ViennaCL: Getting const queue for device " << devices_[current_device_id_].name() << 
" in context " << h_ << std::endl;
 
  282     std::cout << 
"ViennaCL: Current queue id " << current_queue_id_ << std::endl;
 
  286     QueueContainer::const_iterator it = queues_.find(devices_[current_device_id_].
id());
 
  287     if (it != queues_.end()) {
 
  288 #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT) 
  289       std::cout << 
"ViennaCL: Queue handle " << (it->second)[current_queue_id_].
handle() << std::endl;
 
  291       return (it->second)[current_queue_id_];
 
  303     if (i >= queues_[dev].
size())
 
  306 #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT) 
  307     std::cout << 
"ViennaCL: Getting queue " << i << 
" for device " << dev << 
" in context " << h_ << std::endl;
 
  309     unsigned int device_index;
 
  310     for (device_index = 0; device_index < devices_.size(); ++device_index)
 
  312       if (devices_[device_index] == dev)
 
  316     assert(device_index < devices_.size() && bool(
"Device not within context"));
 
  318     return queues_[devices_[device_index].id()][i];
 
  325     return queues_[devices_[current_device_id_].id()][current_queue_id_];
 
  331     assert(i < queues_[devices_[current_device_id_].
id()].
size() && 
bool(
"In class 'context': Provided queue index out of range for device!"));
 
  332     current_queue_id_ = i;
 
  338 #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT) 
  339     std::cout << 
"ViennaCL: Setting new current queue for context " << h_ << std::endl;
 
  342     typedef std::map< cl_device_id, std::vector<viennacl::ocl::command_queue> >    QueueContainer;
 
  346     for (QueueContainer::const_iterator it=queues_.begin(); it != queues_.end(); it++,j++)
 
  348       const std::vector<viennacl::ocl::command_queue> & qv = (it->second);
 
  355           current_device_id_ = j;
 
  356           current_queue_id_ = i;
 
  362       std::cerr << 
"ViennaCL: Warning: Could not set queue " << q.
handle().
get() << 
" for context." << std::endl;
 
  371 #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT) 
  372     std::cout << 
"ViennaCL: Adding program '" << prog_name << 
"' with cl_program to context " << h_ << std::endl;
 
  374     return *programs_.back();
 
  381     const char * source_text = source.c_str();
 
  385 #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT) 
  386     std::cout << 
"ViennaCL: Adding program '" << prog_name << 
"' with source to context " << h_ << std::endl;
 
  394     if (cache_path_.size())
 
  396 #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT) 
  397       std::cout << 
"ViennaCL: Cache at " << cache_path_ << std::endl;
 
  401       for(std::vector< viennacl::ocl::device >::const_iterator it = devices_.begin(); it != devices_.end(); ++it)
 
  402         prefix += it->name() + it->vendor() + it->driver_version();
 
  405       std::ifstream cached((cache_path_+sha1).c_str(),std::ios::binary);
 
  409         std::vector<unsigned char> buffer;
 
  413         cached.read((
char*)(&buffer[0]), std::streamsize(len));
 
  416         cl_device_id devid = devices_[0].id();
 
  417         const unsigned char * bufdata = &buffer[0];
 
  418         temp = clCreateProgramWithBinary(h_.
get(),1,&devid,&len, &bufdata,&status,&err);
 
  425       temp = clCreateProgramWithSource(h_.
get(), 1, (
const char **)&source_text, &source_size, &err);
 
  429     const char * options = build_options_.c_str();
 
  430     err = clBuildProgram(temp, 0, NULL, options, NULL, NULL);
 
  431 #ifndef VIENNACL_BUILD_INFO 
  432     if (err != CL_SUCCESS)
 
  435       cl_build_status status;
 
  436       clGetProgramBuildInfo(temp, devices_[0].
id(), CL_PROGRAM_BUILD_STATUS, 
sizeof(cl_build_status), &status, NULL);
 
  437       std::cout << 
"Build Status = " << status << 
" ( Err = " << err << 
" )" << std::endl;
 
  441       err = clGetProgramBuildInfo(temp, devices_[0].
id(), CL_PROGRAM_BUILD_LOG, 0, NULL, &ret_val_size);
 
  442       build_log = 
new char[ret_val_size+1];
 
  443       err = clGetProgramBuildInfo(temp, devices_[0].
id(), CL_PROGRAM_BUILD_LOG, ret_val_size, build_log, NULL);
 
  444       build_log[ret_val_size] = 
'\0';
 
  445       std::cout << 
"Log: " << build_log << std::endl;
 
  448       std::cout << 
"Sources: " << source << std::endl;
 
  455     if (cache_path_.size())
 
  459       std::vector<vcl_size_t> sizes(devices_.size());
 
  460       clGetProgramInfo(temp,CL_PROGRAM_BINARY_SIZES,0,NULL,&len);
 
  461       clGetProgramInfo(temp,CL_PROGRAM_BINARY_SIZES,len,(
void*)&sizes[0],NULL);
 
  463       std::vector<unsigned char*> binaries;
 
  464       for (
vcl_size_t i = 0; i < devices_.size(); ++i)
 
  465         binaries.push_back(
new unsigned char[sizes[i]]);
 
  467       clGetProgramInfo(temp,CL_PROGRAM_BINARIES,0,NULL,&len);
 
  468       clGetProgramInfo(temp,CL_PROGRAM_BINARIES,len,&binaries[0],NULL);
 
  471       for(std::vector< viennacl::ocl::device >::const_iterator it = devices_.begin(); it != devices_.end(); ++it)
 
  472         prefix += it->name() + it->vendor() + it->driver_version();
 
  474       std::ofstream cached((cache_path_+sha1).c_str(),std::ios::binary);
 
  476       cached.write((
char*)&sizes[0], 
sizeof(
vcl_size_t));
 
  477       cached.write((
char*)binaries[0], std::streamsize(sizes[0]));
 
  479       for (
vcl_size_t i = 0; i < devices_.size(); ++i)
 
  480         delete[] binaries[i];
 
  493     cl_kernel kernels[1024];
 
  494     cl_uint   num_kernels_in_prog;
 
  495     err = clCreateKernelsInProgram(prog.
handle().
get(), 1024, kernels, &num_kernels_in_prog);
 
  498     for (cl_uint i=0; i<num_kernels_in_prog; ++i)
 
  500       char kernel_name[128];
 
  501       err = clGetKernelInfo(kernels[i], CL_KERNEL_FUNCTION_NAME, 128, kernel_name, NULL);
 
  502       prog.
add_kernel(kernels[i], std::string(kernel_name));
 
  505 #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT) 
  506     std::cout << 
"ViennaCL: Stored program '" << programs_.back()->name() << 
"' in context " << h_ << std::endl;
 
  507     std::cout << 
"ViennaCL: There is/are " << programs_.size() << 
" program(s)" << std::endl;
 
  516 #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT) 
  517     std::cout << 
"ViennaCL: Deleting program '" << name << 
"' from context " << h_ << std::endl;
 
  519     for (program_container_type::iterator it = programs_.begin();
 
  520          it != programs_.end();
 
  523       if ((*it)->name() == name)
 
  534 #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT) 
  535     std::cout << 
"ViennaCL: Getting program '" << name << 
"' from context " << h_ << std::endl;
 
  536     std::cout << 
"ViennaCL: There are " << programs_.size() << 
" programs" << std::endl;
 
  538     for (program_container_type::iterator it = programs_.begin();
 
  539          it != programs_.end();
 
  543       if ((*it)->name() == name)
 
  546     std::cerr << 
"ViennaCL: Could not find program '" << name << 
"'" << std::endl;
 
  553 #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT) 
  554     std::cout << 
"ViennaCL: Getting program '" << name << 
"' from context " << h_ << std::endl;
 
  555     std::cout << 
"ViennaCL: There are " << programs_.size() << 
" programs" << std::endl;
 
  557     for (program_container_type::const_iterator it = programs_.begin();
 
  558          it != programs_.end();
 
  562       if ((*it)->name() == name)
 
  565     std::cerr << 
"ViennaCL: Could not find program '" << name << 
"'" << std::endl;
 
  573     for (program_container_type::iterator it = programs_.begin();
 
  574          it != programs_.end();
 
  577       if ((*it)->name() == name) 
return true;
 
  585 #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT) 
  586     std::cout << 
"ViennaCL: Getting program '" << 
id << 
"' from context " << h_ << std::endl;
 
  587     std::cout << 
"ViennaCL: There are " << programs_.size() << 
" programs" << std::endl;
 
  590     if (
id >= programs_.size())
 
  593     return *programs_[id];
 
  625     assert(!initialized_ && 
bool(
"Platform ID must be set before context is initialized!"));
 
  626     pf_index_ = new_index;
 
  632     return h_.
get() < other.h_.
get();
 
  637     return h_.
get() == other.h_.
get();
 
  644     assert(!initialized_ && 
bool(
"ViennaCL FATAL error: Context already created!"));
 
  646 #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT) 
  647     std::cout << 
"ViennaCL: Initializing new ViennaCL context." << std::endl;
 
  651     std::vector<cl_device_id> device_id_array;
 
  652     if (devices_.empty()) 
 
  655 #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT) 
  656       std::cout << 
"ViennaCL: Setting all devices for context..." << std::endl;
 
  660       std::vector<device> 
devices = pf.devices(device_type_);
 
  661 #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT) 
  662       std::cout << 
"ViennaCL: Number of devices for context: " << devices.size() << std::endl;
 
  666         devices_.push_back(devices[i]);
 
  668       if (devices.size() == 0)
 
  670         std::cerr << 
"ViennaCL: FATAL ERROR: No devices of type '";
 
  671         switch (device_type_)
 
  673         case CL_DEVICE_TYPE_CPU:          std::cout << 
"CPU"; 
break;
 
  674         case CL_DEVICE_TYPE_GPU:          std::cout << 
"GPU"; 
break;
 
  675         case CL_DEVICE_TYPE_ACCELERATOR:  std::cout << 
"ACCELERATOR"; 
break;
 
  676         case CL_DEVICE_TYPE_DEFAULT:      std::cout << 
"DEFAULT"; 
break;
 
  678           std::cout << 
"UNKNOWN" << std::endl;
 
  680         std::cout << 
"' found!" << std::endl;
 
  685     for (std::vector< viennacl::ocl::device >::const_iterator iter = devices_.begin();
 
  686          iter != devices_.end();
 
  688       device_id_array.push_back(iter->id());
 
  690     h_ = clCreateContext(0,
 
  691                          static_cast<cl_uint>(devices_.size()),
 
  692                          &(device_id_array[0]),
 
  697 #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT) 
  698     std::cout << 
"ViennaCL: Initialization of new ViennaCL context done." << std::endl;
 
  703   void init_existing(cl_context c)
 
  705     assert(!initialized_ && 
bool(
"ViennaCL FATAL error: Context already created!"));
 
  706 #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT) 
  707     std::cout << 
"ViennaCL: Initialization of ViennaCL context from existing context." << std::endl;
 
  714     if (devices_.empty())
 
  725       assert(temp > 0 && 
bool(
"ViennaCL: FATAL error: Provided context does not contain any devices!"));
 
  726       num_devices = 
static_cast<cl_uint
>(temp / 
sizeof(cl_device_id));
 
  728 #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT) 
  729       std::cout << 
"ViennaCL: Reusing context with " << num_devices << 
" devices." << std::endl;
 
  732       std::vector<cl_device_id> device_ids(num_devices);
 
  733       err = clGetContextInfo(h_.
get(), CL_CONTEXT_DEVICES, num_devices * 
sizeof(cl_device_id), &(device_ids[0]), NULL);
 
  739     current_device_id_ = 0;
 
  742 #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT) 
  743     std::cout << 
"ViennaCL: Initialization of ViennaCL context from existing context done." << std::endl;
 
  749   std::string cache_path_;
 
  750   cl_device_type device_type_;
 
  752   std::vector< viennacl::ocl::device > devices_;
 
  755   program_container_type programs_;
 
  756   std::map< cl_device_id, std::vector< viennacl::ocl::command_queue> > queues_;
 
  757   std::string build_options_;
 
  767   assert(p_context_ != NULL && 
bool(
"Pointer to context invalid in viennacl::ocl::program object"));
 
  769   return *kernels_.back();
 
  776   for (kernel_container_type::iterator it = kernels_.begin();
 
  777        it != kernels_.end();
 
  780     if ((*it)->name() == name)
 
  783   std::cerr << 
"ViennaCL: FATAL ERROR: Could not find kernel '" << name << 
"' from program '" << name_ << 
"'" << std::endl;
 
  784   std::cout << 
"Number of kernels in program: " << kernels_.size() << std::endl;
 
  790 inline void viennacl::ocl::kernel::set_work_size_defaults()
 
  792   assert( p_program_ != NULL && 
bool(
"Kernel not initialized, program pointer invalid."));
 
  793   assert( p_context_ != NULL && 
bool(
"Kernel not initialized, context pointer invalid."));
 
  795   if (   (p_context_->current_device().type() == CL_DEVICE_TYPE_GPU)
 
  796          || (p_context_->current_device().type() == CL_DEVICE_TYPE_ACCELERATOR) 
 
  799     local_work_size_[0] = 128;      local_work_size_[1] = 0;  local_work_size_[2] = 0;
 
  800     global_work_size_[0] = 128*128; global_work_size_[1] = 0; global_work_size_[2] = 0;
 
  805     local_work_size_[0] = 1; local_work_size_[1] = 0; local_work_size_[2] = 0;
 
  807     size_type units = p_context_->current_device().max_compute_units();
 
  813     global_work_size_[0] = s * local_work_size_[0]; global_work_size_[1] = 0; global_work_size_[2] = 0;
 
viennacl::ocl::device const & current_device() const 
Returns the current device. 
This file provides the forward declarations for the OpenCL layer of ViennaCL. 
void switch_queue(vcl_size_t i)
Switches the current device to the i-th device in this context. 
viennacl::ocl::kernel & add_kernel(cl_kernel kernel_handle, std::string const &kernel_name)
Adds a kernel to the program. 
cl_device_id id() const 
Returns the OpenCL device id. 
void platform_index(vcl_size_t new_index)
Sets the platform ID of the platform to be used for the context. 
program_container_type get_programs()
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...
Represents an OpenCL device within ViennaCL. 
void add_queue(cl_device_id dev)
Adds a queue for the given device to the context. 
void default_device_type(cl_device_type dtype)
Sets the device type for this context. 
std::string build_options() const 
Returns the current build option string. 
void switch_device(vcl_size_t i)
Switches the current device to the i-th device in this context. 
viennacl::ocl::command_queue & get_queue()
Represents an OpenCL kernel within ViennaCL. 
viennacl::ocl::program & get_program(std::string const &name)
Returns the program with the provided name. 
void build_options(std::string op)
Sets the build option string, which is passed to the OpenCL compiler in subsequent compilations...
bool operator==(context const &other) const 
const viennacl::ocl::handle< cl_program > & handle() const 
void delete_program(std::string const &name)
Delete the program with the provided name. 
cl_device_type default_device_type()
Returns the default device type for the context. 
Manages an OpenCL context and provides the respective convenience functions for creating buffers...
A class representing a compute device (e.g. a GPU) 
A class representing a command queue. 
vcl_size_t program_num()
Returns the number of programs within this context. 
vcl_size_t platform_index() const 
Returns the platform ID of the platform to be used for the context. 
const viennacl::ocl::handle< cl_context > & handle() const 
Returns the context handle. 
viennacl::ocl::handle< cl_command_queue > const & handle() const 
Implementations of command queue representations. 
vcl_size_t default_device_num() const 
Returns the maximum number of devices to be set up for the context. 
#define VIENNACL_ERR_CHECK(err)
Implementation of a shared pointer class (cf. std::shared_ptr, boost::shared_ptr). Will be used until C++11 is widely available. 
void init()
Initializes a new context. 
viennacl::ocl::program & add_program(cl_program p, std::string const &prog_name)
Adds a program to the context. 
const OCL_TYPE & get() const 
vcl_size_t size(VectorType const &vec)
Generic routine for obtaining the size of a vector (ViennaCL, uBLAS, etc.) 
bool operator<(context const &other) const 
Less-than comparable for compatibility with std:map. 
Exception thrown if an OpenCL program object handle is invalid (e.g. not initialized). 
void inc()
Manually increment the OpenCL reference count. Typically called automatically, but is necessary if us...
void init(cl_context c)
Initializes the context from an existing, user-supplied context. 
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. 
Implements an OpenCL program class for ViennaCL. 
viennacl::ocl::program & get_program(vcl_size_t id)
Returns the program with the provided id. 
std::string cache_path() const 
Returns the compiled kernel cache path. 
Implementation of a smart-pointer-like class for handling OpenCL handles. 
void add_queue(viennacl::ocl::device d)
Adds a queue for the given device to the context. 
void add_device(viennacl::ocl::device const &d)
Add a device to the context. Must be done before the context is initialized. 
void cache_path(std::string new_path)
Sets the compiled kernel cache path. 
Wrapper class for an OpenCL program. 
void add_queue(cl_device_id dev, cl_command_queue q)
Adds an existing queue for the given device to the context. 
std::string name() const 
Device name string. 
viennacl::ocl::program const & get_program(std::string const &name) const 
void default_device_num(vcl_size_t new_num)
Sets the maximum number of devices to be set up for the context. 
Exception thrown if an invalid OpenCL command queue is provided to an OpenCL function. 
Error handling for the OpenCL layer of ViennaCL. 
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...
bool has_program(std::string const &name)
Returns whether the program with the provided name exists or not. 
#define VIENNACL_OCL_MAX_DEVICE_NUM
Representation of an OpenCL kernel in ViennaCL. 
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. 
viennacl::ocl::command_queue const & current_queue()
Returns the current device. 
void add_device(cl_device_id d)
Add a device to the context. Must be done before the context is initialized. 
viennacl::ocl::kernel & get_kernel(std::string const &name)
Returns the kernel with the provided name. 
std::vector< viennacl::ocl::device > const & devices() const 
Returns a vector with all devices in this context. 
vcl_size_t device_num()
Returns the number of devices within this context. 
void switch_device(viennacl::ocl::device const &d)
If the supplied device is used within the context, it becomes the current active device. 
viennacl::ocl::handle< cl_mem > create_memory(cl_mem_flags flags, const VectorType< NumericT, A > &buffer) const 
Creates a memory buffer within the context initialized from the supplied data. 
viennacl::ocl::command_queue const & get_queue() const 
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...
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.