collecttoiorank.hh
Go to the documentation of this file.
1 /*
2  Copyright 2015 IRIS AS
3 
4  This file is part of the Open Porous Media project (OPM).
5 
6  OPM is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  OPM is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with OPM. If not, see <http://www.gnu.org/licenses/>.
18 */
19 #ifndef EWOMS_PARALLELSERIALOUTPUT_HH
20 #define EWOMS_PARALLELSERIALOUTPUT_HH
21 
22 //#if HAVE_DUNE_CORNERPOINT
23 #include <dune/grid/common/p2pcommunicator.hh>
24 //#else
25 //#error "This header needs the dune-cornerpoint module."
26 //#endif
27 
28 namespace Ewoms
29 {
30  template < class GridManager >
32  {
33  public:
34  typedef typename GridManager :: Grid Grid;
35  typedef typename Grid :: CollectiveCommunication CollectiveCommunication;
36 
37  // global id
39  {
40  int globalId_;
41  int localIndex_;
42  bool isInterior_;
43  public:
44  GlobalCellIndex() : globalId_(-1), localIndex_(-1), isInterior_(true) {}
45  void setGhost() { isInterior_ = false; }
46 
47  void setId( const int globalId ) { globalId_ = globalId; }
48  void setIndex( const int localIndex ) { localIndex_ = localIndex; }
49 
50  int localIndex () const { return localIndex_; }
51  int id () const { return globalId_; }
52  bool isInterior() const { return isInterior_; }
53  };
54 
55  typedef typename Dune::PersistentContainer< Grid, GlobalCellIndex > GlobalIndexContainer;
56 
57  static const int dimension = Grid :: dimension ;
58 
59  typedef typename Grid :: LeafGridView GridView;
60  typedef GridView AllGridView;
61 
62  typedef Dune :: Point2PointCommunicator< Dune :: SimpleMessageBuffer > P2PCommunicatorType;
63  typedef typename P2PCommunicatorType :: MessageBufferType MessageBufferType;
64 
65  typedef std::vector< GlobalCellIndex > LocalIndexMapType;
66 
67  typedef std::vector<int> IndexMapType;
68  typedef std::vector< IndexMapType > IndexMapStorageType;
69 
70  class DistributeIndexMapping : public P2PCommunicatorType::DataHandleInterface
71  {
72  protected:
73  const std::vector<int>& distributedGlobalIndex_;
74  IndexMapType& localIndexMap_;
75  IndexMapStorageType& indexMaps_;
76  std::map< const int, const int > globalPosition_;
77 #ifndef NDEBUG
78  std::set< int > checkPosition_;
79 #endif
80 
81  public:
82  DistributeIndexMapping( const std::vector<int>& globalIndex,
83  const std::vector<int>& distributedGlobalIndex,
84  IndexMapType& localIndexMap,
85  IndexMapStorageType& indexMaps )
86  : distributedGlobalIndex_( distributedGlobalIndex ),
87  localIndexMap_( localIndexMap ),
88  indexMaps_( indexMaps ),
89  globalPosition_()
90  {
91  const size_t size = globalIndex.size();
92  // create mapping globalIndex --> localIndex
93  for ( size_t index = 0; index < size; ++index )
94  {
95  globalPosition_.insert( std::make_pair( globalIndex[ index ], index ) );
96  }
97 
98  // on I/O rank we need to create a mapping from local to global
99  if( ! indexMaps_.empty() )
100  {
101  // for the ioRank create a localIndex to index in global state map
102  IndexMapType& indexMap = indexMaps_.back();
103  const size_t localSize = localIndexMap_.size();
104  indexMap.resize( localSize );
105  for( size_t i=0; i<localSize; ++i )
106  {
107  const int id = distributedGlobalIndex_[ localIndexMap_[ i ] ];
108  indexMap[ i ] = globalPosition_[ id ] ;
109 #ifndef NDEBUG
110  assert( checkPosition_.find( id ) == checkPosition_.end() );
111  checkPosition_.insert( id );
112 #endif
113  }
114  }
115  }
116 
117  void pack( const int link, MessageBufferType& buffer )
118  {
119  // we should only get one link
120  if( link != 0 ) {
121  OPM_THROW(std::logic_error,"link in method pack is not 0 as execpted");
122  }
123 
124  // pack all interior global cell id's
125  const int size = localIndexMap_.size();
126  buffer.write( size );
127 
128  for( int index = 0; index < size; ++index )
129  {
130  const int globalIdx = distributedGlobalIndex_[ localIndexMap_[ index ] ];
131  buffer.write( globalIdx );
132  }
133  }
134 
135  void unpack( const int link, MessageBufferType& buffer )
136  {
137  // get index map for current link
138  IndexMapType& indexMap = indexMaps_[ link ];
139  assert( ! globalPosition_.empty() );
140 
141  // unpack all interior global cell id's
142  int numCells = 0;
143  buffer.read( numCells );
144  indexMap.resize( numCells );
145  for( int index = 0; index < numCells; ++index )
146  {
147  int globalId = -1;
148  buffer.read( globalId );
149  assert( globalPosition_.find( globalId ) != globalPosition_.end() );
150  indexMap[ index ] = globalPosition_[ globalId ];
151 #ifndef NDEBUG
152  assert( checkPosition_.find( globalId ) == checkPosition_.end() );
153  checkPosition_.insert( globalId );
154 #endif
155  }
156  }
157  };
158 
159  enum { ioRank = 0 };
160 
161  CollectDataToIORank( const GridManager& gridManager )
162  : toIORankComm_( gridManager.grid().comm() ),
163  isIORank_( gridManager.grid().comm().rank() == ioRank )
164  {
165  const CollectiveCommunication& comm = gridManager.grid().comm();
166  {
167  std::set< int > send, recv;
168  // the I/O rank receives from all other ranks
169  if( isIORank() )
170  {
171  // the I/O rank needs a picture of the global grid
172  const auto& eclGrid = *(gridManager.eclGrid());
173  const size_t cartesianSize = eclGrid.getCartesianSize();
174  // reserve memory
175  globalCartesianIndex_.reserve( cartesianSize );
176  globalCartesianIndex_.clear();
177  // get a global cartesian index for each active cell in the eclipse grid
178  for( size_t cartIndex=0; cartIndex<cartesianSize; ++cartIndex )
179  {
180  if( eclGrid.cellActive( cartIndex ) )
181  {
182  globalCartesianIndex_.push_back( cartIndex );
183  }
184  }
185 
186  for(int i=0; i<comm.size(); ++i)
187  {
188  if( i != ioRank )
189  {
190  recv.insert( i );
191  }
192  }
193  }
194  else // all other simply send to the I/O rank
195  {
196  send.insert( ioRank );
197  }
198 
199  localIndexMap_.clear();
200  const size_t gridSize = gridManager.grid().size( 0 );
201  localIndexMap_.reserve( gridSize );
202 
203  unsigned int index = 0;
204  auto localView = gridManager.grid().leafGridView();
205  for( auto it = localView.template begin< 0 >(),
206  end = localView.template end< 0 >(); it != end; ++it, ++index )
207  {
208  const auto element = *it ;
209  // only store interior element for collection
210  if( element.partitionType() == Dune :: InteriorEntity )
211  {
212  localIndexMap_.push_back( index );
213  }
214  }
215 
216  // insert send and recv linkage to communicator
217  toIORankComm_.insertRequest( send, recv );
218 
219  if( isIORank() )
220  {
221  // need an index map for each rank
222  indexMaps_.clear();
223  indexMaps_.resize( comm.size() );
224  }
225 
226  // store the local cartesian index
227  IndexMapType distributedCartesianIndex;
228  distributedCartesianIndex.reserve( gridSize );
229  for( size_t cell = 0 ; cell<gridSize; ++cell )
230  distributedCartesianIndex.push_back( gridManager.cartesianIndex( cell ) );
231 
232  // distribute global id's to io rank for later association of dof's
233  DistributeIndexMapping distIndexMapping( globalCartesianIndex_, distributedCartesianIndex, localIndexMap_, indexMaps_ );
234  toIORankComm_.exchange( distIndexMapping );
235  }
236  }
237 
238  template <class BufferList>
239  class PackUnPackOutputBuffers : public P2PCommunicatorType::DataHandleInterface
240  {
241  BufferList& bufferList_;
242 
243  const IndexMapType& localIndexMap_;
244  const IndexMapStorageType& indexMaps_;
245 
246  public:
247  PackUnPackOutputBuffers( BufferList& bufferList,
248  const IndexMapType& localIndexMap,
249  const IndexMapStorageType& indexMaps,
250  const size_t globalSize,
251  const bool isIORank )
252  : bufferList_( bufferList ),
253  localIndexMap_( localIndexMap ),
254  indexMaps_( indexMaps )
255  {
256  if( isIORank )
257  {
258  MessageBufferType buffer;
259  pack( 0, buffer );
260  // resize all buffers
261  for (auto it = bufferList_.begin(), end = bufferList_.end(); it != end; ++it )
262  {
263  it->second->resize( globalSize );
264  }
265  // the last index map is the local one
266  doUnpack( indexMaps.back(), buffer );
267 
268  }
269  }
270 
271  // pack all data associated with link
272  void pack( const int link, MessageBufferType& buffer )
273  {
274  // we should only get one link
275  if( link != 0 ) {
276  OPM_THROW(std::logic_error,"link in method pack is not 0 as execpted");
277  }
278 
279  size_t buffers = bufferList_.size();
280  buffer.write( buffers );
281  for (auto it = bufferList_.begin(), end = bufferList_.end(); it != end; ++it )
282  {
283  write( buffer, localIndexMap_, *(it->second) );
284  }
285  }
286 
287  void doUnpack( const IndexMapType& indexMap, MessageBufferType& buffer )
288  {
289  size_t buffers = 0;
290  buffer.read( buffers );
291  assert( buffers == bufferList_.size() );
292  for( auto it = bufferList_.begin(), end = bufferList_.end(); it != end; ++it )
293  {
294  read( buffer, indexMap, *(it->second) );
295  }
296  }
297 
298  // unpack all data associated with link
299  void unpack( const int link, MessageBufferType& buffer )
300  {
301  doUnpack( indexMaps_[ link ], buffer );
302  }
303 
304  protected:
305  template <class Vector>
306  void write( MessageBufferType& buffer, const IndexMapType& localIndexMap, const Vector& data ) const
307  {
308  const size_t size = localIndexMap.size();
309  assert( size <= data.size() );
310  buffer.write( size );
311  for( size_t i=0; i<size; ++i )
312  {
313  buffer.write( data[ localIndexMap[ i ] ] );
314  }
315  }
316 
317  template <class Vector>
318  void read( MessageBufferType& buffer, const IndexMapType& indexMap, Vector& data ) const
319  {
320  size_t size = indexMap.size();
321  assert( size <= data.size() );
322  buffer.read( size );
323  assert( size == indexMap.size() );
324  for( size_t i=0; i<size; ++i )
325  {
326  buffer.read( data[ indexMap[ i ] ] );
327  }
328  }
329 
330  void writeString( MessageBufferType& buffer, const std::string& s) const
331  {
332  const int size = s.size();
333  buffer.write( size );
334  for( int i=0; i<size; ++i )
335  {
336  buffer.write( s[ i ] );
337  }
338  }
339 
340  void readString( MessageBufferType& buffer, std::string& s) const
341  {
342  int size = -1;
343  buffer.read( size );
344  s.resize( size );
345  for( int i=0; i<size; ++i )
346  {
347  buffer.read( s[ i ] );
348  }
349  }
350  };
351 
352  // gather solution to rank 0 for EclipseWriter
353  template <class BufferList>
354  bool collect( BufferList& bufferList ) const
355  {
357  packUnpack( bufferList,
359 
360  //toIORankComm_.exchangeCached( packUnpack );
361  toIORankComm_.exchange( packUnpack );
362 #ifndef NDEBUG
363  // mkae sure every process is on the same page
364  toIORankComm_.barrier();
365 #endif
366  return isIORank();
367  }
368 
369  bool isIORank() const
370  {
371  return isIORank_;
372  }
373 
374  bool isParallel() const
375  {
376  return toIORankComm_.size() > 1;
377  }
378 
379  size_t numCells () const { return globalCartesianIndex_.size(); }
380 
381  protected:
382  P2PCommunicatorType toIORankComm_;
383  IndexMapType globalCartesianIndex_;
384  IndexMapType localIndexMap_;
385  IndexMapStorageType indexMaps_;
386  // true if we are on I/O rank
387  const bool isIORank_;
388  };
389 
390 } // end namespace Opm
391 #endif
std::vector< GlobalCellIndex > LocalIndexMapType
Definition: collecttoiorank.hh:65
std::set< int > checkPosition_
Definition: collecttoiorank.hh:78
Dune::PersistentContainer< Grid, GlobalCellIndex > GlobalIndexContainer
Definition: collecttoiorank.hh:55
std::vector< int > IndexMapType
Definition: collecttoiorank.hh:67
void pack(const int link, MessageBufferType &buffer)
Definition: collecttoiorank.hh:272
IndexMapType globalCartesianIndex_
Definition: collecttoiorank.hh:383
Definition: collecttoiorank.hh:38
void doUnpack(const IndexMapType &indexMap, MessageBufferType &buffer)
Definition: collecttoiorank.hh:287
void setIndex(const int localIndex)
Definition: collecttoiorank.hh:48
IndexMapStorageType indexMaps_
Definition: collecttoiorank.hh:385
CollectDataToIORank(const GridManager &gridManager)
Definition: collecttoiorank.hh:161
Definition: collecttoiorank.hh:239
Grid::CollectiveCommunication CollectiveCommunication
Definition: collecttoiorank.hh:35
PackUnPackOutputBuffers(BufferList &bufferList, const IndexMapType &localIndexMap, const IndexMapStorageType &indexMaps, const size_t globalSize, const bool isIORank)
Definition: collecttoiorank.hh:247
GridView AllGridView
Definition: collecttoiorank.hh:60
const bool isIORank_
Definition: collecttoiorank.hh:387
GlobalCellIndex()
Definition: collecttoiorank.hh:44
std::map< const int, const int > globalPosition_
Definition: collecttoiorank.hh:76
IndexMapType localIndexMap_
Definition: collecttoiorank.hh:384
bool isParallel() const
Definition: collecttoiorank.hh:374
bool isInterior() const
Definition: collecttoiorank.hh:52
void readString(MessageBufferType &buffer, std::string &s) const
Definition: collecttoiorank.hh:340
void pack(const int link, MessageBufferType &buffer)
Definition: collecttoiorank.hh:117
void setGhost()
Definition: collecttoiorank.hh:45
P2PCommunicatorType toIORankComm_
Definition: collecttoiorank.hh:382
const std::vector< int > & distributedGlobalIndex_
Definition: collecttoiorank.hh:73
static const int dimension
Definition: collecttoiorank.hh:57
Definition: baseauxiliarymodule.hh:35
void unpack(const int link, MessageBufferType &buffer)
Definition: collecttoiorank.hh:135
IndexMapType & localIndexMap_
Definition: collecttoiorank.hh:74
void unpack(const int link, MessageBufferType &buffer)
Definition: collecttoiorank.hh:299
IndexMapStorageType & indexMaps_
Definition: collecttoiorank.hh:75
bool collect(BufferList &bufferList) const
Definition: collecttoiorank.hh:354
int id() const
Definition: collecttoiorank.hh:51
void read(MessageBufferType &buffer, const IndexMapType &indexMap, Vector &data) const
Definition: collecttoiorank.hh:318
int localIndex() const
Definition: collecttoiorank.hh:50
P2PCommunicatorType::MessageBufferType MessageBufferType
Definition: collecttoiorank.hh:63
bool isIORank() const
Definition: collecttoiorank.hh:369
size_t numCells() const
Definition: collecttoiorank.hh:379
void writeString(MessageBufferType &buffer, const std::string &s) const
Definition: collecttoiorank.hh:330
Dune::Point2PointCommunicator< Dune::SimpleMessageBuffer > P2PCommunicatorType
Definition: collecttoiorank.hh:62
DistributeIndexMapping(const std::vector< int > &globalIndex, const std::vector< int > &distributedGlobalIndex, IndexMapType &localIndexMap, IndexMapStorageType &indexMaps)
Definition: collecttoiorank.hh:82
GridManager::Grid Grid
Definition: collecttoiorank.hh:34
void setId(const int globalId)
Definition: collecttoiorank.hh:47
Grid::LeafGridView GridView
Definition: collecttoiorank.hh:59
Definition: collecttoiorank.hh:159
Definition: collecttoiorank.hh:31
void write(MessageBufferType &buffer, const IndexMapType &localIndexMap, const Vector &data) const
Definition: collecttoiorank.hh:306
std::vector< IndexMapType > IndexMapStorageType
Definition: collecttoiorank.hh:68