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
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-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 #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  cl_int err = clReleaseMemObject(something);
64  VIENNACL_ERR_CHECK(err);
65  }
66  };
67 
68  //cl_program:
69  template<>
70  struct handle_inc_dec_helper<cl_program>
71  {
72  static void inc(cl_program & something)
73  {
74  cl_int err = clRetainProgram(something);
75  VIENNACL_ERR_CHECK(err);
76  }
77 
78  static void dec(cl_program & something)
79  {
80  (void)something;
81  #ifndef __APPLE__
82  cl_int err = clReleaseProgram(something);
83  VIENNACL_ERR_CHECK(err);
84  #endif
85  }
86  };
87 
88  //cl_kernel:
89  template<>
90  struct handle_inc_dec_helper<cl_kernel>
91  {
92  static void inc(cl_kernel & something)
93  {
94  cl_int err = clRetainKernel(something);
95  VIENNACL_ERR_CHECK(err);
96  }
97 
98  static void dec(cl_kernel & something)
99  {
100  (void)something;
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  (void)something;
121  #ifndef __APPLE__
122  cl_int err = clReleaseCommandQueue(something);
123  VIENNACL_ERR_CHECK(err);
124  #endif
125  }
126  };
127 
128  //cl_context:
129  template<>
130  struct handle_inc_dec_helper<cl_context>
131  {
132  static void inc(cl_context & something)
133  {
134  cl_int err = clRetainContext(something);
135  VIENNACL_ERR_CHECK(err);
136  }
137 
138  static void dec(cl_context & something)
139  {
140  (void)something;
141  #ifndef __APPLE__
142  cl_int err = clReleaseContext(something);
143  VIENNACL_ERR_CHECK(err);
144  #endif
145  }
146  };
150  template<class OCL_TYPE>
151  class handle
152  {
153  public:
154  handle() : h_(0), p_context_(NULL) {}
155  handle(const OCL_TYPE & something, viennacl::ocl::context const & c) : h_(something), p_context_(&c) {}
156  handle(const handle & other) : h_(other.h_), p_context_(other.p_context_) { if (h_ != 0) inc(); }
157  ~handle() { if (h_ != 0) dec(); }
158 
160  handle & operator=(const handle & other)
161  {
162  if (h_ != 0)
163  dec();
164  h_ = other.h_;
165  p_context_ = other.p_context_;
166  inc();
167  return *this;
168  }
169 
171  handle & operator=(const OCL_TYPE & something)
172  {
173  if (h_ != 0) dec();
174  h_ = something;
175  return *this;
176  }
177 
179  handle & operator=(std::pair<OCL_TYPE, cl_context> p)
180  {
181  if (h_ != 0) dec();
182  h_ = p.first;
183  p_context_ = p.second;
184  return *this;
185  }
186 
187 
189  operator OCL_TYPE() const { return h_; }
190 
191  const OCL_TYPE & get() const { return h_; }
192 
194  {
195  assert(p_context_ != NULL && bool("Logic error: Accessing dangling context from handle."));
196  return *p_context_;
197  }
198  void context(viennacl::ocl::context const & c) { p_context_ = &c; }
199 
200 
202  handle & swap(handle & other)
203  {
204  OCL_TYPE tmp = other.h_;
205  other.h_ = this->h_;
206  this->h_ = tmp;
207 
208  viennacl::ocl::context const * tmp2 = other.p_context_;
209  other.p_context_ = this->p_context_;
210  this->p_context_ = tmp2;
211 
212  return *this;
213  }
214 
219  private:
220  OCL_TYPE h_;
221  viennacl::ocl::context const * p_context_;
222  };
223 
224 
225  } //namespace ocl
226 } //namespace viennacl
227 
228 #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:156
viennacl::ocl::context const & context() const
Definition: handle.hpp:193
#define VIENNACL_ERR_CHECK(err)
Definition: error.hpp:681
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:179
void context(viennacl::ocl::context const &c)
Definition: handle.hpp:198
void inc()
Manually increment the OpenCL reference count. Typically called automatically, but is necessary if us...
Definition: handle.hpp:216
void dec()
Manually decrement the OpenCL reference count. Typically called automatically, but might be useful wi...
Definition: handle.hpp:218
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:171
Error handling for the OpenCL layer of ViennaCL.
handle & swap(handle &other)
Swaps the OpenCL handle of two handle objects.
Definition: handle.hpp:202
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:160
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:155