VTK  9.1.0
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=========================================================================*/
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
44#ifndef __VTK_WRAP__
45namespace vtk
46{
47namespace detail
48{
49namespace smp
50{
51template <typename T>
52class vtkSMPTools_Has_Initialize
53{
54 typedef char (&no_type)[1];
55 typedef char (&yes_type)[2];
56 template <typename U, void (U::*)()>
57 struct V
58 {
59 };
60 template <typename U>
61 static yes_type check(V<U, &U::Initialize>*);
62 template <typename U>
63 static no_type check(...);
64
65public:
66 static bool const value = sizeof(check<T>(nullptr)) == sizeof(yes_type);
67};
68
69template <typename T>
70class vtkSMPTools_Has_Initialize_const
71{
72 typedef char (&no_type)[1];
73 typedef char (&yes_type)[2];
74 template <typename U, void (U::*)() const>
75 struct V
76 {
77 };
78 template <typename U>
79 static yes_type check(V<U, &U::Initialize>*);
80 template <typename U>
81 static no_type check(...);
82
83public:
84 static bool const value = sizeof(check<T>(0)) == sizeof(yes_type);
85};
86
87template <typename Functor, bool Init>
88struct vtkSMPTools_FunctorInternal;
89
90template <typename Functor>
91struct vtkSMPTools_FunctorInternal<Functor, false>
92{
93 Functor& F;
94 vtkSMPTools_FunctorInternal(Functor& f)
95 : F(f)
96 {
97 }
98 void Execute(vtkIdType first, vtkIdType last) { this->F(first, last); }
99 void For(vtkIdType first, vtkIdType last, vtkIdType grain)
100 {
101 auto& SMPToolsAPI = vtkSMPToolsAPI::GetInstance();
102 SMPToolsAPI.For(first, last, grain, *this);
103 }
104 vtkSMPTools_FunctorInternal<Functor, false>& operator=(
105 const vtkSMPTools_FunctorInternal<Functor, false>&);
106 vtkSMPTools_FunctorInternal<Functor, false>(const vtkSMPTools_FunctorInternal<Functor, false>&);
107};
108
109template <typename Functor>
110struct vtkSMPTools_FunctorInternal<Functor, true>
111{
112 Functor& F;
114 vtkSMPTools_FunctorInternal(Functor& f)
115 : F(f)
116 , Initialized(0)
117 {
118 }
119 void Execute(vtkIdType first, vtkIdType last)
120 {
121 unsigned char& inited = this->Initialized.Local();
122 if (!inited)
123 {
124 this->F.Initialize();
125 inited = 1;
126 }
127 this->F(first, last);
128 }
129 void For(vtkIdType first, vtkIdType last, vtkIdType grain)
130 {
131 auto& SMPToolsAPI = vtkSMPToolsAPI::GetInstance();
132 SMPToolsAPI.For(first, last, grain, *this);
133 this->F.Reduce();
134 }
135 vtkSMPTools_FunctorInternal<Functor, true>& operator=(
136 const vtkSMPTools_FunctorInternal<Functor, true>&);
137 vtkSMPTools_FunctorInternal<Functor, true>(const vtkSMPTools_FunctorInternal<Functor, true>&);
138};
139
140template <typename Functor>
141class vtkSMPTools_Lookup_For
142{
143 static bool const init = vtkSMPTools_Has_Initialize<Functor>::value;
144
145public:
146 typedef vtkSMPTools_FunctorInternal<Functor, init> type;
147};
148
149template <typename Functor>
150class vtkSMPTools_Lookup_For<Functor const>
151{
152 static bool const init = vtkSMPTools_Has_Initialize_const<Functor>::value;
153
154public:
155 typedef vtkSMPTools_FunctorInternal<Functor const, init> type;
156};
157
158template <typename Iterator, typename Functor, bool Init>
159struct vtkSMPTools_RangeFunctor;
160
161template <typename Iterator, typename Functor>
162struct vtkSMPTools_RangeFunctor<Iterator, Functor, false>
163{
164 Functor& F;
165 Iterator& Begin;
166 vtkSMPTools_RangeFunctor(Iterator& begin, Functor& f)
167 : F(f)
168 , Begin(begin)
169 {
170 }
171 void operator()(vtkIdType first, vtkIdType last)
172 {
173 Iterator itFirst(Begin);
174 std::advance(itFirst, first);
175 Iterator itLast(itFirst);
176 std::advance(itLast, last - first);
177 this->F(itFirst, itLast);
178 }
179};
180
181template <typename Iterator, typename Functor>
182struct vtkSMPTools_RangeFunctor<Iterator, Functor, true>
183{
184 Functor& F;
185 Iterator& Begin;
186 vtkSMPTools_RangeFunctor(Iterator& begin, Functor& f)
187 : F(f)
188 , Begin(begin)
189 {
190 }
191 void Initialize() { this->F.Initialize(); }
192 void operator()(vtkIdType first, vtkIdType last)
193 {
194 Iterator itFirst(Begin);
195 std::advance(itFirst, first);
196 Iterator itLast(itFirst);
197 std::advance(itLast, last - first);
198 this->F(itFirst, itLast);
199 }
200 void Reduce() { this->F.Reduce(); }
201};
202
203template <typename Iterator, typename Functor>
204class vtkSMPTools_Lookup_RangeFor
205{
206 static bool const init = vtkSMPTools_Has_Initialize<Functor>::value;
207
208public:
209 typedef vtkSMPTools_RangeFunctor<Iterator, Functor, init> type;
210};
211
212template <typename Iterator, typename Functor>
213class vtkSMPTools_Lookup_RangeFor<Iterator, Functor const>
214{
215 static bool const init = vtkSMPTools_Has_Initialize_const<Functor>::value;
216
217public:
218 typedef vtkSMPTools_RangeFunctor<Iterator, Functor const, init> type;
219};
220
221template <typename T>
222using resolvedNotInt = typename std::enable_if<!std::is_integral<T>::value, void>::type;
223} // namespace smp
224} // namespace detail
225} // namespace vtk
226#endif // __VTK_WRAP__
227#endif // DOXYGEN_SHOULD_SKIP_THIS
228
229class VTKCOMMONCORE_EXPORT vtkSMPTools
230{
231public:
233
242 template <typename Functor>
243 static void For(vtkIdType first, vtkIdType last, vtkIdType grain, Functor& f)
244 {
245 typename vtk::detail::smp::vtkSMPTools_Lookup_For<Functor>::type fi(f);
246 fi.For(first, last, grain);
247 }
248
249 template <typename Functor>
250 static void For(vtkIdType first, vtkIdType last, vtkIdType grain, Functor const& f)
251 {
252 typename vtk::detail::smp::vtkSMPTools_Lookup_For<Functor const>::type fi(f);
253 fi.For(first, last, grain);
254 }
256
258
267 template <typename Functor>
268 static void For(vtkIdType first, vtkIdType last, Functor& f)
269 {
270 vtkSMPTools::For(first, last, 0, f);
271 }
272
273 template <typename Functor>
274 static void For(vtkIdType first, vtkIdType last, Functor const& f)
275 {
276 vtkSMPTools::For(first, last, 0, f);
277 }
279
281
316 template <typename Iter, typename Functor>
317 static vtk::detail::smp::resolvedNotInt<Iter> For(
318 Iter begin, Iter end, vtkIdType grain, Functor& f)
319 {
320 vtkIdType size = std::distance(begin, end);
321 typename vtk::detail::smp::vtkSMPTools_Lookup_RangeFor<Iter, Functor>::type fi(begin, f);
322 vtkSMPTools::For(0, size, grain, fi);
323 }
324
325 template <typename Iter, typename Functor>
326 static vtk::detail::smp::resolvedNotInt<Iter> For(
327 Iter begin, Iter end, vtkIdType grain, Functor const& f)
328 {
329 vtkIdType size = std::distance(begin, end);
330 typename vtk::detail::smp::vtkSMPTools_Lookup_RangeFor<Iter, Functor const>::type fi(begin, f);
331 vtkSMPTools::For(0, size, grain, fi);
332 }
334
336
369 template <typename Iter, typename Functor>
370 static vtk::detail::smp::resolvedNotInt<Iter> For(Iter begin, Iter end, Functor& f)
371 {
372 vtkSMPTools::For(begin, end, 0, f);
373 }
374
375 template <typename Iter, typename Functor>
376 static vtk::detail::smp::resolvedNotInt<Iter> For(Iter begin, Iter end, Functor const& f)
377 {
378 vtkSMPTools::For(begin, end, 0, f);
379 }
381
385 static const char* GetBackend();
386
398 static bool SetBackend(const char* backend);
399
415 static void Initialize(int numThreads = 0);
416
424
436 static void SetNestedParallelism(bool isNested);
437
441 static bool GetNestedParallelism();
442
446 static bool IsParallelScope();
447
455 struct Config
456 {
457 int MaxNumberOfThreads = 0;
459 bool NestedParallelism = true;
460
462 Config(int maxNumberOfThreads)
463 : MaxNumberOfThreads(maxNumberOfThreads)
464 {
465 }
466 Config(std::string backend)
467 : Backend(backend)
468 {
469 }
470 Config(bool nestedParallelism)
471 : NestedParallelism(nestedParallelism)
472 {
473 }
474 Config(int maxNumberOfThreads, std::string backend, bool nestedParallelism)
475 : MaxNumberOfThreads(maxNumberOfThreads)
476 , Backend(backend)
477 , NestedParallelism(nestedParallelism)
478 {
479 }
480#ifndef DOXYGEN_SHOULD_SKIP_THIS
482 : MaxNumberOfThreads(API.GetInternalDesiredNumberOfThread())
483 , Backend(API.GetBackend())
484 , NestedParallelism(API.GetNestedParallelism())
485 {
486 }
487#endif // DOXYGEN_SHOULD_SKIP_THIS
488 };
489
501 template <typename T>
502 static void LocalScope(Config const& config, T&& lambda)
503 {
505 SMPToolsAPI.LocalScope<vtkSMPTools::Config>(config, lambda);
506 }
507
523 template <typename InputIt, typename OutputIt, typename Functor>
524 static void Transform(InputIt inBegin, InputIt inEnd, OutputIt outBegin, Functor transform)
525 {
527 SMPToolsAPI.Transform(inBegin, inEnd, outBegin, transform);
528 }
529
546 template <typename InputIt1, typename InputIt2, typename OutputIt, typename Functor>
547 static void Transform(
548 InputIt1 inBegin1, InputIt1 inEnd, InputIt2 inBegin2, OutputIt outBegin, Functor transform)
549 {
551 SMPToolsAPI.Transform(inBegin1, inEnd, inBegin2, outBegin, transform);
552 }
553
568 template <typename Iterator, typename T>
569 static void Fill(Iterator begin, Iterator end, const T& value)
570 {
572 SMPToolsAPI.Fill(begin, end, value);
573 }
574
580 template <typename RandomAccessIterator>
581 static void Sort(RandomAccessIterator begin, RandomAccessIterator end)
582 {
584 SMPToolsAPI.Sort(begin, end);
585 }
586
593 template <typename RandomAccessIterator, typename Compare>
594 static void Sort(RandomAccessIterator begin, RandomAccessIterator end, Compare comp)
595 {
597 SMPToolsAPI.Sort(begin, end, comp);
598 }
599};
600
601#endif
602// 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:230
static void Transform(InputIt1 inBegin1, InputIt1 inEnd, InputIt2 inBegin2, OutputIt outBegin, Functor transform)
A convenience method for transforming data.
Definition: vtkSMPTools.h:547
static vtk::detail::smp::resolvedNotInt< Iter > For(Iter begin, Iter end, Functor const &f)
Execute a for operation in parallel.
Definition: vtkSMPTools.h:376
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:524
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:370
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:317
static void Sort(RandomAccessIterator begin, RandomAccessIterator end)
A convenience method for sorting data.
Definition: vtkSMPTools.h:581
static void Fill(Iterator begin, Iterator end, const T &value)
A convenience method for filling data.
Definition: vtkSMPTools.h:569
static void For(vtkIdType first, vtkIdType last, Functor const &f)
Execute a for operation in parallel.
Definition: vtkSMPTools.h:274
static void For(vtkIdType first, vtkIdType last, Functor &f)
Execute a for operation in parallel.
Definition: vtkSMPTools.h:268
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:326
static void For(vtkIdType first, vtkIdType last, vtkIdType grain, Functor const &f)
Execute a for operation in parallel.
Definition: vtkSMPTools.h:250
static void Sort(RandomAccessIterator begin, RandomAccessIterator end, Compare comp)
A convenience method for sorting data.
Definition: vtkSMPTools.h:594
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:502
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:243
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:456
Config(std::string backend)
Definition: vtkSMPTools.h:466
Config(int maxNumberOfThreads)
Definition: vtkSMPTools.h:462
Config(bool nestedParallelism)
Definition: vtkSMPTools.h:470
Config(int maxNumberOfThreads, std::string backend, bool nestedParallelism)
Definition: vtkSMPTools.h:474
int vtkIdType
Definition: vtkType.h:332