From 39233cf157bf7430d9ccefd36a714f6d82ffa926 Mon Sep 17 00:00:00 2001 From: Bradley Lowekamp Date: Fri, 2 Nov 2018 17:18:24 -0400 Subject: [PATCH] BUG: Add parameter which stores the requested number of work units. Adding an internal variable which store the number of work units requested. It is clamps to ITK_MAX_THREADS and initialized from the MultiThreader, which ensures a valid range. The variable is not reduce when the actual number of work units the domain can be partitioned into is computed. Previously, subsequent calls would only reduce the number of work units in the multi-threader and not restore the requested number. --- .../Core/Common/include/itkDomainThreader.h | 8 ++--- .../Core/Common/include/itkDomainThreader.hxx | 33 +++++-------------- 2 files changed, 11 insertions(+), 30 deletions(-) diff --git a/Modules/Core/Common/include/itkDomainThreader.h b/Modules/Core/Common/include/itkDomainThreader.h index 07b06955439..7247b4fd049 100644 --- a/Modules/Core/Common/include/itkDomainThreader.h +++ b/Modules/Core/Common/include/itkDomainThreader.h @@ -104,11 +104,8 @@ class ITK_TEMPLATE_EXPORT DomainThreader: public Object * \warning When setting the desired number of work units, it might be clamped by * itk::MultiThreaderBase::GetGlobalMaximumNumberOfThreads(). * */ - ThreadIdType GetNumberOfWorkUnits() const - { - return this->m_MultiThreader->GetNumberOfWorkUnits(); - } - void SetNumberOfWorkUnits( const ThreadIdType workUnits ); + itkSetClampMacro(NumberOfWorkUnits, ThreadIdType, 1, ITK_MAX_THREADS); + itkGetConstMacro(NumberOfWorkUnits, ThreadIdType); /** 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 @@ -172,6 +169,7 @@ class ITK_TEMPLATE_EXPORT DomainThreader: public Object * well into that number. * This value is determined at the beginning of \c Execute(). */ ThreadIdType m_NumberOfWorkUnitsUsed; + ThreadIdType m_NumberOfWorkUnits; typename DomainPartitionerType::Pointer m_DomainPartitioner; DomainType m_CompleteDomain; MultiThreaderBase::Pointer m_MultiThreader; diff --git a/Modules/Core/Common/include/itkDomainThreader.hxx b/Modules/Core/Common/include/itkDomainThreader.hxx index a0d44311a86..a0bd8e55062 100644 --- a/Modules/Core/Common/include/itkDomainThreader.hxx +++ b/Modules/Core/Common/include/itkDomainThreader.hxx @@ -26,11 +26,12 @@ namespace itk template< typename TDomainPartitioner, typename TAssociate > DomainThreader< TDomainPartitioner, TAssociate > ::DomainThreader() + : m_Associate(nullptr), + m_NumberOfWorkUnitsUsed(0) { this->m_DomainPartitioner = DomainPartitionerType::New(); this->m_MultiThreader = MultiThreaderBase::New(); - this->m_NumberOfWorkUnitsUsed = 0; - this->m_Associate = nullptr; + this->m_NumberOfWorkUnits = this->m_MultiThreader->GetNumberOfWorkUnits(); } template< typename TDomainPartitioner, typename TAssociate > @@ -45,18 +46,6 @@ DomainThreader< TDomainPartitioner, TAssociate > return this->m_MultiThreader; } -template< typename TDomainPartitioner, typename TAssociate > -void -DomainThreader< TDomainPartitioner, TAssociate > -::SetNumberOfWorkUnits( const ThreadIdType workUnits ) -{ - if( workUnits != this->GetNumberOfWorkUnits() ) - { - this->m_MultiThreader->SetNumberOfWorkUnits( workUnits ); - this->Modified(); - }; -} - template< typename TDomainPartitioner, typename TAssociate > void DomainThreader< TDomainPartitioner, TAssociate > @@ -92,24 +81,18 @@ void DomainThreader< TDomainPartitioner, TAssociate > ::DetermineNumberOfWorkUnitsUsed() { - const ThreadIdType threaderNumberOfThreads = this->GetMultiThreader()->GetNumberOfWorkUnits(); + ThreadIdType numberOfWorkUnits = this->GetNumberOfWorkUnits(); // Attempt a single dummy partition, just to get the number of subdomains actually created DomainType subdomain; this->m_NumberOfWorkUnitsUsed = this->m_DomainPartitioner->PartitionDomain(0, - threaderNumberOfThreads, + numberOfWorkUnits, this->m_CompleteDomain, subdomain); - if( this->m_NumberOfWorkUnitsUsed < threaderNumberOfThreads ) - { - // If PartitionDomain is only able to create a lesser number of subdomains, - // 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()->SetNumberOfWorkUnits(this->m_NumberOfWorkUnitsUsed); - } - else if( this->m_NumberOfWorkUnitsUsed > threaderNumberOfThreads ) + this->GetMultiThreader()->SetNumberOfWorkUnits(this->m_NumberOfWorkUnitsUsed); + + if( this->m_NumberOfWorkUnitsUsed > numberOfWorkUnits ) { itkExceptionMacro( "A subclass of ThreadedDomainPartitioner::PartitionDomain" << "returned more subdomains than were requested" );