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