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 // $Id$
2 // $Source$
3 // @HEADER
4 // ***********************************************************************
5 //
6 // Sacado Package
7 // Copyright (2006) Sandia Corporation
8 //
9 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
10 // the U.S. Government retains certain rights in this software.
11 //
12 // This library is free software; you can redistribute it and/or modify
13 // it under the terms of the GNU Lesser General Public License as
14 // published by the Free Software Foundation; either version 2.1 of the
15 // License, or (at your option) any later version.
16 //
17 // This library is distributed in the hope that it will be useful, but
18 // WITHOUT ANY WARRANTY; without even the implied warranty of
19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 // Lesser General Public License for more details.
21 //
22 // You should have received a copy of the GNU Lesser General Public
23 // License along with this library; if not, write to the Free Software
24 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
25 // USA
26 // Questions? Contact David M. Gay (dmgay@sandia.gov) or Eric T. Phipps
27 // (etphipp@sandia.gov).
28 //
29 // ***********************************************************************
30 // @HEADER
31 
32 #include "Sacado_Random.hpp"
33 #include "Sacado_No_Kokkos.hpp"
34 
35 #include "Fad/fad.h"
36 #include "TinyFadET/tfad.h"
37 
38 #include "Teuchos_Time.hpp"
40 
41 // A simple performance test that computes the derivative of a simple
42 // expression using many variants of Fad.
43 
44 template <>
46 
47 void FAD::error(const char *msg) {
48  std::cout << msg << std::endl;
49 }
50 
51 namespace {
52  double xi[3], xj[3], pa[4], f[3], delr[3];
53 }
54 
55 template <typename T>
56 inline T
57 vec3_distsq(const T xi[], const double xj[]) {
58  T delr0 = xi[0]-xj[0];
59  T delr1 = xi[1]-xj[1];
60  T delr2 = xi[2]-xj[2];
61  return delr0*delr0 + delr1*delr1 + delr2*delr2;
62 }
63 
64 template <typename T>
65 inline T
66 vec3_distsq(const T xi[], const double xj[], T delr[]) {
67  delr[0] = xi[0]-xj[0];
68  delr[1] = xi[1]-xj[1];
69  delr[2] = xi[2]-xj[2];
70  return delr[0]*delr[0] + delr[1]*delr[1] + delr[2]*delr[2];
71 }
72 
73 template <typename T>
74 inline void
75 lj(const T xi[], const double xj[], T& energy) {
76  T delr2 = vec3_distsq(xi,xj);
77  T delr_2 = 1.0/delr2;
78  T delr_6 = delr_2*delr_2*delr_2;
79  energy = (pa[1]*delr_6 - pa[2])*delr_6 - pa[3];
80 }
81 
82 inline void
83 lj_and_grad(const double xi[], const double xj[], double& energy,
84  double f[]) {
85  double delr2 = vec3_distsq(xi,xj,delr);
86  double delr_2 = 1.0/delr2;
87  double delr_6 = delr_2*delr_2*delr_2;
88  energy = (pa[1]*delr_6 - pa[2])*delr_6 - pa[3];
89  double tmp = (-12.0*pa[1]*delr_6 - 6.0*pa[2])*delr_6*delr_2;
90  f[0] = delr[0]*tmp;
91  f[1] = delr[1]*tmp;
92  f[2] = delr[2]*tmp;
93 }
94 
95 template <typename FadType>
96 double
97 do_time(int nloop)
98 {
99  Teuchos::Time timer("lj", false);
100  FadType xi_fad[3], energy;
101 
102  for (int i=0; i<3; i++) {
103  xi_fad[i] = FadType(3, i, xi[i]);
104  }
105 
106  timer.start(true);
107  for (int j=0; j<nloop; j++) {
108 
109  lj(xi_fad, xj, energy);
110 
111  for (int i=0; i<3; i++)
112  f[i] += -energy.fastAccessDx(i);
113  }
114  timer.stop();
115 
116  return timer.totalElapsedTime() / nloop;
117 }
118 
119 double
121 {
122  Teuchos::Time timer("lj", false);
123  double energy, ff[3];
124 
125  timer.start(true);
126  for (int j=0; j<nloop; j++) {
127 
128  lj_and_grad(xi, xj, energy, ff);
129 
130  for (int i=0; i<3; i++)
131  f[i] += -ff[i];
132 
133  }
134  timer.stop();
135 
136  return timer.totalElapsedTime() / nloop;
137 }
138 
139 int main(int argc, char* argv[]) {
140  int ierr = 0;
141 
142  try {
143  double t, ta;
144  int p = 2;
145  int w = p+7;
146 
147  // Set up command line options
149  clp.setDocString("This program tests the speed of various forward mode AD implementations for a single multiplication operation");
150  int nloop = 1000000;
151  clp.setOption("nloop", &nloop, "Number of loops");
152 
153  // Parse options
155  parseReturn= clp.parse(argc, argv);
157  return 1;
158 
159  // Memory pool & manager
161  Sacado::Fad::MemPool* pool = poolManager.getMemoryPool(3);
163 
164  std::cout.setf(std::ios::scientific);
165  std::cout.precision(p);
166  std::cout << "Times (sec) nloop = " << nloop << ": " << std::endl;
167 
168  Sacado::Random<double> urand(0.0, 1.0);
169  for (int i=0; i<3; i++) {
170  xi[i] = urand.number();
171  xj[i] = urand.number();
172  pa[i] = urand.number();
173  }
174  pa[3] = urand.number();
175 
176  ta = do_time_analytic(nloop);
177  std::cout << "Analytic: " << std::setw(w) << ta << std::endl;
178 
179  t = do_time< FAD::TFad<3,double> >(nloop);
180  std::cout << "TFad: " << std::setw(w) << t << "\t" << std::setw(w) << t/ta << std::endl;
181 
182  t = do_time< FAD::Fad<double> >(nloop);
183  std::cout << "Fad: " << std::setw(w) << t << "\t" << std::setw(w) << t/ta << std::endl;
184 
185  t = do_time< Sacado::Fad::SFad<double,3> >(nloop);
186  std::cout << "SFad: " << std::setw(w) << t << "\t" << std::setw(w) << t/ta << std::endl;
187 
188  t = do_time< Sacado::Fad::SLFad<double,3> >(nloop);
189  std::cout << "SLFad: " << std::setw(w) << t << "\t" << std::setw(w) << t/ta << std::endl;
190 
191  t = do_time< Sacado::Fad::DFad<double> >(nloop);
192  std::cout << "DFad: " << std::setw(w) << t << "\t" << std::setw(w) << t/ta << std::endl;
193 
194  t = do_time< Sacado::Fad::DMFad<double> >(nloop);
195  std::cout << "DMFad: " << std::setw(w) << t << "\t" << std::setw(w) << t/ta << std::endl;
196 
197  t = do_time< Sacado::ELRFad::SFad<double,3> >(nloop);
198  std::cout << "ELRSFad: " << std::setw(w) << t << "\t" << std::setw(w) << t/ta << std::endl;
199 
200  t = do_time< Sacado::ELRFad::SLFad<double,3> >(nloop);
201  std::cout << "ELRSLFad: " << std::setw(w) << t << "\t" << std::setw(w) << t/ta << std::endl;
202 
203  t = do_time< Sacado::ELRFad::DFad<double> >(nloop);
204  std::cout << "ELRDFad: " << std::setw(w) << t << "\t" << std::setw(w) << t/ta << std::endl;
205 
206  t = do_time< Sacado::CacheFad::DFad<double> >(nloop);
207  std::cout << "CacheFad: " << std::setw(w) << t << "\t" << std::setw(w) << t/ta << std::endl;
208 
209  t = do_time< Sacado::Fad::DVFad<double> >(nloop);
210  std::cout << "DVFad: " << std::setw(w) << t << "\t" << std::setw(w) << t/ta << std::endl;
211 
212  }
213  catch (std::exception& e) {
214  std::cout << e.what() << std::endl;
215  ierr = 1;
216  }
217  catch (const char *s) {
218  std::cout << s << std::endl;
219  ierr = 1;
220  }
221  catch (...) {
222  std::cout << "Caught unknown exception!" << std::endl;
223  ierr = 1;
224  }
225 
226  return ierr;
227 }
MemPool * getMemoryPool(unsigned int dim)
Get memory pool for supplied dimension dim.
double do_time_analytic(int nderiv, int nloop)
Definition: fad_expr.cpp:97
void f()
Sacado::Fad::DFad< double > FadType
ScalarT number()
Get random number.
#define T
Definition: Sacado_rad.hpp:573
void start(bool reset=false)
double stop()
void setOption(const char option_true[], const char option_false[], bool *option_val, const char documentation[]=NULL)
Derivative array storage class using dynamic memory allocation.
int main()
Definition: ad_example.cpp:191
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:83
double do_time(int nderiv, int nloop)
Definition: fad_expr.cpp:73
void setDocString(const char doc_string[])
double totalElapsedTime(bool readCurrentTime=false) const
Forward-mode AD class using dynamic memory allocation and expression templates.
void lj(const T xi[], const double xj[], T &energy)
Definition: fad_lj_grad.cpp:75
T vec3_distsq(const T xi[], const double xj[])
Definition: fad_lj_grad.cpp:57