Sacado Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
fad_expr.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_No_Kokkos.hpp"
33 #include "Sacado_Random.hpp"
34 #include "Sacado_Fad_SimpleFad.hpp"
35 
36 #include "Fad/fad.h"
37 #include "TinyFadET/tfad.h"
38 
39 #include "Teuchos_Time.hpp"
41 
42 // A simple performance test that computes the derivative of a simple
43 // expression using many variants of Fad.
44 
45 void FAD::error(const char *msg) {
46  std::cout << msg << std::endl;
47 }
48 
49 template <typename T>
50 inline void
51 func1(const T& x1, const T& x2, T& y) {
52  y = (x1*x2 + sin(x1)/x2);
53 }
54 
55 inline void
56 func1_and_deriv(int n, double x1, double x2, double* x1dot, double* x2dot,
57  double& y, double* ydot) {
58  double s = sin(x1);
59  double c = cos(x1);
60  double t = s/x2;
61  double t1 = x2 + c/x2;
62  double t2 = x1 - t/x2;
63  y = x1*x2 + t;
64  for (int i=0; i<10; i++)
65  ydot[i] = t1*x1dot[i] + t2*x2dot[i];
66 }
67 
68 template <typename FadType>
69 double
70 do_time(int nderiv, int nloop)
71 {
72  FadType x1, x2, y;
73  Sacado::Random<double> urand(0.0, 1.0);
74 
75  x1 = FadType(nderiv, urand.number());
76  x2 = FadType(nderiv, urand.number());
77  y = 0.0;
78  for (int j=0; j<nderiv; j++) {
79  x1.fastAccessDx(j) = urand.number();
80  x2.fastAccessDx(j) = urand.number();
81  }
82 
83  Teuchos::Time timer("mult", false);
84  timer.start(true);
85  for (int j=0; j<nloop; j++) {
86  func1(x1, x2, y);
87  }
88  timer.stop();
89 
90  return timer.totalElapsedTime() / nloop;
91 }
92 
93 double
94 do_time_analytic(int nderiv, int nloop)
95 {
96  double x1, x2, y;
97  double *x1dot, *x2dot, *ydot;
98  Sacado::Random<double> urand(0.0, 1.0);
99 
100  x1 = urand.number();
101  x2 = urand.number();
102  y = 0.0;
103  x1dot = new double[nderiv];
104  x2dot = new double[nderiv];
105  ydot = new double[nderiv];
106  for (int j=0; j<nderiv; j++) {
107  x1dot[j] = urand.number();
108  x2dot[j] = urand.number();
109  }
110 
111  Teuchos::Time timer("mult", false);
112  timer.start(true);
113  for (int j=0; j<nloop; j++) {
114  func1_and_deriv(nderiv, x1, x2, x1dot, x2dot, y, ydot);
115  }
116  timer.stop();
117 
118  return timer.totalElapsedTime() / nloop;
119 }
120 
121 int main(int argc, char* argv[]) {
122  int ierr = 0;
123 
124  try {
125  double t, ta;
126  int p = 2;
127  int w = p+7;
128 
129  // Set up command line options
131  clp.setDocString("This program tests the speed of various forward mode AD implementations for a single multiplication operation");
132  int nderiv = 10;
133  clp.setOption("nderiv", &nderiv, "Number of derivative components");
134  int nloop = 1000000;
135  clp.setOption("nloop", &nloop, "Number of loops");
136 
137  // Parse options
139  parseReturn= clp.parse(argc, argv);
141  return 1;
142 
143  std::cout.setf(std::ios::scientific);
144  std::cout.precision(p);
145  std::cout << "Times (sec) for nderiv = " << nderiv
146  << " nloop = " << nloop << ": " << std::endl;
147 
148  ta = do_time_analytic(nderiv, nloop);
149  std::cout << "Analytic: " << std::setw(w) << ta << std::endl;
150 
151  t = do_time< Sacado::Fad::SimpleFad<double> >(nderiv, nloop);
152  std::cout << "SimpleFad: " << std::setw(w) << t << "\t" << std::setw(w) << t/ta << std::endl;
153 
154  t = do_time< FAD::TFad<10,double> >(nderiv, nloop);
155  std::cout << "TFad: " << std::setw(w) << t << "\t" << std::setw(w) << t/ta << std::endl;
156 
157  t = do_time< FAD::Fad<double> >(nderiv, nloop);
158  std::cout << "Fad: " << std::setw(w) << t << "\t" << std::setw(w) << t/ta << std::endl;
159 
160  t = do_time< Sacado::Fad::SFad<double,10> >(nderiv, nloop);
161  std::cout << "SFad: " << std::setw(w) << t << "\t" << std::setw(w) << t/ta << std::endl;
162 
163  t = do_time< Sacado::Fad::SLFad<double,10> >(nderiv, nloop);
164  std::cout << "SLFad: " << std::setw(w) << t << "\t" << std::setw(w) << t/ta << std::endl;
165 
166  t = do_time< Sacado::Fad::DFad<double> >(nderiv, nloop);
167  std::cout << "DFad: " << std::setw(w) << t << "\t" << std::setw(w) << t/ta << std::endl;
168 
169  t = do_time< Sacado::ELRFad::SFad<double,10> >(nderiv, nloop);
170  std::cout << "ELRSFad: " << std::setw(w) << t << "\t" << std::setw(w) << t/ta << std::endl;
171 
172  t = do_time< Sacado::ELRFad::SLFad<double,10> >(nderiv, nloop);
173  std::cout << "ELRSLFad: " << std::setw(w) << t << "\t" << std::setw(w) << t/ta << std::endl;
174 
175  t = do_time< Sacado::ELRFad::DFad<double> >(nderiv, nloop);
176  std::cout << "ELRDFad: " << std::setw(w) << t << "\t" << std::setw(w) << t/ta << std::endl;
177 
178  t = do_time< Sacado::CacheFad::DFad<double> >(nderiv, nloop);
179  std::cout << "CacheFad: " << std::setw(w) << t << "\t" << std::setw(w) << t/ta << std::endl;
180 
181  t = do_time< Sacado::Fad::DVFad<double> >(nderiv, nloop);
182  std::cout << "DVFad: " << std::setw(w) << t << "\t" << std::setw(w) << t/ta << std::endl;
183 
184  }
185  catch (std::exception& e) {
186  std::cout << e.what() << std::endl;
187  ierr = 1;
188  }
189  catch (const char *s) {
190  std::cout << s << std::endl;
191  ierr = 1;
192  }
193  catch (...) {
194  std::cout << "Caught unknown exception!" << std::endl;
195  ierr = 1;
196  }
197 
198  return ierr;
199 }
double do_time_analytic(int nderiv, int nloop)
Definition: fad_expr.cpp:94
Sacado::Fad::DFad< double > FadType
void func1_and_deriv(int n, double x1, double x2, double *x1dot, double *x2dot, double &y, double *ydot)
Definition: fad_expr.cpp:56
ScalarT number()
Get random number.
#define T
Definition: Sacado_rad.hpp:573
void start(bool reset=false)
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
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:191
EParseCommandLineReturn parse(int argc, char *argv[], std::ostream *errout=&std::cerr) const
sin(expr.val())
double do_time(int nderiv, int nloop)
Definition: fad_expr.cpp:70
void setDocString(const char doc_string[])
double totalElapsedTime(bool readCurrentTime=false) const
void func1(const T &x1, const T &x2, T &y)
Definition: fad_expr.cpp:51
cos(expr.val())