Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:29:55

0001 //---------------------------------------------------------------------------//
0002 // Copyright (c) 2015 Jakub Szuppe <j.szuppe@gmail.com>
0003 //
0004 // Distributed under the Boost Software License, Version 1.0
0005 // See accompanying file LICENSE_1_0.txt or copy at
0006 // http://www.boost.org/LICENSE_1_0.txt
0007 //
0008 // See http://boostorg.github.com/compute for more information.
0009 //---------------------------------------------------------------------------//
0010 
0011 #ifndef BOOST_COMPUTE_ALGORITHM_DETAIL_SERIAL_REDUCE_BY_KEY_HPP
0012 #define BOOST_COMPUTE_ALGORITHM_DETAIL_SERIAL_REDUCE_BY_KEY_HPP
0013 
0014 #include <iterator>
0015 
0016 #include <boost/compute/command_queue.hpp>
0017 #include <boost/compute/functional.hpp>
0018 #include <boost/compute/container/vector.hpp>
0019 #include <boost/compute/container/detail/scalar.hpp>
0020 #include <boost/compute/detail/meta_kernel.hpp>
0021 #include <boost/compute/detail/iterator_range_size.hpp>
0022 #include <boost/compute/type_traits/result_of.hpp>
0023 
0024 namespace boost {
0025 namespace compute {
0026 namespace detail {
0027 
0028 template<class InputKeyIterator, class InputValueIterator,
0029          class OutputKeyIterator, class OutputValueIterator,
0030          class BinaryFunction, class BinaryPredicate>
0031 inline size_t serial_reduce_by_key(InputKeyIterator keys_first,
0032                                    InputKeyIterator keys_last,
0033                                    InputValueIterator values_first,
0034                                    OutputKeyIterator keys_result,
0035                                    OutputValueIterator values_result,
0036                                    BinaryFunction function,
0037                                    BinaryPredicate predicate,
0038                                    command_queue &queue)
0039 {
0040     typedef typename
0041         std::iterator_traits<InputValueIterator>::value_type value_type;
0042     typedef typename
0043         std::iterator_traits<InputKeyIterator>::value_type key_type;
0044     typedef typename
0045         ::boost::compute::result_of<BinaryFunction(value_type, value_type)>::type result_type;
0046 
0047     const context &context = queue.get_context();
0048     size_t count = detail::iterator_range_size(keys_first, keys_last);
0049     if(count < 1){
0050         return count;
0051     }
0052 
0053     meta_kernel k("serial_reduce_by_key");
0054     size_t count_arg = k.add_arg<uint_>("count");
0055     size_t result_size_arg = k.add_arg<uint_ *>(memory_object::global_memory,
0056                                                 "result_size");
0057 
0058     k <<
0059         k.decl<result_type>("result") <<
0060             " = " << values_first[0] << ";\n" <<
0061         k.decl<key_type>("previous_key") << " = " << keys_first[0] << ";\n" <<
0062         k.decl<result_type>("value") << ";\n" <<
0063         k.decl<key_type>("key") << ";\n" <<
0064 
0065         k.decl<uint_>("size") << " = 1;\n" <<
0066 
0067         keys_result[0] << " = previous_key;\n" <<
0068         values_result[0] << " = result;\n" <<
0069 
0070         "for(ulong i = 1; i < count; i++) {\n" <<
0071         "    value = " << values_first[k.var<uint_>("i")] << ";\n" <<
0072         "    key = " << keys_first[k.var<uint_>("i")] << ";\n" <<
0073         "    if (" << predicate(k.var<key_type>("previous_key"),
0074                                 k.var<key_type>("key")) << ") {\n" <<
0075 
0076         "        result = " << function(k.var<result_type>("result"),
0077                                         k.var<result_type>("value")) << ";\n" <<
0078         "    }\n " <<
0079         "    else { \n" <<
0080                  keys_result[k.var<uint_>("size - 1")] << " = previous_key;\n" <<
0081                  values_result[k.var<uint_>("size - 1")] << " = result;\n" <<
0082         "        result = value;\n" <<
0083         "        size++;\n" <<
0084         "    } \n" <<
0085         "    previous_key = key;\n" <<
0086         "}\n" <<
0087         keys_result[k.var<uint_>("size - 1")] << " = previous_key;\n" <<
0088         values_result[k.var<uint_>("size - 1")] << " = result;\n" <<
0089         "*result_size = size;";
0090 
0091     kernel kernel = k.compile(context);
0092 
0093     scalar<uint_> result_size(context);
0094     kernel.set_arg(result_size_arg, result_size.get_buffer());
0095     kernel.set_arg(count_arg, static_cast<uint_>(count));
0096 
0097     queue.enqueue_task(kernel);
0098 
0099     return static_cast<size_t>(result_size.read(queue));
0100 }
0101 
0102 } // end detail namespace
0103 } // end compute namespace
0104 } // end boost namespace
0105 
0106 #endif // BOOST_COMPUTE_ALGORITHM_DETAIL_SERIAL_REDUCE_BY_KEY_HPP