| 67 | /// |
| 68 | template<class InputIterator, class UnaryPredicate> |
| 69 | inline InputIterator binary_find(InputIterator first, |
| 70 | InputIterator last, |
| 71 | UnaryPredicate predicate, |
| 72 | command_queue &queue = system::default_queue()) |
| 73 | { |
| 74 | const device &device = queue.get_device(); |
| 75 | |
| 76 | boost::shared_ptr<parameter_cache> parameters = |
| 77 | detail::parameter_cache::get_global_cache(device); |
| 78 | |
| 79 | const std::string cache_key = "__boost_binary_find"; |
| 80 | |
| 81 | size_t find_if_limit = 128; |
| 82 | size_t threads = parameters->get(cache_key, "tpb", 128); |
| 83 | size_t count = iterator_range_size(first, last); |
| 84 | |
| 85 | InputIterator search_first = first; |
| 86 | InputIterator search_last = last; |
| 87 | |
| 88 | scalar<uint_> index(queue.get_context()); |
| 89 | |
| 90 | // construct and compile binary_find kernel |
| 91 | binary_find_kernel<InputIterator, UnaryPredicate> |
| 92 | binary_find_kernel(search_first, search_last, predicate); |
| 93 | ::boost::compute::kernel kernel = binary_find_kernel.compile(queue.get_context()); |
| 94 | |
| 95 | // set buffer for index |
| 96 | kernel.set_arg(binary_find_kernel.m_index_arg, index.get_buffer()); |
| 97 | |
| 98 | while(count > find_if_limit) { |
| 99 | index.write(static_cast<uint_>(count), queue); |
| 100 | |
| 101 | // set block and run binary_find kernel |
| 102 | uint_ block = static_cast<uint_>((count - 1)/(threads - 1)); |
| 103 | kernel.set_arg(binary_find_kernel.m_block_arg, block); |
| 104 | queue.enqueue_1d_range_kernel(kernel, 0, threads, 0); |
| 105 | |
| 106 | size_t i = index.read(queue); |
| 107 | |
| 108 | if(i == count) { |
| 109 | search_first = search_last - ((count - 1)%(threads - 1)); |
| 110 | break; |
| 111 | } else { |
| 112 | search_last = search_first + i; |
| 113 | search_first = search_last - ((count - 1)/(threads - 1)); |
| 114 | } |
| 115 | |
| 116 | // Make sure that first and last stay within the input range |
| 117 | search_last = (std::min)(search_last, last); |
| 118 | search_last = (std::max)(search_last, first); |
| 119 | |
| 120 | search_first = (std::max)(search_first, first); |
| 121 | search_first = (std::min)(search_first, last); |
| 122 | |
| 123 | count = iterator_range_size(search_first, search_last); |
| 124 | } |
| 125 | |
| 126 | return find_if(search_first, search_last, predicate, queue); |
no test coverage detected