source: branches/cache/cppad/local/capacity_order.hpp @ 3337

Last change on this file since 3337 was 3337, checked in by bradbell, 6 years ago

capacity_order.hpp: add room for cache to taylor_ array.

  • Property svn:keywords set to Id
File size: 7.5 KB
Line 
1/* $Id: capacity_order.hpp 3337 2014-09-17 10:05:50Z bradbell $ */
2# ifndef CPPAD_CAPACITY_ORDER_INCLUDED
3# define CPPAD_CAPACITY_ORDER_INCLUDED
4
5/* --------------------------------------------------------------------------
6CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-14 Bradley M. Bell
7
8CppAD is distributed under multiple licenses. This distribution is under
9the terms of the
10                    Eclipse Public License Version 1.0.
11
12A copy of this license is included in the COPYING file of this distribution.
13Please visit http://www.coin-or.org/CppAD/ for information on other licenses.
14-------------------------------------------------------------------------- */
15
16/*
17$begin capacity_order$$
18$spell
19        var
20        taylor_
21        xq
22        yq
23$$
24
25$index Forward, capacity$$
26$index capacity_order$$
27$index capacity, Forward$$
28$index control, memory$$
29$index memory, control$$
30
31$section Controlling Taylor Coefficients Memory Allocation$$
32
33$head Syntax$$
34$icode%f%.capacity_order(%c%)%$$
35
36$subhead See Also$$
37$cref seq_property$$
38
39$head Purpose$$
40The Taylor coefficients calculated by $cref Forward$$ mode calculations
41are retained in an $cref ADFun$$ object for subsequent use during
42$cref Reverse$$ mode and higher order Forward mode calculations.
43For example, a call to $cref/Forward/forward_order/$$ with the syntax
44$codei%
45        %yq% = %f%.Forward(%q%, %xq%)
46%$$
47where $icode%q% > 0%$$ and  $code%xq%.size() == %f%.Domain()%$$,
48uses the lower order Taylor coefficients and
49computes the $th q$$ order Taylor coefficients for all
50the variables in the operation sequence corresponding to $icode f$$.
51The $code capacity_order$$ operation allows you to control that
52amount of memory that is retained by an AD function object
53(to hold $code Forward$$ results for subsequent calculations).
54
55$head f$$
56The object $icode f$$ has prototype
57$codei%
58        ADFun<%Base%> %f%
59%$$
60
61$head c$$
62The argument $icode c$$ has prototype
63$codei%
64        size_t %c%
65%$$
66It specifies the number of Taylor coefficient orders that are allocated
67in the AD operation sequence corresponding to $icode f$$.
68
69$subhead Pre-Allocating Memory$$
70If you plan to make calls to $code Forward$$ with the maximum value of
71$icode q$$ equal to $icode Q$$,
72it should be faster to pre-allocate memory for these calls using
73$codei%
74        %f%.capacity_order(%c%)
75%$$
76with $icode c$$ equal to $latex Q + 1$$.
77If you do no do this, $code Forward$$ will automatically allocate memory
78and will copy the results to a larger buffer, when necessary.
79$pre
80
81$$
82Note that each call to $cref Dependent$$ frees the old memory
83connected to the function object and sets the corresponding
84taylor capacity to zero.
85
86$subhead Freeing Memory$$
87If you no longer need the Taylor coefficients of order $icode q$$
88and higher (that are stored in $icode f$$),
89you can reduce the memory allocated to $icode f$$ using
90$codei%
91        %f%.capacity_order(%c%)
92%$$
93with $icode c$$ equal to $icode q$$.
94Note that, if $cref ta_hold_memory$$ is true, this memory is not actually
95returned to the system, but rather held for future use by the same thread.
96
97$head Original State$$
98If $icode f$$ is $cref/constructed/FunConstruct/$$ with the syntax
99$codei%
100        ADFun<%Base%> %f%(%x%, %y%)
101%$$,
102there is an implicit call to $cref forward_zero$$ with $icode xq$$ equal to
103the value of the
104$cref/independent variables/glossary/Tape/Independent Variable/$$
105when the AD operation sequence was recorded.
106This corresponds to $icode%c% == 1%$$.
107
108$children%
109        example/capacity_order.cpp
110%$$
111$head Example$$
112The file
113$cref capacity_order.cpp$$
114contains an example and test of these operations.
115It returns true if it succeeds and false otherwise.
116
117$end
118-----------------------------------------------------------------------------
119*/
120
121namespace CppAD { // BEGIN_CPPAD_NAMESPACE
122/*!
123\file capacity_order.hpp
124Control of number of orders allocated.
125\}
126*/
127
128/*!
129Control of number of orders and directions allocated.
130
131\tparam Base
132The type used during the forward mode computations; i.e., the corresponding
133recording of operations used the type AD<Base>.
134
135\param c
136is the number of orders to allocate memory for.
137If <code>c == 0</code> then \c r must also be zero.
138In this case num_order_taylor_, cap_order_taylor_, and num_direction_taylor_
139are all set to zero.
140In addition, taylor_.free() is called.
141
142\param r
143is the number of directions to allocate memory for.
144If <code>c == 1</code> then \c r must also be one.
145In all cases, it must hold that
146<code>
147        r == num_direction_taylor_ || num_order_taylor <= 1
148</code>
149Upon return, num_direction_taylor_ is equal to r.
150
151\par num_order_taylor_
152The output value of num_order_taylor_ is the mininumum of its input
153value and c. This minimum is the number of orders that are copied to the
154new taylor coefficient buffer.
155
156\par num_direction_taylor_
157The output value of num_direction_taylor_ is equal to \c r.
158*/
159
160template <typename Base>
161void ADFun<Base>::capacity_order(size_t c, size_t r)
162{       // temporary indices
163        size_t i, k, ell;
164
165        if( (c == cap_order_taylor_) & (r == num_direction_taylor_) ) 
166                return;
167
168        if( c == 0 )
169        {       CPPAD_ASSERT_UNKNOWN( r == 0 );
170                taylor_.free();
171                num_order_taylor_     = 0;
172                cap_order_taylor_     = 0;
173                num_direction_taylor_ = r;
174                return;
175        }
176        CPPAD_ASSERT_UNKNOWN(r==num_direction_taylor_ || num_order_taylor_<=1);
177
178        // number of variables including cache
179        size_t num_var_plus_cache = num_var_tape_ + play_.num_cache_rec();
180       
181        // Allocate new taylor with requested number of orders and directions 
182        size_t new_len   = ( (c-1)*r + 1 ) * num_var_plus_cache;
183        pod_vector<Base> new_taylor;
184        new_taylor.extend(new_len);
185
186        // number of orders to copy
187        size_t p = std::min(num_order_taylor_, c);
188        if( p > 0 )
189        {
190                // old order capacity
191                size_t C = cap_order_taylor_;
192
193                // old number of directions
194                size_t R = num_direction_taylor_;
195
196                // copy the old data into the new matrix
197                CPPAD_ASSERT_UNKNOWN( p == 1 || r == R );
198                for(i = 0; i < num_var_tape_; i++)
199                {       // copy zero order
200                        size_t old_index = ((C-1) * R + 1) * i + 0;
201                        size_t new_index = ((c-1) * r + 1) * i + 0;
202                        new_taylor[ new_index ] = taylor_[ old_index ];
203                        // copy higher orders
204                        for(k = 1; k < p; k++)
205                        {       for(ell = 0; ell < R; ell++)
206                                {       old_index = ((C-1) * R + 1) * i + (k-1) * R + ell + 1;
207                                        new_index = ((c-1) * r + 1) * i + (k-1) * r + ell + 1;
208                                        new_taylor[ new_index ] = taylor_[ old_index ];
209                                }
210                        }
211                }
212        }
213
214        // replace taylor_ by new_taylor
215        taylor_.swap(new_taylor);
216        cap_order_taylor_     = c;
217        num_order_taylor_     = p;
218        num_direction_taylor_ = r;
219
220        // note that the destructor for new_taylor will free the old taylor memory
221        return;
222}
223
224/*!
225User API control of number of orders allocated.
226
227\tparam Base
228The type used during the forward mode computations; i.e., the corresponding
229recording of operations used the type AD<Base>.
230
231\param c
232is the number of orders to allocate memory for.
233If <code>c == 0</code>,
234num_order_taylor_, cap_order_taylor_, and num_direction_taylor_
235are all set to zero.
236In addition, taylor_.free() is called.
237
238\par num_order_taylor_
239The output value of num_order_taylor_ is the mininumum of its input
240value and c. This minimum is the number of orders that are copied to the
241new taylor coefficient buffer.
242
243\par num_direction_taylor_
244If \c is zero (one), \c num_direction_taylor_ is set to zero (one).
245Otherwise, if \c num_direction_taylor_ is zero, it is set to one.
246Othwerwise, \c num_direction_taylor_ is not modified.
247*/
248
249template <typename Base>
250void ADFun<Base>::capacity_order(size_t c)
251{       size_t r;
252        if( (c == 0) | (c == 1) )
253        {       r = c;
254                capacity_order(c, r);
255                return;
256        }
257        r = num_direction_taylor_;
258        if( r == 0 )
259                r = 1;
260        capacity_order(c, r);
261        return;
262}
263
264} // END CppAD namespace
265       
266
267# endif
Note: See TracBrowser for help on using the repository browser.