Automatic Differentiation
 
Loading...
Searching...
No Matches
pinned_matrix.hpp
Go to the documentation of this file.
1#ifndef STAN_MATH_OPENCL_PINNED_MATRIX_HPP
2#define STAN_MATH_OPENCL_PINNED_MATRIX_HPP
3#ifdef STAN_OPENCL
4
7#include <CL/opencl.hpp>
8
9namespace stan {
10namespace math {
11
23template <typename MatrixType>
24class pinned_matrix : public Eigen::Map<MatrixType> {
25 public:
27 using Base = Eigen::Map<MatrixType>;
28 using PlainObject = std::decay_t<MatrixType>;
29 static constexpr int RowsAtCompileTime = MatrixType::RowsAtCompileTime;
30 static constexpr int ColsAtCompileTime = MatrixType::ColsAtCompileTime;
31
32 protected:
33 cl::Buffer buffer_;
34
35 pinned_matrix(cl::Buffer&& b, Eigen::Index rows, Eigen::Index cols) try : Base
36 ::Map(b() != NULL ? map_memory(b, rows* cols) : nullptr, rows, cols),
37 buffer_(std::move(b)) {}
38 catch (const cl::Error& e) {
39 check_opencl_error("pinned_matrix(buffer, rows, cols)", e);
40 }
41
42 pinned_matrix(cl::Buffer&& b, Eigen::Index size) try : Base
43 ::Map(b() != NULL ? map_memory(b, size) : nullptr, size),
44 buffer_(std::move(b)) {}
45 catch (const cl::Error& e) {
46 check_opencl_error("pinned_matrix(buffer, size)", e);
47 }
48
49 Scalar* map_memory(cl::Buffer& b, Eigen::Index size) {
50 return static_cast<Scalar*>(opencl_context.queue().enqueueMapBuffer(
51 b, true, CL_MAP_WRITE_INVALIDATE_REGION, 0, sizeof(Scalar) * size));
52 }
53
54 void unmap_memory(const char* function) {
55 if (this->data() != nullptr) {
56 try {
57 opencl_context.queue().enqueueUnmapMemObject(buffer_, this->data());
58 } catch (const cl::Error& e) {
59 check_opencl_error(function, e);
60 }
61 }
62 }
63
64 public:
69 : Base::Map(nullptr,
71 ColsAtCompileTime == Eigen::Dynamic ? 0 : ColsAtCompileTime) {
72 }
73
79 pinned_matrix(Eigen::Index rows, Eigen::Index cols) try
80 : pinned_matrix(rows* cols != 0 ? cl::Buffer(opencl_context.context(),
81 CL_MEM_ALLOC_HOST_PTR,
82 sizeof(Scalar) * rows * cols)
83 : cl::Buffer(),
84 rows, cols) {
85 } catch (const cl::Error& e) {
86 check_opencl_error("pinned_matrix(rows, cols)", e);
87 }
88
94 explicit pinned_matrix(Eigen::Index size) try
95 : pinned_matrix(size != 0 ? cl::Buffer(opencl_context.context(),
96 CL_MEM_ALLOC_HOST_PTR,
97 sizeof(Scalar) * size)
98 : cl::Buffer(),
99 size) {
100 } catch (const cl::Error& e) {
101 check_opencl_error("pinned_matrix(size)", e);
102 }
103
108 template <typename T, require_eigen_t<T>* = nullptr>
109 pinned_matrix(const T& other) // NOLINT
110 : pinned_matrix(other.rows(), other.cols()) {
111 Base::operator=(other);
112 }
113
119 : pinned_matrix(other.rows(), other.cols()) {
120 Base::operator=(other);
121 }
122
128 : Base::Map(other.data(), other.rows(), other.cols()),
129 buffer_(std::move(other.buffer_)) {
130 new (&other) pinned_matrix();
131 }
132
136 ~pinned_matrix() { unmap_memory("~pinned_matrix()"); }
137
138 // without this using, compiler prefers combination of implicit construction
139 // and copy assignment to the inherited operator when assigned an expression
140 using Base::operator=;
141
148 if (this->rows() != other.rows() || this->cols() != other.cols()) {
149 unmap_memory("pinned_matrix::operator=(const&)");
150 if (other.size() == 0) {
151 new (this) Base(nullptr, other.rows(), other.cols());
152 } else {
153 buffer_ = cl::Buffer(opencl_context.context(), CL_MEM_ALLOC_HOST_PTR,
154 sizeof(Scalar) * other.size());
155 // placement new changes what data map points to - only allocation
156 // happens when creating new Buffer
157 new (this)
158 Base(static_cast<Scalar*>(opencl_context.queue().enqueueMapBuffer(
159 buffer_, true, CL_MAP_WRITE_INVALIDATE_REGION, 0,
160 sizeof(Scalar) * other.size())),
161 other.rows(), other.cols());
162 }
163 }
164 Base::operator=(other);
165 return *this;
166 }
167
174 unmap_memory("pinned_matrix::operator=(&&)");
175 // placement new changes what data map points to - there is no allocation
176 new (this)
177 Base(const_cast<Scalar*>(other.data()), other.rows(), other.cols());
178 buffer_ = std::move(other.buffer_);
179 new (&other) pinned_matrix();
180 return *this;
181 }
182
188 template <typename T>
189 pinned_matrix& operator=(const T& other) {
190 if (this->rows() != other.rows() || this->cols() != other.cols()) {
191 unmap_memory("pinned_matrix::operator=(T)");
192 buffer_ = cl::Buffer(opencl_context.context(), CL_MEM_ALLOC_HOST_PTR,
193 sizeof(Scalar) * other.size());
194 // placement new changes what data map points to - only allocation happens
195 // when creating new Buffer
196 new (this)
197 Base(static_cast<Scalar*>(opencl_context.queue().enqueueMapBuffer(
198 buffer_, true, CL_MAP_WRITE_INVALIDATE_REGION, 0,
199 sizeof(Scalar) * other.size())),
200 other.rows(), other.cols());
201 }
202 Base::operator=(other);
203 return *this;
204 }
205};
206
207} // namespace math
208} // namespace stan
209
210namespace Eigen {
211namespace internal {
212
213template <typename T>
214struct traits<stan::math::pinned_matrix<T>> {
215 using base = traits<Eigen::Map<T>>;
216 using XprKind = typename base::XprKind;
217 enum {
218 PlainObjectTypeInnerSize = base::PlainObjectTypeInnerSize,
219 InnerStrideAtCompileTime = base::InnerStrideAtCompileTime,
220 OuterStrideAtCompileTime = base::OuterStrideAtCompileTime,
221 Alignment = base::Alignment,
222 Flags = base::Flags
223 };
224};
225
226} // namespace internal
227} // namespace Eigen
228
229#endif
230#endif
The API to access the methods and values in opencl_context_base.
pinned_matrix(Eigen::Index rows, Eigen::Index cols)
Constructs pinned_matrix with given number of rows and columns.
pinned_matrix(cl::Buffer &&b, Eigen::Index size)
std::decay_t< MatrixType > PlainObject
pinned_matrix(cl::Buffer &&b, Eigen::Index rows, Eigen::Index cols)
Eigen::Map< MatrixType > Base
pinned_matrix & operator=(const T &other)
Assignment operator for assigning an expression.
pinned_matrix(Eigen::Index size)
Constructs pinned_matrix with given size.
pinned_matrix & operator=(const pinned_matrix< MatrixType > &other)
Copy assignment operator.
pinned_matrix & operator=(pinned_matrix< MatrixType > &&other)
Move assignment operator.
static constexpr int ColsAtCompileTime
pinned_matrix()
Default constructor.
value_type_t< MatrixType > Scalar
pinned_matrix(const pinned_matrix< MatrixType > &other)
Copy constructor.
Scalar * map_memory(cl::Buffer &b, Eigen::Index size)
static constexpr int RowsAtCompileTime
void unmap_memory(const char *function)
pinned_matrix(pinned_matrix< MatrixType > &&other)
Move constructor.
~pinned_matrix()
Destructor unmaps the memory.
pinned_matrix(const T &other)
Constructs pinned_matrix from an expression.
Equivalent to Eigen::Matrix, except that the data is stored in (hopefully pinned) memory,...
void check_opencl_error(const char *function, const cl::Error &e)
Throws the domain error with specifying the OpenCL error that occurred.
cl::Context & context() noexcept
Returns the reference to the OpenCL context.
cl::CommandQueue & queue() noexcept
Returns the reference to the active OpenCL command queue for the device.
int64_t cols(const T_x &x)
Returns the number of columns in the specified kernel generator expression.
Definition cols.hpp:21
int64_t rows(const T_x &x)
Returns the number of rows in the specified kernel generator expression.
Definition rows.hpp:22
typename value_type< T >::type value_type_t
Helper function for accessing underlying type.
int64_t size(const T &m)
Returns the size (number of the elements) of a matrix_cl or var_value<matrix_cl<T>>.
Definition size.hpp:19
(Expert) Numerical traits for algorithmic differentiation variables.
static constexpr double e()
Return the base of the natural logarithm.
Definition constants.hpp:20
The lgamma implementation in stan-math is based on either the reentrant safe lgamma_r implementation ...
STL namespace.