Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/embree/common/algorithms/parallel_for.h
9912 views
1
// Copyright 2009-2021 Intel Corporation
2
// SPDX-License-Identifier: Apache-2.0
3
4
#pragma once
5
6
#include "../tasking/taskscheduler.h"
7
#include "../sys/array.h"
8
#include "../math/emath.h"
9
#include "../math/range.h"
10
11
namespace embree
12
{
13
/* parallel_for without range */
14
template<typename Index, typename Func>
15
__forceinline void parallel_for( const Index N, const Func& func)
16
{
17
#if defined(TASKING_INTERNAL) && !defined(TASKING_TBB)
18
if (N) {
19
TaskScheduler::TaskGroupContext context;
20
TaskScheduler::spawn(Index(0),N,Index(1),[&] (const range<Index>& r) {
21
assert(r.size() == 1);
22
func(r.begin());
23
},&context);
24
TaskScheduler::wait();
25
if (context.cancellingException != nullptr) {
26
std::rethrow_exception(context.cancellingException);
27
}
28
}
29
#elif defined(TASKING_TBB)
30
#if TBB_INTERFACE_VERSION >= 12002
31
tbb::task_group_context context;
32
tbb::parallel_for(Index(0),N,Index(1),[&](Index i) {
33
func(i);
34
},context);
35
if (context.is_group_execution_cancelled())
36
throw std::runtime_error("task cancelled");
37
#else
38
tbb::parallel_for(Index(0),N,Index(1),[&](Index i) {
39
func(i);
40
});
41
if (tbb::task::self().is_cancelled())
42
throw std::runtime_error("task cancelled");
43
#endif
44
45
#elif defined(TASKING_PPL)
46
concurrency::parallel_for(Index(0),N,Index(1),[&](Index i) {
47
func(i);
48
});
49
#else
50
# error "no tasking system enabled"
51
#endif
52
}
53
54
/* parallel for with range and granulatity */
55
template<typename Index, typename Func>
56
__forceinline void parallel_for( const Index first, const Index last, const Index minStepSize, const Func& func)
57
{
58
assert(first <= last);
59
#if defined(TASKING_INTERNAL) && !defined(TASKING_TBB)
60
TaskScheduler::TaskGroupContext context;
61
TaskScheduler::spawn(first,last,minStepSize,func,&context);
62
TaskScheduler::wait();
63
if (context.cancellingException != nullptr) {
64
std::rethrow_exception(context.cancellingException);
65
}
66
67
#elif defined(TASKING_TBB)
68
#if TBB_INTERFACE_VERSION >= 12002
69
tbb::task_group_context context;
70
tbb::parallel_for(tbb::blocked_range<Index>(first,last,minStepSize),[&](const tbb::blocked_range<Index>& r) {
71
func(range<Index>(r.begin(),r.end()));
72
},context);
73
if (context.is_group_execution_cancelled())
74
throw std::runtime_error("task cancelled");
75
#else
76
tbb::parallel_for(tbb::blocked_range<Index>(first,last,minStepSize),[&](const tbb::blocked_range<Index>& r) {
77
func(range<Index>(r.begin(),r.end()));
78
});
79
if (tbb::task::self().is_cancelled())
80
throw std::runtime_error("task cancelled");
81
#endif
82
83
#elif defined(TASKING_PPL)
84
concurrency::parallel_for(first, last, Index(1) /*minStepSize*/, [&](Index i) {
85
func(range<Index>(i,i+1));
86
});
87
88
#else
89
# error "no tasking system enabled"
90
#endif
91
}
92
93
/* parallel for with range */
94
template<typename Index, typename Func>
95
__forceinline void parallel_for( const Index first, const Index last, const Func& func)
96
{
97
assert(first <= last);
98
parallel_for(first,last,(Index)1,func);
99
}
100
101
#if defined(TASKING_TBB) && (TBB_INTERFACE_VERSION > 4001)
102
103
template<typename Index, typename Func>
104
__forceinline void parallel_for_static( const Index N, const Func& func)
105
{
106
#if TBB_INTERFACE_VERSION >= 12002
107
tbb::task_group_context context;
108
tbb::parallel_for(Index(0),N,Index(1),[&](Index i) {
109
func(i);
110
},tbb::simple_partitioner(),context);
111
if (context.is_group_execution_cancelled())
112
throw std::runtime_error("task cancelled");
113
#else
114
tbb::parallel_for(Index(0),N,Index(1),[&](Index i) {
115
func(i);
116
},tbb::simple_partitioner());
117
if (tbb::task::self().is_cancelled())
118
throw std::runtime_error("task cancelled");
119
#endif
120
}
121
122
typedef tbb::affinity_partitioner affinity_partitioner;
123
124
template<typename Index, typename Func>
125
__forceinline void parallel_for_affinity( const Index N, const Func& func, tbb::affinity_partitioner& ap)
126
{
127
#if TBB_INTERFACE_VERSION >= 12002
128
tbb::task_group_context context;
129
tbb::parallel_for(Index(0),N,Index(1),[&](Index i) {
130
func(i);
131
},ap,context);
132
if (context.is_group_execution_cancelled())
133
throw std::runtime_error("task cancelled");
134
#else
135
tbb::parallel_for(Index(0),N,Index(1),[&](Index i) {
136
func(i);
137
},ap);
138
if (tbb::task::self().is_cancelled())
139
throw std::runtime_error("task cancelled");
140
#endif
141
}
142
143
#else
144
145
template<typename Index, typename Func>
146
__forceinline void parallel_for_static( const Index N, const Func& func)
147
{
148
parallel_for(N,func);
149
}
150
151
struct affinity_partitioner {
152
};
153
154
template<typename Index, typename Func>
155
__forceinline void parallel_for_affinity( const Index N, const Func& func, affinity_partitioner& ap)
156
{
157
parallel_for(N,func);
158
}
159
160
#endif
161
}
162
163