transform_reduce.hpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  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_TRANSFORM_REDUCE_HPP
  11. #define BOOST_COMPUTE_ALGORITHM_TRANSFORM_REDUCE_HPP
  12. #include <boost/static_assert.hpp>
  13. #include <boost/compute/system.hpp>
  14. #include <boost/compute/algorithm/reduce.hpp>
  15. #include <boost/compute/iterator/transform_iterator.hpp>
  16. #include <boost/compute/iterator/zip_iterator.hpp>
  17. #include <boost/compute/functional/detail/unpack.hpp>
  18. #include <boost/compute/detail/iterator_range_size.hpp>
  19. #include <boost/compute/type_traits/is_device_iterator.hpp>
  20. namespace boost {
  21. namespace compute {
  22. /// Transforms each value in the range [\p first, \p last) with the unary
  23. /// \p transform_function and then reduces each transformed value with
  24. /// \p reduce_function.
  25. ///
  26. /// For example, to calculate the sum of the absolute values of a vector
  27. /// of integers:
  28. ///
  29. /// \snippet test/test_transform_reduce.cpp sum_abs_int
  30. ///
  31. /// Space complexity on GPUs: \Omega(n)<br>
  32. /// Space complexity on CPUs: \Omega(1)
  33. ///
  34. /// \see reduce(), inner_product()
  35. template<class InputIterator,
  36. class OutputIterator,
  37. class UnaryTransformFunction,
  38. class BinaryReduceFunction>
  39. inline void transform_reduce(InputIterator first,
  40. InputIterator last,
  41. OutputIterator result,
  42. UnaryTransformFunction transform_function,
  43. BinaryReduceFunction reduce_function,
  44. command_queue &queue = system::default_queue())
  45. {
  46. BOOST_STATIC_ASSERT(is_device_iterator<InputIterator>::value);
  47. ::boost::compute::reduce(
  48. ::boost::compute::make_transform_iterator(first, transform_function),
  49. ::boost::compute::make_transform_iterator(last, transform_function),
  50. result,
  51. reduce_function,
  52. queue
  53. );
  54. }
  55. /// \overload
  56. template<class InputIterator1,
  57. class InputIterator2,
  58. class OutputIterator,
  59. class BinaryTransformFunction,
  60. class BinaryReduceFunction>
  61. inline void transform_reduce(InputIterator1 first1,
  62. InputIterator1 last1,
  63. InputIterator2 first2,
  64. OutputIterator result,
  65. BinaryTransformFunction transform_function,
  66. BinaryReduceFunction reduce_function,
  67. command_queue &queue = system::default_queue())
  68. {
  69. BOOST_STATIC_ASSERT(is_device_iterator<InputIterator1>::value);
  70. BOOST_STATIC_ASSERT(is_device_iterator<InputIterator2>::value);
  71. BOOST_STATIC_ASSERT(is_device_iterator<OutputIterator>::value);
  72. typedef typename std::iterator_traits<InputIterator1>::difference_type difference_type;
  73. difference_type n = std::distance(first1, last1);
  74. ::boost::compute::transform_reduce(
  75. ::boost::compute::make_zip_iterator(
  76. boost::make_tuple(first1, first2)
  77. ),
  78. ::boost::compute::make_zip_iterator(
  79. boost::make_tuple(last1, first2 + n)
  80. ),
  81. result,
  82. detail::unpack(transform_function),
  83. reduce_function,
  84. queue
  85. );
  86. }
  87. } // end compute namespace
  88. } // end boost namespace
  89. #endif // BOOST_COMPUTE_ALGORITHM_TRANSFORM_REDUCE_HPP