File indexing completed on 2025-01-18 09:29:53
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_COMPUTE_ALGORITHM_DETAIL_COPY_TO_DEVICE_HPP
0012 #define BOOST_COMPUTE_ALGORITHM_DETAIL_COPY_TO_DEVICE_HPP
0013
0014 #include <iterator>
0015
0016 #include <boost/utility/addressof.hpp>
0017
0018 #include <boost/compute/command_queue.hpp>
0019 #include <boost/compute/async/future.hpp>
0020 #include <boost/compute/iterator/buffer_iterator.hpp>
0021 #include <boost/compute/memory/svm_ptr.hpp>
0022
0023 namespace boost {
0024 namespace compute {
0025 namespace detail {
0026
0027 template<class HostIterator, class DeviceIterator>
0028 inline DeviceIterator copy_to_device(HostIterator first,
0029 HostIterator last,
0030 DeviceIterator result,
0031 command_queue &queue,
0032 const wait_list &events)
0033 {
0034 typedef typename
0035 std::iterator_traits<DeviceIterator>::value_type
0036 value_type;
0037 typedef typename
0038 std::iterator_traits<DeviceIterator>::difference_type
0039 difference_type;
0040
0041 size_t count = iterator_range_size(first, last);
0042 if(count == 0){
0043 return result;
0044 }
0045
0046 size_t offset = result.get_index();
0047
0048 queue.enqueue_write_buffer(result.get_buffer(),
0049 offset * sizeof(value_type),
0050 count * sizeof(value_type),
0051 ::boost::addressof(*first),
0052 events);
0053
0054 return result + static_cast<difference_type>(count);
0055 }
0056
0057 template<class HostIterator, class DeviceIterator>
0058 inline DeviceIterator copy_to_device_map(HostIterator first,
0059 HostIterator last,
0060 DeviceIterator result,
0061 command_queue &queue,
0062 const wait_list &events)
0063 {
0064 typedef typename
0065 std::iterator_traits<DeviceIterator>::value_type
0066 value_type;
0067 typedef typename
0068 std::iterator_traits<DeviceIterator>::difference_type
0069 difference_type;
0070
0071 size_t count = iterator_range_size(first, last);
0072 if(count == 0){
0073 return result;
0074 }
0075
0076 size_t offset = result.get_index();
0077
0078
0079 value_type *pointer = static_cast<value_type*>(
0080 queue.enqueue_map_buffer(
0081 result.get_buffer(),
0082 CL_MAP_WRITE,
0083 offset * sizeof(value_type),
0084 count * sizeof(value_type),
0085 events
0086 )
0087 );
0088
0089
0090 std::copy(first, last, pointer);
0091
0092
0093 boost::compute::event unmap_event = queue.enqueue_unmap_buffer(
0094 result.get_buffer(),
0095 static_cast<void*>(pointer)
0096 );
0097 unmap_event.wait();
0098
0099 return result + static_cast<difference_type>(count);
0100 }
0101
0102 template<class HostIterator, class DeviceIterator>
0103 inline future<DeviceIterator> copy_to_device_async(HostIterator first,
0104 HostIterator last,
0105 DeviceIterator result,
0106 command_queue &queue,
0107 const wait_list &events)
0108 {
0109 typedef typename
0110 std::iterator_traits<DeviceIterator>::value_type
0111 value_type;
0112 typedef typename
0113 std::iterator_traits<DeviceIterator>::difference_type
0114 difference_type;
0115
0116 size_t count = iterator_range_size(first, last);
0117 if(count == 0){
0118 return future<DeviceIterator>();
0119 }
0120
0121 size_t offset = result.get_index();
0122
0123 event event_ =
0124 queue.enqueue_write_buffer_async(result.get_buffer(),
0125 offset * sizeof(value_type),
0126 count * sizeof(value_type),
0127 ::boost::addressof(*first),
0128 events);
0129
0130 return make_future(result + static_cast<difference_type>(count), event_);
0131 }
0132
0133 #ifdef BOOST_COMPUTE_CL_VERSION_2_0
0134
0135 template<class HostIterator, class T>
0136 inline svm_ptr<T> copy_to_device(HostIterator first,
0137 HostIterator last,
0138 svm_ptr<T> result,
0139 command_queue &queue,
0140 const wait_list &events)
0141 {
0142 size_t count = iterator_range_size(first, last);
0143 if(count == 0){
0144 return result;
0145 }
0146
0147 queue.enqueue_svm_memcpy(
0148 result.get(), ::boost::addressof(*first), count * sizeof(T), events
0149 );
0150
0151 return result + count;
0152 }
0153
0154 template<class HostIterator, class T>
0155 inline future<svm_ptr<T> > copy_to_device_async(HostIterator first,
0156 HostIterator last,
0157 svm_ptr<T> result,
0158 command_queue &queue,
0159 const wait_list &events)
0160 {
0161 size_t count = iterator_range_size(first, last);
0162 if(count == 0){
0163 return future<svm_ptr<T> >();
0164 }
0165
0166 event event_ = queue.enqueue_svm_memcpy_async(
0167 result.get(), ::boost::addressof(*first), count * sizeof(T), events
0168 );
0169
0170 return make_future(result + count, event_);
0171 }
0172
0173 template<class HostIterator, class T>
0174 inline svm_ptr<T> copy_to_device_map(HostIterator first,
0175 HostIterator last,
0176 svm_ptr<T> result,
0177 command_queue &queue,
0178 const wait_list &events)
0179 {
0180 size_t count = iterator_range_size(first, last);
0181 if(count == 0){
0182 return result;
0183 }
0184
0185
0186 queue.enqueue_svm_map(
0187 result.get(), count * sizeof(T), CL_MAP_WRITE, events
0188 );
0189
0190
0191 std::copy(first, last, static_cast<T*>(result.get()));
0192
0193
0194 queue.enqueue_svm_unmap(result.get()).wait();
0195
0196 return result + count;
0197 }
0198 #endif
0199
0200 }
0201 }
0202 }
0203
0204 #endif