Automatic Differentiation
 
Loading...
Searching...
No Matches
load.hpp
Go to the documentation of this file.
1#ifndef STAN_MATH_OPENCL_KERNEL_GENERATOR_LOAD_HPP
2#define STAN_MATH_OPENCL_KERNEL_GENERATOR_LOAD_HPP
3#ifdef STAN_OPENCL
4
8
13#include <type_traits>
14#include <string>
15#include <utility>
16#include <map>
17#include <vector>
18
19namespace stan {
20namespace math {
21
31template <typename T, assign_op_cl AssignOp = assign_op_cl::equals>
32class load_
33 : public operation_cl_lhs<load_<T, AssignOp>,
34 typename std::remove_reference_t<T>::type> {
35 protected:
36 T a_;
37
38 public:
39 static constexpr assign_op_cl assignment_op = AssignOp;
40 using Scalar = typename std::remove_reference_t<T>::type;
42 using base::var_name_;
44 "load_: argument a must be a matrix_cl<T>!");
45 static_assert(
46 std::is_arithmetic<Scalar>::value,
47 "load_: T in \"matrix_cl<T> a\" argument must be an arithmetic type!");
48
53 explicit load_(T&& a) : a_(std::forward<T>(a)) {}
54
62 }
64 return load_<T, AssignOp>(std::forward<T>(a_));
65 }
66
80 std::unordered_map<const void*, const char*>& generated,
81 std::unordered_map<const void*, const char*>& generated_all,
82 name_generator& name_gen, const std::string& row_index_name,
83 const std::string& col_index_name, bool view_handled) const {
84 kernel_parts res{};
85 if (generated.count(&a_) == 0) {
86 if (generated_all.count(&a_) == 0) {
87 this->var_name_ = name_gen.generate();
88 generated_all[&a_] = generated[&a_] = this->var_name_.c_str();
89 res.body = generate_body(row_index_name, col_index_name, view_handled,
90 this->var_name_.c_str());
91 res.args = "__global " + type_str<Scalar>() + "* " + var_name_
92 + "_global, int " + var_name_ + "_rows, int " + var_name_
93 + "_view, ";
94 } else {
95 const char* arg_var_name = generated_all[&a_];
96 this->var_name_ = name_gen.generate();
97 generated[&a_] = this->var_name_.c_str();
98 res.body = generate_body(row_index_name, col_index_name, view_handled,
99 arg_var_name);
100 }
101 } else {
102 this->var_name_ = generated[&a_];
103 }
104 return res;
105 }
106
115 inline std::string generate_body(const std::string& row_index_name,
116 const std::string& col_index_name,
117 const bool view_handled,
118 const char* arg_var_name) const {
119 std::string type = type_str<Scalar>();
120 if (view_handled) {
121 return type + " " + var_name_ + " = " + arg_var_name + "_global["
122 + row_index_name + " + " + arg_var_name + "_rows * "
123 + col_index_name + "];\n";
124 } else {
125 return type + " " + var_name_ + " = 0;"
126 " if (!((!contains_nonzero(" + arg_var_name
127 + "_view, LOWER) && " + col_index_name + " < " + row_index_name
128 + ") || (!contains_nonzero(" + arg_var_name
129 + "_view, UPPER) && " + col_index_name + " > " + row_index_name
130 + "))) {" + var_name_ + " = " + arg_var_name + "_global["
131 + row_index_name + " + " + arg_var_name + "_rows * "
132 + col_index_name + "];}\n";
133 }
134 }
135
149 std::unordered_map<const void*, const char*>& generated,
150 std::unordered_map<const void*, const char*>& generated_all,
151 name_generator& name_gen, const std::string& row_index_name,
152 const std::string& col_index_name) const {
153 if (generated_all.count(&a_) == 0) {
154 this->var_name_ = name_gen.generate();
155 } else {
156 this->var_name_ = generated_all[&a_];
157 }
158 kernel_parts res = generate_lhs(row_index_name, col_index_name);
159
160 if (generated_all.count(&a_) == 0) {
161 generated_all[&a_] = this->var_name_.c_str();
162 } else {
163 res.args = "";
164 }
165 return res;
166 }
167
175 inline kernel_parts generate_lhs(const std::string& row_index_name,
176 const std::string& col_index_name) const {
177 kernel_parts res;
178 std::string type = type_str<Scalar>();
179 res.args = "__global " + type + "* " + var_name_ + "_global, int "
180 + var_name_ + "_rows, int " + var_name_ + "_view, ";
181 res.body = var_name_ + "_global[" + row_index_name + " + " + var_name_
182 + "_rows * " + col_index_name + "]";
183 return res;
184 }
185
196 inline void set_args(
197 std::unordered_map<const void*, const char*>& generated,
198 std::unordered_map<const void*, const char*>& generated_all,
199 cl::Kernel& kernel, int& arg_num) const {
200 if (generated_all.count(&a_) == 0) {
201 generated_all[&a_] = "";
202 kernel.setArg(arg_num++, a_.buffer());
203 kernel.setArg(arg_num++, a_.rows());
204 kernel.setArg(arg_num++, a_.view());
205 }
206 }
207
212 inline void add_read_event(cl::Event& e) const { a_.add_read_event(e); }
213
218 inline void add_write_event(cl::Event& e) const { a_.add_write_event(e); }
219
226 std::vector<cl::Event>& events) const {
227 events.insert(events.end(), a_.read_events().begin(),
228 a_.read_events().end());
229 events.insert(events.end(), a_.write_events().begin(),
230 a_.write_events().end());
231 a_.clear_read_write_events();
232 }
233
238 inline void get_write_events(std::vector<cl::Event>& events) const {
239 events.insert(events.end(), a_.write_events().begin(),
240 a_.write_events().end());
241 }
242
248 inline int rows() const { return a_.rows(); }
249
255 inline int cols() const { return a_.cols(); }
256
261 inline matrix_cl_view view() const { return a_.view(); }
262
276 inline void set_view(int bottom_diagonal, int top_diagonal,
277 int bottom_zero_diagonal, int top_zero_diagonal) const {
278 if (bottom_zero_diagonal <= top_diagonal && bottom_diagonal < 0) {
279 a_.view(either(a_.view(), matrix_cl_view::Lower));
280 } else if (bottom_zero_diagonal <= 1 - a_.rows()) {
281 a_.view(both(a_.view(), matrix_cl_view::Upper));
282 }
283 if (top_zero_diagonal >= bottom_diagonal && top_diagonal > 0) {
284 a_.view(either(a_.view(), matrix_cl_view::Upper));
285 } else if (top_zero_diagonal >= a_.cols() - 1) {
286 a_.view(both(a_.view(), matrix_cl_view::Lower));
287 }
288 }
289
294 inline std::pair<int, int> extreme_diagonals() const {
295 int bottom = contains_nonzero(a_.view(), matrix_cl_view::Lower)
296 ? -a_.rows() + 1
297 : 0;
298 int top = contains_nonzero(a_.view(), matrix_cl_view::Upper) ? a_.cols() - 1
299 : 0;
300 return {bottom, top};
301 }
302
308 const T& eval() const { return a_; }
309
315 inline void check_assign_dimensions(int rows, int cols) const {
316 if (a_.rows() != rows || a_.cols() != cols) {
318 }
319 }
320
329 std::vector<int>& uids, std::unordered_map<const void*, int>& id_map,
330 int& next_id) const {
331 if (id_map.count(&a_) == 0) {
332 id_map[&a_] = next_id;
333 uids.push_back(next_id);
334 next_id++;
335 } else {
336 uids.push_back(id_map[&a_]);
337 }
338 }
339};
340
342} // namespace math
343} // namespace stan
344
345#endif
346#endif
std::string generate_body(const std::string &row_index_name, const std::string &col_index_name, const bool view_handled, const char *arg_var_name) const
Generates kernel code for main body of this expression.
Definition load.hpp:115
void get_clear_read_write_events(std::vector< cl::Event > &events) const
Adds all read and write events on the matrix used by this expression to a list and clears them from t...
Definition load.hpp:225
int cols() const
Number of columns of a matrix that would be the result of evaluating this expression.
Definition load.hpp:255
void set_args(std::unordered_map< const void *, const char * > &generated, std::unordered_map< const void *, const char * > &generated_all, cl::Kernel &kernel, int &arg_num) const
Sets kernel arguments for this expression.
Definition load.hpp:196
void get_unique_matrix_accesses(std::vector< int > &uids, std::unordered_map< const void *, int > &id_map, int &next_id) const
Collects data that is needed beside types to uniqly identify a kernel generator expression.
Definition load.hpp:328
kernel_parts get_kernel_parts_lhs(std::unordered_map< const void *, const char * > &generated, std::unordered_map< const void *, const char * > &generated_all, name_generator &name_gen, const std::string &row_index_name, const std::string &col_index_name) const
Generates kernel code for this expression if it appears on the left hand side of an assignment.
Definition load.hpp:148
load_(T &&a)
Constructor.
Definition load.hpp:53
const T & eval() const
Evaluates the expression.
Definition load.hpp:308
void get_write_events(std::vector< cl::Event > &events) const
Adds all write events on the matrix used by this expression to a list.
Definition load.hpp:238
void add_write_event(cl::Event &e) const
Adds write event to the matrix used in this expression.
Definition load.hpp:218
load_< const T &, AssignOp > deep_copy() const &
Definition load.hpp:60
load_< T &, AssignOp > deep_copy() &
Creates a deep copy of this expression.
Definition load.hpp:59
kernel_parts generate_lhs(const std::string &row_index_name, const std::string &col_index_name) const
Generates kernel code for this expression if it appears on the left hand side of an assignment.
Definition load.hpp:175
void check_assign_dimensions(int rows, int cols) const
If needed resizes underlying matrix to desired number of rows and cols.
Definition load.hpp:315
void add_read_event(cl::Event &e) const
Adds read event to the matrix used in this expression.
Definition load.hpp:212
std::string var_name_
std::pair< int, int > extreme_diagonals() const
Determine indices of extreme sub- and superdiagonals written.
Definition load.hpp:294
void set_view(int bottom_diagonal, int top_diagonal, int bottom_zero_diagonal, int top_zero_diagonal) const
Sets the view of the matrix depending on which of its parts are written to.
Definition load.hpp:276
matrix_cl_view view() const
View of a matrix that would be the result of evaluating this expression.
Definition load.hpp:261
static constexpr assign_op_cl assignment_op
Definition load.hpp:39
int rows() const
Number of rows of a matrix that would be the result of evaluating this expression.
Definition load.hpp:248
typename std::remove_reference_t< T >::type Scalar
Definition load.hpp:40
load_< T, AssignOp > deep_copy() &&
Definition load.hpp:63
kernel_parts get_kernel_parts(std::unordered_map< const void *, const char * > &generated, std::unordered_map< const void *, const char * > &generated_all, name_generator &name_gen, const std::string &row_index_name, const std::string &col_index_name, bool view_handled) const
Generates kernel code for this expression.
Definition load.hpp:79
Represents an access to a matrix_cl in kernel generator expressions.
Definition load.hpp:34
Represents an arithmetic matrix on the OpenCL device.
Definition matrix_cl.hpp:47
std::string generate()
Generates a unique variable name.
Unique name generator for variables used in generated kernels.
Base for all kernel generator operations that can be used on left hand side of an expression.
Base for all kernel generator operations.
const matrix_cl_view both(const matrix_cl_view left_view, const matrix_cl_view right_view)
Determines which parts are nonzero in both input views.
const matrix_cl_view either(const matrix_cl_view left_view, const matrix_cl_view right_view)
Determines which parts are nonzero in any of the input views.
bool contains_nonzero(const matrix_cl_view view, const matrix_cl_view part)
Check whether a view contains certain nonzero part.
static constexpr double e()
Return the base of the natural logarithm.
Definition constants.hpp:20
assign_op_cl
Ops that decide the type of assignment for LHS operations.
The lgamma implementation in stan-math is based on either the reentrant safe lgamma_r implementation ...
STL namespace.
Extends std::false_type when instantiated with zero or more template parameters, all of which extend ...
Parts of an OpenCL kernel, generated by an expression.