1 //---------------------------------------------------------------------------//
2 // Copyright (c) 2013-2014 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_MEMORY_SVM_PTR_HPP
12 #define BOOST_COMPUTE_MEMORY_SVM_PTR_HPP
14 #include <boost/type_traits.hpp>
15 #include <boost/static_assert.hpp>
16 #include <boost/assert.hpp>
18 #include <boost/compute/cl.hpp>
19 #include <boost/compute/kernel.hpp>
20 #include <boost/compute/context.hpp>
21 #include <boost/compute/command_queue.hpp>
22 #include <boost/compute/type_traits/is_device_iterator.hpp>
27 // forward declaration for svm_ptr<T>
31 // svm functions require OpenCL 2.0
32 #if defined(CL_VERSION_2_0) || defined(BOOST_COMPUTE_DOXYGEN_INVOKED)
35 template<class T, class IndexExpr>
36 struct svm_ptr_index_expr
38 typedef T result_type;
40 svm_ptr_index_expr(const svm_ptr<T> &svm_ptr,
41 const IndexExpr &expr)
49 BOOST_STATIC_ASSERT_MSG(boost::is_integral<IndexExpr>::value,
50 "Index expression must be integral");
52 BOOST_ASSERT(m_svm_ptr.get());
54 const context &context = m_svm_ptr.get_context();
55 const device &device = context.get_device();
56 command_queue queue(context, device);
60 static_cast<T*>(m_svm_ptr.get()) + static_cast<std::ptrdiff_t>(m_expr);
61 queue.enqueue_svm_map(static_cast<void*>(ptr), sizeof(T), CL_MAP_READ);
63 queue.enqueue_svm_unmap(static_cast<void*>(ptr)).wait();
68 const svm_ptr<T> &m_svm_ptr;
72 } // end detail namespace
80 typedef std::ptrdiff_t difference_type;
83 typedef std::random_access_iterator_tag iterator_category;
90 svm_ptr(void *ptr, const context &context)
91 : m_ptr(static_cast<T*>(ptr)),
96 svm_ptr(const svm_ptr<T> &other)
98 m_context(other.m_context)
102 svm_ptr<T>& operator=(const svm_ptr<T> &other)
105 m_context = other.m_context;
118 svm_ptr<T> operator+(difference_type n)
120 return svm_ptr<T>(m_ptr + n, m_context);
123 difference_type operator-(svm_ptr<T> other)
125 BOOST_ASSERT(other.m_context == m_context);
126 return m_ptr - other.m_ptr;
129 context& get_context() const
134 // svm functions require OpenCL 2.0
135 #if defined(CL_VERSION_2_0) || defined(BOOST_COMPUTE_DOXYGEN_INVOKED)
138 detail::svm_ptr_index_expr<T, Expr>
139 operator[](const Expr &expr) const
143 return detail::svm_ptr_index_expr<T, Expr>(*this,
157 struct set_kernel_arg<svm_ptr<T> >
159 void operator()(kernel &kernel_, size_t index, const svm_ptr<T> &ptr)
161 kernel_.set_arg_svm_ptr(index, ptr.get());
165 } // end detail namespace
167 /// \internal_ (is_device_iterator specialization for svm_ptr)
169 struct is_device_iterator<svm_ptr<T> > : boost::true_type {};
171 } // end compute namespace
172 } // end boost namespace
174 #endif // BOOST_COMPUTE_MEMORY_SVM_PTR_HPP