| 159 | // Space complexity: O( ceil(n / 2 / 256) ) |
| 160 | template<class InputIterator, class OutputIterator, class BinaryFunction> |
| 161 | inline void generic_reduce(InputIterator first, |
| 162 | InputIterator last, |
| 163 | OutputIterator result, |
| 164 | BinaryFunction function, |
| 165 | command_queue &queue) |
| 166 | { |
| 167 | typedef typename |
| 168 | std::iterator_traits<InputIterator>::value_type |
| 169 | input_type; |
| 170 | typedef typename |
| 171 | boost::compute::result_of<BinaryFunction(input_type, input_type)>::type |
| 172 | result_type; |
| 173 | |
| 174 | const device &device = queue.get_device(); |
| 175 | const context &context = queue.get_context(); |
| 176 | |
| 177 | size_t count = detail::iterator_range_size(first, last); |
| 178 | |
| 179 | if(device.type() & device::cpu){ |
| 180 | array<result_type, 1> value(context); |
| 181 | detail::reduce_on_cpu(first, last, value.begin(), function, queue); |
| 182 | boost::compute::copy_n(value.begin(), 1, result, queue); |
| 183 | } |
| 184 | else { |
| 185 | size_t block_size = 256; |
| 186 | |
| 187 | // first pass |
| 188 | vector<result_type> results = detail::block_reduce(first, |
| 189 | count, |
| 190 | block_size, |
| 191 | function, |
| 192 | queue); |
| 193 | |
| 194 | if(results.size() > 1){ |
| 195 | detail::inplace_reduce(results.begin(), |
| 196 | results.end(), |
| 197 | function, |
| 198 | queue); |
| 199 | } |
| 200 | |
| 201 | boost::compute::copy_n(results.begin(), 1, result, queue); |
| 202 | } |
| 203 | } |
| 204 | |
| 205 | template<class InputIterator, class OutputIterator, class T> |
| 206 | inline void dispatch_reduce(InputIterator first, |
no test coverage detected