35 #include "TinyFadET/tfad.h"
43 void FAD::error(
const char *msg) {
44 std::cout << msg << std::endl;
47 int main(
int argc,
char* argv[]) {
56 const int slfad_max = 130;
60 clp.
setDocString(
"This program tests the speed of various forward mode AD implementations for a finite-element-like Jacobian fill");
61 int num_nodes = 100000;
64 clp.
setOption(
"n", &num_nodes,
"Number of nodes");
65 clp.
setOption(
"p", &num_eqns,
"Number of equations");
66 clp.
setOption(
"rt", &rt,
"Include ADOL-C retaping test");
70 parseReturn= clp.
parse(argc, argv);
74 double mesh_spacing = 1.0 /
static_cast<double>(num_nodes - 1);
81 std::cout.setf(std::ios::scientific);
82 std::cout.precision(p);
83 std::cout <<
"num_nodes = " << num_nodes
84 <<
", num_eqns = " << num_eqns <<
": " << std::endl
85 <<
" " <<
" Time " <<
"\t"<<
"Time/Analytic" <<
"\t"
86 <<
"Time/(2*p*Residual)" << std::endl;
94 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;
97 #ifndef ADOLC_TAPELESS
98 t = adolc_jac_fill(num_nodes, num_eqns, mesh_spacing);
99 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;
102 t = adolc_retape_jac_fill(num_nodes, num_eqns, mesh_spacing);
103 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;
107 t = adolc_tapeless_jac_fill(num_nodes, num_eqns, mesh_spacing);
108 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;
113 t = adic_jac_fill(num_nodes, num_eqns, mesh_spacing);
114 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;
117 if (num_eqns*2 == 4) {
118 t = fad_jac_fill< FAD::TFad<16,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 == 16) {
122 t = fad_jac_fill< FAD::TFad<16,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;
125 else if (num_eqns*2 == 32) {
126 t = fad_jac_fill< FAD::TFad<32,double> >(num_nodes, num_eqns, mesh_spacing);
127 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;
129 else if (num_eqns*2 == 64) {
130 t = fad_jac_fill< FAD::TFad<64,double> >(num_nodes, num_eqns, mesh_spacing);
131 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;
134 t = fad_jac_fill< FAD::Fad<double> >(num_nodes, num_eqns, mesh_spacing);
135 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;
137 if (num_eqns*2 == 4) {
138 t = fad_jac_fill< Sacado::Fad::SFad<double,4> >(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 == 16) {
142 t = fad_jac_fill< Sacado::Fad::SFad<double,16> >(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;
145 else if (num_eqns*2 == 32) {
146 t = fad_jac_fill< Sacado::Fad::SFad<double,32> >(num_nodes, num_eqns, mesh_spacing);
147 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;
149 else if (num_eqns*2 == 64) {
150 t = fad_jac_fill< Sacado::Fad::SFad<double,64> >(num_nodes, num_eqns, mesh_spacing);
151 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;
154 if (num_eqns*2 < slfad_max) {
155 t = fad_jac_fill< Sacado::Fad::SLFad<double,slfad_max> >(num_nodes, num_eqns, mesh_spacing);
156 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;
159 t = fad_jac_fill< Sacado::Fad::DFad<double> >(num_nodes, num_eqns, mesh_spacing);
160 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;
162 t = fad_jac_fill< Sacado::Fad::SimpleFad<double> >(num_nodes, num_eqns, mesh_spacing);
163 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;
165 t = fad_jac_fill< Sacado::Fad::DMFad<double> >(num_nodes, num_eqns, mesh_spacing);
166 std::cout <<
"DMFad: " << std::setw(w) << t <<
"\t" << std::setw(w) << t/ta <<
"\t" << std::setw(w) << t/(2.0*num_eqns*tr) << std::endl;
168 if (num_eqns*2 == 4) {
169 t = fad_jac_fill< Sacado::ELRFad::SFad<double,4> >(num_nodes, num_eqns, mesh_spacing);
170 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;
172 else if (num_eqns*2 == 16) {
173 t = fad_jac_fill< Sacado::ELRFad::SFad<double,16> >(num_nodes, num_eqns, mesh_spacing);
174 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;
176 else if (num_eqns*2 == 32) {
177 t = fad_jac_fill< Sacado::ELRFad::SFad<double,32> >(num_nodes, num_eqns, mesh_spacing);
178 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;
180 else if (num_eqns*2 == 64) {
181 t = fad_jac_fill< Sacado::ELRFad::SFad<double,64> >(num_nodes, num_eqns, mesh_spacing);
182 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;
185 if (num_eqns*2 < slfad_max) {
186 t = fad_jac_fill< Sacado::ELRFad::SLFad<double,slfad_max> >(num_nodes, num_eqns, mesh_spacing);
187 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;
190 t = fad_jac_fill< Sacado::ELRFad::DFad<double> >(num_nodes, num_eqns, mesh_spacing);
191 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;
193 if (num_eqns*2 == 4) {
194 t = fad_jac_fill< Sacado::CacheFad::SFad<double,4> >(num_nodes, num_eqns, mesh_spacing);
195 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;
197 else if (num_eqns*2 == 16) {
198 t = fad_jac_fill< Sacado::CacheFad::SFad<double,16> >(num_nodes, num_eqns, mesh_spacing);
199 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;
201 else if (num_eqns*2 == 32) {
202 t = fad_jac_fill< Sacado::CacheFad::SFad<double,32> >(num_nodes, num_eqns, mesh_spacing);
203 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;
205 else if (num_eqns*2 == 64) {
206 t = fad_jac_fill< Sacado::CacheFad::SFad<double,64> >(num_nodes, num_eqns, mesh_spacing);
207 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;
210 if (num_eqns*2 < slfad_max) {
211 t = fad_jac_fill< Sacado::CacheFad::SLFad<double,slfad_max> >(num_nodes, num_eqns, mesh_spacing);
212 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;
215 t = fad_jac_fill< Sacado::CacheFad::DFad<double> >(num_nodes, num_eqns, mesh_spacing);
216 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;
218 if (num_eqns*2 == 4) {
219 t = fad_jac_fill< Sacado::ELRCacheFad::SFad<double,4> >(num_nodes, num_eqns, mesh_spacing);
220 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;
222 else if (num_eqns*2 == 16) {
223 t = fad_jac_fill< Sacado::ELRCacheFad::SFad<double,16> >(num_nodes, num_eqns, mesh_spacing);
224 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;
226 else if (num_eqns*2 == 32) {
227 t = fad_jac_fill< Sacado::ELRCacheFad::SFad<double,32> >(num_nodes, num_eqns, mesh_spacing);
228 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;
230 else if (num_eqns*2 == 64) {
231 t = fad_jac_fill< Sacado::ELRCacheFad::SFad<double,64> >(num_nodes, num_eqns, mesh_spacing);
232 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;
235 if (num_eqns*2 < slfad_max) {
236 t = fad_jac_fill< Sacado::ELRCacheFad::SLFad<double,slfad_max> >(num_nodes, num_eqns, mesh_spacing);
237 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;
240 t = fad_jac_fill< Sacado::ELRCacheFad::DFad<double> >(num_nodes, num_eqns, mesh_spacing);
241 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;
243 t = fad_jac_fill< Sacado::Fad::DVFad<double> >(num_nodes, num_eqns, mesh_spacing);
244 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;
247 catch (std::exception& e) {
248 std::cout << e.what() << std::endl;
251 catch (
const char *s) {
252 std::cout << s << std::endl;
256 std::cout <<
"Caught unknown exception!" << std::endl;
MemPool * getMemoryPool(unsigned int dim)
Get memory pool for supplied dimension dim.
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)
Derivative array storage class using dynamic memory allocation.
EParseCommandLineReturn parse(int argc, char *argv[], std::ostream *errout=&std::cerr) const
void setDocString(const char doc_string[])
Forward-mode AD class using dynamic memory allocation and expression templates.