serial_reduce.hpp 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  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_DETAIL_SERIAL_REDUCE_HPP
  11. #define BOOST_COMPUTE_ALGORITHM_DETAIL_SERIAL_REDUCE_HPP
  12. #include <boost/compute/command_queue.hpp>
  13. #include <boost/compute/detail/meta_kernel.hpp>
  14. #include <boost/compute/detail/iterator_range_size.hpp>
  15. #include <boost/compute/type_traits/result_of.hpp>
  16. namespace boost {
  17. namespace compute {
  18. namespace detail {
  19. // Space complexity: O(1)
  20. template<class InputIterator, class OutputIterator, class BinaryFunction>
  21. inline void serial_reduce(InputIterator first,
  22. InputIterator last,
  23. OutputIterator result,
  24. BinaryFunction function,
  25. command_queue &queue)
  26. {
  27. typedef typename
  28. std::iterator_traits<InputIterator>::value_type T;
  29. typedef typename
  30. ::boost::compute::result_of<BinaryFunction(T, T)>::type result_type;
  31. const context &context = queue.get_context();
  32. size_t count = detail::iterator_range_size(first, last);
  33. if(count == 0){
  34. return;
  35. }
  36. meta_kernel k("serial_reduce");
  37. size_t count_arg = k.add_arg<cl_uint>("count");
  38. k <<
  39. k.decl<result_type>("result") << " = " << first[0] << ";\n" <<
  40. "for(uint i = 1; i < count; i++)\n" <<
  41. " result = " << function(k.var<T>("result"),
  42. first[k.var<uint_>("i")]) << ";\n" <<
  43. result[0] << " = result;\n";
  44. kernel kernel = k.compile(context);
  45. kernel.set_arg(count_arg, static_cast<uint_>(count));
  46. queue.enqueue_task(kernel);
  47. }
  48. } // end detail namespace
  49. } // end compute namespace
  50. } // end boost namespace
  51. #endif // BOOST_COMPUTE_ALGORITHM_DETAIL_SERIAL_REDUCE_HPP