Stan Math Library  2.20.0
reverse mode automatic differentiation
matrix_cl.hpp
Go to the documentation of this file.
1 #ifndef STAN_MATH_OPENCL_MATRIX_CL_HPP
2 #define STAN_MATH_OPENCL_MATRIX_CL_HPP
3 #ifdef STAN_OPENCL
11 #include <CL/cl.hpp>
12 #include <iostream>
13 #include <string>
14 #include <vector>
15 #include <algorithm>
16 
22 namespace stan {
23 namespace math {
29 class matrix_cl {
30  private:
36  cl::Buffer oclBuffer_;
37  const int rows_;
38  const int cols_;
39  mutable std::vector<cl::Event> write_events_; // Tracks write jobs
40  mutable std::vector<cl::Event> read_events_; // Tracks reads
41 
42  public:
43  // Forward declare the methods that work in place on the matrix
44  template <TriangularViewCL triangular_view = TriangularViewCL::Entire>
45  void zeros();
46  template <TriangularMapCL triangular_map = TriangularMapCL::LowerToUpper>
47  void triangular_transpose();
48  template <TriangularViewCL triangular_view = TriangularViewCL::Entire>
49  void sub_block(const matrix_cl& A, size_t A_i, size_t A_j, size_t this_i,
50  size_t this_j, size_t nrows, size_t ncols);
51  int rows() const { return rows_; }
52 
53  int cols() const { return cols_; }
54 
55  int size() const { return rows_ * cols_; }
56 
60  inline void clear_write_events() const {
61  write_events_.clear();
62  return;
63  }
64 
68  inline void clear_read_events() const {
69  read_events_.clear();
70  return;
71  }
72 
76  inline void clear_read_write_events() const {
77  read_events_.clear();
78  write_events_.clear();
79  return;
80  }
81 
86  inline const std::vector<cl::Event>& write_events() const {
87  return write_events_;
88  }
89 
94  inline const std::vector<cl::Event>& read_events() const {
95  return read_events_;
96  }
97 
102  inline const std::vector<cl::Event> read_write_events() const {
103  return vec_concat(this->read_events(), this->write_events());
104  }
105 
110  inline void add_read_event(cl::Event new_event) const {
111  this->read_events_.push_back(new_event);
112  }
113 
118  inline void add_write_event(cl::Event new_event) const {
119  this->write_events_.push_back(new_event);
120  }
121 
126  inline void add_read_write_event(cl::Event new_event) const {
127  this->read_events_.push_back(new_event);
128  this->write_events_.push_back(new_event);
129  }
130 
134  inline void wait_for_write_events() const {
135  cl::CommandQueue queue = opencl_context.queue();
136  cl::Event copy_event;
137  queue.enqueueBarrierWithWaitList(&this->write_events(), &copy_event);
138  copy_event.wait();
139  write_events_.clear();
140  return;
141  }
142 
146  inline void wait_for_read_events() const {
147  cl::CommandQueue queue = opencl_context.queue();
148  cl::Event copy_event;
149  queue.enqueueBarrierWithWaitList(&this->read_events(), &copy_event);
150  copy_event.wait();
151  read_events_.clear();
152  return;
153  }
154 
159  inline void wait_for_read_write_events() const {
160  cl::CommandQueue queue = opencl_context.queue();
161  cl::Event copy_event;
162  const std::vector<cl::Event> mat_events = this->read_write_events();
163  queue.enqueueBarrierWithWaitList(&mat_events, &copy_event);
164  copy_event.wait();
165  read_events_.clear();
166  write_events_.clear();
167  return;
168  }
169 
170  const cl::Buffer& buffer() const { return oclBuffer_; }
171 
172  matrix_cl() : rows_(0), cols_(0) {}
173 
174  matrix_cl(const matrix_cl& A) : rows_(A.rows()), cols_(A.cols()) {
175  if (A.size() == 0)
176  return;
177  // the context is needed to create the buffer object
178  cl::Context& ctx = opencl_context.context();
179  cl::CommandQueue queue = opencl_context.queue();
180  try {
181  // creates a read&write object for "size" double values
182  // in the provided context
183  oclBuffer_ = cl::Buffer(ctx, CL_MEM_READ_WRITE, sizeof(double) * size());
184  cl::Event cstr_event;
185  queue.enqueueCopyBuffer(A.buffer(), this->buffer(), 0, 0,
186  A.size() * sizeof(double), &A.write_events(),
187  &cstr_event);
188  this->add_write_event(cstr_event);
189  } catch (const cl::Error& e) {
190  check_opencl_error("copy (OpenCL)->(OpenCL)", e);
191  }
192  }
204  matrix_cl(const int& rows, const int& cols) : rows_(rows), cols_(cols) {
205  if (size() == 0) {
206  return;
207  }
208  cl::Context& ctx = opencl_context.context();
209  try {
210  // creates the OpenCL buffer of the provided size
211  oclBuffer_
212  = cl::Buffer(ctx, CL_MEM_READ_WRITE, sizeof(double) * rows_ * cols_);
213  } catch (const cl::Error& e) {
214  check_opencl_error("matrix constructor", e);
215  }
216  }
228  template <int R, int C>
229  explicit matrix_cl(const Eigen::Matrix<double, R, C>& A)
230  : rows_(A.rows()), cols_(A.cols()) {
231  if (size() == 0) {
232  return;
233  }
234  cl::Context& ctx = opencl_context.context();
235  cl::CommandQueue& queue = opencl_context.queue();
236  try {
237  // creates the OpenCL buffer to copy the Eigen
238  // matrix to the OpenCL device
239  oclBuffer_
240  = cl::Buffer(ctx, CL_MEM_READ_WRITE, sizeof(double) * A.size());
249  cl::Event transfer_event;
250  queue.enqueueWriteBuffer(oclBuffer_, CL_FALSE, 0,
251  sizeof(double) * A.size(), A.data(), NULL,
252  &transfer_event);
253  this->add_write_event(transfer_event);
254  } catch (const cl::Error& e) {
255  check_opencl_error("matrix constructor", e);
256  }
257  }
258 
260  check_size_match("assignment of (OpenCL) matrices", "source.rows()",
261  a.rows(), "destination.rows()", rows());
262  check_size_match("assignment of (OpenCL) matrices", "source.cols()",
263  a.cols(), "destination.cols()", cols());
264  // Need to wait for all of matrices events before destroying old buffer
266  oclBuffer_ = a.buffer();
267  return *this;
268  }
269 };
270 
271 } // namespace math
272 } // namespace stan
273 
274 #endif
275 #endif
const std::vector< T > & vec_concat(const std::vector< T > &v1)
Ends the recursion to extract the event stack.
Definition: vec_concat.hpp:17
void clear_read_events() const
Clear the read events from the event stacks.
Definition: matrix_cl.hpp:68
const std::vector< cl::Event > & read_events() const
Get the events from the event stacks.
Definition: matrix_cl.hpp:94
const cl::Buffer & buffer() const
Definition: matrix_cl.hpp:170
void clear_write_events() const
Clear the write events from the event stacks.
Definition: matrix_cl.hpp:60
void wait_for_read_events() const
Waits for the read events and clears the read event stack.
Definition: matrix_cl.hpp:146
void wait_for_read_write_events() const
Waits for read and write events to finish and clears the read, write, and read/write event stacks...
Definition: matrix_cl.hpp:159
matrix_cl(const matrix_cl &A)
Definition: matrix_cl.hpp:174
The API to access the methods and values in opencl_context_base.
void add_write_event(cl::Event new_event) const
Add an event to the write event stack.
Definition: matrix_cl.hpp:118
void check_size_match(const char *function, const char *name_i, T_size1 i, const char *name_j, T_size2 j)
Check if the provided sizes match.
void triangular_transpose()
Copies a lower/upper triangular of a matrix to it&#39;s upper/lower.
void zeros()
Stores zeros in the matrix on the OpenCL device.
Definition: zeros.hpp:27
void add_read_event(cl::Event new_event) const
Add an event to the read event stack.
Definition: matrix_cl.hpp:110
void sub_block(const matrix_cl &A, size_t A_i, size_t A_j, size_t this_i, size_t this_j, size_t nrows, size_t ncols)
Write the contents of A into this starting at the top left of this
Definition: sub_block.hpp:28
void add_read_write_event(cl::Event new_event) const
Add an event to the read/write event stack.
Definition: matrix_cl.hpp:126
Represents a matrix on the OpenCL device.
Definition: matrix_cl.hpp:29
checking OpenCL error numbers
cl::Context & context()
Returns the reference to the OpenCL context.
matrix_cl(const Eigen::Matrix< double, R, C > &A)
Constructor for the matrix_cl that creates a copy of the Eigen matrix on the OpenCL device...
Definition: matrix_cl.hpp:229
Initialization for OpenCL:
void wait_for_write_events() const
Waits for the write events and clears the read event stack.
Definition: matrix_cl.hpp:134
const std::vector< cl::Event > read_write_events() const
Get the events from the event stacks.
Definition: matrix_cl.hpp:102
double e()
Return the base of the natural logarithm.
Definition: constants.hpp:87
void clear_read_write_events() const
Clear the write events from the event stacks.
Definition: matrix_cl.hpp:76
matrix_cl(const int &rows, const int &cols)
Constructor for the matrix_cl that only allocates the buffer on the OpenCL device.
Definition: matrix_cl.hpp:204
void check_opencl_error(const char *function, const cl::Error &e)
Throws the domain error with specifying the OpenCL error that occured.
const std::vector< cl::Event > & write_events() const
Get the events from the event stacks.
Definition: matrix_cl.hpp:86
cl::CommandQueue & queue()
Returns the reference to the active OpenCL command queue for the device.
matrix_cl & operator=(const matrix_cl &a)
Definition: matrix_cl.hpp:259

     [ Stan Home Page ] © 2011–2018, Stan Development Team.