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=========================================================================*/
36#ifndef vtkSMPTools_h
37#define vtkSMPTools_h
38
39#include "vtkCommonCoreModule.h" // For export macro
40#include "vtkObject.h"
41
43#include "vtkSMPThreadLocal.h" // For Initialized
44
45#include <functional> // For std::function
46#include <iterator> // For std::iterator
47#include <type_traits> // For std:::enable_if
48
49#ifndef DOXYGEN_SHOULD_SKIP_THIS
50namespace vtk
51{
52namespace detail
53{
54namespace smp
55{
56template <typename T>
57class vtkSMPTools_Has_Initialize
58{
59 typedef char (&no_type)[1];
60 typedef char (&yes_type)[2];
61 template <typename U, void (U::*)()>
62 struct V
63 {
64 };
65 template <typename U>
66 static yes_type check(V<U, &U::Initialize>*);
67 template <typename U>
68 static no_type check(...);
69
70public:
71 static bool const value = sizeof(check<T>(nullptr)) == sizeof(yes_type);
72};
73
74template <typename T>
75class vtkSMPTools_Has_Initialize_const
76{
77 typedef char (&no_type)[1];
78 typedef char (&yes_type)[2];
79 template <typename U, void (U::*)() const>
80 struct V
81 {
82 };
83 template <typename U>
84 static yes_type check(V<U, &U::Initialize>*);
85 template <typename U>
86 static no_type check(...);
87
88public:
89 static bool const value = sizeof(check<T>(0)) == sizeof(yes_type);
90};
91
92template <typename Functor, bool Init>
93struct vtkSMPTools_FunctorInternal;
94
95template <typename Functor>
96struct vtkSMPTools_FunctorInternal<Functor, false>
97{
98 Functor& F;
99 vtkSMPTools_FunctorInternal(Functor& f)
100 : F(f)
101 {
102 }
103 void Execute(vtkIdType first, vtkIdType last) { this->F(first, last); }
104 void For(vtkIdType first, vtkIdType last, vtkIdType grain)
105 {
106 auto& SMPToolsAPI = vtkSMPToolsAPI::GetInstance();
107 SMPToolsAPI.For(first, last, grain, *this);
108 }
109 vtkSMPTools_FunctorInternal<Functor, false>& operator=(
110 const vtkSMPTools_FunctorInternal<Functor, false>&);
111 vtkSMPTools_FunctorInternal<Functor, false>(const vtkSMPTools_FunctorInternal<Functor, false>&);
112};
113
114template <typename Functor>
115struct vtkSMPTools_FunctorInternal<Functor, true>
116{
117 Functor& F;
119 vtkSMPTools_FunctorInternal(Functor& f)
120 : F(f)
121 , Initialized(0)
122 {
123 }
124 void Execute(vtkIdType first, vtkIdType last)
125 {
126 unsigned char& inited = this->Initialized.Local();
127 if (!inited)
128 {
129 this->F.Initialize();
130 inited = 1;
131 }
132 this->F(first, last);
133 }
134 void For(vtkIdType first, vtkIdType last, vtkIdType grain)
135 {
136 auto& SMPToolsAPI = vtkSMPToolsAPI::GetInstance();
137 SMPToolsAPI.For(first, last, grain, *this);
138 this->F.Reduce();
139 }
140 vtkSMPTools_FunctorInternal<Functor, true>& operator=(
141 const vtkSMPTools_FunctorInternal<Functor, true>&);
142 vtkSMPTools_FunctorInternal<Functor, true>(const vtkSMPTools_FunctorInternal<Functor, true>&);
143};
144
145template <typename Functor>
146class vtkSMPTools_Lookup_For
147{
148 static bool const init = vtkSMPTools_Has_Initialize<Functor>::value;
149
150public:
151 typedef vtkSMPTools_FunctorInternal<Functor, init> type;
152};
153
154template <typename Functor>
155class vtkSMPTools_Lookup_For<Functor const>
156{
157 static bool const init = vtkSMPTools_Has_Initialize_const<Functor>::value;
158
159public:
160 typedef vtkSMPTools_FunctorInternal<Functor const, init> type;
161};
162
163template <typename Iterator, typename Functor, bool Init>
164struct vtkSMPTools_RangeFunctor;
165
166template <typename Iterator, typename Functor>
167struct vtkSMPTools_RangeFunctor<Iterator, Functor, false>
168{
169 Functor& F;
170 Iterator& Begin;
171 vtkSMPTools_RangeFunctor(Iterator& begin, Functor& f)
172 : F(f)
173 , Begin(begin)
174 {
175 }
176 void operator()(vtkIdType first, vtkIdType last)
177 {
178 Iterator itFirst(Begin);
179 std::advance(itFirst, first);
180 Iterator itLast(itFirst);
181 std::advance(itLast, last - first);
182 this->F(itFirst, itLast);
183 }
184};
185
186template <typename Iterator, typename Functor>
187struct vtkSMPTools_RangeFunctor<Iterator, Functor, true>
188{
189 Functor& F;
190 Iterator& Begin;
191 vtkSMPTools_RangeFunctor(Iterator& begin, Functor& f)
192 : F(f)
193 , Begin(begin)
194 {
195 }
196 void Initialize() { this->F.Initialize(); }
197 void operator()(vtkIdType first, vtkIdType last)
198 {
199 Iterator itFirst(Begin);
200 std::advance(itFirst, first);
201 Iterator itLast(itFirst);
202 std::advance(itLast, last - first);
203 this->F(itFirst, itLast);
204 }
205 void Reduce() { this->F.Reduce(); }
206};
207
208template <typename Iterator, typename Functor>
209class vtkSMPTools_Lookup_RangeFor
210{
211 static bool const init = vtkSMPTools_Has_Initialize<Functor>::value;
212
213public:
214 typedef vtkSMPTools_RangeFunctor<Iterator, Functor, init> type;
215};
216
217template <typename Iterator, typename Functor>
218class vtkSMPTools_Lookup_RangeFor<Iterator, Functor const>
219{
220 static bool const init = vtkSMPTools_Has_Initialize_const<Functor>::value;
221
222public:
223 typedef vtkSMPTools_RangeFunctor<Iterator, Functor const, init> type;
224};
225
226template <typename T>
227using resolvedNotInt = typename std::enable_if<!std::is_integral<T>::value, void>::type;
228} // namespace smp
229} // namespace detail
230} // namespace vtk
231#endif // DOXYGEN_SHOULD_SKIP_THIS
232
233class VTKCOMMONCORE_EXPORT vtkSMPTools
234{
235public:
237
246 template <typename Functor>
247 static void For(vtkIdType first, vtkIdType last, vtkIdType grain, Functor& f)
248 {
249 typename vtk::detail::smp::vtkSMPTools_Lookup_For<Functor>::type fi(f);
250 fi.For(first, last, grain);
251 }
252
253 template <typename Functor>
254 static void For(vtkIdType first, vtkIdType last, vtkIdType grain, Functor const& f)
255 {
256 typename vtk::detail::smp::vtkSMPTools_Lookup_For<Functor const>::type fi(f);
257 fi.For(first, last, grain);
258 }
260
262
271 template <typename Functor>
272 static void For(vtkIdType first, vtkIdType last, Functor& f)
273 {
274 vtkSMPTools::For(first, last, 0, f);
275 }
276
277 template <typename Functor>
278 static void For(vtkIdType first, vtkIdType last, Functor const& f)
279 {
280 vtkSMPTools::For(first, last, 0, f);
281 }
283
285
320 template <typename Iter, typename Functor>
321 static vtk::detail::smp::resolvedNotInt<Iter> For(
322 Iter begin, Iter end, vtkIdType grain, Functor& f)
323 {
324 vtkIdType size = std::distance(begin, end);
325 typename vtk::detail::smp::vtkSMPTools_Lookup_RangeFor<Iter, Functor>::type fi(begin, f);
326 vtkSMPTools::For(0, size, grain, fi);
327 }
328
329 template <typename Iter, typename Functor>
330 static vtk::detail::smp::resolvedNotInt<Iter> For(
331 Iter begin, Iter end, vtkIdType grain, Functor const& f)
332 {
333 vtkIdType size = std::distance(begin, end);
334 typename vtk::detail::smp::vtkSMPTools_Lookup_RangeFor<Iter, Functor const>::type fi(begin, f);
335 vtkSMPTools::For(0, size, grain, fi);
336 }
338
340
373 template <typename Iter, typename Functor>
374 static vtk::detail::smp::resolvedNotInt<Iter> For(Iter begin, Iter end, Functor& f)
375 {
376 vtkSMPTools::For(begin, end, 0, f);
377 }
378
379 template <typename Iter, typename Functor>
380 static vtk::detail::smp::resolvedNotInt<Iter> For(Iter begin, Iter end, Functor const& f)
381 {
382 vtkSMPTools::For(begin, end, 0, f);
383 }
385
389 static const char* GetBackend();
390
402 static bool SetBackend(const char* backend);
403
419 static void Initialize(int numThreads = 0);
420
428
440 static void SetNestedParallelism(bool isNested);
441
445 static bool GetNestedParallelism();
446
450 static bool IsParallelScope();
451
459 struct Config
460 {
461 int MaxNumberOfThreads = 0;
463 bool NestedParallelism = true;
464
466 Config(int maxNumberOfThreads)
467 : MaxNumberOfThreads(maxNumberOfThreads)
468 {
469 }
470 Config(std::string backend)
471 : Backend(backend)
472 {
473 }
474 Config(bool nestedParallelism)
475 : NestedParallelism(nestedParallelism)
476 {
477 }
478 Config(int maxNumberOfThreads, std::string backend, bool nestedParallelism)
479 : MaxNumberOfThreads(maxNumberOfThreads)
480 , Backend(backend)
481 , NestedParallelism(nestedParallelism)
482 {
483 }
484#ifndef DOXYGEN_SHOULD_SKIP_THIS
486 : MaxNumberOfThreads(API.GetInternalDesiredNumberOfThread())
487 , Backend(API.GetBackend())
488 , NestedParallelism(API.GetNestedParallelism())
489 {
490 }
491#endif // DOXYGEN_SHOULD_SKIP_THIS
492 };
493
505 template <typename T>
506 static void LocalScope(Config const& config, T&& lambda)
507 {
509 SMPToolsAPI.LocalScope<vtkSMPTools::Config>(config, lambda);
510 }
511
527 template <typename InputIt, typename OutputIt, typename Functor>
528 static void Transform(InputIt inBegin, InputIt inEnd, OutputIt outBegin, Functor transform)
529 {
531 SMPToolsAPI.Transform(inBegin, inEnd, outBegin, transform);
532 }
533
550 template <typename InputIt1, typename InputIt2, typename OutputIt, typename Functor>
551 static void Transform(
552 InputIt1 inBegin1, InputIt1 inEnd, InputIt2 inBegin2, OutputIt outBegin, Functor transform)
553 {
555 SMPToolsAPI.Transform(inBegin1, inEnd, inBegin2, outBegin, transform);
556 }
557
572 template <typename Iterator, typename T>
573 static void Fill(Iterator begin, Iterator end, const T& value)
574 {
576 SMPToolsAPI.Fill(begin, end, value);
577 }
578
584 template <typename RandomAccessIterator>
585 static void Sort(RandomAccessIterator begin, RandomAccessIterator end)
586 {
588 SMPToolsAPI.Sort(begin, end);
589 }
590
597 template <typename RandomAccessIterator, typename Compare>
598 static void Sort(RandomAccessIterator begin, RandomAccessIterator end, Compare comp)
599 {
601 SMPToolsAPI.Sort(begin, end, comp);
602 }
603};
604
605#endif
606// VTK-HeaderTest-Exclude: vtkSMPTools.h
Thread local storage for VTK objects.
T & Local()
This needs to be called mainly within a threaded execution path.
A set of parallel (multi-threaded) utility functions.
Definition: vtkSMPTools.h:234
static void Transform(InputIt1 inBegin1, InputIt1 inEnd, InputIt2 inBegin2, OutputIt outBegin, Functor transform)
A convenience method for transforming data.
Definition: vtkSMPTools.h:551
static vtk::detail::smp::resolvedNotInt< Iter > For(Iter begin, Iter end, Functor const &f)
Execute a for operation in parallel.
Definition: vtkSMPTools.h:380
static void Initialize(int numThreads=0)
/!\ This method is not thread safe.
static bool SetBackend(const char *backend)
/!\ This method is not thread safe.
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.
Definition: vtkSMPTools.h:528
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.
Definition: vtkSMPTools.h:374
static void SetNestedParallelism(bool isNested)
/!\ This method is not thread safe.
static vtk::detail::smp::resolvedNotInt< Iter > For(Iter begin, Iter end, vtkIdType grain, Functor &f)
Execute a for operation in parallel.
Definition: vtkSMPTools.h:321
static void Sort(RandomAccessIterator begin, RandomAccessIterator end)
A convenience method for sorting data.
Definition: vtkSMPTools.h:585
static void Fill(Iterator begin, Iterator end, const T &value)
A convenience method for filling data.
Definition: vtkSMPTools.h:573
static void For(vtkIdType first, vtkIdType last, Functor const &f)
Execute a for operation in parallel.
Definition: vtkSMPTools.h:278
static void For(vtkIdType first, vtkIdType last, Functor &f)
Execute a for operation in parallel.
Definition: vtkSMPTools.h:272
static vtk::detail::smp::resolvedNotInt< Iter > For(Iter begin, Iter end, vtkIdType grain, Functor const &f)
Execute a for operation in parallel.
Definition: vtkSMPTools.h:330
static void For(vtkIdType first, vtkIdType last, vtkIdType grain, Functor const &f)
Execute a for operation in parallel.
Definition: vtkSMPTools.h:254
static void Sort(RandomAccessIterator begin, RandomAccessIterator end, Compare comp)
A convenience method for sorting data.
Definition: vtkSMPTools.h:598
static bool GetNestedParallelism()
Get true if the nested parallelism is enabled.
static void LocalScope(Config const &config, T &&lambda)
/!\ This method is not thread safe.
Definition: vtkSMPTools.h:506
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.
Definition: vtkSMPTools.h:247
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.
Definition: vtkSMPTools.h:460
Config(std::string backend)
Definition: vtkSMPTools.h:470
Config(int maxNumberOfThreads)
Definition: vtkSMPTools.h:466
Config(bool nestedParallelism)
Definition: vtkSMPTools.h:474
Config(int maxNumberOfThreads, std::string backend, bool nestedParallelism)
Definition: vtkSMPTools.h:478
int vtkIdType
Definition: vtkType.h:332