VTK  9.4.20241222
vtkSMPTools.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
2// SPDX-License-Identifier: BSD-3-Clause
24#ifndef vtkSMPTools_h
25#define vtkSMPTools_h
26
27#include "vtkCommonCoreModule.h" // For export macro
28#include "vtkObject.h"
29
31#include "vtkSMPThreadLocal.h" // For Initialized
32
33#include <functional> // For std::function
34#include <type_traits> // For std:::enable_if
35
36#ifndef DOXYGEN_SHOULD_SKIP_THIS
37namespace vtk
38{
39namespace detail
40{
41namespace smp
42{
43VTK_ABI_NAMESPACE_BEGIN
44template <typename T>
45class vtkSMPTools_Has_Initialize
46{
47 typedef char (&no_type)[1];
48 typedef char (&yes_type)[2];
49 template <typename U, void (U::*)()>
50 struct V
51 {
52 };
53 template <typename U>
54 static yes_type check(V<U, &U::Initialize>*);
55 template <typename U>
56 static no_type check(...);
57
58public:
59 static bool const value = sizeof(check<T>(nullptr)) == sizeof(yes_type);
60};
61
62template <typename T>
63class vtkSMPTools_Has_Initialize_const
64{
65 typedef char (&no_type)[1];
66 typedef char (&yes_type)[2];
67 template <typename U, void (U::*)() const>
68 struct V
69 {
70 };
71 template <typename U>
72 static yes_type check(V<U, &U::Initialize>*);
73 template <typename U>
74 static no_type check(...);
75
76public:
77 static bool const value = sizeof(check<T>(0)) == sizeof(yes_type);
78};
79
80template <typename Functor, bool Init>
81struct vtkSMPTools_FunctorInternal;
82
83template <typename Functor>
84struct vtkSMPTools_FunctorInternal<Functor, false>
85{
86 Functor& F;
87 vtkSMPTools_FunctorInternal(Functor& f)
88 : F(f)
89 {
90 }
91 void Execute(vtkIdType first, vtkIdType last) { this->F(first, last); }
92 void For(vtkIdType first, vtkIdType last, vtkIdType grain)
93 {
94 auto& SMPToolsAPI = vtkSMPToolsAPI::GetInstance();
95 SMPToolsAPI.For(first, last, grain, *this);
96 }
97 vtkSMPTools_FunctorInternal<Functor, false>& operator=(
98 const vtkSMPTools_FunctorInternal<Functor, false>&);
99 vtkSMPTools_FunctorInternal(const vtkSMPTools_FunctorInternal<Functor, false>&);
100};
101
102template <typename Functor>
103struct vtkSMPTools_FunctorInternal<Functor, true>
104{
105 Functor& F;
107 vtkSMPTools_FunctorInternal(Functor& f)
108 : F(f)
109 , Initialized(0)
110 {
111 }
112 void Execute(vtkIdType first, vtkIdType last)
113 {
114 unsigned char& inited = this->Initialized.Local();
115 if (!inited)
116 {
117 this->F.Initialize();
118 inited = 1;
119 }
120 this->F(first, last);
121 }
122 void For(vtkIdType first, vtkIdType last, vtkIdType grain)
123 {
124 auto& SMPToolsAPI = vtkSMPToolsAPI::GetInstance();
125 SMPToolsAPI.For(first, last, grain, *this);
126 this->F.Reduce();
127 }
128 vtkSMPTools_FunctorInternal<Functor, true>& operator=(
129 const vtkSMPTools_FunctorInternal<Functor, true>&);
130 vtkSMPTools_FunctorInternal(const vtkSMPTools_FunctorInternal<Functor, true>&);
131};
132
133template <typename Functor>
134class vtkSMPTools_Lookup_For
135{
136 static bool const init = vtkSMPTools_Has_Initialize<Functor>::value;
137
138public:
139 typedef vtkSMPTools_FunctorInternal<Functor, init> type;
140};
141
142template <typename Functor>
143class vtkSMPTools_Lookup_For<Functor const>
144{
145 static bool const init = vtkSMPTools_Has_Initialize_const<Functor>::value;
146
147public:
148 typedef vtkSMPTools_FunctorInternal<Functor const, init> type;
149};
150
151template <typename Iterator, typename Functor, bool Init>
152struct vtkSMPTools_RangeFunctor;
153
154template <typename Iterator, typename Functor>
155struct vtkSMPTools_RangeFunctor<Iterator, Functor, false>
156{
157 Functor& F;
158 Iterator& Begin;
159 vtkSMPTools_RangeFunctor(Iterator& begin, Functor& f)
160 : F(f)
161 , Begin(begin)
162 {
163 }
164 void operator()(vtkIdType first, vtkIdType last)
165 {
166 Iterator itFirst(Begin);
167 std::advance(itFirst, first);
168 Iterator itLast(itFirst);
169 std::advance(itLast, last - first);
170 this->F(itFirst, itLast);
171 }
172};
173
174template <typename Iterator, typename Functor>
175struct vtkSMPTools_RangeFunctor<Iterator, Functor, true>
176{
177 Functor& F;
178 Iterator& Begin;
179 vtkSMPTools_RangeFunctor(Iterator& begin, Functor& f)
180 : F(f)
181 , Begin(begin)
182 {
183 }
184 void Initialize() { this->F.Initialize(); }
185 void operator()(vtkIdType first, vtkIdType last)
186 {
187 Iterator itFirst(Begin);
188 std::advance(itFirst, first);
189 Iterator itLast(itFirst);
190 std::advance(itLast, last - first);
191 this->F(itFirst, itLast);
192 }
193 void Reduce() { this->F.Reduce(); }
194};
195
196template <typename Iterator, typename Functor>
197class vtkSMPTools_Lookup_RangeFor
198{
199 static bool const init = vtkSMPTools_Has_Initialize<Functor>::value;
200
201public:
202 typedef vtkSMPTools_RangeFunctor<Iterator, Functor, init> type;
203};
204
205template <typename Iterator, typename Functor>
206class vtkSMPTools_Lookup_RangeFor<Iterator, Functor const>
207{
208 static bool const init = vtkSMPTools_Has_Initialize_const<Functor>::value;
209
210public:
211 typedef vtkSMPTools_RangeFunctor<Iterator, Functor const, init> type;
212};
213
214template <typename T>
215using resolvedNotInt = typename std::enable_if<!std::is_integral<T>::value, void>::type;
216VTK_ABI_NAMESPACE_END
217} // namespace smp
218} // namespace detail
219} // namespace vtk
220#endif // DOXYGEN_SHOULD_SKIP_THIS
221
222VTK_ABI_NAMESPACE_BEGIN
223class VTKCOMMONCORE_EXPORT vtkSMPTools
224{
225public:
227
236 template <typename Functor>
237 static void For(vtkIdType first, vtkIdType last, vtkIdType grain, Functor& f)
238 {
239 typename vtk::detail::smp::vtkSMPTools_Lookup_For<Functor>::type fi(f);
240 fi.For(first, last, grain);
241 }
242
243 template <typename Functor>
244 static void For(vtkIdType first, vtkIdType last, vtkIdType grain, Functor const& f)
245 {
246 typename vtk::detail::smp::vtkSMPTools_Lookup_For<Functor const>::type fi(f);
247 fi.For(first, last, grain);
248 }
250
252
261 template <typename Functor>
262 static void For(vtkIdType first, vtkIdType last, Functor& f)
263 {
264 vtkSMPTools::For(first, last, 0, f);
265 }
266
267 template <typename Functor>
268 static void For(vtkIdType first, vtkIdType last, Functor const& f)
269 {
270 vtkSMPTools::For(first, last, 0, f);
271 }
273
275
310 template <typename Iter, typename Functor>
311 static vtk::detail::smp::resolvedNotInt<Iter> For(
312 Iter begin, Iter end, vtkIdType grain, Functor& f)
313 {
314 vtkIdType size = std::distance(begin, end);
315 typename vtk::detail::smp::vtkSMPTools_Lookup_RangeFor<Iter, Functor>::type fi(begin, f);
316 vtkSMPTools::For(0, size, grain, fi);
317 }
318
319 template <typename Iter, typename Functor>
320 static vtk::detail::smp::resolvedNotInt<Iter> For(
321 Iter begin, Iter end, vtkIdType grain, Functor const& f)
322 {
323 vtkIdType size = std::distance(begin, end);
324 typename vtk::detail::smp::vtkSMPTools_Lookup_RangeFor<Iter, Functor const>::type fi(begin, f);
325 vtkSMPTools::For(0, size, grain, fi);
326 }
328
330
363 template <typename Iter, typename Functor>
364 static vtk::detail::smp::resolvedNotInt<Iter> For(Iter begin, Iter end, Functor& f)
365 {
366 vtkSMPTools::For(begin, end, 0, f);
367 }
368
369 template <typename Iter, typename Functor>
370 static vtk::detail::smp::resolvedNotInt<Iter> For(Iter begin, Iter end, Functor const& f)
371 {
372 vtkSMPTools::For(begin, end, 0, f);
373 }
375
379 static const char* GetBackend();
380
392 static bool SetBackend(const char* backend);
393
409 static void Initialize(int numThreads = 0);
410
418
426
438 static void SetNestedParallelism(bool isNested);
439
444 static bool GetNestedParallelism();
445
449 static bool IsParallelScope();
450
455 static bool GetSingleThread();
456
464 struct Config
465 {
466 int MaxNumberOfThreads = 0;
468 bool NestedParallelism = false;
469
470 Config() = default;
471 Config(int maxNumberOfThreads)
472 : MaxNumberOfThreads(maxNumberOfThreads)
473 {
474 }
475 Config(std::string backend)
476 : Backend(backend)
477 {
478 }
479 Config(bool nestedParallelism)
480 : NestedParallelism(nestedParallelism)
481 {
482 }
483 Config(int maxNumberOfThreads, std::string backend, bool nestedParallelism)
484 : MaxNumberOfThreads(maxNumberOfThreads)
485 , Backend(backend)
486 , NestedParallelism(nestedParallelism)
487 {
488 }
489#ifndef DOXYGEN_SHOULD_SKIP_THIS
491 : MaxNumberOfThreads(API.GetInternalDesiredNumberOfThread())
492 , Backend(API.GetBackend())
493 , NestedParallelism(API.GetNestedParallelism())
494 {
495 }
496#endif // DOXYGEN_SHOULD_SKIP_THIS
497 };
521 static constexpr vtkIdType THRESHOLD = 100000;
522
534 template <typename T>
535 static void LocalScope(Config const& config, T&& lambda)
536 {
538 SMPToolsAPI.LocalScope<vtkSMPTools::Config>(config, lambda);
539 }
540
556 template <typename InputIt, typename OutputIt, typename Functor>
557 static void Transform(InputIt inBegin, InputIt inEnd, OutputIt outBegin, Functor transform)
558 {
560 SMPToolsAPI.Transform(inBegin, inEnd, outBegin, transform);
561 }
562
579 template <typename InputIt1, typename InputIt2, typename OutputIt, typename Functor>
580 static void Transform(
581 InputIt1 inBegin1, InputIt1 inEnd, InputIt2 inBegin2, OutputIt outBegin, Functor transform)
582 {
584 SMPToolsAPI.Transform(inBegin1, inEnd, inBegin2, outBegin, transform);
585 }
586
601 template <typename Iterator, typename T>
602 static void Fill(Iterator begin, Iterator end, const T& value)
603 {
605 SMPToolsAPI.Fill(begin, end, value);
606 }
607
613 template <typename RandomAccessIterator>
614 static void Sort(RandomAccessIterator begin, RandomAccessIterator end)
615 {
617 SMPToolsAPI.Sort(begin, end);
618 }
619
626 template <typename RandomAccessIterator, typename Compare>
627 static void Sort(RandomAccessIterator begin, RandomAccessIterator end, Compare comp)
628 {
630 SMPToolsAPI.Sort(begin, end, comp);
631 }
632};
633
634VTK_ABI_NAMESPACE_END
635#endif
636// 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.
static void Transform(InputIt1 inBegin1, InputIt1 inEnd, InputIt2 inBegin2, OutputIt outBegin, Functor transform)
A convenience method for transforming data.
static bool GetSingleThread()
Returns true if the given thread is specified thread for single scope.
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)
/!\ 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.
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)
/!\ 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.
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)
/!\ This method is not thread safe.
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 int GetEstimatedDefaultNumberOfThreads()
Get the estimated number of threads being used by the backend by default.
static vtkSMPToolsAPI & GetInstance()
@ value
Definition vtkX3D.h:220
@ type
Definition vtkX3D.h:516
Specialization of tuple ranges and iterators for vtkAOSDataArrayTemplate.
Structure used to specify configuration for LocalScope() method.
Config(std::string backend)
Config(int maxNumberOfThreads)
Config(bool nestedParallelism)
Config(int maxNumberOfThreads, std::string backend, bool nestedParallelism)
int vtkIdType
Definition vtkType.h:315