Sacado Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
view_example.cpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Stokhos Package
4 //
5 // Copyright 2009 NTESS and the Stokhos contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 #include "Sacado.hpp"
11 
12 //
13 // A simple example showing how to use Sacado with Kokkos
14 //
15 // The code would be simpler using lambda's instead of functors, but that
16 // can be problematic for Cuda and for versions of g++ that claim to, but
17 // don't really support C++11
18 //
19 
20 // This code relies on the Kokkos view specializations being enabled, which
21 // is the default, but can be disabled by the user
22 #if defined(HAVE_SACADO_VIEW_SPEC) && !defined(SACADO_DISABLE_FAD_VIEW_SPEC)
23 
24 // Functor to compute matrix-vector product c = A*b using Kokkos
25 template <typename ViewTypeA, typename ViewTypeB, typename ViewTypeC>
26 class MatVec {
27  const ViewTypeA A;
28  const ViewTypeB b;
29  const ViewTypeC c;
30  const size_t m, n;
31 
32 public:
33 
34  MatVec(const ViewTypeA& A_, const ViewTypeB& b_, const ViewTypeC& c_) :
35  A(A_), b(b_), c(c_),
36  m(A.extent(0)), n(A.extent(1))
37  {
38  typedef typename ViewTypeC::execution_space execution_space;
39  Kokkos::parallel_for(Kokkos::RangePolicy<execution_space>(0,m), *this);
40  }
41 
42  KOKKOS_INLINE_FUNCTION
43  void operator() (const size_t i) const {
44  typedef typename ViewTypeC::value_type scalar_type;
45 
46  scalar_type t = 0.0;
47  for (size_t j=0; j<n; ++j) {
48  scalar_type bb = b(j); // fix for Intel 17.0.1 with optimization
49  t += A(i,j)*bb;
50  }
51  c(i) = t;
52  }
53 };
54 
55 // Function to run mat-vec functor above
56 template <typename ViewTypeA, typename ViewTypeB, typename ViewTypeC>
57 void run_mat_vec(const ViewTypeA& A, const ViewTypeB& b,const ViewTypeC& c)
58 {
59  MatVec<ViewTypeA,ViewTypeB,ViewTypeC> f(A,b,c);
60 }
61 
62 // Functor to compute the derivative of the matrix-vector product
63 // c = A*b using Kokkos.
64 template <typename ViewTypeA, typename ViewTypeB, typename ViewTypeC>
65 class MatVecDeriv {
66  const ViewTypeA A;
67  const ViewTypeB b;
68  const ViewTypeC c;
69  const size_t m, n, p;
70 
71 public:
72 
73  MatVecDeriv(const ViewTypeA& A_, const ViewTypeB& b_, const ViewTypeC& c_) :
74  A(A_), b(b_), c(c_),
75  m(A.extent(0)), n(A.extent(1)), p(A.extent(2)-1)
76  {
77  typedef typename ViewTypeC::execution_space execution_space;
78  Kokkos::parallel_for(Kokkos::RangePolicy<execution_space>(0,m), *this);
79  }
80 
81  KOKKOS_INLINE_FUNCTION
82  void operator() (const size_t i) const {
83  typedef typename ViewTypeC::value_type scalar_type;
84 
85  // Derivative portion
86  for (size_t k=0; k<p; ++k) {
87  scalar_type t = 0.0;
88  for (size_t j=0; j<n; ++j)
89  t += A(i,j,k)*b(j,p) + A(i,j,p)*b(j,k);
90  c(i,k) = t;
91  }
92 
93  // Value portion
94  scalar_type t = 0.0;
95  for (size_t j=0; j<n; ++j)
96  t += A(i,j,p)*b(j,p);
97  c(i,p) = t;
98  }
99 };
100 
101 // Function to run mat-vec derivative functor above
102 template <typename ViewTypeA, typename ViewTypeB, typename ViewTypeC>
103 void run_mat_vec_deriv(const ViewTypeA& A, const ViewTypeB& b,
104  const ViewTypeC& c)
105 {
106  MatVecDeriv<ViewTypeA,ViewTypeB,ViewTypeC> f(A,b,c);
107 }
108 
109 #endif
110 
111 int main(int argc, char* argv[]) {
112  int ret = 0;
113 
114 #if defined(HAVE_SACADO_VIEW_SPEC) && !defined(SACADO_DISABLE_FAD_VIEW_SPEC)
115 
116  Kokkos::initialize(argc, argv);
117  {
118 
119  const size_t m = 10; // Number of rows
120  const size_t n = 2; // Number of columns
121  const size_t p = 1; // Derivative dimension
122 
123  // Allocate Kokkos view's for matrix, input vector, and output vector
124  // Derivative dimension must be specified as the last constructor argument
126  Kokkos::View<FadType**> A("A",m,n,p+1);
127  Kokkos::View<FadType*> b("b",n,p+1);
128  Kokkos::View<FadType*> c("c",m,p+1);
129 
130  // Initialize values
131  Kokkos::deep_copy( A, FadType(p, 0, 2.0) );
132  Kokkos::deep_copy( b, FadType(p, 0, 3.0) );
133  Kokkos::deep_copy( c, 0.0 );
134 
135  // Run mat-vec
136  run_mat_vec(A,b,c);
137 
138  // Print result
139  std::cout << "\nc = A*b: Differentiated using Sacado:" << std::endl;
140  auto h_c = Kokkos::create_mirror_view(c);
141  Kokkos::deep_copy(h_c, c);
142  for (size_t i=0; i<m; ++i)
143  std::cout << "\tc(" << i << ") = " << h_c(i) << std::endl;
144 
145  // Now compute derivative analytically. Any Sacado view can be flattened
146  // into a standard view of one higher rank, with the extra dimension equal
147  // to p+1
148  Kokkos::View<FadType*> c2("c",m,p+1);
149  Kokkos::View<double***> A_flat = A;
150  Kokkos::View<double**> b_flat = b;
151  Kokkos::View<double**> c_flat = c2;
152  run_mat_vec_deriv(A_flat, b_flat, c_flat);
153 
154  // Print result
155  std::cout << "\nc = A*b: Differentiated analytically:" << std::endl;
156  auto h_c2 = Kokkos::create_mirror_view(c2);
157  Kokkos::deep_copy(h_c2, c2);
158  for (size_t i=0; i<m; ++i)
159  std::cout << "\tc(" << i << ") = " << h_c2(i) << std::endl;
160 
161  // Compute the error
162  double err = 0.0;
163  for (size_t i=0; i<m; ++i) {
164  for (size_t k=0; k<p; ++k)
165  err += std::abs(h_c(i).fastAccessDx(k)-h_c2(i).fastAccessDx(k));
166  err += std::abs(h_c(i).val()-h_c2(i).val());
167  }
168 
169  double tol = 1.0e-14;
170  if (err < tol) {
171  ret = 0;
172  std::cout << "\nExample passed!" << std::endl;
173  }
174  else {
175  ret = 1;
176  std::cout <<"\nSomething is wrong, example failed!" << std::endl;
177  }
178 
179  }
180  Kokkos::finalize();
181 
182 #endif
183 
184  return ret;
185 }
const char * p
char c_
void f()
abs(expr.val())
void run_mat_vec(const ViewTypeA &A, const ViewTypeB &b, const ViewTypeC &c)
Sacado::Fad::DFad< double > FadType
expr val()
expr expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c *expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr2 expr1 expr2 expr1 expr1 expr1 c
#define A
Definition: Sacado_rad.hpp:552
int main()
Definition: ad_example.cpp:171
void run_mat_vec_deriv(const ViewTypeA &A, const ViewTypeB &b, const ViewTypeC &c)
Definition: mat_vec.cpp:78
expr expr expr fastAccessDx(i)) FAD_UNARYOP_MACRO(exp
const double tol
int n