44int main(
int argc,
char* argv[]) {
53 const int slfad_max = 130;
56 Teuchos::CommandLineProcessor clp;
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");
66 Teuchos::CommandLineProcessor::EParseCommandLineReturn
67 parseReturn= clp.parse(argc, argv);
68 if(parseReturn != Teuchos::CommandLineProcessor::PARSE_SUCCESSFUL)
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;
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) {
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) {
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) {
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) {
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;
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) {
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) {
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) {
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) {
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) {
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;
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;
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) {
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) {
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) {
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) {
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) {
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;
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) {
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) {
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) {
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) {
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) {
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;
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) {
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) {
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) {
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) {
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) {
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;
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;
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;