118 lines
4.6 KiB
Plaintext
118 lines
4.6 KiB
Plaintext
|
//---------------------------------------------------------------------------//
|
||
|
// 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
|