VTK  9.2.6
vtkSMPTools.h
Go to the documentation of this file.
1/*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkSMPTools.h
5
6 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7 All rights reserved.
8 See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9
10 This software is distributed WITHOUT ANY WARRANTY; without even
11 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12 PURPOSE. See the above copyright notice for more information.
13
14=========================================================================*/
29
30#ifndef vtkSMPTools_h
31#define vtkSMPTools_h
32
33#include "vtkCommonCoreModule.h" // For export macro
34#include "vtkObject.h"
35
37#include "vtkSMPThreadLocal.h" // For Initialized
38
39#include <functional> // For std::function
40#include <iterator> // For std::iterator
41#include <type_traits> // For std:::enable_if
42
43#ifndef DOXYGEN_SHOULD_SKIP_THIS
44namespace vtk
45{
46namespace detail
47{
48namespace smp
49{
50template <typename T>
51class vtkSMPTools_Has_Initialize
52{
53 typedef char (&no_type)[1];
54 typedef char (&yes_type)[2];
55 template <typename U, void (U::*)()>
56 struct V
57 {
58 };
59 template <typename U>
60 static yes_type check(V<U, &U::Initialize>*);
61 template <typename U>
62 static no_type check(...);
63
64public:
65 static bool const value = sizeof(check<T>(nullptr)) == sizeof(yes_type);
66};
67
68template <typename T>
69class vtkSMPTools_Has_Initialize_const
70{
71 typedef char (&no_type)[1];
72 typedef char (&yes_type)[2];
73 template <typename U, void (U::*)() const>
74 struct V
75 {
76 };
77 template <typename U>
78 static yes_type check(V<U, &U::Initialize>*);
79 template <typename U>
80 static no_type check(...);
81
82public:
83 static bool const value = sizeof(check<T>(0)) == sizeof(yes_type);
84};
85
86template <typename Functor, bool Init>
87struct vtkSMPTools_FunctorInternal;
88
89template <typename Functor>
90struct vtkSMPTools_FunctorInternal<Functor, false>
91{
92 Functor& F;
93 vtkSMPTools_FunctorInternal(Functor& f)
94 : F(f)
95 {
96 }
97 void Execute(vtkIdType first, vtkIdType last) { this->F(first, last); }
98 void For(vtkIdType first, vtkIdType last, vtkIdType grain)
99 {
100 auto& SMPToolsAPI = vtkSMPToolsAPI::GetInstance();
101 SMPToolsAPI.For(first, last, grain, *this);
102 }
103 vtkSMPTools_FunctorInternal<Functor, false>& operator=(
104 const vtkSMPTools_FunctorInternal<Functor, false>&);
105 vtkSMPTools_FunctorInternal<Functor, false>(const vtkSMPTools_FunctorInternal<Functor, false>&);
106};
107
108template <typename Functor>
109struct vtkSMPTools_FunctorInternal<Functor, true>
110{
111 Functor& F;
112 vtkSMPThreadLocal<unsigned char> Initialized;
113 vtkSMPTools_FunctorInternal(Functor& f)
114 : F(f)
115 , Initialized(0)
116 {
117 }
118 void Execute(vtkIdType first, vtkIdType last)
119 {
120 unsigned char& inited = this->Initialized.Local();
121 if (!inited)
122 {
123 this->F.Initialize();
124 inited = 1;
125 }
126 this->F(first, last);
127 }
128 void For(vtkIdType first, vtkIdType last, vtkIdType grain)
129 {
130 auto& SMPToolsAPI = vtkSMPToolsAPI::GetInstance();
131 SMPToolsAPI.For(first, last, grain, *this);
132 this->F.Reduce();
133 }
134 vtkSMPTools_FunctorInternal<Functor, true>& operator=(
135 const vtkSMPTools_FunctorInternal<Functor, true>&);
136 vtkSMPTools_FunctorInternal<Functor, true>(const vtkSMPTools_FunctorInternal<Functor, true>&);
137};
138
139template <typename Functor>
140class vtkSMPTools_Lookup_For
141{
142 static bool const init = vtkSMPTools_Has_Initialize<Functor>::value;
143
144public:
145 typedef vtkSMPTools_FunctorInternal<Functor, init> type;
146};
147
148template <typename Functor>
149class vtkSMPTools_Lookup_For<Functor const>
150{
151 static bool const init = vtkSMPTools_Has_Initialize_const<Functor>::value;
152
153public:
154 typedef vtkSMPTools_FunctorInternal<Functor const, init> type;
155};
156
157template <typename Iterator, typename Functor, bool Init>
158struct vtkSMPTools_RangeFunctor;
159
160template <typename Iterator, typename Functor>
161struct vtkSMPTools_RangeFunctor<Iterator, Functor, false>
162{
163 Functor& F;
164 Iterator& Begin;
165 vtkSMPTools_RangeFunctor(Iterator& begin, Functor& f)
166 : F(f)
167 , Begin(begin)
168 {
169 }
170 void operator()(vtkIdType first, vtkIdType last)
171 {
172 Iterator itFirst(Begin);
173 std::advance(itFirst, first);
174 Iterator itLast(itFirst);
175 std::advance(itLast, last - first);
176 this->F(itFirst, itLast);
177 }
178};
179
180template <typename Iterator, typename Functor>
181struct vtkSMPTools_RangeFunctor<Iterator, Functor, true>
182{
183 Functor& F;
184 Iterator& Begin;
185 vtkSMPTools_RangeFunctor(Iterator& begin, Functor& f)
186 : F(f)
187 , Begin(begin)
188 {
189 }
190 void Initialize() { this->F.Initialize(); }
191 void operator()(vtkIdType first, vtkIdType last)
192 {
193 Iterator itFirst(Begin);
194 std::advance(itFirst, first);
195 Iterator itLast(itFirst);
196 std::advance(itLast, last - first);
197 this->F(itFirst, itLast);
198 }
199 void Reduce() { this->F.Reduce(); }
200};
201
202template <typename Iterator, typename Functor>
203class vtkSMPTools_Lookup_RangeFor
204{
205 static bool const init = vtkSMPTools_Has_Initialize<Functor>::value;
206
207public:
208 typedef vtkSMPTools_RangeFunctor<Iterator, Functor, init> type;
209};
210
211template <typename Iterator, typename Functor>
212class vtkSMPTools_Lookup_RangeFor<Iterator, Functor const>
213{
214 static bool const init = vtkSMPTools_Has_Initialize_const<Functor>::value;
215
216public:
217 typedef vtkSMPTools_RangeFunctor<Iterator, Functor const, init> type;
218};
219
220template <typename T>
221using resolvedNotInt = typename std::enable_if<!std::is_integral<T>::value, void>::type;
222} // namespace smp
223} // namespace detail
224} // namespace vtk
225#endif // DOXYGEN_SHOULD_SKIP_THIS
226
227class VTKCOMMONCORE_EXPORT vtkSMPTools
228{
229public:
231
240 template <typename Functor>
241 static void For(vtkIdType first, vtkIdType last, vtkIdType grain, Functor& f)
242 {
243 typename vtk::detail::smp::vtkSMPTools_Lookup_For<Functor>::type fi(f);
244 fi.For(first, last, grain);
245 }
246
247 template <typename Functor>
248 static void For(vtkIdType first, vtkIdType last, vtkIdType grain, Functor const& f)
249 {
250 typename vtk::detail::smp::vtkSMPTools_Lookup_For<Functor const>::type fi(f);
251 fi.For(first, last, grain);
252 }
253
254
256
265 template <typename Functor>
266 static void For(vtkIdType first, vtkIdType last, Functor& f)
267 {
268 vtkSMPTools::For(first, last, 0, f);
269 }
270
271 template <typename Functor>
272 static void For(vtkIdType first, vtkIdType last, Functor const& f)
273 {
274 vtkSMPTools::For(first, last, 0, f);
275 }
276
277
279
314 template <typename Iter, typename Functor>
315 static vtk::detail::smp::resolvedNotInt<Iter> For(
316 Iter begin, Iter end, vtkIdType grain, Functor& f)
317 {
318 vtkIdType size = std::distance(begin, end);
319 typename vtk::detail::smp::vtkSMPTools_Lookup_RangeFor<Iter, Functor>::type fi(begin, f);
320 vtkSMPTools::For(0, size, grain, fi);
321 }
322
323 template <typename Iter, typename Functor>
324 static vtk::detail::smp::resolvedNotInt<Iter> For(
325 Iter begin, Iter end, vtkIdType grain, Functor const& f)
326 {
327 vtkIdType size = std::distance(begin, end);
328 typename vtk::detail::smp::vtkSMPTools_Lookup_RangeFor<Iter, Functor const>::type fi(begin, f);
329 vtkSMPTools::For(0, size, grain, fi);
330 }
331
332
334
367 template <typename Iter, typename Functor>
368 static vtk::detail::smp::resolvedNotInt<Iter> For(Iter begin, Iter end, Functor& f)
369 {
370 vtkSMPTools::For(begin, end, 0, f);
371 }
372
373 template <typename Iter, typename Functor>
374 static vtk::detail::smp::resolvedNotInt<Iter> For(Iter begin, Iter end, Functor const& f)
375 {
376 vtkSMPTools::For(begin, end, 0, f);
377 }
378
379
383 static const char* GetBackend();
384
396 static bool SetBackend(const char* backend);
397
413 static void Initialize(int numThreads = 0);
414
422
434 static void SetNestedParallelism(bool isNested);
435
439 static bool GetNestedParallelism();
440
444 static bool IsParallelScope();
445
453 struct Config
454 {
457 bool NestedParallelism = true;
458
460 Config(int maxNumberOfThreads)
461 : MaxNumberOfThreads(maxNumberOfThreads)
462 {
463 }
464 Config(std::string backend)
465 : Backend(backend)
466 {
467 }
468 Config(bool nestedParallelism)
469 : NestedParallelism(nestedParallelism)
470 {
471 }
472 Config(int maxNumberOfThreads, std::string backend, bool nestedParallelism)
473 : MaxNumberOfThreads(maxNumberOfThreads)
474 , Backend(backend)
475 , NestedParallelism(nestedParallelism)
476 {
477 }
478#ifndef DOXYGEN_SHOULD_SKIP_THIS
480 : MaxNumberOfThreads(API.GetInternalDesiredNumberOfThread())
481 , Backend(API.GetBackend())
482 , NestedParallelism(API.GetNestedParallelism())
483 {
484 }
485#endif // DOXYGEN_SHOULD_SKIP_THIS
486 };
487
499 template <typename T>
500 static void LocalScope(Config const& config, T&& lambda)
501 {
503 SMPToolsAPI.LocalScope<vtkSMPTools::Config>(config, lambda);
504 }
505
521 template <typename InputIt, typename OutputIt, typename Functor>
522 static void Transform(InputIt inBegin, InputIt inEnd, OutputIt outBegin, Functor transform)
523 {
525 SMPToolsAPI.Transform(inBegin, inEnd, outBegin, transform);
526 }
527
544 template <typename InputIt1, typename InputIt2, typename OutputIt, typename Functor>
545 static void Transform(
546 InputIt1 inBegin1, InputIt1 inEnd, InputIt2 inBegin2, OutputIt outBegin, Functor transform)
547 {
549 SMPToolsAPI.Transform(inBegin1, inEnd, inBegin2, outBegin, transform);
550 }
551
566 template <typename Iterator, typename T>
567 static void Fill(Iterator begin, Iterator end, const T& value)
568 {
570 SMPToolsAPI.Fill(begin, end, value);
571 }
572
578 template <typename RandomAccessIterator>
579 static void Sort(RandomAccessIterator begin, RandomAccessIterator end)
580 {
582 SMPToolsAPI.Sort(begin, end);
583 }
584
591 template <typename RandomAccessIterator, typename Compare>
592 static void Sort(RandomAccessIterator begin, RandomAccessIterator end, Compare comp)
593 {
595 SMPToolsAPI.Sort(begin, end, comp);
596 }
597};
598
599#endif
600// VTK-HeaderTest-Exclude: vtkSMPTools.h
T & Local()
This needs to be called mainly within a threaded execution path.
A set of parallel (multi-threaded) utility functions.
static void Transform(InputIt1 inBegin1, InputIt1 inEnd, InputIt2 inBegin2, OutputIt outBegin, Functor transform)
A convenience method for transforming data.
static vtk::detail::smp::resolvedNotInt< Iter > For(Iter begin, Iter end, Functor const &f)
Execute a for operation in parallel.
static void Initialize(int numThreads=0)
/!
static bool SetBackend(const char *backend)
/!
static bool IsParallelScope()
Return true if it is called from a parallel scope.
static void Transform(InputIt inBegin, InputIt inEnd, OutputIt outBegin, Functor transform)
A convenience method for transforming data.
static int GetEstimatedNumberOfThreads()
Get the estimated number of threads being used by the backend.
static vtk::detail::smp::resolvedNotInt< Iter > For(Iter begin, Iter end, Functor &f)
Execute a for operation in parallel.
static void SetNestedParallelism(bool isNested)
/!
static vtk::detail::smp::resolvedNotInt< Iter > For(Iter begin, Iter end, vtkIdType grain, Functor &f)
Execute a for operation in parallel.
static void Sort(RandomAccessIterator begin, RandomAccessIterator end)
A convenience method for sorting data.
static void Fill(Iterator begin, Iterator end, const T &value)
A convenience method for filling data.
static void For(vtkIdType first, vtkIdType last, Functor const &f)
Execute a for operation in parallel.
static void For(vtkIdType first, vtkIdType last, Functor &f)
Execute a for operation in parallel.
static vtk::detail::smp::resolvedNotInt< Iter > For(Iter begin, Iter end, vtkIdType grain, Functor const &f)
Execute a for operation in parallel.
static void For(vtkIdType first, vtkIdType last, vtkIdType grain, Functor const &f)
Execute a for operation in parallel.
static void Sort(RandomAccessIterator begin, RandomAccessIterator end, Compare comp)
A convenience method for sorting data.
static bool GetNestedParallelism()
Get true if the nested parallelism is enabled.
static void LocalScope(Config const &config, T &&lambda)
/!
static const char * GetBackend()
Get the backend in use.
static void For(vtkIdType first, vtkIdType last, vtkIdType grain, Functor &f)
Execute a for operation in parallel.
static vtkSMPToolsAPI & GetInstance()
@ value
Definition vtkX3D.h:226
@ type
Definition vtkX3D.h:522
Specialization of tuple ranges and iterators for vtkAOSDataArrayTemplate.
Structure used to specify configuration for LocalScope() method.
Config(std::string backend)
Config(int maxNumberOfThreads)
std::string Backend
Config(bool nestedParallelism)
Config(int maxNumberOfThreads, std::string backend, bool nestedParallelism)
int vtkIdType
Definition vtkType.h:332