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