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-format on
250 # ifdef ITK_LEGACY_SILENT
251  struct ThreadInfoStruct
252 # else
253  struct [[deprecated("Use WorkUnitInfo, ThreadInfoStruct is deprecated since ITK 5.0")]] ThreadInfoStruct
254 # endif
255  // clang-format off
256 INTEL_PRAGMA_WARN_POP
257  // clang-format on
258  {
259  ThreadIdType ThreadID;
260  ThreadIdType NumberOfThreads;
261  void * UserData;
262  ThreadFunctionType ThreadFunction;
263  enum
264  {
265  SUCCESS,
266  ITK_EXCEPTION,
267  ITK_PROCESS_ABORTED_EXCEPTION,
268  STD_EXCEPTION,
269  UNKNOWN
270  } ThreadExitCode;
271  };
272  // clang-format off
273 ITK_GCC_PRAGMA_DIAG_POP()
274  // clang-format on
275 #endif // ITK_LEGACY_REMOVE
276 
285  {
288  void * UserData;
292 #if !defined(ITK_LEGACY_REMOVE)
293  using ThreadExitCodeType = ThreadExitCodeEnum;
294  static constexpr ThreadExitCodeEnum SUCCESS = ThreadExitCodeEnum::SUCCESS;
295  static constexpr ThreadExitCodeEnum ITK_EXCEPTION = ThreadExitCodeEnum::ITK_EXCEPTION;
296  static constexpr ThreadExitCodeEnum ITK_PROCESS_ABORTED_EXCEPTION =
297  ThreadExitCodeEnum::ITK_PROCESS_ABORTED_EXCEPTION;
298  static constexpr ThreadExitCodeEnum STD_EXCEPTION = ThreadExitCodeEnum::STD_EXCEPTION;
299  static constexpr ThreadExitCodeEnum UNKNOWN = ThreadExitCodeEnum::UNKNOWN;
300 #endif
301  };
308  virtual void
309  SingleMethodExecute() = 0;
310 
315  virtual void
316  SetSingleMethod(ThreadFunctionType, void * data) = 0;
317 
319  void
320  SetSingleMethodAndExecute(ThreadFunctionType func, void * data);
321 
322 #ifndef ITK_FUTURE_LEGACY_REMOVE
323  // `TemplatedThreadingFunctorType` was previously used to declare the `funcP` parameter of `ParallelizeImageRegion`
324  // and `ParallelizeImageRegionRestrictDirection` template member functions.
325  template <unsigned int VDimension>
326  using TemplatedThreadingFunctorType [[deprecated]] = std::function<void(const ImageRegion<VDimension> &)>;
327 #endif
328 
329  using ThreadingFunctorType = std::function<void(const IndexValueType index[], const SizeValueType size[])>;
330  using ArrayThreadingFunctorType = std::function<void(SizeValueType)>;
331 
337  virtual void
338  ParallelizeArray(SizeValueType firstIndex,
339  SizeValueType lastIndexPlus1,
341  ProcessObject * filter);
342 
348  template <unsigned int VDimension, typename TFunction>
349  ITK_TEMPLATE_EXPORT void
350  ParallelizeImageRegion(const ImageRegion<VDimension> & requestedRegion, TFunction funcP, ProcessObject * filter)
351  {
352  this->ParallelizeImageRegion(
353  VDimension,
354  requestedRegion.GetIndex().m_InternalArray,
355  requestedRegion.GetSize().m_InternalArray,
356  [&funcP](const IndexValueType index[], const SizeValueType size[]) {
358  for (unsigned int d = 0; d < VDimension; ++d)
359  {
360  region.SetIndex(d, index[d]);
361  region.SetSize(d, size[d]);
362  }
363  funcP(region);
364  },
365  filter);
366  }
372  template <unsigned int VDimension, typename TFunction>
373  ITK_TEMPLATE_EXPORT void
374  ParallelizeImageRegionRestrictDirection(unsigned int restrictedDirection,
375  const ImageRegion<VDimension> & requestedRegion,
376  TFunction funcP,
377  ProcessObject * filter)
378  {
379  if constexpr (VDimension <= 1) // Cannot split, no parallelization
380  {
381 
382  ProgressReporter progress(filter, 0, requestedRegion.GetNumberOfPixels());
383  funcP(requestedRegion);
384  }
385  else // Can split, parallelize!
386  {
387  constexpr unsigned int SplitDimension = VDimension - 1;
388 
389  Index<SplitDimension> splitIndex{};
390  Size<SplitDimension> splitSize{};
391  for (unsigned int splitDimension = 0, dimension = 0; dimension < VDimension; ++dimension)
392  {
393  if (dimension != restrictedDirection)
394  {
395  splitIndex[splitDimension] = requestedRegion.GetIndex(dimension);
396  splitSize[splitDimension] = requestedRegion.GetSize(dimension);
397  ++splitDimension;
398  }
399  }
400 
401  this->ParallelizeImageRegion(
402  SplitDimension,
403  splitIndex.m_InternalArray,
404  splitSize.m_InternalArray,
405  [restrictedDirection, &requestedRegion, &funcP](const IndexValueType index[], const SizeValueType size[]) {
406  ImageRegion<VDimension> restrictedRequestedRegion;
407  restrictedRequestedRegion.SetIndex(restrictedDirection, requestedRegion.GetIndex(restrictedDirection));
408  restrictedRequestedRegion.SetSize(restrictedDirection, requestedRegion.GetSize(restrictedDirection));
409  for (unsigned int splitDimension = 0, dimension = 0; dimension < VDimension; ++dimension)
410  {
411  if (dimension != restrictedDirection)
412  {
413  restrictedRequestedRegion.SetIndex(dimension, index[splitDimension]);
414  restrictedRequestedRegion.SetSize(dimension, size[splitDimension]);
415  ++splitDimension;
416  }
417  }
418  funcP(restrictedRequestedRegion);
419  },
420  filter);
421  }
422  }
423 
426  virtual void
427  ParallelizeImageRegion(unsigned int dimension,
428  const IndexValueType index[],
429  const SizeValueType size[],
430  ThreadingFunctorType funcP,
431  ProcessObject * filter);
432 
433 protected:
434  MultiThreaderBase();
435  ~MultiThreaderBase() override;
436  void
437  PrintSelf(std::ostream & os, Indent indent) const override;
438 
440  {
445  };
446 
448  ParallelizeArrayHelper(void * arg);
449 
451  {
453  unsigned int dimension;
457  };
458 
460  ParallelizeImageRegionHelper(void * arg);
461 
463  ThreadIdType m_NumberOfWorkUnits{};
464 
473  ThreadIdType m_MaximumNumberOfThreads{};
474 
482  SingleMethodProxy(void * arg);
483 
485  ThreadFunctionType m_SingleMethod{ nullptr };
486 
488  void * m_SingleData{ nullptr };
489 
490 private:
491  static void
492  SetGlobalDefaultThreaderPrivate(ThreaderEnum threaderType);
493  static ThreaderEnum
494  GetGlobalDefaultThreaderPrivate();
495 
497  itkGetGlobalDeclarationMacro(MultiThreaderBaseGlobals, PimplGlobals);
498 
499  std::atomic<bool> m_UpdateProgress{ true };
500 
501  static MultiThreaderBaseGlobals * m_PimplGlobals;
505  friend class ProcessObject;
506 
508  static ThreadIdType
509  GetGlobalDefaultNumberOfThreadsByPlatform();
510 };
511 
512 
513 } // namespace itk
514 
515 #endif
itk::MultiThreaderBase
A class for performing multithreaded execution.
Definition: itkMultiThreaderBase.h:106
itk::MultiThreaderBase::WorkUnitInfo::ThreadFunction
ThreadFunctionType ThreadFunction
Definition: itkMultiThreaderBase.h:289
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:455
itk::MultiThreaderBase::WorkUnitInfo
Definition: itkMultiThreaderBase.h:284
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:442
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:374
itk::MultiThreaderBase::ArrayCallback
Definition: itkMultiThreaderBase.h:439
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:291
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:454
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:443
itkThreadSupport.h
itk::MultiThreaderBase::m_PimplGlobals
static MultiThreaderBaseGlobals * m_PimplGlobals
Definition: itkMultiThreaderBase.h:501
itk::MultiThreaderBase::RegionAndCallback::dimension
unsigned int dimension
Definition: itkMultiThreaderBase.h:453
itk::MultiThreaderBase::WorkUnitInfo::UserData
void * UserData
Definition: itkMultiThreaderBase.h:288
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:452
itkIntTypes.h
itk::MultiThreaderBaseEnums::Threader::Unknown
itk::MultiThreaderBase::RegionAndCallback
Definition: itkMultiThreaderBase.h:450
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:444
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:329
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:287
itk::ProgressReporter
Implements progress tracking for a filter.
Definition: itkProgressReporter.h:60
itk::MultiThreaderBase::ArrayCallback::functor
ArrayThreadingFunctorType functor
Definition: itkMultiThreaderBase.h:441
itk::MultiThreaderBase::RegionAndCallback::filter
ProcessObject * filter
Definition: itkMultiThreaderBase.h:456
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:350
itk::MultiThreaderBaseEnums::Threader::Platform
itk::MultiThreaderBase::WorkUnitInfo::WorkUnitID
ThreadIdType WorkUnitID
Definition: itkMultiThreaderBase.h:286
itk::MultiThreaderBaseEnums::ThreadExitCode::SUCCESS
itk::SizeValueType
unsigned long SizeValueType
Definition: itkIntTypes.h:83
itk::MultiThreaderBase::ArrayThreadingFunctorType
std::function< void(SizeValueType)> ArrayThreadingFunctorType
Definition: itkMultiThreaderBase.h:330