Project revived from Feb2017
[EroSomnia.git] / deps / boost_1_63_0 / boost / compute / algorithm / detail / copy_to_host.hpp
blobd770a996efdd3875ec5417869519925cb9120d27
1 //---------------------------------------------------------------------------//
2 // Copyright (c) 2013 Kyle Lutz <kyle.r.lutz@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 //---------------------------------------------------------------------------//
11 #ifndef BOOST_COMPUTE_ALGORITHM_DETAIL_COPY_TO_HOST_HPP
12 #define BOOST_COMPUTE_ALGORITHM_DETAIL_COPY_TO_HOST_HPP
14 #include <iterator>
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>
24 namespace boost {
25 namespace compute {
26 namespace detail {
28 template<class DeviceIterator, class HostIterator>
29 inline HostIterator copy_to_host(DeviceIterator first,
30 DeviceIterator last,
31 HostIterator result,
32 command_queue &queue)
34 typedef typename
35 std::iterator_traits<DeviceIterator>::value_type
36 value_type;
38 size_t count = iterator_range_size(first, last);
39 if(count == 0){
40 return result;
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,
56 DeviceIterator last,
57 HostIterator result,
58 command_queue &queue)
60 typedef typename
61 std::iterator_traits<DeviceIterator>::value_type
62 value_type;
63 typedef typename
64 std::iterator_traits<DeviceIterator>::difference_type
65 difference_type;
67 size_t count = iterator_range_size(first, last);
68 if(count == 0){
69 return result;
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(
77 first.get_buffer(),
78 CL_MAP_READ,
79 offset * sizeof(value_type),
80 count * sizeof(value_type)
84 // copy [first; last) to result buffer
85 std::copy(
86 pointer,
87 pointer + static_cast<difference_type>(count),
88 result
91 // unmap [first; last)
92 boost::compute::event unmap_event = queue.enqueue_unmap_buffer(
93 first.get_buffer(),
94 static_cast<void*>(pointer)
96 unmap_event.wait();
98 return iterator_plus_distance(result, count);
101 template<class DeviceIterator, class HostIterator>
102 inline future<HostIterator> copy_to_host_async(DeviceIterator first,
103 DeviceIterator last,
104 HostIterator result,
105 command_queue &queue)
107 typedef typename
108 std::iterator_traits<DeviceIterator>::value_type
109 value_type;
111 size_t count = iterator_range_size(first, last);
112 if(count == 0){
113 return future<HostIterator>();
116 const buffer &buffer = first.get_buffer();
117 size_t offset = first.get_index();
119 event event_ =
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,
132 svm_ptr<T> last,
133 HostIterator result,
134 command_queue &queue)
136 size_t count = iterator_range_size(first, last);
137 if(count == 0){
138 return result;
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,
150 svm_ptr<T> last,
151 HostIterator result,
152 command_queue &queue)
154 size_t count = iterator_range_size(first, last);
155 if(count == 0){
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,
168 svm_ptr<T> last,
169 HostIterator result,
170 command_queue &queue)
172 size_t count = iterator_range_size(first, last);
173 if(count == 0){
174 return result;
177 // map
178 queue.enqueue_svm_map(first.get(), count * sizeof(T), CL_MAP_READ);
180 // copy [first; last) to result
181 std::copy(
182 static_cast<T*>(first.get()),
183 static_cast<T*>(last.get()),
184 result
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