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_DEVICE_HPP
12 #define BOOST_COMPUTE_ALGORITHM_DETAIL_COPY_TO_DEVICE_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>
27 template<class HostIterator, class DeviceIterator>
28 inline DeviceIterator copy_to_device(HostIterator first,
30 DeviceIterator result,
34 std::iterator_traits<DeviceIterator>::value_type
37 std::iterator_traits<DeviceIterator>::difference_type
40 size_t count = iterator_range_size(first, last);
45 size_t offset = result.get_index();
47 queue.enqueue_write_buffer(result.get_buffer(),
48 offset * sizeof(value_type),
49 count * sizeof(value_type),
50 ::boost::addressof(*first));
52 return result + static_cast<difference_type>(count);
55 template<class HostIterator, class DeviceIterator>
56 inline DeviceIterator copy_to_device_map(HostIterator first,
58 DeviceIterator result,
62 std::iterator_traits<DeviceIterator>::value_type
65 std::iterator_traits<DeviceIterator>::difference_type
68 size_t count = iterator_range_size(first, last);
73 size_t offset = result.get_index();
75 // map result buffer to host
76 value_type *pointer = static_cast<value_type*>(
77 queue.enqueue_map_buffer(
80 offset * sizeof(value_type),
81 count * sizeof(value_type)
85 // copy [first; last) to result buffer
86 std::copy(first, last, pointer);
88 // unmap result buffer
89 boost::compute::event unmap_event = queue.enqueue_unmap_buffer(
91 static_cast<void*>(pointer)
95 return result + static_cast<difference_type>(count);
98 template<class HostIterator, class DeviceIterator>
99 inline future<DeviceIterator> copy_to_device_async(HostIterator first,
101 DeviceIterator result,
102 command_queue &queue)
105 std::iterator_traits<DeviceIterator>::value_type
108 std::iterator_traits<DeviceIterator>::difference_type
111 size_t count = iterator_range_size(first, last);
113 return future<DeviceIterator>();
116 size_t offset = result.get_index();
119 queue.enqueue_write_buffer_async(result.get_buffer(),
120 offset * sizeof(value_type),
121 count * sizeof(value_type),
122 ::boost::addressof(*first));
124 return make_future(result + static_cast<difference_type>(count), event_);
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,
133 command_queue &queue)
135 size_t count = iterator_range_size(first, last);
140 queue.enqueue_svm_memcpy(
141 result.get(), ::boost::addressof(*first), count * sizeof(T)
144 return result + count;
147 template<class HostIterator, class T>
148 inline future<svm_ptr<T> > copy_to_device_async(HostIterator first,
151 command_queue &queue)
153 size_t count = iterator_range_size(first, last);
155 return future<svm_ptr<T> >();
158 event event_ = queue.enqueue_svm_memcpy_async(
159 result.get(), ::boost::addressof(*first), count * sizeof(T)
162 return make_future(result + count, event_);
165 template<class HostIterator, class T>
166 inline svm_ptr<T> copy_to_device_map(HostIterator first,
169 command_queue &queue)
171 size_t count = iterator_range_size(first, last);
177 queue.enqueue_svm_map(result.get(), count * sizeof(T), CL_MAP_WRITE);
179 // copy [first; last) to result buffer
180 std::copy(first, last, static_cast<T*>(result.get()));
183 queue.enqueue_svm_unmap(result.get()).wait();
185 return result + count;
187 #endif // BOOST_COMPUTE_CL_VERSION_2_0
189 } // end detail namespace
190 } // end compute namespace
191 } // end boost namespace
193 #endif // BOOST_COMPUTE_ALGORITHM_DETAIL_COPY_TO_DEVICE_HPP