VTK  9.7.1
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 
28 namespace vtk
29 {
30 namespace detail
31 {
32 namespace smp
33 {
34 VTK_ABI_NAMESPACE_BEGIN
35 
37 
38 class VTKCOMMONCORE_EXPORT vtkSMPToolsAPI
39 {
40 public:
41  //--------------------------------------------------------------------------------
42  static vtkSMPToolsAPI& GetInstance();
43 
44  //--------------------------------------------------------------------------------
45  BackendType GetBackendType();
46 
47  //--------------------------------------------------------------------------------
48  const char* GetBackend();
49 
50  //--------------------------------------------------------------------------------
51  bool SetBackend(const char* type);
52 
53  //--------------------------------------------------------------------------------
54  void Initialize(int numThreads = 0);
55 
56  //--------------------------------------------------------------------------------
57  int GetEstimatedNumberOfThreads();
58 
59  //--------------------------------------------------------------------------------
60  int GetEstimatedDefaultNumberOfThreads();
61 
62  //------------------------------------------------------------------------------
63  void SetNestedParallelism(bool isNested);
64 
65  //--------------------------------------------------------------------------------
66  bool GetNestedParallelism();
67 
68  //--------------------------------------------------------------------------------
69  bool IsParallelScope();
70 
71  //--------------------------------------------------------------------------------
72  bool GetSingleThread();
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  {
102  this->SequentialBackend->For(first, last, grain, fi);
103  break;
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  {
123  this->SequentialBackend->Transform(inBegin, inEnd, outBegin, transform);
124  break;
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>
139  void Transform(
140  InputIt1 inBegin1, InputIt1 inEnd, InputIt2 inBegin2, OutputIt outBegin, Functor& transform)
141  {
142  switch (this->ActivatedBackend)
143  {
145  this->SequentialBackend->Transform(inBegin1, inEnd, inBegin2, outBegin, transform);
146  break;
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  {
166  this->SequentialBackend->Fill(begin, end, value);
167  break;
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  {
187  this->SequentialBackend->Sort(begin, end);
188  break;
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  {
208  this->SequentialBackend->Sort(begin, end, comp);
209  break;
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
223  vtkSMPToolsAPI(vtkSMPToolsAPI const&) = delete;
224  void operator=(vtkSMPToolsAPI const&) = delete;
225 
226 protected:
227  //--------------------------------------------------------------------------------
228  // Address the static initialization order 'fiasco' by implementing
229  // the schwarz counter idiom.
230  static void ClassInitialize();
231  static void ClassFinalize();
233 
234 private:
235  //--------------------------------------------------------------------------------
236  vtkSMPToolsAPI();
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 //--------------------------------------------------------------------------------
301 class VTKCOMMONCORE_EXPORT vtkSMPToolsAPIInitialize
302 {
303 public:
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 
314 VTK_ABI_NAMESPACE_END
315 } // namespace smp
316 } // namespace detail
317 } // namespace vtk
318 
319 #endif
320 /* VTK-HeaderTest-Exclude: vtkSMPToolsAPI.h */
void Transform(InputIt inBegin, InputIt inEnd, OutputIt outBegin, Functor &transform)
void Sort(RandomAccessIterator begin, RandomAccessIterator end, Compare comp)
Specialization of tuple ranges and iterators for vtkAOSDataArrayTemplate.
int vtkIdType
Definition: vtkType.h:363
void For(vtkIdType first, vtkIdType last, vtkIdType grain, FunctorInternal &fi)
void Transform(InputIt1 inBegin1, InputIt1 inEnd, InputIt2 inBegin2, OutputIt outBegin, Functor &transform)
void LocalScope(Config const &config, T &&lambda)
void Sort(RandomAccessIterator begin, RandomAccessIterator end)
VTKCOMMONCORE_EXPORT ostream & operator<<(ostream &os, const vtkIndent &o)
void Fill(Iterator begin, Iterator end, const T &value)
static vtkSMPToolsAPIInitialize vtkSMPToolsAPIInitializer