exclusive_scan.hpp 3.9 KB

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