matrix.hpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  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. #ifndef boost_numeric_ublas_opencl_matrix_hpp_
  10. #define boost_numeric_ublas_opencl_matrix_hpp_
  11. #include <boost/numeric/ublas/opencl/library.hpp>
  12. #include <boost/numeric/ublas/matrix.hpp>
  13. #include <boost/numeric/ublas/functional.hpp>
  14. #include <boost/compute/core.hpp>
  15. #include <boost/compute/algorithm.hpp>
  16. #include <boost/compute/buffer.hpp>
  17. namespace boost { namespace numeric { namespace ublas { namespace opencl {
  18. class storage;
  19. namespace compute = boost::compute;
  20. } // namespace opencl
  21. template<class T, class L>
  22. class matrix<T, L, opencl::storage> : public matrix_container<matrix<T, L, opencl::storage> >
  23. {
  24. typedef typename boost::compute::buffer_allocator<T>::size_type size_type;
  25. typedef L layout_type;
  26. typedef matrix<T, L, opencl::storage> self_type;
  27. public:
  28. matrix()
  29. : matrix_container<self_type>(),
  30. size1_(0), size2_(0), data_() , device_()
  31. {}
  32. matrix(size_type size1, size_type size2, compute::context c)
  33. : matrix_container<self_type>(),
  34. size1_(size1), size2_(size2), device_(c.get_device())
  35. {
  36. compute::buffer_allocator<T> allocator(c);
  37. data_ = allocator.allocate(layout_type::storage_size(size1, size2)).get_buffer();
  38. }
  39. matrix(size_type size1, size_type size2, T const &value, compute::command_queue &q)
  40. : matrix_container<self_type>(),
  41. size1_(size1), size2_(size2), device_(q.get_device())
  42. {
  43. compute::buffer_allocator<T> allocator(q.get_context());
  44. data_ = allocator.allocate(layout_type::storage_size(size1, size2)).get_buffer();
  45. compute::fill(this->begin(), this->end(), value, q);
  46. q.finish();
  47. }
  48. template <typename A>
  49. matrix(matrix<T, L, A> const &m, compute::command_queue &queue)
  50. : matrix(m.size1(), m.size2(), queue.get_context())
  51. {
  52. this->from_host(m, queue);
  53. }
  54. size_type size1() const { return size1_;}
  55. size_type size2() const { return size2_;}
  56. const compute::buffer_iterator<T> begin() const { return compute::make_buffer_iterator<T>(data_);}
  57. compute::buffer_iterator<T> begin() { return compute::make_buffer_iterator<T>(data_);}
  58. compute::buffer_iterator<T> end() { return compute::make_buffer_iterator<T>(data_, layout_type::storage_size(size1_, size2_));}
  59. const compute::buffer_iterator<T> end() const { return compute::make_buffer_iterator<T>(data_, layout_type::storage_size(size1_, size2_));}
  60. const compute::device &device() const { return device_;}
  61. compute::device &device() { return device_;}
  62. void fill(T value, compute::command_queue &queue)
  63. {
  64. assert(device_ == queue.get_device());
  65. compute::fill(this->begin(), this->end(), value, queue);
  66. queue.finish();
  67. }
  68. /** Copies a matrix to a device
  69. * \param m is a matrix that is not on the device _device and it is copied to it
  70. * \param queue is the command queue that will execute the operation
  71. */
  72. template<class A>
  73. void from_host(ublas::matrix<T, L, A> const &m, compute::command_queue &queue)
  74. {
  75. assert(device_ == queue.get_device());
  76. compute::copy(m.data().begin(),
  77. m.data().end(),
  78. this->begin(),
  79. queue);
  80. queue.finish();
  81. }
  82. /** Copies a matrix from a device
  83. * \param m is a matrix that will be reized to (size1_,size2) and the values of (*this) will be copied in it
  84. * \param queue is the command queue that will execute the operation
  85. */
  86. template<class A>
  87. void to_host(ublas::matrix<T, L, A> &m, compute::command_queue &queue) const
  88. {
  89. assert(device_ == queue.get_device());
  90. compute::copy(this->begin(),
  91. this->end(),
  92. m.data().begin(),
  93. queue);
  94. queue.finish();
  95. }
  96. private:
  97. size_type size1_;
  98. size_type size2_;
  99. compute::buffer data_;
  100. compute::device device_;
  101. };
  102. }}}
  103. #endif