2 # ifndef CPPAD_LOCAL_OPTIMIZE_OPTIMIZE_RUN_HPP
3 # define CPPAD_LOCAL_OPTIMIZE_OPTIMIZE_RUN_HPP
35 namespace CppAD {
namespace local {
namespace optimize {
86 const std::string& options ,
92 bool conditional_skip =
true;
93 bool compare_op =
true;
94 bool print_for_op =
true;
96 while( index < options.size() )
97 {
while( index < options.size() && options[index] ==
' ' )
100 while( index < options.size() && options[index] !=
' ' )
101 option += options[index++];
103 {
if( option ==
"no_conditional_skip" )
104 conditional_skip =
false;
105 else if( option ==
"no_compare_op" )
107 else if( option ==
"no_print_for_op" )
108 print_for_op =
false;
110 { option +=
" is not a valid optimize option";
118 num_op <
size_t( std::numeric_limits<addr_t>::max() )
150 Base base_nan = Base( std::numeric_limits<double>::quiet_NaN() );
166 size_t num_cexp = cexp_info.
size();
174 for(
size_t i = 0; i < num_cexp; i++)
175 keys[i] = cexp_info[i].max_left_right;
179 size_t cskip_order_next = 0;
182 size_t cexp_next = 0;
190 for(
size_t i = 0; i < num_cexp; i++)
191 cskip_new[i].i_arg = 0;
199 std::numeric_limits<addr_t>::max() >= num_vecad_ind
202 for(
size_t i = 0; i < num_vecad_ind; i++)
203 new_vecad_ind[i] =
addr_t( num_vecad_ind );
206 for(
size_t i = 0; i < num_vecad_vec; i++)
212 new_vecad_ind[j] = rec->
PutVecInd(length);
213 for(
size_t k = 1; k <= length; k++) new_vecad_ind[j+k] =
229 for(
size_t i = 0; i < num_op; i++)
230 { old2new[i].new_op = 0;
231 old2new[i].new_var = 0;
247 for(i_op = 0; i_op < num_op; ++i_op)
257 bool skip = conditional_skip;
258 skip &= cskip_order_next < num_cexp;
263 {
size_t j = cskip_order[cskip_order_next];
265 skip &= cexp_info[j].max_left_right < i_var;
267 skip &= cexp_info[j].max_left_right <= i_var;
270 {
size_t j = cskip_order[cskip_order_next];
274 skip &= n_true > 0 || n_false > 0;
277 size_t n_arg = 7 + n_true + n_false;
299 std::numeric_limits<addr_t>::max() >= rec->
num_op_rec()
302 if( opt_op_info[i_op].usage !=
yes_usage )
338 previous = opt_op_info[i_op].previous;
340 {
size_t j_op = previous;
341 old2new[i_op].new_var = old2new[j_op].new_var;
345 new_arg[0] = old2new[ play->
var2op(arg[0]) ].new_var;
346 rec->
PutArg( new_arg[0] );
349 old2new[i_op].new_var = rec->
PutOp(op);
351 new_arg[0] < old2new[play->
var2op(i_var)].new_var
389 old2new[i_op].new_op =
addr_t( size_pair.
i_op );
397 previous = opt_op_info[i_op].previous;
399 {
size_t j_op = previous;
400 old2new[i_op].new_var = old2new[j_op].new_var;
410 old2new[i_op].new_op =
addr_t( size_pair.
i_op );
418 previous = opt_op_info[i_op].previous;
420 {
size_t j_op = previous;
421 old2new[i_op].new_var = old2new[j_op].new_var;
426 new_arg[1] = old2new[ play->
var2op(arg[1]) ].new_var;
427 rec->
PutArg( new_arg[0], new_arg[1] );
430 old2new[i_op].new_var = rec->
PutOp(op);
432 new_arg[1] < old2new[play->
var2op(i_var)].new_var
455 old2new[i_op].new_op =
addr_t( size_pair.
i_op );
464 previous = opt_op_info[i_op].previous;
466 {
size_t j_op = previous;
467 old2new[i_op].new_var = old2new[j_op].new_var;
477 old2new[i_op].new_op =
addr_t( size_pair.
i_op );
502 old2new[i_op].new_op =
addr_t( size_pair.
i_op );
511 previous = opt_op_info[i_op].previous;
513 {
size_t j_op = previous;
514 old2new[i_op].new_var = old2new[j_op].new_var;
524 old2new[i_op].new_op =
addr_t( size_pair.
i_op );
535 for(
size_t i = 2; i < 6; i++)
536 {
if( arg[1] & mask )
537 { new_arg[i] = old2new[ play->
var2op(arg[i]) ].new_var;
539 size_t(new_arg[i]) < num_var
542 else new_arg[i] = rec->
PutPar(
556 old2new[i_op].new_var = rec->
PutOp(op);
561 if( conditional_skip )
564 cskip_new[ cexp_next ].left = new_arg[2];
565 cskip_new[ cexp_next ].right = new_arg[3];
584 new_arg[1] = old2new[ play->
var2op(arg[1]) ].new_var;
585 rec->
PutArg(new_arg[0], new_arg[1]);
593 new_arg[0] = old2new[ play->
var2op(arg[0]) ].new_var;
595 rec->
PutArg(new_arg[0], new_arg[1]);
605 new_arg[0] = old2new[ play->
var2op(arg[0]) ].new_var;
606 new_arg[1] = old2new[ play->
var2op(arg[1]) ].new_var;
607 rec->
PutArg(new_arg[0], new_arg[1]);
617 old2new[i_op].new_var = rec->
PutOp(op);
625 rec->
PutArg( new_arg[0] );
628 old2new[i_op].new_var = rec->
PutOp(op);
640 { new_arg[1] = old2new[ play->
var2op(arg[1]) ].new_var;
649 { new_arg[3] = old2new[ play->
var2op(arg[3]) ].new_var;
677 new_arg[0] = new_vecad_ind[ arg[0] ];
690 old2new[i_op].new_var = rec->
PutLoadOp(op);
696 new_arg[0] = new_vecad_ind[ arg[0] ];
697 new_arg[1] = old2new[ play->
var2op(arg[1]) ].new_var;
710 old2new[i_op].new_var = rec->
PutLoadOp(op);
716 new_arg[0] = new_vecad_ind[ arg[0] ];
732 new_arg[0] = new_vecad_ind[ arg[0] ];
733 new_arg[1] = old2new[ play->
var2op(arg[1]) ].new_var;
749 new_arg[0] = new_vecad_ind[ arg[0] ];
751 new_arg[2] = old2new[ play->
var2op(arg[2]) ].new_var;
766 new_arg[0] = new_vecad_ind[ arg[0] ];
767 new_arg[1] = old2new[ play->
var2op(arg[1]) ].new_var;
768 new_arg[2] = old2new[ play->
var2op(arg[2]) ].new_var;
787 rec->
PutArg(arg[0], arg[1], arg[2], arg[3]);
802 new_arg[0] = old2new[ play->
var2op(arg[0]) ].new_var;
803 if(
size_t(new_arg[0]) < num_var )
804 { rec->
PutArg(new_arg[0]);
811 new_arg[0] = rec->
PutPar( base_nan );
840 for(
size_t i = 0; i < dep_taddr.
size(); i++ )
841 { dep_taddr[i] = old2new[ play->
var2op(dep_taddr[i]) ].new_var;
846 for(i_op = 0; i_op < num_op; i_op++)
850 size_t(old2new[i_op].new_op) < rec->
num_op_rec()
858 for(
size_t i = 0; i < num_cexp; i++)
860 if( cskip_new[i].i_arg > 0 )
864 size_t i_arg = cskip_new[i].i_arg;
865 size_t left = cskip_new[i].left;
866 size_t right = cskip_new[i].right;
874 while( *itr_true != skip_op_true.
end() )
878 rec->
ReplaceArg(i_arg++, old2new[i_op].new_op );
883 while( *itr_false != skip_op_false.
end() )
887 rec->
ReplaceArg(i_arg++, old2new[i_op].new_op );
893 size_t n_arg = 7 + n_true + n_false;
This operator is only used once, it is a summation operator, and its parrent is a summation operator...
#define CPPAD_ASSERT_KNOWN(exp, msg)
Check that exp is true, if not print msg and terminate execution.
size_t end(void) const
Fetch end for this vector of sets object.
Vector of sets of positive integers, each set stored as a singly linked list.
addr_t PutOp(OpCode op)
Put next operator in the operation sequence.
size_t num_vec_ind_rec(void) const
Fetch number of VecAD indices in the recording.
CPPAD_TAPE_ADDR_TYPE addr_t
struct_size_pair record_vv(const player< Base > *play, const CppAD::vector< struct struct_old2new > &old2new, size_t i_op, recorder< Base > *rec)
Record an operation of the form (variable op variable).
addr_t PutTxt(const char *text)
Put a character string in the text for this recording.
std::complex< double > atan(const std::complex< double > &x)
const char * GetTxt(size_t i) const
Fetch a '\0' terminated string from the recording.
size_t NumArg(OpCode op)
Number of arguments for a specified operator.
Record an operation of the form (variable op variable).
size_t ReserveArg(size_t n_arg)
Reserve space for arguments, but delay placing values there.
Class used to store and play back an operation sequence recording.
size_t num_load_op_rec(void) const
Number of LdpOp and LdvOp operations currently in the recording.
Information about one cumulative summation operation.
size_t GetVecInd(size_t i) const
Fetch a VecAD index from the recording.
void PutArg(addr_t arg0)
Put one operation argument index in the recording.
void optimize_run(const std::string &options, size_t n, CppAD::vector< size_t > &dep_taddr, const player< Base > *play, recorder< Base > *rec)
Convert a player object to an optimized recorder object.
size_t NumRes(OpCode op)
Number of variables resulting from the specified operation.
size_t number_elements(size_t i) const
Count number of elements in a set.
Information that maps old an old operator to a new opeator and new variable.
next UserOp marks end of a user atomic call
addr_t PutPar(const Base &par)
Find or add a parameter to the current vector of parameters.
addr_t PutLoadOp(OpCode op)
Put a vecad load operator in the operation sequence (special case)
size_t size(void) const
number of elements currently in this vector.
OpCode
Type used to distinguish different AD< Base > atomic operations.
Class used to store an operation sequence while it is being recorded (the operation sequence is copie...
next UserOp marks beginning of a user atomic call
void get_op_info(size_t op_index, OpCode &op, const addr_t *&op_arg, size_t &var_index) const
fetch the information corresponding to an operator
struct_size_pair record_csum(const player< Base > *play, const vector< struct_opt_op_info > &opt_op_info, const CppAD::vector< struct struct_old2new > &old2new, size_t current, recorder< Base > *rec, struct_csum_stacks &work)
Recording a cummulative cummulative summation.
Information about one conditional expression.
Information for one variable and one operation sequence.
void free(void)
Frees all information in recording.
AD< Base > sqrt(const AD< Base > &x)
void index_sort(const VectorKey &keys, VectorSize &ind)
Compute the indices that sort a vector of keys.
Information about one conditional expression.
size_t num_vecad_vec_rec(void) const
Fetch number of VecAD vectors in the recording.
size_t i_var
operator index for this variable
#define CPPAD_ASSERT_UNKNOWN(exp)
Check that exp is true, if not terminate execution.
void get_opt_op_info(bool conditional_skip, bool compare_op, bool print_for_op, const player< Base > *play, const vector< size_t > &dep_taddr, vector< struct_cexp_info > &cexp_info, sparse_list &skip_op_true, sparse_list &skip_op_false, vector< bool > &vecad_used, vector< struct_opt_op_info > &opt_op_info)
Get variable to operator map and operator basic operator information.
size_t num_op_rec(void) const
Fetch number of operators in the recording.
Record an operation of the form (variable op parameter).
#define CPPAD_ASSERT_NARG_NRES(op, n_arg, n_res)
Check that operator op has the specified number of of arguments and results.
Information about one old variable that is part of a new CSumOp operation.
size_t num_op_rec(void) const
Number of operators currently stored in the recording.
size_t var2op(size_t var_index) const
fetch the operator corresponding to a primary variable
CompareOp cop
comparision operator for this conditional expression
This operator is used one or more times.
size_t flag
(flag & 1) is true if and only if left is a variable (flag & 2) is true if and only if right is a var...
addr_t PutVecInd(size_t vec_ind)
Add a value to the end of the current vector of VecAD indices.
cons_iterator for one set of positive integers in a sparse_list object.
Base GetPar(size_t i) const
Fetch a parameter from the recording.
struct_size_pair record_vp(const player< Base > *play, const CppAD::vector< struct struct_old2new > &old2new, size_t i_op, recorder< Base > *rec)
Record an operation of the form (variable op parameter).
Record an operation of the form (parameter op variable).
Recording a cummulative cummulative summation.
struct_size_pair record_pv(const player< Base > *play, const CppAD::vector< struct struct_old2new > &old2new, size_t i_op, recorder< Base > *rec)
Record an operation of the form (parameter op variable).
void ReplaceArg(size_t i_arg, size_t value)
Replace an argument value in the recording (intended to fill in reserved values). ...
size_t num_var_rec(void) const
Fetch number of variables in the recording.
Information about one cumulative summation operation.