]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | //---------------------------------------------------------------------------// |
2 | // Copyright (c) 2013-2014 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_DETAIL_GET_OBJECT_INFO_HPP | |
12 | #define BOOST_COMPUTE_DETAIL_GET_OBJECT_INFO_HPP | |
13 | ||
14 | #include <string> | |
15 | #include <vector> | |
16 | ||
17 | #include <boost/preprocessor/seq/for_each.hpp> | |
18 | #include <boost/preprocessor/tuple/elem.hpp> | |
19 | ||
20 | #include <boost/throw_exception.hpp> | |
21 | ||
22 | #include <boost/compute/cl.hpp> | |
23 | #include <boost/compute/exception/opencl_error.hpp> | |
24 | ||
25 | namespace boost { | |
26 | namespace compute { | |
27 | namespace detail { | |
28 | ||
29 | template<class Function, class Object, class AuxInfo> | |
30 | struct bound_info_function | |
31 | { | |
32 | bound_info_function(Function function, Object object, AuxInfo aux_info) | |
33 | : m_function(function), | |
34 | m_object(object), | |
35 | m_aux_info(aux_info) | |
36 | { | |
37 | } | |
38 | ||
39 | template<class Info> | |
40 | cl_int operator()(Info info, size_t size, void *value, size_t *size_ret) const | |
41 | { | |
42 | return m_function(m_object, m_aux_info, info, size, value, size_ret); | |
43 | } | |
44 | ||
45 | Function m_function; | |
46 | Object m_object; | |
47 | AuxInfo m_aux_info; | |
48 | }; | |
49 | ||
50 | template<class Function, class Object> | |
51 | struct bound_info_function<Function, Object, void> | |
52 | { | |
53 | bound_info_function(Function function, Object object) | |
54 | : m_function(function), | |
55 | m_object(object) | |
56 | { | |
57 | } | |
58 | ||
59 | template<class Info> | |
60 | cl_int operator()(Info info, size_t size, void *value, size_t *size_ret) const | |
61 | { | |
62 | return m_function(m_object, info, size, value, size_ret); | |
63 | } | |
64 | ||
65 | Function m_function; | |
66 | Object m_object; | |
67 | }; | |
68 | ||
69 | template<class Function, class Object> | |
70 | inline bound_info_function<Function, Object, void> | |
71 | bind_info_function(Function f, Object o) | |
72 | { | |
73 | return bound_info_function<Function, Object, void>(f, o); | |
74 | } | |
75 | ||
76 | template<class Function, class Object, class AuxInfo> | |
77 | inline bound_info_function<Function, Object, AuxInfo> | |
78 | bind_info_function(Function f, Object o, AuxInfo j) | |
79 | { | |
80 | return bound_info_function<Function, Object, AuxInfo>(f, o, j); | |
81 | } | |
82 | ||
83 | // default implementation | |
84 | template<class T> | |
85 | struct get_object_info_impl | |
86 | { | |
87 | template<class Function, class Info> | |
88 | T operator()(Function function, Info info) const | |
89 | { | |
90 | T value; | |
91 | ||
92 | cl_int ret = function(info, sizeof(T), &value, 0); | |
93 | if(ret != CL_SUCCESS){ | |
94 | BOOST_THROW_EXCEPTION(opencl_error(ret)); | |
95 | } | |
96 | ||
97 | return value; | |
98 | } | |
99 | }; | |
100 | ||
101 | // specialization for bool | |
102 | template<> | |
103 | struct get_object_info_impl<bool> | |
104 | { | |
105 | template<class Function, class Info> | |
106 | bool operator()(Function function, Info info) const | |
107 | { | |
108 | cl_bool value; | |
109 | ||
110 | cl_int ret = function(info, sizeof(cl_bool), &value, 0); | |
111 | if(ret != CL_SUCCESS){ | |
112 | BOOST_THROW_EXCEPTION(opencl_error(ret)); | |
113 | } | |
114 | ||
115 | return value == CL_TRUE; | |
116 | } | |
117 | }; | |
118 | ||
119 | // specialization for std::string | |
120 | template<> | |
121 | struct get_object_info_impl<std::string> | |
122 | { | |
123 | template<class Function, class Info> | |
124 | std::string operator()(Function function, Info info) const | |
125 | { | |
126 | size_t size = 0; | |
127 | ||
128 | cl_int ret = function(info, 0, 0, &size); | |
129 | if(ret != CL_SUCCESS){ | |
130 | BOOST_THROW_EXCEPTION(opencl_error(ret)); | |
131 | } | |
132 | ||
133 | if(size == 0){ | |
134 | return std::string(); | |
135 | } | |
136 | ||
137 | std::string value(size - 1, 0); | |
138 | ||
139 | ret = function(info, size, &value[0], 0); | |
140 | if(ret != CL_SUCCESS){ | |
141 | BOOST_THROW_EXCEPTION(opencl_error(ret)); | |
142 | } | |
143 | ||
144 | return value; | |
145 | } | |
146 | }; | |
147 | ||
148 | // specialization for std::vector<T> | |
149 | template<class T> | |
150 | struct get_object_info_impl<std::vector<T> > | |
151 | { | |
152 | template<class Function, class Info> | |
153 | std::vector<T> operator()(Function function, Info info) const | |
154 | { | |
155 | size_t size = 0; | |
156 | ||
157 | cl_int ret = function(info, 0, 0, &size); | |
158 | if(ret != CL_SUCCESS){ | |
159 | BOOST_THROW_EXCEPTION(opencl_error(ret)); | |
160 | } | |
161 | ||
162 | std::vector<T> vector(size / sizeof(T)); | |
163 | ret = function(info, size, &vector[0], 0); | |
164 | if(ret != CL_SUCCESS){ | |
165 | BOOST_THROW_EXCEPTION(opencl_error(ret)); | |
166 | } | |
167 | ||
168 | return vector; | |
169 | } | |
170 | }; | |
171 | ||
172 | // returns the value (of type T) from the given clGet*Info() function call. | |
173 | template<class T, class Function, class Object, class Info> | |
174 | inline T get_object_info(Function f, Object o, Info i) | |
175 | { | |
176 | return get_object_info_impl<T>()(bind_info_function(f, o), i); | |
177 | } | |
178 | ||
179 | template<class T, class Function, class Object, class Info, class AuxInfo> | |
180 | inline T get_object_info(Function f, Object o, Info i, AuxInfo j) | |
181 | { | |
182 | return get_object_info_impl<T>()(bind_info_function(f, o, j), i); | |
183 | } | |
184 | ||
185 | // returns the value type for the clGet*Info() call on Object with Enum. | |
186 | template<class Object, int Enum> | |
187 | struct get_object_info_type; | |
188 | ||
189 | // defines the object::get_info<Enum>() specialization | |
190 | #define BOOST_COMPUTE_DETAIL_DEFINE_GET_INFO_SPECIALIZATION(object_type, result_type, value) \ | |
191 | namespace detail { \ | |
192 | template<> struct get_object_info_type<object_type, value> { typedef result_type type; }; \ | |
193 | } \ | |
194 | template<> inline result_type object_type::get_info<value>() const \ | |
195 | { \ | |
196 | return get_info<result_type>(value); \ | |
197 | } | |
198 | ||
199 | // used by BOOST_COMPUTE_DETAIL_DEFINE_GET_INFO_SPECIALIZATIONS() | |
200 | #define BOOST_COMPUTE_DETAIL_DEFINE_GET_INFO_IMPL(r, data, elem) \ | |
201 | BOOST_COMPUTE_DETAIL_DEFINE_GET_INFO_SPECIALIZATION( \ | |
202 | data, BOOST_PP_TUPLE_ELEM(2, 0, elem), BOOST_PP_TUPLE_ELEM(2, 1, elem) \ | |
203 | ) | |
204 | ||
205 | // defines the object::get_info<Enum>() specialization for each | |
206 | // (result_type, value) tuple in seq for object_type. | |
207 | #define BOOST_COMPUTE_DETAIL_DEFINE_GET_INFO_SPECIALIZATIONS(object_type, seq) \ | |
208 | BOOST_PP_SEQ_FOR_EACH( \ | |
209 | BOOST_COMPUTE_DETAIL_DEFINE_GET_INFO_IMPL, object_type, seq \ | |
210 | ) | |
211 | ||
212 | } // end detail namespace | |
213 | } // end compute namespace | |
214 | } // end boost namespace | |
215 | ||
216 | #endif // BOOST_COMPUTE_DETAIL_GET_OBJECT_INFO_HPP |