1 # ifndef CPPAD_LOCAL_OPTIMIZE_GET_OPT_OP_INFO_HPP
2 # define CPPAD_LOCAL_OPTIMIZE_GET_OPT_OP_INFO_HPP
25 namespace CppAD {
namespace local {
namespace optimize {
100 if( cexp_set.
n_set() > 0 )
101 {
if( opt_op_info[i_arg].usage ==
no_usage )
103 cexp_set.
assignment(i_arg, i_result, cexp_set);
111 bool csum = sum_result && opt_op_info[i_arg].usage ==
no_usage;
199 template <
class Base>
201 bool conditional_skip ,
218 opt_op_info.
resize( num_op );
222 std::numeric_limits<addr_t>::max() >= num_op
226 size_t user_old=0, user_m=0, user_n=0, user_i=0, user_j=0;
243 size_t num_cexp_op = 0;
260 typedef std::set<size_t> size_set;
271 bool user_pack =
false;
272 bool user_bool =
false;
273 bool user_set =
false;
279 vecad_used.
resize(num_vecad);
280 for(
size_t i = 0; i < num_vecad; i++)
281 vecad_used[i] =
false;
284 for(
size_t i = 0; i < num_vecad_ind; i++)
285 arg2vecad[i] = num_vecad;
287 for(
size_t i = 0; i < num_vecad; i++)
290 arg2vecad[arg_0] = i;
293 size_t length = play->
GetVecInd(arg_0 - 1);
302 const Base* parameter = CPPAD_NULL;
304 parameter = play->
GetPar();
315 if( conditional_skip && num_cexp_op > 0)
320 size_t end_set = 2 * num_cexp_op;
323 cexp_set.
resize(num_set, end_set);
327 for(
size_t i = 0; i < num_op; i++)
329 for(
size_t i = 0; i < dep_taddr.
size(); i++)
330 { i_op = play->
var2op(dep_taddr[i]);
335 size_t last_user_i_op = 0;
336 size_t cexp_index = num_cexp_op;
347 enum_usage use_result = opt_op_info[i_op].usage;
385 {
size_t j_op = play->
var2op(arg[0]);
387 play, sum_op, i_op, j_op, opt_op_info, cexp_set
404 {
size_t j_op = play->
var2op(arg[1]);
406 play, sum_op, i_op, j_op, opt_op_info, cexp_set
422 {
for(
size_t i = 0; i < 2; i++)
423 {
size_t j_op = play->
var2op(arg[i]);
425 play, sum_op, i_op, j_op, opt_op_info, cexp_set
435 cexp2op[ cexp_index ] = i_op;
441 {
size_t j_op = play->
var2op(arg[2]);
443 play, sum_op, i_op, j_op, opt_op_info, cexp_set
448 {
size_t j_op = play->
var2op(arg[3]);
450 play, sum_op, i_op, j_op, opt_op_info, cexp_set
454 bool same_variable = bool(arg[1] & 4) && bool(arg[1] & 8);
455 same_variable &= arg[4] == arg[5];
459 {
size_t j_op = play->
var2op(arg[4]);
460 bool can_skip = conditional_skip & (! same_variable);
461 can_skip &= opt_op_info[j_op].usage ==
no_usage;
463 play, sum_op, i_op, j_op, opt_op_info, cexp_set
469 size_t element = 2 * cexp_index + 0;
478 {
size_t j_op = play->
var2op(arg[5]);
479 bool can_skip = conditional_skip & (! same_variable);
480 can_skip &= opt_op_info[j_op].usage ==
no_usage;
482 play, sum_op, i_op, j_op, opt_op_info, cexp_set
488 size_t element = 2 * cexp_index + 1;
517 size_t j_op = play->
var2op(arg[1]);
519 play, sum_op, i_op, j_op, opt_op_info, cexp_set
524 size_t j_op = play->
var2op(arg[3]);
526 play, sum_op, i_op, j_op, opt_op_info, cexp_set
545 size_t j_op = play->
var2op(arg[1]);
547 play, sum_op, i_op, j_op, opt_op_info, cexp_set
559 size_t j_op = play->
var2op(arg[0]);
561 play, sum_op, i_op, j_op, opt_op_info, cexp_set
576 for(
size_t i = 0; i < 2; i++)
577 {
size_t j_op = play->
var2op(arg[i]);
579 play, sum_op, i_op, j_op, opt_op_info, cexp_set
593 {
size_t i_vec = arg2vecad[ arg[0] ];
594 vecad_used[i_vec] =
true;
602 {
size_t i_vec = arg2vecad[ arg[0] ];
603 vecad_used[i_vec] =
true;
605 size_t j_op = play->
var2op(arg[1]);
613 if( vecad_used[ arg2vecad[ arg[0] ] ] )
616 size_t j_op = play->
var2op(arg[2]);
624 if( vecad_used[ arg2vecad[ arg[0] ] ] )
627 size_t j_op = play->
var2op(arg[1]);
629 size_t k_op = play->
var2op(arg[2]);
640 size_t num_add = size_t( arg[0] );
641 size_t num_sub = size_t( arg[1] );
642 for(
size_t i = 0; i < num_add + num_sub; i++)
643 {
size_t j_op = play->
var2op( arg[3 + i] );
645 play, sum_op, i_op, j_op, opt_op_info, cexp_set
657 size_t user_index = arg[0];
666 last_user_i_op = i_op;
669 opt_op_info[last_user_i_op].usage ==
no_usage
672 if( cexp_set.
n_set() > 0 )
681 user_pack = user_atom->
sparsity() ==
683 user_bool = user_atom->
sparsity() ==
691 { user_r_pack.
resize( user_m );
692 user_s_pack.
resize( user_n );
693 for(
size_t i = 0; i < user_m; i++)
694 user_r_pack[ i ] =
false;
697 { user_r_bool.
resize( user_m );
698 user_s_bool.
resize( user_n );
699 for(
size_t i = 0; i < user_m; i++)
700 user_r_bool[ i ] =
false;
703 { user_s_set.
resize(user_n);
704 user_r_set.
resize(user_m);
705 for(
size_t i = 0; i < user_m; i++)
706 user_r_set[i].clear();
719 i_op + user_n + user_m + 1 == last_user_i_op
723 bool user_ok =
false;
727 user_q, user_r_pack, user_s_pack, user_x
730 user_q, user_r_pack, user_s_pack
735 user_q, user_r_bool, user_s_bool, user_x
738 user_q, user_r_bool, user_s_bool
743 user_q, user_r_set, user_s_set, user_x
746 user_q, user_r_set, user_s_set
751 "Optimizing an ADFun object"
752 " that contains the atomic function\n\t";
754 s +=
"\nCurrent atomic_sparsity is set to ";
757 s +=
"set_sparsity_enum.\n";
759 s +=
"bool_sparsity_enum.\n";
761 s +=
"pack_sparsity_enum.\n";
763 s +=
"This version of rev_sparse_jac returned false";
767 if( opt_op_info[last_user_i_op].usage !=
no_usage )
768 for(
size_t j = 0; j < user_n; j++)
771 bool use_arg_j =
false;
773 {
if( ! user_s_set[j].empty() )
777 {
if( user_s_bool[j] )
781 {
if( user_s_pack[j] )
785 {
size_t j_op = play->
var2op(user_ix[j]);
787 sum_op, last_user_i_op, j_op, opt_op_info, cexp_set
792 if( cexp_set.
n_set() > 0 )
793 cexp_set.
assignment(i_op, last_user_i_op, cexp_set);
796 for(
size_t j = 0; j < user_n + user_m + 1; ++j)
797 opt_op_info[i_op + j].usage = opt_op_info[last_user_i_op].usage;
815 user_x[user_j] = parameter[arg[0]];
830 user_ix[user_j] = arg[0];
849 user_r_set[user_i].insert(0);
851 user_r_bool[user_i] =
true;
853 user_r_pack[user_i] =
true;
856 play, sum_op, i_op, last_user_i_op, opt_op_info, cexp_set
885 for(i_op = 0; i_op < num_op; ++i_op)
886 { opt_op_info[i_op].previous = 0;
888 if( opt_op_info[i_op].usage ==
yes_usage )
889 switch( play->
GetOp(i_op) )
965 match_op(play, opt_op_info, i_op, hash_table_op );
966 if( opt_op_info[i_op].previous != 0 )
968 size_t previous = opt_op_info[i_op].previous;
972 play, sum_op, i_op, previous, opt_op_info, cexp_set
981 if( cexp_set.
n_set() == 0 )
985 cexp_info.
resize(num_cexp_op);
986 skip_op_true.
resize(num_cexp_op, num_op);
987 skip_op_false.
resize(num_cexp_op, num_op);
989 for(
size_t i = 0; i < num_cexp_op; i++)
991 opt_op_info[i].previous == 0 || opt_op_info[i].usage ==
yes_usage
1002 info.
right = arg[3];
1007 index = std::max(index, info.
left);
1009 index = std::max(index, info.
right);
1013 cexp_info[i] = info;
1017 while(i_op < num_op)
1018 {
size_t j_op = i_op;
1019 bool keep = opt_op_info[i_op].usage !=
no_usage;
1020 keep &= opt_op_info[i_op].usage !=
csum_usage;
1021 keep &= opt_op_info[i_op].previous == 0;
1024 if( *itr != cexp_set.
end() )
1030 {
switch( play->
GetOp(j_op) )
1044 while( *itr != cexp_set.
end() )
1045 {
size_t element = *itr;
1046 size_t index = element / 2;
1047 bool compare = bool( element % 2 );
1048 if( compare ==
false )
1068 i_op += (1 + j_op) - i_op;
This operator is only used once, it is a summation operator, and its parrent is a summation operator...
virtual bool rev_sparse_jac(size_t q, const vector< std::set< size_t > > &rt, vector< std::set< size_t > > &st, const vector< Base > &x)
Link, after case split, from rev_jac_sweep to atomic_base.
void assignment(size_t this_target, size_t other_source, const sparse_list &other)
Assign one set equal to another set.
#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.
This operator is not used.
size_t num_par_rec(void) const
Fetch number of parameters in the recording.
void add_element(size_t i, size_t element)
Add one element to a set.
size_t max_left_right
maximum variable index between left and right (ignoring parameters).
The CppAD Simple Vector template class.
void binary_intersection(size_t this_target, size_t this_left, size_t other_right, const sparse_list &other)
Assign a set equal to the intersection of two other sets.
static std::vector< atomic_base * > & class_object(void)
List of all the object in this class.
size_t num_vec_ind_rec(void) const
Fetch number of VecAD indices in the recording.
CPPAD_TAPE_ADDR_TYPE addr_t
static Float quiet_NaN(void)
not a number
next UsrrpOp (UsrrvOp) is a parameter (variable) result
size_t NumArg(OpCode op)
Number of arguments for a specified operator.
Class used to store and play back an operation sequence recording.
size_t GetVecInd(size_t i) const
Fetch a VecAD index from the recording.
Check if current operator matches a previous operator.
void resize(size_t n)
change the number of elements in this vector.
size_t NumRes(OpCode op)
Number of variables resulting from the specified operation.
void match_op(const player< Base > *play, vector< struct_opt_op_info > &opt_op_info, size_t current, sparse_list &hash_table_op)
Search for a previous operator that matches the current one.
Create operator information tables.
next UserOp marks end of a user atomic call
size_t left
variable or parameter index for left comparison operand
virtual void set_old(size_t id)
Set value of id (used by deprecated old_atomic class)
size_t size(void) const
number of elements currently in this vector.
OpCode
Type used to distinguish different AD< Base > atomic operations.
void usage_cexp_result2arg(const player< Base > *play, bool sum_result, size_t i_result, size_t i_arg, vector< struct_opt_op_info > &opt_op_info, sparse_list &cexp_set)
Increarse argument usage and propagate cexp_set from result to argument.
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
Information about one conditional expression.
option_enum sparsity(void) const
current sparsity setting
Information about one conditional expression.
size_t num_vecad_vec_rec(void) const
Fetch number of VecAD vectors in the recording.
next UsrapOp (UsravOp) is a parameter (variable) argument
size_t right
variable or parameter index for right comparison operand
#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.
void resize(size_t n_set, size_t end)
Start a new vector of sets.
size_t num_op_rec(void) const
Fetch number of operators in the recording.
#define CPPAD_ASSERT_NARG_NRES(op, n_arg, n_res)
Check that operator op has the specified number of of arguments and results.
size_t n_set(void) const
Fetch n_set for vector of sets object.
const std::string & afun_name(void) const
Name corresponding to a base_atomic object.
bool add_or_subtract(OpCode op)
Is this an addition or subtraction operator.
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.
void resize(size_t n)
change number of elements in this vector
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...
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.
size_t i_op
The operator index for this conditional expression operation.
OpCode GetOp(size_t i) const
fetch an operator from the recording.
#define CPPAD_HASH_TABLE_SIZE
the codes retruned by hash_code are between zero and CPPAD_HASH_TABLE_SIZE minus one.