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__
45 namespace vtk
46 {
47 namespace detail
48 {
49 namespace smp
50 {
51 template <typename T>
52 class 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 
65 public:
66  static bool const value = sizeof(check<T>(nullptr)) == sizeof(yes_type);
67 };
68 
69 template <typename T>
70 class 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 
83 public:
84  static bool const value = sizeof(check<T>(0)) == sizeof(yes_type);
85 };
86 
87 template <typename Functor, bool Init>
88 struct vtkSMPTools_FunctorInternal;
89 
90 template <typename Functor>
91 struct 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 
109 template <typename Functor>
110 struct 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 
140 template <typename Functor>
141 class vtkSMPTools_Lookup_For
142 {
143  static bool const init = vtkSMPTools_Has_Initialize<Functor>::value;
144 
145 public:
146  typedef vtkSMPTools_FunctorInternal<Functor, init> type;
147 };
148 
149 template <typename Functor>
150 class vtkSMPTools_Lookup_For<Functor const>
151 {
152  static bool const init = vtkSMPTools_Has_Initialize_const<Functor>::value;
153 
154 public:
155  typedef vtkSMPTools_FunctorInternal<Functor const, init> type;
156 };
157 
158 template <typename Iterator, typename Functor, bool Init>
159 struct vtkSMPTools_RangeFunctor;
160 
161 template <typename Iterator, typename Functor>
162 struct 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 
181 template <typename Iterator, typename Functor>
182 struct 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 
203 template <typename Iterator, typename Functor>
204 class vtkSMPTools_Lookup_RangeFor
205 {
206  static bool const init = vtkSMPTools_Has_Initialize<Functor>::value;
207 
208 public:
209  typedef vtkSMPTools_RangeFunctor<Iterator, Functor, init> type;
210 };
211 
212 template <typename Iterator, typename Functor>
213 class vtkSMPTools_Lookup_RangeFor<Iterator, Functor const>
214 {
215  static bool const init = vtkSMPTools_Has_Initialize_const<Functor>::value;
216 
217 public:
218  typedef vtkSMPTools_RangeFunctor<Iterator, Functor const, init> type;
219 };
220 
221 template <typename T>
222 using 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 
229 class VTKCOMMONCORE_EXPORT vtkSMPTools
230 {
231 public:
233 
242  template <typename Functor>
243  static void For(vtkIdType first, vtkIdType last, vtkIdType grain, Functor& f)
244  {
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  {
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);
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);
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 
461  Config() {}
462  Config(int maxNumberOfThreads)
463  : MaxNumberOfThreads(maxNumberOfThreads)
464  {
465  }
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  {
504  auto& SMPToolsAPI = vtk::detail::smp::vtkSMPToolsAPI::GetInstance();
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  {
526  auto& SMPToolsAPI = vtk::detail::smp::vtkSMPToolsAPI::GetInstance();
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  {
550  auto& SMPToolsAPI = vtk::detail::smp::vtkSMPToolsAPI::GetInstance();
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  {
571  auto& SMPToolsAPI = vtk::detail::smp::vtkSMPToolsAPI::GetInstance();
572  SMPToolsAPI.Fill(begin, end, value);
573  }
574 
580  template <typename RandomAccessIterator>
581  static void Sort(RandomAccessIterator begin, RandomAccessIterator end)
582  {
583  auto& SMPToolsAPI = vtk::detail::smp::vtkSMPToolsAPI::GetInstance();
584  SMPToolsAPI.Sort(begin, end);
585  }
586 
593  template <typename RandomAccessIterator, typename Compare>
594  static void Sort(RandomAccessIterator begin, RandomAccessIterator end, Compare comp)
595  {
596  auto& SMPToolsAPI = vtk::detail::smp::vtkSMPToolsAPI::GetInstance();
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 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 Transform(InputIt1 inBegin1, InputIt1 inEnd, InputIt2 inBegin2, OutputIt outBegin, Functor transform)
A convenience method for transforming data.
Definition: vtkSMPTools.h:547
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 const &f)
Execute a for operation in parallel.
Definition: vtkSMPTools.h:376
static void SetNestedParallelism(bool isNested)
/!\ This method is not thread safe.
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, Functor &f)
Execute a for operation in parallel.
Definition: vtkSMPTools.h:370
static void For(vtkIdType first, vtkIdType last, vtkIdType grain, Functor const &f)
Execute a for operation in parallel.
Definition: vtkSMPTools.h:250
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 const char * GetBackend()
Get the backend in use.
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 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
@ size
Definition: vtkX3D.h:259
@ string
Definition: vtkX3D.h:496
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