VTK  9.4.20241118
vtkSMPToolsAPI.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
2// SPDX-License-Identifier: BSD-3-Clause
3
4#ifndef vtkSMPToolsAPI_h
5#define vtkSMPToolsAPI_h
6
7#include "vtkCommonCoreModule.h" // For export macro
8#include "vtkNew.h"
9#include "vtkObject.h"
10#include "vtkSMP.h"
11
12#include <memory>
13
15#if VTK_SMP_ENABLE_SEQUENTIAL
16#include "SMP/Sequential/vtkSMPToolsImpl.txx"
17#endif
18#if VTK_SMP_ENABLE_STDTHREAD
19#include "SMP/STDThread/vtkSMPToolsImpl.txx"
20#endif
21#if VTK_SMP_ENABLE_TBB
22#include "SMP/TBB/vtkSMPToolsImpl.txx"
23#endif
24#if VTK_SMP_ENABLE_OPENMP
25#include "SMP/OpenMP/vtkSMPToolsImpl.txx"
26#endif
27
28namespace vtk
29{
30namespace detail
31{
32namespace smp
33{
34VTK_ABI_NAMESPACE_BEGIN
35
37
38class VTKCOMMONCORE_EXPORT vtkSMPToolsAPI
39{
40public:
41 //--------------------------------------------------------------------------------
43
44 //--------------------------------------------------------------------------------
46
47 //--------------------------------------------------------------------------------
48 const char* GetBackend();
49
50 //--------------------------------------------------------------------------------
51 bool SetBackend(const char* type);
52
53 //--------------------------------------------------------------------------------
54 void Initialize(int numThreads = 0);
55
56 //--------------------------------------------------------------------------------
58
59 //--------------------------------------------------------------------------------
61
62 //------------------------------------------------------------------------------
63 void SetNestedParallelism(bool isNested);
64
65 //--------------------------------------------------------------------------------
67
68 //--------------------------------------------------------------------------------
70
71 //--------------------------------------------------------------------------------
73
74 //--------------------------------------------------------------------------------
75 int GetInternalDesiredNumberOfThread() { return this->DesiredNumberOfThread; }
76
77 //------------------------------------------------------------------------------
78 template <typename Config, typename T>
79 void LocalScope(Config const& config, T&& lambda)
80 {
81 const Config oldConfig(*this);
82 *this << config;
83 try
84 {
85 lambda();
86 }
87 catch (...)
88 {
89 *this << oldConfig;
90 throw;
91 }
92 *this << oldConfig;
93 }
94
95 //--------------------------------------------------------------------------------
96 template <typename FunctorInternal>
97 void For(vtkIdType first, vtkIdType last, vtkIdType grain, FunctorInternal& fi)
98 {
99 switch (this->ActivatedBackend)
100 {
101 case BackendType::Sequential:
102 this->SequentialBackend->For(first, last, grain, fi);
103 break;
104 case BackendType::STDThread:
105 this->STDThreadBackend->For(first, last, grain, fi);
106 break;
107 case BackendType::TBB:
108 this->TBBBackend->For(first, last, grain, fi);
109 break;
110 case BackendType::OpenMP:
111 this->OpenMPBackend->For(first, last, grain, fi);
112 break;
113 }
114 }
115
116 //--------------------------------------------------------------------------------
117 template <typename InputIt, typename OutputIt, typename Functor>
118 void Transform(InputIt inBegin, InputIt inEnd, OutputIt outBegin, Functor& transform)
119 {
120 switch (this->ActivatedBackend)
121 {
122 case BackendType::Sequential:
123 this->SequentialBackend->Transform(inBegin, inEnd, outBegin, transform);
124 break;
125 case BackendType::STDThread:
126 this->STDThreadBackend->Transform(inBegin, inEnd, outBegin, transform);
127 break;
128 case BackendType::TBB:
129 this->TBBBackend->Transform(inBegin, inEnd, outBegin, transform);
130 break;
131 case BackendType::OpenMP:
132 this->OpenMPBackend->Transform(inBegin, inEnd, outBegin, transform);
133 break;
134 }
135 }
136
137 //--------------------------------------------------------------------------------
138 template <typename InputIt1, typename InputIt2, typename OutputIt, typename Functor>
140 InputIt1 inBegin1, InputIt1 inEnd, InputIt2 inBegin2, OutputIt outBegin, Functor& transform)
141 {
142 switch (this->ActivatedBackend)
143 {
144 case BackendType::Sequential:
145 this->SequentialBackend->Transform(inBegin1, inEnd, inBegin2, outBegin, transform);
146 break;
147 case BackendType::STDThread:
148 this->STDThreadBackend->Transform(inBegin1, inEnd, inBegin2, outBegin, transform);
149 break;
150 case BackendType::TBB:
151 this->TBBBackend->Transform(inBegin1, inEnd, inBegin2, outBegin, transform);
152 break;
153 case BackendType::OpenMP:
154 this->OpenMPBackend->Transform(inBegin1, inEnd, inBegin2, outBegin, transform);
155 break;
156 }
157 }
158
159 //--------------------------------------------------------------------------------
160 template <typename Iterator, typename T>
161 void Fill(Iterator begin, Iterator end, const T& value)
162 {
163 switch (this->ActivatedBackend)
164 {
165 case BackendType::Sequential:
166 this->SequentialBackend->Fill(begin, end, value);
167 break;
168 case BackendType::STDThread:
169 this->STDThreadBackend->Fill(begin, end, value);
170 break;
171 case BackendType::TBB:
172 this->TBBBackend->Fill(begin, end, value);
173 break;
174 case BackendType::OpenMP:
175 this->OpenMPBackend->Fill(begin, end, value);
176 break;
177 }
178 }
179
180 //--------------------------------------------------------------------------------
181 template <typename RandomAccessIterator>
182 void Sort(RandomAccessIterator begin, RandomAccessIterator end)
183 {
184 switch (this->ActivatedBackend)
185 {
186 case BackendType::Sequential:
187 this->SequentialBackend->Sort(begin, end);
188 break;
189 case BackendType::STDThread:
190 this->STDThreadBackend->Sort(begin, end);
191 break;
192 case BackendType::TBB:
193 this->TBBBackend->Sort(begin, end);
194 break;
195 case BackendType::OpenMP:
196 this->OpenMPBackend->Sort(begin, end);
197 break;
198 }
199 }
200
201 //--------------------------------------------------------------------------------
202 template <typename RandomAccessIterator, typename Compare>
203 void Sort(RandomAccessIterator begin, RandomAccessIterator end, Compare comp)
204 {
205 switch (this->ActivatedBackend)
206 {
207 case BackendType::Sequential:
208 this->SequentialBackend->Sort(begin, end, comp);
209 break;
210 case BackendType::STDThread:
211 this->STDThreadBackend->Sort(begin, end, comp);
212 break;
213 case BackendType::TBB:
214 this->TBBBackend->Sort(begin, end, comp);
215 break;
216 case BackendType::OpenMP:
217 this->OpenMPBackend->Sort(begin, end, comp);
218 break;
219 }
220 }
221
222 // disable copying
224 void operator=(vtkSMPToolsAPI const&) = delete;
225
226protected:
227 //--------------------------------------------------------------------------------
228 // Address the static initialization order 'fiasco' by implementing
229 // the schwarz counter idiom.
230 static void ClassInitialize();
231 static void ClassFinalize();
233
234private:
235 //--------------------------------------------------------------------------------
237
238 //--------------------------------------------------------------------------------
239 void RefreshNumberOfThread();
240
241 //--------------------------------------------------------------------------------
242 // This operator overload is used to unpack Config parameters and set them
243 // in vtkSMPToolsAPI (e.g `*this << config;`)
244 template <typename Config>
245 vtkSMPToolsAPI& operator<<(Config const& config)
246 {
247 this->Initialize(config.MaxNumberOfThreads);
248 this->SetBackend(config.Backend.c_str());
249 this->SetNestedParallelism(config.NestedParallelism);
250 return *this;
251 }
252
256 BackendType ActivatedBackend = DefaultBackend;
257
261 int DesiredNumberOfThread = 0;
262
266#if VTK_SMP_ENABLE_SEQUENTIAL
267 std::unique_ptr<vtkSMPToolsImpl<BackendType::Sequential>> SequentialBackend;
268#else
269 std::unique_ptr<vtkSMPToolsDefaultImpl> SequentialBackend;
270#endif
271
275#if VTK_SMP_ENABLE_STDTHREAD
276 std::unique_ptr<vtkSMPToolsImpl<BackendType::STDThread>> STDThreadBackend;
277#else
278 std::unique_ptr<vtkSMPToolsDefaultImpl> STDThreadBackend;
279#endif
280
284#if VTK_SMP_ENABLE_TBB
285 std::unique_ptr<vtkSMPToolsImpl<BackendType::TBB>> TBBBackend;
286#else
287 std::unique_ptr<vtkSMPToolsDefaultImpl> TBBBackend;
288#endif
289
293#if VTK_SMP_ENABLE_OPENMP
294 std::unique_ptr<vtkSMPToolsImpl<BackendType::OpenMP>> OpenMPBackend;
295#else
296 std::unique_ptr<vtkSMPToolsDefaultImpl> OpenMPBackend;
297#endif
298};
299
300//--------------------------------------------------------------------------------
301class VTKCOMMONCORE_EXPORT vtkSMPToolsAPIInitialize
302{
303public:
306};
307
308//--------------------------------------------------------------------------------
309// This instance will show up in any translation unit that uses vtkSMPToolsAPI singleton.
310// It will make sure vtkSMPToolsAPI is initialized before it is used and finalized when it
311// is done being used.
313
314VTK_ABI_NAMESPACE_END
315} // namespace smp
316} // namespace detail
317} // namespace vtk
318
319#endif
320/* VTK-HeaderTest-Exclude: vtkSMPToolsAPI.h */
void Fill(Iterator begin, Iterator end, const T &value)
void Sort(RandomAccessIterator begin, RandomAccessIterator end)
void Transform(InputIt inBegin, InputIt inEnd, OutputIt outBegin, Functor &transform)
void SetNestedParallelism(bool isNested)
void Transform(InputIt1 inBegin1, InputIt1 inEnd, InputIt2 inBegin2, OutputIt outBegin, Functor &transform)
void Initialize(int numThreads=0)
void Sort(RandomAccessIterator begin, RandomAccessIterator end, Compare comp)
void LocalScope(Config const &config, T &&lambda)
void For(vtkIdType first, vtkIdType last, vtkIdType grain, FunctorInternal &fi)
vtkSMPToolsAPI(vtkSMPToolsAPI const &)=delete
static vtkSMPToolsAPI & GetInstance()
void operator=(vtkSMPToolsAPI const &)=delete
bool SetBackend(const char *type)
static vtkSMPToolsAPIInitialize vtkSMPToolsAPIInitializer
Specialization of tuple ranges and iterators for vtkAOSDataArrayTemplate.
VTKCOMMONCORE_EXPORT ostream & operator<<(ostream &os, const vtkIndent &o)
int vtkIdType
Definition vtkType.h:315