source: releases/20180000.0/speed/main.cpp @ 3999

Last change on this file since 3999 was 3980, checked in by bradbell, 22 months ago

merge to branch: trunk
from repository: https://github.com/coin-or/CppAD
start hash code: 8c00eba5a1d917cdec656feee262fccc40ab9221
end hash code: aafa1ece9306ff869c9003e176ac4e853d37f908

commit aafa1ece9306ff869c9003e176ac4e853d37f908
Author: Brad Bell <bradbell@…>
Date: Wed Nov 22 19:36:54 2017 -0700

Advance to cppad-20171122.

commit f1c34431355e2bac9193003d6dacab37946ab16a
Author: Brad Bell <bradbell@…>
Date: Wed Nov 22 19:36:07 2017 -0700

subgraph.cpp: test optimization and CSum operator.

commit e7d5b16ea64bad1d450da1a0542cd36c7cca9cc5
Author: Brad Bell <bradbell@…>
Date: Wed Nov 22 07:26:55 2017 -0700

tmb branch:
subgraph_reverse.cpp: fix another warning.

commit 74ff017b5a805fd160f0fabfd04579c8483319f4
Author: Brad Bell <bradbell@…>
Date: Wed Nov 22 06:22:53 2017 -0700

tmb branch:
Store mapping from operator to arguments that are variables (dont recalculate).

commit 4fe94f596c29b0f15ab74a548d60f3d3a9aa9454
Author: Brad Bell <bradbell@…>
Date: Wed Nov 22 05:48:42 2017 -0700

tmb branch:
Put vector_of_sets concept in doxygen comments.

commit 29ad16bb1c3012130685f5ea672e2b82ac43024f
Author: Brad Bell <bradbell@…>
Date: Wed Nov 22 05:32:20 2017 -0700

tmb branch:
Fix some warnings.

commit fbf576b2a7530581b54526afbe75cf9b3d40d32b
Author: Brad Bell <bradbell@…>
Date: Wed Nov 22 03:52:08 2017 -0700

tmb branch:
Document CppAD vector_of_sets concept in comments of sparse_list, sparse_pack.

commit 6e3ec07cb063a35021d9268bfa8af633a891c7b1
Author: Brad Bell <bradbell@…>
Date: Wed Nov 22 03:49:55 2017 -0700

tmb branch:
Add n_var to subgraph_info constructor.

commit fe489babbe92f81fb0c60deb7385948abff135a8
Author: Brad Bell <bradbell@…>
Date: Tue Nov 21 08:25:36 2017 -0700

tmb branch:
Add f.subgraph_jac_rev(select_domain, select_range, x, matrix_out) syntax.
batch_edit.sh: add plan for batch editing entire source.

commit 17f76b0b690382d8d8fdfa5a6b232cdc159cb731
Author: Brad Bell <bradbell@…>
Date: Tue Nov 21 06:26:26 2017 -0700

tmb branch:
Change subtraph_reverse so it only returns values on the subgraph.

commit 2f17af1ad9bc9be7230f4291f4f598ce21f1ab87
Author: Brad Bell <bradbell@…>
Date: Mon Nov 20 09:32:29 2017 -0700

tmb branch:
run_cmake.sh: add --callgrind option.

commit b94180d375e8cb41986262e70e54efafc3e3f9d2
Author: Brad Bell <bradbell@…>
Date: Mon Nov 20 07:19:02 2017 -0700

tmb branch:
Change grad2hes -> hes2jac (Hessaian as Jacobian of gradient).
subgraph_reverse.hpp: fix include guard.
whats_new_17.omh: mention subgraph speed test option.

commit f7bb8cfad71b5533bb88de45811dc69aa1f469e3
Author: Brad Bell <bradbell@…>
Date: Mon Nov 20 06:44:50 2017 -0700

tmb branch:
Add the subgraph option to the speed tests.

commit 0540eb87b13eb20403d99e3e349e2b952c141f8d
Author: Brad Bell <bradbell@…>
Date: Mon Nov 20 04:08:48 2017 -0700

tmb branch:
whats_new_17.omh: user's view of recent changes.

commit fad7d9c9e4f8cefc96343f3c091ef945cadcbf30
Author: Brad Bell <bradbell@…>
Date: Mon Nov 20 03:55:46 2017 -0700

tmb branch:
Move reverse_subgraph -> subgraph_reverse.

commit 929107231925d63c8757916d1ef83aa248305508
Author: Brad Bell <bradbell@…>
Date: Mon Nov 20 03:42:33 2017 -0700

tmb branch:
Add the subgraph_jac_rev routine.

commit d311e2d806b91f4c3218148c7da0b97492a14c58
Author: Brad Bell <bradbell@…>
Date: Sun Nov 19 17:59:08 2017 -0700

tmb branch:
Avoid having to initialize all independent variable partials to zero.

commit eb678b868ad604c30f47cb5649c8273179bfc1af
Author: Brad Bell <bradbell@…>
Date: Sun Nov 19 09:30:28 2017 -0700

tmb branch:
reverse_subgraph.hpp: fix bug in initialization of Partial.
sparsity.hpp: fix warning.
subgraph.cpp: more testing of reverse_subgraph.

commit 86c3747ba7574126ebfd75ba87926e5446334d6b
Author: Brad Bell <bradbell@…>
Date: Sun Nov 19 07:53:06 2017 -0700

tmb branch:
reverse_subgraph.cpp: account for roundoff error.

commit 263ef99d6304f9aefd253f8eb90b32a1e76814c4
Author: Brad Bell <bradbell@…>
Date: Sun Nov 19 07:14:48 2017 -0700

tmb branch:
Move in test directory subgraph_sparsity.cpp -> subgraph.cpp (will add other tests).
reverse_subgraph.hpp: fix warning when NDEBUG is defined.

commit 27baa8f5d0c8a840401e9b8d78c2f8b17a373100
Author: Brad Bell <bradbell@…>
Date: Sun Nov 19 06:59:52 2017 -0700

tmb branch:
whats_new_17.omh: inform user of new reverse_subgraph routine.

commit 230b1789f9bb84ad5e6007ef7294ec1d41708be1
Author: Brad Bell <bradbell@…>
Date: Sun Nov 19 06:54:52 2017 -0700

tmb branch:
First version of reverse_subgraph that passes an example / test.
reverse.hpp: was skiping first operator in subgraph (fixed).
sparse_jac_for.cpp: improve section title.
sparse_jac_rev.cpp: improve section title.

commit f175aded81e86375ae591979b635dff6235d9875
Author: Brad Bell <bradbell@…>
Date: Sun Nov 19 05:51:33 2017 -0700

tmb branch:
reverse_subgraph.hpp: add doxygen documentation.

commit 4b2ef5cfdc3d7cf16e32f9cbe9963a3ac97ed974
Author: Brad Bell <bradbell@…>
Date: Sun Nov 19 05:26:17 2017 -0700

tmb branch:
Add reverse_subgraph user API routine (Under construction).

commit 0ffa1a38fb88dd75bb95951630205f81ba62ff2d
Author: Brad Bell <bradbell@…>
Date: Sun Nov 19 04:37:14 2017 -0700

tmb branch:
makefile.am: add missing autotools file.

commit 217b613adb01ffbcf0cf17ee56fda83e14bf409e
Author: Brad Bell <bradbell@…>
Date: Sun Nov 19 04:02:18 2017 -0700

tmb branch:
Add select_domain and process_range to subgraph_info.

commit 8ec30f9702d5f3702f30b01f3b2d6c85385f7889
Author: Brad Bell <bradbell@…>
Date: Sat Nov 18 18:12:37 2017 -0700

tmb branch:
Add processed_ to subgraph_info (check for user error).

commit 12292f41d9f980b43af129b92487c7425cf71319
Author: Brad Bell <bradbell@…>
Date: Sat Nov 18 17:12:01 2017 -0700

tmb branch:
make get_rev_subgraph a subgraph_info member function.

commit 13683f1cb5ed4710a081db9a700e38ad7dcf41e7
Author: Brad Bell <bradbell@…>
Date: Sat Nov 18 16:43:38 2017 -0700

tmb branch:
move in_subgraph.hpp -> init_rev.hpp.

commit ac4029cca2f609f559825c0f5f8a3dd17c2d6333
Author: Brad Bell <bradbell@…>
Date: Sat Nov 18 16:38:04 2017 -0700

tmb branch:
Move init_rev_in_subgraph to separate file.

commit f07ba2423f79e4ca6165a8d4931e85a2a25b7aba
Author: Brad Bell <bradbell@…>
Date: Sat Nov 18 16:06:26 2017 -0700

tmb branch:
batch_edit.sh: add an item to the edit all files plan.
subgraph_sparsity.hpp: Change Pupose -> Notation.
reverse_any.omh: white space edit.
sparsity.hpp: remove unecessary type conversion.

commit 12a190dde560165bc09d07a49e77658500a6ddc6
Author: Brad Bell <bradbell@…>
Date: Sat Nov 18 06:46:29 2017 -0700

tmb branch:
makefile.am: fix autotools build.

commit 4f267a067776765508ee7a80583bc58135925376
Author: Brad Bell <bradbell@…>
Date: Sat Nov 18 06:41:19 2017 -0700

tmb branch:
Split subgraph.hpp into separate files.

commit 26f5013b490effd3c0ff24d0bbc0693b8f675b1e
Author: Brad Bell <bradbell@…>
Date: Sat Nov 18 06:03:43 2017 -0700

tmb branch:

  1. use depend_no, depend_yes in documnetation
  2. fix warning depend_no not used.

commit e4509d788d5890d61f044ae0019cecae37016ef2
Author: Brad Bell <bradbell@…>
Date: Sat Nov 18 05:30:44 2017 -0700

tmb branch:
Move subgraph operations into a separate namespace / directory.

commit 006c120f351ec63b2b8dc1b6767146026c5b232f
Author: Brad Bell <bradbell@…>
Date: Sat Nov 18 05:13:54 2017 -0700

tmb branch:
subgraph.hpp: move argument_variable to top, fix doxygen \return.

commit 1b8f8702e34ba21281d2ad9a7de11016ad108d9a
Author: Brad Bell <bradbell@…>
Date: Sat Nov 18 05:03:48 2017 -0700

tmb branch:
subgraph.hpp: move in_subgraph to f.subgraph_info.

commit 285b29a4514ae0ed31c0edf96abdc883fdcd06e4
Author: Brad Bell <bradbell@…>
Date: Sat Nov 18 04:21:44 2017 -0700

tmb branch:
subgraph.hpp: move map_op_user into f.subgraph_info_.

commit 5d8dccdd1168b2ecf4f0c747852d565f43ff316e
Author: Brad Bell <bradbell@…>
Date: Sat Nov 18 03:57:26 2017 -0700

tmb branch:
subgraph.hpp: add map_user_op setter and getter.

commit 921cd6ecf699001cd3577bb90da7ad70541dd4fe
Author: Brad Bell <bradbell@…>
Date: Fri Nov 17 20:21:36 2017 -0700

tmb branch:
pass subgraph_info into subgraph_sparsity routine.

commit b50235776b872701d1f60af0a01cbcf9f011eebf
Author: Brad Bell <bradbell@…>
Date: Fri Nov 17 12:57:46 2017 -0700

tmb branch:
create subgrah_info class.

commit e41e5a797613bdc630e780f67ccf59632373db82
Author: Brad Bell <bradbell@…>
Date: Fri Nov 17 10:51:21 2017 -0700

tmb branch:
subgraph.hpp: split out adding entire call to subgraph.

commit 0dbda000e88f08db30c33f9fc8d260a1eaa71584
Author: Brad Bell <bradbell@…>
Date: Fri Nov 17 09:41:32 2017 -0700

tmb branch:
Add subgraph indexing to reverse_sweep.

commit ec47c8179edf5b4bd1cc8af741a41c7cc089b998
Author: Brad Bell <bradbell@…>
Date: Fri Nov 17 05:03:01 2017 -0700

tmb branch:
Fix lenght -> length.

commit 41ff2402b0a61b3e4e6e5f01dee12ae93513c92b
Author: Brad Bell <bradbell@…>
Date: Fri Nov 17 05:00:31 2017 -0700

tmb branch:
Move checking location of InvOp? into player::get(recoding, n_ind).

commit 0c70d08670cd09382ed8325d398ecbf71de2516f
Author: Brad Bell <bradbell@…>
Date: Fri Nov 17 04:22:35 2017 -0700

tmb branch:
subgraph.hpp: use rev_subgraph to signify reverse mode subgraphs.

commit 4c64339558af8d8f150702dbdf33a40a1855469c
Author: Brad Bell <bradbell@…>
Date: Fri Nov 17 03:51:00 2017 -0700

tmb branch:
Change rev_jac_subgraph -> subgraph_sparsity.

commit b6f59cbc22b3a069edfed1912db5ed988b1ae059
Merge: d7d0da2b 8c00eba5
Author: Brad Bell <bradbell@…>
Date: Fri Nov 17 03:12:47 2017 -0700

Merge 'master' fix of autools build into tmb

  • Property svn:keywords set to Id
File size: 22.4 KB
Line 
1/* --------------------------------------------------------------------------
2CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-17 Bradley M. Bell
3
4CppAD is distributed under multiple licenses. This distribution is under
5the terms of the
6                    Eclipse Public License Version 1.0.
7
8A copy of this license is included in the COPYING file of this distribution.
9Please visit http://www.coin-or.org/CppAD/ for information on other licenses.
10-------------------------------------------------------------------------- */
11
12# include <cstring>
13# include <cstdlib>
14# include <cassert>
15# include <cstddef>
16# include <iostream>
17# include <iomanip>
18# include <map>
19# include <cppad/utility/vector.hpp>
20# include <cppad/speed/det_grad_33.hpp>
21# include <cppad/speed/det_33.hpp>
22# include <cppad/utility/time_test.hpp>
23# include <cppad/speed/uniform_01.hpp>
24# include <cppad/utility/poly.hpp>
25# include <cppad/utility/track_new_del.hpp>
26# include <cppad/utility/thread_alloc.hpp>
27
28# ifdef CPPAD_ADOLC_SPEED
29# define AD_PACKAGE "adolc"
30# endif
31# ifdef CPPAD_CPPAD_SPEED
32# define AD_PACKAGE "cppad"
33# endif
34# ifdef CPPAD_DOUBLE_SPEED
35# define AD_PACKAGE "double"
36# endif
37# ifdef CPPAD_FADBAD_SPEED
38# define AD_PACKAGE "fadbad"
39# endif
40# ifdef CPPAD_PROFILE_SPEED
41# define AD_PACKAGE "profile"
42# endif
43# ifdef CPPAD_SACADO_SPEED
44# define AD_PACKAGE "sacado"
45# endif
46
47/*
48$begin speed_main$$
49$spell
50        jac
51        subgraph
52        Jacobians
53        hes
54        subgraphs
55        subsparsity
56        revsparsity
57        colpack
58        onetape
59        boolsparsity
60        optionlist
61        underbar
62        alloc
63        mat_mul
64        retaped
65        bool
66        ddp
67        cppad
68        adolc
69        fadbad
70        sacado
71        CppAD
72        det
73        lu
74        Jacobian
75$$
76
77
78$section Running the Speed Test Program$$
79$mindex cppad uniform_01$$
80
81$head Syntax$$
82$codei%speed/%package%/speed_%package% %test% %seed% %option_list%$$
83
84$head Purpose$$
85A version of this program runs the correctness tests
86or the speed tests for one AD package identified by $icode package$$.
87
88$head package$$
89
90$subhead AD Package$$
91The command line argument
92$icode package$$ specifies one of the AD package.
93The CppAD distribution comes with support for the following packages:
94$cref/adolc/speed_adolc/$$,
95$cref/cppad/speed_cppad/$$,
96$cref/fadbad/speed_fadbad/$$,
97$cref/sacado/speed_sacado/$$.
98You can extend this program to include other package.
99Such an extension need not include all the tests.
100For example,
101$cref link_sparse_hessian$$ just returns $code false$$ for the
102$cref/fadbad/fadbad_sparse_hessian.cpp/$$ and
103$cref/sacado/sacado_sparse_hessian.cpp/$$ packages.
104
105
106$subhead double$$
107The value
108$icode package$$ can be $code double$$ in which case
109the function values (instead of derivatives) are computed
110using double precision operations.
111This enables one to compare the speed of computing function
112values in $code double$$ to the speed of the derivative computations.
113(It is often useful to divide the speed of the derivative computation by
114the speed of the function evaluation in $code double$$.)
115
116$subhead profile$$
117In the special case where $icode package$$ is $code profile$$,
118the CppAD package is compiled and run with profiling to aid in determining
119where it is spending most of its time.
120
121$head test$$
122It the argument $icode test$$ specifies which test to run
123and has the following possible values:
124$cref/correct/speed_main/test/correct/$$,
125$cref/speed/speed_main/test/speed/$$,
126$cref/det_minor/link_det_minor/$$,
127$cref/det_lu/link_det_lu/$$,
128$cref/mat_mul/link_mat_mul/$$,
129$cref/ode/link_ode/$$,
130$cref/poly/link_poly/$$,
131$cref/sparse_hessian/link_sparse_hessian/$$,
132$cref/sparse_jacobian/link_sparse_jacobian/$$.
133You can experiment with changing the implementation of a
134particular test for a particular package.
135
136$subhead correct$$
137If $icode test$$ is equal to $code correct$$,
138all of the correctness tests are run.
139
140$subhead speed$$
141If $icode test$$ is equal to $code speed$$,
142all of the speed tests are run.
143
144$head seed$$
145The command line argument $icode seed$$ is an unsigned integer
146(all its characters are between 0 and 9).
147The random number simulator $cref uniform_01$$ is initialized with
148the call
149$codei%
150        uniform_01(%seed%)
151%$$
152before any of the testing routines (listed above) are called.
153
154$head Global Options$$
155This global variable has prototype
156$srccode%cpp%
157        extern std::map<std::string, bool> global_option;
158%$$
159The syntax
160$codei%
161        global_option["%option%"]
162%$$
163has the value true, if $icode option$$ is present,
164and false otherwise.
165This is true for each option that follows $icode seed$$.
166The order of the options does not matter and the list can be empty.
167Each option, is be a separate command line argument to the main program.
168The documentation below specifics how
169$cref speed_cppad$$ uses these options,
170see the examples in $cref speed_adolc$$ for how another package might
171uses these options.
172
173$subhead onetape$$
174If this option is present,
175$cref speed_cppad$$ will use one taping of the operation
176sequence for all the repetitions of that speed test.
177Otherwise, the
178$cref/operation sequence/glossary/Operation/Sequence/$$
179will be retaped for each test repetition.
180$pre
181
182$$
183All of the tests, except $cref/det_lu/link_det_lu/$$,
184have the same operation sequence for each repetition.
185The operation sequence for $code det_lu$$
186may be different because it depends on the matrix for which the determinant
187is being calculated.
188For this reason, $cref cppad_det_lu.cpp$$ returns false,
189to indicate that the test not implemented,
190when $code global_onetape$$ is true.
191
192$subhead memory$$
193This option is special because individual CppAD speed tests need not do
194anything different if this option is true or false.
195If the $code memory$$ option is present, the CppAD
196$cref/hold_memory/ta_hold_memory/$$ routine will be called by
197the speed test main program before any of the tests are executed
198This should make the CppAD $code thread_alloc$$ allocator faster.
199If it is not present, CppAD will used standard memory allocation.
200Another package might use this option for a different
201memory allocation method.
202
203$subhead optimize$$
204If this option is present,
205CppAD will $cref optimize$$
206the operation sequence before doing computations.
207If it is false, this optimization will not be done.
208Note that this option is usually slower unless it is combined with the
209$code onetape$$ option.
210
211$subhead atomic$$
212If this option is present,
213CppAD will use a user defined
214$cref/atomic/atomic_base/$$ operation is used for the test.
215So far, CppAD has only implemented
216the $cref/mat_mul/link_mat_mul/$$ test as an atomic operation.
217
218$subhead hes2jac$$
219If this option is present,
220$cref speed_cppad$$ will compute hessians as the Jacobian
221of the gradient.
222This is accomplished using
223$cref/multiple levels/mul_level/$$ of AD.
224So far, CppAD has only implemented
225the $cref/sparse_hessian/link_sparse_hessian/$$
226test in this manner.
227
228$subhead subgraph$$
229If this option is present,
230$cref speed_cppad$$ will compute sparse Jacobians using subgraphs.
231The CppAD $cref/sparse_jacobian/link_sparse_jacobian/$$
232test is implemented for this option.
233In addition, the CppAD $cref/sparse_hessian/link_sparse_hessian/$$
234test is implemented for this option when $code hes2jac$$ is present.
235
236$head Sparsity Options$$
237The following options only apply to the
238$cref/sparse_jacobian/link_sparse_jacobian/$$ and
239$cref/sparse_hessian/link_sparse_hessian/$$ tests.
240The other tests return false when any of these options
241are present.
242
243$subhead boolsparsity$$
244If this option is present, CppAD will use a
245$cref/vectors of bool/glossary/Sparsity Pattern/Boolean Vector/$$
246to compute sparsity patterns.
247Otherwise CppAD will use
248$cref/vectors of sets/glossary/Sparsity Pattern/Vector of Sets/$$.
249
250$subhead revsparsity$$
251If this option is present,
252CppAD will use reverse mode for to compute sparsity patterns.
253Otherwise CppAD will use forward mode.
254
255$subhead subsparsity$$
256If this option is present,
257CppAD will use subgraphs to compute sparsity patterns.
258If either the $code boolsparsity$$ or $code revsparsity$$ is also present,
259the CppAD speed tests will return false; i.e., these options are not
260supported by $cref subgraph_sparsity$$.
261
262$subhead colpack$$
263If this option is present,
264CppAD will use $cref/colpack/colpack_prefix/$$ to do the coloring.
265Otherwise, it will use it's own coloring algorithm.
266
267$head Correctness Results$$
268One, but not both, of the following two output lines
269$codei%
270        %package%_%test%_%optionlist%_available = false
271        %package%_%test%_%optionlist%_ok = %flag%
272%$$
273is generated for each correctness test where
274$icode package$$ and $icode test$$ are as above,
275$icode optionlist$$ are the options (in $icode option_list$$)
276separated by the underbar $code _$$ character
277(whereas they are separated by spaces in $icode option_list$$),
278and $icode flag$$ is $code true$$ or $code false$$.
279
280$head Speed Results$$
281For each speed test, corresponds to three lines of the
282following form are generated:
283$codei%
284        %package%_%test%_%optionlist%_ok   = %flag%
285        %package%_%test%_size = [ %size_1%, %...%, %size_n% ]
286        %package%_%test%_rate = [ %rate_1%, %...%, %rate_n% ]
287%$$
288The values $icode package$$, $icode test$$, $icode optionlist$$,
289and $icode flag$$ are as in the correctness results above.
290The values $icode size_1$$, ..., $icode size_n$$ are the
291size arguments used for the corresponding tests.
292The values $icode rate_1$$, ..., $icode rate_n$$ are the number of times
293per second that the corresponding size problem executed.
294
295$subhead n_sweep$$
296The $cref/sparse_jacobian/link_sparse_jacobian/$$
297and $cref/sparse_hessian/link_sparse_hessian/$$ tests has an extra output
298line with the following form
299$codei%
300        %package%_sparse_%test%_n_sweep = [ %n_sweep_1%, %...%, %n_sweep_n% ]
301%$$
302were $icode test$$ is $code jacobian$$ ($code hessian$$).
303The values $icode n_sweep_1$$, ..., $icode n_sweep_n$$ are the number of
304sweeps (colors) used for each sparse Jacobian (Hessian) calculation; see
305$icode n_sweep$$ for
306$cref/sparse_jacobian/sparse_jacobian/n_sweep/$$ and
307$cref/sparse_hessian/sparse_hessian/n_sweep/$$.
308
309
310$children%
311        speed/src/link_det_lu.cpp%
312        speed/src/link_det_minor.cpp%
313        speed/src/link_mat_mul.cpp%
314        speed/src/link_ode.cpp%
315        speed/src/link_poly.cpp%
316        speed/src/link_sparse_hessian.cpp%
317        speed/src/link_sparse_jacobian.cpp%
318        speed/src/microsoft_timer.cpp
319%$$
320
321$head Link Functions$$
322Each $cref/package/speed_main/package/$$
323defines it's own version of one of the link functions listed below.
324Each of these functions links this main program to the corresponding test:
325$table
326$rref link_det_lu$$
327$rref link_det_minor$$
328$rref link_mat_mul$$
329$rref link_ode$$
330$rref link_poly$$
331$rref link_sparse_hessian$$
332$rref link_sparse_jacobian$$
333$tend
334
335
336$end
337-----------------------------------------------------------------------------
338*/
339// external routines
340
341# define CPPAD_DECLARE_SPEED(name)                       \
342     extern bool available_##name(void);                 \
343     extern bool correct_##name(bool is_package_double); \
344     extern void speed_##name(size_t size, size_t repeat)
345
346CPPAD_DECLARE_SPEED(det_lu);
347CPPAD_DECLARE_SPEED(det_minor);
348CPPAD_DECLARE_SPEED(mat_mul);
349CPPAD_DECLARE_SPEED(ode);
350CPPAD_DECLARE_SPEED(poly);
351CPPAD_DECLARE_SPEED(sparse_hessian);
352CPPAD_DECLARE_SPEED(sparse_jacobian);
353
354// info is different for each test
355extern void info_sparse_jacobian(size_t size, size_t& n_sweep);
356extern void info_sparse_hessian(size_t size, size_t& n_sweep);
357
358// --------------------------------------------------------------------------
359std::map<std::string, bool> global_option;
360// --------------------------------------------------------------------------
361
362
363namespace {
364        using std::cout;
365        using std::endl;
366        const char* option_list[] = {
367                "memory",
368                "onetape",
369                "optimize",
370                "atomic",
371                "hes2jac",
372                "subgraph",
373                "boolsparsity",
374                "revsparsity",
375                "subsparsity",
376                "colpack"
377        };
378        size_t num_option = sizeof(option_list) / sizeof( option_list[0] );
379        // ----------------------------------------------------------------
380        // not available test message
381        void not_available_message(const char* test_name)
382        {       cout << AD_PACKAGE << ": " << test_name;
383                cout << " is not availabe with " << endl;
384                int max_len = 0;
385                for(size_t i = 0; i < num_option; i++)
386                {       int len = int( std::strlen( option_list[i] ) );
387                        max_len = std::max( max_len, len);
388                }
389                for(size_t i = 0; i < num_option; i++)
390                {       std::string option = option_list[i];
391                        if( global_option[option] )
392                                cout << std::setw(max_len + 1) << option << " = true\n";
393                        else
394                                cout << std::setw(max_len + 1) << option << " = false\n";
395                }
396        }
397        // ------------------------------------------------------
398        // output vector in form readable by octave or matlab
399        // convert size_t to int to avoid warning by MS compiler
400        void output(const CppAD::vector<size_t> &v)
401        {       size_t i= 0, n = v.size();
402                cout << "[ ";
403                while(i < n)
404                {       cout << int(v[i++]);
405                        if( i < n )
406                                cout << ", ";
407                }
408                cout << " ]";
409        }
410
411        // ----------------------------------------------------------------
412        // function that runs one correctness case
413        static size_t Run_ok_count    = 0;
414        static size_t Run_error_count = 0;
415        bool run_correct(
416                bool available_case(void) ,
417                bool correct_case(bool)   ,
418                const char *case_name     )
419        {       bool available = available_case();
420                bool ok        = true;
421                if( available )
422                {
423# ifdef CPPAD_DOUBLE_SPEED
424                        ok = correct_case(true);
425# else
426                        ok = correct_case(false);
427# endif
428                }
429                cout << AD_PACKAGE << "_" << case_name;
430                for(size_t i = 0; i < num_option; i++)
431                {       std::string option = option_list[i];
432                        if( global_option[option]  )
433                                cout << "_" << option;
434                }
435                if( ! available )
436                {       cout << "_available = false" << endl;
437                        return ok;
438                }
439                cout << "_ok = ";
440                if( ok )
441                {       cout << " true" << endl;
442                        Run_ok_count++;
443                }
444                else
445                {       cout << " false" << endl;
446                        Run_error_count++;
447                }
448                return ok;
449        }
450        // ----------------------------------------------------------------
451        // function that runs one speed case
452        void run_speed(
453                void speed_case(size_t size, size_t repeat) ,
454                const CppAD::vector<size_t>&       size_vec ,
455                const std::string&                case_name )
456        {       double time_min = 1.;
457                cout << AD_PACKAGE << "_" << case_name << "_size = ";
458                output(size_vec);
459                cout << endl;
460                cout << AD_PACKAGE << "_" << case_name << "_rate = ";
461                cout << std::fixed;
462                for(size_t i = 0; i < size_vec.size(); i++)
463                {       if( i == 0 )
464                                cout << "[ ";
465                        else    cout << ", ";
466                        cout << std::flush;
467                        size_t size = size_vec[i];
468                        double time = CppAD::time_test(speed_case, time_min, size);
469                        double rate = 1. / time;
470                        if( rate >= 1000 )
471                                cout << std::setprecision(0) << rate;
472                        else cout << std::setprecision(2) << rate;
473                }
474                cout << " ]" << endl;
475                //
476                // free statically allocated memory (size = repeat = 0)
477                speed_case(0, 0);
478                return;
479        }
480}
481
482// main program that runs all the tests
483int main(int argc, char *argv[])
484{       bool ok = true;
485        enum test_enum {
486                test_correct,
487                test_speed,
488                test_det_lu,
489                test_det_minor,
490                test_mat_mul,
491                test_ode,
492                test_poly,
493                test_sparse_hessian,
494                test_sparse_jacobian,
495                test_error
496        };
497        struct test_struct {
498                const char       *name;
499                const test_enum  index;
500        };
501        const test_struct test_list[]= {
502                { "correct",            test_correct         },
503                { "speed",              test_speed           },
504                { "det_lu",             test_det_lu          },
505                { "det_minor",          test_det_minor       },
506                { "mat_mul",            test_mat_mul         },
507                { "ode",                test_ode             },
508                { "poly",               test_poly            },
509                { "sparse_hessian",     test_sparse_hessian  },
510                { "sparse_jacobian",    test_sparse_jacobian }
511        };
512        const size_t n_test  = sizeof(test_list) / sizeof(test_list[0]);
513
514        test_enum match = test_error;
515        int    iseed = 0;
516        bool   error = argc < 3;
517        if( ! error )
518        {       for(size_t i = 0; i < n_test; i++)
519                        if( strcmp(test_list[i].name, argv[1]) == 0 )
520                                match = test_list[i].index;
521                error = match == test_error;
522                for(size_t i = 0; *(argv[2] + i) != '\0'; ++i)
523                {       error |= *(argv[2] + i) < '0';
524                        error |= '9' < *(argv[2] + i);
525                }
526                iseed = std::atoi( argv[2] );
527                error |= iseed < 0;
528                for(size_t i = 0; i < num_option; i++)
529                        global_option[ option_list[i] ] = false;
530                for(size_t i = 3; i < size_t(argc); i++)
531                {       bool found = false;
532                        for(size_t j = 0; j < num_option; j++)
533                        {       if( strcmp(argv[i], option_list[j]) == 0 )
534                                {       global_option[ option_list[j] ] = true;
535                                        found = true;
536                                }
537                        }
538                        error |= ! found;
539                }
540        }
541        if( error )
542        {       cout << "usage: ./speed_"
543                     << AD_PACKAGE << " test seed option_list" << endl;
544                cout << "test choices:";
545                for(size_t i = 0; i < n_test; i++)
546                {       if( i % 5 == 0 )
547                                std::cout << "\n\t";
548                        else
549                                std::cout << ", ";
550                        cout << test_list[i].name;
551                }
552                cout << "\n\nseed: is a positive integer used as a random seed.";
553                cout << "\n\noption_list: zero or more of the following:";
554                for(size_t i = 0; i < num_option; i++)
555                {       if( i % 5 == 0 )
556                                std::cout << "\n\t";
557                        else
558                                std::cout << ", ";
559                        cout << option_list[i];
560                }
561                cout << endl << endl;
562                return 1;
563        }
564        if( global_option["memory"] )
565                CppAD::thread_alloc::hold_memory(true);
566
567        // initialize the random number simulator
568        CppAD::uniform_01(size_t(iseed));
569
570        // arguments needed for speed tests
571        size_t n_size   = 5;
572        CppAD::vector<size_t> size_det_lu(n_size);
573        CppAD::vector<size_t> size_det_minor(n_size);
574        CppAD::vector<size_t> size_mat_mul(n_size);
575        CppAD::vector<size_t> size_ode(n_size);
576        CppAD::vector<size_t> size_poly(n_size);
577        CppAD::vector<size_t> size_sparse_hessian(n_size);
578        CppAD::vector<size_t> size_sparse_jacobian(n_size);
579        for(size_t i = 0; i < n_size; i++)
580        {       size_det_minor[i]   = i + 1;
581                size_det_lu[i]      = 10 * i + 1;
582                size_mat_mul[i]     = 10 * i + 1;
583                size_ode[i]         = 10 * i + 1;
584                size_poly[i]        = 10 * i + 1;
585                size_sparse_hessian[i]  = 150 * (i + 1) * (i + 1);
586                size_sparse_jacobian[i] = 150 * (i + 1) * (i + 1);
587        }
588
589        switch(match)
590        {
591                // run all the correctness tests
592                case test_correct:
593                ok &= run_correct( available_det_lu, correct_det_lu, "det_lu"
594                );
595                ok &= run_correct(
596                        available_det_minor, correct_det_minor, "det_minor"
597                );
598                ok &= run_correct(
599                        available_mat_mul, correct_mat_mul, "mat_mul"
600                );
601                ok &= run_correct(
602                        available_ode, correct_ode, "ode"
603                );
604                ok &= run_correct( available_poly, correct_poly, "poly"
605                );
606                ok &= run_correct(
607                        available_sparse_hessian,
608                        correct_sparse_hessian,
609                        "sparse_hessian"
610                );
611                ok &= run_correct(
612                        available_sparse_jacobian,
613                        correct_sparse_jacobian,
614                        "sparse_jacobian"
615                );
616                // summarize results
617                assert( ok || (Run_error_count > 0) );
618                if( ok )
619                {       cout    << "All " << int(Run_ok_count)
620                                << " correctness tests passed." << endl;
621                }
622                else
623                {       cout    << int(Run_error_count)
624                                << " correctness tests failed." << endl;
625                }
626                break;
627                // ---------------------------------------------------------
628                // run all the speed tests
629                case test_speed:
630                if( available_det_lu() ) run_speed(
631                speed_det_lu,          size_det_lu,          "det_lu"
632                );
633                if( available_det_minor() ) run_speed(
634                speed_det_minor,       size_det_minor,       "det_minor"
635                );
636                if( available_mat_mul() ) run_speed(
637                speed_mat_mul,           size_mat_mul,       "mat_mul"
638                );
639                if( available_ode() ) run_speed(
640                speed_ode,             size_ode,             "ode"
641                );
642                if( available_poly() ) run_speed(
643                speed_poly,            size_poly,            "poly"
644                );
645                if( available_sparse_hessian() ) run_speed(
646                speed_sparse_hessian,  size_sparse_hessian,  "sparse_hessian"
647                );
648                if( available_sparse_jacobian() ) run_speed(
649                speed_sparse_jacobian, size_sparse_jacobian, "sparse_jacobian"
650                );
651                ok = true;
652                break;
653                // ---------------------------------------------------------
654
655                case test_det_lu:
656                if( ! available_det_lu() )
657                {       not_available_message( argv[1] );
658                        exit(1);
659                }
660                ok &= run_correct(
661                        available_det_lu, correct_det_lu, "det_lu")
662                ;
663                run_speed(speed_det_lu,    size_det_lu,     "det_lu");
664                break;
665                // ---------------------------------------------------------
666
667                case test_det_minor:
668                if( ! available_det_minor() )
669                {       not_available_message( argv[1] );
670                        exit(1);
671                }
672                ok &= run_correct(
673                        available_det_minor, correct_det_minor, "det_minor"
674                );
675                run_speed(speed_det_minor, size_det_minor, "det_minor");
676                break;
677                // ---------------------------------------------------------
678
679                case test_mat_mul:
680                if( ! available_mat_mul() )
681                {       not_available_message( argv[1] );
682                        exit(1);
683                }
684                ok &= run_correct(
685                        available_mat_mul, correct_mat_mul, "mat_mul"
686                );
687                run_speed(speed_mat_mul, size_mat_mul, "mat_mul");
688                break;
689                // ---------------------------------------------------------
690
691                case test_ode:
692                if( ! available_ode() )
693                {       not_available_message( argv[1] );
694                        exit(1);
695                }
696                ok &= run_correct(
697                        available_ode, correct_ode, "ode"
698                );
699                run_speed(speed_ode,      size_ode,      "ode");
700                break;
701                // ---------------------------------------------------------
702
703                case test_poly:
704                if( ! available_poly() )
705                {       not_available_message( argv[1] );
706                        exit(1);
707                }
708                ok &= run_correct(
709                        available_poly, correct_poly, "poly"
710                );
711                run_speed(speed_poly,      size_poly,      "poly");
712                break;
713                // ---------------------------------------------------------
714
715                case test_sparse_hessian:
716                if( ! available_sparse_hessian() )
717                {       not_available_message( argv[1] );
718                        exit(1);
719                }
720                ok &= run_correct(
721                        available_sparse_hessian,
722                        correct_sparse_hessian,
723                        "sparse_hessian"
724                );
725                run_speed(
726                        speed_sparse_hessian, size_sparse_hessian,  "sparse_hessian"
727                );
728                cout << AD_PACKAGE << "_sparse_hessian_sweep = ";
729                for(size_t i = 0; i < size_sparse_hessian.size(); i++)
730                {       if( i == 0 )
731                                cout << "[ ";
732                        else    cout << ", ";
733                        size_t n_sweep;
734                        info_sparse_hessian(size_sparse_hessian[i], n_sweep);
735                        cout << n_sweep;
736                }
737                cout << " ]" << endl;
738                break;
739                // ---------------------------------------------------------
740
741                case test_sparse_jacobian:
742                if( ! available_sparse_jacobian() )
743                {       not_available_message( argv[1] );
744                        exit(1);
745                }
746                ok &= run_correct(
747                        available_sparse_jacobian,
748                        correct_sparse_jacobian,
749                        "sparse_jacobian"
750                );
751                run_speed(
752                        speed_sparse_jacobian, size_sparse_jacobian, "sparse_jacobian"
753                );
754                cout << AD_PACKAGE << "_sparse_jacobian_n_sweep = ";
755                for(size_t i = 0; i < size_sparse_jacobian.size(); i++)
756                {       if( i == 0 )
757                                cout << "[ ";
758                        else    cout << ", ";
759                        size_t n_sweep;
760                        info_sparse_jacobian(size_sparse_jacobian[i], n_sweep);
761                        cout << n_sweep;
762                }
763                cout << " ]" << endl;
764                break;
765                // ---------------------------------------------------------
766
767                default:
768                assert(0);
769        }
770# ifndef NDEBUG
771        // return memory for vectors that are still in scope
772        size_det_lu.clear();
773        size_det_minor.clear();
774        size_mat_mul.clear();
775        size_ode.clear();
776        size_poly.clear();
777        size_sparse_hessian.clear();
778        size_sparse_jacobian.clear();
779        // check for memory leak
780        if( CppAD::thread_alloc::free_all() )
781        {       Run_ok_count++;
782                cout << "No memory leak detected" << endl;
783        }
784        else
785        {       ok = false;
786                Run_error_count++;
787                cout << "Memory leak detected" << endl;
788        }
789# endif
790        return static_cast<int>( ! ok );
791}
Note: See TracBrowser for help on using the repository browser.