]>
Commit | Line | Data |
---|---|---|
1 | //---------------------------------------------------------------------------// | |
2 | // Copyright (c) 2014 Mageswaran.D <mageswaran1989@gmail.com> | |
3 | // | |
4 | // Distributed under the Boost Software License, Version 1.0 | |
5 | // See accompanying file LICENSE_1_0.txt or copy at | |
6 | // http://www.boost.org/LICENSE_1_0.txt | |
7 | // | |
8 | // See http://boostorg.github.com/compute for more information. | |
9 | //---------------------------------------------------------------------------// | |
10 | ||
11 | #include <boost/compute/system.hpp> | |
12 | #include <boost/compute/context.hpp> | |
13 | #include <boost/compute/command_queue.hpp> | |
14 | #include <boost/compute/algorithm/any_of.hpp> | |
15 | #include <boost/compute/container/vector.hpp> | |
16 | #include <boost/compute/utility/program_cache.hpp> | |
17 | ||
18 | namespace boost { | |
19 | namespace compute { | |
20 | ||
21 | namespace detail { | |
22 | ||
23 | const char lexicographical_compare_source[] = | |
24 | "__kernel void lexicographical_compare(const uint size1,\n" | |
25 | " const uint size2,\n" | |
26 | " __global const T1 *range1,\n" | |
27 | " __global const T2 *range2,\n" | |
28 | " __global bool *result_buf)\n" | |
29 | "{\n" | |
30 | " const uint i = get_global_id(0);\n" | |
31 | " if((i != size1) && (i != size2)){\n" | |
32 | //Individual elements are compared and results are stored in parallel. | |
33 | //0 is true | |
34 | " if(range1[i] < range2[i])\n" | |
35 | " result_buf[i] = 0;\n" | |
36 | " else\n" | |
37 | " result_buf[i] = 1;\n" | |
38 | " }\n" | |
39 | " else\n" | |
40 | " result_buf[i] = !((i == size1) && (i != size2));\n" | |
41 | "}\n"; | |
42 | ||
43 | template<class InputIterator1, class InputIterator2> | |
44 | inline bool dispatch_lexicographical_compare(InputIterator1 first1, | |
45 | InputIterator1 last1, | |
46 | InputIterator2 first2, | |
47 | InputIterator2 last2, | |
48 | command_queue &queue) | |
49 | { | |
50 | const boost::compute::context &context = queue.get_context(); | |
51 | ||
52 | boost::shared_ptr<program_cache> cache = | |
53 | program_cache::get_global_cache(context); | |
54 | ||
55 | size_t iterator_size1 = iterator_range_size(first1, last1); | |
56 | size_t iterator_size2 = iterator_range_size(first2, last2); | |
57 | size_t max_size = (std::max)(iterator_size1, iterator_size2); | |
58 | ||
59 | if(max_size == 0){ | |
60 | return false; | |
61 | } | |
62 | ||
63 | boost::compute::vector<bool> result_vector(max_size, context); | |
64 | ||
65 | ||
66 | typedef typename std::iterator_traits<InputIterator1>::value_type value_type1; | |
67 | typedef typename std::iterator_traits<InputIterator2>::value_type value_type2; | |
68 | ||
69 | // load (or create) lexicographical compare program | |
70 | std::string cache_key = | |
71 | std::string("__boost_lexicographical_compare") | |
72 | + type_name<value_type1>() + type_name<value_type2>(); | |
73 | ||
74 | std::stringstream options; | |
75 | options << " -DT1=" << type_name<value_type1>(); | |
76 | options << " -DT2=" << type_name<value_type2>(); | |
77 | ||
78 | program lexicographical_compare_program = cache->get_or_build( | |
79 | cache_key, options.str(), lexicographical_compare_source, context | |
80 | ); | |
81 | ||
82 | kernel lexicographical_compare_kernel(lexicographical_compare_program, | |
83 | "lexicographical_compare"); | |
84 | ||
85 | lexicographical_compare_kernel.set_arg<uint_>(0, iterator_size1); | |
86 | lexicographical_compare_kernel.set_arg<uint_>(1, iterator_size2); | |
87 | lexicographical_compare_kernel.set_arg(2, first1.get_buffer()); | |
88 | lexicographical_compare_kernel.set_arg(3, first2.get_buffer()); | |
89 | lexicographical_compare_kernel.set_arg(4, result_vector.get_buffer()); | |
90 | ||
91 | queue.enqueue_1d_range_kernel(lexicographical_compare_kernel, | |
92 | 0, | |
93 | max_size, | |
94 | 0); | |
95 | ||
96 | return boost::compute::any_of(result_vector.begin(), | |
97 | result_vector.end(), | |
98 | _1 == 0, | |
99 | queue); | |
100 | } | |
101 | ||
102 | } // end detail namespace | |
103 | ||
104 | /// Checks if the first range [first1, last1) is lexicographically | |
105 | /// less than the second range [first2, last2). | |
106 | template<class InputIterator1, class InputIterator2> | |
107 | inline bool lexicographical_compare(InputIterator1 first1, | |
108 | InputIterator1 last1, | |
109 | InputIterator2 first2, | |
110 | InputIterator2 last2, | |
111 | command_queue &queue = system::default_queue()) | |
112 | { | |
113 | return detail::dispatch_lexicographical_compare(first1, last1, first2, last2, queue); | |
114 | } | |
115 | ||
116 | } // end compute namespace | |
117 | } // end boost namespac |