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