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