diff options
Diffstat (limited to 'boost/compute/algorithm/random_shuffle.hpp')
-rw-r--r-- | boost/compute/algorithm/random_shuffle.hpp | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/boost/compute/algorithm/random_shuffle.hpp b/boost/compute/algorithm/random_shuffle.hpp new file mode 100644 index 0000000000..7d2d46a133 --- /dev/null +++ b/boost/compute/algorithm/random_shuffle.hpp @@ -0,0 +1,75 @@ +//---------------------------------------------------------------------------// +// Copyright (c) 2013 Kyle Lutz <kyle.r.lutz@gmail.com> +// +// 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_RANDOM_SHUFFLE_HPP +#define BOOST_COMPUTE_ALGORITHM_RANDOM_SHUFFLE_HPP + +#include <vector> +#include <algorithm> + +#include <boost/range/algorithm_ext/iota.hpp> + +#include <boost/compute/system.hpp> +#include <boost/compute/functional.hpp> +#include <boost/compute/command_queue.hpp> +#include <boost/compute/container/vector.hpp> +#include <boost/compute/algorithm/scatter.hpp> +#include <boost/compute/detail/iterator_range_size.hpp> + +namespace boost { +namespace compute { + +/// Randomly shuffles the elements in the range [\p first, \p last). +/// +/// \see scatter() +template<class Iterator> +inline void random_shuffle(Iterator first, + Iterator last, + command_queue &queue = system::default_queue()) +{ + typedef typename std::iterator_traits<Iterator>::value_type value_type; + + size_t count = detail::iterator_range_size(first, last); + if(count == 0){ + return; + } + + // generate shuffled indices on the host + std::vector<cl_uint> random_indices(count); + boost::iota(random_indices, 0); + std::random_shuffle(random_indices.begin(), random_indices.end()); + + // copy random indices to the device + const context &context = queue.get_context(); + vector<cl_uint> indices(count, context); + ::boost::compute::copy(random_indices.begin(), + random_indices.end(), + indices.begin(), + queue); + + // make a copy of the values on the device + vector<value_type> tmp(count, context); + ::boost::compute::copy(first, + last, + tmp.begin(), + queue); + + // write values to their new locations + ::boost::compute::scatter(tmp.begin(), + tmp.end(), + indices.begin(), + first, + queue); +} + +} // end compute namespace +} // end boost namespace + +#endif // BOOST_COMPUTE_ALGORITHM_RANDOM_SHUFFLE_HPP |