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