inline future<OutputIterator> dispatch_copy_async(InputIterator first, InputIterator last, OutputIterator result, command_queue &queue, typename boost::enable_if< mpl::and_< is_device_iterator<InputIterator>, is_device_iterator<OutputIterator>, can_copy_with_copy_buffer< InputIterator, OutputIterator > > >::type* = 0) { typedef typename std::iterator_traits<InputIterator>::value_type value_type; typedef typename std::iterator_traits<InputIterator>::difference_type difference_type; difference_type n = std::distance(first, last); if(n < 1){ // nothing to copy return make_future(result, event()); } event event_ = queue.enqueue_copy_buffer( first.get_buffer(), result.get_buffer(), first.get_index() * sizeof(value_type), result.get_index() * sizeof(value_type), static_cast<size_t>(n) * sizeof(value_type) ); return make_future(result + n, event_); }
inline future<HostIterator> copy_to_host_async(DeviceIterator first, DeviceIterator last, HostIterator result, command_queue &queue) { typedef typename std::iterator_traits<DeviceIterator>::value_type value_type; size_t count = iterator_range_size(first, last); if(count == 0){ return future<HostIterator>(); } const buffer &buffer = first.get_buffer(); size_t offset = first.get_index(); event event_ = queue.enqueue_read_buffer_async(buffer, offset * sizeof(value_type), count * sizeof(value_type), ::boost::addressof(*result)); return make_future(iterator_plus_distance(result, count), event_); }
inline future<DeviceIterator> copy_to_device_async(HostIterator first, HostIterator last, DeviceIterator result, command_queue &queue, const wait_list &events) { typedef typename std::iterator_traits<DeviceIterator>::value_type value_type; typedef typename std::iterator_traits<DeviceIterator>::difference_type difference_type; size_t count = iterator_range_size(first, last); if(count == 0){ return future<DeviceIterator>(); } size_t offset = result.get_index(); event event_ = queue.enqueue_write_buffer_async(result.get_buffer(), offset * sizeof(value_type), count * sizeof(value_type), ::boost::addressof(*first), events); return make_future(result + static_cast<difference_type>(count), event_); }
inline future<OutputIterator> copy_on_device_async(InputIterator first, InputIterator last, OutputIterator result, command_queue &queue) { const device &device = queue.get_device(); copy_kernel<InputIterator, OutputIterator> kernel(device); kernel.set_range(first, last, result); event event_ = kernel.exec(queue); return make_future(result + std::distance(first, last), event_); }
inline future<svm_ptr<T> > copy_on_device_async(svm_ptr<T> first, svm_ptr<T> last, svm_ptr<T> result, command_queue &queue) { size_t count = iterator_range_size(first, last); if(count == 0){ return result; } event event_ = queue.enqueue_svm_memcpy_async( result.get(), first.get(), count * sizeof(T) ); return make_future(result + count, event_); }
inline future<HostIterator> copy_to_host_async(svm_ptr<T> first, svm_ptr<T> last, HostIterator result, command_queue &queue) { size_t count = iterator_range_size(first, last); if(count == 0){ return result; } event event_ = queue.enqueue_svm_memcpy_async( ::boost::addressof(*result), first.get(), count * sizeof(T) ); return make_future(iterator_plus_distance(result, count), event_); }
inline future<svm_ptr<T> > copy_to_device_async(HostIterator first, HostIterator last, svm_ptr<T> result, command_queue &queue, const wait_list &events) { size_t count = iterator_range_size(first, last); if(count == 0){ return future<svm_ptr<T> >(); } event event_ = queue.enqueue_svm_memcpy_async( result.get(), ::boost::addressof(*first), count * sizeof(T), events ); return make_future(result + count, event_); }