1 #ifdef STAN_OPENCL
2 #include <stan/math/opencl/rev.hpp>
3 #include <test/unit/util.hpp>
4 #include <gtest/gtest.h>
5 #include <CL/cl2.hpp>
6 #include <algorithm>
7 #include <vector>
8 
TEST(VariCL,var_matrix_to_matrix_cl)9 TEST(VariCL, var_matrix_to_matrix_cl) {
10   using stan::math::var_value;
11   Eigen::MatrixXd vals(2, 3);
12   vals << 1, 2, 3, 4, 5, 6;
13   var_value<Eigen::MatrixXd> a(vals);
14   var_value<stan::math::matrix_cl<double>> a_cl = stan::math::to_matrix_cl(a);
15   EXPECT_MATRIX_EQ(from_matrix_cl(a_cl.val()), vals);
16   a_cl.adj() = stan::math::constant(1, 2, 3);
17   a_cl.vi_->chain();
18   EXPECT_MATRIX_EQ(a.adj(), Eigen::MatrixXd::Constant(2, 3, 1));
19 }
20 
TEST(MathMatrixGPU,var_std_vector_to_matrix_cl)21 TEST(MathMatrixGPU, var_std_vector_to_matrix_cl) {
22   using stan::math::var_value;
23   std::vector<stan::math::var> vals = {1, 2, 3, 4, 5, 6};
24   var_value<stan::math::matrix_cl<double>> a_cl
25       = stan::math::to_matrix_cl(vals);
26   stan::math::matrix_d a_res = from_matrix_cl(a_cl.val());
27   for (size_t i = 0; i < vals.size(); i++) {
28     EXPECT_FLOAT_EQ(a_res(i), vals[i].val());
29   }
30   a_cl.adj() = stan::math::constant(1, vals.size(), 1);
31   a_cl.vi_->chain();
32   for (size_t i = 0; i < vals.size(); i++) {
33     EXPECT_FLOAT_EQ(vals[i].adj(), 1);
34   }
35 }
36 
TEST(VariCL,matrix_var_to_matrix_cl)37 TEST(VariCL, matrix_var_to_matrix_cl) {
38   using stan::math::var_value;
39   Eigen::MatrixXd vals(2, 3);
40   vals << 1, 2, 3, 4, 5, 6;
41   stan::math::matrix_v vars = vals;
42   var_value<stan::math::matrix_cl<double>> a_cl
43       = stan::math::to_matrix_cl(vars);
44   EXPECT_MATRIX_EQ(from_matrix_cl(a_cl.val()), vals);
45   a_cl.adj() = stan::math::constant(1, 2, 3);
46   a_cl.vi_->chain();
47   EXPECT_MATRIX_EQ(vars.adj(), Eigen::MatrixXd::Constant(2, 3, 1));
48 }
49 
TEST(MathMatrixGPU,std_vector_matrix_var_to_matrix_cl)50 TEST(MathMatrixGPU, std_vector_matrix_var_to_matrix_cl) {
51   using stan::math::var_value;
52   stan::math::matrix_v a(2, 3);
53   a << 1, 2, 3, 4, 5, 6;
54   stan::math::matrix_v b(2, 3);
55   b << 7, 8, 9, 0, 1, 2;
56   stan::math::matrix_d a_adj(2, 3);
57   a_adj << 9, 8, 7, 6, 5, 4;
58   stan::math::matrix_d b_adj(2, 3);
59   b_adj << 6, 5, 4, 3, 2, 1;
60   std::vector<stan::math::matrix_v> vars = {a, b};
61   std::vector<stan::math::matrix_d> adjs = {a_adj, b_adj};
62   var_value<stan::math::matrix_cl<double>> vars_cl
63       = stan::math::to_matrix_cl(vars);
64 
65   vars_cl.adj() = stan::math::to_matrix_cl(adjs);
66   vars_cl.vi_->chain();
67   EXPECT_MATRIX_EQ(vars[0].adj(), a_adj);
68   EXPECT_MATRIX_EQ(vars[1].adj(), b_adj);
69 
70   stan::math::matrix_d vars_res = stan::math::from_matrix_cl(vars_cl.val());
71   for (size_t i = 0; i < a.size(); i++) {
72     EXPECT_FLOAT_EQ(vars_res(i), a(i).val());
73     EXPECT_FLOAT_EQ(vars_res(i + a.size()), b(i).val());
74   }
75 }
76 
TEST(VariCL,var_matrix_from_matrix_cl)77 TEST(VariCL, var_matrix_from_matrix_cl) {
78   using stan::math::var_value;
79   Eigen::MatrixXd vals(2, 3);
80   vals << 1, 2, 3, 4, 5, 6;
81   stan::math::matrix_cl<double> vals_cl(vals);
82   var_value<stan::math::matrix_cl<double>> a_cl(vals_cl);
83   var_value<Eigen::MatrixXd> a = stan::math::from_matrix_cl(a_cl);
84   EXPECT_MATRIX_EQ(a.val(), vals);
85   a.adj() = Eigen::MatrixXd::Constant(2, 3, 1);
86   a.vi_->chain();
87   EXPECT_MATRIX_EQ(from_matrix_cl(a_cl.adj()),
88                    Eigen::MatrixXd::Constant(2, 3, 1));
89 }
90 
TEST(VariCL,eigen_var_from_matrix_cl)91 TEST(VariCL, eigen_var_from_matrix_cl) {
92   using stan::math::var_value;
93   Eigen::MatrixXd vals(2, 3);
94   vals << 1, 2, 3, 4, 5, 6;
95   stan::math::matrix_cl<double> vals_cl(vals);
96   var_value<stan::math::matrix_cl<double>> a_cl(vals_cl);
97   stan::math::matrix_v a
98       = stan::math::from_matrix_cl<stan::math::matrix_v>(a_cl);
99   EXPECT_MATRIX_EQ(a.val(), vals);
100   a.adj() = Eigen::MatrixXd::Constant(2, 3, 1);
101   stan::math::grad();
102   EXPECT_MATRIX_EQ(from_matrix_cl(a_cl.adj()),
103                    Eigen::MatrixXd::Constant(2, 3, 1));
104 }
105 
TEST(VariCL,std_vector_var_from_matrix_cl)106 TEST(VariCL, std_vector_var_from_matrix_cl) {
107   using stan::math::var;
108   using stan::math::var_value;
109   std::vector<double> vals{1, 2, 3, 4, 5, 6};
110   stan::math::matrix_cl<double> vals_cl(vals);
111   var_value<stan::math::matrix_cl<double>> a_cl(vals_cl);
112   std::vector<var> a = stan::math::from_matrix_cl<std::vector<var>>(a_cl);
113   EXPECT_STD_VECTOR_EQ(stan::math::value_of(a), vals);
114   stan::math::as_column_vector_or_scalar(a).adj()
115       = Eigen::VectorXd::Constant(6, 1.0);
116   stan::math::grad();
117   EXPECT_MATRIX_EQ(from_matrix_cl(a_cl.adj()),
118                    Eigen::VectorXd::Constant(6, 1.0));
119 }
120 
TEST(VariCL,std_vector_var_eigen_from_matrix_cl)121 TEST(VariCL, std_vector_var_eigen_from_matrix_cl) {
122   using stan::math::var;
123   using stan::math::var_value;
124   using stan::math::vector_v;
125 
126   Eigen::MatrixXd vals(2, 3);
127   vals << 1, 2, 3, 4, 5, 6;
128 
129   stan::math::matrix_cl<double> vals_cl(vals);
130   var_value<stan::math::matrix_cl<double>> a_cl(vals_cl);
131   std::vector<var_value<Eigen::VectorXd>> a
132       = stan::math::from_matrix_cl<std::vector<var_value<Eigen::VectorXd>>>(
133           a_cl);
134   EXPECT_MATRIX_EQ(stan::math::value_of(a[0]), vals.col(0));
135   EXPECT_MATRIX_EQ(stan::math::value_of(a[1]), vals.col(1));
136   EXPECT_MATRIX_EQ(stan::math::value_of(a[2]), vals.col(2));
137   a[0].adj() = Eigen::VectorXd::Constant(2, 2.0);
138   a[1].adj() = Eigen::VectorXd::Constant(2, 2.0);
139   a[2].adj() = Eigen::VectorXd::Constant(2, 2.0);
140   stan::math::grad();
141   EXPECT_MATRIX_EQ(from_matrix_cl(a_cl.adj()),
142                    Eigen::MatrixXd::Constant(2, 3, 2.0));
143 }
144 
TEST(VariCL,std_vector_eigen_var_from_matrix_cl)145 TEST(VariCL, std_vector_eigen_var_from_matrix_cl) {
146   using stan::math::var;
147   using stan::math::var_value;
148   using stan::math::vector_v;
149 
150   Eigen::MatrixXd vals(2, 3);
151   vals << 1, 2, 3, 4, 5, 6;
152 
153   stan::math::matrix_cl<double> vals_cl(vals);
154   var_value<stan::math::matrix_cl<double>> a_cl(vals_cl);
155   std::vector<vector_v> a
156       = stan::math::from_matrix_cl<std::vector<vector_v>>(a_cl);
157   EXPECT_MATRIX_EQ(stan::math::value_of(a[0]), vals.col(0));
158   EXPECT_MATRIX_EQ(stan::math::value_of(a[1]), vals.col(1));
159   EXPECT_MATRIX_EQ(stan::math::value_of(a[2]), vals.col(2));
160   a[0].adj() = Eigen::VectorXd::Constant(2, 2.0);
161   a[1].adj() = Eigen::VectorXd::Constant(2, 2.0);
162   a[2].adj() = Eigen::VectorXd::Constant(2, 2.0);
163   stan::math::grad();
164   EXPECT_MATRIX_EQ(from_matrix_cl(a_cl.adj()),
165                    Eigen::MatrixXd::Constant(2, 3, 2.0));
166 }
167 
168 #endif
169