ViennaCL - The Vienna Computing Library  1.7.0
Free open-source GPU-accelerated linear algebra and solver library.
handle.hpp
Go to the documentation of this file.
1 #ifndef VIENNACL_OCL_HANDLE_HPP_
2 #define VIENNACL_OCL_HANDLE_HPP_
3 
4 /* =========================================================================
5  Copyright (c) 2010-2015, 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 #ifdef __APPLE__
26 #include <OpenCL/cl.h>
27 #else
28 #include <CL/cl.h>
29 #endif
30 
31 #include <assert.h>
32 #include <string>
33 #include <iostream>
34 #include "viennacl/ocl/forwards.h"
35 #include "viennacl/ocl/error.hpp"
36 
37 namespace viennacl
38 {
39  namespace ocl
40  {
44  template<class OCL_TYPE>
46  {
47  typedef typename OCL_TYPE::ERROR_TEMPLATE_ARGUMENT_FOR_CLASS_INVALID ErrorType;
48  };
49 
51  //cl_mem:
52  template<>
53  struct handle_inc_dec_helper<cl_mem>
54  {
55  static void inc(cl_mem & something)
56  {
57  cl_int err = clRetainMemObject(something);
58  VIENNACL_ERR_CHECK(err);
59  }
60 
61  static void dec(cl_mem & something)
62  {
63  #ifndef __APPLE__
64  cl_int err = clReleaseMemObject(something);
65  VIENNACL_ERR_CHECK(err);
66  #endif
67  }
68  };
69 
70  //cl_program:
71  template<>
72  struct handle_inc_dec_helper<cl_program>
73  {
74  static void inc(cl_program & something)
75  {
76  cl_int err = clRetainProgram(something);
77  VIENNACL_ERR_CHECK(err);
78  }
79 
80  static void dec(cl_program & something)
81  {
82  #ifndef __APPLE__
83  cl_int err = clReleaseProgram(something);
84  VIENNACL_ERR_CHECK(err);
85  #endif
86  }
87  };
88 
89  //cl_kernel:
90  template<>
91  struct handle_inc_dec_helper<cl_kernel>
92  {
93  static void inc(cl_kernel & something)
94  {
95  cl_int err = clRetainKernel(something);
96  VIENNACL_ERR_CHECK(err);
97  }
98 
99  static void dec(cl_kernel & something)
100  {
101  #ifndef __APPLE__
102  cl_int err = clReleaseKernel(something);
103  VIENNACL_ERR_CHECK(err);
104  #endif
105  }
106  };
107 
108  //cl_command_queue:
109  template<>
110  struct handle_inc_dec_helper<cl_command_queue>
111  {
112  static void inc(cl_command_queue & something)
113  {
114  cl_int err = clRetainCommandQueue(something);
115  VIENNACL_ERR_CHECK(err);
116  }
117 
118  static void dec(cl_command_queue & something)
119  {
120  #ifndef __APPLE__
121  cl_int err = clReleaseCommandQueue(something);
122  VIENNACL_ERR_CHECK(err);
123  #endif
124  }
125  };
126 
127  //cl_context:
128  template<>
129  struct handle_inc_dec_helper<cl_context>
130  {
131  static void inc(cl_context & something)
132  {
133  cl_int err = clRetainContext(something);
134  VIENNACL_ERR_CHECK(err);
135  }
136 
137  static void dec(cl_context & something)
138  {
139  #ifndef __APPLE__
140  cl_int err = clReleaseContext(something);
141  VIENNACL_ERR_CHECK(err);
142  #endif
143  }
144  };
148  template<class OCL_TYPE>
149  class handle
150  {
151  public:
152  handle() : h_(0), p_context_(NULL) {}
153  handle(const OCL_TYPE & something, viennacl::ocl::context const & c) : h_(something), p_context_(&c) {}
154  handle(const handle & other) : h_(other.h_), p_context_(other.p_context_) { if (h_ != 0) inc(); }
155  ~handle() { if (h_ != 0) dec(); }
156 
158  handle & operator=(const handle & other)
159  {
160  if (h_ != 0)
161  dec();
162  h_ = other.h_;
163  p_context_ = other.p_context_;
164  inc();
165  return *this;
166  }
167 
169  handle & operator=(const OCL_TYPE & something)
170  {
171  if (h_ != 0) dec();
172  h_ = something;
173  return *this;
174  }
175 
177  handle & operator=(std::pair<OCL_TYPE, cl_context> p)
178  {
179  if (h_ != 0) dec();
180  h_ = p.first;
181  p_context_ = p.second;
182  return *this;
183  }
184 
185 
187  operator OCL_TYPE() const { return h_; }
188 
189  const OCL_TYPE & get() const { return h_; }
190 
192  {
193  assert(p_context_ != NULL && bool("Logic error: Accessing dangling context from handle."));
194  return *p_context_;
195  }
196  void context(viennacl::ocl::context const & c) { p_context_ = &c; }
197 
198 
200  handle & swap(handle & other)
201  {
202  OCL_TYPE tmp = other.h_;
203  other.h_ = this->h_;
204  this->h_ = tmp;
205 
206  viennacl::ocl::context const * tmp2 = other.p_context_;
207  other.p_context_ = this->p_context_;
208  this->p_context_ = tmp2;
209 
210  return *this;
211  }
212 
217  private:
218  OCL_TYPE h_;
219  viennacl::ocl::context const * p_context_;
220  };
221 
222 
223  } //namespace ocl
224 } //namespace viennacl
225 
226 #endif
This file provides the forward declarations for the OpenCL layer of ViennaCL.
Manages an OpenCL context and provides the respective convenience functions for creating buffers...
Definition: context.hpp:55
Helper for OpenCL reference counting used by class handle.
Definition: handle.hpp:45
handle(const handle &other)
Definition: handle.hpp:154
viennacl::ocl::context const & context() const
Definition: handle.hpp:191
#define VIENNACL_ERR_CHECK(err)
Definition: error.hpp:681
Main namespace in ViennaCL. Holds all the basic types such as vector, matrix, etc. and defines operations upon them.
Definition: cpu_ram.hpp:34
handle & operator=(std::pair< OCL_TYPE, cl_context > p)
Wraps an OpenCL handle including its associated context. Decreases the reference count if the handle ...
Definition: handle.hpp:177
void context(viennacl::ocl::context const &c)
Definition: handle.hpp:196
void inc()
Manually increment the OpenCL reference count. Typically called automatically, but is necessary if us...
Definition: handle.hpp:214
void dec()
Manually decrement the OpenCL reference count. Typically called automatically, but might be useful wi...
Definition: handle.hpp:216
handle & operator=(const OCL_TYPE &something)
Wraps an OpenCL handle. Does not change the context of this handle object! Decreases the reference co...
Definition: handle.hpp:169
Error handling for the OpenCL layer of ViennaCL.
handle & swap(handle &other)
Swaps the OpenCL handle of two handle objects.
Definition: handle.hpp:200
handle & operator=(const handle &other)
Copies the OpenCL handle from the provided handle. Does not take ownership like e.g. std::auto_ptr<>, so both handle objects are valid (more like shared_ptr).
Definition: handle.hpp:158
viennacl::backend::mem_handle const & handle(T const &obj)
Returns the generic memory handle of an object. Const-version.
Definition: handle.hpp:48
Handle class the effectively represents a smart pointer for OpenCL handles.
Definition: forwards.h:51
handle(const OCL_TYPE &something, viennacl::ocl::context const &c)
Definition: handle.hpp:153