]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/compute/include/boost/compute/algorithm/detail/copy_to_host.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / compute / include / boost / compute / algorithm / detail / copy_to_host.hpp
CommitLineData
7c673cae
FG
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//---------------------------------------------------------------------------//
10
11#ifndef BOOST_COMPUTE_ALGORITHM_DETAIL_COPY_TO_HOST_HPP
12#define BOOST_COMPUTE_ALGORITHM_DETAIL_COPY_TO_HOST_HPP
13
14#include <iterator>
15
16#include <boost/utility/addressof.hpp>
17
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>
23
24namespace boost {
25namespace compute {
26namespace detail {
27
28template<class DeviceIterator, class HostIterator>
29inline HostIterator copy_to_host(DeviceIterator first,
30 DeviceIterator last,
31 HostIterator result,
32 command_queue &queue)
33{
34 typedef typename
35 std::iterator_traits<DeviceIterator>::value_type
36 value_type;
37
38 size_t count = iterator_range_size(first, last);
39 if(count == 0){
40 return result;
41 }
42
43 const buffer &buffer = first.get_buffer();
44 size_t offset = first.get_index();
45
46 queue.enqueue_read_buffer(buffer,
47 offset * sizeof(value_type),
48 count * sizeof(value_type),
49 ::boost::addressof(*result));
50
51 return iterator_plus_distance(result, count);
52}
53
54template<class DeviceIterator, class HostIterator>
55inline HostIterator copy_to_host_map(DeviceIterator first,
56 DeviceIterator last,
57 HostIterator result,
58 command_queue &queue)
59{
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;
66
67 size_t count = iterator_range_size(first, last);
68 if(count == 0){
69 return result;
70 }
71
72 size_t offset = first.get_index();
73
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)
81 )
82 );
83
84 // copy [first; last) to result buffer
85 std::copy(
86 pointer,
87 pointer + static_cast<difference_type>(count),
88 result
89 );
90
91 // unmap [first; last)
92 boost::compute::event unmap_event = queue.enqueue_unmap_buffer(
93 first.get_buffer(),
94 static_cast<void*>(pointer)
95 );
96 unmap_event.wait();
97
98 return iterator_plus_distance(result, count);
99}
100
101template<class DeviceIterator, class HostIterator>
102inline future<HostIterator> copy_to_host_async(DeviceIterator first,
103 DeviceIterator last,
104 HostIterator result,
105 command_queue &queue)
106{
107 typedef typename
108 std::iterator_traits<DeviceIterator>::value_type
109 value_type;
110
111 size_t count = iterator_range_size(first, last);
112 if(count == 0){
113 return future<HostIterator>();
114 }
115
116 const buffer &buffer = first.get_buffer();
117 size_t offset = first.get_index();
118
119 event event_ =
120 queue.enqueue_read_buffer_async(buffer,
121 offset * sizeof(value_type),
122 count * sizeof(value_type),
123 ::boost::addressof(*result));
124
125 return make_future(iterator_plus_distance(result, count), event_);
126}
127
128#ifdef CL_VERSION_2_0
129// copy_to_host() specialization for svm_ptr
130template<class T, class HostIterator>
131inline HostIterator copy_to_host(svm_ptr<T> first,
132 svm_ptr<T> last,
133 HostIterator result,
134 command_queue &queue)
135{
136 size_t count = iterator_range_size(first, last);
137 if(count == 0){
138 return result;
139 }
140
141 queue.enqueue_svm_memcpy(
142 ::boost::addressof(*result), first.get(), count * sizeof(T)
143 );
144
145 return result + count;
146}
147
148template<class T, class HostIterator>
149inline future<HostIterator> copy_to_host_async(svm_ptr<T> first,
150 svm_ptr<T> last,
151 HostIterator result,
152 command_queue &queue)
153{
154 size_t count = iterator_range_size(first, last);
155 if(count == 0){
156 return future<HostIterator>();
157 }
158
159 event event_ = queue.enqueue_svm_memcpy_async(
160 ::boost::addressof(*result), first.get(), count * sizeof(T)
161 );
162
163 return make_future(iterator_plus_distance(result, count), event_);
164}
165
166template<class T, class HostIterator>
167inline HostIterator copy_to_host_map(svm_ptr<T> first,
168 svm_ptr<T> last,
169 HostIterator result,
170 command_queue &queue)
171{
172 size_t count = iterator_range_size(first, last);
173 if(count == 0){
174 return result;
175 }
176
177 // map
178 queue.enqueue_svm_map(first.get(), count * sizeof(T), CL_MAP_READ);
179
180 // copy [first; last) to result
181 std::copy(
182 static_cast<T*>(first.get()),
183 static_cast<T*>(last.get()),
184 result
185 );
186
187 // unmap [first; last)
188 queue.enqueue_svm_unmap(first.get()).wait();
189
190 return iterator_plus_distance(result, count);
191}
192#endif // CL_VERSION_2_0
193
194} // end detail namespace
195} // end compute namespace
196} // end boost namespace
197
198#endif // BOOST_COMPUTE_ALGORITHM_DETAIL_COPY_TO_HOST_HPP