source: trunk/cppad/local/recorder.hpp @ 3607

Last change on this file since 3607 was 3607, checked in by bradbell, 5 years ago

merge to branch: trunk
from repository: https://github.com/coin-or/CppAD
start hash code: f4baab0ea7c2679ba9351b0439b6efebfa77ba04
end hash code: 894d554a00ceec8a3545f05eca62708a7b5cb43d

commit 894d554a00ceec8a3545f05eca62708a7b5cb43d
Author: Brad Bell <bradbell@…>
Date: Tue Jan 20 09:06:10 2015 -0700

Fix copyright end date.


whats_new_15.omh: Add comment about date of deprecation.

commit 611e982000168db91aba22b763c14bb78d57da47
Author: Brad Bell <bradbell@…>
Date: Tue Jan 20 08:53:00 2015 -0700

Squashed commit from old/compare_op to master:


In addition, fix copyright end date for some files, and add note about
deprecated date in whats_new_15.omh.


commit 6e46df5c850ecd58d7a886db4043bc3f2d4579d1
Author: Brad Bell <bradbell@…>
Date: Tue Jan 20 08:16:57 2015 -0700


Always return f.compare_change_op_index() == 0 after f.optimize().


checkpoint.hpp: ignore comparison operators.
fun_construct.hpp: remove double initilaization of values.
compare_change.cpp: demonstrate more features of new interface.
whats_new_15.omh: prepare for merging this branch into master.
wish_list.omh: update wish list item to new compare_change interface.


commit 45315907c70e5b383d984fb9498b54a474001af0
Author: Brad Bell <bradbell@…>
Date: Tue Jan 20 05:04:37 2015 -0700


Use the new f.compare_change_count(0) option in speed tests.


commit bb6e72befd6d01f1fb62c43b9b19471ffaa7cc2c
Author: Brad Bell <bradbell@…>
Date: Tue Jan 20 04:51:16 2015 -0700


Move CompareChange? -> deprecated and plan -> compare_change.


forward0sweep.hpp: skip comparison operator when count is zero.
forward1sweep.hpp: skip comparison operator when count is zero.
compare_change.cpp: demonstrate count == 0 case.


commit 622a13c568c612d9dfe9ccd1a01f4ac5f74ba824
Author: Brad Bell <bradbell@…>
Date: Mon Jan 19 23:17:42 2015 -0700


Add example and test of new compare change user API.


ad_fun.hpp: fix f.compare_change_op_index.
compare_change.cpp: Change example to use new API.
compare_change.cpp: Move old example here (just test now).


commit ec4c1613eae8df56fbf31e7b8711ce69cc41df83
Author: Brad Bell <bradbell@…>
Date: Mon Jan 19 21:12:11 2015 -0700


Implement the compare change plan, still needs an example and test.
Also have the change from 'plan' to just plain documentation.


commit a81a46f27011bee08ba072551044dc9f4a99a906
Author: Brad Bell <bradbell@…>
Date: Mon Jan 19 17:49:05 2015 -0700


Change name of compare_change functions and partially implement this new plan.


commit 146faad48a700a56362e74f9c3a3c39144a79738
Author: Brad Bell <bradbell@…>
Date: Mon Jan 19 14:22:40 2015 -0700


Branch: compare_op
plan.omh: change name of count function.


commit 35d91d126765d1a0ab4bfe9e2b006bbf535cd648
Author: Brad Bell <bradbell@…>
Date: Mon Jan 19 13:19:07 2015 -0700


Add deprecation date for some more cases.


commit 5bb65a8c48fae4263b66fcd04520e10e66febc11
Author: Brad Bell <bradbell@…>
Date: Mon Jan 19 13:13:51 2015 -0700


Add date of deprecation for some more cases.


commit e95ee6b209601cd9a075d2e37c602e73c32fb6ab
Author: Brad Bell <bradbell@…>
Date: Mon Jan 19 12:58:44 2015 -0700


Add date of deprecation for some more cases.


commit 0ea84ccd87383edc62a6ae1711da104b12e8c444
Author: Brad Bell <bradbell@…>
Date: Mon Jan 19 12:47:01 2015 -0700


Add date of deprecation for some cases.


commit 17755e609ea8e03472b08dcc2fb5ad347eb723cb
Author: Brad Bell <bradbell@…>
Date: Mon Jan 19 08:20:45 2015 -0700


plan.omh: changs some names.


commit 29f369c06d4d0ee284c4c668d52d8461613066dc
Author: Brad Bell <bradbell@…>
Date: Fri Jan 16 06:39:45 2015 -0700


Document the plan for compare_change user API.


compare_change.omh: fix minor typo.
plan.txt: change to the omhelp file plan.omh.


commit a3a2f4dedd202a722812b6eb2714851b40726e6e
Author: Brad Bell <bradbell@…>
Date: Thu Jan 15 21:03:44 2015 -0700


new_branch.sh: remove unused variable.
push_git2svn.py: move repository from github/bradbell to coin-or/bradbell.


commit 3751a197ab2897e76616f9d9b0915148bd855356
Author: Brad Bell <bradbell@…>
Date: Thu Jan 15 20:56:17 2015 -0700


plan.txt: plan for this branches API will go here.


commit 76013ec2ad7baacdeab5e761812d542867910174
Author: Brad Bell <bradbell@…>
Date: Thu Jan 15 18:04:33 2015 -0700


Store the operator index for the first comparision change in the ADFun object.


commit 9caf25014079a60df5de17bcac76775daf8ee201
Author: Brad Bell <bradbell@…>
Date: Thu Jan 15 12:45:56 2015 -0700


Make compare_change a parameter (so will be easy to add compare_first).


commit 2246d22fe82b8909d432f82ab0d783ce3351a02f
Author: Brad Bell <bradbell@…>
Date: Thu Jan 15 09:12:40 2015 -0700


speed_branch.sh: fix directory (before cd).


commit b3910de86558a97749741bfb728e45c5a86d1c73
Author: Brad Bell <bradbell@…>
Date: Thu Jan 15 05:14:01 2015 -0700


search.sh: use git to get list of source files.
ad_fun.hpp: imporve doxygen doc for compare_change_.
ad_tape.hpp: remove RecordCompare? (no longer used).
atomic_base.hpp: minor edit to user documentation.


commit dd74f331386cadc9cc272c264296e575691aa3f8
Author: Brad Bell <bradbell@…>
Date: Thu Jan 15 04:12:34 2015 -0700


Change Leq..Op -> Le..Op and leq.._op -> le.._op.


commit ae729296323eb7f4f4a7c0e90a303a8d7f4ed42a
Author: Brad Bell <bradbell@…>
Date: Wed Jan 14 21:19:55 2015 -0700


comp_op.hpp: Add doxygen documentaiton for compare operators.
compare.hpp: avoid an extra branch.


commit b064d59a5ad01dff5c708cc8c02f628f58c863ec
Author: Brad Bell <bradbell@…>
Date: Wed Jan 14 16:11:25 2015 -0700


Remove ComOp?, replaced by specific cases Eq..Op, Ne..Op, Leq..Op, Lt..Op,
which should run faster.


forward0sweep.hpp: Remove out-dated comment about CompOp?.
forward1sweep.hpp: Remove out-dated comment about CompOp?.


commit 5bb0a70d1151e9086b88024050cea6cf11e83aa7
Author: Brad Bell <bradbell@…>
Date: Wed Jan 14 09:02:17 2015 -0700


Use Eq..Op, Ne..Op to implement == and !=.


commit 0ebeec61bc040a00c50db41ca5da31fb87194f93
Author: Brad Bell <bradbell@…>
Date: Wed Jan 14 07:19:26 2015 -0700


compare.hpp: Finish folding < <= > >= into Lt..Op and Leq..Op.


commit c949e5b72158b98cbab61c8aea98e76008e9c2f4
Author: Brad Bell <bradbell@…>
Date: Wed Jan 14 06:28:41 2015 -0700


  1. Change plan to fold all compare operations into Leq..Op and Lt..Op cases.
  2. Fix alphabetical order between Ld and Leq.


commit 6ffee88b68b682359d62bc75a8c2ba3e28d012ac
Author: Brad Bell <bradbell@…>
Date: Tue Jan 13 22:40:18 2015 -0700


Splite parameter <= variable and parameter > variable as separate compare
operators.


commit 0841014db4ead690d1c2358f5e09494030ae1e5f
Author: Brad Bell <bradbell@…>
Date: Tue Jan 13 21:12:57 2015 -0700


Attempting to recording and playback of compare operators faster:
Split variable <= variable and variable > variable out as separate cases.


compare.hpp: remove white space at end of lines.


commit cfd3afceebd4b3383b3042cbca98caf82ff77670
Author: Brad Bell <bradbell@…>
Date: Tue Jan 13 08:39:12 2015 -0700


speed_branch.sh: compare speed_cppad between two git branches.
speed_new.sh: correct list of options, remove unused variable.
wish_list.omh: correct discussion of effect of keeping compare operators.


commit 9ed03e1ee2c258ca38561ad083067e235d032e14
Author: Brad Bell <bradbell@…>
Date: Tue Jan 13 05:54:30 2015 -0700


Change test so it corresponds to optimization keeping compare operators.


commit 5c418d477d58984b094bba027ebb0794e759e557
Author: Brad Bell <bradbell@…>
Date: Tue Jan 13 05:12:50 2015 -0700


Include example and test of using CompareChange? with optimized tape.


commit c1b48edfa56ca096ce8c2db1dbadb2658cb13fe3
Author: Brad Bell <bradbell@…>
Date: Tue Jan 13 04:24:54 2015 -0700


Fix optimization so variables used in compare opertions are alwasy available.


commit 6fe607ca30db07b356fd3a9fe9779fa2dfd382d8
Author: Brad Bell <bradbell@…>
Date: Mon Jan 12 07:56:41 2015 -0700


Keep CompareChange? in optimized versions of tape and when NDEBUG is defined.

commit b4c0e51489cc0878499a331b4af4875b2781d8d8
Author: Brad Bell <bradbell@…>
Date: Sun Jan 11 17:01:59 2015 -0700

new_branch.sh: final procedure (only hand tested).

  • Property svn:keywords set to Id
File size: 16.7 KB
Line 
1/* $Id: recorder.hpp 3607 2015-01-20 16:20:41Z bradbell $ */
2# ifndef CPPAD_RECORDER_INCLUDED
3# define CPPAD_RECORDER_INCLUDED
4/* --------------------------------------------------------------------------
5CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-15 Bradley M. Bell
6
7CppAD is distributed under multiple licenses. This distribution is under
8the terms of the
9                    Eclipse Public License Version 1.0.
10
11A copy of this license is included in the COPYING file of this distribution.
12Please visit http://www.coin-or.org/CppAD/ for information on other licenses.
13-------------------------------------------------------------------------- */
14# include <cppad/local/hash_code.hpp>
15# include <cppad/local/pod_vector.hpp>
16
17namespace CppAD { // BEGIN_CPPAD_NAMESPACE
18/*!
19\file recorder.hpp
20File used to define the recorder class.
21*/
22
23/*!
24Class used to store an operation sequence while it is being recorded
25(the operation sequence is copied to the player class for playback).
26
27\tparam Base
28This is an AD< \a Base > operation sequence recording; i.e.,
29it records operations of type AD< \a Base >.
30*/
31template <class Base>
32class recorder {
33        friend class player<Base>;
34
35private:
36        /// operator index at which to abort recording with an error
37        /// (do not abort when zero)
38        size_t abort_op_index_;
39
40        /// offset for this thread in the static hash table
41        const size_t thread_offset_;
42
43        /// Number of variables in the recording.
44        size_t    num_var_rec_;
45
46        /// Number vecad load operations (LdpOp or LdvOp) currently in recording.
47        size_t  num_load_op_rec_;
48
49        /// The operators in the recording.
50        pod_vector<CPPAD_OP_CODE_TYPE> op_rec_;
51
52        /// The VecAD indices in the recording.
53        pod_vector<addr_t> vecad_ind_rec_;
54
55        /// The argument indices in the recording
56        pod_vector<addr_t> op_arg_rec_;
57
58        /// The parameters in the recording.
59        /// Note that Base may not be plain old data, so use false in consructor.
60        pod_vector<Base> par_rec_;
61
62        /// Character strings ('\\0' terminated) in the recording.
63        pod_vector<char> text_rec_;
64// ---------------------- Public Functions -----------------------------------
65public:
66        /// Default constructor
67        recorder(void) : 
68        thread_offset_( thread_alloc::thread_num() * CPPAD_HASH_TABLE_SIZE ) ,
69        num_var_rec_(0)                                      ,
70        num_load_op_rec_(0)                                  ,
71        op_rec_( std::numeric_limits<addr_t>::max() )        ,
72        vecad_ind_rec_( std::numeric_limits<addr_t>::max() ) ,
73        op_arg_rec_( std::numeric_limits<addr_t>::max() )    ,
74        par_rec_( std::numeric_limits<addr_t>::max() )       ,
75        text_rec_( std::numeric_limits<addr_t>::max() )
76        {
77                abort_op_index_ = 0;
78        }
79
80        /// Set the abort index
81        void set_abort_op_index(size_t abort_op_index)
82        {       abort_op_index_ = abort_op_index; }
83
84        /// Get the abort index
85        size_t get_abort_op_index(void)
86        {       return abort_op_index_; }
87
88        /// Destructor
89        ~recorder(void)
90        { }
91
92        /*!
93        Frees all information in recording.
94
95        Frees the operation sequence store in this recording
96        (the operation sequence is empty after this operation).
97        The buffers used to store the current recording are returned
98        to the system (so as to conserve on memory).
99        */
100        void free(void)
101        {       num_var_rec_     = 0;
102                num_load_op_rec_ = 0;
103                op_rec_.free();
104                vecad_ind_rec_.free();
105                op_arg_rec_.free();
106                par_rec_.free();
107                text_rec_.free();
108        }
109        /// Put next operator in the operation sequence.
110        inline size_t PutOp(OpCode op);
111        /// Put a vecad load operator in the operation sequence (special case)
112        inline size_t PutLoadOp(OpCode op);
113        /// Add a value to the end of the current vector of VecAD indices.
114        inline size_t PutVecInd(size_t vec_ind);
115        /// Find or add a parameter to the current vector of parameters.
116        inline size_t PutPar(const Base &par);
117        /// Put one operation argument index in the recording
118        inline void PutArg(addr_t arg0); 
119        /// Put two operation argument index in the recording
120        inline void PutArg(addr_t arg0, addr_t arg1); 
121        /// Put three operation argument index in the recording
122        inline void PutArg(addr_t arg0, addr_t arg1, addr_t arg2); 
123        /// Put four operation argument index in the recording
124        inline void PutArg(addr_t arg0, addr_t arg1, addr_t arg2, addr_t arg3); 
125        /// Put five operation argument index in the recording
126        inline void PutArg(addr_t arg0, addr_t arg1, addr_t arg2, addr_t arg3,
127                addr_t arg4);
128        /// Put six operation argument index in the recording
129        inline void PutArg(addr_t arg0, addr_t arg1, addr_t arg2, addr_t arg3,
130                addr_t arg4, addr_t arg5);
131
132        // Reserve space for a specified number of arguments
133        inline size_t ReserveArg(size_t n_arg);
134
135        // Replace an argument value
136        void ReplaceArg(size_t i_arg, size_t value);
137
138        /// Put a character string in the text for this recording.
139        inline size_t PutTxt(const char *text);
140
141        /// Number of variables currently stored in the recording.
142        size_t num_var_rec(void) const
143        {       return num_var_rec_; }
144
145        /// Number of LdpOp and LdvOp operations currently in the recording.
146        size_t num_load_op_rec(void) const
147        {       return num_load_op_rec_; }
148
149        /// Number of operators currently stored in the recording.
150        size_t num_op_rec(void) const
151        {       return  op_rec_.size(); }
152
153        /// Approximate amount of memory used by the recording
154        size_t Memory(void) const
155        {       return op_rec_.capacity()        * sizeof(CPPAD_OP_CODE_TYPE) 
156                     + vecad_ind_rec_.capacity() * sizeof(size_t)
157                     + op_arg_rec_.capacity()    * sizeof(addr_t)
158                     + par_rec_.capacity()       * sizeof(Base)
159                     + text_rec_.capacity()      * sizeof(char);
160        }
161};
162
163/*!
164Put next operator in the operation sequence.
165
166This sets the op code for the next operation in this recording.
167This call must be followed by putting the corresponding
168\verbatim
169        NumArg(op)
170\endverbatim
171argument indices in the recording.
172
173\param op
174Is the op code corresponding to the the operation that is being
175recorded (which must not be LdpOp or LdvOp).
176
177\return
178The return value is the index of the primary (last) variable
179corresponding to the result of this operation.
180The number of variables corresponding to the operation is given by
181\verbatim
182        NumRes(op)
183\endverbatim
184With each call to PutOp or PutLoadOp,
185the return index increases by the number of variables corresponding
186to the call.
187This index starts at zero after the default constructor
188and after each call to Erase.
189*/
190template <class Base>
191inline size_t recorder<Base>::PutOp(OpCode op)
192{       size_t i    = op_rec_.extend(1);
193        CPPAD_ASSERT_KNOWN(
194                (abort_op_index_ == 0) || (abort_op_index_ != i),
195                "Operator index equals abort_op_index in Independent"
196        );
197        op_rec_[i]  = static_cast<CPPAD_OP_CODE_TYPE>(op);
198        CPPAD_ASSERT_UNKNOWN( op_rec_.size() == i + 1 );
199        CPPAD_ASSERT_UNKNOWN( (op != LdpOp) & (op != LdvOp) );
200
201        // first operator should be a BeginOp and NumRes( BeginOp ) > 0
202        num_var_rec_ += NumRes(op);
203        CPPAD_ASSERT_UNKNOWN( num_var_rec_ > 0 );
204
205        return num_var_rec_ - 1;
206}
207
208/*!
209Put next LdpOp or LdvOp operator in operation sequence (special cases).
210
211This sets the op code for the next operation in this recording.
212This call must be followed by putting the corresponding
213\verbatim
214        NumArg(op)
215\endverbatim
216argument indices in the recording.
217
218\param op
219Is the op code corresponding to the the operation that is being
220recorded (which must be LdpOp or LdvOp).
221
222\return
223The return value is the index of the primary (last) variable
224corresponding to the result of this operation.
225The number of variables corresponding to the operation is given by
226\verbatim
227        NumRes(op)
228\endverbatim
229which must be one for this operation.
230With each call to PutLoadOp or PutOp,
231the return index increases by the number of variables corresponding
232to this call to the call.
233This index starts at zero after the default constructor
234and after each call to Erase.
235
236\par num_load_op_rec()
237The return value for <code>num_load_op_rec()</code>
238increases by one after each call to this function
239(and starts at zero after the default constructor or Erase).
240*/
241template <class Base>
242inline size_t recorder<Base>::PutLoadOp(OpCode op)
243{       size_t i    = op_rec_.extend(1);
244        CPPAD_ASSERT_KNOWN(
245                (abort_op_index_ == 0) || (abort_op_index_ != i),
246                "This is the abort operator index specified by "
247                "Independent(x, abort_op_index)."
248        );
249        op_rec_[i]  = static_cast<CPPAD_OP_CODE_TYPE>(op);
250        CPPAD_ASSERT_UNKNOWN( op_rec_.size() == i + 1 );
251        CPPAD_ASSERT_UNKNOWN( (op == LdpOp) | (op == LdvOp) );
252
253        // first operator should be a BeginOp and NumRes( BeginOp ) > 0
254        num_var_rec_ += NumRes(op);
255        CPPAD_ASSERT_UNKNOWN( num_var_rec_ > 0 );
256
257        // count this vecad load operation
258        num_load_op_rec_++;
259
260        return num_var_rec_ - 1;
261}
262
263/*!
264Add a value to the end of the current vector of VecAD indices.
265
266For each VecAD vector, this routine is used to store the length
267of the vector followed by the parameter index corresponding to each
268value in the vector.
269This value for the elements of the VecAD vector corresponds to the
270beginning of the operation sequence.
271
272\param vec_ind
273is the index to be palced at the end of the vector of VecAD indices.
274
275\return
276is the index in the vector of VecAD indices corresponding to this value.
277This index starts at zero after the recorder default constructor
278and after each call to Erase.
279It increments by one for each call to PutVecInd..
280*/
281template <class Base>
282inline size_t recorder<Base>::PutVecInd(size_t vec_ind)
283{       size_t i          = vecad_ind_rec_.extend(1);
284        vecad_ind_rec_[i] = vec_ind;
285        CPPAD_ASSERT_UNKNOWN( vecad_ind_rec_.size() == i + 1 );
286
287        return i;
288}
289
290/*!
291Find or add a parameter to the current vector of parameters.
292
293\param par
294is the parameter to be found or placed in the vector of parameters.
295
296\return
297is the index in the parameter vector corresponding to this parameter value.
298This value is not necessarily placed at the end of the vector
299(because values that are identically equal may be reused).
300*/
301template <class Base>
302size_t recorder<Base>::PutPar(const Base &par)
303{       static size_t   hash_table[CPPAD_HASH_TABLE_SIZE * CPPAD_MAX_NUM_THREADS];
304        size_t          i;
305        size_t          code;
306
307        CPPAD_ASSERT_UNKNOWN( 
308                thread_offset_ / CPPAD_HASH_TABLE_SIZE
309                == 
310                thread_alloc::thread_num() 
311        );
312
313        // get hash code for this value
314        code = static_cast<size_t>( hash_code(par) );
315        CPPAD_ASSERT_UNKNOWN( code < CPPAD_HASH_TABLE_SIZE );
316
317        // If we have a match, return the parameter index
318        i = hash_table[code + thread_offset_];
319        if( i < par_rec_.size() && IdenticalEqualPar(par_rec_[i], par) )
320                        return i;
321       
322        // place a new value in the table
323        i           = par_rec_.extend(1);
324        par_rec_[i] = par;
325        CPPAD_ASSERT_UNKNOWN( par_rec_.size() == i + 1 );
326
327        // make the hash code point to this new value
328        hash_table[code + thread_offset_] = i;
329
330        // return the parameter index
331        return i;
332}
333// -------------------------- PutArg --------------------------------------
334/*!
335Prototype for putting operation argument indices in the recording.
336
337The following syntax
338\verbatim
339        rec.PutArg(arg0)
340        rec.PutArg(arg0, arg1)
341        .
342        .
343        .
344        rec.PutArg(arg0, arg1, ..., arg5)
345\endverbatim
346places the values passed to PutArg at the current end of the
347operation argument indices for the recording.
348\a arg0 comes before \a arg1, etc.
349The proper number of operation argument indices
350corresponding to the operation code op is given by
351\verbatim
352        NumArg(op)
353\endverbatim
354The number of the operation argument indices starts at zero
355after the default constructor and each call to Erase.
356It increases by the number of indices placed by each call to PutArg.
357*/
358inline void prototype_put_arg(void)
359{       // This routine should not be called
360        CPPAD_ASSERT_UNKNOWN(false);
361}
362/*!
363Put one operation argument index in the recording
364
365\param arg0
366The operation argument index
367
368\copydetails prototype_put_arg
369*/
370template <class Base>
371inline void recorder<Base>::PutArg(addr_t arg0)
372{ 
373        size_t i       = op_arg_rec_.extend(1);
374        op_arg_rec_[i] =  static_cast<addr_t>( arg0 );
375        CPPAD_ASSERT_UNKNOWN( op_arg_rec_.size() == i + 1 );
376}
377/*!
378Put two operation argument index in the recording
379
380\param arg0
381First operation argument index.
382
383\param arg1
384Second operation argument index.
385
386\copydetails prototype_put_arg
387*/
388template <class Base>
389inline void recorder<Base>::PutArg(addr_t arg0, addr_t arg1)
390{ 
391        size_t i         = op_arg_rec_.extend(2);
392        op_arg_rec_[i++] =  static_cast<addr_t>( arg0 );
393        op_arg_rec_[i]   =  static_cast<addr_t>( arg1 );
394        CPPAD_ASSERT_UNKNOWN( op_arg_rec_.size() == i + 1 );
395}
396/*!
397Put three operation argument index in the recording
398
399\param arg0
400First operation argument index.
401
402\param arg1
403Second operation argument index.
404
405\param arg2
406Third operation argument index.
407
408\copydetails prototype_put_arg
409*/
410template <class Base>
411inline void recorder<Base>::PutArg(addr_t arg0, addr_t arg1, addr_t arg2)
412{ 
413        size_t i         = op_arg_rec_.extend(3);
414        op_arg_rec_[i++] =  static_cast<addr_t>( arg0 );
415        op_arg_rec_[i++] =  static_cast<addr_t>( arg1 );
416        op_arg_rec_[i]   =  static_cast<addr_t>( arg2 );
417        CPPAD_ASSERT_UNKNOWN( op_arg_rec_.size() == i + 1 );
418}
419/*!
420Put four operation argument index in the recording
421
422\param arg0
423First operation argument index.
424
425\param arg1
426Second operation argument index.
427
428\param arg2
429Third operation argument index.
430
431\param arg3
432Fourth operation argument index.
433
434\copydetails prototype_put_arg
435*/
436template <class Base>
437inline void recorder<Base>::PutArg(addr_t arg0, addr_t arg1, addr_t arg2,
438        addr_t arg3)
439{ 
440        size_t i         = op_arg_rec_.extend(4);
441        op_arg_rec_[i++] =  static_cast<addr_t>( arg0 );
442        op_arg_rec_[i++] =  static_cast<addr_t>( arg1 );
443        op_arg_rec_[i++] =  static_cast<addr_t>( arg2 );
444        op_arg_rec_[i]   =  static_cast<addr_t>( arg3 );
445        CPPAD_ASSERT_UNKNOWN( op_arg_rec_.size() == i + 1 );
446
447}
448/*!
449Put five operation argument index in the recording
450
451\param arg0
452First operation argument index.
453
454\param arg1
455Second operation argument index.
456
457\param arg2
458Third operation argument index.
459
460\param arg3
461Fourth operation argument index.
462
463\param arg4
464Fifth operation argument index.
465
466\copydetails prototype_put_arg
467*/
468template <class Base>
469inline void recorder<Base>::PutArg(addr_t arg0, addr_t arg1, addr_t arg2,
470        addr_t arg3, addr_t arg4)
471{ 
472        size_t i         = op_arg_rec_.extend(5);
473        op_arg_rec_[i++] =  static_cast<addr_t>( arg0 );
474        op_arg_rec_[i++] =  static_cast<addr_t>( arg1 );
475        op_arg_rec_[i++] =  static_cast<addr_t>( arg2 );
476        op_arg_rec_[i++] =  static_cast<addr_t>( arg3 );
477        op_arg_rec_[i]   =  static_cast<addr_t>( arg4 );
478        CPPAD_ASSERT_UNKNOWN( op_arg_rec_.size() == i + 1 );
479
480}
481/*!
482Put six operation argument index in the recording
483
484\param arg0
485First operation argument index.
486
487\param arg1
488Second operation argument index.
489
490\param arg2
491Third operation argument index.
492
493\param arg3
494Fourth operation argument index.
495
496\param arg4
497Fifth operation argument index.
498
499\param arg5
500Sixth operation argument index.
501
502\copydetails prototype_put_arg
503*/
504template <class Base>
505inline void recorder<Base>::PutArg(addr_t arg0, addr_t arg1, addr_t arg2, 
506        addr_t arg3, addr_t arg4, addr_t arg5)
507{ 
508        size_t i         = op_arg_rec_.extend(6);
509        op_arg_rec_[i++] =  static_cast<addr_t>( arg0 );
510        op_arg_rec_[i++] =  static_cast<addr_t>( arg1 );
511        op_arg_rec_[i++] =  static_cast<addr_t>( arg2 );
512        op_arg_rec_[i++] =  static_cast<addr_t>( arg3 );
513        op_arg_rec_[i++] =  static_cast<addr_t>( arg4 );
514        op_arg_rec_[i]   =  static_cast<addr_t>( arg5 );
515        CPPAD_ASSERT_UNKNOWN( op_arg_rec_.size() == i + 1 );
516}
517// --------------------------------------------------------------------------
518/*!
519Reserve space for arguments, but delay placing values there.
520
521\param n_arg
522number of arguements to reserve space for
523
524\return
525is the index in the argument vector corresponding to the
526first of the arguments being reserved.
527*/
528template <class Base>
529inline size_t recorder<Base>::ReserveArg(size_t n_arg)
530{ 
531        size_t i = op_arg_rec_.extend(n_arg);
532        CPPAD_ASSERT_UNKNOWN( op_arg_rec_.size() == i + n_arg );
533        return i;
534}
535
536/*!
537\brief
538Replace an argument value in the recording
539(intended to fill in reserved values).
540
541\param i_arg
542is the index, in argument vector, for the value that is replaced.
543
544\param value
545is the new value for the argument with the specified index.
546*/
547template <class Base>
548inline void recorder<Base>::ReplaceArg(size_t i_arg, size_t value)
549{       op_arg_rec_[i_arg] =  static_cast<addr_t>( value ); }
550// --------------------------------------------------------------------------
551/*!
552Put a character string in the text for this recording.
553
554\param text
555is a '\\0' terminated character string that is to be put in the
556vector of characters corresponding to this recording.
557The terminator '\\0' will be included.
558
559\return
560is the offset with in the text vector for this recording at which
561the character string starts.
562*/
563template <class Base>
564inline size_t recorder<Base>::PutTxt(const char *text)
565{
566        // determine length of the text including terminating '\0'
567        size_t n = 0;
568        while( text[n] != '\0' )
569                n++;
570        CPPAD_ASSERT_UNKNOWN( n <= 1000 ); 
571        n++;
572        CPPAD_ASSERT_UNKNOWN( text[n-1] == '\0' );
573
574        // copy text including terminating '\0'
575        size_t i = text_rec_.extend(n); 
576        size_t j;
577        for(j = 0; j < n; j++)
578                text_rec_[i + j] = text[j];
579        CPPAD_ASSERT_UNKNOWN( text_rec_.size() == i + n );
580
581        return i;
582}
583// -------------------------------------------------------------------------
584
585
586} // END_CPPAD_NAMESPACE
587# endif
Note: See TracBrowser for help on using the repository browser.