ITK  6.0.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);
104 struct MultiThreaderBaseGlobals;
105 class ProcessObject;
106 
107 class ITKCommon_EXPORT MultiThreaderBase : public Object
108 {
109 public:
110  ITK_DISALLOW_COPY_AND_MOVE(MultiThreaderBase);
111 
117 
119  static Pointer
120  New();
121 
123  itkOverrideGetNameOfClassMacro(MultiThreaderBase);
124 
128  virtual void
129  SetMaximumNumberOfThreads(ThreadIdType numberOfThreads);
130  itkGetConstMacro(MaximumNumberOfThreads, ThreadIdType);
136  virtual void
137  SetNumberOfWorkUnits(ThreadIdType numberOfWorkUnits);
138  itkGetConstMacro(NumberOfWorkUnits, ThreadIdType);
141  virtual void
142  SetUpdateProgress(bool updates);
143  itkGetConstMacro(UpdateProgress, bool);
144 
150  static void
151  SetGlobalMaximumNumberOfThreads(ThreadIdType val);
152  static ThreadIdType
153  GetGlobalMaximumNumberOfThreads();
161  itkLegacyMacro(static void SetGlobalDefaultUseThreadPool(const bool GlobalDefaultUseThreadPool);)
162  itkLegacyMacro(static bool GetGlobalDefaultUseThreadPool();)
166 #if !defined(ITK_LEGACY_REMOVE)
167  using ThreaderType = ThreaderEnum;
168  static constexpr ThreaderEnum Platform = ThreaderEnum::Platform;
169  static constexpr ThreaderEnum First = ThreaderEnum::First;
170  static constexpr ThreaderEnum Pool = ThreaderEnum::Pool;
171  static constexpr ThreaderEnum TBB = ThreaderEnum::TBB;
172  static constexpr ThreaderEnum Last = ThreaderEnum::Last;
173  static constexpr ThreaderEnum Unknown = ThreaderEnum::Unknown;
174 #endif
175 
177  static ThreaderEnum
178  ThreaderTypeFromString(std::string threaderString);
179 
181  static std::string
183  {
184  switch (threader)
185  {
186  case ThreaderEnum::Platform:
187  return "Platform";
188  case ThreaderEnum::Pool:
189  return "Pool";
190  case ThreaderEnum::TBB:
191  return "TBB";
192  case ThreaderEnum::Unknown:
193  default:
194  return "Unknown";
195  }
196  }
210  static void
211  SetGlobalDefaultThreader(ThreaderEnum threaderType);
212  static ThreaderEnum
213  GetGlobalDefaultThreader();
220  static void
221  SetGlobalDefaultNumberOfThreads(ThreadIdType val);
222  static ThreadIdType
223  GetGlobalDefaultNumberOfThreads();
226 #if !defined(ITK_LEGACY_REMOVE)
227 
229  itkLegacyMacro(virtual void SetNumberOfThreads(ThreadIdType numberOfThreads))
230  {
231  this->SetMaximumNumberOfThreads(numberOfThreads);
232  this->SetNumberOfWorkUnits(this->GetMaximumNumberOfThreads()); // Might be clamped
233  }
234  itkLegacyMacro(virtual ThreadIdType GetNumberOfThreads())
235  {
236  return this->GetNumberOfWorkUnits();
237  }
248  // clang-format off
249 ITK_GCC_PRAGMA_DIAG_PUSH()
250 ITK_GCC_PRAGMA_DIAG(ignored "-Wattributes")
251 INTEL_PRAGMA_WARN_PUSH
252 INTEL_SUPPRESS_warning_1292
253  // clang-format on
254 # ifdef ITK_LEGACY_SILENT
255  struct ThreadInfoStruct
256 # else
257  struct [[deprecated("Use WorkUnitInfo, ThreadInfoStruct is deprecated since ITK 5.0")]] ThreadInfoStruct
258 # endif
259  // clang-format off
260 INTEL_PRAGMA_WARN_POP
261  // clang-format on
262  {
263  ThreadIdType ThreadID;
264  ThreadIdType NumberOfThreads;
265  void * UserData;
266  ThreadFunctionType ThreadFunction;
267  enum
268  {
269  SUCCESS,
270  ITK_EXCEPTION,
271  ITK_PROCESS_ABORTED_EXCEPTION,
272  STD_EXCEPTION,
273  UNKNOWN
274  } ThreadExitCode;
275  };
276  // clang-format off
277 ITK_GCC_PRAGMA_DIAG_POP()
278  // clang-format on
279 #endif // ITK_LEGACY_REMOVE
280 
289  {
292  void * UserData;
296 #if !defined(ITK_LEGACY_REMOVE)
297  using ThreadExitCodeType = ThreadExitCodeEnum;
298  static constexpr ThreadExitCodeEnum SUCCESS = ThreadExitCodeEnum::SUCCESS;
299  static constexpr ThreadExitCodeEnum ITK_EXCEPTION = ThreadExitCodeEnum::ITK_EXCEPTION;
300  static constexpr ThreadExitCodeEnum ITK_PROCESS_ABORTED_EXCEPTION =
301  ThreadExitCodeEnum::ITK_PROCESS_ABORTED_EXCEPTION;
302  static constexpr ThreadExitCodeEnum STD_EXCEPTION = ThreadExitCodeEnum::STD_EXCEPTION;
303  static constexpr ThreadExitCodeEnum UNKNOWN = ThreadExitCodeEnum::UNKNOWN;
304 #endif
305  };
312  virtual void
313  SingleMethodExecute() = 0;
314 
319  virtual void
320  SetSingleMethod(ThreadFunctionType, void * data) = 0;
321 
323  void
324  SetSingleMethodAndExecute(ThreadFunctionType func, void * data);
325 
326 #ifndef ITK_FUTURE_LEGACY_REMOVE
327  // `TemplatedThreadingFunctorType` was previously used to declare the `funcP` parameter of `ParallelizeImageRegion`
328  // and `ParallelizeImageRegionRestrictDirection` template member functions.
329  template <unsigned int VDimension>
330  using TemplatedThreadingFunctorType [[deprecated]] = std::function<void(const ImageRegion<VDimension> &)>;
331 #endif
332 
333  using ThreadingFunctorType = std::function<void(const IndexValueType index[], const SizeValueType size[])>;
334  using ArrayThreadingFunctorType = std::function<void(SizeValueType)>;
335 
341  virtual void
342  ParallelizeArray(SizeValueType firstIndex,
343  SizeValueType lastIndexPlus1,
345  ProcessObject * filter);
346 
352  template <unsigned int VDimension, typename TFunction>
353  ITK_TEMPLATE_EXPORT void
354  ParallelizeImageRegion(const ImageRegion<VDimension> & requestedRegion, TFunction funcP, ProcessObject * filter)
355  {
356  this->ParallelizeImageRegion(
357  VDimension,
358  requestedRegion.GetIndex().m_InternalArray,
359  requestedRegion.GetSize().m_InternalArray,
360  [&funcP](const IndexValueType index[], const SizeValueType size[]) {
362  for (unsigned int d = 0; d < VDimension; ++d)
363  {
364  region.SetIndex(d, index[d]);
365  region.SetSize(d, size[d]);
366  }
367  funcP(region);
368  },
369  filter);
370  }
376  template <unsigned int VDimension, typename TFunction>
377  ITK_TEMPLATE_EXPORT void
378  ParallelizeImageRegionRestrictDirection(unsigned int restrictedDirection,
379  const ImageRegion<VDimension> & requestedRegion,
380  TFunction funcP,
381  ProcessObject * filter)
382  {
383  if constexpr (VDimension <= 1) // Cannot split, no parallelization
384  {
385 
386  ProgressReporter progress(filter, 0, requestedRegion.GetNumberOfPixels());
387  funcP(requestedRegion);
388  }
389  else // Can split, parallelize!
390  {
391  constexpr unsigned int SplitDimension = VDimension - 1;
392 
393  Index<SplitDimension> splitIndex{};
394  Size<SplitDimension> splitSize{};
395  for (unsigned int splitDimension = 0, dimension = 0; dimension < VDimension; ++dimension)
396  {
397  if (dimension != restrictedDirection)
398  {
399  splitIndex[splitDimension] = requestedRegion.GetIndex(dimension);
400  splitSize[splitDimension] = requestedRegion.GetSize(dimension);
401  ++splitDimension;
402  }
403  }
404 
405  this->ParallelizeImageRegion(
406  SplitDimension,
407  splitIndex.m_InternalArray,
408  splitSize.m_InternalArray,
409  [restrictedDirection, &requestedRegion, &funcP](const IndexValueType index[], const SizeValueType size[]) {
410  ImageRegion<VDimension> restrictedRequestedRegion;
411  restrictedRequestedRegion.SetIndex(restrictedDirection, requestedRegion.GetIndex(restrictedDirection));
412  restrictedRequestedRegion.SetSize(restrictedDirection, requestedRegion.GetSize(restrictedDirection));
413  for (unsigned int splitDimension = 0, dimension = 0; dimension < VDimension; ++dimension)
414  {
415  if (dimension != restrictedDirection)
416  {
417  restrictedRequestedRegion.SetIndex(dimension, index[splitDimension]);
418  restrictedRequestedRegion.SetSize(dimension, size[splitDimension]);
419  ++splitDimension;
420  }
421  }
422  funcP(restrictedRequestedRegion);
423  },
424  filter);
425  }
426  }
427 
430  virtual void
431  ParallelizeImageRegion(unsigned int dimension,
432  const IndexValueType index[],
433  const SizeValueType size[],
434  ThreadingFunctorType funcP,
435  ProcessObject * filter);
436 
437 protected:
438  MultiThreaderBase();
439  ~MultiThreaderBase() override;
440  void
441  PrintSelf(std::ostream & os, Indent indent) const override;
442 
444  {
449  };
450 
452  ParallelizeArrayHelper(void * arg);
453 
455  {
457  unsigned int dimension;
461  };
462 
464  ParallelizeImageRegionHelper(void * arg);
465 
467  ThreadIdType m_NumberOfWorkUnits{};
468 
477  ThreadIdType m_MaximumNumberOfThreads{};
478 
486  SingleMethodProxy(void * arg);
487 
489  ThreadFunctionType m_SingleMethod{ nullptr };
490 
492  void * m_SingleData{ nullptr };
493 
494 private:
495  static void
496  SetGlobalDefaultThreaderPrivate(ThreaderEnum threaderType);
497  static ThreaderEnum
498  GetGlobalDefaultThreaderPrivate();
499 
501  itkGetGlobalDeclarationMacro(MultiThreaderBaseGlobals, PimplGlobals);
502 
503  std::atomic<bool> m_UpdateProgress{ true };
504 
505  static MultiThreaderBaseGlobals * m_PimplGlobals;
509  friend class ProcessObject;
510 
512  static ThreadIdType
513  GetGlobalDefaultNumberOfThreadsByPlatform();
514 };
515 
516 
517 } // namespace itk
518 
519 #endif
itk::MultiThreaderBase
A class for performing multithreaded execution.
Definition: itkMultiThreaderBase.h:107
itk::MultiThreaderBase::WorkUnitInfo::ThreadFunction
ThreadFunctionType ThreadFunction
Definition: itkMultiThreaderBase.h:293
itkObjectFactory.h
itk::MultiThreaderBaseEnums::ThreadExitCode::STD_EXCEPTION
itk::Index
Represent a n-dimensional index in a n-dimensional image.
Definition: itkIndex.h:68
itk::MultiThreaderBase::RegionAndCallback::size
const SizeValueType * size
Definition: itkMultiThreaderBase.h:459
itk::MultiThreaderBase::WorkUnitInfo
Definition: itkMultiThreaderBase.h:288
itk::MultiThreaderBaseEnums::Threader::First
itk::Size
Represent a n-dimensional size (bounds) of a n-dimensional image.
Definition: itkSize.h:69
itk::MultiThreaderBaseEnums::Threader::Pool
itk::MultiThreaderBase::ArrayCallback::firstIndex
const SizeValueType firstIndex
Definition: itkMultiThreaderBase.h:446
itk::ImageRegion::GetIndex
const IndexType & GetIndex() const
Definition: itkImageRegion.h:188
itk::ImageRegion< VDimension >
itk::MultiThreaderBaseEnums::Threader::TBB
itkProgressReporter.h
itk::MultiThreaderBase::ParallelizeImageRegionRestrictDirection
ITK_TEMPLATE_EXPORT void ParallelizeImageRegionRestrictDirection(unsigned int restrictedDirection, const ImageRegion< VDimension > &requestedRegion, TFunction funcP, ProcessObject *filter)
Definition: itkMultiThreaderBase.h:378
itk::MultiThreaderBase::ArrayCallback
Definition: itkMultiThreaderBase.h:443
itk::MultiThreaderBaseEnums::Threader::Last
itkSingletonMacro.h
itk::ImageRegion::GetSize
const SizeType & GetSize() const
Definition: itkImageRegion.h:209
itk::operator<<
ITKCommon_EXPORT std::ostream & operator<<(std::ostream &out, typename AnatomicalOrientation::CoordinateEnum value)
itk::SmartPointer< Self >
itk::ThreadFunctionType
void(*)(void *) ThreadFunctionType
Definition: itkThreadSupport.h:82
itkImageRegion.h
itk::IndexValueType
long IndexValueType
Definition: itkIntTypes.h:93
itk::MultiThreaderBase::WorkUnitInfo::ThreadExitCode
ThreadExitCodeEnum ThreadExitCode
Definition: itkMultiThreaderBase.h:295
itk::ThreadIdType
unsigned int ThreadIdType
Definition: itkIntTypes.h:102
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:458
itk::MultiThreaderBaseEnums::ThreadExitCode::ITK_PROCESS_ABORTED_EXCEPTION
itk::MultiThreaderBaseEnums::ThreadExitCode
ThreadExitCode
Definition: itkMultiThreaderBase.h:74
itk::LightObject
Light weight base class for most itk classes.
Definition: itkLightObject.h:55
itk::MultiThreaderBase::ArrayCallback::lastIndexPlus1
const SizeValueType lastIndexPlus1
Definition: itkMultiThreaderBase.h:447
itkThreadSupport.h
itk::MultiThreaderBase::m_PimplGlobals
static MultiThreaderBaseGlobals * m_PimplGlobals
Definition: itkMultiThreaderBase.h:505
itk::MultiThreaderBase::RegionAndCallback::dimension
unsigned int dimension
Definition: itkMultiThreaderBase.h:457
itk::MultiThreaderBase::WorkUnitInfo::UserData
void * UserData
Definition: itkMultiThreaderBase.h:292
itk::MultiThreaderBaseEnums::Threader::Unknown
itk::Index::m_InternalArray
IndexValueType m_InternalArray[VDimension]
Definition: itkIndex.h:291
itk::MultiThreaderBaseEnums::ThreadExitCode::ITK_EXCEPTION
itk::MultiThreaderBaseEnums
enums for MultiThreaderBase
Definition: itkMultiThreaderBase.h:53
itk::MultiThreaderBase::RegionAndCallback::functor
ThreadingFunctorType functor
Definition: itkMultiThreaderBase.h:456
itkIntTypes.h
itk::MultiThreaderBaseEnums::Threader
Threader
Definition: itkMultiThreaderBase.h:61
itk::MultiThreaderBaseEnums::ThreadExitCode::UNKNOWN
itk::MultiThreaderBase::RegionAndCallback
Definition: itkMultiThreaderBase.h:454
itkObject.h
itk::Size::m_InternalArray
SizeValueType m_InternalArray[VDimension]
Definition: itkSize.h:243
itk
The "itk" namespace contains all Insight Segmentation and Registration Toolkit (ITK) classes....
Definition: itkAnatomicalOrientation.h:29
itk::MultiThreaderBase::ArrayCallback::filter
ProcessObject * filter
Definition: itkMultiThreaderBase.h:448
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::ProcessObject
class ITK_FORWARD_EXPORT ProcessObject
Definition: itkDataObject.h:41
itkGetGlobalDeclarationMacro
#define itkGetGlobalDeclarationMacro(Type, VarName)
Definition: itkSingletonMacro.h:34
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:333
itk::MultiThreaderBaseEnums::ThreadExitCode::SUCCESS
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:291
itk::ProgressReporter
Implements progress tracking for a filter.
Definition: itkProgressReporter.h:60
itk::MultiThreaderBase::ArrayCallback::functor
ArrayThreadingFunctorType functor
Definition: itkMultiThreaderBase.h:445
itk::MultiThreaderBase::RegionAndCallback::filter
ProcessObject * filter
Definition: itkMultiThreaderBase.h:460
itk::MultiThreaderBase::ThreaderTypeToString
static std::string ThreaderTypeToString(ThreaderEnum threader)
Definition: itkMultiThreaderBase.h:182
itk::MultiThreaderBase::ParallelizeImageRegion
ITK_TEMPLATE_EXPORT void ParallelizeImageRegion(const ImageRegion< VDimension > &requestedRegion, TFunction funcP, ProcessObject *filter)
Definition: itkMultiThreaderBase.h:354
itk::MultiThreaderBase::WorkUnitInfo::WorkUnitID
ThreadIdType WorkUnitID
Definition: itkMultiThreaderBase.h:290
itk::MultiThreaderBaseEnums::Threader::Platform
itk::SizeValueType
unsigned long SizeValueType
Definition: itkIntTypes.h:86
itk::MultiThreaderBase::ArrayThreadingFunctorType
std::function< void(SizeValueType)> ArrayThreadingFunctorType
Definition: itkMultiThreaderBase.h:334