ITK 6.0.0
Insight Toolkit
 
Loading...
Searching...
No Matches
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
44namespace itk
45{
46
84// Define how to print enumeration
85extern ITKCommon_EXPORT std::ostream &
86 operator<<(std::ostream & out, const MultiThreaderBaseEnums::Threader value);
87extern ITKCommon_EXPORT std::ostream &
88 operator<<(std::ostream & out, const MultiThreaderBaseEnums::ThreadExitCode value);
89
103
104struct MultiThreaderBaseGlobals;
105class ProcessObject;
106
107class ITKCommon_EXPORT MultiThreaderBase : public Object
108{
109public:
110 ITK_DISALLOW_COPY_AND_MOVE(MultiThreaderBase);
111
117
119 static Pointer
121
123 itkOverrideGetNameOfClassMacro(MultiThreaderBase);
124
129 virtual void
131 itkGetConstMacro(MaximumNumberOfThreads, ThreadIdType);
137 virtual void
139 itkGetConstMacro(NumberOfWorkUnits, ThreadIdType);
141 virtual void
142 SetUpdateProgress(bool updates);
143 itkGetConstMacro(UpdateProgress, bool);
144
151 static void
153 static ThreadIdType
162 itkLegacyMacro(static void SetGlobalDefaultUseThreadPool(const bool GlobalDefaultUseThreadPool);)
163 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 Single = ThreaderEnum::Single;
173 static constexpr ThreaderEnum Last = ThreaderEnum::Last;
174 static constexpr ThreaderEnum Unknown = ThreaderEnum::Unknown;
175#endif
176
178 static ThreaderEnum
179 ThreaderTypeFromString(std::string threaderString);
180
182 static std::string
184 {
185 switch (threader)
186 {
187 case ThreaderEnum::Platform:
188 return "Platform";
189 case ThreaderEnum::Pool:
190 return "Pool";
191 case ThreaderEnum::TBB:
192 return "TBB";
193 case ThreaderEnum::Single:
194 return "Single";
195 case ThreaderEnum::Unknown:
196 default:
197 return "Unknown";
198 }
199 }
200
213 static void
215 static ThreaderEnum
223 static void
225 static ThreadIdType
228
237 static void
239 static ThreadIdType
242#if !defined(ITK_LEGACY_REMOVE)
246 itkLegacyMacro(virtual void SetNumberOfThreads(ThreadIdType numberOfThreads))
247 {
248 this->SetMaximumNumberOfThreads(numberOfThreads);
249 this->SetNumberOfWorkUnits(this->GetMaximumNumberOfThreads()); // Might be clamped
250 }
251 itkLegacyMacro(virtual ThreadIdType GetNumberOfThreads())
252 {
253 return this->GetNumberOfWorkUnits();
254 }
265 // clang-format off
266ITK_GCC_PRAGMA_DIAG_PUSH()
267ITK_GCC_PRAGMA_DIAG(ignored "-Wattributes")
268 // clang-format on
269# ifdef ITK_LEGACY_SILENT
270 struct ThreadInfoStruct
271# else
272 struct [[deprecated("Use WorkUnitInfo, ThreadInfoStruct is deprecated since ITK 5.0")]] ThreadInfoStruct
273# endif
274 {
275 ThreadIdType ThreadID;
276 ThreadIdType NumberOfThreads;
277 void * UserData;
278 ThreadFunctionType ThreadFunction;
279 enum
280 {
281 SUCCESS,
282 ITK_EXCEPTION,
283 ITK_PROCESS_ABORTED_EXCEPTION,
284 STD_EXCEPTION,
285 UNKNOWN
286 } ThreadExitCode;
287 };
288 // clang-format off
289ITK_GCC_PRAGMA_DIAG_POP()
290 // clang-format on
292#endif // ITK_LEGACY_REMOVE
293
301 {
304 void * UserData;
308#if !defined(ITK_LEGACY_REMOVE)
309 using ThreadExitCodeType = ThreadExitCodeEnum;
310 static constexpr ThreadExitCodeEnum SUCCESS = ThreadExitCodeEnum::SUCCESS;
311 static constexpr ThreadExitCodeEnum ITK_EXCEPTION = ThreadExitCodeEnum::ITK_EXCEPTION;
312 static constexpr ThreadExitCodeEnum ITK_PROCESS_ABORTED_EXCEPTION =
313 ThreadExitCodeEnum::ITK_PROCESS_ABORTED_EXCEPTION;
314 static constexpr ThreadExitCodeEnum STD_EXCEPTION = ThreadExitCodeEnum::STD_EXCEPTION;
315 static constexpr ThreadExitCodeEnum UNKNOWN = ThreadExitCodeEnum::UNKNOWN;
316#endif
317 };
318
323 virtual void
325
330 virtual void
332
334 void
336
337#ifndef ITK_FUTURE_LEGACY_REMOVE
338 // `TemplatedThreadingFunctorType` was previously used to declare the `funcP` parameter of `ParallelizeImageRegion`
339 // and `ParallelizeImageRegionRestrictDirection` template member functions.
340 template <unsigned int VDimension>
341 using TemplatedThreadingFunctorType [[deprecated]] = std::function<void(const ImageRegion<VDimension> &)>;
342#endif
343
344 using ThreadingFunctorType = std::function<void(const IndexValueType index[], const SizeValueType size[])>;
345 using ArrayThreadingFunctorType = std::function<void(SizeValueType)>;
346
352 virtual void
354 SizeValueType lastIndexPlus1,
356 ProcessObject * filter);
357
363 template <unsigned int VDimension, typename TFunction>
364 ITK_TEMPLATE_EXPORT void
365 ParallelizeImageRegion(const ImageRegion<VDimension> & requestedRegion, TFunction funcP, ProcessObject * filter)
366 {
368 VDimension,
369 requestedRegion.GetIndex().m_InternalArray,
370 requestedRegion.GetSize().m_InternalArray,
371 [&funcP](const IndexValueType index[], const SizeValueType size[]) {
372 ImageRegion<VDimension> region;
373 for (unsigned int d = 0; d < VDimension; ++d)
374 {
375 region.SetIndex(d, index[d]);
376 region.SetSize(d, size[d]);
377 }
378 funcP(region);
379 },
380 filter);
381 }
382
386 template <unsigned int VDimension, typename TFunction>
387 ITK_TEMPLATE_EXPORT void
388 ParallelizeImageRegionRestrictDirection(unsigned int restrictedDirection,
389 const ImageRegion<VDimension> & requestedRegion,
390 TFunction funcP,
391 ProcessObject * filter)
392 {
393 if constexpr (VDimension <= 1) // Cannot split, no parallelization
394 {
395
396 const ProgressReporter progress(filter, 0, requestedRegion.GetNumberOfPixels());
397 funcP(requestedRegion);
398 }
399 else // Can split, parallelize!
400 {
401 constexpr unsigned int SplitDimension = VDimension - 1;
402
403 Index<SplitDimension> splitIndex{};
404 Size<SplitDimension> splitSize{};
405 for (unsigned int splitDimension = 0, dimension = 0; dimension < VDimension; ++dimension)
406 {
407 if (dimension != restrictedDirection)
408 {
409 splitIndex[splitDimension] = requestedRegion.GetIndex(dimension);
410 splitSize[splitDimension] = requestedRegion.GetSize(dimension);
411 ++splitDimension;
412 }
413 }
414
416 SplitDimension,
417 splitIndex.m_InternalArray,
418 splitSize.m_InternalArray,
419 [restrictedDirection, &requestedRegion, &funcP](const IndexValueType index[], const SizeValueType size[]) {
420 ImageRegion<VDimension> restrictedRequestedRegion;
421 restrictedRequestedRegion.SetIndex(restrictedDirection, requestedRegion.GetIndex(restrictedDirection));
422 restrictedRequestedRegion.SetSize(restrictedDirection, requestedRegion.GetSize(restrictedDirection));
423 for (unsigned int splitDimension = 0, dimension = 0; dimension < VDimension; ++dimension)
424 {
425 if (dimension != restrictedDirection)
426 {
427 restrictedRequestedRegion.SetIndex(dimension, index[splitDimension]);
428 restrictedRequestedRegion.SetSize(dimension, size[splitDimension]);
429 ++splitDimension;
430 }
431 }
432 funcP(restrictedRequestedRegion);
433 },
434 filter);
435 }
436 }
437
440 virtual void
441 ParallelizeImageRegion(unsigned int dimension,
442 const IndexValueType index[],
443 const SizeValueType size[],
445 ProcessObject * filter);
446
447protected:
450 void
451 PrintSelf(std::ostream & os, Indent indent) const override;
452
460
463
472
475
478
488
496 SingleMethodProxy(void * arg);
497
500
502 void * m_SingleData{ nullptr };
503
504private:
505 static void
507 static ThreaderEnum
509
511 itkGetGlobalDeclarationMacro(MultiThreaderBaseGlobals, PimplGlobals);
512
513 std::atomic<bool> m_UpdateProgress{ true };
514
515 static MultiThreaderBaseGlobals * m_PimplGlobals;
519 friend class ProcessObject;
520
522 static ThreadIdType
524};
525
526
527} // namespace itk
528
529#endif
An image region represents a structured region of data.
SizeValueType GetNumberOfPixels() const
const IndexType & GetIndex() const
const SizeType & GetSize() const
Control indentation during Print() invocation.
Definition itkIndent.h:53
enums for MultiThreaderBase
static ITK_THREAD_RETURN_FUNCTION_CALL_CONVENTION ParallelizeArrayHelper(void *arg)
static bool GetGlobalDefaultUseThreadPool()
ITK_TEMPLATE_EXPORT void ParallelizeImageRegion(const ImageRegion< VDimension > &requestedRegion, TFunction funcP, ProcessObject *filter)
MultiThreaderBaseEnums::Threader ThreaderEnum
ITK_TEMPLATE_EXPORT void ParallelizeImageRegionRestrictDirection(unsigned int restrictedDirection, const ImageRegion< VDimension > &requestedRegion, TFunction funcP, ProcessObject *filter)
virtual void SetMaximumNumberOfThreads(ThreadIdType numberOfThreads)
void SetSingleMethodAndExecute(ThreadFunctionType func, void *data)
static void SetGlobalDefaultUseThreadPool(const bool GlobalDefaultUseThreadPool)
static std::string ThreaderTypeToString(ThreaderEnum threader)
static ThreaderEnum GetGlobalDefaultThreaderPrivate()
static Pointer New()
static void SetGlobalDefaultThreaderPrivate(ThreaderEnum threaderType)
static ITK_THREAD_RETURN_FUNCTION_CALL_CONVENTION SingleMethodProxy(void *arg)
static ThreaderEnum GetGlobalDefaultThreader()
static void SetGlobalDefaultThreader(ThreaderEnum threaderType)
SmartPointer< Self > Pointer
static MultiThreaderBaseGlobals * m_PimplGlobals
static ThreaderEnum ThreaderTypeFromString(std::string threaderString)
ThreadFunctionType m_SingleMethod
static ThreadIdType GetGlobalMaximumNumberOfThreads()
virtual void SetNumberOfWorkUnits(ThreadIdType numberOfWorkUnits)
SmartPointer< const Self > ConstPointer
virtual void SetUpdateProgress(bool updates)
static ThreadIdType GetGlobalDefaultNumberOfThreadsByPlatform()
void PrintSelf(std::ostream &os, Indent indent) const override
virtual void SetSingleMethod(ThreadFunctionType, void *data)=0
itkGetGlobalDeclarationMacro(MultiThreaderBaseGlobals, PimplGlobals)
virtual void ParallelizeImageRegion(unsigned int dimension, const IndexValueType index[], const SizeValueType size[], ThreadingFunctorType funcP, ProcessObject *filter)
static ITK_THREAD_RETURN_FUNCTION_CALL_CONVENTION ParallelizeImageRegionHelper(void *arg)
static ThreadIdType GetGlobalDefaultNumberOfThreads()
virtual ThreadIdType GetMaximumNumberOfThreads() const
virtual void SingleMethodExecute()=0
std::function< void(SizeValueType)> ArrayThreadingFunctorType
~MultiThreaderBase() override
std::function< void(const IndexValueType index[], const SizeValueType size[])> ThreadingFunctorType
static void SetGlobalMaximumNumberOfThreads(ThreadIdType val)
static void SetGlobalDefaultNumberOfThreads(ThreadIdType val)
virtual void ParallelizeArray(SizeValueType firstIndex, SizeValueType lastIndexPlus1, ArrayThreadingFunctorType aFunc, ProcessObject *filter)
std::atomic< bool > m_UpdateProgress
static void SetGlobalDefaultWorkUnitPerThreadRatio(ThreadIdType val)
static ThreadIdType GetGlobalDefaultWorkUnitPerThreadRatio()
The base class for all process objects (source, filters, mappers) in the Insight data processing pipe...
Implements progress tracking for a filter.
Implements transparent reference counting.
The "itk" namespace contains all Insight Segmentation and Registration Toolkit (ITK) classes....
unsigned int ThreadIdType
Definition itkIntTypes.h:98
unsigned long SizeValueType
Definition itkIntTypes.h:82
void(*)(void *) ThreadFunctionType
ITKCommon_EXPORT std::ostream & operator<<(std::ostream &out, AnatomicalOrientation::CoordinateEnum value)
ITK_THREAD_RETURN_TYPE ITK_THREAD_RETURN_FUNCTION_CALL_CONVENTION
long IndexValueType
Definition itkIntTypes.h:85
Represent a n-dimensional index in a n-dimensional image.
Definition itkIndex.h:69
IndexValueType m_InternalArray[VDimension]
Definition itkIndex.h:289
MultiThreaderBaseEnums::ThreadExitCode ThreadExitCodeEnum
Represent a n-dimensional size (bounds) of a n-dimensional image.
Definition itkSize.h:70
SizeValueType m_InternalArray[VDimension]
Definition itkSize.h:242