memory_object.hpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. //---------------------------------------------------------------------------//
  2. // Copyright (c) 2013 Kyle Lutz <[email protected]>
  3. //
  4. // Distributed under the Boost Software License, Version 1.0
  5. // See accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt
  7. //
  8. // See http://boostorg.github.com/compute for more information.
  9. //---------------------------------------------------------------------------//
  10. #ifndef BOOST_COMPUTE_MEMORY_OBJECT_HPP
  11. #define BOOST_COMPUTE_MEMORY_OBJECT_HPP
  12. #include <boost/compute/config.hpp>
  13. #include <boost/compute/context.hpp>
  14. #include <boost/compute/kernel.hpp>
  15. #include <boost/compute/detail/get_object_info.hpp>
  16. #include <boost/compute/detail/assert_cl_success.hpp>
  17. namespace boost {
  18. namespace compute {
  19. /// \class memory_object
  20. /// \brief Base-class for memory objects.
  21. ///
  22. /// The memory_object class is the base-class for memory objects on
  23. /// compute devices.
  24. ///
  25. /// \see buffer, vector
  26. class memory_object
  27. {
  28. public:
  29. /// Flags for the creation of memory objects.
  30. enum mem_flags {
  31. read_write = CL_MEM_READ_WRITE,
  32. read_only = CL_MEM_READ_ONLY,
  33. write_only = CL_MEM_WRITE_ONLY,
  34. use_host_ptr = CL_MEM_USE_HOST_PTR,
  35. alloc_host_ptr = CL_MEM_ALLOC_HOST_PTR,
  36. copy_host_ptr = CL_MEM_COPY_HOST_PTR
  37. #ifdef BOOST_COMPUTE_CL_VERSION_1_2
  38. ,
  39. host_write_only = CL_MEM_HOST_WRITE_ONLY,
  40. host_read_only = CL_MEM_HOST_READ_ONLY,
  41. host_no_access = CL_MEM_HOST_NO_ACCESS
  42. #endif
  43. };
  44. /// Symbolic names for the OpenCL address spaces.
  45. enum address_space {
  46. global_memory,
  47. local_memory,
  48. private_memory,
  49. constant_memory
  50. };
  51. /// Returns the underlying OpenCL memory object.
  52. cl_mem& get() const
  53. {
  54. return const_cast<cl_mem &>(m_mem);
  55. }
  56. /// Returns the size of the memory object in bytes.
  57. size_t get_memory_size() const
  58. {
  59. return get_memory_info<size_t>(CL_MEM_SIZE);
  60. }
  61. /// Returns the type for the memory object.
  62. cl_mem_object_type get_memory_type() const
  63. {
  64. return get_memory_info<cl_mem_object_type>(CL_MEM_TYPE);
  65. }
  66. /// Returns the flags for the memory object.
  67. cl_mem_flags get_memory_flags() const
  68. {
  69. return get_memory_info<cl_mem_flags>(CL_MEM_FLAGS);
  70. }
  71. /// Returns the context for the memory object.
  72. context get_context() const
  73. {
  74. return context(get_memory_info<cl_context>(CL_MEM_CONTEXT));
  75. }
  76. /// Returns the host pointer associated with the memory object.
  77. void* get_host_ptr() const
  78. {
  79. return get_memory_info<void *>(CL_MEM_HOST_PTR);
  80. }
  81. /// Returns the reference count for the memory object.
  82. uint_ reference_count() const
  83. {
  84. return get_memory_info<uint_>(CL_MEM_REFERENCE_COUNT);
  85. }
  86. /// Returns information about the memory object.
  87. ///
  88. /// \see_opencl_ref{clGetMemObjectInfo}
  89. template<class T>
  90. T get_memory_info(cl_mem_info info) const
  91. {
  92. return detail::get_object_info<T>(clGetMemObjectInfo, m_mem, info);
  93. }
  94. #if defined(BOOST_COMPUTE_CL_VERSION_1_1) || defined(BOOST_COMPUTE_DOXYGEN_INVOKED)
  95. /// Registers a function to be called when the memory object is deleted
  96. /// and its resources freed.
  97. ///
  98. /// \see_opencl_ref{clSetMemObjectDestructorCallback}
  99. ///
  100. /// \opencl_version_warning{1,1}
  101. void set_destructor_callback(void (BOOST_COMPUTE_CL_CALLBACK *callback)(
  102. cl_mem memobj, void *user_data
  103. ),
  104. void *user_data = 0)
  105. {
  106. cl_int ret = clSetMemObjectDestructorCallback(m_mem, callback, user_data);
  107. if(ret != CL_SUCCESS){
  108. BOOST_THROW_EXCEPTION(opencl_error(ret));
  109. }
  110. }
  111. /// Registers a function to be called when the memory object is deleted
  112. /// and its resources freed.
  113. ///
  114. /// The function specified by \p callback must be invokable with zero
  115. /// arguments (e.g. \c callback()).
  116. ///
  117. /// \opencl_version_warning{1,1}
  118. template<class Function>
  119. void set_destructor_callback(Function callback)
  120. {
  121. set_destructor_callback(
  122. destructor_callback_invoker,
  123. new boost::function<void()>(callback)
  124. );
  125. }
  126. #endif // BOOST_COMPUTE_CL_VERSION_1_1
  127. /// Returns \c true if the memory object is the same as \p other.
  128. bool operator==(const memory_object &other) const
  129. {
  130. return m_mem == other.m_mem;
  131. }
  132. /// Returns \c true if the memory object is different from \p other.
  133. bool operator!=(const memory_object &other) const
  134. {
  135. return m_mem != other.m_mem;
  136. }
  137. private:
  138. #ifdef BOOST_COMPUTE_CL_VERSION_1_1
  139. /// \internal_
  140. static void BOOST_COMPUTE_CL_CALLBACK
  141. destructor_callback_invoker(cl_mem, void *user_data)
  142. {
  143. boost::function<void()> *callback =
  144. static_cast<boost::function<void()> *>(user_data);
  145. (*callback)();
  146. delete callback;
  147. }
  148. #endif // BOOST_COMPUTE_CL_VERSION_1_1
  149. protected:
  150. /// \internal_
  151. memory_object()
  152. : m_mem(0)
  153. {
  154. }
  155. /// \internal_
  156. explicit memory_object(cl_mem mem, bool retain = true)
  157. : m_mem(mem)
  158. {
  159. if(m_mem && retain){
  160. clRetainMemObject(m_mem);
  161. }
  162. }
  163. /// \internal_
  164. memory_object(const memory_object &other)
  165. : m_mem(other.m_mem)
  166. {
  167. if(m_mem){
  168. clRetainMemObject(m_mem);
  169. }
  170. }
  171. /// \internal_
  172. memory_object& operator=(const memory_object &other)
  173. {
  174. if(this != &other){
  175. if(m_mem){
  176. clReleaseMemObject(m_mem);
  177. }
  178. m_mem = other.m_mem;
  179. if(m_mem){
  180. clRetainMemObject(m_mem);
  181. }
  182. }
  183. return *this;
  184. }
  185. #ifndef BOOST_COMPUTE_NO_RVALUE_REFERENCES
  186. /// \internal_
  187. memory_object(memory_object&& other) BOOST_NOEXCEPT
  188. : m_mem(other.m_mem)
  189. {
  190. other.m_mem = 0;
  191. }
  192. /// \internal_
  193. memory_object& operator=(memory_object&& other) BOOST_NOEXCEPT
  194. {
  195. if(m_mem){
  196. clReleaseMemObject(m_mem);
  197. }
  198. m_mem = other.m_mem;
  199. other.m_mem = 0;
  200. return *this;
  201. }
  202. #endif // BOOST_COMPUTE_NO_RVALUE_REFERENCES
  203. /// \internal_
  204. ~memory_object()
  205. {
  206. if(m_mem){
  207. BOOST_COMPUTE_ASSERT_CL_SUCCESS(
  208. clReleaseMemObject(m_mem)
  209. );
  210. }
  211. }
  212. protected:
  213. cl_mem m_mem;
  214. };
  215. namespace detail {
  216. // set_kernel_arg specialization for memory_object
  217. template<>
  218. struct set_kernel_arg<memory_object>
  219. {
  220. void operator()(kernel &kernel_, size_t index, const memory_object &mem)
  221. {
  222. kernel_.set_arg(index, mem.get());
  223. }
  224. };
  225. } // end detail namespace
  226. } // end compute namespace
  227. } // end boost namespace
  228. #endif // BOOST_COMPUTE_MEMORY_OBJECT_HPP