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
 | 
