2
0
mirror of https://github.com/boostorg/compute.git synced 2026-02-19 14:22:12 +00:00

Use radix_sort() for stable_sort() when possible

This commit is contained in:
Kyle Lutz
2014-11-09 11:06:47 -08:00
parent 5c1aac441c
commit 88d19723e3
4 changed files with 122 additions and 12 deletions

View File

@@ -23,6 +23,8 @@
#include <boost/compute/algorithm/exclusive_scan.hpp>
#include <boost/compute/container/vector.hpp>
#include <boost/compute/type_traits/type_name.hpp>
#include <boost/compute/type_traits/is_fundamental.hpp>
#include <boost/compute/type_traits/is_vector_type.hpp>
#include <boost/compute/detail/iterator_range_size.hpp>
#include <boost/compute/detail/program_cache.hpp>
@@ -30,6 +32,16 @@ namespace boost {
namespace compute {
namespace detail {
// meta-function returning true if type T is radix-sortable
template<class T>
struct is_radix_sortable :
boost::mpl::and_<
typename ::boost::compute::is_fundamental<T>::type,
typename boost::mpl::not_<typename is_vector_type<T>::type>::type
>
{
};
template<size_t N>
struct radix_sort_value_type
{

View File

@@ -15,10 +15,51 @@
#include <boost/compute/system.hpp>
#include <boost/compute/command_queue.hpp>
#include <boost/compute/algorithm/detail/radix_sort.hpp>
#include <boost/compute/algorithm/detail/insertion_sort.hpp>
#include <boost/compute/algorithm/reverse.hpp>
#include <boost/compute/functional/operator.hpp>
namespace boost {
namespace compute {
namespace detail {
template<class Iterator, class Compare>
inline void dispatch_stable_sort(Iterator first,
Iterator last,
Compare compare,
command_queue &queue)
{
::boost::compute::detail::serial_insertion_sort(
first, last, compare, queue
);
}
template<class T>
inline typename boost::enable_if_c<is_radix_sortable<T>::value>::type
dispatch_stable_sort(buffer_iterator<T> first,
buffer_iterator<T> last,
less<T>,
command_queue &queue)
{
::boost::compute::detail::radix_sort(first, last, queue);
}
template<class T>
inline typename boost::enable_if_c<is_radix_sortable<T>::value>::type
dispatch_stable_sort(buffer_iterator<T> first,
buffer_iterator<T> last,
greater<T>,
command_queue &queue)
{
// radix sort in ascending order
::boost::compute::detail::radix_sort(first, last, queue);
// reverse range to descending order
::boost::compute::reverse(first, last, queue);
}
} // end detail namespace
/// Sorts the values in the range [\p first, \p last) according to
/// \p compare. The relative order of identical values is preserved.
@@ -30,10 +71,9 @@ inline void stable_sort(Iterator first,
Compare compare,
command_queue &queue = system::default_queue())
{
return ::boost::compute::detail::serial_insertion_sort(first,
last,
compare,
queue);
::boost::compute::detail::dispatch_stable_sort(
first, last, compare, queue
);
}
/// \overload
@@ -46,7 +86,7 @@ inline void stable_sort(Iterator first,
::boost::compute::less<value_type> less;
return ::boost::compute::stable_sort(first, last, less, queue);
::boost::compute::stable_sort(first, last, less, queue);
}
} // end compute namespace

View File

@@ -11,6 +11,8 @@
#ifndef BOOST_COMPUTE_TYPE_TRAITS_IS_VECTOR_TYPE_HPP
#define BOOST_COMPUTE_TYPE_TRAITS_IS_VECTOR_TYPE_HPP
#include <boost/mpl/bool.hpp>
#include <boost/compute/type_traits/vector_size.hpp>
namespace boost {
@@ -26,10 +28,8 @@ namespace compute {
///
/// \see make_vector_type, vector_size
template<class T>
struct is_vector_type
struct is_vector_type : boost::mpl::bool_<vector_size<T>::value != 1>
{
/// \internal_
BOOST_STATIC_CONSTANT(bool, value = (vector_size<T>::value != 1));
};
} // end compute namespace