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