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/math.h"
9#include "../math/range.h"
10
11namespace 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)
18 if (N) {
19 TaskScheduler::spawn(Index(0),N,Index(1),[&] (const range<Index>& r) {
20 assert(r.size() == 1);
21 func(r.begin());
22 });
23 if (!TaskScheduler::wait())
24 // -- GODOT start --
25 // throw std::runtime_error("task cancelled");
26 abort();
27 // -- GODOT end --
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 // -- GODOT start --
37 // throw std::runtime_error("task cancelled");
38 abort();
39 // -- GODOT end --
40 #else
41 tbb::parallel_for(Index(0),N,Index(1),[&](Index i) {
42 func(i);
43 });
44 if (tbb::task::self().is_cancelled())
45 // -- GODOT start --
46 // throw std::runtime_error("task cancelled");
47 abort();
48 // -- GODOT end --
49 #endif
50
51#elif defined(TASKING_PPL)
52 concurrency::parallel_for(Index(0),N,Index(1),[&](Index i) {
53 func(i);
54 });
55#else
56# error "no tasking system enabled"
57#endif
58 }
59
60 /* parallel for with range and granulatity */
61 template<typename Index, typename Func>
62 __forceinline void parallel_for( const Index first, const Index last, const Index minStepSize, const Func& func)
63 {
64 assert(first <= last);
65#if defined(TASKING_INTERNAL)
66 TaskScheduler::spawn(first,last,minStepSize,func);
67 if (!TaskScheduler::wait())
68 // -- GODOT start --
69 // throw std::runtime_error("task cancelled");
70 abort();
71 // -- GODOT end --
72
73#elif defined(TASKING_TBB)
74 #if TBB_INTERFACE_VERSION >= 12002
75 tbb::task_group_context context;
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 },context);
79 if (context.is_group_execution_cancelled())
80 // -- GODOT start --
81 // throw std::runtime_error("task cancelled");
82 abort();
83 // -- GODOT end --
84 #else
85 tbb::parallel_for(tbb::blocked_range<Index>(first,last,minStepSize),[&](const tbb::blocked_range<Index>& r) {
86 func(range<Index>(r.begin(),r.end()));
87 });
88 if (tbb::task::self().is_cancelled())
89 // -- GODOT start --
90 // throw std::runtime_error("task cancelled");
91 abort();
92 // -- GODOT end --
93 #endif
94
95#elif defined(TASKING_PPL)
96 concurrency::parallel_for(first, last, Index(1) /*minStepSize*/, [&](Index i) {
97 func(range<Index>(i,i+1));
98 });
99
100#else
101# error "no tasking system enabled"
102#endif
103 }
104
105 /* parallel for with range */
106 template<typename Index, typename Func>
107 __forceinline void parallel_for( const Index first, const Index last, const Func& func)
108 {
109 assert(first <= last);
110 parallel_for(first,last,(Index)1,func);
111 }
112
113#if defined(TASKING_TBB) && (TBB_INTERFACE_VERSION > 4001)
114
115 template<typename Index, typename Func>
116 __forceinline void parallel_for_static( const Index N, const Func& func)
117 {
118 #if TBB_INTERFACE_VERSION >= 12002
119 tbb::task_group_context context;
120 tbb::parallel_for(Index(0),N,Index(1),[&](Index i) {
121 func(i);
122 },tbb::simple_partitioner(),context);
123 if (context.is_group_execution_cancelled())
124 // -- GODOT start --
125 // throw std::runtime_error("task cancelled");
126 abort();
127 // -- GODOT end --
128 #else
129 tbb::parallel_for(Index(0),N,Index(1),[&](Index i) {
130 func(i);
131 },tbb::simple_partitioner());
132 if (tbb::task::self().is_cancelled())
133 // -- GODOT start --
134 // throw std::runtime_error("task cancelled");
135 abort();
136 // -- GODOT end --
137 #endif
138 }
139
140 typedef tbb::affinity_partitioner affinity_partitioner;
141
142 template<typename Index, typename Func>
143 __forceinline void parallel_for_affinity( const Index N, const Func& func, tbb::affinity_partitioner& ap)
144 {
145 #if TBB_INTERFACE_VERSION >= 12002
146 tbb::task_group_context context;
147 tbb::parallel_for(Index(0),N,Index(1),[&](Index i) {
148 func(i);
149 },ap,context);
150 if (context.is_group_execution_cancelled())
151 // -- GODOT start --
152 // throw std::runtime_error("task cancelled");
153 abort();
154 // -- GODOT end --
155 #else
156 tbb::parallel_for(Index(0),N,Index(1),[&](Index i) {
157 func(i);
158 },ap);
159 if (tbb::task::self().is_cancelled())
160 // -- GODOT start --
161 // throw std::runtime_error("task cancelled");
162 abort();
163 // -- GODOT end --
164 #endif
165 }
166
167#else
168
169 template<typename Index, typename Func>
170 __forceinline void parallel_for_static( const Index N, const Func& func)
171 {
172 parallel_for(N,func);
173 }
174
175 struct affinity_partitioner {
176 };
177
178 template<typename Index, typename Func>
179 __forceinline void parallel_for_affinity( const Index N, const Func& func, affinity_partitioner& ap)
180 {
181 parallel_for(N,func);
182 }
183
184#endif
185}
186