OmniSciDB  d2f719934e
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
threading_tbb.h
Go to the documentation of this file.
1 
2 #include <functional>
3 #define TBB_PREVIEW_TASK_GROUP_EXTENSIONS 1
4 #include <tbb/blocked_range.h>
5 #include <tbb/parallel_for.h>
6 #include <tbb/parallel_reduce.h>
7 #include <tbb/task_arena.h>
8 #include <tbb/task_group.h>
9 
10 namespace threading_tbb {
11 
12 using tbb::blocked_range;
13 using tbb::task_arena;
14 using tbb::task_group;
15 namespace this_task_arena {
16 using namespace tbb::this_task_arena;
17 }
18 extern tbb::task_arena g_tbb_arena;
19 
20 template <typename... X>
21 void parallel_for(X&&... x) {
22  g_tbb_arena.execute([&] {
23  this_task_arena::isolate([&] { tbb::parallel_for(std::forward<X>(x)...); });
24  });
25 }
26 
27 template <typename... X>
28 auto parallel_reduce(X&&... x) -> decltype(tbb::parallel_reduce(std::forward<X>(x)...)) {
29  return g_tbb_arena.execute([&] {
30  return this_task_arena::isolate(
31  [&] { return tbb::parallel_reduce(std::forward<X>(x)...); });
32  });
33 }
34 
35 template <typename T>
36 struct tbb_packaged_task : tbb::task_group {
38  tbb_packaged_task() : value_(T()) {}
39 };
40 
41 template <>
42 struct tbb_packaged_task<void> : tbb::task_group {};
43 
44 template <typename T>
45 struct future {
46  std::unique_ptr<tbb_packaged_task<T>> task_;
47  future() = default;
48  future(future&&) = default;
49  future(std::unique_ptr<tbb_packaged_task<T>>&& p) : task_(std::move(p)) {}
50  void wait() {
51  g_tbb_arena.execute([this] { task_->wait(); });
52  }
53  T& get() {
54  wait();
55  return task_->value_;
56  }
57 };
58 
59 template <>
60 struct future<void> {
61  std::unique_ptr<tbb_packaged_task<void>> task_;
62  future() = default;
63  future(future&&) = default;
64  future(std::unique_ptr<tbb_packaged_task<void>>&& p) : task_(std::move(p)) {}
65  void wait() {
66  g_tbb_arena.execute([this] { task_->wait(); });
67  }
68  void get() { wait(); }
69 };
70 
71 template <typename Fn,
72  typename... Args,
73  typename Result = std::result_of_t<Fn && (Args && ...)>>
74 future<Result> async(Fn&& fn, Args&&... args) {
75  auto f = std::bind(std::forward<Fn>(fn), std::forward<Args>(args)...);
76  auto ptask = std::make_unique<tbb_packaged_task<Result>>();
77 #if TBB_INTERFACE_VERSION >= 12040
78  g_tbb_arena.enqueue(ptask->defer(f));
79 #else
80  g_tbb_arena.execute([&] { ptask->run(f); });
81 #endif
82  return future<Result>(std::move(ptask));
83 }
84 
85 } // namespace threading_tbb
future(std::unique_ptr< tbb_packaged_task< void >> &&p)
Definition: threading_tbb.h:64
future(std::unique_ptr< tbb_packaged_task< T >> &&p)
Definition: threading_tbb.h:49
tbb::task_arena g_tbb_arena
auto parallel_reduce(X &&...x) -> decltype(tbb::parallel_reduce(std::forward< X >(x)...))
Definition: threading_tbb.h:28
Value parallel_reduce(const blocked_range< Int > &range, const Value &identity, const RealBody &real_body, const Reduction &reduction, const Partitioner &p=Partitioner())
Parallel iteration with reduction.
void parallel_for(const blocked_range< Int > &range, const Body &body, const Partitioner &p=Partitioner())
std::unique_ptr< tbb_packaged_task< T > > task_
Definition: threading_tbb.h:46
char * f
std::unique_ptr< tbb_packaged_task< void > > task_
Definition: threading_tbb.h:61
future< Result > async(Fn &&fn, Args &&...args)
Definition: threading_tbb.h:74
void parallel_for(X &&...x)
Definition: threading_tbb.h:21