ITK  5.2.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  * http://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 <functional>
39 #include <thread>
40 #include "itkProgressReporter.h"
41 
42 
43 namespace itk
44 {
45 
53 {
54 public:
60  enum class Threader : int8_t
61  {
62  Platform = 0,
63  First = Platform,
64  Pool,
65  TBB,
66  Last = TBB,
67  Unknown = -1
68  };
69 
73  enum class ThreadExitCode : uint8_t
74  {
75  SUCCESS,
79  UNKNOWN
80  };
81 };
82 // Define how to print enumeration
83 extern ITKCommon_EXPORT std::ostream &
84  operator<<(std::ostream & out, const MultiThreaderBaseEnums::Threader value);
85 extern ITKCommon_EXPORT std::ostream &
86  operator<<(std::ostream & out, const MultiThreaderBaseEnums::ThreadExitCode value);
87 
102 struct MultiThreaderBaseGlobals;
103 class ProcessObject;
104 
105 class ITKCommon_EXPORT MultiThreaderBase : public Object
106 {
107 public:
108  ITK_DISALLOW_COPY_AND_MOVE(MultiThreaderBase);
109 
115 
117  static Pointer
118  New();
119 
121  itkTypeMacro(MultiThreaderBase, Object);
122 
126  virtual void
127  SetMaximumNumberOfThreads(ThreadIdType numberOfThreads);
128  itkGetConstMacro(MaximumNumberOfThreads, ThreadIdType);
130 
134  virtual void
135  SetNumberOfWorkUnits(ThreadIdType numberOfWorkUnits);
136  itkGetConstMacro(NumberOfWorkUnits, ThreadIdType);
138 
139  virtual void
140  SetUpdateProgress(bool updates);
141  itkGetConstMacro(UpdateProgress, bool);
142 
148  static void
149  SetGlobalMaximumNumberOfThreads(ThreadIdType val);
150  static ThreadIdType
151  GetGlobalMaximumNumberOfThreads();
153 
159  itkLegacyMacro(static void SetGlobalDefaultUseThreadPool(const bool GlobalDefaultUseThreadPool));
160  itkLegacyMacro(static bool GetGlobalDefaultUseThreadPool());
162 
164 #if !defined(ITK_LEGACY_REMOVE)
165  using ThreaderType = ThreaderEnum;
166  static constexpr ThreaderEnum Platform = ThreaderEnum::Platform;
167  static constexpr ThreaderEnum First = ThreaderEnum::First;
168  static constexpr ThreaderEnum Pool = ThreaderEnum::Pool;
169  static constexpr ThreaderEnum TBB = ThreaderEnum::TBB;
170  static constexpr ThreaderEnum Last = ThreaderEnum::Last;
171  static constexpr ThreaderEnum Unknown = ThreaderEnum::Unknown;
172 #endif
173 
175  static ThreaderEnum
176  ThreaderTypeFromString(std::string threaderString);
177 
179  static std::string
181  {
182  switch (threader)
183  {
184  case ThreaderEnum::Platform:
185  return "Platform";
186  break;
187  case ThreaderEnum::Pool:
188  return "Pool";
189  break;
190  case ThreaderEnum::TBB:
191  return "TBB";
192  break;
193  case ThreaderEnum::Unknown:
194  default:
195  return "Unknown";
196  break;
197  }
198  }
200 
212  static void
213  SetGlobalDefaultThreader(ThreaderEnum threaderType);
214  static ThreaderEnum
215  GetGlobalDefaultThreader();
217 
222  static void
223  SetGlobalDefaultNumberOfThreads(ThreadIdType val);
224  static ThreadIdType
225  GetGlobalDefaultNumberOfThreads();
227 
228 #if !defined(ITK_LEGACY_REMOVE)
229 
231  itkLegacyMacro(virtual void SetNumberOfThreads(ThreadIdType numberOfThreads))
232  {
233  this->SetMaximumNumberOfThreads(numberOfThreads);
234  this->SetNumberOfWorkUnits(this->GetMaximumNumberOfThreads()); // Might be clamped
235  }
236  itkLegacyMacro(virtual ThreadIdType GetNumberOfThreads()) { return this->GetNumberOfWorkUnits(); }
238 
247  // clang-format off
248 ITK_GCC_PRAGMA_DIAG_PUSH()
249 ITK_GCC_PRAGMA_DIAG(ignored "-Wattributes")
250 INTEL_PRAGMA_WARN_PUSH
251 INTEL_SUPPRESS_warning_1292
252 CLANG_PRAGMA_PUSH
253 CLANG_SUPPRESS_Wc__14_extensions
254  // clang-format on
255 # ifdef ITK_LEGACY_SILENT
256  struct ThreadInfoStruct
257 # else
258  struct [[deprecated("Use WorkUnitInfo, ThreadInfoStruct is deprecated since ITK 5.0")]] ThreadInfoStruct
259 # endif
260  // clang-format off
261 CLANG_PRAGMA_POP
262 INTEL_PRAGMA_WARN_POP
263  // clang-format on
264  {
265  ThreadIdType ThreadID;
266  ThreadIdType NumberOfThreads;
267  void * UserData;
268  ThreadFunctionType ThreadFunction;
269  enum
270  {
271  SUCCESS,
272  ITK_EXCEPTION,
273  ITK_PROCESS_ABORTED_EXCEPTION,
274  STD_EXCEPTION,
275  UNKNOWN
276  } ThreadExitCode;
277  };
278  // clang-format off
279 ITK_GCC_PRAGMA_DIAG_POP()
280  // clang-format on
281 #endif // ITK_LEGACY_REMOVE
282 
283 
291  {
294  void * UserData;
298 #if !defined(ITK_LEGACY_REMOVE)
299  using ThreadExitCodeType = ThreadExitCodeEnum;
300  static constexpr ThreadExitCodeEnum SUCCESS = ThreadExitCodeEnum::SUCCESS;
301  static constexpr ThreadExitCodeEnum ITK_EXCEPTION = ThreadExitCodeEnum::ITK_EXCEPTION;
302  static constexpr ThreadExitCodeEnum ITK_PROCESS_ABORTED_EXCEPTION =
303  ThreadExitCodeEnum::ITK_PROCESS_ABORTED_EXCEPTION;
304  static constexpr ThreadExitCodeEnum STD_EXCEPTION = ThreadExitCodeEnum::STD_EXCEPTION;
305  static constexpr ThreadExitCodeEnum UNKNOWN = ThreadExitCodeEnum::UNKNOWN;
306 #endif
307  };
309 
314  virtual void
315  SingleMethodExecute() = 0;
316 
321  virtual void
322  SetSingleMethod(ThreadFunctionType, void * data) = 0;
323 
324  template <unsigned int VDimension>
325  using TemplatedThreadingFunctorType = std::function<void(const ImageRegion<VDimension> &)>;
326  using ThreadingFunctorType = std::function<void(const IndexValueType index[], const SizeValueType size[])>;
327  using ArrayThreadingFunctorType = std::function<void(SizeValueType)>;
328 
334  virtual void
335  ParallelizeArray(SizeValueType firstIndex,
336  SizeValueType lastIndexPlus1,
338  ProcessObject * filter);
339 
343  template <unsigned int VDimension>
344  ITK_TEMPLATE_EXPORT void
347  ProcessObject * filter)
348  {
349  this->ParallelizeImageRegion(
350  VDimension,
351  requestedRegion.GetIndex().m_InternalArray,
352  requestedRegion.GetSize().m_InternalArray,
353  [funcP](const IndexValueType index[], const SizeValueType size[]) {
355  for (unsigned int d = 0; d < VDimension; ++d)
356  {
357  region.SetIndex(d, index[d]);
358  region.SetSize(d, size[d]);
359  }
360  funcP(region);
361  },
362  filter);
363  }
365 
369  template <unsigned int VDimension>
370  ITK_TEMPLATE_EXPORT void
371  ParallelizeImageRegionRestrictDirection(unsigned int restrictedDirection,
372  const ImageRegion<VDimension> & requestedRegion,
374  ProcessObject * filter)
375  {
376  if (VDimension <= 1) // Cannot split, no parallelization
377  {
378 
379  ProgressReporter progress(filter, 0, requestedRegion.GetNumberOfPixels());
380  funcP(requestedRegion);
381  }
382  else // Can split, parallelize!
383  {
384  constexpr unsigned int SplitDimension = (VDimension - 1) ? VDimension - 1 : VDimension;
385  using SplitRegionType = ImageRegion<SplitDimension>;
386 
387  SplitRegionType splitRegion;
388  for (unsigned int splitDimension = 0, dimension = 0; dimension < VDimension; ++dimension)
389  {
390  if (dimension == restrictedDirection)
391  {
392  continue;
393  }
394  splitRegion.SetIndex(splitDimension, requestedRegion.GetIndex(dimension));
395  splitRegion.SetSize(splitDimension, requestedRegion.GetSize(dimension));
396  ++splitDimension;
397  }
398 
399  this->ParallelizeImageRegion(
400  SplitDimension,
401  splitRegion.GetIndex().m_InternalArray,
402  splitRegion.GetSize().m_InternalArray,
403  [&](const IndexValueType index[], const SizeValueType size[]) {
404  ImageRegion<VDimension> restrictedRequestedRegion;
405  restrictedRequestedRegion.SetIndex(restrictedDirection, requestedRegion.GetIndex(restrictedDirection));
406  restrictedRequestedRegion.SetSize(restrictedDirection, requestedRegion.GetSize(restrictedDirection));
407  for (unsigned int splitDimension = 0, dimension = 0; dimension < VDimension; ++dimension)
408  {
409  if (dimension == restrictedDirection)
410  {
411  continue;
412  }
413  restrictedRequestedRegion.SetIndex(dimension, index[splitDimension]);
414  restrictedRequestedRegion.SetSize(dimension, size[splitDimension]);
415  ++splitDimension;
416  }
417  funcP(restrictedRequestedRegion);
418  },
419  filter);
420  }
421  }
422 
425  virtual void
426  ParallelizeImageRegion(unsigned int dimension,
427  const IndexValueType index[],
428  const SizeValueType size[],
429  ThreadingFunctorType funcP,
430  ProcessObject * filter);
431 
432 protected:
434  ~MultiThreaderBase() override;
435  void
436  PrintSelf(std::ostream & os, Indent indent) const override;
437 
439  {
444  };
445 
447  ParallelizeArrayHelper(void * arg);
448 
450  {
452  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:
492  itkGetGlobalDeclarationMacro(MultiThreaderBaseGlobals, PimplGlobals);
493 
494  bool m_UpdateProgress{ true };
495 
496  static MultiThreaderBaseGlobals * m_PimplGlobals;
500  friend class ProcessObject;
501 
503  static ThreadIdType
504  GetGlobalDefaultNumberOfThreadsByPlatform();
505 };
506 
507 
508 } // namespace itk
509 
510 #endif
itk::MultiThreaderBase
A class for performing multithreaded execution.
Definition: itkMultiThreaderBase.h:105
itk::MultiThreaderBase::WorkUnitInfo::ThreadFunction
ThreadFunctionType ThreadFunction
Definition: itkMultiThreaderBase.h:295
itk::uint8_t
::uint8_t uint8_t
Definition: itkIntTypes.h:29
itkObjectFactory.h
itk::MultiThreaderBase::TemplatedThreadingFunctorType
std::function< void(const ImageRegion< VDimension > &)> TemplatedThreadingFunctorType
Definition: itkMultiThreaderBase.h:325
itk::MultiThreaderBase::RegionAndCallback::size
const SizeValueType * size
Definition: itkMultiThreaderBase.h:454
itk::MultiThreaderBase::WorkUnitInfo
Definition: itkMultiThreaderBase.h:290
itk::MultiThreaderBaseEnums::Threader::Last
itk::operator<<
std::ostream & operator<<(std::ostream &os, const Array< TValue > &arr)
Definition: itkArray.h:213
itk::MultiThreaderBaseEnums::ThreadExitCode
ThreadExitCode
Definition: itkMultiThreaderBase.h:73
itk::int8_t
::int8_t int8_t
Definition: itkIntTypes.h:28
itk::MultiThreaderBase::ArrayCallback::firstIndex
const SizeValueType firstIndex
Definition: itkMultiThreaderBase.h:441
itk::ImageRegion::GetIndex
const IndexType & GetIndex() const
Definition: itkImageRegion.h:160
itk::ImageRegion< VDimension >
itkProgressReporter.h
itk::MultiThreaderBase::ArrayCallback
Definition: itkMultiThreaderBase.h:438
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:77
itkImageRegion.h
itk::MultiThreaderBaseEnums::Threader::Pool
itk::MultiThreaderBase::WorkUnitInfo::ThreadExitCode
ThreadExitCodeEnum ThreadExitCode
Definition: itkMultiThreaderBase.h:297
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:82
itk::MultiThreaderBase::RegionAndCallback::index
const IndexValueType * index
Definition: itkMultiThreaderBase.h:453
itk::MultiThreaderBaseEnums::ThreadExitCode::UNKNOWN
itk::LightObject
Light weight base class for most itk classes.
Definition: itkLightObject.h:59
itk::MultiThreaderBase::ArrayCallback::lastIndexPlus1
const SizeValueType lastIndexPlus1
Definition: itkMultiThreaderBase.h:442
itkThreadSupport.h
itk::MultiThreaderBase::m_PimplGlobals
static MultiThreaderBaseGlobals * m_PimplGlobals
Definition: itkMultiThreaderBase.h:496
itk::MultiThreaderBase::RegionAndCallback::dimension
unsigned int dimension
Definition: itkMultiThreaderBase.h:452
itk::MultiThreaderBase::WorkUnitInfo::UserData
void * UserData
Definition: itkMultiThreaderBase.h:294
itk::MultiThreaderBase::m_NumberOfWorkUnits
ThreadIdType m_NumberOfWorkUnits
Definition: itkMultiThreaderBase.h:463
itk::MultiThreaderBaseEnums::Threader
Threader
Definition: itkMultiThreaderBase.h:60
itk::Index::m_InternalArray
IndexValueType m_InternalArray[VDimension]
Definition: itkIndex.h:289
itk::MultiThreaderBaseEnums
enums for MultiThreaderBase
Definition: itkMultiThreaderBase.h:52
itk::MultiThreaderBase::RegionAndCallback::functor
ThreadingFunctorType functor
Definition: itkMultiThreaderBase.h:451
itkIntTypes.h
itk::MultiThreaderBaseEnums::Threader::Unknown
itk::MultiThreaderBase::RegionAndCallback
Definition: itkMultiThreaderBase.h:449
itk::MultiThreaderBaseEnums::Threader::TBB
itkObject.h
itk::MultiThreaderBaseEnums::ThreadExitCode::ITK_PROCESS_ABORTED_EXCEPTION
itk::Size::m_InternalArray
SizeValueType m_InternalArray[VDimension]
Definition: itkSize.h:230
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:443
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::IndexValueType
signed long IndexValueType
Definition: itkIntTypes.h:90
itk::MultiThreaderBaseEnums::ThreadExitCode::STD_EXCEPTION
itkGetGlobalDeclarationMacro
#define itkGetGlobalDeclarationMacro(Type, VarName)
Definition: itkSingletonMacro.h:34
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:326
itk::MultiThreaderBase::m_MaximumNumberOfThreads
ThreadIdType m_MaximumNumberOfThreads
Definition: itkMultiThreaderBase.h:473
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:293
itk::MultiThreaderBase::ParallelizeImageRegion
ITK_TEMPLATE_EXPORT void ParallelizeImageRegion(const ImageRegion< VDimension > &requestedRegion, TemplatedThreadingFunctorType< VDimension > funcP, ProcessObject *filter)
Definition: itkMultiThreaderBase.h:345
itk::ProgressReporter
Implements progress tracking for a filter.
Definition: itkProgressReporter.h:60
itk::MultiThreaderBase::ArrayCallback::functor
ArrayThreadingFunctorType functor
Definition: itkMultiThreaderBase.h:440
itk::MultiThreaderBase::ParallelizeImageRegionRestrictDirection
ITK_TEMPLATE_EXPORT void ParallelizeImageRegionRestrictDirection(unsigned int restrictedDirection, const ImageRegion< VDimension > &requestedRegion, TemplatedThreadingFunctorType< VDimension > funcP, ProcessObject *filter)
Definition: itkMultiThreaderBase.h:371
itk::MultiThreaderBase::RegionAndCallback::filter
ProcessObject * filter
Definition: itkMultiThreaderBase.h:456
itk::MultiThreaderBase::ThreaderTypeToString
static std::string ThreaderTypeToString(ThreaderEnum threader)
Definition: itkMultiThreaderBase.h:180
itk::MultiThreaderBaseEnums::Threader::Platform
itk::MultiThreaderBase::RegionAndCallback::pixelCount
SizeValueType pixelCount
Definition: itkMultiThreaderBase.h:455
itk::MultiThreaderBase::WorkUnitInfo::WorkUnitID
ThreadIdType WorkUnitID
Definition: itkMultiThreaderBase.h:292
itk::MultiThreaderBaseEnums::ThreadExitCode::SUCCESS
itk::SizeValueType
unsigned long SizeValueType
Definition: itkIntTypes.h:83
itk::MultiThreaderBase::ArrayThreadingFunctorType
std::function< void(SizeValueType)> ArrayThreadingFunctorType
Definition: itkMultiThreaderBase.h:327