DUNE-FEM (unstable)

domainthreaditerator.hh
1#ifndef DUNE_FEM_DOMAINTHREADITERATOR_HH
2#define DUNE_FEM_DOMAINTHREADITERATOR_HH
3
4#include <vector>
5
7
9
10#include <dune/fem/space/common/dofmanager.hh>
11#include <dune/fem/gridpart/filteredgridpart.hh>
12#include <dune/fem/gridpart/filter/domainfilter.hh>
13#include <dune/fem/misc/threads/threaditeratorstorage.hh>
14
15#ifdef USE_SMP_PARALLEL
16#if HAVE_DUNE_ALUGRID
17#define USE_THREADPARTITIONER
18#include <dune/fem/misc/threads/threadpartitioner.hh>
19#endif
20#endif
21
22namespace Dune {
23
24 namespace Fem {
25
27 template <class GridPart>
29 {
30 public:
31 typedef GridPart GridPartType;
32 typedef typename GridPartType :: GridType GridType;
33 typedef typename GridPartType :: IndexSetType IndexSetType;
34
35 typedef DomainFilter<GridPartType> FilterType;
36#ifdef USE_THREADPARTITIONER
37 typedef FilteredGridPart< GridPartType, FilterType, false > FilteredGridPartType ;
38
39 typedef typename FilteredGridPartType :: template Codim< 0 > :: IteratorType
40 IteratorType;
41#else
42 typedef typename GridPartType :: template Codim< 0 > :: IteratorType IteratorType ;
43#endif
44
45 typedef typename IteratorType :: Entity EntityType ;
46
48
49 static const PartitionIteratorType pitype = GridPartType :: indexSetPartitionType ;
50
51#ifdef USE_THREADPARTITIONER
52 typedef ThreadPartitioner< GridPartType > ThreadPartitionerType;
53 typedef typename ThreadPartitionerType :: Method PartitioningMethodType ;
54#endif // #ifdef USE_SMP_PARALLEL
55
56 protected:
57 const GridPartType& gridPart_;
58 const DofManagerType& dofManager_;
59 const IndexSetType& indexSet_;
60 const typename MPIManager::ThreadPoolType& threadPool_;
61
62#ifdef USE_THREADPARTITIONER
63 int sequence_;
64 int numThreads_;
65 std::vector< std::unique_ptr< FilteredGridPartType > > filteredGridParts_;
66
67 typedef typename FilterType :: DomainArrayType ThreadArrayType;
68 ThreadArrayType threadNum_;
69#endif
70 // ratio of computing time needed by the master thread compared to the other threads
71 double masterRatio_ ;
72
73#ifdef USE_THREADPARTITIONER
74 const PartitioningMethodType method_;
75#endif // #ifdef USE_SMP_PARALLEL
76
77 // if true, thread 0 does only communication and no computation
78 const bool communicationThread_;
79 const bool verbose_ ;
80
81 protected:
82#ifdef USE_THREADPARTITIONER
83 static PartitioningMethodType getMethod ( const ParameterReader &parameter )
84 {
85 // default is recursive
86 const std::string methodNames[] = { "recursive", "kway", "sfc" };
87 return (PartitioningMethodType ) parameter.getEnum("fem.threads.partitioningmethod", methodNames, 0 );
88 }
89#endif // #ifdef USE_SMP_PARALLEL
90
91 public:
93 explicit DomainDecomposedIterator( const GridPartType& gridPart, const ParameterReader &parameter = Parameter::container() )
94 : gridPart_( gridPart ),
95 dofManager_( DofManagerType :: instance( gridPart_.grid() ) ),
96 indexSet_( gridPart_.indexSet() ),
97 threadPool_( MPIManager::threadPool() )
98#ifdef USE_THREADPARTITIONER
99 , sequence_( -1 )
100 , numThreads_( threadPool_.numThreads() )
101 , filteredGridParts_( threadPool_.maxThreads() )
102#endif
103 , masterRatio_( 1.0 )
104#ifdef USE_THREADPARTITIONER
105 , method_( getMethod( parameter ) )
106#endif // #ifdef USE_SMP_PARALLEL
107 , communicationThread_( parameter.getValue<bool>("fem.threads.communicationthread", false)
108 && threadPool_.maxThreads() > 1 ) // only possible if maxThreads > 1
109 , verbose_( Parameter::verbose() &&
110 parameter.getValue<bool>("fem.threads.verbose", false ) )
111 {
112#ifdef USE_THREADPARTITIONER
113 for(int thread=0; thread < threadPool_.maxThreads(); ++thread )
114 {
115 // thread is the thread number of this filter
116 filteredGridParts_[ thread ].reset(
117 new FilteredGridPartType( const_cast<GridPartType &> (gridPart_),
118 FilterType( gridPart_, threadNum_, thread ) ) );
119 }
120
121 threadNum_.setMemoryFactor( 1.1 );
122#endif
123 update();
124 }
125
126#ifdef USE_THREADPARTITIONER
128 const FilterType& filter( const int thread ) const
129 {
130 return filteredGridParts_[ thread ]->filter();
131 }
132#endif // USE_SMP_PARALLEL
133
135 void update()
136 {
137#ifdef USE_THREADPARTITIONER
138 const int sequence = dofManager_.sequence() ;
139 // if grid got updated also update iterators
140 if( sequence_ != sequence || numThreads_ != threadPool_.numThreads() )
141 {
142 if( ! threadPool_.singleThreadMode() )
143 {
144 std::cerr << "Don't call ThreadIterator::update in a parallel environment!" << std::endl;
145 assert( false );
146 abort();
147 }
148
149 // check that grid is viewThreadSafe otherwise weird bugs can occur
150 if( (threadPool_.numThreads() > 1) && (! Dune::Capabilities::viewThreadSafe< GridType >:: v) )
151 {
152 DUNE_THROW(InvalidStateException,"DomainDecomposedIterator needs a grid with viewThreadSafe capability!");
153 }
154
155 const int commThread = communicationThread_ ? 1 : 0;
156 // get number of partitions possible
157 const size_t partitions = threadPool_.numThreads() - commThread ;
158
159 // create partitioner
160 ThreadPartitionerType db( gridPart_, partitions, masterRatio_ );
161 // do partitioning
162 db.serialPartition( method_ );
163
164 // get end iterator
165 typedef typename GridPartType :: template Codim< 0 > :: IteratorType GPIteratorType;
166 const GPIteratorType endit = gridPart_.template end< 0 >();
167
168 // get size for index set
169 const size_t size = indexSet_.size( 0 );
170
171 // resize threads storage
172 threadNum_.resize( size );
173 // set all values to default value
174 for(size_t i = 0; i<size; ++i) threadNum_[ i ] = -1;
175
176 {
177 // just for diagnostics
178 std::vector< int > counter( partitions+commThread , 0 );
179
180 int numInteriorElems = 0;
181 for(GPIteratorType it = gridPart_.template begin< 0 >();
182 it != endit; ++it, ++numInteriorElems )
183 {
184 const EntityType& entity = * it;
185 const int rank = db.getRank( entity ) + commThread ;
186 assert( rank >= 0 );
187 //std::cout << "Got rank = " << rank << "\n";
188 threadNum_[ indexSet_.index( entity ) ] = rank ;
189 ++counter[ rank ];
190 }
191
192 // update sequence number
193 sequence_ = sequence;
194
195 // update numThreads_
196 numThreads_ = threadPool_.numThreads();
197
198 if( verbose_ )
199 {
200 std::cout << "DomainDecomposedIterator: sequence = " << sequence_ << " size = " << numInteriorElems << std::endl;
201 const size_t counterSize = counter.size();
202 for(size_t i = 0; i<counterSize; ++i )
203 std::cout << "DomainDecomposedIterator: T[" << i << "] = " << counter[ i ] << std::endl;
204 }
205
206#ifndef NDEBUG
207 // check that all interior elements have got a valid thread number
208 for(GPIteratorType it = gridPart_.template begin< 0 >(); it != endit; ++it )
209 {
210 assert( threadNum_[ indexSet_.index( *it ) ] >= 0 );
211 }
212#endif
213 //for(size_t i = 0; i<size; ++i )
214 //{
215 // //std::cout << threadNum_[ i ] << std::endl;
216 //}
217 }
218 }
219#endif
220 }
221
223 IteratorType begin() const
224 {
225#ifdef USE_THREADPARTITIONER
226 if( ! threadPool_.singleThreadMode () )
227 {
228 const int thread = threadPool_.thread() ;
229 if( communicationThread_ && thread == 0 )
230 return filteredGridParts_[ thread ]->template end< 0 > ();
231 else
232 return filteredGridParts_[ thread ]->template begin< 0 > ();
233 }
234 else
235#endif
236 {
237 return gridPart_.template begin< 0 > ();
238 }
239 }
240
242 IteratorType end() const
243 {
244#ifdef USE_THREADPARTITIONER
245 if( ! threadPool_.singleThreadMode () )
246 {
247 return filteredGridParts_[ threadPool_.thread() ]->template end< 0 > ();
248 }
249 else
250#endif
251 {
252 return gridPart_.template end< 0 > ();
253 }
254 }
255
257 int index(const EntityType& entity ) const
258 {
259 return indexSet_.index( entity );
260 }
261
263 int thread(const EntityType& entity ) const
264 {
265#ifdef USE_THREADPARTITIONER
266 assert( (int)threadNum_.size() > (int) indexSet_.index( entity ) );
267 // NOTE: this number can also be negative for ghost elements or elements
268 // that do not belong to the set covered by the space iterators
269 return threadNum_[ indexSet_.index( entity ) ];
270#else
271 return 0;
272#endif
273 }
274
275 void setMasterRatio( const double ratio )
276 {
277 masterRatio_ = 0.5 * (ratio + masterRatio_);
278 }
279 };
280
281
283 template <class GridPart>
285 : public ThreadIteratorStorageBase< DomainDecomposedIterator< GridPart > >
286 {
288 public:
289 DomainDecomposedIteratorStorage( const GridPart& gridPart )
290 : BaseType( gridPart )
291 {}
292 };
293
294 } // end namespace Fem
295
296} // end namespace Dune
297
298#endif // #ifndef DUNE_FEM_DG_DOMAINTHREADITERATOR_HH
Definition: dofmanager.hh:786
Storage of thread iterators using domain decomposition.
Definition: domainthreaditerator.hh:286
Thread iterators using domain decomposition.
Definition: domainthreaditerator.hh:29
int index(const EntityType &entity) const
return thread number this entity belongs to
Definition: domainthreaditerator.hh:257
IteratorType begin() const
return begin iterator for current thread
Definition: domainthreaditerator.hh:223
IteratorType end() const
return end iterator for current thread
Definition: domainthreaditerator.hh:242
int thread(const EntityType &entity) const
return thread number this entity belongs to
Definition: domainthreaditerator.hh:263
DomainDecomposedIterator(const GridPartType &gridPart, const ParameterReader &parameter=Parameter::container())
contructor creating thread iterators
Definition: domainthreaditerator.hh:93
void update()
update internal list of iterators
Definition: domainthreaditerator.hh:135
A FilteredGridPart allows to extract a set of entities from a grid satisfying a given constrainted de...
Definition: filteredgridpart.hh:221
Container for User Specified Parameters.
Definition: parameter.hh:191
Storage of thread iterators using domain decomposition.
Definition: threaditeratorstorage.hh:22
Default exception if a function was called while the object is not in a valid state for that function...
Definition: exceptions.hh:281
A few common exception classes.
A set of traits classes to store static information about grid implementation.
int sequence() const
return number of sequence, if dofmanagers memory was changed by calling some method like resize,...
Definition: dofmanager.hh:1007
#define DUNE_THROW(E, m)
Definition: exceptions.hh:218
PartitionIteratorType
Parameter to be used for the parallel level- and leaf iterators.
Definition: gridenums.hh:136
Dune namespace.
Definition: alignedallocator.hh:13
constexpr std::integral_constant< std::size_t, sizeof...(II)> size(std::integer_sequence< T, II... >)
Return the size of the sequence.
Definition: integersequence.hh:75
Specialize with 'true' if the grid implementation is thread safe, while it is not modified....
Definition: capabilities.hh:169
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Nov 21, 23:30, 2024)