File indexing completed on 2025-01-18 09:29:57
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_COMPUTE_ALGORITHM_RANDOM_SHUFFLE_HPP
0012 #define BOOST_COMPUTE_ALGORITHM_RANDOM_SHUFFLE_HPP
0013
0014 #include <vector>
0015 #include <algorithm>
0016
0017 #ifdef BOOST_COMPUTE_USE_CPP11
0018 #include <random>
0019 #endif
0020
0021 #include <boost/static_assert.hpp>
0022 #include <boost/range/algorithm_ext/iota.hpp>
0023
0024 #include <boost/compute/system.hpp>
0025 #include <boost/compute/functional.hpp>
0026 #include <boost/compute/command_queue.hpp>
0027 #include <boost/compute/container/vector.hpp>
0028 #include <boost/compute/algorithm/scatter.hpp>
0029 #include <boost/compute/detail/iterator_range_size.hpp>
0030 #include <boost/compute/type_traits/is_device_iterator.hpp>
0031
0032 namespace boost {
0033 namespace compute {
0034
0035
0036
0037
0038
0039
0040 template<class Iterator>
0041 inline void random_shuffle(Iterator first,
0042 Iterator last,
0043 command_queue &queue = system::default_queue())
0044 {
0045 BOOST_STATIC_ASSERT(is_device_iterator<Iterator>::value);
0046 typedef typename std::iterator_traits<Iterator>::value_type value_type;
0047
0048 size_t count = detail::iterator_range_size(first, last);
0049 if(count == 0){
0050 return;
0051 }
0052
0053
0054 std::vector<cl_uint> random_indices(count);
0055 boost::iota(random_indices, 0);
0056 #ifdef BOOST_COMPUTE_USE_CPP11
0057 std::random_device nondeterministic_randomness;
0058 std::default_random_engine random_engine(nondeterministic_randomness());
0059 std::shuffle(random_indices.begin(), random_indices.end(), random_engine);
0060 #else
0061 std::random_shuffle(random_indices.begin(), random_indices.end());
0062 #endif
0063
0064
0065 const context &context = queue.get_context();
0066 vector<cl_uint> indices(count, context);
0067 ::boost::compute::copy(random_indices.begin(),
0068 random_indices.end(),
0069 indices.begin(),
0070 queue);
0071
0072
0073 vector<value_type> tmp(count, context);
0074 ::boost::compute::copy(first,
0075 last,
0076 tmp.begin(),
0077 queue);
0078
0079
0080 ::boost::compute::scatter(tmp.begin(),
0081 tmp.end(),
0082 indices.begin(),
0083 first,
0084 queue);
0085 }
0086
0087 }
0088 }
0089
0090 #endif