File indexing completed on 2025-01-18 09:43:01
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef boost_numeric_ublas_opencl_matrix_hpp_
0011 #define boost_numeric_ublas_opencl_matrix_hpp_
0012
0013 #include <boost/numeric/ublas/opencl/library.hpp>
0014 #include <boost/numeric/ublas/matrix.hpp>
0015 #include <boost/numeric/ublas/functional.hpp>
0016 #include <boost/compute/core.hpp>
0017 #include <boost/compute/algorithm.hpp>
0018 #include <boost/compute/buffer.hpp>
0019
0020 namespace boost { namespace numeric { namespace ublas { namespace opencl {
0021
0022 class storage;
0023
0024 namespace compute = boost::compute;
0025
0026 }
0027
0028 template<class T, class L>
0029 class matrix<T, L, opencl::storage> : public matrix_container<matrix<T, L, opencl::storage> >
0030 {
0031 typedef typename boost::compute::buffer_allocator<T>::size_type size_type;
0032 typedef L layout_type;
0033 typedef matrix<T, L, opencl::storage> self_type;
0034 public:
0035 matrix()
0036 : matrix_container<self_type>(),
0037 size1_(0), size2_(0), data_() , device_()
0038 {}
0039
0040 matrix(size_type size1, size_type size2, compute::context c)
0041 : matrix_container<self_type>(),
0042 size1_(size1), size2_(size2), device_(c.get_device())
0043 {
0044 compute::buffer_allocator<T> allocator(c);
0045 data_ = allocator.allocate(layout_type::storage_size(size1, size2)).get_buffer();
0046 }
0047
0048 matrix(size_type size1, size_type size2, T const &value, compute::command_queue &q)
0049 : matrix_container<self_type>(),
0050 size1_(size1), size2_(size2), device_(q.get_device())
0051 {
0052 compute::buffer_allocator<T> allocator(q.get_context());
0053 data_ = allocator.allocate(layout_type::storage_size(size1, size2)).get_buffer();
0054 compute::fill(this->begin(), this->end(), value, q);
0055 q.finish();
0056 }
0057
0058 template <typename A>
0059 matrix(matrix<T, L, A> const &m, compute::command_queue &queue)
0060 : matrix(m.size1(), m.size2(), queue.get_context())
0061 {
0062 this->from_host(m, queue);
0063 }
0064
0065 size_type size1() const { return size1_;}
0066 size_type size2() const { return size2_;}
0067
0068 const compute::buffer_iterator<T> begin() const { return compute::make_buffer_iterator<T>(data_);}
0069 compute::buffer_iterator<T> begin() { return compute::make_buffer_iterator<T>(data_);}
0070
0071 compute::buffer_iterator<T> end() { return compute::make_buffer_iterator<T>(data_, layout_type::storage_size(size1_, size2_));}
0072 const compute::buffer_iterator<T> end() const { return compute::make_buffer_iterator<T>(data_, layout_type::storage_size(size1_, size2_));}
0073
0074 const compute::device &device() const { return device_;}
0075 compute::device &device() { return device_;}
0076
0077 void fill(T value, compute::command_queue &queue)
0078 {
0079 assert(device_ == queue.get_device());
0080 compute::fill(this->begin(), this->end(), value, queue);
0081 queue.finish();
0082 }
0083
0084
0085
0086
0087
0088 template<class A>
0089 void from_host(ublas::matrix<T, L, A> const &m, compute::command_queue &queue)
0090 {
0091 assert(device_ == queue.get_device());
0092 compute::copy(m.data().begin(),
0093 m.data().end(),
0094 this->begin(),
0095 queue);
0096 queue.finish();
0097 }
0098
0099
0100
0101
0102
0103 template<class A>
0104 void to_host(ublas::matrix<T, L, A> &m, compute::command_queue &queue) const
0105 {
0106 assert(device_ == queue.get_device());
0107 compute::copy(this->begin(),
0108 this->end(),
0109 m.data().begin(),
0110 queue);
0111 queue.finish();
0112 }
0113
0114 private:
0115 size_type size1_;
0116 size_type size2_;
0117 compute::buffer data_;
0118 compute::device device_;
0119 };
0120
0121 }}}
0122
0123 #endif