Automatic Differentiation
 
Loading...
Searching...
No Matches
init_threadpool_tbb.hpp
Go to the documentation of this file.
1#ifndef STAN_MATH_PRIM_CORE_INIT_THREADPOOL_TBB_HPP
2#define STAN_MATH_PRIM_CORE_INIT_THREADPOOL_TBB_HPP
3
5
6#ifndef TBB_INTERFACE_NEW
7#include <tbb/tbb_stddef.h>
8
9#if TBB_VERSION_MAJOR >= 2020
10#define TBB_INTERFACE_NEW
11#endif
12#endif
13
14#ifdef TBB_INTERFACE_NEW
15#include <tbb/global_control.h>
16#include <tbb/task_arena.h>
17#else
18#include <tbb/task_scheduler_init.h>
19#endif
20
21#include <charconv>
22#include <cstdlib>
23#include <string_view>
24#include <thread>
25
26namespace stan {
27namespace math {
28namespace internal {
29
46inline int get_num_threads() {
47#ifdef STAN_THREADS
48 const char* env_stan_num_threads = std::getenv("STAN_NUM_THREADS");
49 if (env_stan_num_threads == nullptr) {
50 return 1;
51 }
52
53 const std::string_view value(env_stan_num_threads);
54 int num_threads;
55 const auto [end, error]
56 = std::from_chars(value.begin(), value.end(), num_threads);
57 if (error != std::errc() || end != value.end()
58 || (num_threads < 1 && num_threads != -1)) {
59 invalid_argument("get_num_threads(int)", "STAN_NUM_THREADS",
60 env_stan_num_threads,
61 "The STAN_NUM_THREADS environment variable is '",
62 "' but it must be a positive number or -1");
63 }
64
65 return num_threads == -1 ? std::thread::hardware_concurrency() : num_threads;
66#else
67 return 1;
68#endif
69}
70
71} // namespace internal
72
73#ifdef TBB_INTERFACE_NEW
96inline tbb::task_arena& init_threadpool_tbb(int n_threads = 0) {
97 int tbb_max_threads = 1;
98#ifdef STAN_THREADS
99 if (n_threads == 0) {
100 tbb_max_threads = internal::get_num_threads();
101 } else if (n_threads > 0) {
102 tbb_max_threads = n_threads;
103 } else if (n_threads == -1) {
104 tbb_max_threads = std::thread::hardware_concurrency();
105 } else {
106 invalid_argument("init_threadpool_tbb(int)", "n_threads", n_threads,
107 "The number of threads is '",
108 "' but it must be positive or -1");
109 }
110#endif
111 static tbb::global_control tbb_gc(
112 tbb::global_control::max_allowed_parallelism, tbb_max_threads);
113 static tbb::task_arena tbb_arena(tbb_max_threads, 1);
114 tbb_arena.initialize();
115
116 return tbb_arena;
117}
118#else
141inline tbb::task_scheduler_init& init_threadpool_tbb(int n_threads = 0) {
142 int tbb_max_threads = 1;
143#ifdef STAN_THREADS
144 if (n_threads == 0) {
145 tbb_max_threads = internal::get_num_threads();
146 } else if (n_threads > 0) {
147 tbb_max_threads = n_threads;
148 } else if (n_threads == -1) {
149 tbb_max_threads = std::thread::hardware_concurrency();
150 } else {
151 invalid_argument("init_threadpool_tbb(int)", "n_threads", n_threads,
152 "The number of threads is '",
153 "' but it must be positive or -1");
154 }
155#endif
156 static tbb::task_scheduler_init tbb_scheduler(tbb_max_threads, 0);
157 return tbb_scheduler;
158}
159#endif
160
161} // namespace math
162} // namespace stan
163
164#endif
int get_num_threads()
Get number of threads to use.
tbb::task_arena & init_threadpool_tbb(int n_threads=0)
Initialize the Intel TBB threadpool and global scheduler through the tbb::task_arena object.
void invalid_argument(const char *function, const char *name, const T &y, const char *msg1, const char *msg2)
Throw an invalid_argument exception with a consistently formatted message.
The lgamma implementation in stan-math is based on either the reentrant safe lgamma_r implementation ...