ITK  5.3.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  itkTypeMacro(MultiThreaderBase, Object);
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  break;
188  case ThreaderEnum::Pool:
189  return "Pool";
190  break;
191  case ThreaderEnum::TBB:
192  return "TBB";
193  break;
194  case ThreaderEnum::Unknown:
195  default:
196  return "Unknown";
197  break;
198  }
199  }
213  static void
214  SetGlobalDefaultThreader(ThreaderEnum threaderType);
215  static ThreaderEnum
216  GetGlobalDefaultThreader();
223  static void
224  SetGlobalDefaultNumberOfThreads(ThreadIdType val);
225  static ThreadIdType
226  GetGlobalDefaultNumberOfThreads();
229 #if !defined(ITK_LEGACY_REMOVE)
230 
232  itkLegacyMacro(virtual void SetNumberOfThreads(ThreadIdType numberOfThreads))
233  {
234  this->SetMaximumNumberOfThreads(numberOfThreads);
235  this->SetNumberOfWorkUnits(this->GetMaximumNumberOfThreads()); // Might be clamped
236  }
237  itkLegacyMacro(virtual ThreadIdType GetNumberOfThreads()) { return this->GetNumberOfWorkUnits(); }
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_PRAGMA_PUSH
254 CLANG_SUPPRESS_Wcpp14_extensions
255  // clang-format on
256 # ifdef ITK_LEGACY_SILENT
257  struct ThreadInfoStruct
258 # else
259  struct [[deprecated("Use WorkUnitInfo, ThreadInfoStruct is deprecated since ITK 5.0")]] ThreadInfoStruct
260 # endif
261  // clang-format off
262 CLANG_PRAGMA_POP
263 INTEL_PRAGMA_WARN_POP
264  // clang-format on
265  {
266  ThreadIdType ThreadID;
267  ThreadIdType NumberOfThreads;
268  void * UserData;
269  ThreadFunctionType ThreadFunction;
270  enum
271  {
272  SUCCESS,
273  ITK_EXCEPTION,
274  ITK_PROCESS_ABORTED_EXCEPTION,
275  STD_EXCEPTION,
276  UNKNOWN
277  } ThreadExitCode;
278  };
279  // clang-format off
280 ITK_GCC_PRAGMA_DIAG_POP()
281  // clang-format on
282 #endif // ITK_LEGACY_REMOVE
283 
292  {
295  void * UserData;
299 #if !defined(ITK_LEGACY_REMOVE)
300  using ThreadExitCodeType = ThreadExitCodeEnum;
301  static constexpr ThreadExitCodeEnum SUCCESS = ThreadExitCodeEnum::SUCCESS;
302  static constexpr ThreadExitCodeEnum ITK_EXCEPTION = ThreadExitCodeEnum::ITK_EXCEPTION;
303  static constexpr ThreadExitCodeEnum ITK_PROCESS_ABORTED_EXCEPTION =
304  ThreadExitCodeEnum::ITK_PROCESS_ABORTED_EXCEPTION;
305  static constexpr ThreadExitCodeEnum STD_EXCEPTION = ThreadExitCodeEnum::STD_EXCEPTION;
306  static constexpr ThreadExitCodeEnum UNKNOWN = ThreadExitCodeEnum::UNKNOWN;
307 #endif
308  };
315  virtual void
316  SingleMethodExecute() = 0;
317 
322  virtual void
323  SetSingleMethod(ThreadFunctionType, void * data) = 0;
324 
325  template <unsigned int VDimension>
326  using TemplatedThreadingFunctorType = std::function<void(const ImageRegion<VDimension> &)>;
327  using ThreadingFunctorType = std::function<void(const IndexValueType index[], const SizeValueType size[])>;
328  using ArrayThreadingFunctorType = std::function<void(SizeValueType)>;
329 
335  virtual void
336  ParallelizeArray(SizeValueType firstIndex,
337  SizeValueType lastIndexPlus1,
339  ProcessObject * filter);
340 
344  template <unsigned int VDimension>
345  ITK_TEMPLATE_EXPORT void
348  ProcessObject * filter)
349  {
350  this->ParallelizeImageRegion(
351  VDimension,
352  requestedRegion.GetIndex().m_InternalArray,
353  requestedRegion.GetSize().m_InternalArray,
354  [funcP](const IndexValueType index[], const SizeValueType size[]) {
356  for (unsigned int d = 0; d < VDimension; ++d)
357  {
358  region.SetIndex(d, index[d]);
359  region.SetSize(d, size[d]);
360  }
361  funcP(region);
362  },
363  filter);
364  }
370  template <unsigned int VDimension>
371  ITK_TEMPLATE_EXPORT void
372  ParallelizeImageRegionRestrictDirection(unsigned int restrictedDirection,
373  const ImageRegion<VDimension> & requestedRegion,
375  ProcessObject * filter)
376  {
377  if (VDimension <= 1) // Cannot split, no parallelization
378  {
379 
380  ProgressReporter progress(filter, 0, requestedRegion.GetNumberOfPixels());
381  funcP(requestedRegion);
382  }
383  else // Can split, parallelize!
384  {
385  constexpr unsigned int SplitDimension = (VDimension - 1) ? VDimension - 1 : VDimension;
386  using SplitRegionType = ImageRegion<SplitDimension>;
387 
388  SplitRegionType splitRegion;
389  for (unsigned int splitDimension = 0, dimension = 0; dimension < VDimension; ++dimension)
390  {
391  if (dimension == restrictedDirection)
392  {
393  continue;
394  }
395  splitRegion.SetIndex(splitDimension, requestedRegion.GetIndex(dimension));
396  splitRegion.SetSize(splitDimension, requestedRegion.GetSize(dimension));
397  ++splitDimension;
398  }
399 
400  this->ParallelizeImageRegion(
401  SplitDimension,
402  splitRegion.GetIndex().m_InternalArray,
403  splitRegion.GetSize().m_InternalArray,
404  [&](const IndexValueType index[], const SizeValueType size[]) {
405  ImageRegion<VDimension> restrictedRequestedRegion;
406  restrictedRequestedRegion.SetIndex(restrictedDirection, requestedRegion.GetIndex(restrictedDirection));
407  restrictedRequestedRegion.SetSize(restrictedDirection, requestedRegion.GetSize(restrictedDirection));
408  for (unsigned int splitDimension = 0, dimension = 0; dimension < VDimension; ++dimension)
409  {
410  if (dimension == restrictedDirection)
411  {
412  continue;
413  }
414  restrictedRequestedRegion.SetIndex(dimension, index[splitDimension]);
415  restrictedRequestedRegion.SetSize(dimension, size[splitDimension]);
416  ++splitDimension;
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:
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 
464 
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:296
itkObjectFactory.h
itk::MultiThreaderBase::TemplatedThreadingFunctorType
std::function< void(const ImageRegion< VDimension > &)> TemplatedThreadingFunctorType
Definition: itkMultiThreaderBase.h:326
itk::MultiThreaderBase::RegionAndCallback::size
const SizeValueType * size
Definition: itkMultiThreaderBase.h:455
itk::MultiThreaderBase::WorkUnitInfo
Definition: itkMultiThreaderBase.h:291
itk::MultiThreaderBaseEnums::Threader::Last
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:160
itk::ImageRegion< VDimension >
itkProgressReporter.h
itk::MultiThreaderBase::ArrayCallback
Definition: itkMultiThreaderBase.h:439
Threader
itkSingletonMacro.h
itk::ImageRegion::GetSize
const SizeType & GetSize() const
Definition: itkImageRegion.h:181
itk::SmartPointer< Self >
itk::Indent
Control indentation during Print() invocation.
Definition: itkIndent.h:49
itk::ThreadFunctionType
void(*)(void *) ThreadFunctionType
Definition: itkThreadSupport.h:81
itkImageRegion.h
itk::IndexValueType
long IndexValueType
Definition: itkIntTypes.h:90
itk::MultiThreaderBaseEnums::Threader::Pool
itk::MultiThreaderBase::WorkUnitInfo::ThreadExitCode
ThreadExitCodeEnum ThreadExitCode
Definition: itkMultiThreaderBase.h:298
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:88
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:295
itk::MultiThreaderBase::m_NumberOfWorkUnits
ThreadIdType m_NumberOfWorkUnits
Definition: itkMultiThreaderBase.h:463
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:232
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:138
itk::ImageRegion::SetIndex
void SetIndex(const IndexType &index)
Definition: itkImageRegion.h:153
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:62
itk::MultiThreaderBase::ThreadingFunctorType
std::function< void(const IndexValueType index[], const SizeValueType size[])> ThreadingFunctorType
Definition: itkMultiThreaderBase.h:327
itk::MultiThreaderBase::m_MaximumNumberOfThreads
ThreadIdType m_MaximumNumberOfThreads
Definition: itkMultiThreaderBase.h:473
New
static Pointer New()
itk::ImageRegion::SetSize
void SetSize(const SizeType &size)
Definition: itkImageRegion.h:174
itk::ImageRegion::GetNumberOfPixels
SizeValueType GetNumberOfPixels() const
itk::MultiThreaderBase::WorkUnitInfo::NumberOfWorkUnits
ThreadIdType NumberOfWorkUnits
Definition: itkMultiThreaderBase.h:294
itk::MultiThreaderBase::ParallelizeImageRegion
ITK_TEMPLATE_EXPORT void ParallelizeImageRegion(const ImageRegion< VDimension > &requestedRegion, TemplatedThreadingFunctorType< VDimension > funcP, ProcessObject *filter)
Definition: itkMultiThreaderBase.h:346
itk::ProgressReporter
Implements progress tracking for a filter.
Definition: itkProgressReporter.h:60
itk::MultiThreaderBase::ArrayCallback::functor
ArrayThreadingFunctorType functor
Definition: itkMultiThreaderBase.h:441
itk::MultiThreaderBase::ParallelizeImageRegionRestrictDirection
ITK_TEMPLATE_EXPORT void ParallelizeImageRegionRestrictDirection(unsigned int restrictedDirection, const ImageRegion< VDimension > &requestedRegion, TemplatedThreadingFunctorType< VDimension > funcP, ProcessObject *filter)
Definition: itkMultiThreaderBase.h:372
itk::MultiThreaderBase::RegionAndCallback::filter
ProcessObject * filter
Definition: itkMultiThreaderBase.h:456
itk::MultiThreaderBase::ThreaderTypeToString
static std::string ThreaderTypeToString(ThreaderEnum threader)
Definition: itkMultiThreaderBase.h:181
itk::MultiThreaderBaseEnums::Threader::Platform
itk::MultiThreaderBase::WorkUnitInfo::WorkUnitID
ThreadIdType WorkUnitID
Definition: itkMultiThreaderBase.h:293
itk::MultiThreaderBaseEnums::ThreadExitCode::SUCCESS
itk::SizeValueType
unsigned long SizeValueType
Definition: itkIntTypes.h:83
itk::MultiThreaderBase::ArrayThreadingFunctorType
std::function< void(SizeValueType)> ArrayThreadingFunctorType
Definition: itkMultiThreaderBase.h:328