1 /*=========================================================================
2 *
3 * Copyright Insight Software Consortium
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0.txt
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 *=========================================================================*/
18 #ifndef itkThreadedIteratorRangePartitioner_hxx
19 #define itkThreadedIteratorRangePartitioner_hxx
20
21 #include "itkNumericTraits.h"
22 #include "itkThreadedIteratorRangePartitioner.h"
23 #include "itkMath.h"
24
25 #include <iterator>
26
27 namespace itk
28 {
29
30 template< typename TIterator >
31 ThreadIdType
32 ThreadedIteratorRangePartitioner< TIterator >
PartitionDomain(const ThreadIdType threadId,const ThreadIdType requestedTotal,const DomainType & completeDomain,DomainType & subDomain) const33 ::PartitionDomain( const ThreadIdType threadId,
34 const ThreadIdType requestedTotal,
35 const DomainType& completeDomain,
36 DomainType& subDomain ) const
37 {
38 // overallIndexRange is expected to be inclusive
39
40 // determine the actual number of pieces that will be generated
41 ThreadIdType count = std::distance( completeDomain.Begin(), completeDomain.End() );
42
43 auto valuesPerThread = Math::Ceil<ThreadIdType>( static_cast< double >( count ) / static_cast< double >( requestedTotal ));
44 ThreadIdType maxThreadIdUsed =
45 Math::Ceil<ThreadIdType>( static_cast< double >( count ) / static_cast< double >( valuesPerThread )) - 1;
46
47 if ( threadId > maxThreadIdUsed )
48 {
49 // return before advancing Begin iterator, to prevent advancing
50 // past end
51 return maxThreadIdUsed + 1;
52 }
53
54 const ThreadIdType startIndexCount = threadId * valuesPerThread;
55 subDomain.m_Begin = completeDomain.Begin();
56 std::advance( subDomain.m_Begin, startIndexCount );
57
58 if (threadId < maxThreadIdUsed)
59 {
60 subDomain.m_End = subDomain.m_Begin;
61 std::advance( subDomain.m_End, valuesPerThread );
62 }
63 if (threadId == maxThreadIdUsed)
64 {
65 // last thread needs to process the "rest" of the range
66 subDomain.m_End = completeDomain.End();
67 }
68
69 return maxThreadIdUsed + 1;
70 }
71
72 } // end namespace itk
73
74 #endif
75