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
50 namespace vtk
51 {
52 namespace detail
53 {
54 namespace smp
55 {
56 template <typename T>
57 class 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 
70 public:
71  static bool const value = sizeof(check<T>(nullptr)) == sizeof(yes_type);
72 };
73 
74 template <typename T>
75 class 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 
88 public:
89  static bool const value = sizeof(check<T>(0)) == sizeof(yes_type);
90 };
91 
92 template <typename Functor, bool Init>
93 struct vtkSMPTools_FunctorInternal;
94 
95 template <typename Functor>
96 struct 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 
114 template <typename Functor>
115 struct 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 
145 template <typename Functor>
146 class vtkSMPTools_Lookup_For
147 {
148  static bool const init = vtkSMPTools_Has_Initialize<Functor>::value;
149 
150 public:
151  typedef vtkSMPTools_FunctorInternal<Functor, init> type;
152 };
153 
154 template <typename Functor>
155 class vtkSMPTools_Lookup_For<Functor const>
156 {
157  static bool const init = vtkSMPTools_Has_Initialize_const<Functor>::value;
158 
159 public:
160  typedef vtkSMPTools_FunctorInternal<Functor const, init> type;
161 };
162 
163 template <typename Iterator, typename Functor, bool Init>
164 struct vtkSMPTools_RangeFunctor;
165 
166 template <typename Iterator, typename Functor>
167 struct 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 
186 template <typename Iterator, typename Functor>
187 struct 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 
208 template <typename Iterator, typename Functor>
209 class vtkSMPTools_Lookup_RangeFor
210 {
211  static bool const init = vtkSMPTools_Has_Initialize<Functor>::value;
212 
213 public:
214  typedef vtkSMPTools_RangeFunctor<Iterator, Functor, init> type;
215 };
216 
217 template <typename Iterator, typename Functor>
218 class vtkSMPTools_Lookup_RangeFor<Iterator, Functor const>
219 {
220  static bool const init = vtkSMPTools_Has_Initialize_const<Functor>::value;
221 
222 public:
223  typedef vtkSMPTools_RangeFunctor<Iterator, Functor const, init> type;
224 };
225 
226 template <typename T>
227 using 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 
233 class VTKCOMMONCORE_EXPORT vtkSMPTools
234 {
235 public:
237 
246  template <typename Functor>
247  static void For(vtkIdType first, vtkIdType last, vtkIdType grain, Functor& f)
248  {
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  {
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);
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);
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 
427  static int GetEstimatedNumberOfThreads();
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 
465  Config() {}
466  Config(int maxNumberOfThreads)
467  : MaxNumberOfThreads(maxNumberOfThreads)
468  {
469  }
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  {
508  auto& SMPToolsAPI = vtk::detail::smp::vtkSMPToolsAPI::GetInstance();
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  {
530  auto& SMPToolsAPI = vtk::detail::smp::vtkSMPToolsAPI::GetInstance();
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  {
554  auto& SMPToolsAPI = vtk::detail::smp::vtkSMPToolsAPI::GetInstance();
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  {
575  auto& SMPToolsAPI = vtk::detail::smp::vtkSMPToolsAPI::GetInstance();
576  SMPToolsAPI.Fill(begin, end, value);
577  }
578 
584  template <typename RandomAccessIterator>
585  static void Sort(RandomAccessIterator begin, RandomAccessIterator end)
586  {
587  auto& SMPToolsAPI = vtk::detail::smp::vtkSMPToolsAPI::GetInstance();
588  SMPToolsAPI.Sort(begin, end);
589  }
590 
597  template <typename RandomAccessIterator, typename Compare>
598  static void Sort(RandomAccessIterator begin, RandomAccessIterator end, Compare comp)
599  {
600  auto& SMPToolsAPI = vtk::detail::smp::vtkSMPToolsAPI::GetInstance();
601  SMPToolsAPI.Sort(begin, end, comp);
602  }
603 };
604 
605 #endif
606 // VTK-HeaderTest-Exclude: vtkSMPTools.h
Structure used to specify configuration for LocalScope() method.
Definition: vtkSMPTools.h:459
T & Local()
This needs to be called mainly within a threaded execution path.
static vtkSMPToolsAPI & GetInstance()
static void For(vtkIdType first, vtkIdType last, Functor const &f)
Execute a for operation in parallel.
Definition: vtkSMPTools.h:278
Config(std::string backend)
Definition: vtkSMPTools.h:470
Specialization of tuple ranges and iterators for vtkAOSDataArrayTemplate.
int vtkIdType
Definition: vtkType.h:332
static void Fill(Iterator begin, Iterator end, const T &value)
A convenience method for filling data.
Definition: vtkSMPTools.h:573
static void Transform(InputIt1 inBegin1, InputIt1 inEnd, InputIt2 inBegin2, OutputIt outBegin, Functor transform)
A convenience method for transforming data.
Definition: vtkSMPTools.h:551
static void Transform(InputIt inBegin, InputIt inEnd, OutputIt outBegin, Functor transform)
A convenience method for transforming data.
Definition: vtkSMPTools.h:528
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 Sort(RandomAccessIterator begin, RandomAccessIterator end)
A convenience method for sorting data.
Definition: vtkSMPTools.h:585
static void For(vtkIdType first, vtkIdType last, Functor &f)
Execute a for operation in parallel.
Definition: vtkSMPTools.h:272
Thread local storage for VTK objects.
Config(bool nestedParallelism)
Definition: vtkSMPTools.h:474
static void LocalScope(Config const &config, T &&lambda)
/!\ This method is not thread safe.
Definition: vtkSMPTools.h:506
static void For(vtkIdType first, vtkIdType last, vtkIdType grain, Functor &f)
Execute a for operation in parallel.
Definition: vtkSMPTools.h:247
A set of parallel (multi-threaded) utility functions.
Definition: vtkSMPTools.h:233
static void Sort(RandomAccessIterator begin, RandomAccessIterator end, Compare comp)
A convenience method for sorting data.
Definition: vtkSMPTools.h:598
static void For(vtkIdType first, vtkIdType last, vtkIdType grain, Functor const &f)
Execute a for operation in parallel.
Definition: vtkSMPTools.h:254
Config(int maxNumberOfThreads)
Definition: vtkSMPTools.h:466
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 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 vtk::detail::smp::resolvedNotInt< Iter > For(Iter begin, Iter end, Functor const &f)
Execute a for operation in parallel.
Definition: vtkSMPTools.h:380
Config(int maxNumberOfThreads, std::string backend, bool nestedParallelism)
Definition: vtkSMPTools.h:478