• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_ALGORITHM_EXCLUSIVE_SCAN_HPP
12 #define BOOST_COMPUTE_ALGORITHM_EXCLUSIVE_SCAN_HPP
13 
14 #include <boost/static_assert.hpp>
15 
16 #include <boost/compute/functional.hpp>
17 #include <boost/compute/system.hpp>
18 #include <boost/compute/command_queue.hpp>
19 #include <boost/compute/algorithm/detail/scan.hpp>
20 #include <boost/compute/type_traits/is_device_iterator.hpp>
21 
22 namespace boost {
23 namespace compute {
24 
25 /// Performs an exclusive scan of the elements in the range [\p first, \p last)
26 /// and stores the results in the range beginning at \p result.
27 ///
28 /// Each element in the output is assigned to the sum of all the previous
29 /// values in the input.
30 ///
31 /// \param first first element in the range to scan
32 /// \param last last element in the range to scan
33 /// \param result first element in the result range
34 /// \param init value used to initialize the scan sequence
35 /// \param binary_op associative binary operator
36 /// \param queue command queue to perform the operation
37 ///
38 /// \return \c OutputIterator to the end of the result range
39 ///
40 /// The default operation is to add the elements up.
41 ///
42 /// \snippet test/test_scan.cpp exclusive_scan_int
43 ///
44 /// But different associative operation can be specified as \p binary_op
45 /// instead (e.g., multiplication, maximum, minimum). Also value used to
46 /// initialized the scan sequence can be specified.
47 ///
48 /// \snippet test/test_scan.cpp exclusive_scan_int_multiplies
49 ///
50 /// Space complexity on GPUs: \Omega(n)<br>
51 /// Space complexity on GPUs when \p first == \p result: \Omega(2n)<br>
52 /// Space complexity on CPUs: \Omega(1)
53 ///
54 /// \see inclusive_scan()
55 template<class InputIterator, class OutputIterator, class T, class BinaryOperator>
56 inline OutputIterator
exclusive_scan(InputIterator first,InputIterator last,OutputIterator result,T init,BinaryOperator binary_op,command_queue & queue=system::default_queue ())57 exclusive_scan(InputIterator first,
58                InputIterator last,
59                OutputIterator result,
60                T init,
61                BinaryOperator binary_op,
62                command_queue &queue = system::default_queue())
63 {
64     BOOST_STATIC_ASSERT(is_device_iterator<InputIterator>::value);
65     BOOST_STATIC_ASSERT(is_device_iterator<OutputIterator>::value);
66     return detail::scan(first, last, result, true, init, binary_op, queue);
67 }
68 
69 /// \overload
70 template<class InputIterator, class OutputIterator, class T>
71 inline OutputIterator
exclusive_scan(InputIterator first,InputIterator last,OutputIterator result,T init,command_queue & queue=system::default_queue ())72 exclusive_scan(InputIterator first,
73                InputIterator last,
74                OutputIterator result,
75                T init,
76                command_queue &queue = system::default_queue())
77 {
78     BOOST_STATIC_ASSERT(is_device_iterator<InputIterator>::value);
79     BOOST_STATIC_ASSERT(is_device_iterator<OutputIterator>::value);
80     typedef typename
81         std::iterator_traits<OutputIterator>::value_type output_type;
82 
83     return detail::scan(first, last, result, true,
84                         init, boost::compute::plus<output_type>(),
85                         queue);
86 }
87 
88 /// \overload
89 template<class InputIterator, class OutputIterator>
90 inline OutputIterator
exclusive_scan(InputIterator first,InputIterator last,OutputIterator result,command_queue & queue=system::default_queue ())91 exclusive_scan(InputIterator first,
92                InputIterator last,
93                OutputIterator result,
94                command_queue &queue = system::default_queue())
95 {
96     BOOST_STATIC_ASSERT(is_device_iterator<InputIterator>::value);
97     BOOST_STATIC_ASSERT(is_device_iterator<OutputIterator>::value);
98     typedef typename
99         std::iterator_traits<OutputIterator>::value_type output_type;
100 
101     return detail::scan(first, last, result, true,
102                         output_type(0), boost::compute::plus<output_type>(),
103                         queue);
104 }
105 
106 } // end compute namespace
107 } // end boost namespace
108 
109 #endif // BOOST_COMPUTE_ALGORITHM_EXCLUSIVE_SCAN_HPP
110