summaryrefslogtreecommitdiff
path: root/boost/compute/algorithm/random_shuffle.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/compute/algorithm/random_shuffle.hpp')
-rw-r--r--boost/compute/algorithm/random_shuffle.hpp75
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