1 //---------------------------------------------------------------------------// 2 // Copyright (c) 2013-2014 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_ALLOCATOR_BUFFER_ALLOCATOR_HPP 12 #define BOOST_COMPUTE_ALLOCATOR_BUFFER_ALLOCATOR_HPP 13 14 #include <boost/compute/buffer.hpp> 15 #include <boost/compute/config.hpp> 16 #include <boost/compute/context.hpp> 17 #include <boost/compute/detail/device_ptr.hpp> 18 19 namespace boost { 20 namespace compute { 21 22 /// \class buffer_allocator 23 /// \brief The buffer_allocator class allocates memory with \ref buffer objects 24 /// 25 /// \see buffer 26 template<class T> 27 class buffer_allocator 28 { 29 public: 30 typedef T value_type; 31 typedef detail::device_ptr<T> pointer; 32 typedef const detail::device_ptr<T> const_pointer; 33 typedef std::size_t size_type; 34 typedef std::ptrdiff_t difference_type; 35 buffer_allocator(const context & context)36 explicit buffer_allocator(const context &context) 37 : m_context(context), 38 m_mem_flags(buffer::read_write) 39 { 40 } 41 buffer_allocator(const buffer_allocator<T> & other)42 buffer_allocator(const buffer_allocator<T> &other) 43 : m_context(other.m_context), 44 m_mem_flags(other.m_mem_flags) 45 { 46 } 47 operator =(const buffer_allocator<T> & other)48 buffer_allocator<T>& operator=(const buffer_allocator<T> &other) 49 { 50 if(this != &other){ 51 m_context = other.m_context; 52 m_mem_flags = other.m_mem_flags; 53 } 54 55 return *this; 56 } 57 58 #ifndef BOOST_COMPUTE_NO_RVALUE_REFERENCES buffer_allocator(buffer_allocator<T> && other)59 buffer_allocator(buffer_allocator<T>&& other) BOOST_NOEXCEPT 60 : m_context(std::move(other.m_context)), 61 m_mem_flags(other.m_mem_flags) 62 { 63 } 64 operator =(buffer_allocator<T> && other)65 buffer_allocator<T>& operator=(buffer_allocator<T>&& other) BOOST_NOEXCEPT 66 { 67 m_context = std::move(other.m_context); 68 m_mem_flags = other.m_mem_flags; 69 70 return *this; 71 } 72 #endif // BOOST_COMPUTE_NO_RVALUE_REFERENCES 73 ~buffer_allocator()74 ~buffer_allocator() 75 { 76 } 77 allocate(size_type n)78 pointer allocate(size_type n) 79 { 80 buffer buf(m_context, n * sizeof(T), m_mem_flags); 81 clRetainMemObject(buf.get()); 82 return detail::device_ptr<T>(buf); 83 } 84 deallocate(pointer p,size_type n)85 void deallocate(pointer p, size_type n) 86 { 87 BOOST_ASSERT(p.get_buffer().get_context() == m_context); 88 89 (void) n; 90 91 clReleaseMemObject(p.get_buffer().get()); 92 } 93 max_size() const94 size_type max_size() const 95 { 96 return m_context.get_device().max_memory_alloc_size() / sizeof(T); 97 } 98 get_context() const99 context get_context() const 100 { 101 return m_context; 102 } 103 104 protected: set_mem_flags(cl_mem_flags flags)105 void set_mem_flags(cl_mem_flags flags) 106 { 107 m_mem_flags = flags; 108 } 109 110 private: 111 context m_context; 112 cl_mem_flags m_mem_flags; 113 }; 114 115 } // end compute namespace 116 } // end boost namespace 117 118 #endif // BOOST_COMPUTE_ALLOCATOR_BUFFER_ALLOCATOR_HPP 119