1 // Boost.uBLAS 2 // 3 // Copyright (c) 2018 Fady Essam 4 // Copyright (c) 2018 Stefan Seefeld 5 // 6 // Distributed under the Boost Software License, Version 1.0. 7 // (See accompanying file LICENSE_1_0.txt or 8 // copy at http://www.boost.org/LICENSE_1_0.txt) 9 10 #ifndef boost_numeric_ublas_opencl_matrix_hpp_ 11 #define boost_numeric_ublas_opencl_matrix_hpp_ 12 13 #include <boost/numeric/ublas/opencl/library.hpp> 14 #include <boost/numeric/ublas/matrix.hpp> 15 #include <boost/numeric/ublas/functional.hpp> 16 #include <boost/compute/core.hpp> 17 #include <boost/compute/algorithm.hpp> 18 #include <boost/compute/buffer.hpp> 19 20 namespace boost { namespace numeric { namespace ublas { namespace opencl { 21 22 class storage; 23 24 namespace compute = boost::compute; 25 26 } // namespace opencl 27 28 template<class T, class L> 29 class matrix<T, L, opencl::storage> : public matrix_container<matrix<T, L, opencl::storage> > 30 { 31 typedef typename boost::compute::buffer_allocator<T>::size_type size_type; 32 typedef L layout_type; 33 typedef matrix<T, L, opencl::storage> self_type; 34 public: matrix()35 matrix() 36 : matrix_container<self_type>(), 37 size1_(0), size2_(0), data_() , device_() 38 {} 39 matrix(size_type size1,size_type size2,compute::context c)40 matrix(size_type size1, size_type size2, compute::context c) 41 : matrix_container<self_type>(), 42 size1_(size1), size2_(size2), device_(c.get_device()) 43 { 44 compute::buffer_allocator<T> allocator(c); 45 data_ = allocator.allocate(layout_type::storage_size(size1, size2)).get_buffer(); 46 } 47 matrix(size_type size1,size_type size2,T const & value,compute::command_queue & q)48 matrix(size_type size1, size_type size2, T const &value, compute::command_queue &q) 49 : matrix_container<self_type>(), 50 size1_(size1), size2_(size2), device_(q.get_device()) 51 { 52 compute::buffer_allocator<T> allocator(q.get_context()); 53 data_ = allocator.allocate(layout_type::storage_size(size1, size2)).get_buffer(); 54 compute::fill(this->begin(), this->end(), value, q); 55 q.finish(); 56 } 57 58 template <typename A> matrix(matrix<T,L,A> const & m,compute::command_queue & queue)59 matrix(matrix<T, L, A> const &m, compute::command_queue &queue) 60 : matrix(m.size1(), m.size2(), queue.get_context()) 61 { 62 this->from_host(m, queue); 63 } 64 size1() const65 size_type size1() const { return size1_;} size2() const66 size_type size2() const { return size2_;} 67 begin() const68 const compute::buffer_iterator<T> begin() const { return compute::make_buffer_iterator<T>(data_);} begin()69 compute::buffer_iterator<T> begin() { return compute::make_buffer_iterator<T>(data_);} 70 end()71 compute::buffer_iterator<T> end() { return compute::make_buffer_iterator<T>(data_, layout_type::storage_size(size1_, size2_));} end() const72 const compute::buffer_iterator<T> end() const { return compute::make_buffer_iterator<T>(data_, layout_type::storage_size(size1_, size2_));} 73 device() const74 const compute::device &device() const { return device_;} device()75 compute::device &device() { return device_;} 76 fill(T value,compute::command_queue & queue)77 void fill(T value, compute::command_queue &queue) 78 { 79 assert(device_ == queue.get_device()); 80 compute::fill(this->begin(), this->end(), value, queue); 81 queue.finish(); 82 } 83 84 /** Copies a matrix to a device 85 * \param m is a matrix that is not on the device _device and it is copied to it 86 * \param queue is the command queue that will execute the operation 87 */ 88 template<class A> from_host(ublas::matrix<T,L,A> const & m,compute::command_queue & queue)89 void from_host(ublas::matrix<T, L, A> const &m, compute::command_queue &queue) 90 { 91 assert(device_ == queue.get_device()); 92 compute::copy(m.data().begin(), 93 m.data().end(), 94 this->begin(), 95 queue); 96 queue.finish(); 97 } 98 99 /** Copies a matrix from a device 100 * \param m is a matrix that will be reized to (size1_,size2) and the values of (*this) will be copied in it 101 * \param queue is the command queue that will execute the operation 102 */ 103 template<class A> to_host(ublas::matrix<T,L,A> & m,compute::command_queue & queue) const104 void to_host(ublas::matrix<T, L, A> &m, compute::command_queue &queue) const 105 { 106 assert(device_ == queue.get_device()); 107 compute::copy(this->begin(), 108 this->end(), 109 m.data().begin(), 110 queue); 111 queue.finish(); 112 } 113 114 private: 115 size_type size1_; 116 size_type size2_; 117 compute::buffer data_; 118 compute::device device_; 119 }; 120 121 }}} 122 123 #endif 124