1 //---------------------------------------------------------------------------//
2 // Copyright (c) 2013-2014 Kyle Lutz <kyle.r.lutz@gmail.com>
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
8 // See http://boostorg.github.com/compute for more information.
9 //---------------------------------------------------------------------------//
11 #ifndef BOOST_COMPUTE_DETAIL_GET_OBJECT_INFO_HPP
12 #define BOOST_COMPUTE_DETAIL_GET_OBJECT_INFO_HPP
17 #include <boost/preprocessor/seq/for_each.hpp>
18 #include <boost/preprocessor/tuple/elem.hpp>
20 #include <boost/throw_exception.hpp>
22 #include <boost/compute/cl.hpp>
23 #include <boost/compute/exception/opencl_error.hpp>
29 template<class Function, class Object, class AuxInfo>
30 struct bound_info_function
32 bound_info_function(Function function, Object object, AuxInfo aux_info)
33 : m_function(function),
40 cl_int operator()(Info info, size_t input_size, const void *input,
41 size_t size, void *value, size_t *size_ret) const
44 m_object, m_aux_info, info,
45 input_size, input, size, value, size_ret
50 cl_int operator()(Info info, size_t size, void *value, size_t *size_ret) const
52 return m_function(m_object, m_aux_info, info, size, value, size_ret);
60 template<class Function, class Object>
61 struct bound_info_function<Function, Object, void>
63 bound_info_function(Function function, Object object)
64 : m_function(function),
70 cl_int operator()(Info info, size_t size, void *value, size_t *size_ret) const
72 return m_function(m_object, info, size, value, size_ret);
79 template<class Function, class Object>
80 inline bound_info_function<Function, Object, void>
81 bind_info_function(Function f, Object o)
83 return bound_info_function<Function, Object, void>(f, o);
86 template<class Function, class Object, class AuxInfo>
87 inline bound_info_function<Function, Object, AuxInfo>
88 bind_info_function(Function f, Object o, AuxInfo j)
90 return bound_info_function<Function, Object, AuxInfo>(f, o, j);
93 // default implementation
95 struct get_object_info_impl
97 template<class Function, class Info>
98 T operator()(Function function, Info info) const
102 cl_int ret = function(info, sizeof(T), &value, 0);
103 if(ret != CL_SUCCESS){
104 BOOST_THROW_EXCEPTION(opencl_error(ret));
110 template<class Function, class Info>
111 T operator()(Function function, Info info,
112 const size_t input_size, const void* input) const
116 cl_int ret = function(info, input_size, input, sizeof(T), &value, 0);
117 if(ret != CL_SUCCESS){
118 BOOST_THROW_EXCEPTION(opencl_error(ret));
125 // specialization for bool
127 struct get_object_info_impl<bool>
129 template<class Function, class Info>
130 bool operator()(Function function, Info info) const
134 cl_int ret = function(info, sizeof(cl_bool), &value, 0);
135 if(ret != CL_SUCCESS){
136 BOOST_THROW_EXCEPTION(opencl_error(ret));
139 return value == CL_TRUE;
143 // specialization for std::string
145 struct get_object_info_impl<std::string>
147 template<class Function, class Info>
148 std::string operator()(Function function, Info info) const
152 cl_int ret = function(info, 0, 0, &size);
153 if(ret != CL_SUCCESS){
154 BOOST_THROW_EXCEPTION(opencl_error(ret));
158 return std::string();
161 std::string value(size - 1, 0);
163 ret = function(info, size, &value[0], 0);
164 if(ret != CL_SUCCESS){
165 BOOST_THROW_EXCEPTION(opencl_error(ret));
172 // specialization for std::vector<T>
174 struct get_object_info_impl<std::vector<T> >
176 template<class Function, class Info>
177 std::vector<T> operator()(Function function, Info info) const
181 cl_int ret = function(info, 0, 0, &size);
182 if(ret != CL_SUCCESS){
183 BOOST_THROW_EXCEPTION(opencl_error(ret));
186 if(size == 0) return std::vector<T>();
188 std::vector<T> vector(size / sizeof(T));
189 ret = function(info, size, &vector[0], 0);
190 if(ret != CL_SUCCESS){
191 BOOST_THROW_EXCEPTION(opencl_error(ret));
197 template<class Function, class Info>
198 std::vector<T> operator()(Function function, Info info,
199 const size_t input_size, const void* input) const
201 #ifdef BOOST_COMPUTE_CL_VERSION_2_1
202 // For CL_KERNEL_LOCAL_SIZE_FOR_SUB_GROUP_COUNT in clGetKernelSubGroupInfo
203 // we can't get param_value_size using param_value_size_ret
204 if(info == CL_KERNEL_LOCAL_SIZE_FOR_SUB_GROUP_COUNT)
206 std::vector<T> vector(3);
207 cl_int ret = function(
208 info, input_size, input,
209 sizeof(T) * vector.size(), &vector[0], 0
211 if(ret != CL_SUCCESS){
212 BOOST_THROW_EXCEPTION(opencl_error(ret));
219 cl_int ret = function(info, input_size, input, 0, 0, &size);
220 if(ret != CL_SUCCESS){
221 BOOST_THROW_EXCEPTION(opencl_error(ret));
224 std::vector<T> vector(size / sizeof(T));
225 ret = function(info, input_size, input, size, &vector[0], 0);
226 if(ret != CL_SUCCESS){
227 BOOST_THROW_EXCEPTION(opencl_error(ret));
234 // returns the value (of type T) from the given clGet*Info() function call.
235 template<class T, class Function, class Object, class Info>
236 inline T get_object_info(Function f, Object o, Info i)
238 return get_object_info_impl<T>()(bind_info_function(f, o), i);
241 template<class T, class Function, class Object, class Info, class AuxInfo>
242 inline T get_object_info(Function f, Object o, Info i, AuxInfo j)
244 return get_object_info_impl<T>()(bind_info_function(f, o, j), i);
247 template<class T, class Function, class Object, class Info, class AuxInfo>
248 inline T get_object_info(Function f, Object o, Info i, AuxInfo j, const size_t k, const void * l)
250 return get_object_info_impl<T>()(bind_info_function(f, o, j), i, k, l);
253 // returns the value type for the clGet*Info() call on Object with Enum.
254 template<class Object, int Enum>
255 struct get_object_info_type;
257 // defines the object::get_info<Enum>() specialization
258 #define BOOST_COMPUTE_DETAIL_DEFINE_GET_INFO_SPECIALIZATION(object_type, result_type, value) \
260 template<> struct get_object_info_type<object_type, value> { typedef result_type type; }; \
262 template<> inline result_type object_type::get_info<value>() const \
264 return get_info<result_type>(value); \
267 // used by BOOST_COMPUTE_DETAIL_DEFINE_GET_INFO_SPECIALIZATIONS()
268 #define BOOST_COMPUTE_DETAIL_DEFINE_GET_INFO_IMPL(r, data, elem) \
269 BOOST_COMPUTE_DETAIL_DEFINE_GET_INFO_SPECIALIZATION( \
270 data, BOOST_PP_TUPLE_ELEM(2, 0, elem), BOOST_PP_TUPLE_ELEM(2, 1, elem) \
273 // defines the object::get_info<Enum>() specialization for each
274 // (result_type, value) tuple in seq for object_type.
275 #define BOOST_COMPUTE_DETAIL_DEFINE_GET_INFO_SPECIALIZATIONS(object_type, seq) \
276 BOOST_PP_SEQ_FOR_EACH( \
277 BOOST_COMPUTE_DETAIL_DEFINE_GET_INFO_IMPL, object_type, seq \
280 } // end detail namespace
281 } // end compute namespace
282 } // end boost namespace
284 #endif // BOOST_COMPUTE_DETAIL_GET_OBJECT_INFO_HPP