dune-fem 2.8.0
Loading...
Searching...
No Matches
threaditerator.hh
Go to the documentation of this file.
1#ifndef DUNE_FEM_THREADITERATOR_HH
2#define DUNE_FEM_THREADITERATOR_HH
3
4#include <vector>
5
6#include <dune/common/exceptions.hh>
7
12
13namespace Dune
14{
15
16 namespace Fem
17 {
18
20 template <class GridPart, PartitionIteratorType ptype = InteriorBorder_Partition >
22 {
24 ThreadIterator& operator= ( const ThreadIterator& );
25 public:
26 // partition type of iterators used
27 static const PartitionIteratorType pitype = ptype ;
28
29 typedef GridPart GridPartType;
30 typedef typename GridPartType :: GridType GridType;
31 typedef typename GridPartType :: template Codim< 0 > :: template Partition< pitype > :: IteratorType IteratorType ;
32 typedef typename GridPartType :: template Codim< 0 > :: EntityType EntityType ;
33 typedef typename GridPartType :: IndexSetType IndexSetType ;
35
37
38
39 protected:
43
46
47 std::vector< IteratorType > iterators_;
49 std::vector< std::vector< int > > threadId_;
50 std::vector< std::unique_ptr< FilterType > > filters_;
51
52 // if true, thread 0 does only communication and no computation
54 const bool verbose_ ;
55
56 public:
58 explicit ThreadIterator( const GridPartType& gridPart, const ParameterReader &parameter = Parameter::container() )
59 : gridPart_( gridPart )
60 , dofManager_( DofManagerType :: instance( gridPart_.grid() ) )
61 , indexSet_( gridPart_.indexSet() )
62 , sequence_( -1 )
63 , numThreads_( MPIManager::numThreads() )
64 , iterators_( MPIManager::maxThreads() + 1 , gridPart_.template end< 0, pitype >() )
65 , threadId_( MPIManager::maxThreads() )
66 , filters_( MPIManager::maxThreads() )
67 , communicationThread_( parameter.getValue<bool>("fem.threads.communicationthread", false)
68 && Fem :: MPIManager :: maxThreads() > 1 ) // only possible if maxThreads > 1
69 , verbose_( Parameter::verbose() &&
70 parameter.getValue<bool>("fem.threads.verbose", false ) )
71 {
73 for(int thread=0; thread < Fem :: MPIManager :: maxThreads(); ++thread )
74 {
76 }
77 update();
78 }
79
81 const FilterType& filter( const unsigned int thread ) const
82 {
83 assert( thread < filters_.size() );
84 return *(filters_[ thread ]);
85 }
86
88 void update()
89 {
90 const int sequence = gridPart_.sequence();
91 // if grid got updated also update iterators
92 if( sequence_ != sequence || numThreads_ != MPIManager :: numThreads() )
93 {
94 if( ! MPIManager :: singleThreadMode() )
95 {
96 std::cerr << "Don't call ThreadIterator::update in a parallel environment!" << std::endl;
97 assert( false );
98 abort();
99 }
100
101 // update currently used thread numbers
102 numThreads_ = MPIManager :: numThreads() ;
103 const size_t numThreads = numThreads_;
104
105 // get end iterator
106 const IteratorType endit = gridPart_.template end< 0, pitype >();
107
108 // pass default value to resize to initialize all iterators
109 iterators_.resize( numThreads+1, endit );
110
111 IteratorType it = gridPart_.template begin< 0, pitype >();
112 if( it == endit )
113 {
114 // set all iterators to end iterators
115 for( size_t thread = 0; thread <= numThreads; ++thread )
116 iterators_[ thread ] = endit ;
117
118 // free memory here
119 threadNum_.resize( 0 );
120
121 // update sequence number
122 sequence_ = sequence;
123 return ;
124 }
125
126 // thread 0 starts at begin
127 iterators_[ 0 ] = it ;
128
129 // get size for index set (this only works well when pitype == All_Partition)
130 // otherwise element have to be counted
131 const size_t iterSize = countElements( it, endit );
132 const size_t size = indexSet_.size( 0 );
133
134 // resize threads storage
135 threadNum_.resize( size );
136 // set all values to default value
137 for(size_t i = 0; i<size; ++i) threadNum_[ i ] = -1;
138
139 // here use iterator to count
140 size_t checkSize = 0;
141 const size_t roundOff = (iterSize % numThreads);
142 const size_t counterBase = ((size_t) iterSize / numThreads );
143
144 // just for diagnostics
145 std::vector< int > nElems( numThreads, 0 );
146
147 for( size_t thread = 1; thread <= numThreads; ++thread )
148 {
149 size_t i = 0;
150 const size_t counter = counterBase + (( (thread-1) < roundOff ) ? 1 : 0);
151 nElems[ thread-1 ] = counter ;
152 checkSize += counter ;
153 //std::cout << counter << " for thread " << thread-1 << std::endl;
154 while( (i < counter) && (it != endit) )
155 {
156 const EntityType &entity = *it;
157 assert( std::size_t( indexSet_.index( entity ) ) < std::size_t( threadNum_.size() ) );
158 threadNum_[ indexSet_.index( entity ) ] = thread - 1;
159 ++i;
160 ++it;
161 }
162 iterators_[ thread ] = it ;
163 }
164 iterators_[ numThreads ] = endit ;
165
166 if( checkSize != iterSize )
167 {
168 assert( checkSize == iterSize );
169 DUNE_THROW(InvalidStateException,"Partitioning inconsistent!");
170 }
171
172 // update sequence number
173 sequence_ = sequence;
174
175 if( verbose_ )
176 {
177 std::cout << "ThreadIterator: sequence = " << sequence_ << " size = " << checkSize << std::endl;
178 const size_t counterSize = nElems.size();
179 for(size_t i = 0; i<counterSize; ++i )
180 std::cout << "ThreadIterator: T[" << i << "] = " << nElems[ i ] << std::endl;
181 }
182
183 checkConsistency( iterSize );
184
185 //for(size_t i = 0; i<size; ++i )
186 // std::cout << threadNum_[ i ] << std::endl;
187 }
188 }
189
192 {
193 if( MPIManager :: singleThreadMode() )
194 {
195 return gridPart_.template begin< 0, pitype >();
196 }
197 // in multi thread mode return iterators for each thread
198 else
199 {
200 assert( MPIManager :: thread() < numThreads_ );
201 return iterators_[ MPIManager :: thread() ];
202 }
203 }
205 {
206 return iterators_[ thread ];
207 }
208
211 {
212 if( MPIManager :: singleThreadMode() )
213 {
214 return gridPart_.template end< 0, pitype >();
215 }
216 // in multi thread mode return iterators for each thread
217 else
218 {
219 assert( MPIManager :: thread() < numThreads_ );
220 return iterators_[ MPIManager :: thread() + 1 ];
221 }
222 }
224 {
225 return iterators_[ thread + 1 ];
226 }
227
229 int index( const EntityType& entity ) const
230 {
231 return indexSet_.index( entity );
232 }
233
234 int threadParallel( const EntityType& entity ) const
235 {
236 assert( std::size_t( threadNum_.size() ) > std::size_t( indexSet_.index( entity ) ) );
237 // NOTE: this number can also be negative for ghost elements or elements
238 // that do not belong to the set covered by the space iterators
239 return threadNum_[ indexSet_.index( entity ) ];
240 }
242 int thread( const EntityType& entity ) const
243 {
245 return 0;
246 else
247 return threadParallel(entity);
248 }
249
251 void setMasterRatio( const double ratio )
252 {
253 }
254
255 protected:
256 template < class Iterator >
257 size_t countElements( const Iterator& begin, const Iterator& end ) const
258 {
259 size_t count = 0;
260 for( Iterator it = begin; it != end; ++ it )
261 ++count ;
262 return count ;
263 }
264
265 // check that we have a non-overlapping iterator decomposition
266 void checkConsistency( const size_t totalElements )
267 {
268#ifndef NDEBUG
269 const int numThreads = MPIManager :: numThreads() ;
270 std::set< int > indices ;
271 for( int thread = 0; thread < numThreads; ++ thread )
272 {
273 const IteratorType end = iterators_[ thread+1 ];
274 for( IteratorType it = iterators_[ thread ]; it != end; ++it )
275 {
276 const int idx = gridPart_.indexSet().index( *it );
277 assert( indices.find( idx ) == indices.end() ) ;
278 indices.insert( idx );
279 }
280 }
281 assert( indices.size() == totalElements );
282#endif
283 }
284 };
285
287 template <class GridPart, PartitionIteratorType pitype = InteriorBorder_Partition >
289 : public ThreadIteratorStorageBase< ThreadIterator< GridPart, pitype > >
290 {
292 public:
293 ThreadIteratorStorage( const GridPart& gridPart )
294 : BaseType( gridPart )
295 {}
296 };
297
298 } // namespace Fem
299
300} // namespace Dune
301
302#endif // #ifndef DUNE_FEM_THREADITERATOR_HH
Definition: bindguard.hh:11
Definition: domainfilter.hh:55
Container for User Specified Parameters.
Definition: io/parameter.hh:191
static ParameterContainer & container()
Definition: io/parameter.hh:193
Definition: mpimanager.hh:337
static bool singleThreadMode()
returns true if program is operating on one thread currently
Definition: mpimanager.hh:436
Thread iterators.
Definition: threaditerator.hh:22
DynamicArray< int > threadNum_
Definition: threaditerator.hh:48
DofManager< GridType > DofManagerType
Definition: threaditerator.hh:34
GridPartType::template Codim< 0 >::EntityType EntityType
Definition: threaditerator.hh:32
int sequence_
Definition: threaditerator.hh:44
const bool verbose_
Definition: threaditerator.hh:54
GridPartType::GridType GridType
Definition: threaditerator.hh:30
void checkConsistency(const size_t totalElements)
Definition: threaditerator.hh:266
static const PartitionIteratorType pitype
Definition: threaditerator.hh:27
int thread(const EntityType &entity) const
return thread number this entity belongs to
Definition: threaditerator.hh:242
IteratorType begin(int thread) const
Definition: threaditerator.hh:204
GridPartType::IndexSetType IndexSetType
Definition: threaditerator.hh:33
int numThreads_
Definition: threaditerator.hh:45
IteratorType end() const
return end iterator for current thread
Definition: threaditerator.hh:210
std::vector< std::vector< int > > threadId_
Definition: threaditerator.hh:49
std::vector< std::unique_ptr< FilterType > > filters_
Definition: threaditerator.hh:50
void update()
update internal list of iterators
Definition: threaditerator.hh:88
void setMasterRatio(const double ratio)
set ratio between master thread and other threads in comp time
Definition: threaditerator.hh:251
DomainFilter< GridPartType > FilterType
Definition: threaditerator.hh:36
const IndexSetType & indexSet_
Definition: threaditerator.hh:42
GridPartType::template Codim< 0 >::template Partition< pitype >::IteratorType IteratorType
Definition: threaditerator.hh:31
const bool communicationThread_
Definition: threaditerator.hh:53
size_t countElements(const Iterator &begin, const Iterator &end) const
Definition: threaditerator.hh:257
GridPart GridPartType
Definition: threaditerator.hh:29
IteratorType end(int thread) const
Definition: threaditerator.hh:223
IteratorType begin() const
return begin iterator for current thread
Definition: threaditerator.hh:191
const GridPartType & gridPart_
Definition: threaditerator.hh:40
const FilterType & filter(const unsigned int thread) const
return filter for given thread
Definition: threaditerator.hh:81
int index(const EntityType &entity) const
return thread number this entity belongs to
Definition: threaditerator.hh:229
int threadParallel(const EntityType &entity) const
Definition: threaditerator.hh:234
const DofManagerType & dofManager_
Definition: threaditerator.hh:41
std::vector< IteratorType > iterators_
Definition: threaditerator.hh:47
ThreadIterator(const GridPartType &gridPart, const ParameterReader &parameter=Parameter::container())
contructor creating thread iterators
Definition: threaditerator.hh:58
Storage of thread iterators.
Definition: threaditerator.hh:290
ThreadIteratorStorage(const GridPart &gridPart)
Definition: threaditerator.hh:293
Storage of thread iterators using domain decomposition.
Definition: threaditeratorstorage.hh:22
Definition: dofmanager.hh:761
size_type size() const
return size of array
Definition: dynamicarray.hh:170
void setMemoryFactor(double memFactor)
set memory factor
Definition: dynamicarray.hh:296
void resize(size_type nsize)
Definition: dynamicarray.hh:334