Stan Math Library  2.20.0
reverse mode automatic differentiation
copy.hpp
Go to the documentation of this file.
1 #ifndef STAN_MATH_OPENCL_COPY_HPP
2 #define STAN_MATH_OPENCL_COPY_HPP
3 #ifdef STAN_OPENCL
4 
16 
17 #include <CL/cl.hpp>
18 #include <iostream>
19 #include <vector>
20 #include <algorithm>
21 #include <type_traits>
22 
23 namespace stan {
24 namespace math {
25 
36 template <int R, int C>
37 inline matrix_cl to_matrix_cl(const Eigen::Matrix<double, R, C>& src) {
38  matrix_cl dst(src.rows(), src.cols());
39  if (src.size() == 0) {
40  return dst;
41  }
42  try {
50  cl::Event copy_event;
51  const cl::CommandQueue& queue = opencl_context.queue();
52  queue.enqueueWriteBuffer(dst.buffer(), CL_FALSE, 0,
53  sizeof(double) * dst.size(), src.data(),
54  &dst.write_events(), &copy_event);
55  dst.add_write_event(copy_event);
56  } catch (const cl::Error& e) {
57  check_opencl_error("copy Eigen->(OpenCL)", e);
58  }
59  return dst;
60 }
61 
70 inline Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> from_matrix_cl(
71  const matrix_cl& src) {
72  Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> dst(src.rows(),
73  src.cols());
74  if (src.size() == 0) {
75  return dst;
76  }
77  try {
86  cl::Event copy_event;
87  const cl::CommandQueue queue = opencl_context.queue();
88  queue.enqueueReadBuffer(src.buffer(), CL_FALSE, 0,
89  sizeof(double) * dst.size(), dst.data(),
90  &src.write_events(), &copy_event);
91  copy_event.wait();
92  src.clear_write_events();
93  } catch (const cl::Error& e) {
94  check_opencl_error("copy (OpenCL)->Eigen", e);
95  }
96  return dst;
97 }
98 
107 template <TriangularViewCL triangular_view>
108 inline std::vector<double> packed_copy(const matrix_cl& src) {
109  const int packed_size = src.rows() * (src.rows() + 1) / 2;
110  std::vector<double> dst(packed_size);
111  if (dst.size() == 0) {
112  return dst;
113  }
114  try {
115  const cl::CommandQueue queue = opencl_context.queue();
116  matrix_cl packed(packed_size, 1);
117  stan::math::opencl_kernels::pack(cl::NDRange(src.rows(), src.rows()),
118  packed, src, src.rows(), src.rows(),
119  triangular_view);
120  const std::vector<cl::Event> mat_events
121  = vec_concat(packed.read_write_events(), src.write_events());
122  cl::Event copy_event;
123  queue.enqueueReadBuffer(packed.buffer(), CL_FALSE, 0,
124  sizeof(double) * packed_size, dst.data(),
125  &mat_events, &copy_event);
126  copy_event.wait();
127  src.clear_write_events();
128  } catch (const cl::Error& e) {
129  check_opencl_error("packed_copy (OpenCL->std::vector)", e);
130  }
131  return dst;
132 }
133 
147 template <TriangularViewCL triangular_view>
148 inline matrix_cl packed_copy(const std::vector<double>& src, int rows) {
149  const int packed_size = rows * (rows + 1) / 2;
150  check_size_match("copy (packed std::vector -> OpenCL)", "src.size()",
151  src.size(), "rows * (rows + 1) / 2", packed_size);
152  matrix_cl dst(rows, rows);
153  if (dst.size() == 0) {
154  return dst;
155  }
156  try {
157  matrix_cl packed(packed_size, 1);
158  cl::Event packed_event;
159  const cl::CommandQueue queue = opencl_context.queue();
160  queue.enqueueWriteBuffer(packed.buffer(), CL_FALSE, 0,
161  sizeof(double) * packed_size, src.data(), NULL,
162  &packed_event);
163  packed.add_write_event(packed_event);
164  stan::math::opencl_kernels::unpack(cl::NDRange(dst.rows(), dst.rows()), dst,
165  packed, dst.rows(), dst.rows(),
166  triangular_view);
167  } catch (const cl::Error& e) {
168  check_opencl_error("packed_copy (std::vector->OpenCL)", e);
169  }
170  return dst;
171 }
172 
183 inline matrix_cl copy_cl(const matrix_cl& src) {
184  matrix_cl dst(src.rows(), src.cols());
185  if (src.size() == 0) {
186  return dst;
187  }
188  try {
194  cl::CommandQueue queue = opencl_context.queue();
195  const std::vector<cl::Event> mat_events
196  = vec_concat(dst.read_write_events(), src.write_events());
197  cl::Event copy_event;
198  queue.enqueueCopyBuffer(src.buffer(), dst.buffer(), 0, 0,
199  sizeof(double) * src.size(), &mat_events,
200  &copy_event);
201  dst.add_write_event(copy_event);
202  src.add_read_event(copy_event);
203  } catch (const cl::Error& e) {
204  check_opencl_error("copy (OpenCL)->(OpenCL)", e);
205  }
206  return dst;
207 }
208 
215 template <typename T, std::enable_if_t<std::is_arithmetic<T>::value, int> = 0>
216 inline T from_matrix_cl(const matrix_cl& src) {
217  T dst;
218  check_size_match("copy ((OpenCL) -> (OpenCL))", "src.rows()", src.rows(),
219  "dst.rows()", 1);
220  check_size_match("copy ((OpenCL) -> (OpenCL))", "src.cols()", src.cols(),
221  "dst.cols()", 1);
222  try {
223  cl::Event copy_event;
224  const cl::CommandQueue queue = opencl_context.queue();
225  queue.enqueueReadBuffer(src.buffer(), CL_FALSE, 0, sizeof(T), &dst,
226  &src.write_events(), &copy_event);
227  copy_event.wait();
228  src.clear_write_events();
229  } catch (const cl::Error& e) {
230  check_opencl_error("copy (OpenCL)->(OpenCL)", e);
231  }
232  return dst;
233 }
234 
241 template <typename T, std::enable_if_t<std::is_arithmetic<T>::value, int> = 0>
242 inline matrix_cl to_matrix_cl(const T& src) {
243  matrix_cl dst(1, 1);
244  check_size_match("copy ((OpenCL) -> (OpenCL))", "src.rows()", dst.rows(),
245  "dst.rows()", 1);
246  check_size_match("copy ((OpenCL) -> (OpenCL))", "src.cols()", dst.cols(),
247  "dst.cols()", 1);
248  try {
249  cl::Event copy_event;
250  const cl::CommandQueue queue = opencl_context.queue();
251  queue.enqueueWriteBuffer(dst.buffer(), CL_FALSE, 0, sizeof(T), &src,
252  &dst.write_events(), &copy_event);
253  dst.add_write_event(copy_event);
254  } catch (const cl::Error& e) {
255  check_opencl_error("copy (OpenCL)->(OpenCL)", e);
256  }
257  return dst;
258 }
259 
260 } // namespace math
261 } // namespace stan
262 #endif
263 #endif
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > from_matrix_cl(const matrix_cl &src)
Copies the source matrix that is stored on the OpenCL device to the destination Eigen matrix...
Definition: copy.hpp:70
int rows(const Eigen::Matrix< T, R, C > &m)
Return the number of rows in the specified matrix, vector, or row vector.
Definition: rows.hpp:20
const std::vector< T > & vec_concat(const std::vector< T > &v1)
Ends the recursion to extract the event stack.
Definition: vec_concat.hpp:17
const kernel_cl< out_buffer, in_buffer, int, int, TriangularViewCL > unpack("unpack", {indexing_helpers, unpack_kernel_code})
See the docs for unpack() .
const kernel_cl< out_buffer, in_buffer, int, int, TriangularViewCL > pack("pack", {indexing_helpers, pack_kernel_code})
See the docs for pack() .
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
matrix_cl copy_cl(const matrix_cl &src)
Copies the source matrix to the destination matrix.
Definition: copy.hpp:183
The API to access the methods and values in opencl_context_base.
The matrix_cl class - allocates memory space on the OpenCL device, functions for transfering matrices...
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 add_read_event(cl::Event new_event) const
Add an event to the read event stack.
Definition: matrix_cl.hpp:110
Represents a matrix on the OpenCL device.
Definition: matrix_cl.hpp:29
checking OpenCL error numbers
Initialization for OpenCL:
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
matrix_cl to_matrix_cl(const Eigen::Matrix< double, R, C > &src)
Copies the source Eigen matrix to the destination matrix that is stored on the OpenCL device...
Definition: copy.hpp:37
std::vector< double > packed_copy(const matrix_cl &src)
Packs the flat triagnular matrix on the OpenCL device and copies it to the std::vector.
Definition: copy.hpp:108
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.

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