//---------------------------------------------------------------------------// // Copyright (c) 2016 Jakub Szuppe // // Distributed under the Boost Software License, Version 1.0 // See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt // // See http://boostorg.github.com/compute for more information. //---------------------------------------------------------------------------// #ifndef BOOST_COMPUTE_ALGORITHM_STABLE_SORT_BY_KEY_HPP #define BOOST_COMPUTE_ALGORITHM_STABLE_SORT_BY_KEY_HPP #include #include #include #include #include namespace boost { namespace compute { namespace detail { template inline void dispatch_gpu_ssort_by_key(KeyIterator keys_first, KeyIterator keys_last, ValueIterator values_first, less::value_type> compare, command_queue &queue, typename boost::enable_if_c< is_radix_sortable< typename std::iterator_traits::value_type >::value >::type* = 0) { size_t count = detail::iterator_range_size(keys_first, keys_last); if(count < 32){ detail::serial_insertion_sort_by_key( keys_first, keys_last, values_first, compare, queue ); } else { detail::radix_sort_by_key( keys_first, keys_last, values_first, queue ); } } template inline void dispatch_gpu_ssort_by_key(KeyIterator keys_first, KeyIterator keys_last, ValueIterator values_first, greater::value_type> compare, command_queue &queue, typename boost::enable_if_c< is_radix_sortable< typename std::iterator_traits::value_type >::value >::type* = 0) { size_t count = detail::iterator_range_size(keys_first, keys_last); if(count < 32){ detail::serial_insertion_sort_by_key( keys_first, keys_last, values_first, compare, queue ); } else { // radix sorts in descending order detail::radix_sort_by_key( keys_first, keys_last, values_first, false, queue ); } } template inline void dispatch_gpu_ssort_by_key(KeyIterator keys_first, KeyIterator keys_last, ValueIterator values_first, Compare compare, command_queue &queue) { size_t count = detail::iterator_range_size(keys_first, keys_last); if(count < 32){ detail::serial_insertion_sort_by_key( keys_first, keys_last, values_first, compare, queue ); } else { detail::merge_sort_by_key_on_gpu( keys_first, keys_last, values_first, compare, true /* stable */, queue ); } } template inline void dispatch_ssort_by_key(KeyIterator keys_first, KeyIterator keys_last, ValueIterator values_first, Compare compare, command_queue &queue) { if(queue.get_device().type() & device::gpu) { dispatch_gpu_ssort_by_key( keys_first, keys_last, values_first, compare, queue ); return; } ::boost::compute::detail::merge_sort_by_key_on_cpu( keys_first, keys_last, values_first, compare, queue ); } } // end detail namespace /// Performs a key-value stable sort using the keys in the range [\p keys_first, /// \p keys_last) on the values in the range [\p values_first, /// \p values_first \c + (\p keys_last \c - \p keys_first)) using \p compare. /// /// If no compare function is specified, \c less is used. /// /// \see sort() template inline void stable_sort_by_key(KeyIterator keys_first, KeyIterator keys_last, ValueIterator values_first, Compare compare, command_queue &queue = system::default_queue()) { ::boost::compute::detail::dispatch_ssort_by_key( keys_first, keys_last, values_first, compare, queue ); } /// \overload template inline void stable_sort_by_key(KeyIterator keys_first, KeyIterator keys_last, ValueIterator values_first, command_queue &queue = system::default_queue()) { typedef typename std::iterator_traits::value_type key_type; ::boost::compute::stable_sort_by_key( keys_first, keys_last, values_first, less(), queue ); } } // end compute namespace } // end boost namespace #endif // BOOST_COMPUTE_ALGORITHM_STABLE_SORT_BY_KEY_HPP