File indexing completed on 2025-01-18 09:29:58
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_COMPUTE_ALGORITHM_SORT_HPP
0012 #define BOOST_COMPUTE_ALGORITHM_SORT_HPP
0013
0014 #include <iterator>
0015
0016 #include <boost/utility/enable_if.hpp>
0017
0018 #include <boost/compute/system.hpp>
0019 #include <boost/compute/command_queue.hpp>
0020 #include <boost/compute/algorithm/detail/merge_sort_on_cpu.hpp>
0021 #include <boost/compute/algorithm/detail/merge_sort_on_gpu.hpp>
0022 #include <boost/compute/algorithm/detail/radix_sort.hpp>
0023 #include <boost/compute/algorithm/detail/insertion_sort.hpp>
0024 #include <boost/compute/algorithm/reverse.hpp>
0025 #include <boost/compute/container/mapped_view.hpp>
0026 #include <boost/compute/detail/iterator_range_size.hpp>
0027 #include <boost/compute/iterator/buffer_iterator.hpp>
0028 #include <boost/compute/type_traits/is_device_iterator.hpp>
0029
0030 namespace boost {
0031 namespace compute {
0032 namespace detail {
0033
0034 template<class T>
0035 inline void dispatch_gpu_sort(buffer_iterator<T> first,
0036 buffer_iterator<T> last,
0037 less<T>,
0038 command_queue &queue,
0039 typename boost::enable_if_c<
0040 is_radix_sortable<T>::value
0041 >::type* = 0)
0042 {
0043 size_t count = detail::iterator_range_size(first, last);
0044
0045 if(count < 2){
0046
0047 return;
0048 }
0049 else if(count <= 32){
0050 ::boost::compute::detail::serial_insertion_sort(first, last, queue);
0051 }
0052 else {
0053 ::boost::compute::detail::radix_sort(first, last, queue);
0054 }
0055 }
0056
0057 template<class T>
0058 inline void dispatch_gpu_sort(buffer_iterator<T> first,
0059 buffer_iterator<T> last,
0060 greater<T> compare,
0061 command_queue &queue,
0062 typename boost::enable_if_c<
0063 is_radix_sortable<T>::value
0064 >::type* = 0)
0065 {
0066 size_t count = detail::iterator_range_size(first, last);
0067
0068 if(count < 2){
0069
0070 return;
0071 }
0072 else if(count <= 32){
0073 ::boost::compute::detail::serial_insertion_sort(
0074 first, last, compare, queue
0075 );
0076 }
0077 else {
0078
0079 ::boost::compute::detail::radix_sort(first, last, false, queue);
0080 }
0081 }
0082
0083 template<class Iterator, class Compare>
0084 inline void dispatch_gpu_sort(Iterator first,
0085 Iterator last,
0086 Compare compare,
0087 command_queue &queue)
0088 {
0089 size_t count = detail::iterator_range_size(first, last);
0090
0091 if(count < 2){
0092
0093 return;
0094 }
0095 else if(count <= 32){
0096 ::boost::compute::detail::serial_insertion_sort(
0097 first, last, compare, queue
0098 );
0099 }
0100 else {
0101 ::boost::compute::detail::merge_sort_on_gpu(
0102 first, last, compare, queue
0103 );
0104 }
0105 }
0106
0107
0108 template<class Iterator, class Compare>
0109 inline void dispatch_sort(Iterator first,
0110 Iterator last,
0111 Compare compare,
0112 command_queue &queue,
0113 typename boost::enable_if<
0114 is_device_iterator<Iterator>
0115 >::type* = 0)
0116 {
0117 if(queue.get_device().type() & device::gpu) {
0118 dispatch_gpu_sort(first, last, compare, queue);
0119 return;
0120 }
0121 ::boost::compute::detail::merge_sort_on_cpu(first, last, compare, queue);
0122 }
0123
0124
0125 template<class Iterator, class Compare>
0126 inline void dispatch_sort(Iterator first,
0127 Iterator last,
0128 Compare compare,
0129 command_queue &queue,
0130 typename boost::disable_if<
0131 is_device_iterator<Iterator>
0132 >::type* = 0)
0133 {
0134 typedef typename std::iterator_traits<Iterator>::value_type T;
0135
0136 size_t size = static_cast<size_t>(std::distance(first, last));
0137
0138
0139 mapped_view<T> view(
0140 boost::addressof(*first), size, queue.get_context()
0141 );
0142
0143
0144 dispatch_sort(view.begin(), view.end(), compare, queue);
0145
0146
0147 view.map(queue);
0148 }
0149
0150 }
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182 template<class Iterator, class Compare>
0183 inline void sort(Iterator first,
0184 Iterator last,
0185 Compare compare,
0186 command_queue &queue = system::default_queue())
0187 {
0188 ::boost::compute::detail::dispatch_sort(first, last, compare, queue);
0189 }
0190
0191
0192 template<class Iterator>
0193 inline void sort(Iterator first,
0194 Iterator last,
0195 command_queue &queue = system::default_queue())
0196 {
0197 typedef typename std::iterator_traits<Iterator>::value_type value_type;
0198
0199 ::boost::compute::sort(
0200 first, last, ::boost::compute::less<value_type>(), queue
0201 );
0202 }
0203
0204 }
0205 }
0206
0207 #endif