17 #ifndef __TBB_parallel_invoke_H 18 #define __TBB_parallel_invoke_H 23 #if __TBB_VARIADIC_PARALLEL_INVOKE 29 #if !__TBB_TASK_GROUP_CONTEXT 31 struct task_group_context {
39 template<
typename function>
53 template <
size_t N,
typename function1,
typename function2,
typename function3>
65 __TBB_ASSERT(N==2 || N==3,
"Number of arguments passed to spawner is wrong");
68 internal::function_invoker<function2>* invoker2 =
new (
allocate_child()) internal::function_invoker<function2>(
my_func2);
73 internal::function_invoker<function3>* invoker3 =
new (
allocate_child()) internal::function_invoker<function3>(
my_func3);
101 #if __TBB_VARIADIC_PARALLEL_INVOKE 105 template <
typename function>
108 internal::function_invoker<function>* invoker =
new (
allocate_child()) internal::function_invoker<function>(std::forward<function>(_func));
113 template<
typename function>
120 template <
typename function1,
typename function2,
typename...
function>
121 void add_children(function1&& _func1, function2&& _func2,
function&&... _func)
124 parallel_invoke_noop noop;
125 typedef internal::spawner<2, function1, function2, parallel_invoke_noop> spawner_type;
126 spawner_type & sub_root = *
new(
allocate_child()) spawner_type(std::forward<function1>(_func1), std::forward<function2>(_func2), noop);
132 template <
typename function>
135 internal::function_invoker<function>* invoker =
new (
allocate_child()) internal::function_invoker<function>(_func);
142 template <
typename function1,
typename function2>
147 internal::spawner<2, function1, function2, parallel_invoke_noop>& sub_root = *
new(
allocate_child())internal::spawner<2, function1, function2, parallel_invoke_noop>(_func1, _func2, noop);
151 template <
typename function1,
typename function2,
typename function3>
152 void add_children (
const function1& _func1,
const function2& _func2,
const function3& _func3)
154 internal::spawner<3, function1, function2, function3>& sub_root = *
new(
allocate_child())internal::spawner<3, function1, function2, function3>(_func1, _func2, _func3);
157 #endif // __TBB_VARIADIC_PARALLEL_INVOKE 160 template <
typename F0>
163 internal::function_invoker<F0>* invoker =
new (
allocate_child()) internal::function_invoker<F0>(f0);
171 #if __TBB_TASK_GROUP_CONTEXT 183 internal::parallel_invoke_helper&
root;
186 #if __TBB_VARIADIC_PARALLEL_INVOKE 188 template<
typename... T>
struct impl_selector;
190 template<
typename T1,
typename... T>
struct impl_selector<T1, T...> {
191 typedef typename impl_selector<T...>
::type type;
194 template<
typename T>
struct impl_selector<T> {
197 template<>
struct impl_selector<task_group_context&> {
202 inline task_group_context& get_context( task_group_context& tgc ) {
return tgc; }
204 template<
typename T1,
typename... T>
205 task_group_context& get_context( T1&& , T&&... t )
206 {
return get_context( std::forward<T>(t)... ); }
209 template<
typename F0,
typename F1,
typename... F>
210 void parallel_invoke_impl(
true_type, F0&& f0, F1&& f1, F&&... f) {
213 const size_t number_of_children = 2 +
sizeof...(F)/2;
214 parallel_invoke_cleaner cleaner(number_of_children, get_context(std::forward<F>(f)...));
215 parallel_invoke_helper& root = cleaner.root;
217 root.add_children(std::forward<F>(f)...);
218 root.add_children(std::forward<F1>(f1));
219 root.run_and_finish(std::forward<F0>(f0));
223 template<
typename F0,
typename F1,
typename... F>
224 void parallel_invoke_impl(
false_type, F0&& f0, F1&& f1, F&&... f) {
227 parallel_invoke_impl(
true_type(), std::forward<F0>(f0), std::forward<F1>(f1), std::forward<F>(f)..., context);
239 #if __TBB_VARIADIC_PARALLEL_INVOKE 243 template<
typename F0,
typename F1,
typename... F>
246 internal::parallel_invoke_impl(selector_type(), std::forward<F0>(f0), std::forward<F1>(f1), std::forward<F>(f)...);
253 template<
typename F0,
typename F1 >
255 internal::parallel_invoke_cleaner cleaner(2, context);
256 internal::parallel_invoke_helper& root = cleaner.root;
258 root.add_children(f1);
260 root.run_and_finish(f0);
264 template<
typename F0,
typename F1,
typename F2 >
266 internal::parallel_invoke_cleaner cleaner(3, context);
267 internal::parallel_invoke_helper& root = cleaner.root;
269 root.add_children(f2);
270 root.add_children(f1);
272 root.run_and_finish(f0);
276 template<
typename F0,
typename F1,
typename F2,
typename F3>
280 internal::parallel_invoke_cleaner cleaner(4, context);
281 internal::parallel_invoke_helper& root = cleaner.root;
283 root.add_children(f3);
284 root.add_children(f2);
285 root.add_children(f1);
287 root.run_and_finish(f0);
291 template<
typename F0,
typename F1,
typename F2,
typename F3,
typename F4 >
292 void parallel_invoke(
const F0& f0,
const F1& f1,
const F2& f2,
const F3& f3,
const F4& f4,
295 internal::parallel_invoke_cleaner cleaner(3, context);
296 internal::parallel_invoke_helper& root = cleaner.root;
298 root.add_children(f4, f3);
299 root.add_children(f2, f1);
301 root.run_and_finish(f0);
305 template<
typename F0,
typename F1,
typename F2,
typename F3,
typename F4,
typename F5>
306 void parallel_invoke(
const F0& f0,
const F1& f1,
const F2& f2,
const F3& f3,
const F4& f4,
const F5& f5,
309 internal::parallel_invoke_cleaner cleaner(3, context);
310 internal::parallel_invoke_helper& root = cleaner.root;
312 root.add_children(f5, f4, f3);
313 root.add_children(f2, f1);
315 root.run_and_finish(f0);
319 template<
typename F0,
typename F1,
typename F2,
typename F3,
typename F4,
typename F5,
typename F6>
320 void parallel_invoke(
const F0& f0,
const F1& f1,
const F2& f2,
const F3& f3,
const F4& f4,
321 const F5& f5,
const F6& f6,
324 internal::parallel_invoke_cleaner cleaner(3, context);
325 internal::parallel_invoke_helper& root = cleaner.root;
327 root.add_children(f6, f5, f4);
328 root.add_children(f3, f2, f1);
330 root.run_and_finish(f0);
334 template<
typename F0,
typename F1,
typename F2,
typename F3,
typename F4,
335 typename F5,
typename F6,
typename F7>
336 void parallel_invoke(
const F0& f0,
const F1& f1,
const F2& f2,
const F3& f3,
const F4& f4,
337 const F5& f5,
const F6& f6,
const F7& f7,
340 internal::parallel_invoke_cleaner cleaner(4, context);
341 internal::parallel_invoke_helper& root = cleaner.root;
343 root.add_children(f7, f6, f5);
344 root.add_children(f4, f3);
345 root.add_children(f2, f1);
347 root.run_and_finish(f0);
351 template<
typename F0,
typename F1,
typename F2,
typename F3,
typename F4,
352 typename F5,
typename F6,
typename F7,
typename F8>
353 void parallel_invoke(
const F0& f0,
const F1& f1,
const F2& f2,
const F3& f3,
const F4& f4,
354 const F5& f5,
const F6& f6,
const F7& f7,
const F8& f8,
357 internal::parallel_invoke_cleaner cleaner(4, context);
358 internal::parallel_invoke_helper& root = cleaner.root;
360 root.add_children(f8, f7, f6);
361 root.add_children(f5, f4, f3);
362 root.add_children(f2, f1);
364 root.run_and_finish(f0);
368 template<
typename F0,
typename F1,
typename F2,
typename F3,
typename F4,
369 typename F5,
typename F6,
typename F7,
typename F8,
typename F9>
370 void parallel_invoke(
const F0& f0,
const F1& f1,
const F2& f2,
const F3& f3,
const F4& f4,
371 const F5& f5,
const F6& f6,
const F7& f7,
const F8& f8,
const F9& f9,
374 internal::parallel_invoke_cleaner cleaner(4, context);
375 internal::parallel_invoke_helper& root = cleaner.root;
377 root.add_children(f9, f8, f7);
378 root.add_children(f6, f5, f4);
379 root.add_children(f3, f2, f1);
381 root.run_and_finish(f0);
385 template<
typename F0,
typename F1>
388 parallel_invoke<F0, F1>(f0, f1, context);
391 template<
typename F0,
typename F1,
typename F2>
394 parallel_invoke<F0, F1, F2>(f0, f1, f2, context);
397 template<
typename F0,
typename F1,
typename F2,
typename F3 >
400 parallel_invoke<F0, F1, F2, F3>(f0, f1, f2, f3, context);
403 template<
typename F0,
typename F1,
typename F2,
typename F3,
typename F4>
404 void parallel_invoke(
const F0& f0,
const F1& f1,
const F2& f2,
const F3& f3,
const F4& f4) {
406 parallel_invoke<F0, F1, F2, F3, F4>(f0, f1, f2, f3, f4, context);
409 template<
typename F0,
typename F1,
typename F2,
typename F3,
typename F4,
typename F5>
410 void parallel_invoke(
const F0& f0,
const F1& f1,
const F2& f2,
const F3& f3,
const F4& f4,
const F5& f5) {
412 parallel_invoke<F0, F1, F2, F3, F4, F5>(f0, f1, f2, f3, f4, f5, context);
415 template<
typename F0,
typename F1,
typename F2,
typename F3,
typename F4,
typename F5,
typename F6>
416 void parallel_invoke(
const F0& f0,
const F1& f1,
const F2& f2,
const F3& f3,
const F4& f4,
417 const F5& f5,
const F6& f6)
420 parallel_invoke<F0, F1, F2, F3, F4, F5, F6>(f0, f1, f2, f3, f4, f5, f6, context);
423 template<
typename F0,
typename F1,
typename F2,
typename F3,
typename F4,
424 typename F5,
typename F6,
typename F7>
425 void parallel_invoke(
const F0& f0,
const F1& f1,
const F2& f2,
const F3& f3,
const F4& f4,
426 const F5& f5,
const F6& f6,
const F7& f7)
429 parallel_invoke<F0, F1, F2, F3, F4, F5, F6, F7>(f0, f1, f2, f3, f4, f5, f6, f7, context);
432 template<
typename F0,
typename F1,
typename F2,
typename F3,
typename F4,
433 typename F5,
typename F6,
typename F7,
typename F8>
434 void parallel_invoke(
const F0& f0,
const F1& f1,
const F2& f2,
const F3& f3,
const F4& f4,
435 const F5& f5,
const F6& f6,
const F7& f7,
const F8& f8)
438 parallel_invoke<F0, F1, F2, F3, F4, F5, F6, F7, F8>(f0, f1, f2, f3, f4, f5, f6, f7, f8, context);
441 template<
typename F0,
typename F1,
typename F2,
typename F3,
typename F4,
442 typename F5,
typename F6,
typename F7,
typename F8,
typename F9>
443 void parallel_invoke(
const F0& f0,
const F1& f1,
const F2& f2,
const F3& f3,
const F4& f4,
444 const F5& f5,
const F6& f6,
const F7& f7,
const F8& f8,
const F9& f9)
447 parallel_invoke<F0, F1, F2, F3, F4, F5, F6, F7, F8, F9>(f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, context);
449 #endif // __TBB_VARIADIC_PARALLEL_INVOKE
task * execute() __TBB_override
Should be overridden by derived classes.
internal::parallel_invoke_helper & root
const function & my_function
~parallel_invoke_cleaner()
bool_constant< false > false_type
task_group_context(kind_type relation_with_parent=bound, uintptr_t t=default_traits)
Default & binding constructor.
parallel_invoke_cleaner(int number_of_children, tbb::task_group_context &context)
const function3 & my_func3
const function1 & my_func1
void spawn_and_wait_for_all(task &child)
Similar to spawn followed by wait_for_all, but more efficient.
void parallel_invoke(const F0 &f0, const F1 &f1, tbb::task_group_context &context)
Executes a list of tasks in parallel and waits for all tasks to complete.
void add_children(const function1 &_func1, const function2 &_func2, const function3 &_func3)
void run_and_finish(const F0 &f0)
function_invoker(const function &_function)
task that does nothing. Useful for synchronization.
Used to form groups of tasks.
#define __TBB_STATIC_ASSERT(condition, msg)
internal::allocate_child_proxy & allocate_child()
Returns proxy for overloaded new that allocates a child task of *this.
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
void add_children(const function &_func)
void add_children(const function1 &_func1, const function2 &_func2)
void set_ref_count(int count)
Set reference count.
parallel_invoke_helper(int number_of_children)
Base class for user-defined tasks.
spawner(const function1 &_func1, const function2 &_func2, const function3 &_func3)
task * execute() __TBB_override
Should be overridden by derived classes.
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain ITT_FORMAT p const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_id __itt_string_handle __itt_metadata_type size_t void ITT_FORMAT p const __itt_domain __itt_id __itt_string_handle const wchar_t size_t ITT_FORMAT lu const __itt_domain __itt_id __itt_relation __itt_id ITT_FORMAT p const wchar_t int ITT_FORMAT __itt_group_mark d int
const function2 & my_func2
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain ITT_FORMAT p const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_id __itt_string_handle __itt_metadata_type type
void recycle_as_safe_continuation()
Recommended to use, safe variant of recycle_as_continuation.
bool_constant< true > true_type