]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/compute/algorithm/detail/copy_to_device.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / compute / algorithm / detail / copy_to_device.hpp
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_DEVICE_HPP
12 #define BOOST_COMPUTE_ALGORITHM_DETAIL_COPY_TO_DEVICE_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
23 namespace boost {
24 namespace compute {
25 namespace detail {
26
27 template<class HostIterator, class DeviceIterator>
28 inline DeviceIterator copy_to_device(HostIterator first,
29 HostIterator last,
30 DeviceIterator result,
31 command_queue &queue)
32 {
33 typedef typename
34 std::iterator_traits<DeviceIterator>::value_type
35 value_type;
36 typedef typename
37 std::iterator_traits<DeviceIterator>::difference_type
38 difference_type;
39
40 size_t count = iterator_range_size(first, last);
41 if(count == 0){
42 return result;
43 }
44
45 size_t offset = result.get_index();
46
47 queue.enqueue_write_buffer(result.get_buffer(),
48 offset * sizeof(value_type),
49 count * sizeof(value_type),
50 ::boost::addressof(*first));
51
52 return result + static_cast<difference_type>(count);
53 }
54
55 template<class HostIterator, class DeviceIterator>
56 inline DeviceIterator copy_to_device_map(HostIterator first,
57 HostIterator last,
58 DeviceIterator result,
59 command_queue &queue)
60 {
61 typedef typename
62 std::iterator_traits<DeviceIterator>::value_type
63 value_type;
64 typedef typename
65 std::iterator_traits<DeviceIterator>::difference_type
66 difference_type;
67
68 size_t count = iterator_range_size(first, last);
69 if(count == 0){
70 return result;
71 }
72
73 size_t offset = result.get_index();
74
75 // map result buffer to host
76 value_type *pointer = static_cast<value_type*>(
77 queue.enqueue_map_buffer(
78 result.get_buffer(),
79 CL_MAP_WRITE,
80 offset * sizeof(value_type),
81 count * sizeof(value_type)
82 )
83 );
84
85 // copy [first; last) to result buffer
86 std::copy(first, last, pointer);
87
88 // unmap result buffer
89 boost::compute::event unmap_event = queue.enqueue_unmap_buffer(
90 result.get_buffer(),
91 static_cast<void*>(pointer)
92 );
93 unmap_event.wait();
94
95 return result + static_cast<difference_type>(count);
96 }
97
98 template<class HostIterator, class DeviceIterator>
99 inline future<DeviceIterator> copy_to_device_async(HostIterator first,
100 HostIterator last,
101 DeviceIterator result,
102 command_queue &queue)
103 {
104 typedef typename
105 std::iterator_traits<DeviceIterator>::value_type
106 value_type;
107 typedef typename
108 std::iterator_traits<DeviceIterator>::difference_type
109 difference_type;
110
111 size_t count = iterator_range_size(first, last);
112 if(count == 0){
113 return future<DeviceIterator>();
114 }
115
116 size_t offset = result.get_index();
117
118 event event_ =
119 queue.enqueue_write_buffer_async(result.get_buffer(),
120 offset * sizeof(value_type),
121 count * sizeof(value_type),
122 ::boost::addressof(*first));
123
124 return make_future(result + static_cast<difference_type>(count), event_);
125 }
126
127 #ifdef BOOST_COMPUTE_CL_VERSION_2_0
128 // copy_to_device() specialization for svm_ptr
129 template<class HostIterator, class T>
130 inline svm_ptr<T> copy_to_device(HostIterator first,
131 HostIterator last,
132 svm_ptr<T> result,
133 command_queue &queue)
134 {
135 size_t count = iterator_range_size(first, last);
136 if(count == 0){
137 return result;
138 }
139
140 queue.enqueue_svm_memcpy(
141 result.get(), ::boost::addressof(*first), count * sizeof(T)
142 );
143
144 return result + count;
145 }
146
147 template<class HostIterator, class T>
148 inline future<svm_ptr<T> > copy_to_device_async(HostIterator first,
149 HostIterator last,
150 svm_ptr<T> result,
151 command_queue &queue)
152 {
153 size_t count = iterator_range_size(first, last);
154 if(count == 0){
155 return future<svm_ptr<T> >();
156 }
157
158 event event_ = queue.enqueue_svm_memcpy_async(
159 result.get(), ::boost::addressof(*first), count * sizeof(T)
160 );
161
162 return make_future(result + count, event_);
163 }
164
165 template<class HostIterator, class T>
166 inline svm_ptr<T> copy_to_device_map(HostIterator first,
167 HostIterator last,
168 svm_ptr<T> result,
169 command_queue &queue)
170 {
171 size_t count = iterator_range_size(first, last);
172 if(count == 0){
173 return result;
174 }
175
176 // map
177 queue.enqueue_svm_map(result.get(), count * sizeof(T), CL_MAP_WRITE);
178
179 // copy [first; last) to result buffer
180 std::copy(first, last, static_cast<T*>(result.get()));
181
182 // unmap result
183 queue.enqueue_svm_unmap(result.get()).wait();
184
185 return result + count;
186 }
187 #endif // BOOST_COMPUTE_CL_VERSION_2_0
188
189 } // end detail namespace
190 } // end compute namespace
191 } // end boost namespace
192
193 #endif // BOOST_COMPUTE_ALGORITHM_DETAIL_COPY_TO_DEVICE_HPP