]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/compute/include/boost/compute/container/valarray.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / compute / include / boost / compute / container / valarray.hpp
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_CONTAINER_VALARRAY_HPP
12 #define BOOST_COMPUTE_CONTAINER_VALARRAY_HPP
13
14 #include <cstddef>
15 #include <valarray>
16
17 #include <boost/static_assert.hpp>
18 #include <boost/type_traits.hpp>
19
20 #include <boost/compute/buffer.hpp>
21 #include <boost/compute/algorithm/copy.hpp>
22 #include <boost/compute/algorithm/fill.hpp>
23 #include <boost/compute/algorithm/max_element.hpp>
24 #include <boost/compute/algorithm/min_element.hpp>
25 #include <boost/compute/algorithm/transform.hpp>
26 #include <boost/compute/algorithm/accumulate.hpp>
27 #include <boost/compute/detail/buffer_value.hpp>
28 #include <boost/compute/functional.hpp>
29 #include <boost/compute/functional/bind.hpp>
30 #include <boost/compute/iterator/buffer_iterator.hpp>
31 #include <boost/compute/type_traits.hpp>
32
33 namespace boost {
34 namespace compute {
35
36 template<class T>
37 class valarray
38 {
39 public:
40 explicit valarray(const context &context = system::default_context())
41 : m_buffer(context, 0)
42 {
43 }
44
45 explicit valarray(size_t size,
46 const context &context = system::default_context())
47 : m_buffer(context, size * sizeof(T))
48 {
49 }
50
51 valarray(const T &value,
52 size_t size,
53 const context &context = system::default_context())
54 : m_buffer(context, size * sizeof(T))
55 {
56 fill(begin(), end(), value);
57 }
58
59 valarray(const T *values,
60 size_t size,
61 const context &context = system::default_context())
62 : m_buffer(context, size * sizeof(T))
63 {
64 copy(values, values + size, begin());
65 }
66
67 valarray(const valarray<T> &other)
68 : m_buffer(other.m_buffer.get_context(), other.size() * sizeof(T))
69 {
70 }
71
72 valarray(const std::valarray<T> &valarray,
73 const context &context = system::default_context())
74 : m_buffer(context, valarray.size() * sizeof(T))
75 {
76 copy(&valarray[0], &valarray[valarray.size()], begin());
77 }
78
79 valarray<T>& operator=(const valarray<T> &other)
80 {
81 if(this != &other){
82 // change to other's OpenCL context
83 m_buffer = buffer(other.m_buffer.get_context(), other.size() * sizeof(T));
84 copy(other.begin(), other.end(), begin());
85 }
86
87 return *this;
88 }
89
90 valarray<T>& operator=(const std::valarray<T> &valarray)
91 {
92 m_buffer = buffer(m_buffer.get_context(), valarray.size() * sizeof(T));
93 copy(&valarray[0], &valarray[valarray.size()], begin());
94
95 return *this;
96 }
97
98 valarray<T>& operator*=(const T&);
99
100 valarray<T>& operator/=(const T&);
101
102 valarray<T>& operator%=(const T& val);
103
104 valarray<T> operator+() const
105 {
106 // This operator can be used with any type.
107 valarray<T> result(size());
108 copy(begin(), end(), result.begin());
109 return result;
110 }
111
112 valarray<T> operator-() const
113 {
114 BOOST_STATIC_ASSERT_MSG(
115 is_fundamental<T>::value,
116 "This operator can be used with all OpenCL built-in scalar"
117 " and vector types"
118 );
119 valarray<T> result(size());
120 BOOST_COMPUTE_FUNCTION(T, unary_minus, (T x),
121 {
122 return -x;
123 });
124 transform(begin(), end(), result.begin(), unary_minus);
125 return result;
126 }
127
128 valarray<T> operator~() const
129 {
130 BOOST_STATIC_ASSERT_MSG(
131 is_fundamental<T>::value &&
132 !is_floating_point<typename scalar_type<T>::type>::value,
133 "This operator can be used with all OpenCL built-in scalar"
134 " and vector types except the built-in scalar and vector float types"
135 );
136 valarray<T> result(size());
137 BOOST_COMPUTE_FUNCTION(T, bitwise_not, (T x),
138 {
139 return ~x;
140 });
141 transform(begin(), end(), result.begin(), bitwise_not);
142 return result;
143 }
144
145 /// In OpenCL there cannot be memory buffer with bool type, for
146 /// this reason return type is valarray<char> instead of valarray<bool>.
147 /// 1 means true, 0 means false.
148 valarray<char> operator!() const
149 {
150 BOOST_STATIC_ASSERT_MSG(
151 is_fundamental<T>::value,
152 "This operator can be used with all OpenCL built-in scalar"
153 " and vector types"
154 );
155 valarray<char> result(size());
156 BOOST_COMPUTE_FUNCTION(char, logical_not, (T x),
157 {
158 return !x;
159 });
160 transform(begin(), end(), &result[0], logical_not);
161 return result;
162 }
163
164 valarray<T>& operator+=(const T&);
165
166 valarray<T>& operator-=(const T&);
167
168 valarray<T>& operator^=(const T&);
169
170 valarray<T>& operator&=(const T&);
171
172 valarray<T>& operator|=(const T&);
173
174 valarray<T>& operator<<=(const T&);
175
176 valarray<T>& operator>>=(const T&);
177
178 valarray<T>& operator*=(const valarray<T>&);
179
180 valarray<T>& operator/=(const valarray<T>&);
181
182 valarray<T>& operator%=(const valarray<T>&);
183
184 valarray<T>& operator+=(const valarray<T>&);
185
186 valarray<T>& operator-=(const valarray<T>&);
187
188 valarray<T>& operator^=(const valarray<T>&);
189
190 valarray<T>& operator&=(const valarray<T>&);
191
192 valarray<T>& operator|=(const valarray<T>&);
193
194 valarray<T>& operator<<=(const valarray<T>&);
195
196 valarray<T>& operator>>=(const valarray<T>&);
197
198 ~valarray()
199 {
200
201 }
202
203 size_t size() const
204 {
205 return m_buffer.size() / sizeof(T);
206 }
207
208 void resize(size_t size, T value = T())
209 {
210 m_buffer = buffer(m_buffer.get_context(), size * sizeof(T));
211 fill(begin(), end(), value);
212 }
213
214 detail::buffer_value<T> operator[](size_t index)
215 {
216 return *(begin() + static_cast<ptrdiff_t>(index));
217 }
218
219 const detail::buffer_value<T> operator[](size_t index) const
220 {
221 return *(begin() + static_cast<ptrdiff_t>(index));
222 }
223
224 T (min)() const
225 {
226 return *(boost::compute::min_element(begin(), end()));
227 }
228
229 T (max)() const
230 {
231 return *(boost::compute::max_element(begin(), end()));
232 }
233
234 T sum() const
235 {
236 return boost::compute::accumulate(begin(), end(), T(0));
237 }
238
239 template<class UnaryFunction>
240 valarray<T> apply(UnaryFunction function) const
241 {
242 valarray<T> result(size());
243 transform(begin(), end(), result.begin(), function);
244 return result;
245 }
246
247 const buffer& get_buffer() const
248 {
249 return m_buffer;
250 }
251
252
253 private:
254 buffer_iterator<T> begin() const
255 {
256 return buffer_iterator<T>(m_buffer, 0);
257 }
258
259 buffer_iterator<T> end() const
260 {
261 return buffer_iterator<T>(m_buffer, size());
262 }
263
264 private:
265 buffer m_buffer;
266 };
267
268 /// \internal_
269 #define BOOST_COMPUTE_DEFINE_VALARRAY_COMPOUND_ASSIGNMENT(op, op_name, assert) \
270 template<class T> \
271 inline valarray<T>& \
272 valarray<T>::operator op##=(const T& val) \
273 { \
274 assert \
275 transform(begin(), end(), begin(), \
276 ::boost::compute::bind(op_name<T>(), placeholders::_1, val)); \
277 return *this; \
278 } \
279 \
280 template<class T> \
281 inline valarray<T>& \
282 valarray<T>::operator op##=(const valarray<T> &rhs) \
283 { \
284 assert \
285 transform(begin(), end(), rhs.begin(), begin(), op_name<T>()); \
286 return *this; \
287 }
288
289 /// \internal_
290 #define BOOST_COMPUTE_DEFINE_VALARRAY_COMPOUND_ASSIGNMENT_ANY(op, op_name) \
291 BOOST_COMPUTE_DEFINE_VALARRAY_COMPOUND_ASSIGNMENT(op, op_name, \
292 BOOST_STATIC_ASSERT_MSG( \
293 is_fundamental<T>::value, \
294 "This operator can be used with all OpenCL built-in scalar" \
295 " and vector types" \
296 ); \
297 )
298
299 /// \internal_
300 /// For some operators class T can't be floating point type.
301 /// See OpenCL specification, operators chapter.
302 #define BOOST_COMPUTE_DEFINE_VALARRAY_COMPOUND_ASSIGNMENT_NO_FP(op, op_name) \
303 BOOST_COMPUTE_DEFINE_VALARRAY_COMPOUND_ASSIGNMENT(op, op_name, \
304 BOOST_STATIC_ASSERT_MSG( \
305 is_fundamental<T>::value && \
306 !is_floating_point<typename scalar_type<T>::type>::value, \
307 "This operator can be used with all OpenCL built-in scalar" \
308 " and vector types except the built-in scalar and vector float types" \
309 ); \
310 )
311
312 // defining operators
313 BOOST_COMPUTE_DEFINE_VALARRAY_COMPOUND_ASSIGNMENT_ANY(+, plus)
314 BOOST_COMPUTE_DEFINE_VALARRAY_COMPOUND_ASSIGNMENT_ANY(-, minus)
315 BOOST_COMPUTE_DEFINE_VALARRAY_COMPOUND_ASSIGNMENT_ANY(*, multiplies)
316 BOOST_COMPUTE_DEFINE_VALARRAY_COMPOUND_ASSIGNMENT_ANY(/, divides)
317 BOOST_COMPUTE_DEFINE_VALARRAY_COMPOUND_ASSIGNMENT_NO_FP(^, bit_xor)
318 BOOST_COMPUTE_DEFINE_VALARRAY_COMPOUND_ASSIGNMENT_NO_FP(&, bit_and)
319 BOOST_COMPUTE_DEFINE_VALARRAY_COMPOUND_ASSIGNMENT_NO_FP(|, bit_or)
320 BOOST_COMPUTE_DEFINE_VALARRAY_COMPOUND_ASSIGNMENT_NO_FP(<<, shift_left)
321 BOOST_COMPUTE_DEFINE_VALARRAY_COMPOUND_ASSIGNMENT_NO_FP(>>, shift_right)
322
323 // The remainder (%) operates on
324 // integer scalar and integer vector data types only.
325 // See OpenCL specification.
326 BOOST_COMPUTE_DEFINE_VALARRAY_COMPOUND_ASSIGNMENT(%, modulus,
327 BOOST_STATIC_ASSERT_MSG(
328 is_integral<typename scalar_type<T>::type>::value,
329 "This operator can be used only with OpenCL built-in integer types"
330 );
331 )
332
333 #undef BOOST_COMPUTE_DEFINE_VALARRAY_COMPOUND_ASSIGNMENT_ANY
334 #undef BOOST_COMPUTE_DEFINE_VALARRAY_COMPOUND_ASSIGNMENT_NO_FP
335
336 #undef BOOST_COMPUTE_DEFINE_VALARRAY_COMPOUND_ASSIGNMENT
337
338 /// \internal_
339 /// Macro for defining binary operators for valarray
340 #define BOOST_COMPUTE_DEFINE_VALARRAY_BINARY_OPERATOR(op, op_name, assert) \
341 template<class T> \
342 valarray<T> operator op (const valarray<T>& lhs, const valarray<T>& rhs) \
343 { \
344 assert \
345 valarray<T> result(lhs.size()); \
346 transform(buffer_iterator<T>(lhs.get_buffer(), 0), \
347 buffer_iterator<T>(lhs.get_buffer(), lhs.size()), \
348 buffer_iterator<T>(rhs.get_buffer(), 0), \
349 buffer_iterator<T>(result.get_buffer(), 0), \
350 op_name<T>()); \
351 return result; \
352 } \
353 \
354 template<class T> \
355 valarray<T> operator op (const T& val, const valarray<T>& rhs) \
356 { \
357 assert \
358 valarray<T> result(rhs.size()); \
359 transform(buffer_iterator<T>(rhs.get_buffer(), 0), \
360 buffer_iterator<T>(rhs.get_buffer(), rhs.size()), \
361 buffer_iterator<T>(result.get_buffer(), 0), \
362 ::boost::compute::bind(op_name<T>(), val, placeholders::_1)); \
363 return result; \
364 } \
365 \
366 template<class T> \
367 valarray<T> operator op (const valarray<T>& lhs, const T& val) \
368 { \
369 assert \
370 valarray<T> result(lhs.size()); \
371 transform(buffer_iterator<T>(lhs.get_buffer(), 0), \
372 buffer_iterator<T>(lhs.get_buffer(), lhs.size()), \
373 buffer_iterator<T>(result.get_buffer(), 0), \
374 ::boost::compute::bind(op_name<T>(), placeholders::_1, val)); \
375 return result; \
376 }
377
378 /// \internal_
379 #define BOOST_COMPUTE_DEFINE_VALARRAY_BINARY_OPERATOR_ANY(op, op_name) \
380 BOOST_COMPUTE_DEFINE_VALARRAY_BINARY_OPERATOR(op, op_name, \
381 BOOST_STATIC_ASSERT_MSG( \
382 is_fundamental<T>::value, \
383 "This operator can be used with all OpenCL built-in scalar" \
384 " and vector types" \
385 ); \
386 )
387
388 /// \internal_
389 /// For some operators class T can't be floating point type.
390 /// See OpenCL specification, operators chapter.
391 #define BOOST_COMPUTE_DEFINE_VALARRAY_BINARY_OPERATOR_NO_FP(op, op_name) \
392 BOOST_COMPUTE_DEFINE_VALARRAY_BINARY_OPERATOR(op, op_name, \
393 BOOST_STATIC_ASSERT_MSG( \
394 is_fundamental<T>::value && \
395 !is_floating_point<typename scalar_type<T>::type>::value, \
396 "This operator can be used with all OpenCL built-in scalar" \
397 " and vector types except the built-in scalar and vector float types" \
398 ); \
399 )
400
401 // defining binary operators for valarray
402 BOOST_COMPUTE_DEFINE_VALARRAY_BINARY_OPERATOR_ANY(+, plus)
403 BOOST_COMPUTE_DEFINE_VALARRAY_BINARY_OPERATOR_ANY(-, minus)
404 BOOST_COMPUTE_DEFINE_VALARRAY_BINARY_OPERATOR_ANY(*, multiplies)
405 BOOST_COMPUTE_DEFINE_VALARRAY_BINARY_OPERATOR_ANY(/, divides)
406 BOOST_COMPUTE_DEFINE_VALARRAY_BINARY_OPERATOR_NO_FP(^, bit_xor)
407 BOOST_COMPUTE_DEFINE_VALARRAY_BINARY_OPERATOR_NO_FP(&, bit_and)
408 BOOST_COMPUTE_DEFINE_VALARRAY_BINARY_OPERATOR_NO_FP(|, bit_or)
409 BOOST_COMPUTE_DEFINE_VALARRAY_BINARY_OPERATOR_NO_FP(<<, shift_left)
410 BOOST_COMPUTE_DEFINE_VALARRAY_BINARY_OPERATOR_NO_FP(>>, shift_right)
411
412 #undef BOOST_COMPUTE_DEFINE_VALARRAY_BINARY_OPERATOR_ANY
413 #undef BOOST_COMPUTE_DEFINE_VALARRAY_BINARY_OPERATOR_NO_FP
414
415 #undef BOOST_COMPUTE_DEFINE_VALARRAY_BINARY_OPERATOR
416
417 /// \internal_
418 /// Macro for defining valarray comparison operators.
419 /// For return type valarray<char> is used instead of valarray<bool> because
420 /// in OpenCL there cannot be memory buffer with bool type.
421 ///
422 /// Note it's also used for defining binary logical operators (==, &&)
423 #define BOOST_COMPUTE_DEFINE_VALARRAY_COMPARISON_OPERATOR(op, op_name) \
424 template<class T> \
425 valarray<char> operator op (const valarray<T>& lhs, const valarray<T>& rhs) \
426 { \
427 BOOST_STATIC_ASSERT_MSG( \
428 is_fundamental<T>::value, \
429 "This operator can be used with all OpenCL built-in scalar" \
430 " and vector types" \
431 ); \
432 valarray<char> result(lhs.size()); \
433 transform(buffer_iterator<T>(lhs.get_buffer(), 0), \
434 buffer_iterator<T>(lhs.get_buffer(), lhs.size()), \
435 buffer_iterator<T>(rhs.get_buffer(), 0), \
436 buffer_iterator<char>(result.get_buffer(), 0), \
437 op_name<T>()); \
438 return result; \
439 } \
440 \
441 template<class T> \
442 valarray<char> operator op (const T& val, const valarray<T>& rhs) \
443 { \
444 BOOST_STATIC_ASSERT_MSG( \
445 is_fundamental<T>::value, \
446 "This operator can be used with all OpenCL built-in scalar" \
447 " and vector types" \
448 ); \
449 valarray<char> result(rhs.size()); \
450 transform(buffer_iterator<T>(rhs.get_buffer(), 0), \
451 buffer_iterator<T>(rhs.get_buffer(), rhs.size()), \
452 buffer_iterator<char>(result.get_buffer(), 0), \
453 ::boost::compute::bind(op_name<T>(), val, placeholders::_1)); \
454 return result; \
455 } \
456 \
457 template<class T> \
458 valarray<char> operator op (const valarray<T>& lhs, const T& val) \
459 { \
460 BOOST_STATIC_ASSERT_MSG( \
461 is_fundamental<T>::value, \
462 "This operator can be used with all OpenCL built-in scalar" \
463 " and vector types" \
464 ); \
465 valarray<char> result(lhs.size()); \
466 transform(buffer_iterator<T>(lhs.get_buffer(), 0), \
467 buffer_iterator<T>(lhs.get_buffer(), lhs.size()), \
468 buffer_iterator<char>(result.get_buffer(), 0), \
469 ::boost::compute::bind(op_name<T>(), placeholders::_1, val)); \
470 return result; \
471 }
472
473 BOOST_COMPUTE_DEFINE_VALARRAY_COMPARISON_OPERATOR(==, equal_to)
474 BOOST_COMPUTE_DEFINE_VALARRAY_COMPARISON_OPERATOR(!=, not_equal_to)
475 BOOST_COMPUTE_DEFINE_VALARRAY_COMPARISON_OPERATOR(>, greater)
476 BOOST_COMPUTE_DEFINE_VALARRAY_COMPARISON_OPERATOR(<, less)
477 BOOST_COMPUTE_DEFINE_VALARRAY_COMPARISON_OPERATOR(>=, greater_equal)
478 BOOST_COMPUTE_DEFINE_VALARRAY_COMPARISON_OPERATOR(<=, less_equal)
479
480 /// \internal_
481 /// Macro for defining binary logical operators for valarray.
482 ///
483 /// For return type valarray<char> is used instead of valarray<bool> because
484 /// in OpenCL there cannot be memory buffer with bool type.
485 /// 1 means true, 0 means false.
486 #define BOOST_COMPUTE_DEFINE_VALARRAY_LOGICAL_OPERATOR(op, op_name) \
487 BOOST_COMPUTE_DEFINE_VALARRAY_COMPARISON_OPERATOR(op, op_name)
488
489 BOOST_COMPUTE_DEFINE_VALARRAY_LOGICAL_OPERATOR(&&, logical_and)
490 BOOST_COMPUTE_DEFINE_VALARRAY_LOGICAL_OPERATOR(||, logical_or)
491
492 #undef BOOST_COMPUTE_DEFINE_VALARRAY_LOGICAL_OPERATOR
493
494 #undef BOOST_COMPUTE_DEFINE_VALARRAY_COMPARISON_OPERATOR
495
496 } // end compute namespace
497 } // end boost namespace
498
499 #endif // BOOST_COMPUTE_CONTAINER_VALARRAY_HPP