Automatic Differentiation
 
Loading...
Searching...
No Matches
init_chainablestack.hpp
Go to the documentation of this file.
1#ifndef STAN_MATH_REV_CORE_INIT_CHAINABLESTACK_HPP
2#define STAN_MATH_REV_CORE_INIT_CHAINABLESTACK_HPP
3
5
6#include <tbb/task_scheduler_observer.h>
7
8#include <mutex>
9#include <unordered_map>
10#include <utility>
11#include <thread>
12#include <tuple>
13
14#ifdef __APPLE__
15#include <pthread.h>
16#if defined(__arm64__) || defined(__aarch64__)
17#include <sys/qos.h>
18#endif
19#endif
20
21namespace stan {
22namespace math {
23
38class ad_tape_observer final : public tbb::task_scheduler_observer {
39 using stack_ptr = std::unique_ptr<ChainableStack>;
40 using ad_map = std::unordered_map<std::thread::id, stack_ptr>;
41
42 public:
43 ad_tape_observer() : tbb::task_scheduler_observer(), thread_tape_map_() {
44 on_scheduler_entry(true); // register current process
45 observe(true); // activates the observer
46 }
47
48 ~ad_tape_observer() { observe(false); }
49
50 void on_scheduler_entry(bool worker) {
51#ifdef __APPLE__
52#if defined(__arm64__) || defined(__aarch64__)
53 // Set thread QoS to USER_INITIATED so macOS prefers scheduling
54 // TBB worker threads on performance cores rather than efficiency cores.
55 pthread_set_qos_class_self_np(QOS_CLASS_USER_INITIATED, 0);
56#endif
57#endif
58 std::lock_guard<std::mutex> thread_tape_map_lock(thread_tape_map_mutex_);
59 const std::thread::id thread_id = std::this_thread::get_id();
60 if (thread_tape_map_.find(thread_id) == thread_tape_map_.end()) {
61 ad_map::iterator insert_elem;
62 bool status = false;
63 std::tie(insert_elem, status)
64 = thread_tape_map_.emplace(ad_map::value_type{thread_id, nullptr});
65 insert_elem->second = std::make_unique<ChainableStack>();
66 }
67 }
68
69 void on_scheduler_exit(bool worker) {
70 std::lock_guard<std::mutex> thread_tape_map_lock(thread_tape_map_mutex_);
71 auto elem = thread_tape_map_.find(std::this_thread::get_id());
72 if (elem != thread_tape_map_.end()) {
73 thread_tape_map_.erase(elem);
74 }
75 }
76
77 private:
80};
81
82namespace {
83
84ad_tape_observer global_observer;
85
86} // namespace
87} // namespace math
88} // namespace stan
89
90#endif
std::unordered_map< std::thread::id, stack_ptr > ad_map
std::unique_ptr< ChainableStack > stack_ptr
TBB observer object which is a callback hook called whenever the TBB scheduler adds a new thread to t...
The lgamma implementation in stan-math is based on either the reentrant safe lgamma_r implementation ...