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 throw std::runtime_error("task cancelled");
25 }
26
27#elif defined(TASKING_TBB)
28 #if TBB_INTERFACE_VERSION >= 12002
29 tbb::task_group_context context;
30 tbb::parallel_for(Index(0),N,Index(1),[&](Index i) {
31 func(i);
32 },context);
33 if (context.is_group_execution_cancelled())
34 throw std::runtime_error("task cancelled");
35 #else
36 tbb::parallel_for(Index(0),N,Index(1),[&](Index i) {
37 func(i);
38 });
39 if (tbb::task::self().is_cancelled())
40 throw std::runtime_error("task cancelled");
41 #endif
42
43#elif defined(TASKING_PPL)
44 concurrency::parallel_for(Index(0),N,Index(1),[&](Index i) {
45 func(i);
46 });
47#else
48# error "no tasking system enabled"
49#endif
50 }
51
52 /* parallel for with range and granulatity */
53 template<typename Index, typename Func>
54 __forceinline void parallel_for( const Index first, const Index last, const Index minStepSize, const Func& func)
55 {
56 assert(first <= last);
57#if defined(TASKING_INTERNAL)
58 TaskScheduler::spawn(first,last,minStepSize,func);
59 if (!TaskScheduler::wait())
60 throw std::runtime_error("task cancelled");
61
62#elif defined(TASKING_TBB)
63 #if TBB_INTERFACE_VERSION >= 12002
64 tbb::task_group_context context;
65 tbb::parallel_for(tbb::blocked_range<Index>(first,last,minStepSize),[&](const tbb::blocked_range<Index>& r) {
66 func(range<Index>(r.begin(),r.end()));
67 },context);
68 if (context.is_group_execution_cancelled())
69 throw std::runtime_error("task cancelled");
70 #else
71 tbb::parallel_for(tbb::blocked_range<Index>(first,last,minStepSize),[&](const tbb::blocked_range<Index>& r) {
72 func(range<Index>(r.begin(),r.end()));
73 });
74 if (tbb::task::self().is_cancelled())
75 throw std::runtime_error("task cancelled");
76 #endif
77
78#elif defined(TASKING_PPL)
79 concurrency::parallel_for(first, last, Index(1) /*minStepSize*/, [&](Index i) {
80 func(range<Index>(i,i+1));
81 });
82
83#else
84# error "no tasking system enabled"
85#endif
86 }
87
88 /* parallel for with range */
89 template<typename Index, typename Func>
90 __forceinline void parallel_for( const Index first, const Index last, const Func& func)
91 {
92 assert(first <= last);
93 parallel_for(first,last,(Index)1,func);
94 }
95
96#if defined(TASKING_TBB) && (TBB_INTERFACE_VERSION > 4001)
97
98 template<typename Index, typename Func>
99 __forceinline void parallel_for_static( const Index N, const Func& func)
100 {
101 #if TBB_INTERFACE_VERSION >= 12002
102 tbb::task_group_context context;
103 tbb::parallel_for(Index(0),N,Index(1),[&](Index i) {
104 func(i);
105 },tbb::simple_partitioner(),context);
106 if (context.is_group_execution_cancelled())
107 throw std::runtime_error("task cancelled");
108 #else
109 tbb::parallel_for(Index(0),N,Index(1),[&](Index i) {
110 func(i);
111 },tbb::simple_partitioner());
112 if (tbb::task::self().is_cancelled())
113 throw std::runtime_error("task cancelled");
114 #endif
115 }
116
117 typedef tbb::affinity_partitioner affinity_partitioner;
118
119 template<typename Index, typename Func>
120 __forceinline void parallel_for_affinity( const Index N, const Func& func, tbb::affinity_partitioner& ap)
121 {
122 #if TBB_INTERFACE_VERSION >= 12002
123 tbb::task_group_context context;
124 tbb::parallel_for(Index(0),N,Index(1),[&](Index i) {
125 func(i);
126 },ap,context);
127 if (context.is_group_execution_cancelled())
128 throw std::runtime_error("task cancelled");
129 #else
130 tbb::parallel_for(Index(0),N,Index(1),[&](Index i) {
131 func(i);
132 },ap);
133 if (tbb::task::self().is_cancelled())
134 throw std::runtime_error("task cancelled");
135 #endif
136 }
137
138#else
139
140 template<typename Index, typename Func>
141 __forceinline void parallel_for_static( const Index N, const Func& func)
142 {
143 parallel_for(N,func);
144 }
145
146 struct affinity_partitioner {
147 };
148
149 template<typename Index, typename Func>
150 __forceinline void parallel_for_affinity( const Index N, const Func& func, affinity_partitioner& ap)
151 {
152 parallel_for(N,func);
153 }
154
155#endif
156}
157

source code of qtquick3d/src/3rdparty/embree/common/algorithms/parallel_for.h