ViennaCL - The Vienna Computing Library
1.5.0
|
00001 #ifndef VIENNACL_OCL_HANDLE_HPP_ 00002 #define VIENNACL_OCL_HANDLE_HPP_ 00003 00004 /* ========================================================================= 00005 Copyright (c) 2010-2013, Institute for Microelectronics, 00006 Institute for Analysis and Scientific Computing, 00007 TU Wien. 00008 Portions of this software are copyright by UChicago Argonne, LLC. 00009 00010 ----------------- 00011 ViennaCL - The Vienna Computing Library 00012 ----------------- 00013 00014 Project Head: Karl Rupp rupp@iue.tuwien.ac.at 00015 00016 (A list of authors and contributors can be found in the PDF manual) 00017 00018 License: MIT (X11), see file LICENSE in the base directory 00019 ============================================================================= */ 00020 00025 #ifdef __APPLE__ 00026 #include <OpenCL/cl.h> 00027 #else 00028 #include <CL/cl.h> 00029 #endif 00030 00031 #include <assert.h> 00032 #include <string> 00033 #include <iostream> 00034 #include "viennacl/ocl/forwards.h" 00035 #include "viennacl/ocl/error.hpp" 00036 00037 namespace viennacl 00038 { 00039 namespace ocl 00040 { 00044 template<class OCL_TYPE> 00045 class handle_inc_dec_helper 00046 { 00047 typedef typename OCL_TYPE::ERROR_TEMPLATE_ARGUMENT_FOR_CLASS_INVALID ErrorType; 00048 }; 00049 00051 //cl_mem: 00052 template <> 00053 struct handle_inc_dec_helper<cl_mem> 00054 { 00055 static void inc(cl_mem & something) 00056 { 00057 cl_int err = clRetainMemObject(something); 00058 VIENNACL_ERR_CHECK(err); 00059 } 00060 00061 static void dec(cl_mem & something) 00062 { 00063 #ifndef __APPLE__ 00064 cl_int err = clReleaseMemObject(something); 00065 VIENNACL_ERR_CHECK(err); 00066 #endif 00067 } 00068 }; 00069 00070 //cl_program: 00071 template <> 00072 struct handle_inc_dec_helper<cl_program> 00073 { 00074 static void inc(cl_program & something) 00075 { 00076 cl_int err = clRetainProgram(something); 00077 VIENNACL_ERR_CHECK(err); 00078 } 00079 00080 static void dec(cl_program & something) 00081 { 00082 #ifndef __APPLE__ 00083 cl_int err = clReleaseProgram(something); 00084 VIENNACL_ERR_CHECK(err); 00085 #endif 00086 } 00087 }; 00088 00089 //cl_kernel: 00090 template <> 00091 struct handle_inc_dec_helper<cl_kernel> 00092 { 00093 static void inc(cl_kernel & something) 00094 { 00095 cl_int err = clRetainKernel(something); 00096 VIENNACL_ERR_CHECK(err); 00097 } 00098 00099 static void dec(cl_kernel & something) 00100 { 00101 #ifndef __APPLE__ 00102 cl_int err = clReleaseKernel(something); 00103 VIENNACL_ERR_CHECK(err); 00104 #endif 00105 } 00106 }; 00107 00108 //cl_command_queue: 00109 template <> 00110 struct handle_inc_dec_helper<cl_command_queue> 00111 { 00112 static void inc(cl_command_queue & something) 00113 { 00114 cl_int err = clRetainCommandQueue(something); 00115 VIENNACL_ERR_CHECK(err); 00116 } 00117 00118 static void dec(cl_command_queue & something) 00119 { 00120 #ifndef __APPLE__ 00121 cl_int err = clReleaseCommandQueue(something); 00122 VIENNACL_ERR_CHECK(err); 00123 #endif 00124 } 00125 }; 00126 00127 //cl_context: 00128 template <> 00129 struct handle_inc_dec_helper<cl_context> 00130 { 00131 static void inc(cl_context & something) 00132 { 00133 cl_int err = clRetainContext(something); 00134 VIENNACL_ERR_CHECK(err); 00135 } 00136 00137 static void dec(cl_context & something) 00138 { 00139 #ifndef __APPLE__ 00140 cl_int err = clReleaseContext(something); 00141 VIENNACL_ERR_CHECK(err); 00142 #endif 00143 } 00144 }; 00148 template<class OCL_TYPE> 00149 class handle 00150 { 00151 public: 00152 handle() : h_(0), p_context_(NULL) {} 00153 handle(const OCL_TYPE & something, viennacl::ocl::context const & c) : h_(something), p_context_(&c) {} 00154 handle(const handle & other) : h_(other.h_), p_context_(other.p_context_) { if (h_ != 0) inc(); } 00155 ~handle() { if (h_ != 0) dec(); } 00156 00158 handle & operator=(const handle & other) 00159 { 00160 if (h_ != 0) 00161 dec(); 00162 h_ = other.h_; 00163 p_context_ = other.p_context_; 00164 inc(); 00165 return *this; 00166 } 00167 00169 handle & operator=(const OCL_TYPE & something) 00170 { 00171 if (h_ != 0) dec(); 00172 h_ = something; 00173 return *this; 00174 } 00175 00177 handle & operator=(std::pair<OCL_TYPE, cl_context> p) 00178 { 00179 if (h_ != 0) dec(); 00180 h_ = p.first; 00181 p_context_ = p.second; 00182 return *this; 00183 } 00184 00185 00187 operator OCL_TYPE() const { return h_; } 00188 00189 const OCL_TYPE & get() const { return h_; } 00190 00191 viennacl::ocl::context const & context() const 00192 { 00193 assert(p_context_ != NULL && bool("Logic error: Accessing dangling context from handle.")); 00194 return *p_context_; 00195 } 00196 void context(viennacl::ocl::context const & c) { p_context_ = &c; } 00197 00198 00200 handle & swap(handle & other) 00201 { 00202 OCL_TYPE tmp = other.h_; 00203 other.h_ = this->h_; 00204 this->h_ = tmp; 00205 00206 viennacl::ocl::context const * tmp2 = other.p_context_; 00207 other.p_context_ = this->p_context_; 00208 this->p_context_ = tmp2; 00209 00210 return *this; 00211 } 00212 00214 void inc() { handle_inc_dec_helper<OCL_TYPE>::inc(h_); } 00216 void dec() { handle_inc_dec_helper<OCL_TYPE>::dec(h_); } 00217 private: 00218 OCL_TYPE h_; 00219 viennacl::ocl::context const * p_context_; 00220 }; 00221 00222 00223 } //namespace ocl 00224 } //namespace viennacl 00225 00226 #endif