35 #include "TinyFadET/tfad.h"
40 void FAD::error(
const char *msg) {
41 std::cout << msg << std::endl;
44 int main(
int argc,
char* argv[]) {
53 const int slfad_max = 130;
57 clp.
setDocString(
"This program tests the speed of various forward mode AD implementations for a finite-element-like Jacobian fill");
58 int num_nodes = 100000;
61 clp.
setOption(
"n", &num_nodes,
"Number of nodes");
62 clp.
setOption(
"p", &num_eqns,
"Number of equations");
63 clp.
setOption(
"rt", &rt,
"Include ADOL-C retaping test");
67 parseReturn= clp.
parse(argc, argv);
71 double mesh_spacing = 1.0 /
static_cast<double>(num_nodes - 1);
73 std::cout.setf(std::ios::scientific);
74 std::cout.precision(p);
75 std::cout <<
"num_nodes = " << num_nodes
76 <<
", num_eqns = " << num_eqns <<
": " << std::endl
77 <<
" " <<
" Time " <<
"\t"<<
"Time/Analytic" <<
"\t"
78 <<
"Time/(2*p*Residual)" << std::endl;
86 std::cout <<
"Analytic: " << std::setw(w) << ta <<
"\t" << std::setw(w) << ta/ta <<
"\t" << std::setw(w) << ta/(2.0*num_eqns*tr) << std::endl;
89 #ifndef ADOLC_TAPELESS
90 t = adolc_jac_fill(num_nodes, num_eqns, mesh_spacing);
91 std::cout <<
"ADOL-C: " << std::setw(w) << t <<
"\t" << std::setw(w) << t/ta <<
"\t" << std::setw(w) << t/(2.0*num_eqns*tr) << std::endl;
94 t = adolc_retape_jac_fill(num_nodes, num_eqns, mesh_spacing);
95 std::cout <<
"ADOL-C(rt): " << std::setw(w) << t <<
"\t" << std::setw(w) << t/ta <<
"\t" << std::setw(w) << t/(2.0*num_eqns*tr) << std::endl;
99 t = adolc_tapeless_jac_fill(num_nodes, num_eqns, mesh_spacing);
100 std::cout <<
"ADOL-C(tl): " << std::setw(w) << t <<
"\t" << std::setw(w) << t/ta <<
"\t" << std::setw(w) << t/(2.0*num_eqns*tr) << std::endl;
105 t = adic_jac_fill(num_nodes, num_eqns, mesh_spacing);
106 std::cout <<
"ADIC: " << std::setw(w) << t <<
"\t" << std::setw(w) << t/ta <<
"\t" << std::setw(w) << t/(2.0*num_eqns*tr) << std::endl;
109 if (num_eqns*2 == 4) {
110 t = fad_jac_fill< FAD::TFad<16,double> >(num_nodes, num_eqns, mesh_spacing);
111 std::cout <<
"TFad: " << std::setw(w) << t <<
"\t" << std::setw(w) << t/ta <<
"\t" << std::setw(w) << t/(2.0*num_eqns*tr) << std::endl;
113 else if (num_eqns*2 == 16) {
114 t = fad_jac_fill< FAD::TFad<16,double> >(num_nodes, num_eqns, mesh_spacing);
115 std::cout <<
"TFad: " << std::setw(w) << t <<
"\t" << std::setw(w) << t/ta <<
"\t" << std::setw(w) << t/(2.0*num_eqns*tr) << std::endl;
117 else if (num_eqns*2 == 32) {
118 t = fad_jac_fill< FAD::TFad<32,double> >(num_nodes, num_eqns, mesh_spacing);
119 std::cout <<
"TFad: " << std::setw(w) << t <<
"\t" << std::setw(w) << t/ta <<
"\t" << std::setw(w) << t/(2.0*num_eqns*tr) << std::endl;
121 else if (num_eqns*2 == 64) {
122 t = fad_jac_fill< FAD::TFad<64,double> >(num_nodes, num_eqns, mesh_spacing);
123 std::cout <<
"TFad: " << std::setw(w) << t <<
"\t" << std::setw(w) << t/ta <<
"\t" << std::setw(w) << t/(2.0*num_eqns*tr) << std::endl;
126 t = fad_jac_fill< FAD::Fad<double> >(num_nodes, num_eqns, mesh_spacing);
127 std::cout <<
"Fad: " << std::setw(w) << t <<
"\t" << std::setw(w) << t/ta <<
"\t" << std::setw(w) << t/(2.0*num_eqns*tr) << std::endl;
129 if (num_eqns*2 == 4) {
130 t = fad_jac_fill< Sacado::Fad::SFad<double,4> >(num_nodes, num_eqns, mesh_spacing);
131 std::cout <<
"SFad: " << std::setw(w) << t <<
"\t" << std::setw(w) << t/ta <<
"\t" << std::setw(w) << t/(2.0*num_eqns*tr) << std::endl;
133 else if (num_eqns*2 == 16) {
134 t = fad_jac_fill< Sacado::Fad::SFad<double,16> >(num_nodes, num_eqns, mesh_spacing);
135 std::cout <<
"SFad: " << std::setw(w) << t <<
"\t" << std::setw(w) << t/ta <<
"\t" << std::setw(w) << t/(2.0*num_eqns*tr) << std::endl;
137 else if (num_eqns*2 == 32) {
138 t = fad_jac_fill< Sacado::Fad::SFad<double,32> >(num_nodes, num_eqns, mesh_spacing);
139 std::cout <<
"SFad: " << std::setw(w) << t <<
"\t" << std::setw(w) << t/ta <<
"\t" << std::setw(w) << t/(2.0*num_eqns*tr) << std::endl;
141 else if (num_eqns*2 == 64) {
142 t = fad_jac_fill< Sacado::Fad::SFad<double,64> >(num_nodes, num_eqns, mesh_spacing);
143 std::cout <<
"SFad: " << std::setw(w) << t <<
"\t" << std::setw(w) << t/ta <<
"\t" << std::setw(w) << t/(2.0*num_eqns*tr) << std::endl;
146 if (num_eqns*2 < slfad_max) {
147 t = fad_jac_fill< Sacado::Fad::SLFad<double,slfad_max> >(num_nodes, num_eqns, mesh_spacing);
148 std::cout <<
"SLFad: " << std::setw(w) << t <<
"\t" << std::setw(w) << t/ta <<
"\t" << std::setw(w) << t/(2.0*num_eqns*tr) << std::endl;
151 t = fad_jac_fill< Sacado::Fad::DFad<double> >(num_nodes, num_eqns, mesh_spacing);
152 std::cout <<
"DFad: " << std::setw(w) << t <<
"\t" << std::setw(w) << t/ta <<
"\t" << std::setw(w) << t/(2.0*num_eqns*tr) << std::endl;
154 t = fad_jac_fill< Sacado::Fad::SimpleFad<double> >(num_nodes, num_eqns, mesh_spacing);
155 std::cout <<
"SimpleFad: " << std::setw(w) << t <<
"\t" << std::setw(w) << t/ta <<
"\t" << std::setw(w) << t/(2.0*num_eqns*tr) << std::endl;
157 if (num_eqns*2 == 4) {
158 t = fad_jac_fill< Sacado::ELRFad::SFad<double,4> >(num_nodes, num_eqns, mesh_spacing);
159 std::cout <<
"ELRSFad: " << std::setw(w) << t <<
"\t" << std::setw(w) << t/ta <<
"\t" << std::setw(w) << t/(2.0*num_eqns*tr) << std::endl;
161 else if (num_eqns*2 == 16) {
162 t = fad_jac_fill< Sacado::ELRFad::SFad<double,16> >(num_nodes, num_eqns, mesh_spacing);
163 std::cout <<
"ELRSFad: " << std::setw(w) << t <<
"\t" << std::setw(w) << t/ta <<
"\t" << std::setw(w) << t/(2.0*num_eqns*tr) << std::endl;
165 else if (num_eqns*2 == 32) {
166 t = fad_jac_fill< Sacado::ELRFad::SFad<double,32> >(num_nodes, num_eqns, mesh_spacing);
167 std::cout <<
"ELRSFad: " << std::setw(w) << t <<
"\t" << std::setw(w) << t/ta <<
"\t" << std::setw(w) << t/(2.0*num_eqns*tr) << std::endl;
169 else if (num_eqns*2 == 64) {
170 t = fad_jac_fill< Sacado::ELRFad::SFad<double,64> >(num_nodes, num_eqns, mesh_spacing);
171 std::cout <<
"ELRSFad: " << std::setw(w) << t <<
"\t" << std::setw(w) << t/ta <<
"\t" << std::setw(w) << t/(2.0*num_eqns*tr) << std::endl;
174 if (num_eqns*2 < slfad_max) {
175 t = fad_jac_fill< Sacado::ELRFad::SLFad<double,slfad_max> >(num_nodes, num_eqns, mesh_spacing);
176 std::cout <<
"ELRSLFad: " << std::setw(w) << t <<
"\t" << std::setw(w) << t/ta <<
"\t" << std::setw(w) << t/(2.0*num_eqns*tr) << std::endl;
179 t = fad_jac_fill< Sacado::ELRFad::DFad<double> >(num_nodes, num_eqns, mesh_spacing);
180 std::cout <<
"ELRDFad: " << std::setw(w) << t <<
"\t" << std::setw(w) << t/ta <<
"\t" << std::setw(w) << t/(2.0*num_eqns*tr) << std::endl;
182 if (num_eqns*2 == 4) {
183 t = fad_jac_fill< Sacado::CacheFad::SFad<double,4> >(num_nodes, num_eqns, mesh_spacing);
184 std::cout <<
"CacheSFad: " << std::setw(w) << t <<
"\t" << std::setw(w) << t/ta <<
"\t" << std::setw(w) << t/(2.0*num_eqns*tr) << std::endl;
186 else if (num_eqns*2 == 16) {
187 t = fad_jac_fill< Sacado::CacheFad::SFad<double,16> >(num_nodes, num_eqns, mesh_spacing);
188 std::cout <<
"CacheSFad: " << std::setw(w) << t <<
"\t" << std::setw(w) << t/ta <<
"\t" << std::setw(w) << t/(2.0*num_eqns*tr) << std::endl;
190 else if (num_eqns*2 == 32) {
191 t = fad_jac_fill< Sacado::CacheFad::SFad<double,32> >(num_nodes, num_eqns, mesh_spacing);
192 std::cout <<
"CacheSFad: " << std::setw(w) << t <<
"\t" << std::setw(w) << t/ta <<
"\t" << std::setw(w) << t/(2.0*num_eqns*tr) << std::endl;
194 else if (num_eqns*2 == 64) {
195 t = fad_jac_fill< Sacado::CacheFad::SFad<double,64> >(num_nodes, num_eqns, mesh_spacing);
196 std::cout <<
"CacheSFad: " << std::setw(w) << t <<
"\t" << std::setw(w) << t/ta <<
"\t" << std::setw(w) << t/(2.0*num_eqns*tr) << std::endl;
199 if (num_eqns*2 < slfad_max) {
200 t = fad_jac_fill< Sacado::CacheFad::SLFad<double,slfad_max> >(num_nodes, num_eqns, mesh_spacing);
201 std::cout <<
"CacheSLFad: " << std::setw(w) << t <<
"\t" << std::setw(w) << t/ta <<
"\t" << std::setw(w) << t/(2.0*num_eqns*tr) << std::endl;
204 t = fad_jac_fill< Sacado::CacheFad::DFad<double> >(num_nodes, num_eqns, mesh_spacing);
205 std::cout <<
"CacheFad: " << std::setw(w) << t <<
"\t" << std::setw(w) << t/ta <<
"\t" << std::setw(w) << t/(2.0*num_eqns*tr) << std::endl;
207 if (num_eqns*2 == 4) {
208 t = fad_jac_fill< Sacado::ELRCacheFad::SFad<double,4> >(num_nodes, num_eqns, mesh_spacing);
209 std::cout <<
"ELRCacheSFad: " << std::setw(w) << t <<
"\t" << std::setw(w) << t/ta <<
"\t" << std::setw(w) << t/(2.0*num_eqns*tr) << std::endl;
211 else if (num_eqns*2 == 16) {
212 t = fad_jac_fill< Sacado::ELRCacheFad::SFad<double,16> >(num_nodes, num_eqns, mesh_spacing);
213 std::cout <<
"ELRCacheSFad: " << std::setw(w) << t <<
"\t" << std::setw(w) << t/ta <<
"\t" << std::setw(w) << t/(2.0*num_eqns*tr) << std::endl;
215 else if (num_eqns*2 == 32) {
216 t = fad_jac_fill< Sacado::ELRCacheFad::SFad<double,32> >(num_nodes, num_eqns, mesh_spacing);
217 std::cout <<
"ELRCacheSFad: " << std::setw(w) << t <<
"\t" << std::setw(w) << t/ta <<
"\t" << std::setw(w) << t/(2.0*num_eqns*tr) << std::endl;
219 else if (num_eqns*2 == 64) {
220 t = fad_jac_fill< Sacado::ELRCacheFad::SFad<double,64> >(num_nodes, num_eqns, mesh_spacing);
221 std::cout <<
"ELRCacheSFad: " << std::setw(w) << t <<
"\t" << std::setw(w) << t/ta <<
"\t" << std::setw(w) << t/(2.0*num_eqns*tr) << std::endl;
224 if (num_eqns*2 < slfad_max) {
225 t = fad_jac_fill< Sacado::ELRCacheFad::SLFad<double,slfad_max> >(num_nodes, num_eqns, mesh_spacing);
226 std::cout <<
"ELRCacheSLFad: " << std::setw(w) << t <<
"\t" << std::setw(w) << t/ta <<
"\t" << std::setw(w) << t/(2.0*num_eqns*tr) << std::endl;
229 t = fad_jac_fill< Sacado::ELRCacheFad::DFad<double> >(num_nodes, num_eqns, mesh_spacing);
230 std::cout <<
"ELRCacheFad: " << std::setw(w) << t <<
"\t" << std::setw(w) << t/ta <<
"\t" << std::setw(w) << t/(2.0*num_eqns*tr) << std::endl;
232 t = fad_jac_fill< Sacado::Fad::DVFad<double> >(num_nodes, num_eqns, mesh_spacing);
233 std::cout <<
"DVFad: " << std::setw(w) << t <<
"\t" << std::setw(w) << t/ta <<
"\t" << std::setw(w) << t/(2.0*num_eqns*tr) << std::endl;
236 catch (std::exception& e) {
237 std::cout << e.what() << std::endl;
240 catch (
const char *s) {
241 std::cout << s << std::endl;
245 std::cout <<
"Caught unknown exception!" << std::endl;
double residual_fill(unsigned int num_nodes, unsigned int num_eqns, double mesh_spacing)
double analytic_jac_fill(unsigned int num_nodes, unsigned int num_eqns, double mesh_spacing)
void setOption(const char option_true[], const char option_false[], bool *option_val, const char documentation[]=NULL)
EParseCommandLineReturn parse(int argc, char *argv[], std::ostream *errout=&std::cerr) const
void setDocString(const char doc_string[])