File indexing completed on 2024-11-15 09:04:25
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_COMPUTE_DEVICE_PTR_HPP
0012 #define BOOST_COMPUTE_DEVICE_PTR_HPP
0013
0014 #include <boost/type_traits.hpp>
0015 #include <boost/static_assert.hpp>
0016
0017 #include <boost/compute/buffer.hpp>
0018 #include <boost/compute/config.hpp>
0019 #include <boost/compute/detail/is_buffer_iterator.hpp>
0020 #include <boost/compute/detail/read_write_single_value.hpp>
0021 #include <boost/compute/type_traits/is_device_iterator.hpp>
0022
0023 namespace boost {
0024 namespace compute {
0025 namespace detail {
0026
0027 template<class T, class IndexExpr>
0028 struct device_ptr_index_expr
0029 {
0030 typedef T result_type;
0031
0032 device_ptr_index_expr(const buffer &buffer,
0033 uint_ index,
0034 const IndexExpr &expr)
0035 : m_buffer(buffer),
0036 m_index(index),
0037 m_expr(expr)
0038 {
0039 }
0040
0041 operator T() const
0042 {
0043 BOOST_STATIC_ASSERT_MSG(boost::is_integral<IndexExpr>::value,
0044 "Index expression must be integral");
0045
0046 BOOST_ASSERT(m_buffer.get());
0047
0048 const context &context = m_buffer.get_context();
0049 const device &device = context.get_device();
0050 command_queue queue(context, device);
0051
0052 return detail::read_single_value<T>(m_buffer, m_expr, queue);
0053 }
0054
0055 const buffer &m_buffer;
0056 uint_ m_index;
0057 IndexExpr m_expr;
0058 };
0059
0060 template<class T>
0061 class device_ptr
0062 {
0063 public:
0064 typedef T value_type;
0065 typedef std::size_t size_type;
0066 typedef std::ptrdiff_t difference_type;
0067 typedef std::random_access_iterator_tag iterator_category;
0068 typedef T* pointer;
0069 typedef T& reference;
0070
0071 device_ptr()
0072 : m_index(0)
0073 {
0074 }
0075
0076 device_ptr(const buffer &buffer, size_t index = 0)
0077 : m_buffer(buffer.get(), false),
0078 m_index(index)
0079 {
0080 }
0081
0082 device_ptr(const device_ptr<T> &other)
0083 : m_buffer(other.m_buffer.get(), false),
0084 m_index(other.m_index)
0085 {
0086 }
0087
0088 device_ptr<T>& operator=(const device_ptr<T> &other)
0089 {
0090 if(this != &other){
0091 m_buffer.get() = other.m_buffer.get();
0092 m_index = other.m_index;
0093 }
0094
0095 return *this;
0096 }
0097
0098 #ifndef BOOST_COMPUTE_NO_RVALUE_REFERENCES
0099 device_ptr(device_ptr<T>&& other) BOOST_NOEXCEPT
0100 : m_buffer(other.m_buffer.get(), false),
0101 m_index(other.m_index)
0102 {
0103 other.m_buffer.get() = 0;
0104 }
0105
0106 device_ptr<T>& operator=(device_ptr<T>&& other) BOOST_NOEXCEPT
0107 {
0108 m_buffer.get() = other.m_buffer.get();
0109 m_index = other.m_index;
0110
0111 other.m_buffer.get() = 0;
0112
0113 return *this;
0114 }
0115 #endif
0116
0117 ~device_ptr()
0118 {
0119
0120
0121 m_buffer.get() = 0;
0122 }
0123
0124 size_type get_index() const
0125 {
0126 return m_index;
0127 }
0128
0129 const buffer& get_buffer() const
0130 {
0131 return m_buffer;
0132 }
0133
0134 template<class OT>
0135 device_ptr<OT> cast() const
0136 {
0137 return device_ptr<OT>(m_buffer, m_index);
0138 }
0139
0140 device_ptr<T> operator+(difference_type n) const
0141 {
0142 return device_ptr<T>(m_buffer, m_index + n);
0143 }
0144
0145 device_ptr<T> operator+(const device_ptr<T> &other) const
0146 {
0147 return device_ptr<T>(m_buffer, m_index + other.m_index);
0148 }
0149
0150 device_ptr<T>& operator+=(difference_type n)
0151 {
0152 m_index += static_cast<size_t>(n);
0153 return *this;
0154 }
0155
0156 difference_type operator-(const device_ptr<T> &other) const
0157 {
0158 return static_cast<difference_type>(m_index - other.m_index);
0159 }
0160
0161 device_ptr<T>& operator-=(difference_type n)
0162 {
0163 m_index -= n;
0164 return *this;
0165 }
0166
0167 bool operator==(const device_ptr<T> &other) const
0168 {
0169 return m_buffer.get() == other.m_buffer.get() &&
0170 m_index == other.m_index;
0171 }
0172
0173 bool operator!=(const device_ptr<T> &other) const
0174 {
0175 return !(*this == other);
0176 }
0177
0178 template<class Expr>
0179 detail::device_ptr_index_expr<T, Expr>
0180 operator[](const Expr &expr) const
0181 {
0182 BOOST_ASSERT(m_buffer.get());
0183
0184 return detail::device_ptr_index_expr<T, Expr>(m_buffer,
0185 uint_(m_index),
0186 expr);
0187 }
0188
0189 private:
0190 const buffer m_buffer;
0191 size_t m_index;
0192 };
0193
0194
0195 template<class Iterator>
0196 struct is_buffer_iterator<
0197 Iterator,
0198 typename boost::enable_if<
0199 boost::is_same<
0200 device_ptr<typename Iterator::value_type>,
0201 typename boost::remove_const<Iterator>::type
0202 >
0203 >::type
0204 > : public boost::true_type {};
0205
0206 }
0207
0208
0209 template<class T>
0210 struct is_device_iterator<detail::device_ptr<T> > : boost::true_type {};
0211
0212 }
0213 }
0214
0215 #endif