Automatic Differentiation
 
Loading...
Searching...
No Matches
copy.hpp
Go to the documentation of this file.
1#ifndef STAN_MATH_OPENCL_REV_COPY_HPP
2#define STAN_MATH_OPENCL_REV_COPY_HPP
3#ifdef STAN_OPENCL
4
14
15#include <CL/opencl.hpp>
16#include <iostream>
17#include <vector>
18#include <algorithm>
19#include <type_traits>
20
21namespace stan {
22namespace math {
23
32template <typename T>
34 const var_value<T>& a) {
35 return make_callback_var(to_matrix_cl(a.val()), [a](auto& res_vari) mutable {
36 a.adj() += from_matrix_cl<plain_type_t<T>>(res_vari.adj());
37 });
38}
39
48template <typename T, require_stan_scalar_t<T>* = nullptr>
50 const std::vector<var_value<T>>& a) {
51 return to_matrix_cl(
52 Eigen::Map<const Eigen::Matrix<var_value<T>, Eigen::Dynamic, 1>>(
53 a.data(), a.size()));
54}
55
66template <typename T, require_eigen_vt<is_var, T>* = nullptr>
68 const T& src) {
69 arena_t<T> src_stacked = src;
70
71 return make_callback_var(
72 to_matrix_cl(src_stacked.val()), [src_stacked](auto& res_vari) mutable {
73 src_stacked.adj() += from_matrix_cl<
74 Eigen::Matrix<double, T::RowsAtCompileTime, T::ColsAtCompileTime>>(
75 res_vari.adj());
76 });
77}
78
88template <typename T, require_eigen_vt<is_var, T>* = nullptr>
90 const std::vector<T>& src) {
91 auto src_stacked = to_arena(src);
92
93 return make_callback_var(
94 to_matrix_cl(value_of(src_stacked)),
95 [src_stacked](auto& res_vari) mutable {
96 Eigen::MatrixXd adj = from_matrix_cl(res_vari.adj());
97 for (int i = 0; i < src_stacked.size(); i++) {
98 src_stacked[i].adj()
99 += Eigen::Map<plain_type_t<decltype(src_stacked[i].adj())>>(
100 adj.data() + adj.rows() * i, src_stacked[i].rows(),
101 src_stacked[i].cols());
102 }
103 });
104}
105
115template <typename T_dst, typename T,
118inline T_dst from_matrix_cl(const var_value<T>& a) {
119 return make_callback_var(
120 from_matrix_cl<Eigen::Matrix<double, T_dst::RowsAtCompileTime,
121 T_dst::ColsAtCompileTime>>(a.val()),
122 [a](auto& res_vari) mutable { a.adj() += to_matrix_cl(res_vari.adj()); });
123}
124
134template <typename T_dst, typename T,
137inline T_dst from_matrix_cl(const var_value<T>& a) {
139 = from_matrix_cl<Eigen::Matrix<double, T_dst::RowsAtCompileTime,
140 T_dst::ColsAtCompileTime>>(a.val());
142 [a, res]() mutable { a.adj() += to_matrix_cl(res.adj()); });
143 return res;
144}
145
155template <typename T_dst, typename T,
156 require_std_vector_vt<is_var, T_dst>* = nullptr,
157 require_all_stan_scalar_t<value_type_t<T_dst>>* = nullptr,
158 require_all_kernel_expressions_t<T>* = nullptr>
159inline T_dst from_matrix_cl(const var_value<T>& a) {
160 check_size_match("from_matrix_cl<std::vector<var>>", "src.cols()", a.cols(),
161 "dst.cols()", 1);
162 std::vector<double> val = from_matrix_cl<std::vector<double>>(a.val());
163 arena_t<T_dst> res(val.begin(), val.end());
164 reverse_pass_callback([a, res]() mutable {
165 a.adj() += to_matrix_cl(as_column_vector_or_scalar(res).adj());
166 });
167 return {res.begin(), res.end()};
168}
169
180template <typename T_dst, typename T, require_std_vector_t<T_dst>* = nullptr,
181 require_rev_vector_t<value_type_t<T_dst>>* = nullptr,
182 require_all_kernel_expressions_t<T>* = nullptr>
183inline T_dst from_matrix_cl(const var_value<T>& a) {
184 Eigen::MatrixXd val = from_matrix_cl(a.val());
185 arena_t<T_dst> res;
186 res.reserve(a.cols());
187 for (int i = 0; i < a.cols(); i++) {
188 res.emplace_back(val.col(i));
189 }
190 reverse_pass_callback([a, res]() mutable {
191 Eigen::MatrixXd adj(a.rows(), a.cols());
192 for (int i = 0; i < a.cols(); i++) {
193 adj.col(i) = res[i].adj();
194 }
195 a.adj() += to_matrix_cl(adj);
196 });
197 return {res.begin(), res.end()};
198}
199
208template <typename T, require_all_kernel_expressions_t<T>* = nullptr>
209auto from_matrix_cl(const var_value<T>& src) {
210 return from_matrix_cl<var_value<Eigen::MatrixXd>>(src);
211}
212
213} // namespace math
214} // namespace stan
215#endif
216#endif
require_t< container_type_check_base< is_eigen, value_type_t, TypeCheck, Check... > > require_eigen_vt
Require type satisfies is_eigen.
Definition is_eigen.hpp:97
auto as_column_vector_or_scalar(T &&a)
as_column_vector_or_scalar of a kernel generator expression.
require_all_t< is_kernel_expression< Types >... > require_all_kernel_expressions_t
Enables a template if all given types are are a valid kernel generator expressions.
matrix_cl< scalar_type_t< T > > to_matrix_cl(T &&src)
Copies the source Eigen matrix, std::vector or scalar to the destination matrix that is stored on the...
Definition copy.hpp:45
auto from_matrix_cl(const T &src)
Copies the source matrix that is stored on the OpenCL device to the destination Eigen matrix.
Definition copy.hpp:61
require_t< container_type_check_base< is_var, value_type_t, TypeCheck, Check... > > require_var_vt
Require type satisfies is_var.
Definition is_var.hpp:64
var_value< plain_type_t< T > > make_callback_var(T &&value, F &&functor)
Creates a new var initialized with a callback_vari with a given value and reverse-pass callback funct...
void reverse_pass_callback(F &&functor)
Puts a callback on the autodiff stack to be called in reverse pass.
T value_of(const fvar< T > &v)
Return the value of the specified variable.
Definition value_of.hpp:18
arena_t< T > to_arena(const T &a)
Converts given argument into a type that either has any dynamic allocation on AD stack or schedules i...
Definition to_arena.hpp:25
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.
typename plain_type< T >::type plain_type_t
typename internal::arena_type_impl< std::decay_t< T > >::type arena_t
Determines a type that can be used in place of T that does any dynamic allocations on the AD stack.
The lgamma implementation in stan-math is based on either the reentrant safe lgamma_r implementation ...