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
61#ifdef USE_THREADPARTITIONER
62 int sequence_;
63 int numThreads_;
64 std::vector< std::unique_ptr< FilteredGridPartType > > filteredGridParts_;
65
66 typedef typename FilterType :: DomainArrayType ThreadArrayType;
67 ThreadArrayType threadNum_;
68#endif
69 // ratio of computing time needed by the master thread compared to the other threads
70 double masterRatio_ ;
71
72#ifdef USE_THREADPARTITIONER
73 const PartitioningMethodType method_;
74#endif // #ifdef USE_SMP_PARALLEL
75
76 // if true, thread 0 does only communication and no computation
77 const bool communicationThread_;
78 const bool verbose_ ;
79
80 protected:
81#ifdef USE_THREADPARTITIONER
82 static PartitioningMethodType getMethod ( const ParameterReader &parameter )
83 {
84 // default is recursive
85 const std::string methodNames[] = { "recursive", "kway", "sfc" };
86 return (PartitioningMethodType ) parameter.getEnum("fem.threads.partitioningmethod", methodNames, 0 );
87 }
88#endif // #ifdef USE_SMP_PARALLEL
89
90 public:
92 explicit DomainDecomposedIterator( const GridPartType& gridPart, const ParameterReader &parameter = Parameter::container() )
93 : gridPart_( gridPart ),
94 dofManager_( DofManagerType :: instance( gridPart_.grid() ) ),
95 indexSet_( gridPart_.indexSet() )
96#ifdef USE_THREADPARTITIONER
97 , sequence_( -1 )
98 , numThreads_( Fem :: MPIManager :: numThreads() )
99 , filteredGridParts_( Fem :: MPIManager :: maxThreads() )
100#endif
101 , masterRatio_( 1.0 )
102#ifdef USE_THREADPARTITIONER
103 , method_( getMethod( parameter ) )
104#endif // #ifdef USE_SMP_PARALLEL
105 , communicationThread_( parameter.getValue<bool>("fem.threads.communicationthread", false)
106 && Fem :: MPIManager :: maxThreads() > 1 ) // only possible if maxThreads > 1
107 , verbose_( Parameter::verbose() &&
108 parameter.getValue<bool>("fem.threads.verbose", false ) )
109 {
110#ifdef USE_THREADPARTITIONER
111 for(int thread=0; thread < Fem :: MPIManager :: maxThreads(); ++thread )
112 {
113 // thread is the thread number of this filter
114 filteredGridParts_[ thread ].reset(
115 new FilteredGridPartType( const_cast<GridPartType &> (gridPart_),
116 FilterType( gridPart_, threadNum_, thread ) ) );
117 }
118
119 threadNum_.setMemoryFactor( 1.1 );
120#endif
121 update();
122 }
123
124#ifdef USE_THREADPARTITIONER
126 const FilterType& filter( const int thread ) const
127 {
128 return filteredGridParts_[ thread ]->filter();
129 }
130#endif // USE_SMP_PARALLEL
131
133 void update()
134 {
135#ifdef USE_THREADPARTITIONER
136 const int sequence = dofManager_.sequence() ;
137 // if grid got updated also update iterators
138 if( sequence_ != sequence || numThreads_ != MPIManager :: numThreads() )
139 {
140 if( ! MPIManager :: singleThreadMode() )
141 {
142 std::cerr << "Don't call ThreadIterator::update in a parallel environment!" << std::endl;
143 assert( false );
144 abort();
145 }
146
147 // check that grid is viewThreadSafe otherwise weird bugs can occur
148 if( (MPIManager :: numThreads() > 1) && (! Dune::Capabilities::viewThreadSafe< GridType >:: v) )
149 {
150 DUNE_THROW(InvalidStateException,"DomainDecomposedIterator needs a grid with viewThreadSafe capability!");
151 }
152
153 const int commThread = communicationThread_ ? 1 : 0;
154 // get number of partitions possible
155 const size_t partitions = MPIManager :: numThreads() - commThread ;
156
157 // create partitioner
158 ThreadPartitionerType db( gridPart_, partitions, masterRatio_ );
159 // do partitioning
160 db.serialPartition( method_ );
161
162 // get end iterator
163 typedef typename GridPartType :: template Codim< 0 > :: IteratorType GPIteratorType;
164 const GPIteratorType endit = gridPart_.template end< 0 >();
165
166 // get size for index set
167 const size_t size = indexSet_.size( 0 );
168
169 // resize threads storage
170 threadNum_.resize( size );
171 // set all values to default value
172 for(size_t i = 0; i<size; ++i) threadNum_[ i ] = -1;
173
174 {
175 // just for diagnostics
176 std::vector< int > counter( partitions+commThread , 0 );
177
178 int numInteriorElems = 0;
179 for(GPIteratorType it = gridPart_.template begin< 0 >();
180 it != endit; ++it, ++numInteriorElems )
181 {
182 const EntityType& entity = * it;
183 const int rank = db.getRank( entity ) + commThread ;
184 assert( rank >= 0 );
185 //std::cout << "Got rank = " << rank << "\n";
186 threadNum_[ indexSet_.index( entity ) ] = rank ;
187 ++counter[ rank ];
188 }
189
190 // update sequence number
191 sequence_ = sequence;
192
193 // update numThreads_
194 numThreads_ = MPIManager :: numThreads();
195
196 if( verbose_ )
197 {
198 std::cout << "DomainDecomposedIterator: sequence = " << sequence_ << " size = " << numInteriorElems << std::endl;
199 const size_t counterSize = counter.size();
200 for(size_t i = 0; i<counterSize; ++i )
201 std::cout << "DomainDecomposedIterator: T[" << i << "] = " << counter[ i ] << std::endl;
202 }
203
204#ifndef NDEBUG
205 // check that all interior elements have got a valid thread number
206 for(GPIteratorType it = gridPart_.template begin< 0 >(); it != endit; ++it )
207 {
208 assert( threadNum_[ indexSet_.index( *it ) ] >= 0 );
209 }
210#endif
211 //for(size_t i = 0; i<size; ++i )
212 //{
213 // //std::cout << threadNum_[ i ] << std::endl;
214 //}
215 }
216 }
217#endif
218 }
219
221 IteratorType begin() const
222 {
223#ifdef USE_THREADPARTITIONER
224 if( ! MPIManager :: singleThreadMode () )
225 {
226 const int thread = MPIManager :: thread() ;
227 if( communicationThread_ && thread == 0 )
228 return filteredGridParts_[ thread ]->template end< 0 > ();
229 else
230 return filteredGridParts_[ thread ]->template begin< 0 > ();
231 }
232 else
233#endif
234 {
235 return gridPart_.template begin< 0 > ();
236 }
237 }
238
240 IteratorType end() const
241 {
242#ifdef USE_THREADPARTITIONER
243 if( ! MPIManager :: singleThreadMode () )
244 {
245 return filteredGridParts_[ MPIManager :: thread() ]->template end< 0 > ();
246 }
247 else
248#endif
249 {
250 return gridPart_.template end< 0 > ();
251 }
252 }
253
255 int index(const EntityType& entity ) const
256 {
257 return indexSet_.index( entity );
258 }
259
261 int thread(const EntityType& entity ) const
262 {
263#ifdef USE_THREADPARTITIONER
264 assert( (int)threadNum_.size() > (int) indexSet_.index( entity ) );
265 // NOTE: this number can also be negative for ghost elements or elements
266 // that do not belong to the set covered by the space iterators
267 return threadNum_[ indexSet_.index( entity ) ];
268#else
269 return 0;
270#endif
271 }
272
273 void setMasterRatio( const double ratio )
274 {
275 masterRatio_ = 0.5 * (ratio + masterRatio_);
276 }
277 };
278
279
281 template <class GridPart>
283 : public ThreadIteratorStorageBase< DomainDecomposedIterator< GridPart > >
284 {
286 public:
287 DomainDecomposedIteratorStorage( const GridPart& gridPart )
288 : BaseType( gridPart )
289 {}
290 };
291
292 } // end namespace Fem
293
294} // end namespace Dune
295
296#endif // #ifndef DUNE_FEM_DG_DOMAINTHREADITERATOR_HH
Definition: dofmanager.hh:786
Storage of thread iterators using domain decomposition.
Definition: domainthreaditerator.hh:284
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:255
IteratorType begin() const
return begin iterator for current thread
Definition: domainthreaditerator.hh:221
IteratorType end() const
return end iterator for current thread
Definition: domainthreaditerator.hh:240
int thread(const EntityType &entity) const
return thread number this entity belongs to
Definition: domainthreaditerator.hh:261
DomainDecomposedIterator(const GridPartType &gridPart, const ParameterReader &parameter=Parameter::container())
contructor creating thread iterators
Definition: domainthreaditerator.hh:92
void update()
update internal list of iterators
Definition: domainthreaditerator.hh:133
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 (Jul 24, 22:29, 2024)