diff options
Diffstat (limited to 'boost/compute/algorithm/lexicographical_compare.hpp')
-rw-r--r-- | boost/compute/algorithm/lexicographical_compare.hpp | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/boost/compute/algorithm/lexicographical_compare.hpp b/boost/compute/algorithm/lexicographical_compare.hpp new file mode 100644 index 0000000000..c4f7120807 --- /dev/null +++ b/boost/compute/algorithm/lexicographical_compare.hpp @@ -0,0 +1,117 @@ +//---------------------------------------------------------------------------// +// Copyright (c) 2014 Mageswaran.D <mageswaran1989@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. +//---------------------------------------------------------------------------// + +#include <boost/compute/system.hpp> +#include <boost/compute/context.hpp> +#include <boost/compute/command_queue.hpp> +#include <boost/compute/algorithm/any_of.hpp> +#include <boost/compute/container/vector.hpp> +#include <boost/compute/utility/program_cache.hpp> + +namespace boost { +namespace compute { + +namespace detail { + +const char lexicographical_compare_source[] = +"__kernel void lexicographical_compare(const uint size1,\n" +" const uint size2,\n" +" __global const T1 *range1,\n" +" __global const T2 *range2,\n" +" __global bool *result_buf)\n" +"{\n" +" const uint i = get_global_id(0);\n" +" if((i != size1) && (i != size2)){\n" + //Individual elements are compared and results are stored in parallel. + //0 is true +" if(range1[i] < range2[i])\n" +" result_buf[i] = 0;\n" +" else\n" +" result_buf[i] = 1;\n" +" }\n" +" else\n" +" result_buf[i] = !((i == size1) && (i != size2));\n" +"}\n"; + +template<class InputIterator1, class InputIterator2> +inline bool dispatch_lexicographical_compare(InputIterator1 first1, + InputIterator1 last1, + InputIterator2 first2, + InputIterator2 last2, + command_queue &queue) +{ + const boost::compute::context &context = queue.get_context(); + + boost::shared_ptr<program_cache> cache = + program_cache::get_global_cache(context); + + size_t iterator_size1 = iterator_range_size(first1, last1); + size_t iterator_size2 = iterator_range_size(first2, last2); + size_t max_size = (std::max)(iterator_size1, iterator_size2); + + if(max_size == 0){ + return false; + } + + boost::compute::vector<bool> result_vector(max_size, context); + + + typedef typename std::iterator_traits<InputIterator1>::value_type value_type1; + typedef typename std::iterator_traits<InputIterator2>::value_type value_type2; + + // load (or create) lexicographical compare program + std::string cache_key = + std::string("__boost_lexicographical_compare") + + type_name<value_type1>() + type_name<value_type2>(); + + std::stringstream options; + options << " -DT1=" << type_name<value_type1>(); + options << " -DT2=" << type_name<value_type2>(); + + program lexicographical_compare_program = cache->get_or_build( + cache_key, options.str(), lexicographical_compare_source, context + ); + + kernel lexicographical_compare_kernel(lexicographical_compare_program, + "lexicographical_compare"); + + lexicographical_compare_kernel.set_arg<uint_>(0, iterator_size1); + lexicographical_compare_kernel.set_arg<uint_>(1, iterator_size2); + lexicographical_compare_kernel.set_arg(2, first1.get_buffer()); + lexicographical_compare_kernel.set_arg(3, first2.get_buffer()); + lexicographical_compare_kernel.set_arg(4, result_vector.get_buffer()); + + queue.enqueue_1d_range_kernel(lexicographical_compare_kernel, + 0, + max_size, + 0); + + return boost::compute::any_of(result_vector.begin(), + result_vector.end(), + _1 == 0, + queue); +} + +} // end detail namespace + +/// Checks if the first range [first1, last1) is lexicographically +/// less than the second range [first2, last2). +template<class InputIterator1, class InputIterator2> +inline bool lexicographical_compare(InputIterator1 first1, + InputIterator1 last1, + InputIterator2 first2, + InputIterator2 last2, + command_queue &queue = system::default_queue()) +{ + return detail::dispatch_lexicographical_compare(first1, last1, first2, last2, queue); +} + +} // end compute namespace +} // end boost namespac |