1 # ifndef CPPAD_CORE_ATOMIC_BASE_HPP 
    2 # define CPPAD_CORE_ATOMIC_BASE_HPP 
   78      work_struct* 
work_[CPPAD_MAX_NUM_THREADS];
 
   85           static std::vector<atomic_base *> list_;
 
   91           static std::vector<std::string> list_;
 
  222           "Attempt to use the atomic_base default constructor" 
  237           const std::string&     name,
 
  244           "atomic_base: constructor cannot be called in parallel mode." 
  251      for(
size_t thread = 0; thread < CPPAD_MAX_NUM_THREADS; thread++)
 
  252           work_[thread] = CPPAD_NULL;
 
  262      for(
size_t thread = 0; thread < CPPAD_MAX_NUM_THREADS; thread++)
 
  267 {    
if( 
work_[thread] == CPPAD_NULL )
 
  269           size_t min_bytes = 
sizeof(work_struct);
 
  273           work_[thread]    = 
reinterpret_cast<work_struct*
>( v_ptr );
 
  275           new( 
work_[thread] ) work_struct;
 
  281 {    
if( 
work_[thread] != CPPAD_NULL )
 
  283           work_[thread]->~work_struct();
 
  287           work_[thread] = CPPAD_NULL;
 
  366 {    
switch( option_value )
 
  376                "atoic_base::option: option_value is not valid" 
  471 template <
class ADVector>
 
  477      size_t n = ax.size();
 
  478      size_t m = ay.size();
 
  481      std::string msg = 
"atomic_base: " + 
afun_name() + 
".eval: ";
 
  482      if( (n == 0) | (m == 0) )
 
  483      {    msg += 
"ax.size() or ay.size() is zero";
 
  506      for(j = 0; j < n; j++)
 
  507      {    tx[j]  = ax[j].value_;
 
  512                {    tape    = ax[j].tape_this();
 
  513                     tape_id = ax[j].tape_id_;
 
  517                if( tape_id != ax[j].tape_id_ )
 
  519                     ": ax contains variables from different threads.";
 
  531      ok = 
forward(p, q, vx, vy, tx, ty);
 
  533      {    msg += 
afun_name() + 
": ok is false for " 
  534                "zero order forward mode calculation.";
 
  538      bool record_operation = 
false;
 
  539      for(i = 0; i < m; i++)
 
  542           ay[i].value_ = ty[i];
 
  550           record_operation |= vy[i];
 
  553      if( record_operation & (tape == CPPAD_NULL) )
 
  555           "all elements of vx are false but vy contains a true element";
 
  560      if( record_operation )
 
  566                std::max( std::max( std::max(
index_, 
id), n), m ),
 
  567                "atomic_base: cppad_tape_addr_type maximum not large enough" 
  577           for(j = 0; j < n; j++)
 
  580                     tape->
Rec_.PutArg(ax[j].taddr_);
 
  586                     tape->
Rec_.PutArg(par);
 
  596           for(i = 0; i < m; i++)
 
  599                     ay[i].tape_id_  = tape_id;
 
  602                {    
addr_t par = tape->
Rec_.PutPar(ay[i].value_);
 
  603                     tape->
Rec_.PutArg(par);
 
  610                std::max( std::max( std::max(
index_, 
id), n), m ),
 
  611                "atomic_base: cppad_tape_addr_type maximum not large enough" 
 1187      const vector< std::set<size_t> >&       r  ,
 
 1188            vector< std::set<size_t> >&       s  ,
 
 1206      const vector< std::set<size_t> >&       r  ,
 
 1207            vector< std::set<size_t> >&       s  )
 
 1245 template <
class InternalSparsity>
 
 1250      InternalSparsity&          var_sparsity )
 
 1253      size_t q           = var_sparsity.end();
 
 1254      bool   input_empty = 
true;
 
 1255      bool   zero_empty  = 
true;
 
 1256      bool   transpose   = 
false;
 
 1257      size_t m           = y_index.
size();
 
 1262      std::string msg    = 
": atomic_base.for_sparse_jac: returned false";
 
 1267                transpose, x_index, var_sparsity, pack_r
 
 1275           {    msg = 
afun_name() + msg + 
" sparsity = pack_sparsity_enum";
 
 1279                transpose, y_index, var_sparsity, pack_s
 
 1286                transpose, x_index, var_sparsity, bool_r
 
 1293           {    msg = 
afun_name() + msg + 
" sparsity = bool_sparsity_enum";
 
 1297                transpose, y_index, var_sparsity, bool_s
 
 1305                transpose, x_index, var_sparsity, set_r
 
 1313           {    msg = 
afun_name() + msg + 
" sparsity = set_sparsity_enum";
 
 1317                transpose, y_index, var_sparsity, set_s
 
 1458      const vector< std::set<size_t> >&       rt ,
 
 1459            vector< std::set<size_t> >&       st ,
 
 1477      const vector< std::set<size_t> >&       rt ,
 
 1478            vector< std::set<size_t> >&       st )
 
 1515 template <
class InternalSparsity>
 
 1520      InternalSparsity&          var_sparsity )
 
 1523      size_t q           = var_sparsity.end();
 
 1524      bool   input_empty = 
false;
 
 1525      bool   zero_empty  = 
true;
 
 1526      bool   transpose   = 
false;
 
 1527      size_t n           = x_index.
size();
 
 1532      std::string msg    = 
": atomic_base.rev_sparse_jac: returned false";
 
 1537                transpose, y_index, var_sparsity, pack_rt
 
 1545           {    msg = 
afun_name() + msg + 
" sparsity = pack_sparsity_enum";
 
 1549                transpose, x_index, var_sparsity, pack_st
 
 1556                transpose, y_index, var_sparsity, bool_rt
 
 1563           {    msg = 
afun_name() + msg + 
" sparsity = bool_sparsity_enum";
 
 1567                transpose, x_index, var_sparsity, bool_st
 
 1575                transpose, y_index, var_sparsity, set_rt
 
 1582           {    msg = 
afun_name() + msg + 
" sparsity = set_sparsity_enum";
 
 1586                transpose, x_index, var_sparsity, set_st
 
 1732      vector< std::set<size_t> >&     h  ,
 
 1754      vector< std::set<size_t> >&     h  )
 
 1802 template <
class InternalSparsity>
 
 1807      const InternalSparsity&    for_jac_sparsity ,
 
 1808      const InternalSparsity&    rev_jac_sparsity ,
 
 1809      InternalSparsity&          for_hes_sparsity )
 
 1810 {    
typedef typename InternalSparsity::const_iterator const_iterator;
 
 1812      size_t n      = x_index.
size();
 
 1813      size_t m      = y_index.
size();
 
 1820      for(
size_t j = 0; j < n; j++)
 
 1821           vx[j] = x_index[j] != 0;
 
 1826      for(
size_t j = 0; j < n; j++)
 
 1828           const_iterator itr(for_jac_sparsity, x_index[j]);
 
 1830           bool_r[j] = i < for_jac_sparsity.end();
 
 1836      for(
size_t i = 0; i < m; i++)
 
 1838           bool_s[i] = rev_jac_sparsity.is_element(y_index[i], 0);
 
 1847      std::string msg    = 
": atomic_base.for_sparse_hes: returned false";
 
 1854           {    msg = 
afun_name() + msg + 
" sparsity = pack_sparsity_enum";
 
 1864           {    msg = 
afun_name() + msg + 
" sparsity = bool_sparsity_enum";
 
 1875           {    msg = 
afun_name() + msg + 
" sparsity = set_sparsity_enum";
 
 1882      for(
size_t i = 0; i < n; i++)
 
 1883      {    
for(
size_t j = 0; j < n; j++)
 
 1884           {    
if( (x_index[i] > 0) & (x_index[j] > 0) )
 
 1885                {    
bool flag = 
false;
 
 1888                          flag = pack_h[i * n + j];
 
 1892                          flag = bool_h[i * n + j];
 
 1896                          flag = set_h[i].find(j) != set_h[i].end();
 
 1900                     {    const_iterator itr_i(for_jac_sparsity, x_index[i]);
 
 1901                          size_t i_x = *itr_i;
 
 1902                          while( i_x < for_jac_sparsity.end() )
 
 1903                          {    for_hes_sparsity.binary_union(
 
 1904                                    i_x, i_x, x_index[j], for_jac_sparsity
 
 1908                          const_iterator itr_j(for_jac_sparsity, x_index[j]);
 
 1909                          size_t j_x = *itr_j;
 
 1910                          while( j_x < for_jac_sparsity.end() )
 
 1911                          {    for_hes_sparsity.binary_union(
 
 1912                                    j_x, j_x, x_index[i], for_jac_sparsity
 
 2145      const vector< std::set<size_t> >&       r  ,
 
 2146      const vector< std::set<size_t> >&       u  ,
 
 2147            vector< std::set<size_t> >&       v  ,
 
 2176      const vector< std::set<size_t> >&       r  ,
 
 2177      const vector< std::set<size_t> >&       u  ,
 
 2178            vector< std::set<size_t> >&       v  )
 
 2233 template <
class InternalSparsity>
 
 2238      const InternalSparsity&    for_jac_sparsity ,
 
 2239      bool*                      rev_jac_flag     ,
 
 2240      InternalSparsity&          rev_hes_sparsity )
 
 2242      size_t q           = rev_hes_sparsity.end();
 
 2243      size_t n           = x_index.
size();
 
 2244      size_t m           = y_index.
size();
 
 2248      bool   zero_empty  = 
true;
 
 2249      bool   input_empty = 
false;
 
 2250      bool   transpose   = 
false;
 
 2254      for(
size_t j = 0; j < n; j++)
 
 2255           vx[j] = x_index[j] != 0;
 
 2264      for(
size_t i = 0; i < m; i++)
 
 2265      {    
if( y_index[i] > 0  )
 
 2266                bool_s[i] = rev_jac_flag[ y_index[i] ];
 
 2269      std::string msg = 
": atomic_base.rev_sparse_hes: returned false";
 
 2278                transpose, x_index, for_jac_sparsity, pack_r
 
 2281                transpose, y_index, rev_hes_sparsity, pack_u
 
 2284           ok = 
rev_sparse_hes(vx, bool_s, bool_t, q, pack_r, pack_u, pack_v, x);
 
 2286                ok = 
rev_sparse_hes(vx, bool_s, bool_t, q, pack_r, pack_u, pack_v);
 
 2288           {    msg = 
afun_name() + msg + 
" sparsity = pack_sparsity_enum";
 
 2292                transpose, x_index, rev_hes_sparsity, pack_v
 
 2303                transpose, x_index, for_jac_sparsity, bool_r
 
 2306                transpose, y_index, rev_hes_sparsity, bool_u
 
 2309           ok = 
rev_sparse_hes(vx, bool_s, bool_t, q, bool_r, bool_u, bool_v, x);
 
 2311                ok = 
rev_sparse_hes(vx, bool_s, bool_t, q, bool_r, bool_u, bool_v);
 
 2313           {    msg = 
afun_name() + msg + 
" sparsity = bool_sparsity_enum";
 
 2317                transpose, x_index, rev_hes_sparsity, bool_v
 
 2329                transpose, x_index, for_jac_sparsity, set_r
 
 2332                transpose, y_index, rev_hes_sparsity, set_u
 
 2335           ok = 
rev_sparse_hes(vx, bool_s, bool_t, q, set_r, set_u, set_v, x);
 
 2339           {    msg = 
afun_name() + msg + 
" sparsity = set_sparsity_enum";
 
 2343                transpose, x_index, rev_hes_sparsity, set_v
 
 2346      for(
size_t j = 0; j < n; j++)
 
 2347      {    
if( x_index[j] > 0  )
 
 2348                rev_jac_flag[ x_index[j] ] |= bool_t[j];
 
 2399           "cannot use atomic_base clear during parallel execution" 
 2404           if( op != CPPAD_NULL )
 
 2405           {    
for(
size_t thread = 0; thread < CPPAD_MAX_NUM_THREADS; thread++)
 
virtual bool for_sparse_hes(const vector< bool > &vx, const vector< bool > &r, const vector< bool > &s, vector< bool > &h)
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. 
#define CPPAD_ASSERT_KNOWN(exp, msg)
Check that exp is true, if not print msg and terminate execution. 
vector< std::set< size_t > > set_s
virtual bool for_sparse_hes(const vector< bool > &vx, const vector< bool > &r, const vector< bool > &s, vectorBool &h)
void free_work(size_t thread)
frees work_ for a specified thread 
virtual bool for_sparse_hes(const vector< bool > &vx, const vector< bool > &r, const vector< bool > &s, vectorBool &h, const vector< Base > &x)
static std::vector< atomic_base * > & class_object(void)
List of all the object in this class. 
virtual bool rev_sparse_hes(const vector< bool > &vx, const vector< bool > &s, vector< bool > &t, size_t q, const vector< std::set< size_t > > &r, const vector< std::set< size_t > > &u, vector< std::set< size_t > > &v)
virtual bool rev_sparse_hes(const vector< bool > &vx, const vector< bool > &s, vector< bool > &t, size_t q, const vectorBool &r, const vectorBool &u, vectorBool &v, const vector< Base > &x)
static void return_memory(void *v_ptr)
Return memory that was obtained by get_memory. 
virtual bool for_sparse_jac(size_t q, const vectorBool &r, vectorBool &s, const vector< Base > &x)
CPPAD_TAPE_ADDR_TYPE addr_t
atomic_base(void)
Base class for atomic_user functions. 
void get_internal_sparsity(bool transpose, const vector< size_t > &internal_index, const InternalSparsity &internal_pattern, sparse_rc< SizeVector > &pattern_out)
Get sparsity pattern for a sub-set of variables. 
static bool in_parallel(void)
Are we in a parallel execution state; i.e., is it possible that other threads are currently executing...
virtual bool rev_sparse_jac(size_t q, const vector< bool > &rt, vector< bool > &st)
size_t NumArg(OpCode op)
Number of arguments for a specified operator. 
void for_sparse_jac(const vector< Base > &x, const vector< size_t > &x_index, const vector< size_t > &y_index, InternalSparsity &var_sparsity)
Link, before case split, from for_jac_sweep to atomic_base. 
virtual bool for_sparse_hes(const vector< bool > &vx, const vector< bool > &r, const vector< bool > &s, vector< std::set< size_t > > &h)
Define the CppAD error checking macros (all of which begin with CPPAD_ASSERT_) 
void for_sparse_hes(const vector< Base > &x, const vector< size_t > &x_index, const vector< size_t > &y_index, const InternalSparsity &for_jac_sparsity, const InternalSparsity &rev_jac_sparsity, InternalSparsity &for_hes_sparsity)
Link, before case split, from for_hes_sweep to atomic_base. 
static size_t thread_num(void)
Get current thread number. 
#define CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL
Check that the first call to a routine is not during parallel execution mode. 
virtual ~atomic_base(void)
destructor informs CppAD that this atomic function with this index has dropped out of scope by settin...
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. 
virtual bool for_sparse_hes(const vector< bool > &vx, const vector< bool > &r, const vector< bool > &s, vector< std::set< size_t > > &h, const vector< Base > &x)
Link, after case split, from for_hes_sweep to atomic_base. 
virtual bool forward(size_t p, size_t q, const vector< bool > &vx, vector< bool > &vy, const vector< Base > &tx, vector< Base > &ty)
Link from atomic_base to forward mode. 
virtual bool reverse(size_t q, const vector< Base > &tx, const vector< Base > &ty, vector< Base > &px, const vector< Base > &py)
Link from reverse mode sweep to users routine. 
virtual bool rev_sparse_jac(size_t q, const vector< std::set< size_t > > &rt, vector< std::set< size_t > > &st)
vector< std::set< size_t > > set_h
static std::vector< std::string > & class_name(void)
List of names for each object in this class. 
static void * get_memory(size_t min_bytes, size_t &cap_bytes)
Use thread_alloc to get a specified amount of memory. 
virtual bool for_sparse_jac(size_t q, const vector< bool > &r, vector< bool > &s)
vector< std::set< size_t > > set_r
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. 
static const std::string & class_name(size_t index)
atomic_base function name corresponding to a certain index 
void operator()(const ADVector &ax, ADVector &ay, size_t id=0)
Implement the user call to afun(ax, ay) and old_atomic call to afun(ax, ay, id). 
virtual bool for_sparse_jac(size_t q, const vector< std::set< size_t > > &r, vector< std::set< size_t > > &s)
virtual bool rev_sparse_hes(const vector< bool > &vx, const vector< bool > &s, vector< bool > &t, size_t q, const vectorBool &r, const vectorBool &u, vectorBool &v)
option_enum sparsity(void) const 
current sparsity setting 
virtual bool rev_sparse_hes(const vector< bool > &vx, const vector< bool > &s, vector< bool > &t, size_t q, const vector< bool > &r, const vector< bool > &u, vector< bool > &v, const vector< Base > &x)
static atomic_base * class_object(size_t index)
atomic_base function object corresponding to a certain index 
vector< std::set< size_t > > set_u
CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION bool Variable(const AD< Base > &x)
virtual bool rev_sparse_hes(const vector< bool > &vx, const vector< bool > &s, vector< bool > &t, size_t q, const vector< std::set< size_t > > &r, const vector< std::set< size_t > > &u, vector< std::set< size_t > > &v, const vector< Base > &x)
Link from reverse Hessian sparsity sweep to base_atomic. 
void allocate_work(size_t thread)
allocates work_ for a specified thread 
option_enum sparsity_
sparsity pattern this object is currently using (set by constructor and option member functions) ...
#define CPPAD_ASSERT_UNKNOWN(exp)
Check that exp is true, if not terminate execution. 
virtual bool for_sparse_jac(size_t q, const vectorBool &r, vectorBool &s)
work_struct * work_[CPPAD_MAX_NUM_THREADS]
const size_t index_
index of this object in class_object 
local::recorder< Base > Rec_
This is where the information is recorded. 
virtual bool rev_sparse_jac(size_t q, const vectorBool &rt, vectorBool &st)
static void clear(void)
Free all thread_alloc static memory held by atomic_base (avoids reallocations). 
Class used to hold tape that records AD<Base> operations. 
void rev_sparse_jac(const vector< Base > &x, const vector< size_t > &x_index, const vector< size_t > &y_index, InternalSparsity &var_sparsity)
Link, before case split, from rev_jac_sweep to atomic_base. 
virtual bool for_sparse_jac(size_t q, const vector< bool > &r, vector< bool > &s, const vector< Base > &x)
const std::string & afun_name(void) const 
Name corresponding to a base_atomic object. 
File used to define the CppAD multi-threading allocator class. 
void set_internal_sparsity(bool zero_empty, bool input_empty, bool transpose, const vector< size_t > &internal_index, InternalSparsity &internal_pattern, const sparse_rc< SizeVector > &pattern_in)
Update the internal sparsity pattern for a sub-set of rows. 
virtual bool rev_sparse_jac(size_t q, const vector< bool > &rt, vector< bool > &st, const vector< Base > &x)
void rev_sparse_hes(const vector< Base > &x, const vector< size_t > &x_index, const vector< size_t > &y_index, const InternalSparsity &for_jac_sparsity, bool *rev_jac_flag, InternalSparsity &rev_hes_sparsity)
Link, before case split, from rev_hes_sweep to atomic_base. 
virtual bool for_sparse_jac(size_t q, const vector< std::set< size_t > > &r, vector< std::set< size_t > > &s, const vector< Base > &x)
Link, after case split, from for_jac_sweep to atomic_base. 
Routines that enable code to be independent of which internal spasity pattern is used. 
void resize(size_t n)
change number of elements in this vector 
atomic_base(const std::string &name, option_enum sparsity=bool_sparsity_enum)
Constructor. 
virtual bool rev_sparse_jac(size_t q, const vectorBool &rt, vectorBool &st, const vector< Base > &x)
virtual bool rev_sparse_hes(const vector< bool > &vx, const vector< bool > &s, vector< bool > &t, size_t q, const vector< bool > &r, const vector< bool > &u, vector< bool > &v)
void option(enum option_enum option_value)
CPPAD_TAPE_ID_TYPE tape_id_t
virtual bool for_sparse_hes(const vector< bool > &vx, const vector< bool > &r, const vector< bool > &s, vector< bool > &h, const vector< Base > &x)
temporary work space used by member functions, declared here to avoid