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