1 //---------------------------------------------------------------------------//
2 // Copyright (c) 2013 Kyle Lutz <kyle.r.lutz@gmail.com>
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
8 // See http://boostorg.github.com/compute for more information.
9 //---------------------------------------------------------------------------//
11 #ifndef BOOST_COMPUTE_ALGORITHM_DETAIL_COPY_TO_HOST_HPP
12 #define BOOST_COMPUTE_ALGORITHM_DETAIL_COPY_TO_HOST_HPP
16 #include <boost/utility/addressof.hpp>
18 #include <boost/compute/command_queue.hpp>
19 #include <boost/compute/async/future.hpp>
20 #include <boost/compute/iterator/buffer_iterator.hpp>
21 #include <boost/compute/memory/svm_ptr.hpp>
22 #include <boost/compute/detail/iterator_plus_distance.hpp>
28 template<class DeviceIterator, class HostIterator>
29 inline HostIterator copy_to_host(DeviceIterator first,
35 std::iterator_traits<DeviceIterator>::value_type
38 size_t count = iterator_range_size(first, last);
43 const buffer &buffer = first.get_buffer();
44 size_t offset = first.get_index();
46 queue.enqueue_read_buffer(buffer,
47 offset * sizeof(value_type),
48 count * sizeof(value_type),
49 ::boost::addressof(*result));
51 return iterator_plus_distance(result, count);
54 template<class DeviceIterator, class HostIterator>
55 inline HostIterator copy_to_host_map(DeviceIterator first,
61 std::iterator_traits<DeviceIterator>::value_type
64 std::iterator_traits<DeviceIterator>::difference_type
67 size_t count = iterator_range_size(first, last);
72 size_t offset = first.get_index();
74 // map [first; last) buffer to host
75 value_type *pointer = static_cast<value_type*>(
76 queue.enqueue_map_buffer(
79 offset * sizeof(value_type),
80 count * sizeof(value_type)
84 // copy [first; last) to result buffer
87 pointer + static_cast<difference_type>(count),
91 // unmap [first; last)
92 boost::compute::event unmap_event = queue.enqueue_unmap_buffer(
94 static_cast<void*>(pointer)
98 return iterator_plus_distance(result, count);
101 template<class DeviceIterator, class HostIterator>
102 inline future<HostIterator> copy_to_host_async(DeviceIterator first,
105 command_queue &queue)
108 std::iterator_traits<DeviceIterator>::value_type
111 size_t count = iterator_range_size(first, last);
113 return future<HostIterator>();
116 const buffer &buffer = first.get_buffer();
117 size_t offset = first.get_index();
120 queue.enqueue_read_buffer_async(buffer,
121 offset * sizeof(value_type),
122 count * sizeof(value_type),
123 ::boost::addressof(*result));
125 return make_future(iterator_plus_distance(result, count), event_);
128 #ifdef CL_VERSION_2_0
129 // copy_to_host() specialization for svm_ptr
130 template<class T, class HostIterator>
131 inline HostIterator copy_to_host(svm_ptr<T> first,
134 command_queue &queue)
136 size_t count = iterator_range_size(first, last);
141 queue.enqueue_svm_memcpy(
142 ::boost::addressof(*result), first.get(), count * sizeof(T)
145 return result + count;
148 template<class T, class HostIterator>
149 inline future<HostIterator> copy_to_host_async(svm_ptr<T> first,
152 command_queue &queue)
154 size_t count = iterator_range_size(first, last);
156 return future<HostIterator>();
159 event event_ = queue.enqueue_svm_memcpy_async(
160 ::boost::addressof(*result), first.get(), count * sizeof(T)
163 return make_future(iterator_plus_distance(result, count), event_);
166 template<class T, class HostIterator>
167 inline HostIterator copy_to_host_map(svm_ptr<T> first,
170 command_queue &queue)
172 size_t count = iterator_range_size(first, last);
178 queue.enqueue_svm_map(first.get(), count * sizeof(T), CL_MAP_READ);
180 // copy [first; last) to result
182 static_cast<T*>(first.get()),
183 static_cast<T*>(last.get()),
187 // unmap [first; last)
188 queue.enqueue_svm_unmap(first.get()).wait();
190 return iterator_plus_distance(result, count);
192 #endif // CL_VERSION_2_0
194 } // end detail namespace
195 } // end compute namespace
196 } // end boost namespace
198 #endif // BOOST_COMPUTE_ALGORITHM_DETAIL_COPY_TO_HOST_HPP