ITK  5.4.0
Insight Toolkit
itkMultiThreaderBase.h
Go to the documentation of this file.
1 /*=========================================================================
2  *
3  * Copyright NumFOCUS
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * https://www.apache.org/licenses/LICENSE-2.0.txt
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *=========================================================================*/
18 /*=========================================================================
19  *
20  * Portions of this file are subject to the VTK Toolkit Version 3 copyright.
21  *
22  * Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
23  *
24  * For complete copyright, license and disclaimer of warranty information
25  * please refer to the NOTICE file at the top of the ITK source tree.
26  *
27  *=========================================================================*/
28 #ifndef itkMultiThreaderBase_h
29 #define itkMultiThreaderBase_h
30 
31 #include "itkObject.h"
32 #include "itkThreadSupport.h"
33 #include "itkObjectFactory.h"
34 #include "itkIntTypes.h"
35 #include "itkImageRegion.h"
36 #include "itkImageIORegion.h"
37 #include "itkSingletonMacro.h"
38 #include <atomic>
39 #include <functional>
40 #include <thread>
41 #include "itkProgressReporter.h"
42 
43 
44 namespace itk
45 {
46 
54 {
55 public:
61  enum class Threader : int8_t
62  {
63  Platform = 0,
64  First = Platform,
65  Pool,
66  TBB,
67  Last = TBB,
68  Unknown = -1
69  };
70 
74  enum class ThreadExitCode : uint8_t
75  {
76  SUCCESS,
80  UNKNOWN
81  };
82 };
83 // Define how to print enumeration
84 extern ITKCommon_EXPORT std::ostream &
85  operator<<(std::ostream & out, const MultiThreaderBaseEnums::Threader value);
86 extern ITKCommon_EXPORT std::ostream &
87  operator<<(std::ostream & out, const MultiThreaderBaseEnums::ThreadExitCode value);
88 
103 struct MultiThreaderBaseGlobals;
104 class ProcessObject;
105 
106 class ITKCommon_EXPORT MultiThreaderBase : public Object
107 {
108 public:
109  ITK_DISALLOW_COPY_AND_MOVE(MultiThreaderBase);
110 
116 
118  static Pointer
119  New();
120 
122  itkOverrideGetNameOfClassMacro(MultiThreaderBase);
123 
127  virtual void
128  SetMaximumNumberOfThreads(ThreadIdType numberOfThreads);
129  itkGetConstMacro(MaximumNumberOfThreads, ThreadIdType);
135  virtual void
136  SetNumberOfWorkUnits(ThreadIdType numberOfWorkUnits);
137  itkGetConstMacro(NumberOfWorkUnits, ThreadIdType);
140  virtual void
141  SetUpdateProgress(bool updates);
142  itkGetConstMacro(UpdateProgress, bool);
143 
149  static void
150  SetGlobalMaximumNumberOfThreads(ThreadIdType val);
151  static ThreadIdType
152  GetGlobalMaximumNumberOfThreads();
160  itkLegacyMacro(static void SetGlobalDefaultUseThreadPool(const bool GlobalDefaultUseThreadPool));
161  itkLegacyMacro(static bool GetGlobalDefaultUseThreadPool());
165 #if !defined(ITK_LEGACY_REMOVE)
166  using ThreaderType = ThreaderEnum;
167  static constexpr ThreaderEnum Platform = ThreaderEnum::Platform;
168  static constexpr ThreaderEnum First = ThreaderEnum::First;
169  static constexpr ThreaderEnum Pool = ThreaderEnum::Pool;
170  static constexpr ThreaderEnum TBB = ThreaderEnum::TBB;
171  static constexpr ThreaderEnum Last = ThreaderEnum::Last;
172  static constexpr ThreaderEnum Unknown = ThreaderEnum::Unknown;
173 #endif
174 
176  static ThreaderEnum
177  ThreaderTypeFromString(std::string threaderString);
178 
180  static std::string
182  {
183  switch (threader)
184  {
185  case ThreaderEnum::Platform:
186  return "Platform";
187  case ThreaderEnum::Pool:
188  return "Pool";
189  case ThreaderEnum::TBB:
190  return "TBB";
191  case ThreaderEnum::Unknown:
192  default:
193  return "Unknown";
194  }
195  }
209  static void
210  SetGlobalDefaultThreader(ThreaderEnum threaderType);
211  static ThreaderEnum
212  GetGlobalDefaultThreader();
219  static void
220  SetGlobalDefaultNumberOfThreads(ThreadIdType val);
221  static ThreadIdType
222  GetGlobalDefaultNumberOfThreads();
225 #if !defined(ITK_LEGACY_REMOVE)
226 
228  itkLegacyMacro(virtual void SetNumberOfThreads(ThreadIdType numberOfThreads))
229  {
230  this->SetMaximumNumberOfThreads(numberOfThreads);
231  this->SetNumberOfWorkUnits(this->GetMaximumNumberOfThreads()); // Might be clamped
232  }
233  itkLegacyMacro(virtual ThreadIdType GetNumberOfThreads()) { return this->GetNumberOfWorkUnits(); }
244  // clang-format off
245 ITK_GCC_PRAGMA_DIAG_PUSH()
246 ITK_GCC_PRAGMA_DIAG(ignored "-Wattributes")
247 INTEL_PRAGMA_WARN_PUSH
248 INTEL_SUPPRESS_warning_1292
249 CLANG_PRAGMA_PUSH
250 CLANG_SUPPRESS_Wcpp14_extensions
251  // clang-format on
252 # ifdef ITK_LEGACY_SILENT
253  struct ThreadInfoStruct
254 # else
255  struct [[deprecated("Use WorkUnitInfo, ThreadInfoStruct is deprecated since ITK 5.0")]] ThreadInfoStruct
256 # endif
257  // clang-format off
258 CLANG_PRAGMA_POP
259 INTEL_PRAGMA_WARN_POP
260  // clang-format on
261  {
262  ThreadIdType ThreadID;
263  ThreadIdType NumberOfThreads;
264  void * UserData;
265  ThreadFunctionType ThreadFunction;
266  enum
267  {
268  SUCCESS,
269  ITK_EXCEPTION,
270  ITK_PROCESS_ABORTED_EXCEPTION,
271  STD_EXCEPTION,
272  UNKNOWN
273  } ThreadExitCode;
274  };
275  // clang-format off
276 ITK_GCC_PRAGMA_DIAG_POP()
277  // clang-format on
278 #endif // ITK_LEGACY_REMOVE
279 
288  {
291  void * UserData;
295 #if !defined(ITK_LEGACY_REMOVE)
296  using ThreadExitCodeType = ThreadExitCodeEnum;
297  static constexpr ThreadExitCodeEnum SUCCESS = ThreadExitCodeEnum::SUCCESS;
298  static constexpr ThreadExitCodeEnum ITK_EXCEPTION = ThreadExitCodeEnum::ITK_EXCEPTION;
299  static constexpr ThreadExitCodeEnum ITK_PROCESS_ABORTED_EXCEPTION =
300  ThreadExitCodeEnum::ITK_PROCESS_ABORTED_EXCEPTION;
301  static constexpr ThreadExitCodeEnum STD_EXCEPTION = ThreadExitCodeEnum::STD_EXCEPTION;
302  static constexpr ThreadExitCodeEnum UNKNOWN = ThreadExitCodeEnum::UNKNOWN;
303 #endif
304  };
311  virtual void
312  SingleMethodExecute() = 0;
313 
318  virtual void
319  SetSingleMethod(ThreadFunctionType, void * data) = 0;
320 
322  void
323  SetSingleMethodAndExecute(ThreadFunctionType func, void * data);
324 
325 #ifndef ITK_FUTURE_LEGACY_REMOVE
326  // `TemplatedThreadingFunctorType` was previously used to declare the `funcP` parameter of `ParallelizeImageRegion`
327  // and `ParallelizeImageRegionRestrictDirection` template member functions.
328  template <unsigned int VDimension>
329  using TemplatedThreadingFunctorType [[deprecated]] = std::function<void(const ImageRegion<VDimension> &)>;
330 #endif
331 
332  using ThreadingFunctorType = std::function<void(const IndexValueType index[], const SizeValueType size[])>;
333  using ArrayThreadingFunctorType = std::function<void(SizeValueType)>;
334 
340  virtual void
341  ParallelizeArray(SizeValueType firstIndex,
342  SizeValueType lastIndexPlus1,
344  ProcessObject * filter);
345 
351  template <unsigned int VDimension, typename TFunction>
352  ITK_TEMPLATE_EXPORT void
353  ParallelizeImageRegion(const ImageRegion<VDimension> & requestedRegion, TFunction funcP, ProcessObject * filter)
354  {
355  this->ParallelizeImageRegion(
356  VDimension,
357  requestedRegion.GetIndex().m_InternalArray,
358  requestedRegion.GetSize().m_InternalArray,
359  [&funcP](const IndexValueType index[], const SizeValueType size[]) {
361  for (unsigned int d = 0; d < VDimension; ++d)
362  {
363  region.SetIndex(d, index[d]);
364  region.SetSize(d, size[d]);
365  }
366  funcP(region);
367  },
368  filter);
369  }
375  template <unsigned int VDimension, typename TFunction>
376  ITK_TEMPLATE_EXPORT void
377  ParallelizeImageRegionRestrictDirection(unsigned int restrictedDirection,
378  const ImageRegion<VDimension> & requestedRegion,
379  TFunction funcP,
380  ProcessObject * filter)
381  {
382  if constexpr (VDimension <= 1) // Cannot split, no parallelization
383  {
384 
385  ProgressReporter progress(filter, 0, requestedRegion.GetNumberOfPixels());
386  funcP(requestedRegion);
387  }
388  else // Can split, parallelize!
389  {
390  constexpr unsigned int SplitDimension = VDimension - 1;
391 
392  Index<SplitDimension> splitIndex{};
393  Size<SplitDimension> splitSize{};
394  for (unsigned int splitDimension = 0, dimension = 0; dimension < VDimension; ++dimension)
395  {
396  if (dimension != restrictedDirection)
397  {
398  splitIndex[splitDimension] = requestedRegion.GetIndex(dimension);
399  splitSize[splitDimension] = requestedRegion.GetSize(dimension);
400  ++splitDimension;
401  }
402  }
403 
404  this->ParallelizeImageRegion(
405  SplitDimension,
406  splitIndex.m_InternalArray,
407  splitSize.m_InternalArray,
408  [restrictedDirection, &requestedRegion, &funcP](const IndexValueType index[], const SizeValueType size[]) {
409  ImageRegion<VDimension> restrictedRequestedRegion;
410  restrictedRequestedRegion.SetIndex(restrictedDirection, requestedRegion.GetIndex(restrictedDirection));
411  restrictedRequestedRegion.SetSize(restrictedDirection, requestedRegion.GetSize(restrictedDirection));
412  for (unsigned int splitDimension = 0, dimension = 0; dimension < VDimension; ++dimension)
413  {
414  if (dimension != restrictedDirection)
415  {
416  restrictedRequestedRegion.SetIndex(dimension, index[splitDimension]);
417  restrictedRequestedRegion.SetSize(dimension, size[splitDimension]);
418  ++splitDimension;
419  }
420  }
421  funcP(restrictedRequestedRegion);
422  },
423  filter);
424  }
425  }
426 
429  virtual void
430  ParallelizeImageRegion(unsigned int dimension,
431  const IndexValueType index[],
432  const SizeValueType size[],
433  ThreadingFunctorType funcP,
434  ProcessObject * filter);
435 
436 protected:
437  MultiThreaderBase();
438  ~MultiThreaderBase() override;
439  void
440  PrintSelf(std::ostream & os, Indent indent) const override;
441 
443  {
448  };
449 
451  ParallelizeArrayHelper(void * arg);
452 
454  {
456  unsigned int dimension;
460  };
461 
463  ParallelizeImageRegionHelper(void * arg);
464 
466  ThreadIdType m_NumberOfWorkUnits{};
467 
476  ThreadIdType m_MaximumNumberOfThreads{};
477 
485  SingleMethodProxy(void * arg);
486 
488  ThreadFunctionType m_SingleMethod{ nullptr };
489 
491  void * m_SingleData{ nullptr };
492 
493 private:
494  static void
495  SetGlobalDefaultThreaderPrivate(ThreaderEnum threaderType);
496  static ThreaderEnum
497  GetGlobalDefaultThreaderPrivate();
498 
500  itkGetGlobalDeclarationMacro(MultiThreaderBaseGlobals, PimplGlobals);
501 
502  std::atomic<bool> m_UpdateProgress{ true };
503 
504  static MultiThreaderBaseGlobals * m_PimplGlobals;
508  friend class ProcessObject;
509 
511  static ThreadIdType
512  GetGlobalDefaultNumberOfThreadsByPlatform();
513 };
514 
515 
516 } // namespace itk
517 
518 #endif
itk::MultiThreaderBase
A class for performing multithreaded execution.
Definition: itkMultiThreaderBase.h:106
itk::MultiThreaderBase::WorkUnitInfo::ThreadFunction
ThreadFunctionType ThreadFunction
Definition: itkMultiThreaderBase.h:292
itkObjectFactory.h
itk::Index
Represent a n-dimensional index in a n-dimensional image.
Definition: itkIndex.h:70
itk::MultiThreaderBase::RegionAndCallback::size
const SizeValueType * size
Definition: itkMultiThreaderBase.h:458
itk::MultiThreaderBase::WorkUnitInfo
Definition: itkMultiThreaderBase.h:287
itk::MultiThreaderBaseEnums::Threader::Last
itk::Size
Represent a n-dimensional size (bounds) of a n-dimensional image.
Definition: itkSize.h:71
itk::operator<<
std::ostream & operator<<(std::ostream &os, const Array< TValue > &arr)
Definition: itkArray.h:216
itk::MultiThreaderBaseEnums::ThreadExitCode
ThreadExitCode
Definition: itkMultiThreaderBase.h:74
itk::MultiThreaderBase::ArrayCallback::firstIndex
const SizeValueType firstIndex
Definition: itkMultiThreaderBase.h:445
itk::ImageRegion::GetIndex
const IndexType & GetIndex() const
Definition: itkImageRegion.h:188
itk::ImageRegion< VDimension >
itkProgressReporter.h
itk::MultiThreaderBase::ParallelizeImageRegionRestrictDirection
ITK_TEMPLATE_EXPORT void ParallelizeImageRegionRestrictDirection(unsigned int restrictedDirection, const ImageRegion< VDimension > &requestedRegion, TFunction funcP, ProcessObject *filter)
Definition: itkMultiThreaderBase.h:377
itk::MultiThreaderBase::ArrayCallback
Definition: itkMultiThreaderBase.h:442
Threader
itkSingletonMacro.h
itk::ImageRegion::GetSize
const SizeType & GetSize() const
Definition: itkImageRegion.h:209
itk::SmartPointer< Self >
itk::ThreadFunctionType
void(*)(void *) ThreadFunctionType
Definition: itkThreadSupport.h:82
itkImageRegion.h
itk::IndexValueType
long IndexValueType
Definition: itkIntTypes.h:90
itk::MultiThreaderBaseEnums::Threader::Pool
itk::MultiThreaderBase::WorkUnitInfo::ThreadExitCode
ThreadExitCodeEnum ThreadExitCode
Definition: itkMultiThreaderBase.h:294
itk::ThreadIdType
unsigned int ThreadIdType
Definition: itkIntTypes.h:99
itk::MultiThreaderBaseEnums::Threader::First
itk::ITK_THREAD_RETURN_FUNCTION_CALL_CONVENTION
itk::ITK_THREAD_RETURN_TYPE ITK_THREAD_RETURN_FUNCTION_CALL_CONVENTION
Definition: itkThreadSupport.h:89
itk::MultiThreaderBase::RegionAndCallback::index
const IndexValueType * index
Definition: itkMultiThreaderBase.h:457
itk::MultiThreaderBaseEnums::ThreadExitCode::UNKNOWN
itk::LightObject
Light weight base class for most itk classes.
Definition: itkLightObject.h:55
itk::MultiThreaderBase::ArrayCallback::lastIndexPlus1
const SizeValueType lastIndexPlus1
Definition: itkMultiThreaderBase.h:446
itkThreadSupport.h
itk::MultiThreaderBase::m_PimplGlobals
static MultiThreaderBaseGlobals * m_PimplGlobals
Definition: itkMultiThreaderBase.h:504
itk::MultiThreaderBase::RegionAndCallback::dimension
unsigned int dimension
Definition: itkMultiThreaderBase.h:456
itk::MultiThreaderBase::WorkUnitInfo::UserData
void * UserData
Definition: itkMultiThreaderBase.h:291
itk::MultiThreaderBaseEnums::Threader
Threader
Definition: itkMultiThreaderBase.h:61
itk::Index::m_InternalArray
IndexValueType m_InternalArray[VDimension]
Definition: itkIndex.h:293
itk::MultiThreaderBaseEnums
enums for MultiThreaderBase
Definition: itkMultiThreaderBase.h:53
itk::MultiThreaderBase::RegionAndCallback::functor
ThreadingFunctorType functor
Definition: itkMultiThreaderBase.h:455
itkIntTypes.h
itk::MultiThreaderBaseEnums::Threader::Unknown
itk::MultiThreaderBase::RegionAndCallback
Definition: itkMultiThreaderBase.h:453
itk::MultiThreaderBaseEnums::Threader::TBB
itkObject.h
itk::MultiThreaderBaseEnums::ThreadExitCode::ITK_PROCESS_ABORTED_EXCEPTION
itk::Size::m_InternalArray
SizeValueType m_InternalArray[VDimension]
Definition: itkSize.h:245
itk
The "itk" namespace contains all Insight Segmentation and Registration Toolkit (ITK) classes....
Definition: itkAnnulusOperator.h:24
itk::MultiThreaderBase::ArrayCallback::filter
ProcessObject * filter
Definition: itkMultiThreaderBase.h:447
itk::ProcessObject
The base class for all process objects (source, filters, mappers) in the Insight data processing pipe...
Definition: itkProcessObject.h:139
itk::ImageRegion::SetIndex
void SetIndex(const IndexType &index)
Definition: itkImageRegion.h:181
itk::MultiThreaderBaseEnums::ThreadExitCode::ITK_EXCEPTION
itk::ProcessObject
class ITK_FORWARD_EXPORT ProcessObject
Definition: itkDataObject.h:41
ThreadExitCode
itk::MultiThreaderBaseEnums::ThreadExitCode::STD_EXCEPTION
itkGetGlobalDeclarationMacro
#define itkGetGlobalDeclarationMacro(Type, VarName)
Definition: itkSingletonMacro.h:35
itkImageIORegion.h
itk::Object
Base class for most ITK classes.
Definition: itkObject.h:61
itk::MultiThreaderBase::ThreadingFunctorType
std::function< void(const IndexValueType index[], const SizeValueType size[])> ThreadingFunctorType
Definition: itkMultiThreaderBase.h:332
New
static Pointer New()
itk::ImageRegion::SetSize
void SetSize(const SizeType &size)
Definition: itkImageRegion.h:202
itk::ImageRegion::GetNumberOfPixels
SizeValueType GetNumberOfPixels() const
itk::MultiThreaderBase::WorkUnitInfo::NumberOfWorkUnits
ThreadIdType NumberOfWorkUnits
Definition: itkMultiThreaderBase.h:290
itk::ProgressReporter
Implements progress tracking for a filter.
Definition: itkProgressReporter.h:60
itk::MultiThreaderBase::ArrayCallback::functor
ArrayThreadingFunctorType functor
Definition: itkMultiThreaderBase.h:444
itk::MultiThreaderBase::RegionAndCallback::filter
ProcessObject * filter
Definition: itkMultiThreaderBase.h:459
itk::MultiThreaderBase::ThreaderTypeToString
static std::string ThreaderTypeToString(ThreaderEnum threader)
Definition: itkMultiThreaderBase.h:181
itk::MultiThreaderBase::ParallelizeImageRegion
ITK_TEMPLATE_EXPORT void ParallelizeImageRegion(const ImageRegion< VDimension > &requestedRegion, TFunction funcP, ProcessObject *filter)
Definition: itkMultiThreaderBase.h:353
itk::MultiThreaderBaseEnums::Threader::Platform
itk::MultiThreaderBase::WorkUnitInfo::WorkUnitID
ThreadIdType WorkUnitID
Definition: itkMultiThreaderBase.h:289
itk::MultiThreaderBaseEnums::ThreadExitCode::SUCCESS
itk::SizeValueType
unsigned long SizeValueType
Definition: itkIntTypes.h:83
itk::MultiThreaderBase::ArrayThreadingFunctorType
std::function< void(SizeValueType)> ArrayThreadingFunctorType
Definition: itkMultiThreaderBase.h:333