/*! Moving an operation sequence from a recorder to a player \param rec the object that was used to record the operation sequence. After this operation, the state of the recording is no longer defined. For example, the \c pod_vector member variables in \c this have been swapped with \c rec . */ void get(recorder<Base>& rec) { size_t i; // just set size_t values num_var_rec_ = rec.num_var_rec_; num_load_op_rec_ = rec.num_load_op_rec_; // op_rec_ op_rec_.swap(rec.op_rec_); // vec_ind_rec_ vecad_ind_rec_.swap(rec.vecad_ind_rec_); // op_arg_rec_ op_arg_rec_.swap(rec.op_arg_rec_); // par_rec_ par_rec_.swap(rec.par_rec_); // text_rec_ text_rec_.swap(rec.text_rec_); // set the number of VecAD vectors num_vecad_vec_rec_ = 0; for(i = 0; i < vecad_ind_rec_.size(); i += vecad_ind_rec_[i] + 1) num_vecad_vec_rec_++; // vecad_ind_rec_ contains size of each VecAD followed by // the parameter indices used to iniialize it. CPPAD_ASSERT_UNKNOWN( i == vecad_ind_rec_.size() ); }
/*! Moving an operation sequence from a recorder to a player \param rec the object that was used to record the operation sequence. After this operation, the state of the recording is no longer defined. For example, the \c pod_vector member variables in \c this have been swapped with \c rec . */ void get(recorder<Base>& rec) { size_t i; // Var num_rec_var_ = rec.num_rec_var_; // Op rec_op_.swap(rec.rec_op_); // VecInd rec_vecad_ind_.swap(rec.rec_vecad_ind_); // Arg rec_op_arg_.swap(rec.rec_op_arg_); // Par rec_par_.swap(rec.rec_par_); // Txt rec_text_.swap(rec.rec_text_); // set the number of VecAD vectors num_rec_vecad_vec_ = 0; for(i = 0; i < rec_vecad_ind_.size(); i += rec_vecad_ind_[i] + 1) num_rec_vecad_vec_++; // rec_vecad_ind_ contains size of each VecAD followed by // the parameter indices used to iniialize it. CPPAD_ASSERT_UNKNOWN( i == rec_vecad_ind_.size() ); }
/// Fetch a rough measure of amount of memory used to store recording /// (just lengths, not capacities). size_t Memory(void) const { return op_rec_.size() * sizeof(OpCode) + op_arg_rec_.size() * sizeof(addr_t) + par_rec_.size() * sizeof(Base) + text_rec_.size() * sizeof(char) + vecad_ind_rec_.size() * sizeof(addr_t) ; }
/// Fetch a rough measure of amount of memory used to store recording /// (just lengths, not capacities). size_t Memory(void) const { return rec_op_.size() * sizeof(OpCode) + rec_op_arg_.size() * sizeof(addr_t) + rec_par_.size() * sizeof(Base) + rec_text_.size() * sizeof(char) + rec_vecad_ind_.size() * sizeof(addr_t) ; }
void reverse_start( OpCode& op, const addr_t*& op_arg, size_t& op_index, size_t& var_index) { op_arg = op_arg_ = op_arg_rec_.data() + op_arg_rec_.size(); op_index = op_index_ = op_rec_.size() - 1; var_index = var_index_ = num_var_rec_ - 1; op = op_ = OpCode( op_rec_[ op_index_ ] ); CPPAD_ASSERT_UNKNOWN( op_ == EndOp ); CPPAD_ASSERT_NARG_NRES(op, 0, 0); return; }
void start_reverse( OpCode& op, const addr_t*& op_arg, size_t& op_index, size_t& var_index) { op_arg_ = rec_op_arg_.size(); // index op_arg = op_arg_ + rec_op_arg_.data(); // pointer op_index = op_index_ = rec_op_.size() - 1; var_index = var_index_ = num_rec_var_ - 1; op = op_ = OpCode( rec_op_[ op_index_ ] ); CPPAD_ASSERT_UNKNOWN( op_ == EndOp ); CPPAD_ASSERT_NARG_NRES(op, 0, 0); return; }
void reverse_cskip( OpCode& op, const addr_t*& op_arg, size_t& op_index, size_t& var_index) { using CppAD::NumRes; using CppAD::NumArg; CPPAD_ASSERT_UNKNOWN( op_ == op ); CPPAD_ASSERT_UNKNOWN( op_arg == op_arg_ ); CPPAD_ASSERT_UNKNOWN( op_index == op_index_ ); CPPAD_ASSERT_UNKNOWN( var_index == var_index_ ); CPPAD_ASSERT_UNKNOWN( op == CSkipOp ); CPPAD_ASSERT_UNKNOWN( NumArg(CSkipOp) == 0 ); /* The variables that need fixing are op_arg_ and op_arg. Currently, op_arg points first arugment for the previous operator. */ --op_arg; op_arg = op_arg_ -= (op_arg[0] + 4); CPPAD_ASSERT_UNKNOWN( op_arg[1] + op_arg[2] == op_arg[ 3 + op_arg[1] + op_arg[2] ] ); CPPAD_ASSERT_UNKNOWN( op_index_ < op_rec_.size() ); CPPAD_ASSERT_UNKNOWN( op_arg_rec_.data() <= op_arg_ ); CPPAD_ASSERT_UNKNOWN( var_index_ < num_var_rec_ ); }
/*! Fetch the next operator during a reverse sweep. Use reverse_start to initialize to reverse play back. The first call to reverse_next (after reverse_start) will give the last operator in the recording. We use the notation reverse_routine to denote the set reverse_start, reverse_next, reverse_csum, reverse_cskip. \param op [in,out] The input value of \c op must be its output value from the previous call to a reverse_routine. Its output value is the next operator in the recording (in reverse order). The last operator sets op equal to EndOp. \param op_arg [in,out] The input value of \c op_arg must be its output value from the previous call to a reverse_routine. Its output value is the beginning of the vector of argument indices for this operation. The last operator sets op_arg equal to the beginning of the argument indices for the entire recording. For speed, \c reverse_next does not check for the special cases <tt>op == CSumOp</tt> or <tt>op == CSkipOp</tt>. In these cases, the other return values from \c reverse_next must be corrected by a call to \c reverse_csum or \c reverse_cskip respectively. \param op_index [in,out] The input value of \c op_index must be its output value from the previous call to a reverse_routine. Its output value is the index of this operator in the recording. Thus the output value following the previous call to reverse_start is equal to the number of variables in the recording minus one. In addition, the output value decreases by one with each call to reverse_next. The last operator sets op_index equal to 0. \param var_index [in,out] The input value of \c var_index must be its output value from the previous call to a reverse_routine. Its output value is the index of the primary (last) result corresponding to the operator op. The last operator sets var_index equal to 0 (corresponding to BeginOp at beginning of operation sequence). */ void reverse_next( OpCode& op, const addr_t*& op_arg, size_t& op_index, size_t& var_index) { using CppAD::NumRes; using CppAD::NumArg; CPPAD_ASSERT_UNKNOWN( op_ == op ); CPPAD_ASSERT_UNKNOWN( op_arg == op_arg_ ); CPPAD_ASSERT_UNKNOWN( op_index == op_index_ ); CPPAD_ASSERT_UNKNOWN( var_index == var_index_ ); // index of the last result for the next operator CPPAD_ASSERT_UNKNOWN( var_index_ >= NumRes(op_) ); var_index = var_index_ -= NumRes(op_); // next operator CPPAD_ASSERT_UNKNOWN( op_index_ > 0 ); op_index = --op_index_; // index op = op_ = OpCode( op_rec_[ op_index_ ] ); // value // first argument for next operator op_arg = op_arg_ -= NumArg(op); CPPAD_ASSERT_UNKNOWN( op_arg_rec_.data() <= op_arg_ ); CPPAD_ASSERT_UNKNOWN( op_arg_ + NumArg(op) <= op_arg_rec_.data() + op_arg_rec_.size() ); }
/*! Correct \c forward_next return values when <tt>op == CSkipOp</tt>. \param op [in] The input value of op must be the return value from the previous call to \c forward_next and must be \c CSkipOp. It is not modified. \param op_arg [in,out] The input value of \c op_arg must be the return value from the previous call to \c forward_next. Its output value is the beginning of the vector of argument indices for the next operation. \param op_index [in] The input value of \c op_index does must be the return value from the previous call to \c forward_next. Its is not modified. \param var_index [in,out] The input value of \c var_index must be the return value from the previous call to \c forward_next. It is not modified. */ void forward_cskip( OpCode& op, const addr_t*& op_arg, size_t& op_index, size_t& var_index) { using CppAD::NumRes; using CppAD::NumArg; CPPAD_ASSERT_UNKNOWN( op_ == op ); CPPAD_ASSERT_UNKNOWN( op_arg == op_arg_ ); CPPAD_ASSERT_UNKNOWN( op_index == op_index_ ); CPPAD_ASSERT_UNKNOWN( var_index == var_index_ ); CPPAD_ASSERT_UNKNOWN( op == CSkipOp ); CPPAD_ASSERT_UNKNOWN( NumArg(CSkipOp) == 0 ); CPPAD_ASSERT_UNKNOWN( op_arg[4] + op_arg[5] == op_arg[ 6 + op_arg[4] + op_arg[5] ] ); /* The only thing that really needs fixing is op_arg_. Actual number of arugments for this operator is 7 + op_arg[4] + op_arg[5] We must change op_arg_ so that when you add NumArg(CSkipOp) you get first argument for next operator in sequence. */ op_arg = op_arg_ += 7 + op_arg[4] + op_arg[5]; CPPAD_ASSERT_UNKNOWN( op_arg_rec_.data() <= op_arg_ ); CPPAD_ASSERT_UNKNOWN( op_arg_ + NumArg(op) <= op_arg_rec_.data() + op_arg_rec_.size() ); CPPAD_ASSERT_UNKNOWN( var_index_ < num_var_rec_ ); }
/*! Fetch the next operator during a forward sweep. Use forward_start to initialize to the first operator; i.e., the BeginOp at the beginning of the recording. We use the notation forward_routine to denote the set forward_start, forward_next, forward_csum, forward_cskip. \param op [in,out] The input value of \c op must be its output value from the previous call to a forward_routine. Its output value is the next operator in the recording. For speed, \c forward_next does not check for the special cases where <tt>op == CSumOp</tt> or <tt>op == CSkipOp</tt>. In these cases, the other return values from \c forward_next must be corrected by a call to \c forward_csum or \c forward_cskip respectively. \param op_arg [in,out] The input value of \c op_arg must be its output value form the previous call to a forward routine. Its output value is the beginning of the vector of argument indices for this operation. \param op_index [in,out] The input value of \c op_index must be its output value form the previous call to a forward routine. Its output value is the index of the next operator in the recording. Thus the ouput value following the previous call to forward_start is one. In addition, the output value increases by one with each call to forward_next. \param var_index [in,out] The input value of \c var_index must be its output value form the previous call to a forward routine. Its output value is the index of the primary (last) result corresponding to the operator op. */ void forward_next( OpCode& op, const addr_t*& op_arg, size_t& op_index, size_t& var_index) { using CppAD::NumRes; using CppAD::NumArg; CPPAD_ASSERT_UNKNOWN( op_ == op ); CPPAD_ASSERT_UNKNOWN( op_arg == op_arg_ ); CPPAD_ASSERT_UNKNOWN( op_index == op_index_ ); CPPAD_ASSERT_UNKNOWN( var_index == var_index_ ); // index for the next operator op_index = ++op_index_; // first argument for next operator op_arg = op_arg_ += NumArg(op_); // next operator op = op_ = OpCode( op_rec_[ op_index_ ] ); // index for last result for next operator var_index = var_index_ += NumRes(op); CPPAD_ASSERT_UNKNOWN( op_arg_rec_.data() <= op_arg_ ); CPPAD_ASSERT_UNKNOWN( op_arg_ + NumArg(op) <= op_arg_rec_.data() + op_arg_rec_.size() ); CPPAD_ASSERT_UNKNOWN( var_index_ < num_var_rec_ ); }
static int xconvert(const char* x, pod_vector<T>& out, const char** errPos, int sep) { if (sep == 0) { sep = Potassco::def_sep; } typename pod_vector<T>::size_type sz = out.size(); std::size_t t = Potassco::convert_seq<T>(x, out.max_size() - sz, std::back_inserter(out), static_cast<char>(sep), errPos); if (!t) { out.resize(sz); } return static_cast<int>(t); }
void get_internal_sparsity( bool transpose , const pod_vector<size_t>& internal_index , const InternalSparsity& internal_pattern , vector<bool>& pattern_out ) { typedef typename InternalSparsity::const_iterator iterator; // number variables size_t nr = internal_index.size(); // // column size of interanl sparstiy pattern size_t nc = internal_pattern.end(); // pattern_out.resize(nr * nc); for(size_t ij = 0; ij < nr * nc; ij++) pattern_out[ij] = false; // for(size_t i = 0; i < nr; i++) { CPPAD_ASSERT_UNKNOWN( internal_index[i] < internal_pattern.n_set() ); iterator itr(internal_pattern, internal_index[i]); size_t j = *itr; while( j < nc ) { if( transpose ) pattern_out[j * nr + i] = true; else pattern_out[i * nc + j] = true; j = *(++itr); } } return; }
void get_internal_sparsity( bool transpose , const pod_vector<size_t>& internal_index , const InternalSparsity& internal_pattern , vector< std::set<size_t> >& pattern_out ) { typedef typename InternalSparsity::const_iterator iterator; // number variables size_t nr = internal_index.size(); // // column size of interanl sparstiy pattern size_t nc = internal_pattern.end(); // if( transpose ) pattern_out.resize(nc); else pattern_out.resize(nr); for(size_t k = 0; k < pattern_out.size(); k++) pattern_out[k].clear(); // for(size_t i = 0; i < nr; i++) { CPPAD_ASSERT_UNKNOWN( internal_index[i] < internal_pattern.n_set() ); iterator itr(internal_pattern, internal_index[i]); size_t j = *itr; while( j < nc ) { if( transpose ) pattern_out[j].insert(i); else pattern_out[i].insert(j); j = *(++itr); } } return; }
void reverse_csum( OpCode& op, const addr_t*& op_arg, size_t& op_index, size_t& var_index) { using CppAD::NumRes; using CppAD::NumArg; CPPAD_ASSERT_UNKNOWN( op_ == op ); CPPAD_ASSERT_UNKNOWN( op_arg == op_arg_ ); CPPAD_ASSERT_UNKNOWN( op_index == op_index_ ); CPPAD_ASSERT_UNKNOWN( var_index == var_index_ ); CPPAD_ASSERT_UNKNOWN( op == CSumOp ); CPPAD_ASSERT_UNKNOWN( NumArg(CSumOp) == 0 ); /* The variables that need fixing are op_arg_ and op_arg. Currently, op_arg points to the last argument for the previous operator. */ // last argument for this csum operation --op_arg; // first argument for this csum operation op_arg = op_arg_ -= (op_arg[0] + 4); // now op_arg points to the first argument for this csum operator CPPAD_ASSERT_UNKNOWN( op_arg[0] + op_arg[1] == op_arg[ 3 + op_arg[0] + op_arg[1] ] ); CPPAD_ASSERT_UNKNOWN( op_index_ < op_rec_.size() ); CPPAD_ASSERT_UNKNOWN( op_arg_rec_.data() <= op_arg_ ); CPPAD_ASSERT_UNKNOWN( var_index_ < num_var_rec_ ); }
void reverse_csum( OpCode& op, const addr_t*& op_arg, size_t& op_index, size_t& var_index) { using CppAD::NumRes; using CppAD::NumArg; CPPAD_ASSERT_UNKNOWN( op == CSumOp ); CPPAD_ASSERT_UNKNOWN( NumArg(CSumOp) == 0 ); /* The things needs fixing are op_arg_ and op_arg. Currently, op_arg points first arugment for the previous operator. */ --op_arg; op_arg_ -= (op_arg[0] + 4); op_arg = op_arg_ + rec_op_arg_.data(); CPPAD_ASSERT_UNKNOWN( op_arg[0] + op_arg[1] == op_arg[ 3 + op_arg[0] + op_arg[1] ] ); CPPAD_ASSERT_UNKNOWN( op_index_ < rec_op_.size() ); CPPAD_ASSERT_UNKNOWN( op_arg_ + NumArg(op) <= rec_op_arg_.size() ); CPPAD_ASSERT_UNKNOWN( var_index_ < num_rec_var_ ); }
void set_internal_sparsity( bool zero_empty , bool input_empty , bool transpose , const pod_vector<size_t>& internal_index , InternalSparsity& internal_pattern , const vector< std::set<size_t> >& pattern_in ) { size_t nr = internal_index.size(); size_t nc = internal_pattern.end(); # ifndef NDEBUG if( input_empty ) for(size_t i = 0; i < nr; i++) { size_t i_var = internal_index[i]; CPPAD_ASSERT_UNKNOWN( internal_pattern.number_elements(i_var) == 0 ); } # endif if( transpose ) { CPPAD_ASSERT_UNKNOWN( pattern_in.size() == nc ); for(size_t j = 0; j < nc; j++) { std::set<size_t>::const_iterator itr( pattern_in[j].begin() ); while( itr != pattern_in[j].end() ) { size_t i = *itr; size_t i_var = internal_index[i]; CPPAD_ASSERT_UNKNOWN( i_var < internal_pattern.n_set() ); CPPAD_ASSERT_UNKNOWN( j < nc ); bool ignore = zero_empty && i_var == 0; if( ! ignore ) internal_pattern.post_element( i_var, j); ++itr; } } } else { CPPAD_ASSERT_UNKNOWN( pattern_in.size() == nr ); for(size_t i = 0; i < nr; i++) { std::set<size_t>::const_iterator itr( pattern_in[i].begin() ); while( itr != pattern_in[i].end() ) { size_t j = *itr; size_t i_var = internal_index[i]; CPPAD_ASSERT_UNKNOWN( i_var < internal_pattern.n_set() ); CPPAD_ASSERT_UNKNOWN( j < nc ); bool ignore = zero_empty && i_var == 0; if( ! ignore ) internal_pattern.post_element( i_var, j); ++itr; } } } // process posts for(size_t i = 0; i < nr; ++i) internal_pattern.process_post( internal_index[i] ); return; }
void get_internal_sparsity( bool transpose , const pod_vector<size_t>& internal_index , const InternalSparsity& internal_pattern , sparse_rc<SizeVector>& pattern_out ) { typedef typename InternalSparsity::const_iterator iterator; // number variables size_t nr = internal_index.size(); // column size of interanl sparstiy pattern size_t nc = internal_pattern.end(); // determine nnz, the number of possibly non-zero index pairs size_t nnz = 0; for(size_t i = 0; i < nr; i++) { CPPAD_ASSERT_UNKNOWN( internal_index[i] < internal_pattern.n_set() ); iterator itr(internal_pattern, internal_index[i]); size_t j = *itr; while( j < nc ) { ++nnz; j = *(++itr); } } // transposed if( transpose ) { pattern_out.resize(nc, nr, nnz); // size_t k = 0; for(size_t i = 0; i < nr; i++) { iterator itr(internal_pattern, internal_index[i]); size_t j = *itr; while( j < nc ) { pattern_out.set(k++, j, i); j = *(++itr); } } return; } // not transposed pattern_out.resize(nr, nc, nnz); // size_t k = 0; for(size_t i = 0; i < nr; i++) { iterator itr(internal_pattern, internal_index[i]); size_t j = *itr; while( j < nc ) { pattern_out.set(k++, i, j); j = *(++itr); } } return; }
void set_internal_sparsity( bool zero_empty , bool input_empty , bool transpose , const pod_vector<size_t>& internal_index , InternalSparsity& internal_pattern , const sparse_rc<SizeVector>& pattern_in ) { size_t nr = internal_index.size(); # ifndef NDEBUG size_t nc = internal_pattern.end(); if( transpose ) { CPPAD_ASSERT_UNKNOWN( pattern_in.nr() == nc ); CPPAD_ASSERT_UNKNOWN( pattern_in.nc() == nr ); } else { CPPAD_ASSERT_UNKNOWN( pattern_in.nr() == nr ); CPPAD_ASSERT_UNKNOWN( pattern_in.nc() == nc ); } if( input_empty ) for(size_t i = 0; i < nr; i++) { size_t i_var = internal_index[i]; CPPAD_ASSERT_UNKNOWN( internal_pattern.number_elements(i_var) == 0 ); } # endif const SizeVector& row( pattern_in.row() ); const SizeVector& col( pattern_in.col() ); size_t nnz = row.size(); for(size_t k = 0; k < nnz; k++) { size_t r = row[k]; size_t c = col[k]; if( transpose ) std::swap(r, c); // size_t i_var = internal_index[r]; CPPAD_ASSERT_UNKNOWN( i_var < internal_pattern.n_set() ); CPPAD_ASSERT_UNKNOWN( c < nc ); bool ignore = zero_empty && i_var == 0; if( ! ignore ) internal_pattern.post_element( internal_index[r], c ); } // process posts for(size_t i = 0; i < nr; ++i) internal_pattern.process_post( internal_index[i] ); }
void next_forward( OpCode& op, const addr_t*& op_arg, size_t& op_index, size_t& var_index) { using CppAD::NumRes; using CppAD::NumArg; // index for the next operator op_index = ++op_index_; // first argument for next operator op_arg_ += NumArg(op_); // index op_arg = op_arg_ + rec_op_arg_.data(); // pointer // next operator op = op_ = OpCode( rec_op_[ op_index_ ] ); // index for last result for next operator var_index = var_index_ += NumRes(op); CPPAD_ASSERT_UNKNOWN( op_arg_ + NumArg(op) <= rec_op_arg_.size() ); CPPAD_ASSERT_UNKNOWN( var_index_ < num_rec_var_ ); }
/*! Correct \c next_forward return values when <tt>op == CSumOp</tt>. \param op The input value of op must be the return value from the previous call to \c next_forward and must be \c CSumOp. \param op_arg The input value of *op_arg must be the return value from the previous call to \c next_forward. Its output value is the beginning of the vector of argument indices for this operation. \param op_index The input value of op_index does must be the return value from the previous call to \c next_forward. Its output value is the index of this operator in the recording. \param var_index The input value of var_index must be the return value from the previous call to \c next_forward. Its output value is the index of the primary (last) result corresponding to this. */ void forward_csum( OpCode& op, const addr_t*& op_arg, size_t& op_index, size_t& var_index) { using CppAD::NumRes; using CppAD::NumArg; CPPAD_ASSERT_UNKNOWN( op == CSumOp ); CPPAD_ASSERT_UNKNOWN( NumArg(CSumOp) == 0 ); CPPAD_ASSERT_UNKNOWN( op_arg[0] + op_arg[1] == op_arg[ 3 + op_arg[0] + op_arg[1] ] ); /* The only thing that really needs fixing is op_arg_. Actual number of arugments for this operator is op_arg[0] + op_arg[1] + 4. We must change op_arg_ so that when you add NumArg(CSumOp) you get first argument for next operator in sequence. */ op_arg_ += op_arg[0] + op_arg[1] + 4; CPPAD_ASSERT_UNKNOWN( op_arg_ + NumArg(op) <= rec_op_arg_.size() ); CPPAD_ASSERT_UNKNOWN( var_index_ < num_rec_var_ ); }
void set_internal_sparsity( bool zero_empty , bool input_empty , bool transpose , const pod_vector<size_t>& internal_index , InternalSparsity& internal_pattern , const vector<bool>& pattern_in ) { size_t nr = internal_index.size(); size_t nc = internal_pattern.end(); # ifndef NDEBUG CPPAD_ASSERT_UNKNOWN( pattern_in.size() == nr * nc ); if( input_empty ) for(size_t i = 0; i < nr; i++) { size_t i_var = internal_index[i]; CPPAD_ASSERT_UNKNOWN( internal_pattern.number_elements(i_var) == 0 ); } # endif for(size_t i = 0; i < nr; i++) { for(size_t j = 0; j < nc; j++) { bool flag = pattern_in[i * nc + j]; if( transpose ) flag = pattern_in[j * nr + i]; if( flag ) { size_t i_var = internal_index[i]; CPPAD_ASSERT_UNKNOWN( i_var < internal_pattern.n_set() ); CPPAD_ASSERT_UNKNOWN( j < nc ); bool ignore = zero_empty && i_var == 0; if( ! ignore ) internal_pattern.post_element( i_var, j); } } } // process posts for(size_t i = 0; i < nr; ++i) internal_pattern.process_post( internal_index[i] ); return; }
/// Fetch number of characters (representing strings) in the recording. size_t num_text_rec(void) const { return text_rec_.size(); }
/// Fetch number of characters (representing strings) in the recording. size_t num_rec_text(void) const { return rec_text_.size(); }
/// Fetch number of parameters in the recording. size_t num_rec_par(void) const { return rec_par_.size(); }
/// Fetch number of argument indices in the recording. size_t num_rec_op_arg(void) const { return rec_op_arg_.size(); }
/*! \brief Fetch a '\\0' terminated string from the recording. \return the beginning of the string. \param i the index where the string begins. */ const char *GetTxt(size_t i) const { CPPAD_ASSERT_UNKNOWN(i < rec_text_.size() ); return rec_text_.data() + i; }
/// Fetch number of parameters in the recording. size_t num_par_rec(void) const { return par_rec_.size(); }
/// Fetch number of operators in the recording. size_t num_rec_op(void) const { return rec_op_.size(); }
/// Fetch number of VecAD indices in the recording. size_t num_rec_vecad_ind(void) const { return rec_vecad_ind_.size(); }
void subgraph_info::get_rev( const play::const_random_iterator<Addr>& random_itr , const pod_vector<size_t>& dep_taddr , addr_t i_dep , pod_vector<addr_t>& subgraph ) { // check sizes CPPAD_ASSERT_UNKNOWN( map_user_op_.size() == n_op_ ); // process_range_ CPPAD_ASSERT_UNKNOWN( process_range_[i_dep] == false ); process_range_[i_dep] = true; // special value; see init_rev_in_subgraph addr_t depend_yes = addr_t( n_dep_ ); // assumption on i_dep CPPAD_ASSERT_UNKNOWN( i_dep < depend_yes ); // start with an empty subgraph for this dependent variable subgraph.resize(0); // tape index corresponding to this dependent variable size_t i_var = dep_taddr[i_dep]; // operator corresponding to this dependent variable size_t i_op = random_itr.var2op(i_var); i_op = size_t( map_user_op_[i_op] ); // if this variable depends on the selected indepent variables // process its subgraph CPPAD_ASSERT_UNKNOWN( in_subgraph_[i_op] != i_dep ) if( in_subgraph_[i_op] <= depend_yes ) { subgraph.push_back( addr_t(i_op) ); in_subgraph_[i_op] = i_dep; } // space used to return set of arguments that are variables pod_vector<size_t> argument_variable; // temporary space used by get_argument_variable pod_vector<bool> work; // scan all the operators in this subgraph size_t sub_index = 0; while(sub_index < subgraph.size() ) { // this operator connected to this dependent and selected independent i_op = size_t( subgraph[sub_index] ); CPPAD_ASSERT_UNKNOWN( in_subgraph_[i_op] == i_dep ); // // There must be a result for this operator # ifndef NDEBUG OpCode op = random_itr.get_op(i_op); CPPAD_ASSERT_UNKNOWN(op == AFunOp || NumRes(op) > 0 ); # endif // // which variables are connected to this operator get_argument_variable(random_itr, i_op, argument_variable, work); for(size_t j = 0; j < argument_variable.size(); ++j) { // add the corresponding operators to the subgraph size_t j_var = argument_variable[j]; size_t j_op = random_itr.var2op(j_var); j_op = size_t( map_user_op_[j_op] ); bool add = in_subgraph_[j_op] <= depend_yes; add &= in_subgraph_[j_op] != i_dep; if( random_itr.get_op(j_op) == InvOp ) { CPPAD_ASSERT_UNKNOWN( j_op == j_var ); add &= select_domain_[j_var - 1]; } if( add ) { subgraph.push_back( addr_t(j_op) ); in_subgraph_[j_op] = i_dep; } } // we are done scaning this subgraph operator ++sub_index; } }