-
Notifications
You must be signed in to change notification settings - Fork 59
Expand file tree
/
Copy pathTBB.h
More file actions
166 lines (134 loc) · 4.15 KB
/
TBB.h
File metadata and controls
166 lines (134 loc) · 4.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
#ifndef __RCPP_PARALLEL_TBB__
#define __RCPP_PARALLEL_TBB__
#include "Common.h"
#ifndef TBB_PREVIEW_GLOBAL_CONTROL
# define TBB_PREVIEW_GLOBAL_CONTROL 1
#endif
// For compatibility with existing packages on CRAN.
#include "tbb/blocked_range.h"
#include "tbb/concurrent_unordered_set.h"
#include "tbb/concurrent_unordered_map.h"
#include "tbb/global_control.h"
#include "tbb/mutex.h"
#include "tbb/parallel_for.h"
#include "tbb/parallel_for_each.h"
#include "tbb/parallel_reduce.h"
#include "tbb/parallel_sort.h"
#include "tbb/spin_mutex.h"
// For compatibility with older R packages.
namespace tbb {
#ifndef __TBB_task_scheduler_init_H
#define __TBB_task_scheduler_init_H
class task_scheduler_init {
public:
task_scheduler_init(
int number_of_threads = -1,
std::size_t stack_size = 0)
{
}
static int default_num_threads()
{
return 2;
}
static const int automatic = -1;
static const int deferred = -2;
};
#endif
} // end namespace tbb
namespace RcppParallel {
// This class is primarily used to implement type erasure. The goals here were:
//
// 1. Hide the tbb symbols / implementation details from client R packages.
// That is, they should get the tools they need only via RcppParallel.
//
// 2. Do this in a way that preserves binary compatibility with pre-existing
// classes that make use of parallelReduce().
//
// 3. Ensure that those packages, when re-compiled without source changes,
// can still function as expected.
//
// The downside here is that all the indirection through std::function<>
// and the requirement for RTTI is probably expensive, but I couldn't find
// a better way forward that could also preserve binary compatibility with
// existing pre-built pacakges.
//
// Hopefully, in a future release, we can do away with this wrapper, once
// packages have been rebuilt and no longer implicitly depend on TBB internals.
struct ReducerWrapper {
template <typename T>
ReducerWrapper(T* reducer)
{
self_ = reinterpret_cast<void*>(reducer);
owned_ = false;
work_ = [&](void* self, std::size_t begin, std::size_t end)
{
(*reinterpret_cast<T*>(self))(begin, end);
};
split_ = [&](void* object, Split split)
{
return new T(*reinterpret_cast<T*>(object), split);
};
join_ = [&](void* self, void* other)
{
(*reinterpret_cast<T*>(self)).join(*reinterpret_cast<T*>(other));
};
deleter_ = [&](void* object)
{
delete (T*) object;
};
}
~ReducerWrapper()
{
if (owned_)
{
deleter_(self_);
self_ = nullptr;
}
}
void operator()(std::size_t begin, std::size_t end) const
{
work_(self_, begin, end);
}
ReducerWrapper(const ReducerWrapper& rhs, Split split)
{
self_ = rhs.split_(rhs.self_, split);
owned_ = true;
work_ = rhs.work_;
split_ = rhs.split_;
join_ = rhs.join_;
deleter_ = rhs.deleter_;
}
void join(const ReducerWrapper& rhs) const
{
join_(self_, rhs.self_);
}
private:
void* self_ = nullptr;
bool owned_ = false;
std::function<void (void*, std::size_t, std::size_t)> work_;
std::function<void*(void*, Split)> split_;
std::function<void (void*, void*)> join_;
std::function<void(void*)> deleter_;
};
void tbbParallelFor(std::size_t begin,
std::size_t end,
Worker& worker,
std::size_t grainSize = 1,
int numThreads = -1);
void tbbParallelReduceImpl(std::size_t begin,
std::size_t end,
ReducerWrapper& wrapper,
std::size_t grainSize = 1,
int numThreads = -1);
template <typename Reducer>
void tbbParallelReduce(std::size_t begin,
std::size_t end,
Reducer& reducer,
std::size_t grainSize = 1,
int numThreads = -1)
{
ReducerWrapper wrapper(&reducer);
tbbParallelReduceImpl(begin, end, wrapper, grainSize, numThreads);
}
} // namespace RcppParallel
#endif // __RCPP_PARALLEL_TBB__