Sacado Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
fad_lj_grad.cpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Sacado Package
4 //
5 // Copyright 2006 NTESS and the Sacado contributors.
6 // SPDX-License-Identifier: LGPL-2.1-or-later
7 // *****************************************************************************
8 // @HEADER
9 
10 #include "Sacado_Random.hpp"
11 #include "Sacado_No_Kokkos.hpp"
12 
13 #include "Fad/fad.h"
14 #include "TinyFadET/tfad.h"
15 
16 #include "Teuchos_Time.hpp"
18 
19 // A simple performance test that computes the derivative of a simple
20 // expression using many variants of Fad.
21 
22 void FAD::error(const char *msg) {
23  std::cout << msg << std::endl;
24 }
25 
26 namespace {
27  double xi[3], xj[3], pa[4], f[3], delr[3];
28 }
29 
30 template <typename T>
31 inline T
32 vec3_distsq(const T xi[], const double xj[]) {
33  T delr0 = xi[0]-xj[0];
34  T delr1 = xi[1]-xj[1];
35  T delr2 = xi[2]-xj[2];
36  return delr0*delr0 + delr1*delr1 + delr2*delr2;
37 }
38 
39 template <typename T>
40 inline T
41 vec3_distsq(const T xi[], const double xj[], T delr[]) {
42  delr[0] = xi[0]-xj[0];
43  delr[1] = xi[1]-xj[1];
44  delr[2] = xi[2]-xj[2];
45  return delr[0]*delr[0] + delr[1]*delr[1] + delr[2]*delr[2];
46 }
47 
48 template <typename T>
49 inline void
50 lj(const T xi[], const double xj[], T& energy) {
51  T delr2 = vec3_distsq(xi,xj);
52  T delr_2 = 1.0/delr2;
53  T delr_6 = delr_2*delr_2*delr_2;
54  energy = (pa[1]*delr_6 - pa[2])*delr_6 - pa[3];
55 }
56 
57 inline void
58 lj_and_grad(const double xi[], const double xj[], double& energy,
59  double f[]) {
60  double delr2 = vec3_distsq(xi,xj,delr);
61  double delr_2 = 1.0/delr2;
62  double delr_6 = delr_2*delr_2*delr_2;
63  energy = (pa[1]*delr_6 - pa[2])*delr_6 - pa[3];
64  double tmp = (-12.0*pa[1]*delr_6 - 6.0*pa[2])*delr_6*delr_2;
65  f[0] = delr[0]*tmp;
66  f[1] = delr[1]*tmp;
67  f[2] = delr[2]*tmp;
68 }
69 
70 template <typename FadType>
71 double
72 do_time(int nloop)
73 {
74  Teuchos::Time timer("lj", false);
75  FadType xi_fad[3], energy;
76 
77  for (int i=0; i<3; i++) {
78  xi_fad[i] = FadType(3, i, xi[i]);
79  }
80 
81  timer.start(true);
82  for (int j=0; j<nloop; j++) {
83 
84  lj(xi_fad, xj, energy);
85 
86  for (int i=0; i<3; i++)
87  f[i] += -energy.fastAccessDx(i);
88  }
89  timer.stop();
90 
91  return timer.totalElapsedTime() / nloop;
92 }
93 
94 double
95 do_time_analytic(int nloop)
96 {
97  Teuchos::Time timer("lj", false);
98  double energy, ff[3];
99 
100  timer.start(true);
101  for (int j=0; j<nloop; j++) {
102 
103  lj_and_grad(xi, xj, energy, ff);
104 
105  for (int i=0; i<3; i++)
106  f[i] += -ff[i];
107 
108  }
109  timer.stop();
110 
111  return timer.totalElapsedTime() / nloop;
112 }
113 
114 int main(int argc, char* argv[]) {
115  int ierr = 0;
116 
117  try {
118  double t, ta;
119  int p = 2;
120  int w = p+7;
121 
122  // Set up command line options
124  clp.setDocString("This program tests the speed of various forward mode AD implementations for a single multiplication operation");
125  int nloop = 1000000;
126  clp.setOption("nloop", &nloop, "Number of loops");
127 
128  // Parse options
130  parseReturn= clp.parse(argc, argv);
132  return 1;
133 
134  std::cout.setf(std::ios::scientific);
135  std::cout.precision(p);
136  std::cout << "Times (sec) nloop = " << nloop << ": " << std::endl;
137 
138  Sacado::Random<double> urand(0.0, 1.0);
139  for (int i=0; i<3; i++) {
140  xi[i] = urand.number();
141  xj[i] = urand.number();
142  pa[i] = urand.number();
143  }
144  pa[3] = urand.number();
145 
146  ta = do_time_analytic(nloop);
147  std::cout << "Analytic: " << std::setw(w) << ta << std::endl;
148 
149  t = do_time< FAD::TFad<3,double> >(nloop);
150  std::cout << "TFad: " << std::setw(w) << t << "\t" << std::setw(w) << t/ta << std::endl;
151 
152  t = do_time< FAD::Fad<double> >(nloop);
153  std::cout << "Fad: " << std::setw(w) << t << "\t" << std::setw(w) << t/ta << std::endl;
154 
155  t = do_time< Sacado::Fad::SFad<double,3> >(nloop);
156  std::cout << "SFad: " << std::setw(w) << t << "\t" << std::setw(w) << t/ta << std::endl;
157 
158  t = do_time< Sacado::Fad::SLFad<double,3> >(nloop);
159  std::cout << "SLFad: " << std::setw(w) << t << "\t" << std::setw(w) << t/ta << std::endl;
160 
161  t = do_time< Sacado::Fad::DFad<double> >(nloop);
162  std::cout << "DFad: " << std::setw(w) << t << "\t" << std::setw(w) << t/ta << std::endl;
163 
164  t = do_time< Sacado::ELRFad::SFad<double,3> >(nloop);
165  std::cout << "ELRSFad: " << std::setw(w) << t << "\t" << std::setw(w) << t/ta << std::endl;
166 
167  t = do_time< Sacado::ELRFad::SLFad<double,3> >(nloop);
168  std::cout << "ELRSLFad: " << std::setw(w) << t << "\t" << std::setw(w) << t/ta << std::endl;
169 
170  t = do_time< Sacado::ELRFad::DFad<double> >(nloop);
171  std::cout << "ELRDFad: " << std::setw(w) << t << "\t" << std::setw(w) << t/ta << std::endl;
172 
173  t = do_time< Sacado::CacheFad::DFad<double> >(nloop);
174  std::cout << "CacheFad: " << std::setw(w) << t << "\t" << std::setw(w) << t/ta << std::endl;
175 
176  t = do_time< Sacado::Fad::DVFad<double> >(nloop);
177  std::cout << "DVFad: " << std::setw(w) << t << "\t" << std::setw(w) << t/ta << std::endl;
178 
179  }
180  catch (std::exception& e) {
181  std::cout << e.what() << std::endl;
182  ierr = 1;
183  }
184  catch (const char *s) {
185  std::cout << s << std::endl;
186  ierr = 1;
187  }
188  catch (...) {
189  std::cout << "Caught unknown exception!" << std::endl;
190  ierr = 1;
191  }
192 
193  return ierr;
194 }
const char * p
double do_time_analytic(int nderiv, int nloop)
Definition: fad_expr.cpp:72
void f()
Sacado::Fad::DFad< double > FadType
ScalarT number()
Get random number.
#define T
Definition: Sacado_rad.hpp:553
void start(bool reset=false)
double stop()
void setOption(const char option_true[], const char option_false[], bool *option_val, const char documentation[]=NULL)
int main()
Definition: ad_example.cpp:171
EParseCommandLineReturn parse(int argc, char *argv[], std::ostream *errout=&std::cerr) const
void lj_and_grad(const double xi[], const double xj[], double &energy, double f[])
Definition: fad_lj_grad.cpp:58
double do_time(int nderiv, int nloop)
Definition: fad_expr.cpp:48
void setDocString(const char doc_string[])
double totalElapsedTime(bool readCurrentTime=false) const
void lj(const T xi[], const double xj[], T &energy)
Definition: fad_lj_grad.cpp:50
T vec3_distsq(const T xi[], const double xj[])
Definition: fad_lj_grad.cpp:32