diff --git a/Modules/Core/Common/include/itkDomainThreader.h b/Modules/Core/Common/include/itkDomainThreader.h index 192803b7293..1207a98fb84 100644 --- a/Modules/Core/Common/include/itkDomainThreader.h +++ b/Modules/Core/Common/include/itkDomainThreader.h @@ -48,7 +48,7 @@ namespace itk * Since a threaded operation is relatively complex compared to a simple serial * operation, a class instead of a simple method is required. Inside this * class, the method to partition the data is handled, the logic for - * determining the number of threads is determined, and operations surrounding + * deciding the number of work units is determined, and operations surrounding * the threading are encapsulated into the class with the * \c DetermineNumberOfWorkUnitsToUse, \c BeforeThreadedExecution, \c ThreadedExecution, * and \c AfterThreadedExecution virtual methods. @@ -90,22 +90,35 @@ class ITK_TEMPLATE_EXPORT DomainThreader: public Object void Execute( AssociateType * enclosingClass, const DomainType & domain ); /** Set/Get the DomainPartitioner. */ - itkSetObjectMacro( DomainPartitioner, DomainPartitionerType ); - itkGetModifiableObjectMacro(DomainPartitioner, DomainPartitionerType ); + itkSetObjectMacro( DomainPartitioner, DomainPartitionerType ); + itkGetModifiableObjectMacro( DomainPartitioner, DomainPartitionerType ); - /** Accessor for number of threads that were actually used in the last + /** Accessor for number of work units that were actually used in the last * ThreadedExecution. */ itkGetConstMacro( NumberOfWorkUnitsUsed, ThreadIdType ); /** Return the multithreader used by this class. */ MultiThreaderBase * GetMultiThreader() const; - /** Convenience methods to set/get the maximum number of work units to use. - * \warning When setting the maximum number of work units, it will be clamped by - * itk::MultiThreaderBase::GetGlobalMaximumNumberOfThreads() and ITK_MAX_THREADS. + /** Convenience methods to set/get the desired number of work units to use. + * \warning When setting the desired number of work units, it might be clamped by + * itk::MultiThreaderBase::GetGlobalMaximumNumberOfThreads(). * */ - ThreadIdType GetMaximumNumberOfThreads() const; - void SetMaximumNumberOfThreads( const ThreadIdType threads ); + ThreadIdType GetNumberOfWorkUnits() const + { + return this->m_MultiThreader->GetNumberOfWorkUnits(); + } + void SetNumberOfWorkUnits( const ThreadIdType workUnits ); + + /** Convenience methods to set/get the maximum number of threads to use. + * \warning When setting the maximum number of threads, it will be clamped by + * itk::MultiThreaderBase::GetGlobalMaximumNumberOfThreads(). + * */ + ThreadIdType GetMaximumNumberOfThreads() const + { + return this->m_MultiThreader->GetMaximumNumberOfThreads(); + } + void SetMaximumNumberOfThreads(const ThreadIdType threads); protected: DomainThreader(); @@ -154,7 +167,7 @@ class ITK_TEMPLATE_EXPORT DomainThreader: public Object DomainThreader * domainThreader; }; - /** Store the actual number of threads used, which may be less than + /** Store the actual number of work units used, which may be less than * the number allocated by the threader if the object does not split * well into that number. * This value is determined at the beginning of \c Execute(). */ diff --git a/Modules/Core/Common/include/itkDomainThreader.hxx b/Modules/Core/Common/include/itkDomainThreader.hxx index 6e025f1bbec..0765e033c13 100644 --- a/Modules/Core/Common/include/itkDomainThreader.hxx +++ b/Modules/Core/Common/include/itkDomainThreader.hxx @@ -48,11 +48,15 @@ DomainThreader< TDomainPartitioner, TAssociate > } template< typename TDomainPartitioner, typename TAssociate > -ThreadIdType +void DomainThreader< TDomainPartitioner, TAssociate > -::GetMaximumNumberOfThreads() const +::SetNumberOfWorkUnits( const ThreadIdType workUnits ) { - return this->m_MultiThreader->GetNumberOfThreads(); + if( workUnits != this->GetNumberOfWorkUnits() ) + { + this->m_MultiThreader->SetNumberOfWorkUnits( workUnits ); + this->Modified(); + }; } template< typename TDomainPartitioner, typename TAssociate > @@ -62,7 +66,7 @@ DomainThreader< TDomainPartitioner, TAssociate > { if( threads != this->GetMaximumNumberOfThreads() ) { - this->m_MultiThreader->SetNumberOfThreads( threads ); + this->m_MultiThreader->SetMaximumNumberOfThreads( threads ); this->Modified(); } } @@ -90,7 +94,7 @@ void DomainThreader< TDomainPartitioner, TAssociate > ::DetermineNumberOfWorkUnitsUsed() { - const ThreadIdType threaderNumberOfThreads = this->GetMultiThreader()->GetNumberOfThreads(); + const ThreadIdType threaderNumberOfThreads = this->GetMultiThreader()->GetNumberOfWorkUnits(); // Attempt a single dummy partition, just to get the number of subdomains actually created DomainType subdomain; @@ -102,10 +106,10 @@ DomainThreader< TDomainPartitioner, TAssociate > if( this->m_NumberOfWorkUnitsUsed < threaderNumberOfThreads ) { // If PartitionDomain is only able to create a lesser number of subdomains, - // ensure that superfluous threads aren't created + // ensure that superfluous work units aren't created // DomainThreader::SetMaximumNumberOfThreads *should* already have been called by this point, // but it's not fatal if it somehow gets called later - this->GetMultiThreader()->SetNumberOfThreads(this->m_NumberOfWorkUnitsUsed); + this->GetMultiThreader()->SetNumberOfWorkUnits(this->m_NumberOfWorkUnitsUsed); } else if( this->m_NumberOfWorkUnitsUsed > threaderNumberOfThreads ) { @@ -135,11 +139,11 @@ ITK_THREAD_RETURN_TYPE DomainThreader< TDomainPartitioner, TAssociate > ::ThreaderCallback( void* arg ) { - auto * info = static_cast(arg); + auto * info = static_cast(arg); auto * str = static_cast(info->UserData); DomainThreader *thisDomainThreader = str->domainThreader; - const ThreadIdType threadId = info->ThreadID; - const ThreadIdType threadCount = info->NumberOfThreads; + const ThreadIdType threadId = info->WorkUnitID; + const ThreadIdType threadCount = info->NumberOfWorkUnits; // Get the sub-domain to process for this thread. DomainType subdomain; diff --git a/Modules/Core/Common/include/itkImageSource.h b/Modules/Core/Common/include/itkImageSource.h index c3c7a874f04..f5a90002938 100644 --- a/Modules/Core/Common/include/itkImageSource.h +++ b/Modules/Core/Common/include/itkImageSource.h @@ -281,7 +281,7 @@ class ITK_TEMPLATE_EXPORT ImageSource * in its own specific thread. Pool and TBB multi-threaders maintain * a pool of threads (normally equal to number of processing cores) * which they use to process the pieces. This normally results - * in a single thread being reused to process multiple pieces. + * in a single thread being reused to process multiple work units. * * \sa GenerateData(), SplitRequestedRegion() */ virtual void ThreadedGenerateData(const OutputImageRegionType & outputRegionForThread, diff --git a/Modules/Core/Common/include/itkImageSource.hxx b/Modules/Core/Common/include/itkImageSource.hxx index 9c8540edaa2..85313beabc1 100644 --- a/Modules/Core/Common/include/itkImageSource.hxx +++ b/Modules/Core/Common/include/itkImageSource.hxx @@ -212,7 +212,7 @@ ImageSource const ImageRegionSplitterBase * splitter = this->GetImageRegionSplitter(); const unsigned int validThreads = splitter->GetNumberOfSplits(outputPtr->GetRequestedRegion(), this->GetNumberOfWorkUnits()); - this->GetMultiThreader()->SetNumberOfThreads(validThreads); + this->GetMultiThreader()->SetNumberOfWorkUnits(validThreads); this->GetMultiThreader()->SetSingleMethod(callbackFunction, &str); this->GetMultiThreader()->SingleMethodExecute(); @@ -238,7 +238,7 @@ ImageSource< TOutputImage > } else { - this->GetMultiThreader()->SetNumberOfThreads(this->GetNumberOfWorkUnits()); + this->GetMultiThreader()->SetNumberOfWorkUnits(this->GetNumberOfWorkUnits()); this->GetMultiThreader()->template ParallelizeImageRegion( this->GetOutput()->GetRequestedRegion(), [this](const OutputImageRegionType & outputRegionForThread) @@ -287,10 +287,10 @@ ITK_THREAD_RETURN_TYPE ImageSource< TOutputImage > ::ThreaderCallback(void *arg) { - using ThreadInfo = MultiThreaderBase::ThreadInfoStruct; + using ThreadInfo = MultiThreaderBase::WorkUnitInfo; ThreadInfo * threadInfo = static_cast(arg); - ThreadIdType threadId = threadInfo->ThreadID; - ThreadIdType threadCount = threadInfo->NumberOfThreads; + ThreadIdType threadId = threadInfo->WorkUnitID; + ThreadIdType threadCount = threadInfo->NumberOfWorkUnits; ThreadStruct *str = (ThreadStruct *)(threadInfo->UserData); // execute the actual method with appropriate output region diff --git a/Modules/Core/Common/include/itkImageToImageFilter.h b/Modules/Core/Common/include/itkImageToImageFilter.h index e5a971302b4..850092584ef 100644 --- a/Modules/Core/Common/include/itkImageToImageFilter.h +++ b/Modules/Core/Common/include/itkImageToImageFilter.h @@ -48,7 +48,7 @@ namespace itk * GenerateData(), the image processing will run in a single thread and the * implementation is responsible for allocating its output data. If a filter * provides an implementation of ThreadedGenerateData() instead, the image - * will be divided into a number of pieces, a number of threads will be + * will be divided into a number of work units, a number of threads will be * spawned, and ThreadedGenerateData() will be called in each thread. Here, * the output memory will be allocated by this superclass prior to calling * ThreadedGenerateData(). diff --git a/Modules/Core/Common/include/itkImageTransformer.hxx b/Modules/Core/Common/include/itkImageTransformer.hxx index 04b548720d9..9a31ee8f187 100644 --- a/Modules/Core/Common/include/itkImageTransformer.hxx +++ b/Modules/Core/Common/include/itkImageTransformer.hxx @@ -278,7 +278,7 @@ ImageTransformer< TInputImage > ThreadStruct str; str.Filter = this; - this->GetMultiThreader()->SetNumberOfThreads(this->GetNumberOfWorkUnits()); + this->GetMultiThreader()->SetNumberOfWorkUnits(this->GetNumberOfWorkUnits()); this->GetMultiThreader()->SetSingleMethod(callbackFunction, &str); this->GetMultiThreader()->SingleMethodExecute(); @@ -337,10 +337,10 @@ ImageTransformer< TInputImage > ThreadStruct *str; ThreadIdType total, threadId, threadCount; - threadId = ( (MultiThreaderBase::ThreadInfoStruct *)( arg ) )->ThreadID; - threadCount = ( (MultiThreaderBase::ThreadInfoStruct *)( arg ) )->NumberOfThreads; + threadId = ( (MultiThreaderBase::WorkUnitInfo *)( arg ) )->WorkUnitID; + threadCount = ( (MultiThreaderBase::WorkUnitInfo *)( arg ) )->NumberOfWorkUnits; - str = (ThreadStruct *)( ( (MultiThreaderBase::ThreadInfoStruct *)( arg ) )->UserData ); + str = (ThreadStruct *)( ( (MultiThreaderBase::WorkUnitInfo *)( arg ) )->UserData ); // execute the actual method with appropriate output region // first find out how many pieces extent can be split into. diff --git a/Modules/Core/Common/include/itkMultiThreaderBase.h b/Modules/Core/Common/include/itkMultiThreaderBase.h index 35e3b25a151..907e19ab45b 100644 --- a/Modules/Core/Common/include/itkMultiThreaderBase.h +++ b/Modules/Core/Common/include/itkMultiThreaderBase.h @@ -75,11 +75,17 @@ class ITKCommon_EXPORT MultiThreaderBase : public Object /** Run-time type information (and related methods). */ itkTypeMacro(MultiThreaderBase, Object); - /** Get/Set the number of threads to create. It will be clamped to the range + /** Get/Set the number of threads to use. It will be clamped to the range * [ 1, m_GlobalMaximumNumberOfThreads ], so the caller of this method should * check that the requested number of threads was accepted. */ - virtual void SetNumberOfThreads(ThreadIdType numberOfThreads); - itkGetConstMacro(NumberOfThreads, ThreadIdType); + virtual void SetMaximumNumberOfThreads( ThreadIdType numberOfThreads ); + itkGetConstMacro( MaximumNumberOfThreads, ThreadIdType ); + + /** Get/Set the number of work units to create. It might be clamped to the range + * [ 1, SomeMaximumNumber ], so the caller of this method should + * check that the requested number of work units was accepted. */ + virtual void SetNumberOfWorkUnits( ThreadIdType numberOfWorkUnits ); + itkGetConstMacro( NumberOfWorkUnits, ThreadIdType ); /** Set/Get the maximum number of threads to use when multithreading. It * will be clamped to the range [ 1, ITK_MAX_THREADS ] because several arrays @@ -149,27 +155,33 @@ class ITKCommon_EXPORT MultiThreaderBase : public Object /** This is the structure that is passed to the thread that is * created from the SingleMethodExecute. It is passed in as a void *, * and it is up to the method to cast correctly and extract the information. - * The ThreadID is a number between 0 and NumberOfThreads-1 that - * indicates the id of this thread. The UserData is the + * The WorkUnitID is a number between 0 and NumberOfWorkUnits-1 that + * indicates the id of this work unit. The UserData is the * (void *)arg passed into the SetSingleMethod. */ - struct ThreadInfoStruct - { - ThreadIdType ThreadID; - ThreadIdType NumberOfThreads; - void* UserData; + struct WorkUnitInfo + { + ThreadIdType WorkUnitID; + ThreadIdType NumberOfWorkUnits; + void* UserData; ThreadFunctionType ThreadFunction; - enum { SUCCESS, ITK_EXCEPTION, ITK_PROCESS_ABORTED_EXCEPTION, STD_EXCEPTION, UNKNOWN } ThreadExitCode; - }; + enum + { + SUCCESS, + ITK_EXCEPTION, + ITK_PROCESS_ABORTED_EXCEPTION, + STD_EXCEPTION, + UNKNOWN + } ThreadExitCode; + }; /** Execute the SingleMethod (as define by SetSingleMethod) using - * m_NumberOfThreads threads. As a side effect the m_NumberOfThreads will be + * m_NumberOfWorkUnits threads. As a side effect the m_NumberOfWorkUnits will be * checked against the current m_GlobalMaximumNumberOfThreads and clamped if * necessary. */ virtual void SingleMethodExecute() = 0; /** Set the SingleMethod to f() and the UserData field of the - * ThreadInfoStruct that is passed to it will be data. - * This method (and all the methods passed to SetMultipleMethod) + * WorkUnitInfo that is passed to it will be data. This method * must be of type itkThreadFunctionType and must take a single argument of * type void *. */ virtual void SetSingleMethod(ThreadFunctionType, void *data) = 0; @@ -264,23 +276,25 @@ class ITKCommon_EXPORT MultiThreaderBase : public Object static ITK_THREAD_RETURN_TYPE ParallelizeImageRegionHelper(void *arg); + /** The number of work units to create. */ + ThreadIdType m_NumberOfWorkUnits; + /** The number of threads to use. - * The m_NumberOfThreads must always be less than or equal to + * The m_MaximumNumberOfThreads must always be less than or equal to * the m_GlobalMaximumNumberOfThreads before it is used during the execution - * of a threaded method. Its value is clamped in the SingleMethodExecute() - * and MultipleMethodExecute(). Its value is initialized to + * of a threaded method. Its value is initialized to * m_GlobalDefaultNumberOfThreads at construction time. Its value is clamped * to the current m_GlobalMaximumNumberOfThreads in the - * SingleMethodExecute() and MultipleMethodExecute() methods. + * SingleMethodExecute() method. */ - ThreadIdType m_NumberOfThreads; + ThreadIdType m_MaximumNumberOfThreads; /** Static function used as a "proxy callback" by multi-threaders. The - * threading library will call this routine for each thread, which - * will delegate the control to the prescribed SingleMethod. This - * routine acts as an intermediary between the multi-threaders and the - * user supplied callback (SingleMethod) in order to catch any - * exceptions thrown by the threads. */ + * threading library will call this routine for each thread, which + * will delegate the control to the prescribed SingleMethod. This + * routine acts as an intermediary between the multi-threaders and the + * user supplied callback (SingleMethod) in order to catch any + * exceptions thrown by the threads. */ static ITK_THREAD_RETURN_TYPE SingleMethodProxy(void *arg); /** The method to invoke. */ @@ -300,5 +314,5 @@ class ITKCommon_EXPORT MultiThreaderBase : public Object ITKCommon_EXPORT std::ostream& operator << (std::ostream& os, const MultiThreaderBase::ThreaderType& threader); -} // end namespace itk +} // end namespace itk #endif diff --git a/Modules/Core/Common/include/itkPlatformMultiThreader.h b/Modules/Core/Common/include/itkPlatformMultiThreader.h index 1c965ac19b4..ed07cccdf26 100644 --- a/Modules/Core/Common/include/itkPlatformMultiThreader.h +++ b/Modules/Core/Common/include/itkPlatformMultiThreader.h @@ -105,26 +105,26 @@ It can affect all MultiThreaderBase's derived classes in ITK"); #endif /** Execute the SingleMethod (as define by SetSingleMethod) using - * m_NumberOfThreads threads. As a side effect the m_NumberOfThreads will be + * m_NumberOfWorkUnits threads. As a side effect the m_NumberOfWorkUnits will be * checked against the current m_GlobalMaximumNumberOfThreads and clamped if * necessary. */ void SingleMethodExecute() override; /** Execute the MultipleMethods (as define by calling SetMultipleMethod for - * each of the required m_NumberOfThreads methods) using m_NumberOfThreads - * threads. As a side effect the m_NumberOfThreads will be checked against the + * each of the required m_NumberOfWorkUnits methods) using m_NumberOfWorkUnits + * threads. As a side effect the m_NumberOfWorkUnits will be checked against the * current m_GlobalMaximumNumberOfThreads and clamped if necessary. */ itkLegacyMacro(void MultipleMethodExecute()); /** Set the SingleMethod to f() and the UserData field of the - * ThreadInfoStruct that is passed to it will be data. + * WorkUnitInfo that is passed to it will be data. * This method (and all the methods passed to SetMultipleMethod) * must be of type itkThreadFunctionType and must take a single argument of * type void *. */ void SetSingleMethod(ThreadFunctionType, void *data) override; /** Set the MultipleMethod at the given index to f() and the UserData - * field of the ThreadInfoStruct that is passed to it will be data. */ + * field of the WorkUnitInfo that is passed to it will be data. */ itkLegacyMacro(void SetMultipleMethod(ThreadIdType index, ThreadFunctionType, void *data)); /** Create a new thread for the given function. Return a thread id @@ -137,7 +137,10 @@ It can affect all MultiThreaderBase's derived classes in ITK"); * Deprecated. Use C++11 thread support instead. */ itkLegacyMacro(void TerminateThread(ThreadIdType thread_id)); - struct ThreadInfoStruct: MultiThreaderBase::ThreadInfoStruct + virtual void SetMaximumNumberOfThreads( ThreadIdType numberOfThreads ) override; + virtual void SetNumberOfWorkUnits( ThreadIdType numberOfWorkUnits ) override; + + struct WorkUnitInfo: MultiThreaderBase::WorkUnitInfo { int *ActiveFlag; MutexLock::Pointer ActiveFlagLock; @@ -152,14 +155,14 @@ It can affect all MultiThreaderBase's derived classes in ITK"); /** An array of thread info containing a thread id * (0, 1, 2, .. ITK_MAX_THREADS-1), the thread count, and a pointer * to void so that user data can be passed to each thread. */ - ThreadInfoStruct m_ThreadInfoArray[ITK_MAX_THREADS]; + WorkUnitInfo m_ThreadInfoArray[ITK_MAX_THREADS]; /** Storage of MutexFunctions and ints used to control spawned * threads and the spawned thread ids. */ int m_SpawnedThreadActiveFlag[ITK_MAX_THREADS]; MutexLock::Pointer m_SpawnedThreadActiveFlagLock[ITK_MAX_THREADS]; ThreadProcessIdType m_SpawnedThreadProcessID[ITK_MAX_THREADS]; - ThreadInfoStruct m_SpawnedThreadInfoArray[ITK_MAX_THREADS]; + WorkUnitInfo m_SpawnedThreadInfoArray[ITK_MAX_THREADS]; #if !defined ( ITK_LEGACY_REMOVE ) /** The methods to invoke. */ @@ -170,7 +173,7 @@ It can affect all MultiThreaderBase's derived classes in ITK"); #endif /** spawn a new thread for the SingleMethod */ - ThreadProcessIdType SpawnDispatchSingleMethodThread(ThreadInfoStruct *); + ThreadProcessIdType SpawnDispatchSingleMethodThread(WorkUnitInfo *); /** wait for a thread in the threadpool to finish work */ void SpawnWaitForSingleMethodThread(ThreadProcessIdType); diff --git a/Modules/Core/Common/include/itkPoolMultiThreader.h b/Modules/Core/Common/include/itkPoolMultiThreader.h index 199f571c622..03adbe7b31e 100644 --- a/Modules/Core/Common/include/itkPoolMultiThreader.h +++ b/Modules/Core/Common/include/itkPoolMultiThreader.h @@ -51,7 +51,7 @@ class ITKCommon_EXPORT PoolMultiThreader : public MultiThreaderBase /** Standard class type aliases. */ using Self = PoolMultiThreader; - using Superclass = Object; + using Superclass = MultiThreaderBase; using Pointer = SmartPointer; using ConstPointer = SmartPointer; @@ -59,24 +59,28 @@ class ITKCommon_EXPORT PoolMultiThreader : public MultiThreaderBase itkNewMacro(Self); /** Run-time type information (and related methods). */ - itkTypeMacro(PoolMultiThreader, Object); + itkTypeMacro(PoolMultiThreader, MultiThreaderBase); /** Execute the SingleMethod (as define by SetSingleMethod) using - * m_NumberOfThreads threads. As a side effect the m_NumberOfThreads will be + * m_NumberOfWorkUnits work units. As a side effect the m_NumberOfWorkUnits will be * checked against the current m_GlobalMaximumNumberOfThreads and clamped if * necessary. */ void SingleMethodExecute() override; /** Set the SingleMethod to f() and the UserData field of the - * ThreadInfoStruct that is passed to it will be data. + * WorkUnitInfo that is passed to it will be data. * This method must be of type itkThreadFunctionType and * must take a single argument of type void. */ void SetSingleMethod(ThreadFunctionType, void *data) override; + /** Set the number of threads to use. PoolMultiThreader + * can only INCREASE its number of threads. */ + virtual void SetMaximumNumberOfThreads( ThreadIdType numberOfThreads ) override; + using JobSemaphoreType = ThreadPool::Semaphore; - struct ThreadPoolInfoStruct :ThreadInfoStruct + struct ThreadPoolInfoStruct :WorkUnitInfo { JobSemaphoreType Semaphore; }; diff --git a/Modules/Core/Common/include/itkProcessObject.h b/Modules/Core/Common/include/itkProcessObject.h index ffd76ea5863..75fddbdfcea 100644 --- a/Modules/Core/Common/include/itkProcessObject.h +++ b/Modules/Core/Common/include/itkProcessObject.h @@ -439,7 +439,7 @@ class ITKCommon_EXPORT ProcessObject:public Object itkGetConstReferenceMacro(ReleaseDataBeforeUpdateFlag, bool); itkBooleanMacro(ReleaseDataBeforeUpdateFlag); - /** Get/Set the number of threads to create when executing. */ + /** Get/Set the number of work units to create when executing. */ itkSetClampMacro(NumberOfWorkUnits, ThreadIdType, 1, ITK_MAX_THREADS); itkGetConstReferenceMacro(NumberOfWorkUnits, ThreadIdType); diff --git a/Modules/Core/Common/include/itkTBBMultiThreader.h b/Modules/Core/Common/include/itkTBBMultiThreader.h index 105852d3de8..804604d9885 100644 --- a/Modules/Core/Common/include/itkTBBMultiThreader.h +++ b/Modules/Core/Common/include/itkTBBMultiThreader.h @@ -42,7 +42,7 @@ class ITKCommon_EXPORT TBBMultiThreader : public MultiThreaderBase /** Standard class type aliases. */ using Self = TBBMultiThreader; - using Superclass = Object; + using Superclass = MultiThreaderBase; using Pointer = SmartPointer; using ConstPointer = SmartPointer; @@ -50,17 +50,21 @@ class ITKCommon_EXPORT TBBMultiThreader : public MultiThreaderBase itkNewMacro(Self); /** Run-time type information (and related methods). */ - itkTypeMacro(TBBMultiThreader, Object); + itkTypeMacro(TBBMultiThreader, MultiThreaderBase); + /** Get/Set the number of work units to create. TBBMultiThreader + * does not limit the number of work units. This number is + * only respected by SetSingleMethod/SingleMethodExecute. */ + virtual void SetNumberOfWorkUnits( ThreadIdType numberOfWorkUnits ) override; /** Execute the SingleMethod (as define by SetSingleMethod) using - * m_NumberOfThreads threads. As a side effect the m_NumberOfThreads will be + * m_NumberOfWorkUnits work units. As a side effect the m_NumberOfWorkUnits will be * checked against the current m_GlobalMaximumNumberOfThreads and clamped if * necessary. */ void SingleMethodExecute() override; /** Set the SingleMethod to f() and the UserData field of the - * ThreadInfoStruct that is passed to it will be data. + * WorkUnitInfo that is passed to it will be data. * This method must be of type itkThreadFunctionType and * must take a single argument of type void. */ void SetSingleMethod(ThreadFunctionType, void *data) override; diff --git a/Modules/Core/Common/include/itkThreadPool.h b/Modules/Core/Common/include/itkThreadPool.h index e15021201f4..9f701655fd6 100644 --- a/Modules/Core/Common/include/itkThreadPool.h +++ b/Modules/Core/Common/include/itkThreadPool.h @@ -36,20 +36,13 @@ namespace itk * \class ThreadPool * \brief Thread pool maintains a constant number of threads. * - * Thread pool is called and initialized from within the MultiThreader. + * Thread pool is called and initialized from within the PoolMultiThreader. * Initially the thread pool is started with GlobalDefaultNumberOfThreads. * The ThreadJob class is used to submit jobs to the thread pool. The ThreadJob's * necessary members need to be set and then the ThreadJob can be passed to the * ThreadPool by calling its AddWork method. * One can then wait for the job by calling the WaitForJob method. * - * When thread pool is in use by the MultiThreader, invoking SetNumberOfThreads - * on MultiThreader will only increase the number of jobs submitted to the - * ThreadPool, it will not increase the number of threads. This trick can be - * used to increase the number of chunks, which can help load balancing in - * case the algorithm takes more time for some parts of the image, and there - * is relatively small overhead for chunking (splitting the image for processing). - * * If more threads are required, e.g. in case when Barrier is used, * AddThreads method should be invoked. * @@ -92,6 +85,11 @@ class ITKCommon_EXPORT ThreadPool : public Object /** Can call this method if we want to add extra threads to the pool. */ void AddThreads(ThreadIdType count); + ThreadIdType GetMaximumNumberOfThreads() const + { + return m_Threads.size(); + } + /** The approximate number of idle threads. */ int GetNumberOfCurrentlyIdleThreads() const; diff --git a/Modules/Core/Common/src/itkMemoryUsageObserver.cxx b/Modules/Core/Common/src/itkMemoryUsageObserver.cxx index e24eef91a26..25178089516 100644 --- a/Modules/Core/Common/src/itkMemoryUsageObserver.cxx +++ b/Modules/Core/Common/src/itkMemoryUsageObserver.cxx @@ -149,7 +149,7 @@ typedef struct _SYSTEM_THREADS { typedef struct _SYSTEM_PROCESSES { // Information Class 5 ULONG NextEntryDelta; - ULONG ThreadCount; + ULONG MaximumNumberOfThreads; ULONG Reserved1[6]; LARGE_INTEGER CreateTime; LARGE_INTEGER UserTime; diff --git a/Modules/Core/Common/src/itkMultiThreaderBase.cxx b/Modules/Core/Common/src/itkMultiThreaderBase.cxx index cf40ac78e06..f902b908a96 100644 --- a/Modules/Core/Common/src/itkMultiThreaderBase.cxx +++ b/Modules/Core/Common/src/itkMultiThreaderBase.cxx @@ -339,20 +339,35 @@ void MultiThreaderBase::SetGlobalDefaultNumberOfThreads(ThreadIdType val) } -void MultiThreaderBase::SetNumberOfThreads(ThreadIdType numberOfThreads) +void MultiThreaderBase::SetMaximumNumberOfThreads( ThreadIdType numberOfThreads ) { - if( m_NumberOfThreads == numberOfThreads && + if( m_MaximumNumberOfThreads == numberOfThreads && numberOfThreads <= m_MultiThreaderBaseGlobals->m_GlobalMaximumNumberOfThreads ) { return; } - m_NumberOfThreads = numberOfThreads; + m_MaximumNumberOfThreads = numberOfThreads; // clamp between 1 and m_MultiThreaderBaseGlobals->m_GlobalMaximumNumberOfThreads - m_NumberOfThreads = std::min( m_NumberOfThreads, - m_MultiThreaderBaseGlobals->m_GlobalMaximumNumberOfThreads ); - m_NumberOfThreads = std::max( m_NumberOfThreads, NumericTraits::OneValue() ); + m_MaximumNumberOfThreads = std::min( m_MaximumNumberOfThreads, m_MultiThreaderBaseGlobals->m_GlobalMaximumNumberOfThreads ); + m_MaximumNumberOfThreads = std::max( m_MaximumNumberOfThreads, NumericTraits< ThreadIdType >::OneValue() ); +} + +void MultiThreaderBase::SetNumberOfWorkUnits(ThreadIdType numberOfWorkUnits) +{ + if( m_NumberOfWorkUnits == numberOfWorkUnits && + numberOfWorkUnits <= m_MultiThreaderBaseGlobals->m_GlobalMaximumNumberOfThreads ) + { + return; + } + + m_NumberOfWorkUnits = numberOfWorkUnits; + + // clamp between 1 and m_MultiThreaderBaseGlobals->m_GlobalMaximumNumberOfThreads + m_NumberOfWorkUnits = std::min( m_NumberOfWorkUnits, + m_MultiThreaderBaseGlobals->m_GlobalMaximumNumberOfThreads ); + m_NumberOfWorkUnits = std::max( m_NumberOfWorkUnits, NumericTraits::OneValue() ); } @@ -402,7 +417,8 @@ MultiThreaderBase::MultiThreaderBase() : m_SingleMethod{ nullptr } , m_SingleData{ nullptr } { - m_NumberOfThreads = MultiThreaderBase::GetGlobalDefaultNumberOfThreads(); + m_MaximumNumberOfThreads = MultiThreaderBase::GetGlobalDefaultNumberOfThreads(); + m_NumberOfWorkUnits = m_MaximumNumberOfThreads; } MultiThreaderBase::~MultiThreaderBase() @@ -413,30 +429,30 @@ ITK_THREAD_RETURN_TYPE MultiThreaderBase ::SingleMethodProxy(void *arg) { - // grab the ThreadInfoStruct originally prescribed - auto * threadInfoStruct = static_cast( arg ); + // grab the WorkUnitInfo originally prescribed + auto * threadInfoStruct = static_cast( arg ); // execute the user specified threader callback, catching any exceptions try { ( *threadInfoStruct->ThreadFunction )(arg); - threadInfoStruct->ThreadExitCode = ThreadInfoStruct::SUCCESS; + threadInfoStruct->ThreadExitCode = WorkUnitInfo::SUCCESS; } catch( ProcessAborted & ) { - threadInfoStruct->ThreadExitCode = ThreadInfoStruct::ITK_PROCESS_ABORTED_EXCEPTION; + threadInfoStruct->ThreadExitCode = WorkUnitInfo::ITK_PROCESS_ABORTED_EXCEPTION; } catch( ExceptionObject & ) { - threadInfoStruct->ThreadExitCode = ThreadInfoStruct::ITK_EXCEPTION; + threadInfoStruct->ThreadExitCode = WorkUnitInfo::ITK_EXCEPTION; } catch( std::exception & ) { - threadInfoStruct->ThreadExitCode = ThreadInfoStruct::STD_EXCEPTION; + threadInfoStruct->ThreadExitCode = WorkUnitInfo::STD_EXCEPTION; } catch( ... ) { - threadInfoStruct->ThreadExitCode = ThreadInfoStruct::UNKNOWN; + threadInfoStruct->ThreadExitCode = WorkUnitInfo::UNKNOWN; } return ITK_THREAD_RETURN_VALUE; @@ -494,10 +510,10 @@ ITK_THREAD_RETURN_TYPE MultiThreaderBase ::ParallelizeArrayHelper(void * arg) { - using ThreadInfo = MultiThreaderBase::ThreadInfoStruct; + using ThreadInfo = MultiThreaderBase::WorkUnitInfo; auto* threadInfo = static_cast< ThreadInfo* >( arg ); - ThreadIdType threadId = threadInfo->ThreadID; - ThreadIdType threadCount = threadInfo->NumberOfThreads; + ThreadIdType threadId = threadInfo->WorkUnitID; + ThreadIdType threadCount = threadInfo->NumberOfWorkUnits; auto* acParams = static_cast< struct ArrayCallback* >( threadInfo->UserData ); if ( acParams->filter && acParams->filter->GetAbortGenerateData() ) @@ -589,10 +605,10 @@ ITK_THREAD_RETURN_TYPE MultiThreaderBase ::ParallelizeImageRegionHelper(void * arg) { - using ThreadInfo = MultiThreaderBase::ThreadInfoStruct; + using ThreadInfo = MultiThreaderBase::WorkUnitInfo; auto * threadInfo = static_cast(arg); - ThreadIdType threadId = threadInfo->ThreadID; - ThreadIdType threadCount = threadInfo->NumberOfThreads; + ThreadIdType threadId = threadInfo->WorkUnitID; + ThreadIdType threadCount = threadInfo->NumberOfWorkUnits; auto * rnc = static_cast(threadInfo->UserData); const ImageRegionSplitterBase * splitter = ImageSourceCommon::GetGlobalDefaultSplitter(); @@ -644,7 +660,8 @@ void MultiThreaderBase::PrintSelf(std::ostream & os, Indent indent) const { Superclass::PrintSelf(os, indent); - os << indent << "Number of Threads: " << m_NumberOfThreads << "\n"; + os << indent << "Number of Work Units: " << m_NumberOfWorkUnits << "\n"; + os << indent << "Number of Threads: " << m_MaximumNumberOfThreads << "\n"; os << indent << "Global Maximum Number Of Threads: " << m_MultiThreaderBaseGlobals->m_GlobalMaximumNumberOfThreads << std::endl; os << indent << "Global Default Number Of Threads: " diff --git a/Modules/Core/Common/src/itkPlatformMultiThreader.cxx b/Modules/Core/Common/src/itkPlatformMultiThreader.cxx index 7269ccdbbf5..bb436f59b79 100644 --- a/Modules/Core/Common/src/itkPlatformMultiThreader.cxx +++ b/Modules/Core/Common/src/itkPlatformMultiThreader.cxx @@ -49,7 +49,7 @@ PlatformMultiThreader::PlatformMultiThreader() { for( ThreadIdType i = 0; i < ITK_MAX_THREADS; ++i ) { - m_ThreadInfoArray[i].ThreadID = i; + m_ThreadInfoArray[i].WorkUnitID = i; m_ThreadInfoArray[i].ActiveFlag = nullptr; m_ThreadInfoArray[i].ActiveFlagLock = nullptr; @@ -60,7 +60,7 @@ PlatformMultiThreader::PlatformMultiThreader() m_SpawnedThreadActiveFlag[i] = 0; m_SpawnedThreadActiveFlagLock[i] = nullptr; - m_SpawnedThreadInfoArray[i].ThreadID = i; + m_SpawnedThreadInfoArray[i].WorkUnitID = i; } } @@ -68,6 +68,17 @@ PlatformMultiThreader::~PlatformMultiThreader() { } +void PlatformMultiThreader::SetMaximumNumberOfThreads( ThreadIdType numberOfThreads ) +{ + Superclass::SetMaximumNumberOfThreads( numberOfThreads ); + Superclass::SetNumberOfWorkUnits( numberOfThreads ); +} + +void PlatformMultiThreader::SetNumberOfWorkUnits( ThreadIdType numberOfWorkUnits ) +{ + this->SetMaximumNumberOfThreads( numberOfWorkUnits ); +} + void PlatformMultiThreader::SetSingleMethod(ThreadFunctionType f, void *data) { m_SingleMethod = f; @@ -75,16 +86,16 @@ void PlatformMultiThreader::SetSingleMethod(ThreadFunctionType f, void *data) } #if !defined ( ITK_LEGACY_REMOVE ) -// Set one of the user defined methods that will be run on NumberOfThreads +// Set one of the user defined methods that will be run on NumberOfWorkUnits // threads when MultipleMethodExecute is called. This method should be -// called with index = 0, 1, .., NumberOfThreads-1 to set up all the +// called with index = 0, 1, .., NumberOfWorkUnits-1 to set up all the // required user defined methods void PlatformMultiThreader::SetMultipleMethod(ThreadIdType index, ThreadFunctionType f, void *data) { - // You can only set the method for 0 through NumberOfThreads-1 - if( index >= m_NumberOfThreads ) + // You can only set the method for 0 through NumberOfWorkUnits-1 + if( index >= m_NumberOfWorkUnits ) { - itkExceptionMacro(<< "Can't set method " << index << " with a thread count of " << m_NumberOfThreads); + itkExceptionMacro(<< "Can't set method " << index << " with a thread count of " << m_NumberOfWorkUnits); } else { @@ -105,11 +116,11 @@ void PlatformMultiThreader::SingleMethodExecute() } // obey the global maximum number of threads limit - m_NumberOfThreads = std::min( MultiThreaderBase::GetGlobalMaximumNumberOfThreads(), m_NumberOfThreads ); + m_NumberOfWorkUnits = std::min( MultiThreaderBase::GetGlobalMaximumNumberOfThreads(), m_NumberOfWorkUnits ); // Init process_id table because a valid process_id (i.e., non-zero), is // checked in the WaitForSingleMethodThread loops - for( thread_loop = 1; thread_loop < m_NumberOfThreads; ++thread_loop ) + for( thread_loop = 1; thread_loop < m_NumberOfWorkUnits; ++thread_loop ) { process_id[thread_loop] = 0; } @@ -125,10 +136,10 @@ void PlatformMultiThreader::SingleMethodExecute() std::string exceptionDetails; try { - for( thread_loop = 1; thread_loop < m_NumberOfThreads; ++thread_loop ) + for( thread_loop = 1; thread_loop < m_NumberOfWorkUnits; ++thread_loop ) { m_ThreadInfoArray[thread_loop].UserData = m_SingleData; - m_ThreadInfoArray[thread_loop].NumberOfThreads = m_NumberOfThreads; + m_ThreadInfoArray[thread_loop].NumberOfWorkUnits = m_NumberOfWorkUnits; m_ThreadInfoArray[thread_loop].ThreadFunction = m_SingleMethod; process_id[thread_loop] = @@ -156,14 +167,14 @@ void PlatformMultiThreader::SingleMethodExecute() try { m_ThreadInfoArray[0].UserData = m_SingleData; - m_ThreadInfoArray[0].NumberOfThreads = m_NumberOfThreads; + m_ThreadInfoArray[0].NumberOfWorkUnits = m_NumberOfWorkUnits; m_SingleMethod( (void *)( &m_ThreadInfoArray[0] ) ); } catch( ProcessAborted & ) { // Need cleanup and rethrow ProcessAborted // close down other threads - for( thread_loop = 1; thread_loop < m_NumberOfThreads; ++thread_loop ) + for( thread_loop = 1; thread_loop < m_NumberOfWorkUnits; ++thread_loop ) { try { @@ -194,7 +205,7 @@ void PlatformMultiThreader::SingleMethodExecute() } // The parent thread has finished this->SingleMethod() - so now it // waits for each of the other processes to exit - for( thread_loop = 1; thread_loop < m_NumberOfThreads; ++thread_loop ) + for( thread_loop = 1; thread_loop < m_NumberOfWorkUnits; ++thread_loop ) { try { @@ -202,7 +213,7 @@ void PlatformMultiThreader::SingleMethodExecute() this->SpawnWaitForSingleMethodThread(process_id[thread_loop]); if( m_ThreadInfoArray[thread_loop].ThreadExitCode - != ThreadInfoStruct::SUCCESS ) + != WorkUnitInfo::SUCCESS ) { exceptionOccurred = true; } diff --git a/Modules/Core/Common/src/itkPlatformMultiThreaderPosix.cxx b/Modules/Core/Common/src/itkPlatformMultiThreaderPosix.cxx index 62fdfcbbe4f..fc8ce9d263e 100644 --- a/Modules/Core/Common/src/itkPlatformMultiThreaderPosix.cxx +++ b/Modules/Core/Common/src/itkPlatformMultiThreaderPosix.cxx @@ -50,11 +50,11 @@ void PlatformMultiThreader::MultipleMethodExecute() pthread_t process_id[ITK_MAX_THREADS]; // obey the global maximum number of threads limit - if( m_NumberOfThreads > MultiThreaderBase::GetGlobalMaximumNumberOfThreads() ) + if( m_NumberOfWorkUnits > MultiThreaderBase::GetGlobalMaximumNumberOfThreads() ) { - m_NumberOfThreads = MultiThreaderBase::GetGlobalMaximumNumberOfThreads(); + m_NumberOfWorkUnits = MultiThreaderBase::GetGlobalMaximumNumberOfThreads(); } - for( ThreadIdType thread_loop = 0; thread_loop < m_NumberOfThreads; ++thread_loop ) + for( ThreadIdType thread_loop = 0; thread_loop < m_NumberOfWorkUnits; ++thread_loop ) { if( m_MultipleMethod[thread_loop] == (ThreadFunctionType)nullptr ) { @@ -65,14 +65,14 @@ void PlatformMultiThreader::MultipleMethodExecute() // Using POSIX threads // - // We want to use pthread_create to start m_NumberOfThreads - 1 + // We want to use pthread_create to start m_NumberOfWorkUnits - 1 // additional - // threads which will be used to call the NumberOfThreads-1 methods + // threads which will be used to call the NumberOfWorkUnits-1 methods // defined in m_MultipleMethods[](). The parent thread - // will call m_MultipleMethods[NumberOfThreads-1](). When it is done, + // will call m_MultipleMethods[NumberOfWorkUnits-1](). When it is done, // it will wait for all the children to finish. // - // First, start up the m_NumberOfThreads-1 processes. Keep track + // First, start up the m_NumberOfWorkUnits-1 processes. Keep track // of their process ids for use later in the pthread_join call pthread_attr_t attr; @@ -81,11 +81,11 @@ void PlatformMultiThreader::MultipleMethodExecute() #ifndef __CYGWIN__ pthread_attr_setscope(&attr, PTHREAD_SCOPE_PROCESS); #endif - for( ThreadIdType thread_loop = 1; thread_loop < m_NumberOfThreads; ++thread_loop ) + for( ThreadIdType thread_loop = 1; thread_loop < m_NumberOfWorkUnits; ++thread_loop ) { m_ThreadInfoArray[thread_loop].UserData = m_MultipleData[thread_loop]; - m_ThreadInfoArray[thread_loop].NumberOfThreads = m_NumberOfThreads; + m_ThreadInfoArray[thread_loop].NumberOfWorkUnits = m_NumberOfWorkUnits; int threadError = pthread_create( &( process_id[thread_loop] ), &attr, reinterpret_cast( m_MultipleMethod[thread_loop] ), ( (void *)( &m_ThreadInfoArray[thread_loop] ) ) ); @@ -98,11 +98,11 @@ void PlatformMultiThreader::MultipleMethodExecute() // Now, the parent thread calls the last method itself m_ThreadInfoArray[0].UserData = m_MultipleData[0]; - m_ThreadInfoArray[0].NumberOfThreads = m_NumberOfThreads; + m_ThreadInfoArray[0].NumberOfWorkUnits = m_NumberOfWorkUnits; ( m_MultipleMethod[0] )( (void *)( &m_ThreadInfoArray[0] ) ); // The parent thread has finished its method - so now it // waits for each of the other processes to exit - for( ThreadIdType thread_loop = 1; thread_loop < m_NumberOfThreads; ++thread_loop ) + for( ThreadIdType thread_loop = 1; thread_loop < m_NumberOfWorkUnits; ++thread_loop ) { pthread_join(process_id[thread_loop], nullptr); } @@ -138,7 +138,7 @@ ThreadIdType PlatformMultiThreader::SpawnThread(ThreadFunctionType f, void *User } m_SpawnedThreadInfoArray[id].UserData = UserData; - m_SpawnedThreadInfoArray[id].NumberOfThreads = 1; + m_SpawnedThreadInfoArray[id].NumberOfWorkUnits = 1; m_SpawnedThreadInfoArray[id].ActiveFlag = &m_SpawnedThreadActiveFlag[id]; m_SpawnedThreadInfoArray[id].ActiveFlagLock = m_SpawnedThreadActiveFlagLock[id]; @@ -161,21 +161,21 @@ ThreadIdType PlatformMultiThreader::SpawnThread(ThreadFunctionType f, void *User return id; } -void PlatformMultiThreader::TerminateThread(ThreadIdType ThreadID) +void PlatformMultiThreader::TerminateThread(ThreadIdType WorkUnitID) { - if( !m_SpawnedThreadActiveFlag[ThreadID] ) + if( !m_SpawnedThreadActiveFlag[WorkUnitID] ) { return; } - m_SpawnedThreadActiveFlagLock[ThreadID]->Lock(); - m_SpawnedThreadActiveFlag[ThreadID] = 0; - m_SpawnedThreadActiveFlagLock[ThreadID]->Unlock(); + m_SpawnedThreadActiveFlagLock[WorkUnitID]->Lock(); + m_SpawnedThreadActiveFlag[WorkUnitID] = 0; + m_SpawnedThreadActiveFlagLock[WorkUnitID]->Unlock(); - pthread_join(m_SpawnedThreadProcessID[ThreadID], nullptr); + pthread_join(m_SpawnedThreadProcessID[WorkUnitID], nullptr); - m_SpawnedThreadActiveFlagLock[ThreadID] = nullptr; - m_SpawnedThreadActiveFlagLock[ThreadID] = nullptr; + m_SpawnedThreadActiveFlagLock[WorkUnitID] = nullptr; + m_SpawnedThreadActiveFlagLock[WorkUnitID] = nullptr; } #endif @@ -192,7 +192,7 @@ ::SpawnWaitForSingleMethodThread(ThreadProcessIdType threadHandle) ThreadProcessIdType PlatformMultiThreader -::SpawnDispatchSingleMethodThread(PlatformMultiThreader::ThreadInfoStruct *threadInfo) +::SpawnDispatchSingleMethodThread(PlatformMultiThreader::WorkUnitInfo *threadInfo) { // Using POSIX threads pthread_attr_t attr; diff --git a/Modules/Core/Common/src/itkPlatformMultiThreaderSingle.cxx b/Modules/Core/Common/src/itkPlatformMultiThreaderSingle.cxx index 212bc712297..32b15858b55 100644 --- a/Modules/Core/Common/src/itkPlatformMultiThreaderSingle.cxx +++ b/Modules/Core/Common/src/itkPlatformMultiThreaderSingle.cxx @@ -38,12 +38,12 @@ void PlatformMultiThreader::MultipleMethodExecute() ThreadIdType thread_loop; // obey the global maximum number of threads limit - if ( m_NumberOfThreads > m_GlobalMaximumNumberOfThreads ) + if ( m_NumberOfWorkUnits > m_GlobalMaximumNumberOfThreads ) { - m_NumberOfThreads = m_GlobalMaximumNumberOfThreads; + m_NumberOfWorkUnits = m_GlobalMaximumNumberOfThreads; } - for ( thread_loop = 0; thread_loop < m_NumberOfThreads; thread_loop++ ) + for ( thread_loop = 0; thread_loop < m_NumberOfWorkUnits; thread_loop++ ) { if ( m_MultipleMethod[thread_loop] == (ThreadFunctionType)0 ) { @@ -54,7 +54,7 @@ void PlatformMultiThreader::MultipleMethodExecute() // There is no multi threading, so there is only one thread. m_ThreadInfoArray[0].UserData = m_MultipleData[0]; - m_ThreadInfoArray[0].NumberOfThreads = m_NumberOfThreads; + m_ThreadInfoArray[0].NumberOfWorkUnits = m_NumberOfWorkUnits; ( m_MultipleMethod[0] )( (void *)( &m_ThreadInfoArray[0] ) ); } @@ -66,7 +66,7 @@ ThreadIdType PlatformMultiThreader::SpawnThread(ThreadFunctionType itkNotUsed( f return -1; } -void PlatformMultiThreader::TerminateThread(ThreadIdType ThreadID) +void PlatformMultiThreader::TerminateThread(ThreadIdType WorkUnitID) { // There is no multi threading, so there is only one thread. // This won't work - so give an error message. @@ -84,7 +84,7 @@ ::SpawnWaitForSingleMethodThread(ThreadProcessIdType itkNotUsed( threadHandle )) ThreadProcessIdType PlatformMultiThreader -::SpawnDispatchSingleMethodThread(PlatformMultiThreader::ThreadInfoStruct * itkNotUsed( threadInfo )) +::SpawnDispatchSingleMethodThread(PlatformMultiThreader::WorkUnitInfo * itkNotUsed( threadInfo )) { // No threading library specified. Do nothing. The computation // will be run by the main execution thread. diff --git a/Modules/Core/Common/src/itkPlatformMultiThreaderWindows.cxx b/Modules/Core/Common/src/itkPlatformMultiThreaderWindows.cxx index 4041c73bffe..1a92ca9a26d 100644 --- a/Modules/Core/Common/src/itkPlatformMultiThreaderWindows.cxx +++ b/Modules/Core/Common/src/itkPlatformMultiThreaderWindows.cxx @@ -44,11 +44,11 @@ void PlatformMultiThreader::MultipleMethodExecute() HANDLE processId[ITK_MAX_THREADS]; // obey the global maximum number of threads limit - if( m_NumberOfThreads > MultiThreaderBase::GetGlobalMaximumNumberOfThreads() ) + if( m_NumberOfWorkUnits > MultiThreaderBase::GetGlobalMaximumNumberOfThreads() ) { - m_NumberOfThreads = MultiThreaderBase::GetGlobalMaximumNumberOfThreads(); + m_NumberOfWorkUnits = MultiThreaderBase::GetGlobalMaximumNumberOfThreads(); } - for( threadCount = 0; threadCount < m_NumberOfThreads; ++threadCount ) + for( threadCount = 0; threadCount < m_NumberOfWorkUnits; ++threadCount ) { if( m_MultipleMethod[threadCount] == (ThreadFunctionType)0 ) { @@ -58,19 +58,19 @@ void PlatformMultiThreader::MultipleMethodExecute() } // Using _beginthreadex on a PC // - // We want to use _beginthreadex to start m_NumberOfThreads - 1 - // additional threads which will be used to call the NumberOfThreads-1 + // We want to use _beginthreadex to start m_NumberOfWorkUnits - 1 + // additional threads which will be used to call the NumberOfWorkUnits-1 // methods defined in this->MultipleMethods[](). The parent thread - // will call m_MultipleMethods[NumberOfThreads-1](). When it is done, + // will call m_MultipleMethods[NumberOfWorkUnits-1](). When it is done, // it will wait for all the children to finish. // - // First, start up the m_NumberOfThreads-1 processes. Keep track + // First, start up the m_NumberOfWorkUnits-1 processes. Keep track // of their process ids for use later in the waitid call - for( threadCount = 1; threadCount < m_NumberOfThreads; ++threadCount ) + for( threadCount = 1; threadCount < m_NumberOfWorkUnits; ++threadCount ) { m_ThreadInfoArray[threadCount].UserData = m_MultipleData[threadCount]; - m_ThreadInfoArray[threadCount].NumberOfThreads = m_NumberOfThreads; + m_ThreadInfoArray[threadCount].NumberOfWorkUnits = m_NumberOfWorkUnits; processId[threadCount] = (void *) _beginthreadex(0, 0, @@ -86,17 +86,17 @@ void PlatformMultiThreader::MultipleMethodExecute() // Now, the parent thread calls the last method itself m_ThreadInfoArray[0].UserData = m_MultipleData[0]; - m_ThreadInfoArray[0].NumberOfThreads = m_NumberOfThreads; + m_ThreadInfoArray[0].NumberOfWorkUnits = m_NumberOfWorkUnits; ( m_MultipleMethod[0] )( (void *)( &m_ThreadInfoArray[0] ) ); // The parent thread has finished its method - so now it // waits for each of the other processes to // exit - for( threadCount = 1; threadCount < m_NumberOfThreads; ++threadCount ) + for( threadCount = 1; threadCount < m_NumberOfWorkUnits; ++threadCount ) { WaitForSingleObject(processId[threadCount], INFINITE); } // close the threads - for( threadCount = 1; threadCount < m_NumberOfThreads; ++threadCount ) + for( threadCount = 1; threadCount < m_NumberOfWorkUnits; ++threadCount ) { CloseHandle(processId[threadCount]); } @@ -133,7 +133,7 @@ ThreadIdType PlatformMultiThreader::SpawnThread(ThreadFunctionType f, void *User } m_SpawnedThreadInfoArray[id].UserData = UserData; - m_SpawnedThreadInfoArray[id].NumberOfThreads = 1; + m_SpawnedThreadInfoArray[id].NumberOfWorkUnits = 1; m_SpawnedThreadInfoArray[id].ActiveFlag = &m_SpawnedThreadActiveFlag[id]; m_SpawnedThreadInfoArray[id].ActiveFlagLock = m_SpawnedThreadActiveFlagLock[id]; @@ -150,20 +150,20 @@ ThreadIdType PlatformMultiThreader::SpawnThread(ThreadFunctionType f, void *User return id; } -void PlatformMultiThreader::TerminateThread(ThreadIdType ThreadID) +void PlatformMultiThreader::TerminateThread(ThreadIdType WorkUnitID) { - if( !m_SpawnedThreadActiveFlag[ThreadID] ) + if( !m_SpawnedThreadActiveFlag[WorkUnitID] ) { return; } - m_SpawnedThreadActiveFlagLock[ThreadID]->Lock(); - m_SpawnedThreadActiveFlag[ThreadID] = 0; - m_SpawnedThreadActiveFlagLock[ThreadID]->Unlock(); + m_SpawnedThreadActiveFlagLock[WorkUnitID]->Lock(); + m_SpawnedThreadActiveFlag[WorkUnitID] = 0; + m_SpawnedThreadActiveFlagLock[WorkUnitID]->Unlock(); - WaitForSingleObject(m_SpawnedThreadProcessID[ThreadID], INFINITE); - CloseHandle(m_SpawnedThreadProcessID[ThreadID]); - m_SpawnedThreadActiveFlagLock[ThreadID] = nullptr; + WaitForSingleObject(m_SpawnedThreadProcessID[WorkUnitID], INFINITE); + CloseHandle(m_SpawnedThreadProcessID[WorkUnitID]); + m_SpawnedThreadActiveFlagLock[WorkUnitID] = nullptr; } #endif @@ -178,7 +178,7 @@ ::SpawnWaitForSingleMethodThread(ThreadProcessIdType threadHandle) ThreadProcessIdType PlatformMultiThreader -::SpawnDispatchSingleMethodThread(PlatformMultiThreader::ThreadInfoStruct *threadInfo) +::SpawnDispatchSingleMethodThread(PlatformMultiThreader::WorkUnitInfo *threadInfo) { // Using _beginthreadex on a PC DWORD threadId; diff --git a/Modules/Core/Common/src/itkPoolMultiThreader.cxx b/Modules/Core/Common/src/itkPoolMultiThreader.cxx index 59d5dead9a6..61b4091e5b9 100644 --- a/Modules/Core/Common/src/itkPoolMultiThreader.cxx +++ b/Modules/Core/Common/src/itkPoolMultiThreader.cxx @@ -42,12 +42,13 @@ PoolMultiThreader::PoolMultiThreader() : { for( ThreadIdType i = 0; i < ITK_MAX_THREADS; ++i ) { - m_ThreadInfoArray[i].ThreadID = i; + m_ThreadInfoArray[i].WorkUnitID = i; } ThreadIdType idleCount = std::max(1u, m_ThreadPool->GetNumberOfCurrentlyIdleThreads()); ThreadIdType maxCount = std::max(1u, GetGlobalDefaultNumberOfThreads()); - m_NumberOfThreads = std::min(maxCount, idleCount); + m_NumberOfWorkUnits = std::min(maxCount, idleCount); + m_MaximumNumberOfThreads = m_ThreadPool->GetMaximumNumberOfThreads(); } PoolMultiThreader::~PoolMultiThreader() @@ -60,6 +61,17 @@ void PoolMultiThreader::SetSingleMethod(ThreadFunctionType f, void *data) m_SingleData = data; } +void PoolMultiThreader::SetMaximumNumberOfThreads(ThreadIdType numberOfThreads) +{ + Superclass::SetMaximumNumberOfThreads( numberOfThreads ); + ThreadIdType threadCount = m_ThreadPool->GetMaximumNumberOfThreads(); + if ( threadCount < m_MaximumNumberOfThreads ) + { + m_ThreadPool->AddThreads( m_MaximumNumberOfThreads - threadCount ); + } + m_MaximumNumberOfThreads = m_ThreadPool->GetMaximumNumberOfThreads(); +} + void PoolMultiThreader::SingleMethodExecute() { ThreadIdType thread_loop = 0; @@ -70,7 +82,7 @@ void PoolMultiThreader::SingleMethodExecute() } // obey the global maximum number of threads limit - m_NumberOfThreads = std::min( this->GetGlobalMaximumNumberOfThreads(), m_NumberOfThreads ); + m_NumberOfWorkUnits = std::min( this->GetGlobalMaximumNumberOfThreads(), m_NumberOfWorkUnits ); // Spawn a set of threads through the SingleMethodProxy. Exceptions @@ -87,10 +99,10 @@ void PoolMultiThreader::SingleMethodExecute() ThreadJob threadJob; threadJob.m_ThreadFunction = (this->SingleMethodProxy); - for( thread_loop = 1; thread_loop < m_NumberOfThreads; ++thread_loop ) + for( thread_loop = 1; thread_loop < m_NumberOfWorkUnits; ++thread_loop ) { m_ThreadInfoArray[thread_loop].UserData = m_SingleData; - m_ThreadInfoArray[thread_loop].NumberOfThreads = m_NumberOfThreads; + m_ThreadInfoArray[thread_loop].NumberOfWorkUnits = m_NumberOfWorkUnits; m_ThreadInfoArray[thread_loop].ThreadFunction = m_SingleMethod; threadJob.m_UserData = &m_ThreadInfoArray[thread_loop]; @@ -125,14 +137,14 @@ void PoolMultiThreader::SingleMethodExecute() try { m_ThreadInfoArray[0].UserData = m_SingleData; - m_ThreadInfoArray[0].NumberOfThreads = m_NumberOfThreads; + m_ThreadInfoArray[0].NumberOfWorkUnits = m_NumberOfWorkUnits; m_SingleMethod( (void *)( &m_ThreadInfoArray[0] ) ); } catch( ProcessAborted & ) { // Need cleanup and rethrow ProcessAborted // close down other threads - for( thread_loop = 1; thread_loop < m_NumberOfThreads; ++thread_loop ) + for( thread_loop = 1; thread_loop < m_NumberOfWorkUnits; ++thread_loop ) { try { @@ -165,7 +177,7 @@ void PoolMultiThreader::SingleMethodExecute() } // The parent thread has finished this->SingleMethod() - so now it // waits for each of the other processes to exit - for( thread_loop = 1; thread_loop < m_NumberOfThreads; ++thread_loop ) + for( thread_loop = 1; thread_loop < m_NumberOfWorkUnits; ++thread_loop ) { try { diff --git a/Modules/Core/Common/src/itkProcessObject.cxx b/Modules/Core/Common/src/itkProcessObject.cxx index f184f8c0a88..00b48a8678f 100644 --- a/Modules/Core/Common/src/itkProcessObject.cxx +++ b/Modules/Core/Common/src/itkProcessObject.cxx @@ -1665,13 +1665,13 @@ ::SetMultiThreader(MultiThreaderType* threader) if (this->m_MultiThreader.IsNull()) { this->m_MultiThreader = threader; - m_NumberOfWorkUnits = m_MultiThreader->GetNumberOfThreads(); + m_NumberOfWorkUnits = m_MultiThreader->GetNumberOfWorkUnits(); } else { - ThreadIdType oldDefaultNumber = m_MultiThreader->GetNumberOfThreads(); + ThreadIdType oldDefaultNumber = m_MultiThreader->GetNumberOfWorkUnits(); this->m_MultiThreader = threader; - ThreadIdType newDefaultNumber = m_MultiThreader->GetNumberOfThreads(); + ThreadIdType newDefaultNumber = m_MultiThreader->GetNumberOfWorkUnits(); if (m_NumberOfWorkUnits == oldDefaultNumber) { m_NumberOfWorkUnits = newDefaultNumber; @@ -1937,7 +1937,7 @@ ::DetermineNumberOfWorkUnitsUsed() { MultiThreaderBase * multiThreader = this->m_Associate->GetMultiThreader(); this->SetMultiThreader( multiThreader ); - multiThreader->SetNumberOfThreads( this->m_Associate->GetNumberOfWorkUnits() ); + multiThreader->SetNumberOfWorkUnits( this->m_Associate->GetNumberOfWorkUnits() ); Superclass::DetermineNumberOfWorkUnitsUsed(); } diff --git a/Modules/Core/Common/src/itkTBBMultiThreader.cxx b/Modules/Core/Common/src/itkTBBMultiThreader.cxx index 8d444dae7fa..1c657adbb86 100644 --- a/Modules/Core/Common/src/itkTBBMultiThreader.cxx +++ b/Modules/Core/Common/src/itkTBBMultiThreader.cxx @@ -23,13 +23,13 @@ #include #include #include "tbb/parallel_for.h" +#include "tbb/task_scheduler_init.h" namespace itk { TBBMultiThreader::TBBMultiThreader() { - m_NumberOfThreads = std::max(1u, GetGlobalDefaultNumberOfThreads()); } TBBMultiThreader::~TBBMultiThreader() @@ -49,22 +49,28 @@ void TBBMultiThreader::SingleMethodExecute() itkExceptionMacro(<< "No single method set!"); } + tbb::task_scheduler_init tbb_init( m_MaximumNumberOfThreads ); //we request grain size of 1 and simple_partitioner to ensure there is no chunking - tbb::parallel_for(tbb::blocked_range(0, m_NumberOfThreads, 1), [&](tbb::blocked_ranger) + tbb::parallel_for(tbb::blocked_range(0, m_NumberOfWorkUnits, 1), [&](tbb::blocked_ranger) { - // Make sure that TBB did not call us with a block of "threads" - // but rather with only one "thread" to handle + // Make sure that TBB did not call us with a block of work units + // but rather with only one work unit to handle itkAssertInDebugAndIgnoreInReleaseMacro(r.begin() + 1 == r.end()); - ThreadInfoStruct ti; - ti.ThreadID = r.begin(); + WorkUnitInfo ti; + ti.WorkUnitID = r.begin(); ti.UserData = m_SingleData; - ti.NumberOfThreads = m_NumberOfThreads; + ti.NumberOfWorkUnits = m_NumberOfWorkUnits; m_SingleMethod(&ti); //TBB takes care of properly propagating exceptions }, tbb::simple_partitioner()); } +void TBBMultiThreader::SetNumberOfWorkUnits(ThreadIdType numberOfWorkUnits) +{ + m_NumberOfWorkUnits = std::max( 1u, numberOfWorkUnits ); +} + void TBBMultiThreader::PrintSelf(std::ostream & os, Indent indent) const { Superclass::PrintSelf(os, indent); @@ -88,6 +94,7 @@ ::ParallelizeArray( unsigned count = lastIndexPlus1 - firstIndex; std::atomic< SizeValueType > progress( 0 ); std::thread::id callingThread = std::this_thread::get_id(); + tbb::task_scheduler_init tbb_init( m_MaximumNumberOfThreads ); //we request grain size of 1 and simple_partitioner to ensure there is no chunking tbb::parallel_for( tbb::blocked_range(firstIndex, lastIndexPlus1, 1), @@ -223,7 +230,7 @@ ::ParallelizeImageRegion( filter->UpdateProgress(0.0f); } - if (m_NumberOfThreads == 1) //no multi-threading wanted + if (m_NumberOfWorkUnits == 1) //no multi-threading wanted { funcP(index, size); } @@ -240,7 +247,7 @@ ::ParallelizeImageRegion( std::atomic pixelProgress = { 0 }; SizeValueType totalCount = region.GetNumberOfPixels(); std::thread::id callingThread = std::this_thread::get_id(); - + tbb::task_scheduler_init tbb_init( m_MaximumNumberOfThreads ); tbb::parallel_for(regionSplitter, [&](TBBImageRegionSplitter regionToProcess) { if (filter && filter->GetAbortGenerateData()) diff --git a/Modules/Core/Common/test/CMakeLists.txt b/Modules/Core/Common/test/CMakeLists.txt index 41377b104a3..473e9f19a47 100644 --- a/Modules/Core/Common/test/CMakeLists.txt +++ b/Modules/Core/Common/test/CMakeLists.txt @@ -154,7 +154,7 @@ itkObjectFactoryTest2.cxx itkObjectFactoryTest3.cxx itkMinimumMaximumImageCalculatorTest.cxx itkSliceIteratorTest.cxx -itkPlatformMultiThreaderTest.cxx +itkMultiThreaderBaseTest.cxx itkMultiThreaderTypeFromEnvironmentTest itkMultiThreadingEnvironmentTest.cxx itkMultiThreaderParallelizeArrayTest.cxx @@ -381,7 +381,17 @@ if(0) endif() itk_add_test(NAME itkMetaDataDictionaryTest COMMAND ITKCommon2TestDriver itkMetaDataDictionaryTest) -itk_add_test(NAME itkPlatformMultiThreaderTest COMMAND ITKCommon2TestDriver itkPlatformMultiThreaderTest) + +itk_add_test(NAME itkMultiThreaderBaseTestPlatform + COMMAND ITKCommon2TestDriver itkMultiThreaderBaseTest) +set_tests_properties(itkMultiThreaderBaseTestPlatform + PROPERTIES ENVIRONMENT "ITK_GLOBAL_DEFAULT_THEADER=Platform") +itk_add_test(NAME itkMultiThreaderBaseTestPool + COMMAND ITKCommon2TestDriver itkMultiThreaderBaseTest) +set_tests_properties(itkMultiThreaderBaseTestPool + PROPERTIES ENVIRONMENT "ITK_GLOBAL_DEFAULT_THEADER=Pool") +itk_add_test(NAME itkMultiThreaderBaseTest3 + COMMAND ITKCommon2TestDriver itkMultiThreaderBaseTest 3) # test with 3 threads itk_add_test(NAME itkMultiThreaderTypeFromEnvironmentTestPlatform COMMAND ITKCommon2TestDriver itkMultiThreaderTypeFromEnvironmentTest PlatFORM) @@ -394,6 +404,11 @@ set_tests_properties(itkMultiThreaderTypeFromEnvironmentTestPool PROPERTIES ENVIRONMENT "ITK_GLOBAL_DEFAULT_THREADER=pOoL") # tests letter case too if(Module_ITKTBB) # ITK_USE_TBB is not yet defined here + itk_add_test(NAME itkMultiThreaderBaseTestTBB + COMMAND ITKCommon2TestDriver itkMultiThreaderBaseTest) + set_tests_properties(itkMultiThreaderBaseTestTBB + PROPERTIES ENVIRONMENT "ITK_GLOBAL_DEFAULT_THEADER=TBB") + itk_add_test(NAME itkMultiThreaderTypeFromEnvironmentTestTBB COMMAND ITKCommon2TestDriver itkMultiThreaderTypeFromEnvironmentTest TBB) set_tests_properties(itkMultiThreaderTypeFromEnvironmentTestTBB diff --git a/Modules/Core/Common/test/itkAtomicIntTest.cxx b/Modules/Core/Common/test/itkAtomicIntTest.cxx index acee274b30b..7021d18bda2 100644 --- a/Modules/Core/Common/test/itkAtomicIntTest.cxx +++ b/Modules/Core/Common/test/itkAtomicIntTest.cxx @@ -243,7 +243,7 @@ int itkAtomicIntTest(int, char*[]) itk::ModifiedTimeType beforeMTime = AnObject->GetMTime(); mt->SetSingleMethod(MyFunction, nullptr); - mt->SetNumberOfThreads( NumThreads ); + mt->SetNumberOfWorkUnits( NumThreads ); mt->SingleMethodExecute(); mt->SetSingleMethod(MyFunction2, nullptr); diff --git a/Modules/Core/Common/test/itkBarrierTest.cxx b/Modules/Core/Common/test/itkBarrierTest.cxx index 18e6adec6d9..d2e8388dbe8 100644 --- a/Modules/Core/Common/test/itkBarrierTest.cxx +++ b/Modules/Core/Common/test/itkBarrierTest.cxx @@ -49,9 +49,9 @@ class BarrierTestUserData ITK_THREAD_RETURN_TYPE BarrierTestIncrement( void *ptr ) { - itk::ThreadIdType threadId = ( (itk::PlatformMultiThreader::ThreadInfoStruct *)(ptr) )->ThreadID; + itk::ThreadIdType threadId = ( (itk::PlatformMultiThreader::WorkUnitInfo *)(ptr) )->WorkUnitID; auto * data = static_cast( - ( (itk::PlatformMultiThreader::ThreadInfoStruct *)(ptr) )->UserData ); + ( (itk::PlatformMultiThreader::WorkUnitInfo *)(ptr) )->UserData ); for (unsigned int i = 0; i < data->m_NumberOfIterations; i++) { @@ -69,7 +69,7 @@ ITK_THREAD_RETURN_TYPE BarrierTestIncrement( void *ptr ) ITK_THREAD_RETURN_TYPE BarrierCheckIncrement( void *ptr ) { auto * data = static_cast( - ( (itk::PlatformMultiThreader::ThreadInfoStruct *)(ptr) )->UserData ); + ( (itk::PlatformMultiThreader::WorkUnitInfo *)(ptr) )->UserData ); for (unsigned int i = 0; i < data->m_NumberOfIterations; i++) { @@ -92,9 +92,9 @@ ITK_THREAD_RETURN_TYPE BarrierCheckIncrement( void *ptr ) ITK_THREAD_RETURN_TYPE BarrierTestCallback( void *ptr ) { - itk::ThreadIdType threadId = ( (itk::PlatformMultiThreader::ThreadInfoStruct *)(ptr) )->ThreadID; + itk::ThreadIdType threadId = ( (itk::PlatformMultiThreader::WorkUnitInfo *)(ptr) )->WorkUnitID; auto * data = static_cast( - ( (itk::PlatformMultiThreader::ThreadInfoStruct *)(ptr) )->UserData ); + ( (itk::PlatformMultiThreader::WorkUnitInfo *)(ptr) )->UserData ); if (threadId == data->m_NumberOfWorkUnits - 1) { @@ -111,7 +111,7 @@ ITK_THREAD_RETURN_TYPE BarrierTestCallback( void *ptr ) ITK_THREAD_RETURN_TYPE BarrierSpecialTest( void *ptr ) { auto * data = static_cast( - ( (itk::PlatformMultiThreader::ThreadInfoStruct *)(ptr) )->UserData ); + ( (itk::PlatformMultiThreader::WorkUnitInfo *)(ptr) )->UserData ); for (unsigned int j = 0; j < 1000; j++ ) { @@ -142,7 +142,7 @@ int itkBarrierTest(int argc, char *argv[]) // { // multithreader->GetModifiableThreadPool()->AddThreads(number_of_threads - maxThreads); // } - multithreader->SetNumberOfThreads( number_of_threads ); + multithreader->SetNumberOfWorkUnits( number_of_threads ); multithreader->SetSingleMethod( BarrierTestCallback, &data); for (unsigned int i = 0; i < 5; i++) //repeat test 5 times diff --git a/Modules/Core/Common/test/itkCompensatedSummationTest2.cxx b/Modules/Core/Common/test/itkCompensatedSummationTest2.cxx index 9d1ad15e377..b4e017a29bc 100644 --- a/Modules/Core/Common/test/itkCompensatedSummationTest2.cxx +++ b/Modules/Core/Common/test/itkCompensatedSummationTest2.cxx @@ -156,6 +156,7 @@ int itkCompensatedSummationTest2(int, char* []) /* Test with single thread. We should get the same result. */ itk::ThreadIdType numberOfThreads = 1; domainThreader->SetMaximumNumberOfThreads( numberOfThreads ); + domainThreader->SetNumberOfWorkUnits( numberOfThreads ); std::cout << "Testing with " << numberOfThreads << " threads and domain " << domain << " ..." << std::endl; @@ -186,6 +187,7 @@ int itkCompensatedSummationTest2(int, char* []) if( domainThreader->GetMultiThreader()->GetGlobalMaximumNumberOfThreads() > 2 ) { domainThreader->SetMaximumNumberOfThreads( maxNumberOfThreads ); + domainThreader->SetNumberOfWorkUnits( maxNumberOfThreads ); std::cout << "Testing with " << maxNumberOfThreads << " threads and domain " << domain << " ..." << std::endl; diff --git a/Modules/Core/Common/test/itkConditionVariableTest.cxx b/Modules/Core/Common/test/itkConditionVariableTest.cxx index 1cbe3659b1b..46a469c34fd 100644 --- a/Modules/Core/Common/test/itkConditionVariableTest.cxx +++ b/Modules/Core/Common/test/itkConditionVariableTest.cxx @@ -41,7 +41,7 @@ class ConditionVariableTestUserData ITK_THREAD_RETURN_TYPE ConditionVariableTestIncCount( void *ptr ) { auto * data = static_cast( - ( (itk::MultiThreaderBase::ThreadInfoStruct *)(ptr) )->UserData ); + ( (itk::MultiThreaderBase::WorkUnitInfo *)(ptr) )->UserData ); double v = 400.0; @@ -74,7 +74,7 @@ ITK_THREAD_RETURN_TYPE ConditionVariableTestIncCount( void *ptr ) ITK_THREAD_RETURN_TYPE ConditionVariableTestWatchCount( void *ptr ) { auto * data = static_cast( - ( (itk::MultiThreaderBase::ThreadInfoStruct *)(ptr) )->UserData ); + ( (itk::MultiThreaderBase::WorkUnitInfo *)(ptr) )->UserData ); // Lock the mutex and wait for the signal. data->m_Mutex.Lock(); @@ -89,7 +89,7 @@ ITK_THREAD_RETURN_TYPE ConditionVariableTestWatchCount( void *ptr ) ITK_THREAD_RETURN_TYPE ConditionVariableTestCallback( void *ptr ) { - itk::ThreadIdType threadId = ( (itk::MultiThreaderBase::ThreadInfoStruct *)(ptr) )->ThreadID; + itk::ThreadIdType threadId = ( (itk::MultiThreaderBase::WorkUnitInfo *)(ptr) )->WorkUnitID; if ( threadId == 0 ) { @@ -109,7 +109,7 @@ int itkConditionVariableTest(int , char*[]) try { itk::PlatformMultiThreader::Pointer multithreader = itk::PlatformMultiThreader::New(); - multithreader->SetNumberOfThreads(3); + multithreader->SetNumberOfWorkUnits(3); multithreader->SetSingleMethod( ConditionVariableTestCallback, &cond); for (unsigned int i = 0; i < 1000; i++) diff --git a/Modules/Core/Common/test/itkLoggerThreadWrapperTest.cxx b/Modules/Core/Common/test/itkLoggerThreadWrapperTest.cxx index dd82df08fe0..f8fde42d5ee 100644 --- a/Modules/Core/Common/test/itkLoggerThreadWrapperTest.cxx +++ b/Modules/Core/Common/test/itkLoggerThreadWrapperTest.cxx @@ -126,10 +126,10 @@ class LogTester ITK_THREAD_RETURN_TYPE ThreadedGenerateLogMessages2(void* arg) { - const auto* threadInfo = static_cast(arg); + const auto* threadInfo = static_cast(arg); if (threadInfo) { - const unsigned int threadId = threadInfo->ThreadID; + const unsigned int threadId = threadInfo->WorkUnitID; std::string threadPrefix; { std::ostringstream msg; @@ -157,7 +157,7 @@ ITK_THREAD_RETURN_TYPE ThreadedGenerateLogMessages2(void* arg) return ITK_THREAD_RETURN_VALUE; } } else { - std::cerr << "ERROR: arg was not of type itk::MultiThreaderBase::ThreadInfoStruct*" << std::endl; + std::cerr << "ERROR: arg was not of type itk::MultiThreaderBase::WorkUnitInfo*" << std::endl; return ITK_THREAD_RETURN_VALUE; } return ITK_THREAD_RETURN_VALUE; @@ -248,7 +248,7 @@ int itkLoggerThreadWrapperTest( int argc, char * argv[] ) ThreadDataVec threadData = create_threaded_data2(numthreads, logger); itk::MultiThreaderBase::Pointer threader = itk::MultiThreaderBase::New(); itk::MultiThreaderBase::SetGlobalMaximumNumberOfThreads(numthreads + 10); - threader->SetNumberOfThreads(numthreads); + threader->SetNumberOfWorkUnits(numthreads); threader->SetSingleMethod(ThreadedGenerateLogMessages2, &threadData); threader->SingleMethodExecute(); logger->Flush(); diff --git a/Modules/Core/Common/test/itkMultiThreaderBaseTest.cxx b/Modules/Core/Common/test/itkMultiThreaderBaseTest.cxx new file mode 100644 index 00000000000..9dce4e1c61c --- /dev/null +++ b/Modules/Core/Common/test/itkMultiThreaderBaseTest.cxx @@ -0,0 +1,130 @@ +/*========================================================================= + * + * Copyright Insight Software Consortium + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0.txt + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *=========================================================================*/ + +#include "itkMultiThreaderBase.h" +#include "itkPlatformMultiThreader.h" +#include "itkPoolMultiThreader.h" +#ifdef ITK_USE_TBB +#include "itkTBBMultiThreader.h" +#endif +#include "itkTestingMacros.h" + +bool VerifyRange(int value, int min, int max, const char * msg) +{ + if( value < min ) + { + std::cerr << msg << std::endl; + return false; + } + + if( value > max ) + { + std::cerr << msg << std::endl; + return false; + } + return true; +} + + +bool SetAndVerifyGlobalMaximumNumberOfThreads( int value ) +{ + itk::MultiThreaderBase::SetGlobalMaximumNumberOfThreads( value ); + return VerifyRange( itk::MultiThreaderBase::GetGlobalMaximumNumberOfThreads(), + 1, ITK_MAX_THREADS, "Range error in MaximumNumberOfThreads"); +} + +bool SetAndVerifyGlobalDefaultNumberOfThreads( int value ) +{ + itk::MultiThreaderBase::SetGlobalDefaultNumberOfThreads( value ); + return VerifyRange( itk::MultiThreaderBase::GetGlobalDefaultNumberOfThreads(), + 1, itk::MultiThreaderBase::GetGlobalMaximumNumberOfThreads(), + "Range error in DefaultNumberOfThreads"); +} + +bool SetAndVerifyMaximumNumberOfThreads( int value, itk::MultiThreaderBase * threader ) +{ + threader->SetMaximumNumberOfThreads( value ); + return VerifyRange( threader->GetMaximumNumberOfThreads(), + 1, itk::MultiThreaderBase::GetGlobalMaximumNumberOfThreads(), + "Range error in MaximumNumberOfThreads"); +} + +bool SetAndVerify( int number ) +{ + bool result = true; + result &= SetAndVerifyGlobalMaximumNumberOfThreads( number ); + result &= SetAndVerifyGlobalDefaultNumberOfThreads( number ); + itk::MultiThreaderBase::Pointer threader = itk::MultiThreaderBase::New(); + // PoolMultiThreader can only increase number of threads + // so make sure to increase this before testing thread count + itk::MultiThreaderBase::SetGlobalMaximumNumberOfThreads( ITK_MAX_THREADS ); + result &= SetAndVerifyMaximumNumberOfThreads( number, threader ); + //number of Work Units is not max-limited by TBBMultiThreader + return result; +} + +#define TEST_SINGLE_CLASS(ClassName) \ +{ \ + itk::ClassName::Pointer threader = itk::ClassName::New(); \ + if ( threader.IsNull() ) \ + { \ + result = false; \ + } \ + \ + EXERCISE_BASIC_OBJECT_METHODS( threader, ClassName, MultiThreaderBase ); \ +} + +int itkMultiThreaderBaseTest(int argc, char* argv[]) +{ + // Choose a number of threads. + int numberOfThreads = 10; + if( argc > 1 ) + { + const int nt = atoi( argv[1] ); + if(nt > 1) + { + numberOfThreads = nt; + } + } + + bool result = true; + TEST_SINGLE_CLASS( PlatformMultiThreader ); + TEST_SINGLE_CLASS( PoolMultiThreader ); +#ifdef ITK_USE_TBB + TEST_SINGLE_CLASS( TBBMultiThreader ); +#endif + + itk::MultiThreaderBase::SetGlobalDefaultNumberOfThreads( numberOfThreads ); + + result &= SetAndVerify( -1 ); + result &= SetAndVerify( 0 ); + result &= SetAndVerify( 1 ); + result &= SetAndVerify( 2 ); + result &= SetAndVerify( ITK_MAX_THREADS ); + result &= SetAndVerify( ITK_MAX_THREADS - 1 ); + result &= SetAndVerify( ITK_MAX_THREADS + 1 ); + result &= SetAndVerify( itk::MultiThreaderBase::GetGlobalMaximumNumberOfThreads() ); + result &= SetAndVerify( itk::MultiThreaderBase::GetGlobalMaximumNumberOfThreads() - 1 ); + result &= SetAndVerify( itk::MultiThreaderBase::GetGlobalMaximumNumberOfThreads() + 1 ); + + if( !result ) + { + return EXIT_FAILURE; + } + return EXIT_SUCCESS; +} diff --git a/Modules/Core/Common/test/itkMultiThreaderParallelizeArrayTest.cxx b/Modules/Core/Common/test/itkMultiThreaderParallelizeArrayTest.cxx index ffdc66541a6..964c54e135a 100644 --- a/Modules/Core/Common/test/itkMultiThreaderParallelizeArrayTest.cxx +++ b/Modules/Core/Common/test/itkMultiThreaderParallelizeArrayTest.cxx @@ -60,7 +60,7 @@ itkMultiThreaderParallelizeArrayTest( int argc, char* argv[] ) if ( argc >= 2 ) { unsigned threadCount = static_cast< unsigned >( atoi( argv[1] ) ); - mt->SetNumberOfThreads( threadCount ); + mt->SetNumberOfWorkUnits( threadCount ); } constexpr unsigned size = 1029; diff --git a/Modules/Core/Common/test/itkPlatformMultiThreaderTest.cxx b/Modules/Core/Common/test/itkPlatformMultiThreaderTest.cxx deleted file mode 100644 index 4ec5e665dab..00000000000 --- a/Modules/Core/Common/test/itkPlatformMultiThreaderTest.cxx +++ /dev/null @@ -1,133 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0.txt - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - *=========================================================================*/ - -#include "itkPlatformMultiThreader.h" -#include "itkTestingMacros.h" - -bool VerifyRange(int value, int min, int max, const char * msg) -{ - if( value < min ) - { - std::cerr << msg << std::endl; - return false; - } - - if( value > max ) - { - std::cerr << msg << std::endl; - return false; - } - return true; -} - - -bool SetAndVerifyGlobalMaximumNumberOfThreads( int value ) -{ - itk::MultiThreaderBase::SetGlobalMaximumNumberOfThreads( value ); - return VerifyRange( itk::MultiThreaderBase::GetGlobalMaximumNumberOfThreads(), - 1, ITK_MAX_THREADS, "Range error in MaximumNumberOfThreads"); -} - -bool SetAndVerifyGlobalDefaultNumberOfThreads( int value ) -{ - itk::MultiThreaderBase::SetGlobalDefaultNumberOfThreads( value ); - return VerifyRange( itk::MultiThreaderBase::GetGlobalDefaultNumberOfThreads(), - 1, itk::MultiThreaderBase::GetGlobalMaximumNumberOfThreads(), - "Range error in DefaultNumberOfThreads"); -} - -bool SetAndVerifyNumberOfThreads( int value, itk::PlatformMultiThreader * threader ) -{ - threader->SetNumberOfThreads( value ); - return VerifyRange( threader->GetNumberOfThreads(), - 1, itk::MultiThreaderBase::GetGlobalMaximumNumberOfThreads(), - "Range error in NumberOfThreads"); -} - -int itkPlatformMultiThreaderTest(int argc, char* argv[]) -{ - // Choose a number of threads. - int numberOfThreads = 10; - if( argc > 1 ) - { - const int nt = atoi( argv[1] ); - if(nt > 1) - { - numberOfThreads = nt; - } - } - - itk::PlatformMultiThreader::Pointer threader = itk::PlatformMultiThreader::New(); - if(threader.IsNull()) - { - return EXIT_FAILURE; - } - - EXERCISE_BASIC_OBJECT_METHODS(threader, PlatformMultiThreader, MultiThreaderBase); - - itk::MultiThreaderBase::SetGlobalDefaultNumberOfThreads( numberOfThreads ); - - { - // Test settings for GlobalMaximumNumberOfThreads - - bool result = true; - - result &= SetAndVerifyGlobalMaximumNumberOfThreads( -1 ); - result &= SetAndVerifyGlobalMaximumNumberOfThreads( 0 ); - result &= SetAndVerifyGlobalMaximumNumberOfThreads( 1 ); - result &= SetAndVerifyGlobalMaximumNumberOfThreads( 2 ); - result &= SetAndVerifyGlobalMaximumNumberOfThreads( ITK_MAX_THREADS ); - result &= SetAndVerifyGlobalMaximumNumberOfThreads( ITK_MAX_THREADS - 1 ); - result &= SetAndVerifyGlobalMaximumNumberOfThreads( ITK_MAX_THREADS + 1 ); - - if( !result ) - { - return EXIT_FAILURE; - } - - - result &= SetAndVerifyGlobalDefaultNumberOfThreads( -1 ); - result &= SetAndVerifyGlobalDefaultNumberOfThreads( 0 ); - result &= SetAndVerifyGlobalDefaultNumberOfThreads( 1 ); - result &= SetAndVerifyGlobalDefaultNumberOfThreads( itk::MultiThreaderBase::GetGlobalMaximumNumberOfThreads() ); - result &= SetAndVerifyGlobalDefaultNumberOfThreads( itk::MultiThreaderBase::GetGlobalMaximumNumberOfThreads() - 1 ); - result &= SetAndVerifyGlobalDefaultNumberOfThreads( itk::MultiThreaderBase::GetGlobalMaximumNumberOfThreads() + 1 ); - - if( !result ) - { - return EXIT_FAILURE; - } - - itk::PlatformMultiThreader::Pointer threader2 = itk::PlatformMultiThreader::New(); - - result &= SetAndVerifyNumberOfThreads( -1, threader2 ); - result &= SetAndVerifyNumberOfThreads( 0, threader2 ); - result &= SetAndVerifyNumberOfThreads( 1, threader2 ); - result &= SetAndVerifyNumberOfThreads( itk::MultiThreaderBase::GetGlobalMaximumNumberOfThreads(), threader2 ); - result &= SetAndVerifyNumberOfThreads( itk::MultiThreaderBase::GetGlobalMaximumNumberOfThreads() - 1, threader2); - result &= SetAndVerifyNumberOfThreads( itk::MultiThreaderBase::GetGlobalMaximumNumberOfThreads() + 1, threader2); - - if( !result ) - { - return EXIT_FAILURE; - } - - } - - return EXIT_SUCCESS; -} diff --git a/Modules/Core/Common/test/itkSTLThreadTest.cxx b/Modules/Core/Common/test/itkSTLThreadTest.cxx index dd273fc92a7..5897b5cb8c4 100644 --- a/Modules/Core/Common/test/itkSTLThreadTest.cxx +++ b/Modules/Core/Common/test/itkSTLThreadTest.cxx @@ -83,7 +83,7 @@ int itkSTLThreadTest(int argc, char* argv[]) itk::PlatformMultiThreader::Pointer threader = itk::PlatformMultiThreader::New(); itkSTLThreadTestImpl::sharedMutex = itk::MutexLock::New(); threader->SetSingleMethod(itkSTLThreadTestImpl::Runner, results); - threader->SetNumberOfThreads(numThreads); + threader->SetNumberOfWorkUnits(numThreads); threader->SingleMethodExecute(); // Report results. @@ -126,8 +126,8 @@ static ITK_THREAD_RETURN_TYPE Runner(void* infoIn) { // Get the thread id and result pointer and run the method for this // thread. - auto * info = static_cast(infoIn); - itk::ThreadIdType tnum = info->ThreadID; + auto * info = static_cast(infoIn); + itk::ThreadIdType tnum = info->WorkUnitID; auto * results = static_cast(info->UserData); if(results) { diff --git a/Modules/Core/Common/test/itkSpawnThreadTest.cxx b/Modules/Core/Common/test/itkSpawnThreadTest.cxx index b08b16e3991..2cd12ff532e 100644 --- a/Modules/Core/Common/test/itkSpawnThreadTest.cxx +++ b/Modules/Core/Common/test/itkSpawnThreadTest.cxx @@ -24,24 +24,19 @@ typedef struct { - int numberOfLoop; + int numberOfLoop; itk::MutexLock::Pointer sharedMutex; } SharedThreadData; void* ThreadFunction(void *ptr) { - // Retrieve shared thread data and user data - auto * threadInfo = static_cast(ptr); - - itk::ThreadIdType localthreadId = threadInfo->ThreadID; - - auto * localThreadData = static_cast(threadInfo->UserData); - - int localnumberOfLoop = localThreadData->numberOfLoop; + auto * workUnitInfo = static_cast(ptr); + itk::ThreadIdType localthreadId = workUnitInfo->WorkUnitID; + auto * localThreadData = static_cast(workUnitInfo->UserData); + int localnumberOfLoop = localThreadData->numberOfLoop; itk::MutexLock::Pointer localMutex = localThreadData->sharedMutex; - // Loop for (int i = 0; i < localnumberOfLoop; ++i) { localMutex->Lock(); diff --git a/Modules/Core/Common/test/itkThreadLoggerTest.cxx b/Modules/Core/Common/test/itkThreadLoggerTest.cxx index 361a04b8e4c..fc94b582c75 100644 --- a/Modules/Core/Common/test/itkThreadLoggerTest.cxx +++ b/Modules/Core/Common/test/itkThreadLoggerTest.cxx @@ -59,10 +59,10 @@ class LogTester ITK_THREAD_RETURN_TYPE ThreadedGenerateLogMessages(void* arg) { - const auto* threadInfo = static_cast(arg); + const auto* threadInfo = static_cast(arg); if (threadInfo) { - const unsigned int threadId = threadInfo->ThreadID; + const unsigned int threadId = threadInfo->WorkUnitID; std::string threadPrefix; { std::ostringstream msg; @@ -90,7 +90,7 @@ ITK_THREAD_RETURN_TYPE ThreadedGenerateLogMessages(void* arg) return ITK_THREAD_RETURN_VALUE; } } else { - std::cerr << "ERROR: arg was not of type itk::PlatformMultiThreader::ThreadInfoStruct*" << std::endl; + std::cerr << "ERROR: arg was not of type itk::MultiThreaderBase::WorkUnitInfo*" << std::endl; return ITK_THREAD_RETURN_VALUE; } return ITK_THREAD_RETURN_VALUE; @@ -178,7 +178,7 @@ int itkThreadLoggerTest( int argc, char * argv[] ) ThreadDataVec threadData = create_threaded_data(numthreads, logger); itk::MultiThreaderBase::Pointer threader = itk::MultiThreaderBase::New(); itk::MultiThreaderBase::SetGlobalMaximumNumberOfThreads(numthreads + 10); - threader->SetNumberOfThreads(numthreads); + threader->SetNumberOfWorkUnits(numthreads); threader->SetSingleMethod(ThreadedGenerateLogMessages, &threadData); threader->SingleMethodExecute(); logger->Flush(); diff --git a/Modules/Core/Common/test/itkThreadPoolTest.cxx b/Modules/Core/Common/test/itkThreadPoolTest.cxx index 469d139a99e..9263f1dd149 100644 --- a/Modules/Core/Common/test/itkThreadPoolTest.cxx +++ b/Modules/Core/Common/test/itkThreadPoolTest.cxx @@ -26,7 +26,7 @@ itk::MutexLock::Pointer sharedMutex; ITK_THREAD_RETURN_TYPE execute(void *ptr) { // Here - get any args from ptr. - auto * threadInfo = static_cast(ptr); + auto * threadInfo = static_cast(ptr); auto * data = static_cast(threadInfo->UserData); diff --git a/Modules/Core/Common/test/itkThreadedIndexedContainerPartitionerTest.cxx b/Modules/Core/Common/test/itkThreadedIndexedContainerPartitionerTest.cxx index a47e8447bed..c8930091464 100644 --- a/Modules/Core/Common/test/itkThreadedIndexedContainerPartitionerTest.cxx +++ b/Modules/Core/Common/test/itkThreadedIndexedContainerPartitionerTest.cxx @@ -117,7 +117,7 @@ int ThreadedIndexedContainerPartitionerRunTest( // Exercise GetMultiThreader(). domainThreader->GetMultiThreader(); domainThreader->SetMaximumNumberOfThreads( numberOfThreads ); - // Possible if numberOfThreads < GlobalMaximumNumberOfThreads + // Possible if numberOfThreads > GlobalMaximumNumberOfThreads if( domainThreader->GetMaximumNumberOfThreads() < numberOfThreads ) { std::cerr << "Failed setting requested number of threads: " @@ -127,6 +127,17 @@ int ThreadedIndexedContainerPartitionerRunTest( return EXIT_FAILURE; } + domainThreader->SetNumberOfWorkUnits(numberOfThreads); + // Possible if numberOfThreads > GlobalMaximumNumberOfThreads + if( domainThreader->GetNumberOfWorkUnits() != numberOfThreads ) + { + std::cerr << "Failed setting requested number of work units: " + << numberOfThreads << std::endl + << "domainThreader->GetNumberOfWorkUnits(): " + << domainThreader->GetNumberOfWorkUnits() << std::endl; + return EXIT_FAILURE; + } + enclosingClass.Execute( fullRange ); /* Did we use as many threads as requested? */ @@ -193,7 +204,8 @@ int itkThreadedIndexedContainerPartitionerTest(int, char* []) std::cout << "GetGlobalDefaultNumberOfThreads: " << domainThreader->GetMultiThreader()->GetGlobalDefaultNumberOfThreads() << std::endl; - std::cout << "domainThreader->GetMultiThreader()->NumberOfThreads(): " << domainThreader->GetMultiThreader()->GetNumberOfThreads() + std::cout << "domainThreader->GetMultiThreader()->NumberOfWorkUnits(): " + << domainThreader->GetMultiThreader()->GetNumberOfWorkUnits() << std::endl; using DomainType = DomainThreaderAssociate::TestDomainThreader::DomainType; @@ -201,7 +213,7 @@ int itkThreadedIndexedContainerPartitionerTest(int, char* []) /* Test with single thread */ fullRange[0] = 0; - fullRange[1] = 102; //set total range to prime to test uneven division + fullRange[1] = 103; //set total range to prime to test uneven division itk::ThreadIdType numberOfThreads = 1; if( ThreadedIndexedContainerPartitionerRunTest( enclosingClass, numberOfThreads, fullRange ) != EXIT_SUCCESS ) @@ -211,7 +223,7 @@ int itkThreadedIndexedContainerPartitionerTest(int, char* []) /* Test with range that doesn't start at 0 */ fullRange[0] = 2; - fullRange[1] = 104; //set total range to prime to test uneven division + fullRange[1] = 105; //set total range to prime to test uneven division numberOfThreads = 1; if( ThreadedIndexedContainerPartitionerRunTest( enclosingClass, numberOfThreads, fullRange ) != EXIT_SUCCESS ) @@ -224,7 +236,7 @@ int itkThreadedIndexedContainerPartitionerTest(int, char* []) { /* Test with default number of threads. */ fullRange[0] = 6; - fullRange[1] = 108; //set total range to prime to test uneven division + fullRange[1] = 109; //set total range to prime to test uneven division numberOfThreads = domainThreader->GetMultiThreader()->GetGlobalDefaultNumberOfThreads(); if( ThreadedIndexedContainerPartitionerRunTest( enclosingClass, numberOfThreads, fullRange ) diff --git a/Modules/Core/Common/test/itkThreadedIteratorRangePartitionerTest.cxx b/Modules/Core/Common/test/itkThreadedIteratorRangePartitionerTest.cxx index 3e728cb1502..29673d08040 100644 --- a/Modules/Core/Common/test/itkThreadedIteratorRangePartitionerTest.cxx +++ b/Modules/Core/Common/test/itkThreadedIteratorRangePartitionerTest.cxx @@ -127,7 +127,7 @@ namespace // Exercise GetMultiThreader(). domainThreader->GetMultiThreader(); domainThreader->SetMaximumNumberOfThreads( numberOfThreads ); - // Possible if numberOfThreads < GlobalMaximumNumberOfThreads + // Possible if numberOfThreads > GlobalMaximumNumberOfThreads if( domainThreader->GetMaximumNumberOfThreads() < numberOfThreads ) { std::cerr << "Failed setting requested number of threads: " @@ -137,6 +137,17 @@ namespace return EXIT_FAILURE; } + domainThreader->SetNumberOfWorkUnits(numberOfThreads); + // Possible if numberOfThreads > GlobalMaximumNumberOfThreads + if( domainThreader->GetNumberOfWorkUnits() != numberOfThreads ) + { + std::cerr << "Failed setting requested number of work units: " + << numberOfThreads << std::endl + << "domainThreader->GetNumberOfWorkUnits(): " + << domainThreader->GetNumberOfWorkUnits() << std::endl; + return EXIT_FAILURE; + } + enclosingClass.Execute( fullDomain ); /* Did we use as many threads as requested? */ @@ -233,7 +244,8 @@ int itkThreadedIteratorRangePartitionerTest(int, char* []) std::cout << "GetGlobalDefaultNumberOfThreads: " << domainThreader->GetMultiThreader()->GetGlobalDefaultNumberOfThreads() << std::endl; - std::cout << "domainThreader->GetMultiThreader()->NumberOfThreads(): " << domainThreader->GetMultiThreader()->GetNumberOfThreads() + std::cout << "domainThreader->GetMultiThreader()->NumberOfWorkUnits(): " + << domainThreader->GetMultiThreader()->GetNumberOfWorkUnits() << std::endl; using DomainType = IteratorRangeDomainThreaderAssociate::TestDomainThreader::DomainType; @@ -279,15 +291,15 @@ int itkThreadedIteratorRangePartitionerTest(int, char* []) * many as is reasonable. */ itk::ThreadIdType maxNumberOfThreads = domainThreader->GetMultiThreader()->GetGlobalMaximumNumberOfThreads(); - setStartEnd( 6, 6+maxNumberOfThreads/2, container, fullDomain ); + setStartEnd( 6, 6+maxNumberOfThreads, container, fullDomain ); if( ThreadedIteratorRangePartitionerRunTest( enclosingClass, maxNumberOfThreads, fullDomain ) != EXIT_SUCCESS ) { return EXIT_FAILURE; } - if( domainThreader->GetNumberOfWorkUnitsUsed() != maxNumberOfThreads-1 ) + if( domainThreader->GetNumberOfWorkUnitsUsed() != maxNumberOfThreads ) { - std::cerr << "Error: Expected to use only " << maxNumberOfThreads-1 + std::cerr << "Error: Expected to use " << maxNumberOfThreads << "threads, but used " << domainThreader->GetNumberOfWorkUnitsUsed() << "." << std::endl; } diff --git a/Modules/Core/Common/test/itkThreadedIteratorRangePartitionerTest2.cxx b/Modules/Core/Common/test/itkThreadedIteratorRangePartitionerTest2.cxx index bbc4cba9495..096a577386a 100644 --- a/Modules/Core/Common/test/itkThreadedIteratorRangePartitionerTest2.cxx +++ b/Modules/Core/Common/test/itkThreadedIteratorRangePartitionerTest2.cxx @@ -131,7 +131,7 @@ namespace // Exercise GetMultiThreader(). domainThreader->GetMultiThreader(); domainThreader->SetMaximumNumberOfThreads( numberOfThreads ); - // Possible if numberOfThreads < GlobalMaximumNumberOfThreads + // Possible if numberOfThreads > GlobalMaximumNumberOfThreads if( domainThreader->GetMaximumNumberOfThreads() < numberOfThreads ) { std::cerr << "Failed setting requested number of threads: " @@ -141,6 +141,17 @@ namespace return EXIT_FAILURE; } + domainThreader->SetNumberOfWorkUnits(numberOfThreads); + // Possible if numberOfThreads > GlobalMaximumNumberOfThreads + if( domainThreader->GetNumberOfWorkUnits() != numberOfThreads ) + { + std::cerr << "Failed setting requested number of work units: " + << numberOfThreads << std::endl + << "domainThreader->GetNumberOfWorkUnits(): " + << domainThreader->GetNumberOfWorkUnits() << std::endl; + return EXIT_FAILURE; + } + enclosingClass.Execute( fullDomain ); /* Did we use as many threads as requested? */ @@ -241,7 +252,8 @@ int itkThreadedIteratorRangePartitionerTest2(int, char* []) std::cout << "GetGlobalDefaultNumberOfThreads: " << domainThreader->GetMultiThreader()->GetGlobalDefaultNumberOfThreads() << std::endl; - std::cout << "domainThreader->GetMultiThreader()->NumberOfThreads(): " << domainThreader->GetMultiThreader()->GetNumberOfThreads() + std::cout << "domainThreader->GetMultiThreader()->NumberOfWorkUnits(): " + << domainThreader->GetMultiThreader()->GetNumberOfWorkUnits() << std::endl; } else @@ -296,15 +308,15 @@ int itkThreadedIteratorRangePartitionerTest2(int, char* []) * many as is reasonable. */ itk::ThreadIdType maxNumberOfThreads = domainThreader->GetMultiThreader()->GetGlobalMaximumNumberOfThreads(); - setStartEnd( 6, 6+maxNumberOfThreads/2, container, fullDomain ); + setStartEnd( 6, 6+maxNumberOfThreads, container, fullDomain ); if( ThreadedIteratorRangePartitionerRunTest( enclosingClass, maxNumberOfThreads, fullDomain ) != EXIT_SUCCESS ) { return EXIT_FAILURE; } - if( domainThreader->GetNumberOfWorkUnitsUsed() != maxNumberOfThreads-1 ) + if( domainThreader->GetNumberOfWorkUnitsUsed() != maxNumberOfThreads ) { - std::cerr << "Error: Expected to use only " << maxNumberOfThreads-1 + std::cerr << "Error: Expected to use only " << maxNumberOfThreads << "threads, but used " << domainThreader->GetNumberOfWorkUnitsUsed() << "." << std::endl; } diff --git a/Modules/Core/Common/test/itkThreadedIteratorRangePartitionerTest3.cxx b/Modules/Core/Common/test/itkThreadedIteratorRangePartitionerTest3.cxx index 234a82a9a30..fdef0fdca10 100644 --- a/Modules/Core/Common/test/itkThreadedIteratorRangePartitionerTest3.cxx +++ b/Modules/Core/Common/test/itkThreadedIteratorRangePartitionerTest3.cxx @@ -131,7 +131,7 @@ namespace // Exercise GetMultiThreader(). domainThreader->GetMultiThreader(); domainThreader->SetMaximumNumberOfThreads( numberOfThreads ); - // Possible if numberOfThreads < GlobalMaximumNumberOfThreads + // Possible if numberOfThreads > GlobalMaximumNumberOfThreads if( domainThreader->GetMaximumNumberOfThreads() < numberOfThreads ) { std::cerr << "Failed setting requested number of threads: " @@ -141,6 +141,17 @@ namespace return EXIT_FAILURE; } + domainThreader->SetNumberOfWorkUnits(numberOfThreads); + // Possible if numberOfThreads > GlobalMaximumNumberOfThreads + if( domainThreader->GetNumberOfWorkUnits() != numberOfThreads ) + { + std::cerr << "Failed setting requested number of work units: " + << numberOfThreads << std::endl + << "domainThreader->GetNumberOfWorkUnits(): " + << domainThreader->GetNumberOfWorkUnits() << std::endl; + return EXIT_FAILURE; + } + enclosingClass.Execute( fullDomain ); /* Did we use as many threads as requested? */ @@ -241,7 +252,8 @@ int itkThreadedIteratorRangePartitionerTest3(int, char* []) std::cout << "GetGlobalDefaultNumberOfThreads: " << domainThreader->GetMultiThreader()->GetGlobalDefaultNumberOfThreads() << std::endl; - std::cout << "domainThreader->GetMultiThreader()->NumberOfThreads(): " << domainThreader->GetMultiThreader()->GetNumberOfThreads() + std::cout << "domainThreader->GetMultiThreader()->NumberOfWorkUnits(): " + << domainThreader->GetMultiThreader()->GetNumberOfWorkUnits() << std::endl; } else @@ -295,15 +307,15 @@ int itkThreadedIteratorRangePartitionerTest3(int, char* []) * many as is reasonable. */ itk::ThreadIdType maxNumberOfThreads = domainThreader->GetMultiThreader()->GetGlobalMaximumNumberOfThreads(); - setStartEnd( 6, 6+maxNumberOfThreads/2, container, fullDomain ); + setStartEnd( 6, 6+maxNumberOfThreads, container, fullDomain ); if( ThreadedIteratorRangePartitionerRunTest( enclosingClass, maxNumberOfThreads, fullDomain ) != EXIT_SUCCESS ) { return EXIT_FAILURE; } - if( domainThreader->GetNumberOfWorkUnitsUsed() != maxNumberOfThreads-1 ) + if( domainThreader->GetNumberOfWorkUnitsUsed() != maxNumberOfThreads ) { - std::cerr << "Error: Expected to use only " << maxNumberOfThreads-1 + std::cerr << "Error: Expected to use only " << maxNumberOfThreads << "threads, but used " << domainThreader->GetNumberOfWorkUnitsUsed() << "." << std::endl; } diff --git a/Modules/Core/Common/test/itkTimeStampTest.cxx b/Modules/Core/Common/test/itkTimeStampTest.cxx index d367d8d4415..4863399db92 100644 --- a/Modules/Core/Common/test/itkTimeStampTest.cxx +++ b/Modules/Core/Common/test/itkTimeStampTest.cxx @@ -31,11 +31,11 @@ typedef struct { ITK_THREAD_RETURN_TYPE modified_function( void *ptr ) { - using ThreadInfoType = itk::MultiThreaderBase::ThreadInfoStruct; + using ThreadInfoType = itk::MultiThreaderBase::WorkUnitInfo; auto * infoStruct = static_cast< ThreadInfoType * >( ptr ); - const itk::ThreadIdType threadId = infoStruct->ThreadID; + const itk::ThreadIdType threadId = infoStruct->WorkUnitID; auto * helper = static_cast< TimeStampTestHelper * >( infoStruct->UserData ); @@ -55,11 +55,11 @@ int itkTimeStampTest(int, char*[]) // Set up the multithreader itk::MultiThreaderBase::Pointer multithreader = itk::MultiThreaderBase::New(); - multithreader->SetNumberOfThreads( ITK_MAX_THREADS+10 );// this will be clamped + multithreader->SetNumberOfWorkUnits( ITK_MAX_THREADS+10 );// this will be clamped multithreader->SetSingleMethod( modified_function, &helper); // Test that the number of threads has actually been clamped - const itk::ThreadIdType numberOfThreads = multithreader->GetNumberOfThreads(); + const itk::ThreadIdType numberOfThreads = multithreader->GetMaximumNumberOfThreads(); if( numberOfThreads > ITK_MAX_THREADS ) { @@ -68,17 +68,19 @@ int itkTimeStampTest(int, char*[]) return EXIT_FAILURE; } + const itk::ThreadIdType numberOfWorkUnits = multithreader->GetNumberOfWorkUnits(); + // Set up the helper class - helper.counters.resize( numberOfThreads ); - helper.timestamps.resize( numberOfThreads ); - for(itk::ThreadIdType k=0; k < numberOfThreads; k++) + helper.counters.resize( numberOfWorkUnits ); + helper.timestamps.resize( numberOfWorkUnits ); + for(itk::ThreadIdType k=0; k < numberOfWorkUnits; k++) { helper.counters[k] = 0; } // Declare an array to test whether the all modified times have // been used - std::vector istimestamped( numberOfThreads ); + std::vector istimestamped( numberOfWorkUnits ); // Call Modified once on any object to make it up-to-date multithreader->Modified(); @@ -96,7 +98,7 @@ int itkTimeStampTest(int, char*[]) itk::ModifiedTimeType min_mtime = helper.timestamps[0].GetMTime(); itk::ModifiedTimeType max_mtime = helper.timestamps[0].GetMTime(); - for(itk::ThreadIdType k=0; k < numberOfThreads; k++) + for(itk::ThreadIdType k=0; k < numberOfWorkUnits; k++) { const itk::ModifiedTimeType & mtime = helper.timestamps[k].GetMTime(); if ( mtime > max_mtime ) @@ -113,12 +115,12 @@ int itkTimeStampTest(int, char*[]) } bool iter_success = - ( ((max_mtime-prev_mtime ) == numberOfThreads) && + ( ((max_mtime-prev_mtime ) == numberOfWorkUnits) && (min_mtime==prev_mtime+1) ); if ( iter_success ) { - for(itk::ThreadIdType k=0; k < numberOfThreads; k++) + for(itk::ThreadIdType k=0; k < numberOfWorkUnits; k++) { // Test whether the all modified times have // been used @@ -151,11 +153,12 @@ int itkTimeStampTest(int, char*[]) std::cerr << "min_mtime : " << min_mtime << std::endl; std::cerr << "prev_mtime : " << prev_mtime << std::endl; std::cerr << "num_threads : " << numberOfThreads << std::endl; + std::cerr << "num_work_units : " << numberOfWorkUnits << std::endl; std::cerr << "max - prev mtime: " << max_mtime - prev_mtime << std::endl; std::cerr << std::endl; success = false; - // Note that in a more general setting, (max_mtime-prev_mtime)>numberOfThreads + // Note that in a more general setting, (max_mtime-prev_mtime)>numberOfWorkUnits // might be a normal case since the modified time of a time stamp // is global. If a new itk object is created this will also increment // the time. In our specific test, there's no reason for another ITK object to be diff --git a/Modules/Core/FiniteDifference/include/itkDenseFiniteDifferenceImageFilter.hxx b/Modules/Core/FiniteDifference/include/itkDenseFiniteDifferenceImageFilter.hxx index 4749b598356..021abc249bd 100644 --- a/Modules/Core/FiniteDifference/include/itkDenseFiniteDifferenceImageFilter.hxx +++ b/Modules/Core/FiniteDifference/include/itkDenseFiniteDifferenceImageFilter.hxx @@ -90,7 +90,7 @@ DenseFiniteDifferenceImageFilter< TInputImage, TOutputImage > str.Filter = this; str.TimeStep = dt; - this->GetMultiThreader()->SetNumberOfThreads( this->GetNumberOfWorkUnits() ); + this->GetMultiThreader()->SetNumberOfWorkUnits( this->GetNumberOfWorkUnits() ); this->GetMultiThreader()->SetSingleMethod(this->ApplyUpdateThreaderCallback, &str); // Multithread the execution @@ -108,10 +108,10 @@ ITK_THREAD_RETURN_TYPE DenseFiniteDifferenceImageFilter< TInputImage, TOutputImage > ::ApplyUpdateThreaderCallback(void *arg) { - ThreadIdType threadId = ( (MultiThreaderBase::ThreadInfoStruct *)( arg ) )->ThreadID; - ThreadIdType threadCount = ( (MultiThreaderBase::ThreadInfoStruct *)( arg ) )->NumberOfThreads; + ThreadIdType threadId = ( (MultiThreaderBase::WorkUnitInfo *)( arg ) )->WorkUnitID; + ThreadIdType threadCount = ( (MultiThreaderBase::WorkUnitInfo *)( arg ) )->NumberOfWorkUnits; - auto * str = (DenseFDThreadStruct *) ( ( (MultiThreaderBase::ThreadInfoStruct *)( arg ) )->UserData ); + auto * str = (DenseFDThreadStruct *) ( ( (MultiThreaderBase::WorkUnitInfo *)( arg ) )->UserData ); // Execute the actual method with appropriate output region // first find out how many pieces extent can be split into. @@ -140,14 +140,14 @@ DenseFiniteDifferenceImageFilter< TInputImage, TOutputImage > str.Filter = this; str.TimeStep = NumericTraits< TimeStepType >::ZeroValue(); // Not used during the // calculate change step. - this->GetMultiThreader()->SetNumberOfThreads( this->GetNumberOfWorkUnits() ); + this->GetMultiThreader()->SetNumberOfWorkUnits( this->GetNumberOfWorkUnits() ); this->GetMultiThreader()->SetSingleMethod(this->CalculateChangeThreaderCallback, &str); // Initialize the list of time step values that will be generated by the // various threads. There is one distinct slot for each possible thread, // so this data structure is thread-safe. - ThreadIdType threadCount = this->GetMultiThreader()->GetNumberOfThreads(); + ThreadIdType threadCount = this->GetMultiThreader()->GetNumberOfWorkUnits(); str.TimeStepList.clear(); str.TimeStepList.resize( threadCount, NumericTraits< TimeStepType >::ZeroValue() ); @@ -176,10 +176,10 @@ ITK_THREAD_RETURN_TYPE DenseFiniteDifferenceImageFilter< TInputImage, TOutputImage > ::CalculateChangeThreaderCallback(void *arg) { - ThreadIdType threadId = ( (MultiThreaderBase::ThreadInfoStruct *)( arg ) )->ThreadID; - ThreadIdType threadCount = ( (MultiThreaderBase::ThreadInfoStruct *)( arg ) )->NumberOfThreads; + ThreadIdType threadId = ( (MultiThreaderBase::WorkUnitInfo *)( arg ) )->WorkUnitID; + ThreadIdType threadCount = ( (MultiThreaderBase::WorkUnitInfo *)( arg ) )->NumberOfWorkUnits; - auto * str = (DenseFDThreadStruct *) ( ( (MultiThreaderBase::ThreadInfoStruct *)( arg ) )->UserData ); + auto * str = (DenseFDThreadStruct *) ( ( (MultiThreaderBase::WorkUnitInfo *)( arg ) )->UserData ); // Execute the actual method with appropriate output region // first find out how many pieces extent can be split into. diff --git a/Modules/Core/FiniteDifference/include/itkFiniteDifferenceImageFilter.h b/Modules/Core/FiniteDifference/include/itkFiniteDifferenceImageFilter.h index 3c645c54205..d3643f95132 100644 --- a/Modules/Core/FiniteDifference/include/itkFiniteDifferenceImageFilter.h +++ b/Modules/Core/FiniteDifference/include/itkFiniteDifferenceImageFilter.h @@ -276,7 +276,7 @@ class ITK_TEMPLATE_EXPORT FiniteDifferenceImageFilter: /** This method is similar to Halt(), and its default implementation in this * class is simply to call Halt(). However, this method takes as a parameter - * a void pointer to the MultiThreaderBase::ThreadInfoStruct structure. If you + * a void pointer to the MultiThreaderBase::WorkUnitInfo structure. If you * override this method instead of overriding Halt, you will be able to get * the current thread ID and handle the Halt method accordingly. This is useful * if you are doing a lot of processing in Halt that you don't want parallelized. diff --git a/Modules/Core/FiniteDifference/include/itkFiniteDifferenceSparseImageFilter.hxx b/Modules/Core/FiniteDifference/include/itkFiniteDifferenceSparseImageFilter.hxx index 882a5e69cca..ac9fc534bb7 100644 --- a/Modules/Core/FiniteDifference/include/itkFiniteDifferenceSparseImageFilter.hxx +++ b/Modules/Core/FiniteDifference/include/itkFiniteDifferenceSparseImageFilter.hxx @@ -85,7 +85,7 @@ FiniteDifferenceSparseImageFilter< TInputImageType, TSparseOutputImageType > str.Filter = this; str.TimeStep = dt; - this->GetMultiThreader()->SetNumberOfThreads( this->GetNumberOfWorkUnits() ); + this->GetMultiThreader()->SetNumberOfWorkUnits( this->GetNumberOfWorkUnits() ); this->GetMultiThreader()->SetSingleMethod(this->ApplyUpdateThreaderCallback, &str); // Multithread the execution @@ -100,10 +100,10 @@ FiniteDifferenceSparseImageFilter< TInputImageType, TSparseOutputImageType > FDThreadStruct *str; ThreadIdType total, threadId, threadCount; - threadId = ( (MultiThreaderBase::ThreadInfoStruct *)( arg ) )->ThreadID; - threadCount = ( (MultiThreaderBase::ThreadInfoStruct *)( arg ) )->NumberOfThreads; + threadId = ( (MultiThreaderBase::WorkUnitInfo *)( arg ) )->WorkUnitID; + threadCount = ( (MultiThreaderBase::WorkUnitInfo *)( arg ) )->NumberOfWorkUnits; str = (FDThreadStruct *) - ( ( (MultiThreaderBase::ThreadInfoStruct *)( arg ) )->UserData ); + ( ( (MultiThreaderBase::WorkUnitInfo *)( arg ) )->UserData ); // Execute the actual method with appropriate output region // first find out how many pieces extent can be split into. @@ -148,7 +148,7 @@ FiniteDifferenceSparseImageFilter< TInputImageType, TSparseOutputImageType > str.Filter = this; - this->GetMultiThreader()->SetNumberOfThreads( this->GetNumberOfWorkUnits() ); + this->GetMultiThreader()->SetNumberOfWorkUnits( this->GetNumberOfWorkUnits() ); this->GetMultiThreader()->SetSingleMethod (this->PrecalculateChangeThreaderCallback, &str); @@ -173,7 +173,7 @@ FiniteDifferenceSparseImageFilter< TInputImageType, TSparseOutputImageType > str.TimeStep = NumericTraits< TimeStepType >::ZeroValue(); // Not used during the calculate change step for normals. - this->GetMultiThreader()->SetNumberOfThreads( this->GetNumberOfWorkUnits() ); + this->GetMultiThreader()->SetNumberOfWorkUnits( this->GetNumberOfWorkUnits() ); this->GetMultiThreader()->SetSingleMethod (this->CalculateChangeThreaderCallback, &str); @@ -181,7 +181,7 @@ FiniteDifferenceSparseImageFilter< TInputImageType, TSparseOutputImageType > // various threads. There is one distinct slot for each possible thread, // so this data structure is thread-safe. All of the time steps calculated // in each thread will be combined in the ResolveTimeStepMethod. - ThreadIdType threadCount = this->GetMultiThreader()->GetNumberOfThreads(); + ThreadIdType threadCount = this->GetMultiThreader()->GetNumberOfWorkUnits(); str.TimeStepList.resize(threadCount, false); str.ValidTimeStepList.resize(threadCount); @@ -207,11 +207,11 @@ FiniteDifferenceSparseImageFilter< TInputImageType, TSparseOutputImageType > FDThreadStruct *str; ThreadIdType total, threadId, threadCount; - threadId = ( (MultiThreaderBase::ThreadInfoStruct *)( arg ) )->ThreadID; - threadCount = ( (MultiThreaderBase::ThreadInfoStruct *)( arg ) )->NumberOfThreads; + threadId = ( (MultiThreaderBase::WorkUnitInfo *)( arg ) )->WorkUnitID; + threadCount = ( (MultiThreaderBase::WorkUnitInfo *)( arg ) )->NumberOfWorkUnits; str = (FDThreadStruct *) - ( ( (MultiThreaderBase::ThreadInfoStruct *)( arg ) )->UserData ); + ( ( (MultiThreaderBase::WorkUnitInfo *)( arg ) )->UserData ); // Execute the actual method with appropriate output region // first find out how many pieces extent can be split into. @@ -238,11 +238,11 @@ FiniteDifferenceSparseImageFilter< TInputImageType, TSparseOutputImageType > FDThreadStruct *str; ThreadIdType total, threadId, threadCount; - threadId = ( (MultiThreaderBase::ThreadInfoStruct *)( arg ) )->ThreadID; - threadCount = ( (MultiThreaderBase::ThreadInfoStruct *)( arg ) )->NumberOfThreads; + threadId = ( (MultiThreaderBase::WorkUnitInfo *)( arg ) )->WorkUnitID; + threadCount = ( (MultiThreaderBase::WorkUnitInfo *)( arg ) )->NumberOfWorkUnits; str = (FDThreadStruct *) - ( ( (MultiThreaderBase::ThreadInfoStruct *)( arg ) )->UserData ); + ( ( (MultiThreaderBase::WorkUnitInfo *)( arg ) )->UserData ); // Execute the actual method with appropriate output region // first find out how many pieces extent can be split into. diff --git a/Modules/Core/GPUFiniteDifference/include/itkGPUFiniteDifferenceImageFilter.h b/Modules/Core/GPUFiniteDifference/include/itkGPUFiniteDifferenceImageFilter.h index 45fd3300fe1..3b13ce65468 100644 --- a/Modules/Core/GPUFiniteDifference/include/itkGPUFiniteDifferenceImageFilter.h +++ b/Modules/Core/GPUFiniteDifference/include/itkGPUFiniteDifferenceImageFilter.h @@ -178,7 +178,7 @@ class ITK_TEMPLATE_EXPORT GPUFiniteDifferenceImageFilter : /** This method is similar to Halt(), and its default implementation in this * class is simply to call Halt(). However, this method takes as a parameter - * a void pointer to the MultiThreaderBase::ThreadInfoStruct structure. If you + * a void pointer to the MultiThreaderBase::WorkUnitInfo structure. If you * override this method instead of overriding Halt, you will be able to get * the current thread ID and handle the Halt method accordingly. This is useful * if you are doing a lot of processing in Halt that you don't want parallelized. diff --git a/Modules/Core/Transform/test/itkTestTransformGetInverse.cxx b/Modules/Core/Transform/test/itkTestTransformGetInverse.cxx index e8aff34e6ad..da567177033 100644 --- a/Modules/Core/Transform/test/itkTestTransformGetInverse.cxx +++ b/Modules/Core/Transform/test/itkTestTransformGetInverse.cxx @@ -65,7 +65,7 @@ template ITK_THREAD_RETURN_TYPE TestGetInverseThreadFunction(void *perThreadData) { - auto * ti = static_cast(perThreadData); + auto * ti = static_cast(perThreadData); auto * td = static_cast *>(ti->UserData); for(unsigned int i = 0; i < 100000; ++i) { diff --git a/Modules/Filtering/Denoising/include/itkPatchBasedDenoisingImageFilter.hxx b/Modules/Filtering/Denoising/include/itkPatchBasedDenoisingImageFilter.hxx index 021072eb19e..8c480e72a5e 100644 --- a/Modules/Filtering/Denoising/include/itkPatchBasedDenoisingImageFilter.hxx +++ b/Modules/Filtering/Denoising/include/itkPatchBasedDenoisingImageFilter.hxx @@ -690,7 +690,7 @@ PatchBasedDenoisingImageFilter ThreadFilterStruct str; str.Filter = this; str.Img = const_cast(img); - this->GetMultiThreader()->SetNumberOfThreads( this->GetNumberOfWorkUnits() ); + this->GetMultiThreader()->SetNumberOfWorkUnits( this->GetNumberOfWorkUnits() ); this->GetMultiThreader()->SetSingleMethod(this->RiemannianMinMaxThreaderCallback, &str); // Multithread the execution @@ -703,11 +703,11 @@ ITK_THREAD_RETURN_TYPE PatchBasedDenoisingImageFilter ::RiemannianMinMaxThreaderCallback(void * arg) { - const unsigned int threadId = ( (MultiThreaderBase::ThreadInfoStruct *)(arg) )->ThreadID; - const unsigned int threadCount = ( (MultiThreaderBase::ThreadInfoStruct *)(arg) )->NumberOfThreads; + const unsigned int threadId = ( (MultiThreaderBase::WorkUnitInfo *)(arg) )->WorkUnitID; + const unsigned int threadCount = ( (MultiThreaderBase::WorkUnitInfo *)(arg) )->NumberOfWorkUnits; const ThreadFilterStruct * str = - (ThreadFilterStruct *)( ( (MultiThreaderBase::ThreadInfoStruct *)(arg) )->UserData); + (ThreadFilterStruct *)( ( (MultiThreaderBase::WorkUnitInfo *)(arg) )->UserData); // Execute the actual method with appropriate output region // first find out how many pieces extent can be split into. @@ -1428,7 +1428,7 @@ PatchBasedDenoisingImageFilter // Set up for multithreaded processing. ThreadFilterStruct str; str.Filter = this; - this->GetMultiThreader()->SetNumberOfThreads( this->GetNumberOfWorkUnits() ); + this->GetMultiThreader()->SetNumberOfWorkUnits( this->GetNumberOfWorkUnits() ); this->GetMultiThreader()->SetSingleMethod(this->ApplyUpdateThreaderCallback, &str); // Multithread the execution @@ -1445,11 +1445,11 @@ ITK_THREAD_RETURN_TYPE PatchBasedDenoisingImageFilter ::ApplyUpdateThreaderCallback( void * arg ) { - const unsigned int threadId = ( (MultiThreaderBase::ThreadInfoStruct *)(arg) )->ThreadID; - const unsigned int threadCount = ( (MultiThreaderBase::ThreadInfoStruct *)(arg) )->NumberOfThreads; + const unsigned int threadId = ( (MultiThreaderBase::WorkUnitInfo *)(arg) )->WorkUnitID; + const unsigned int threadCount = ( (MultiThreaderBase::WorkUnitInfo *)(arg) )->NumberOfWorkUnits; const ThreadFilterStruct * str = - (ThreadFilterStruct *)( ( (MultiThreaderBase::ThreadInfoStruct *)(arg) )->UserData); + (ThreadFilterStruct *)( ( (MultiThreaderBase::WorkUnitInfo *)(arg) )->UserData); // Execute the actual method with appropriate output region // first find out how many pieces extent can be split into. @@ -1488,7 +1488,7 @@ PatchBasedDenoisingImageFilter str.Filter = this; // Calculate sigma update - this->GetMultiThreader()->SetNumberOfThreads( this->GetNumberOfWorkUnits() ); + this->GetMultiThreader()->SetNumberOfWorkUnits( this->GetNumberOfWorkUnits() ); this->GetMultiThreader()->SetSingleMethod(this->ComputeSigmaUpdateThreaderCallback, &str); @@ -1566,11 +1566,11 @@ ITK_THREAD_RETURN_TYPE PatchBasedDenoisingImageFilter ::ComputeSigmaUpdateThreaderCallback( void * arg ) { - const unsigned int threadId = ( (MultiThreaderBase::ThreadInfoStruct *)(arg) )->ThreadID; - const unsigned int threadCount = ( (MultiThreaderBase::ThreadInfoStruct *)(arg) )->NumberOfThreads; + const unsigned int threadId = ( (MultiThreaderBase::WorkUnitInfo *)(arg) )->WorkUnitID; + const unsigned int threadCount = ( (MultiThreaderBase::WorkUnitInfo *)(arg) )->NumberOfWorkUnits; const ThreadFilterStruct * str = - (ThreadFilterStruct *)( ( (MultiThreaderBase::ThreadInfoStruct *)(arg) )->UserData); + (ThreadFilterStruct *)( ( (MultiThreaderBase::WorkUnitInfo *)(arg) )->UserData); // Execute the actual method with appropriate output region // first find out how many pieces extent can be split into. @@ -2011,7 +2011,7 @@ PatchBasedDenoisingImageFilter // Compute smoothing updated for intensites at each pixel // based on gradient of the joint entropy - this->GetMultiThreader()->SetNumberOfThreads( this->GetNumberOfWorkUnits() ); + this->GetMultiThreader()->SetNumberOfWorkUnits( this->GetNumberOfWorkUnits() ); this->GetMultiThreader()->SetSingleMethod(this->ComputeImageUpdateThreaderCallback, &str); @@ -2024,11 +2024,11 @@ ITK_THREAD_RETURN_TYPE PatchBasedDenoisingImageFilter ::ComputeImageUpdateThreaderCallback( void * arg ) { - const unsigned int threadId = ( (MultiThreaderBase::ThreadInfoStruct *)(arg) )->ThreadID; - const unsigned int threadCount = ( (MultiThreaderBase::ThreadInfoStruct *)(arg) )->NumberOfThreads; + const unsigned int threadId = ( (MultiThreaderBase::WorkUnitInfo *)(arg) )->WorkUnitID; + const unsigned int threadCount = ( (MultiThreaderBase::WorkUnitInfo *)(arg) )->NumberOfWorkUnits; const ThreadFilterStruct *str = - (ThreadFilterStruct *)( ( (MultiThreaderBase::ThreadInfoStruct *)(arg) )->UserData); + (ThreadFilterStruct *)( ( (MultiThreaderBase::WorkUnitInfo *)(arg) )->UserData); // Execute the actual method with appropriate output region // first find out how many pieces extent can be split into. diff --git a/Modules/Filtering/DisplacementField/include/itkInvertDisplacementFieldImageFilter.hxx b/Modules/Filtering/DisplacementField/include/itkInvertDisplacementFieldImageFilter.hxx index 45ec233f4fb..09fa310bf46 100644 --- a/Modules/Filtering/DisplacementField/include/itkInvertDisplacementFieldImageFilter.hxx +++ b/Modules/Filtering/DisplacementField/include/itkInvertDisplacementFieldImageFilter.hxx @@ -141,7 +141,7 @@ InvertDisplacementFieldImageFilter this->m_MaxErrorNorm = NumericTraits::ZeroValue(); this->m_DoThreadedEstimateInverse = false; - this->GetMultiThreader()->SetNumberOfThreads( this->GetNumberOfWorkUnits() ); + this->GetMultiThreader()->SetNumberOfWorkUnits( this->GetNumberOfWorkUnits() ); this->GetMultiThreader()->template ParallelizeImageRegion( this->GetOutput()->GetRequestedRegion(), [this](const OutputImageRegionType & outputRegionForThread) diff --git a/Modules/Filtering/DistanceMap/include/itkIsoContourDistanceImageFilter.hxx b/Modules/Filtering/DistanceMap/include/itkIsoContourDistanceImageFilter.hxx index b2707e15c5d..ead01c119f7 100644 --- a/Modules/Filtering/DistanceMap/include/itkIsoContourDistanceImageFilter.hxx +++ b/Modules/Filtering/DistanceMap/include/itkIsoContourDistanceImageFilter.hxx @@ -139,10 +139,10 @@ ITK_THREAD_RETURN_TYPE IsoContourDistanceImageFilter ::ThreaderFullCallback(void *arg) { - using ThreadInfo = MultiThreaderBase::ThreadInfoStruct; + using ThreadInfo = MultiThreaderBase::WorkUnitInfo; ThreadInfo * threadInfo = static_cast(arg); - ThreadIdType threadId = threadInfo->ThreadID; - ThreadIdType threadCount = threadInfo->NumberOfThreads; + ThreadIdType threadId = threadInfo->WorkUnitID; + ThreadIdType threadCount = threadInfo->NumberOfWorkUnits; using FilterStruct = typename ImageSource::ThreadStruct; FilterStruct* str = (FilterStruct *)(threadInfo->UserData); Self* filter = static_cast(str->Filter.GetPointer()); diff --git a/Modules/Filtering/DistanceMap/include/itkSignedMaurerDistanceMapImageFilter.hxx b/Modules/Filtering/DistanceMap/include/itkSignedMaurerDistanceMapImageFilter.hxx index d43330ad008..136acb126aa 100644 --- a/Modules/Filtering/DistanceMap/include/itkSignedMaurerDistanceMapImageFilter.hxx +++ b/Modules/Filtering/DistanceMap/include/itkSignedMaurerDistanceMapImageFilter.hxx @@ -167,7 +167,7 @@ SignedMaurerDistanceMapImageFilter< TInputImage, TOutputImage > typename ImageSource< OutputImageType >::ThreadStruct str; str.Filter = this; - this->GetMultiThreader()->SetNumberOfThreads( nbthreads ); + this->GetMultiThreader()->SetNumberOfWorkUnits( nbthreads ); this->GetMultiThreader()->SetSingleMethod(this->ThreaderCallback, &str); // multithread the execution diff --git a/Modules/Filtering/ImageFeature/include/itkCannyEdgeDetectionImageFilter.hxx b/Modules/Filtering/ImageFeature/include/itkCannyEdgeDetectionImageFilter.hxx index 5a66d66aee0..b405d0146df 100644 --- a/Modules/Filtering/ImageFeature/include/itkCannyEdgeDetectionImageFilter.hxx +++ b/Modules/Filtering/ImageFeature/include/itkCannyEdgeDetectionImageFilter.hxx @@ -231,7 +231,7 @@ CannyEdgeDetectionImageFilter< TInputImage, TOutputImage > // Calculate the 2nd order directional derivative of the smoothed image. // The output of this filter will be used to store the directional // derivative. - this->GetMultiThreader()->SetNumberOfThreads( this->GetNumberOfWorkUnits() ); + this->GetMultiThreader()->SetNumberOfWorkUnits( this->GetNumberOfWorkUnits() ); this->GetMultiThreader()->template ParallelizeImageRegion( this->GetOutput()->GetRequestedRegion(), [this](const OutputImageRegionType & outputRegionForThread) diff --git a/Modules/Filtering/ImageFusion/include/itkLabelMapContourOverlayImageFilter.hxx b/Modules/Filtering/ImageFusion/include/itkLabelMapContourOverlayImageFilter.hxx index e3b9d6d0b0f..9d08aa946a8 100644 --- a/Modules/Filtering/ImageFusion/include/itkLabelMapContourOverlayImageFilter.hxx +++ b/Modules/Filtering/ImageFusion/include/itkLabelMapContourOverlayImageFilter.hxx @@ -85,7 +85,7 @@ LabelMapContourOverlayImageFilter this->BeforeThreadedGenerateData(); this->UpdateProgress(0.05f); - this->GetMultiThreader()->SetNumberOfThreads( this->GetNumberOfWorkUnits() ); + this->GetMultiThreader()->SetNumberOfWorkUnits( this->GetNumberOfWorkUnits() ); this->GetMultiThreader()->template ParallelizeImageRegion( this->GetOutput()->GetRequestedRegion(), [this](const OutputImageRegionType & outputRegionForThread) diff --git a/Modules/Filtering/ImageFusion/include/itkLabelMapOverlayImageFilter.hxx b/Modules/Filtering/ImageFusion/include/itkLabelMapOverlayImageFilter.hxx index 66ce9f67d72..b0b5f549085 100644 --- a/Modules/Filtering/ImageFusion/include/itkLabelMapOverlayImageFilter.hxx +++ b/Modules/Filtering/ImageFusion/include/itkLabelMapOverlayImageFilter.hxx @@ -70,7 +70,7 @@ LabelMapOverlayImageFilter Superclass::BeforeThreadedGenerateData(); this->UpdateProgress(0.01f); - this->GetMultiThreader()->SetNumberOfThreads( this->GetNumberOfWorkUnits() ); + this->GetMultiThreader()->SetNumberOfWorkUnits( this->GetNumberOfWorkUnits() ); this->GetMultiThreader()->template ParallelizeImageRegion( this->GetOutput()->GetRequestedRegion(), [this](const OutputImageRegionType & outputRegionForThread) diff --git a/Modules/Filtering/ImageGrid/include/itkBSplineScatteredDataPointSetToImageFilter.hxx b/Modules/Filtering/ImageGrid/include/itkBSplineScatteredDataPointSetToImageFilter.hxx index 1ab3d472f1e..acf8456531d 100644 --- a/Modules/Filtering/ImageGrid/include/itkBSplineScatteredDataPointSetToImageFilter.hxx +++ b/Modules/Filtering/ImageGrid/include/itkBSplineScatteredDataPointSetToImageFilter.hxx @@ -292,7 +292,7 @@ BSplineScatteredDataPointSetToImageFilter typename ImageSource::ThreadStruct str1; str1.Filter = this; - this->GetMultiThreader()->SetNumberOfThreads( this->GetNumberOfWorkUnits() ); + this->GetMultiThreader()->SetNumberOfWorkUnits( this->GetNumberOfWorkUnits() ); this->GetMultiThreader()->SetSingleMethod( this->ThreaderCallback, &str1 ); // Multithread the generation of the control point lattice. diff --git a/Modules/Filtering/ImageLabel/include/itkBinaryContourImageFilter.hxx b/Modules/Filtering/ImageLabel/include/itkBinaryContourImageFilter.hxx index 837d79078e0..ca886d59992 100644 --- a/Modules/Filtering/ImageLabel/include/itkBinaryContourImageFilter.hxx +++ b/Modules/Filtering/ImageLabel/include/itkBinaryContourImageFilter.hxx @@ -82,7 +82,7 @@ BinaryContourImageFilter RegionType reqRegion = this->GetOutput()->GetRequestedRegion(); - this->GetMultiThreader()->SetNumberOfThreads( this->GetNumberOfWorkUnits() ); + this->GetMultiThreader()->SetNumberOfWorkUnits( this->GetNumberOfWorkUnits() ); //parallelize in a way which does not split the region along X axis //to accomplish this, we parallelize a region with lower dimension //which we extend with full scanlines along X diff --git a/Modules/Filtering/ImageLabel/include/itkLabelContourImageFilter.hxx b/Modules/Filtering/ImageLabel/include/itkLabelContourImageFilter.hxx index e0347470964..5820f52e3ac 100644 --- a/Modules/Filtering/ImageLabel/include/itkLabelContourImageFilter.hxx +++ b/Modules/Filtering/ImageLabel/include/itkLabelContourImageFilter.hxx @@ -79,7 +79,7 @@ LabelContourImageFilter OutputRegionType reqRegion = this->GetOutput()->GetRequestedRegion(); - this->GetMultiThreader()->SetNumberOfThreads( this->GetNumberOfWorkUnits() ); + this->GetMultiThreader()->SetNumberOfWorkUnits( this->GetNumberOfWorkUnits() ); //parallelize in a way which does not split the region along X axis //to accomplish this, we parallelize a region with lower dimension //which we extend with full scanlines along X diff --git a/Modules/Filtering/LabelMap/include/itkLabelMapMaskImageFilter.hxx b/Modules/Filtering/LabelMap/include/itkLabelMapMaskImageFilter.hxx index 6c26984ecb6..c2897f6779a 100644 --- a/Modules/Filtering/LabelMap/include/itkLabelMapMaskImageFilter.hxx +++ b/Modules/Filtering/LabelMap/include/itkLabelMapMaskImageFilter.hxx @@ -252,7 +252,7 @@ LabelMapMaskImageFilter< TInputImage, TOutputImage > this->BeforeThreadedGenerateData(); this->UpdateProgress(0.05f); - this->GetMultiThreader()->SetNumberOfThreads( this->GetNumberOfWorkUnits() ); + this->GetMultiThreader()->SetNumberOfWorkUnits( this->GetNumberOfWorkUnits() ); this->GetMultiThreader()->template ParallelizeImageRegion( this->GetOutput()->GetRequestedRegion(), [this](const OutputImageRegionType & outputRegionForThread) diff --git a/Modules/Filtering/LabelMap/include/itkLabelMapToBinaryImageFilter.hxx b/Modules/Filtering/LabelMap/include/itkLabelMapToBinaryImageFilter.hxx index 0a7767ae097..dffee91c5fc 100644 --- a/Modules/Filtering/LabelMap/include/itkLabelMapToBinaryImageFilter.hxx +++ b/Modules/Filtering/LabelMap/include/itkLabelMapToBinaryImageFilter.hxx @@ -69,7 +69,7 @@ LabelMapToBinaryImageFilter< TInputImage, TOutputImage > this->BeforeThreadedGenerateData(); this->UpdateProgress(0.05f); - this->GetMultiThreader()->SetNumberOfThreads( this->GetNumberOfWorkUnits() ); + this->GetMultiThreader()->SetNumberOfWorkUnits( this->GetNumberOfWorkUnits() ); this->GetMultiThreader()->template ParallelizeImageRegion( this->GetOutput()->GetRequestedRegion(), [this](const OutputImageRegionType & outputRegionForThread) diff --git a/Modules/Nonunit/Review/include/itkMultiphaseFiniteDifferenceImageFilter.h b/Modules/Nonunit/Review/include/itkMultiphaseFiniteDifferenceImageFilter.h index c8ba8a3df86..6f28e0d27a8 100644 --- a/Modules/Nonunit/Review/include/itkMultiphaseFiniteDifferenceImageFilter.h +++ b/Modules/Nonunit/Review/include/itkMultiphaseFiniteDifferenceImageFilter.h @@ -459,7 +459,7 @@ class ITK_TEMPLATE_EXPORT MultiphaseFiniteDifferenceImageFilter: /** This method is similar to Halt(), and its default implementation in this * class is simply to call Halt(). However, this method takes as a parameter a - * void pointer to the MultiThreaderBase::ThreadInfoStruct structure. If you + * void pointer to the MultiThreaderBase::WorkUnitInfo structure. If you * override this method instead of overriding Halt, you will be able to get the * current thread ID and handle the Halt method accordingly. This is useful if * you are doing a lot of processing in Halt that you don't want parallelized. diff --git a/Modules/Numerics/NarrowBand/include/itkNarrowBandImageFilterBase.hxx b/Modules/Numerics/NarrowBand/include/itkNarrowBandImageFilterBase.hxx index c433af45b2e..c9489b109e5 100644 --- a/Modules/Numerics/NarrowBand/include/itkNarrowBandImageFilterBase.hxx +++ b/Modules/Numerics/NarrowBand/include/itkNarrowBandImageFilterBase.hxx @@ -60,8 +60,8 @@ NarrowBandImageFilterBase< TInputImage, TOutputImage > output->SetBufferedRegion( output->GetRequestedRegion() ); output->Allocate(); - //Set the number of threads before any other initialization happens - this->GetMultiThreader()->SetNumberOfThreads( NumberOfWorkUnits ); + //Set the number of work units before any other initialization happens + this->GetMultiThreader()->SetNumberOfWorkUnits( NumberOfWorkUnits ); // Copy the input image to the output image. Algorithms will operate // directly on the output image and the update buffer. @@ -114,10 +114,10 @@ ITK_THREAD_RETURN_TYPE NarrowBandImageFilterBase< TInputImage, TOutputImage > ::IterateThreaderCallback(void *arg) { - ThreadIdType threadId = ( (MultiThreaderBase::ThreadInfoStruct *)( arg ) )->ThreadID; + ThreadIdType threadId = ( (MultiThreaderBase::WorkUnitInfo *)( arg ) )->WorkUnitID; auto * str = (NarrowBandImageFilterBaseThreadStruct *) - ( ( (MultiThreaderBase::ThreadInfoStruct *)( arg ) )->UserData ); + ( ( (MultiThreaderBase::WorkUnitInfo *)( arg ) )->UserData ); str->Filter->ThreadedIterate(arg, threadId); @@ -135,7 +135,7 @@ NarrowBandImageFilterBase< TInputImage, TOutputImage > //ThreadedApplyUpdate and ThreadedCalculateChanged // is called instead of ApplyUpdate and CalculateChange auto * str = (NarrowBandImageFilterBaseThreadStruct *) - ( ( (MultiThreaderBase::ThreadInfoStruct *)( arg ) )->UserData ); + ( ( (MultiThreaderBase::WorkUnitInfo *)( arg ) )->UserData ); IdentifierType iter = 0; while ( !( this->ThreadedHalt(arg) ) ) @@ -224,7 +224,7 @@ NarrowBandImageFilterBase< TInputImage, TOutputImage > // It should use the InsertNarrowBandNode function, which takes care of // memory management issues, to create the desired narrow band. - m_RegionList = m_NarrowBand->SplitBand( this->GetMultiThreader()->GetNumberOfThreads() ); + m_RegionList = m_NarrowBand->SplitBand( this->GetMultiThreader()->GetNumberOfWorkUnits() ); // The narrow band is split into multi-threading regions once here for // computationally efficiency. Later GetSplitRegions is used to access these @@ -234,10 +234,10 @@ NarrowBandImageFilterBase< TInputImage, TOutputImage > // Allocation of flag variable to check if a given thread touch the outer part // of the narrowband. If this part is touched, band should be reinitialized. - m_TouchedForThread.resize( this->GetMultiThreader()->GetNumberOfThreads(), false ); + m_TouchedForThread.resize( this->GetMultiThreader()->GetNumberOfWorkUnits(), false ); // A global barrier for all threads. - m_Barrier->Initialize( this->GetMultiThreader()->GetNumberOfThreads() ); + m_Barrier->Initialize( this->GetMultiThreader()->GetNumberOfWorkUnits() ); } template< typename TInputImage, typename TOutputImage > @@ -246,7 +246,7 @@ NarrowBandImageFilterBase< TInputImage, TOutputImage > ::InitializeIteration() { //Set m_Touched flag from threads information - for ( ThreadIdType i = 0; i < this->GetMultiThreader()->GetNumberOfThreads(); i++ ) + for ( ThreadIdType i = 0; i < this->GetMultiThreader()->GetNumberOfWorkUnits(); i++ ) { m_Touched = ( m_Touched || m_TouchedForThread[i] ); m_TouchedForThread[i] = false; @@ -259,7 +259,7 @@ NarrowBandImageFilterBase< TInputImage, TOutputImage > CreateNarrowBand(); // Rebuild the narrow band splits used in multithreading - m_RegionList = m_NarrowBand->SplitBand( this->GetMultiThreader()->GetNumberOfThreads() ); + m_RegionList = m_NarrowBand->SplitBand( this->GetMultiThreader()->GetNumberOfWorkUnits() ); m_Step = 0; m_Touched = false; diff --git a/Modules/Numerics/Statistics/include/itkImageToHistogramFilter.hxx b/Modules/Numerics/Statistics/include/itkImageToHistogramFilter.hxx index 20f8c9c532d..ca140bff1c3 100644 --- a/Modules/Numerics/Statistics/include/itkImageToHistogramFilter.hxx +++ b/Modules/Numerics/Statistics/include/itkImageToHistogramFilter.hxx @@ -189,10 +189,10 @@ ITK_THREAD_RETURN_TYPE ImageToHistogramFilter< TImage > ::ThreaderMinMaxCallback(void *arg) { - using ThreadInfo = MultiThreaderBase::ThreadInfoStruct; + using ThreadInfo = MultiThreaderBase::WorkUnitInfo; ThreadInfo * threadInfo = static_cast(arg); - ThreadIdType threadId = threadInfo->ThreadID; - ThreadIdType threadCount = threadInfo->NumberOfThreads; + ThreadIdType threadId = threadInfo->WorkUnitID; + ThreadIdType threadCount = threadInfo->NumberOfWorkUnits; using FilterStruct = typename ImageTransformer< TImage >::ThreadStruct; FilterStruct* str = (FilterStruct *)(threadInfo->UserData); Self* filter = static_cast(str->Filter.GetPointer()); diff --git a/Modules/Registration/Common/include/itkBlockMatchingImageFilter.hxx b/Modules/Registration/Common/include/itkBlockMatchingImageFilter.hxx index b135cc201aa..670e24cb941 100644 --- a/Modules/Registration/Common/include/itkBlockMatchingImageFilter.hxx +++ b/Modules/Registration/Common/include/itkBlockMatchingImageFilter.hxx @@ -95,7 +95,7 @@ BlockMatchingImageFilter< TFixedImage, TMovingImage, TFeatures, TDisplacements, ThreadStruct str; str.Filter = this; - this->GetMultiThreader()->SetNumberOfThreads( this->GetNumberOfWorkUnits() ); + this->GetMultiThreader()->SetNumberOfWorkUnits( this->GetNumberOfWorkUnits() ); this->GetMultiThreader()->SetSingleMethod(this->ThreaderCallback, &str); // multithread the execution @@ -210,8 +210,8 @@ ITK_THREAD_RETURN_TYPE BlockMatchingImageFilter< TFixedImage, TMovingImage, TFeatures, TDisplacements, TSimilarities > ::ThreaderCallback(void *arg) { - auto * str = (ThreadStruct *)( ( (MultiThreaderBase::ThreadInfoStruct *)( arg ) )->UserData ); - ThreadIdType threadId = ( (MultiThreaderBase::ThreadInfoStruct *)( arg ) )->ThreadID; + auto * str = (ThreadStruct *)( ( (MultiThreaderBase::WorkUnitInfo *)( arg ) )->UserData ); + ThreadIdType threadId = ( (MultiThreaderBase::WorkUnitInfo *)( arg ) )->WorkUnitID; str->Filter->ThreadedGenerateData( threadId ); diff --git a/Modules/Registration/Common/include/itkImageRegistrationMethod.hxx b/Modules/Registration/Common/include/itkImageRegistrationMethod.hxx index 676b9b28208..9cf5a54100f 100644 --- a/Modules/Registration/Common/include/itkImageRegistrationMethod.hxx +++ b/Modules/Registration/Common/include/itkImageRegistrationMethod.hxx @@ -51,7 +51,7 @@ ImageRegistrationMethod< TFixedImage, TMovingImage > this->ProcessObject::SetNthOutput( 0, transformDecorator.GetPointer() ); - this->SetNumberOfWorkUnits( this->GetMultiThreader()->GetNumberOfThreads() ); + this->SetNumberOfWorkUnits( this->GetMultiThreader()->GetNumberOfWorkUnits() ); } /** @@ -179,7 +179,7 @@ ImageRegistrationMethod< TFixedImage, TMovingImage > } // Setup the metric - this->GetMultiThreader()->SetNumberOfThreads( this->GetNumberOfWorkUnits() ); + this->GetMultiThreader()->SetNumberOfWorkUnits( this->GetNumberOfWorkUnits() ); this->m_Metric->SetNumberOfWorkUnits( this->GetNumberOfWorkUnits() ); m_Metric->SetMovingImage(m_MovingImage); m_Metric->SetFixedImage(m_FixedImage); diff --git a/Modules/Registration/Common/include/itkImageToImageMetric.hxx b/Modules/Registration/Common/include/itkImageToImageMetric.hxx index a248721e10a..80381a5ca1a 100644 --- a/Modules/Registration/Common/include/itkImageToImageMetric.hxx +++ b/Modules/Registration/Common/include/itkImageToImageMetric.hxx @@ -90,7 +90,7 @@ ImageToImageMetric< TFixedImage, TMovingImage > m_WithinThreadPostProcess(false) { this->m_ThreaderParameter.metric = this; - this->m_NumberOfWorkUnits = this->m_Threader->GetNumberOfThreads(); + this->m_NumberOfWorkUnits = this->m_Threader->GetNumberOfWorkUnits(); /* if 100% backward compatible, we should include this...but... typename BSplineTransformType::Pointer transformer = @@ -129,8 +129,8 @@ void ImageToImageMetric< TFixedImage, TMovingImage > ::SetNumberOfWorkUnits(ThreadIdType numberOfThreads) { - m_Threader->SetNumberOfThreads( numberOfThreads ); - m_NumberOfWorkUnits = m_Threader->GetNumberOfThreads(); + m_Threader->SetNumberOfWorkUnits( numberOfThreads ); + m_NumberOfWorkUnits = m_Threader->GetNumberOfWorkUnits(); } /** @@ -1214,10 +1214,10 @@ ImageToImageMetric< TFixedImage, TMovingImage > ThreadIdType threadId; MultiThreaderParameterType *mtParam; - threadId = ( (MultiThreaderType::ThreadInfoStruct *)( arg ) )->ThreadID; + threadId = ( (MultiThreaderType::WorkUnitInfo *)( arg ) )->WorkUnitID; mtParam = (MultiThreaderParameterType *) - ( ( (MultiThreaderType::ThreadInfoStruct *)( arg ) )->UserData ); + ( ( (MultiThreaderType::WorkUnitInfo *)( arg ) )->UserData ); mtParam->metric->GetValueThreadPreProcess(threadId, false); @@ -1235,10 +1235,10 @@ ImageToImageMetric< TFixedImage, TMovingImage > ThreadIdType threadId; MultiThreaderParameterType *mtParam; - threadId = ( (MultiThreaderType::ThreadInfoStruct *)( arg ) )->ThreadID; + threadId = ( (MultiThreaderType::WorkUnitInfo *)( arg ) )->WorkUnitID; mtParam = (MultiThreaderParameterType *) - ( ( (MultiThreaderType::ThreadInfoStruct *)( arg ) )->UserData ); + ( ( (MultiThreaderType::WorkUnitInfo *)( arg ) )->UserData ); mtParam->metric->GetValueThread(threadId); @@ -1256,10 +1256,10 @@ ImageToImageMetric< TFixedImage, TMovingImage > ThreadIdType threadId; MultiThreaderParameterType *mtParam; - threadId = ( (MultiThreaderType::ThreadInfoStruct *)( arg ) )->ThreadID; + threadId = ( (MultiThreaderType::WorkUnitInfo *)( arg ) )->WorkUnitID; mtParam = (MultiThreaderParameterType *) - ( ( (MultiThreaderType::ThreadInfoStruct *)( arg ) )->UserData ); + ( ( (MultiThreaderType::WorkUnitInfo *)( arg ) )->UserData ); mtParam->metric->GetValueThreadPostProcess(threadId, false); @@ -1377,10 +1377,10 @@ ImageToImageMetric< TFixedImage, TMovingImage > ThreadIdType threadId; MultiThreaderParameterType *mtParam; - threadId = ( (MultiThreaderType::ThreadInfoStruct *)( arg ) )->ThreadID; + threadId = ( (MultiThreaderType::WorkUnitInfo *)( arg ) )->WorkUnitID; mtParam = (MultiThreaderParameterType *) - ( ( (MultiThreaderType::ThreadInfoStruct *)( arg ) )->UserData ); + ( ( (MultiThreaderType::WorkUnitInfo *)( arg ) )->UserData ); mtParam->metric->GetValueAndDerivativeThreadPreProcess(threadId, false); @@ -1398,10 +1398,10 @@ ImageToImageMetric< TFixedImage, TMovingImage > ThreadIdType threadId; MultiThreaderParameterType *mtParam; - threadId = ( (MultiThreaderType::ThreadInfoStruct *)( arg ) )->ThreadID; + threadId = ( (MultiThreaderType::WorkUnitInfo *)( arg ) )->WorkUnitID; mtParam = (MultiThreaderParameterType *) - ( ( (MultiThreaderType::ThreadInfoStruct *)( arg ) )->UserData ); + ( ( (MultiThreaderType::WorkUnitInfo *)( arg ) )->UserData ); mtParam->metric->GetValueAndDerivativeThread(threadId); @@ -1419,10 +1419,10 @@ ImageToImageMetric< TFixedImage, TMovingImage > ThreadIdType threadId; MultiThreaderParameterType *mtParam; - threadId = ( (MultiThreaderType::ThreadInfoStruct *)( arg ) )->ThreadID; + threadId = ( (MultiThreaderType::WorkUnitInfo *)( arg ) )->WorkUnitID; mtParam = (MultiThreaderParameterType *) - ( ( (MultiThreaderType::ThreadInfoStruct *)( arg ) )->UserData ); + ( ( (MultiThreaderType::WorkUnitInfo *)( arg ) )->UserData ); mtParam->metric->GetValueAndDerivativeThreadPostProcess(threadId, false); diff --git a/Modules/Registration/Common/include/itkMatchCardinalityImageToImageMetric.hxx b/Modules/Registration/Common/include/itkMatchCardinalityImageToImageMetric.hxx index f35f852d006..a4de32a5888 100644 --- a/Modules/Registration/Common/include/itkMatchCardinalityImageToImageMetric.hxx +++ b/Modules/Registration/Common/include/itkMatchCardinalityImageToImageMetric.hxx @@ -96,7 +96,7 @@ MatchCardinalityImageToImageMetric< TFixedImage, TMovingImage > ThreadStruct str; str.Metric = this; - this->GetMultiThreader()->SetNumberOfThreads( this->GetNumberOfWorkUnits() ); + this->GetMultiThreader()->SetNumberOfWorkUnits( this->GetNumberOfWorkUnits() ); this->GetMultiThreader()->SetSingleMethod(this->ThreaderCallback, &str); // multithread the execution @@ -263,10 +263,10 @@ MatchCardinalityImageToImageMetric< TFixedImage, TMovingImage > ThreadStruct *str; ThreadIdType total, threadId, threadCount; - threadId = ( (MultiThreaderBase::ThreadInfoStruct *)( arg ) )->ThreadID; - threadCount = ( (MultiThreaderBase::ThreadInfoStruct *)( arg ) )->NumberOfThreads; + threadId = ( (MultiThreaderBase::WorkUnitInfo *)( arg ) )->WorkUnitID; + threadCount = ( (MultiThreaderBase::WorkUnitInfo *)( arg ) )->NumberOfWorkUnits; - str = (ThreadStruct *)( ( (MultiThreaderBase::ThreadInfoStruct *)( arg ) )->UserData ); + str = (ThreadStruct *)( ( (MultiThreaderBase::WorkUnitInfo *)( arg ) )->UserData ); // execute the actual method with appropriate computation region // first find out how many pieces extent can be split into. diff --git a/Modules/Segmentation/LevelSets/include/itkParallelSparseFieldLevelSetImageFilter.hxx b/Modules/Segmentation/LevelSets/include/itkParallelSparseFieldLevelSetImageFilter.hxx index bb8fe07eeed..a9645893ed8 100644 --- a/Modules/Segmentation/LevelSets/include/itkParallelSparseFieldLevelSetImageFilter.hxx +++ b/Modules/Segmentation/LevelSets/include/itkParallelSparseFieldLevelSetImageFilter.hxx @@ -1134,7 +1134,7 @@ ParallelSparseFieldLevelSetImageFilter< TInputImage, TOutputImage > str.Filter = this; str.TimeStep = NumericTraits< TimeStepType >::ZeroValue(); - this->GetMultiThreader()->SetNumberOfThreads( m_NumOfThreads ); + this->GetMultiThreader()->SetNumberOfWorkUnits( m_NumOfThreads ); // Initialize the list of time step values that will be generated by the // various threads. There is one distinct slot for each possible thread, @@ -1159,10 +1159,10 @@ ParallelSparseFieldLevelSetImageFilter< TInputImage, TOutputImage > constexpr unsigned int LOAD_BALANCE_ITERATION_FREQUENCY = 30; unsigned int i; - ThreadIdType ThreadId = ( (MultiThreaderBase::ThreadInfoStruct *)( arg ) )->ThreadID; + ThreadIdType ThreadId = ( (MultiThreaderBase::WorkUnitInfo *)( arg ) )->WorkUnitID; auto * str = (ParallelSparseFieldLevelSetThreadStruct *) - ( ( (MultiThreaderBase::ThreadInfoStruct *)( arg ) )->UserData ); + ( ( (MultiThreaderBase::WorkUnitInfo *)( arg ) )->UserData ); // allocate thread data: every thread allocates its own data // We do NOT assume here that malloc is thread safe: hence make threads diff --git a/Modules/Segmentation/LevelSetsv4/include/itkLevelSetEvolution.hxx b/Modules/Segmentation/LevelSetsv4/include/itkLevelSetEvolution.hxx index c46813f2eab..6e597a5c615 100644 --- a/Modules/Segmentation/LevelSetsv4/include/itkLevelSetEvolution.hxx +++ b/Modules/Segmentation/LevelSetsv4/include/itkLevelSetEvolution.hxx @@ -239,7 +239,7 @@ void LevelSetEvolution< TEquationContainer, WhitakerSparseLevelSetImage< TOutput, VDimension > > ::SetNumberOfWorkUnits( const ThreadIdType numberOfThreads) { - this->m_SplitLevelSetComputeIterationThreader->SetMaximumNumberOfThreads( numberOfThreads ); + this->m_SplitLevelSetComputeIterationThreader->SetNumberOfWorkUnits( numberOfThreads ); } template< typename TEquationContainer, typename TOutput, unsigned int VDimension > @@ -247,7 +247,7 @@ ThreadIdType LevelSetEvolution< TEquationContainer, WhitakerSparseLevelSetImage< TOutput, VDimension > > ::GetNumberOfWorkUnits() const { - return this->m_SplitLevelSetComputeIterationThreader->GetMaximumNumberOfThreads(); + return this->m_SplitLevelSetComputeIterationThreader->GetNumberOfWorkUnits(); } template< typename TEquationContainer, typename TOutput, unsigned int VDimension > diff --git a/Modules/Segmentation/SuperPixel/include/itkSLICImageFilter.hxx b/Modules/Segmentation/SuperPixel/include/itkSLICImageFilter.hxx index 5e0b615ad4d..5c78126471f 100644 --- a/Modules/Segmentation/SuperPixel/include/itkSLICImageFilter.hxx +++ b/Modules/Segmentation/SuperPixel/include/itkSLICImageFilter.hxx @@ -622,7 +622,7 @@ SLICImageFilter this->AllocateOutputs(); this->BeforeThreadedGenerateData(); - this->GetMultiThreader()->SetNumberOfThreads( this->GetNumberOfWorkUnits() ); + this->GetMultiThreader()->SetNumberOfWorkUnits( this->GetNumberOfWorkUnits() ); const InputImageType *inputImage = this->GetInput(); OutputImageType *outputImage = this->GetOutput(); diff --git a/Modules/Video/Core/include/itkVideoSource.hxx b/Modules/Video/Core/include/itkVideoSource.hxx index ad914147f2b..7254327e42b 100644 --- a/Modules/Video/Core/include/itkVideoSource.hxx +++ b/Modules/Video/Core/include/itkVideoSource.hxx @@ -251,7 +251,7 @@ TemporalStreamingGenerateData() ThreadStruct str; str.Filter = this; - this->GetMultiThreader()->SetNumberOfThreads( this->GetNumberOfWorkUnits() ); + this->GetMultiThreader()->SetNumberOfWorkUnits( this->GetNumberOfWorkUnits() ); this->GetMultiThreader()->SetSingleMethod(this->ThreaderCallback, &str); // multithread the execution @@ -368,10 +368,10 @@ ThreaderCallback(void* arg) ThreadStruct *str; int total, threadId, threadCount; - threadId = ( (MultiThreaderBase::ThreadInfoStruct *)( arg ) )->ThreadID; - threadCount = ( (MultiThreaderBase::ThreadInfoStruct *)( arg ) )->NumberOfThreads; + threadId = ( (MultiThreaderBase::WorkUnitInfo *)( arg ) )->WorkUnitID; + threadCount = ( (MultiThreaderBase::WorkUnitInfo *)( arg ) )->NumberOfWorkUnits; - str = (ThreadStruct *)( ( (MultiThreaderBase::ThreadInfoStruct *)( arg ) )->UserData ); + str = (ThreadStruct *)( ( (MultiThreaderBase::WorkUnitInfo *)( arg ) )->UserData ); // execute the actual method with appropriate output region // first find out how many pieces extent can be split into.