EpetraExt  Development
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
EpetraExt_Migrate.h
Go to the documentation of this file.
1 //@HEADER
2 // ***********************************************************************
3 //
4 // EpetraExt: Epetra Extended - Linear Algebra Services Package
5 // Copyright (2011) Sandia Corporation
6 //
7 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
8 // the U.S. Government retains certain rights in this software.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
38 //
39 // ***********************************************************************
40 //@HEADER
41 #ifndef EPETRAEXT_MIGRATE_H
42 #define EPETRAEXT_MIGRATE_H
43 
44 // ---------- Includes ----------
45 
46 #include <string>
47 #include <vector>
48 #include <map>
49 
50 #include <Teuchos_RCP.hpp>
51 
52 #include <EpetraExt_PackTraits.h>
53 
54 #ifdef EPETRA_MPI
55  #include <Epetra_MpiComm.h>
56  #include <Epetra_MpiDistributor.h>
57 #endif
58 
59 namespace EpetraExt {
60 
62 
64 template <typename KT, typename DT>
65 class Migrate
66 {
67  public:
68 
69  typedef typename std::map< KT, Teuchos::RCP<DT> > DataMap;
70  typedef typename DataMap::iterator DataMapIter;
71  typedef typename DataMap::const_iterator DataMapCIter;
72 
73  typedef typename DataMap::value_type DataPair;
74 
75  typedef typename std::vector<KT> KeyList;
76  typedef typename KeyList::iterator KeyListIter;
77  typedef typename KeyList::const_iterator KeyListCIter;
78 
79  typedef typename std::vector<int> ProcList;
80  typedef typename ProcList::iterator ProcListIter;
81 
82  typedef typename std::vector<char> Buffer;
83 
84  // Constructor
85  Migrate( Epetra_Comm & comm )
86  : comm_(comm),
87  imports_(0),
88  importSize_(0)
89  {}
90 
91  // Destructor
93  { if( importSize_ ) delete [] imports_; }
94 
95  private:
96 
97  // No public copy construction, assignment, or equality operators.
98  Migrate();
99 
100  bool operator==( Migrate const & right ) const;
101  bool operator!=( Migrate const & right ) const;
102 
103  public:
104 
105  void operator()( std::vector<int> const & pList,
106  std::vector<KT> const & iKeys,
107  std::vector<KT> & oKeys );
108 
109  void operator()( std::vector<int> const & pList,
110  std::map< KT, Teuchos::RCP<DT> > const & iData,
111  std::multimap< KT, Teuchos::RCP<DT> > & oData );
112 
113  void rvs( std::vector<int> const & pList,
114  std::vector<KT> const & keys,
115  std::map< KT, Teuchos::RCP<DT> > & iData,
116  std::map< KT, Teuchos::RCP<DT> > & oData );
117 
118  protected:
119 
121 
122  char * imports_;
124 
126 
127 };
128 
129 template <typename DT>
130 class Migrate1
131 {
132  public:
133 
134  typedef typename Teuchos::RCP<DT> DataPtr;
135  typedef typename std::vector<DataPtr> DataContainer;
136  typedef typename DataContainer::iterator DataContainerIter;
137  typedef typename DataContainer::const_iterator DataContainerCIter;
138 
139  typedef typename std::vector<int> ProcList;
140  typedef typename ProcList::iterator ProcListIter;
141 
142  typedef typename std::vector<char> Buffer;
143 
144  // Constructor
146  : comm_(comm),
147  imports_(0),
148  importSize_(0)
149  {}
150 
151  // Destructor
153  { if( importSize_ ) delete [] imports_; }
154 
155  private:
156 
157  // No public copy construction, assignment, or equality operators.
158  Migrate1();
159 
160  bool operator==( Migrate1 const & right ) const;
161  bool operator!=( Migrate1 const & right ) const;
162 
163  public:
164 
165  void operator()( std::vector<int> const & pList,
166  std::vector< Teuchos::RCP<DT> > const & iData,
167  std::vector< Teuchos::RCP<DT> > & oData );
168 
169  void rvs( std::vector<int> const & pList,
170  std::vector< Teuchos::RCP<DT> > const & iData,
171  std::vector< Teuchos::RCP<DT> > & oData );
172 
173  protected:
174 
176 
177  char * imports_;
179 
181 
182 };
183 
184 template <typename KT, typename DT>
185 void
187 operator()( std::vector<int> const & pList,
188  std::vector<KT> const & iKeys,
189  std::vector<KT> & oKeys )
190 {
191 #ifdef EPETRA_MPI
192  Epetra_MpiDistributor distributor( dynamic_cast<Epetra_MpiComm&>(comm_) );
193 
194  int exportCnt = pList.size();
195 
196  int max_size = 0;
197  KeyListCIter citKL = iKeys.begin();
198  KeyListCIter cendKL = iKeys.end();
199  for( ; citKL != cendKL; ++citKL )
200  max_size = std::max( max_size, static_cast<int>(PackTraits<KT>::size( *citKL )) );
201 
202  int importCnt;
203  distributor.CreateFromSends( exportCnt, &(pList[0]), true, importCnt );
204 
205  int max_all;
206  comm_.MaxAll( &max_size, &max_all, 1 );
207 
208  exports_.resize( max_all * exportCnt );
209 
210  if( importSize_ < (max_all*importCnt) )
211  {
212  if( importSize_ ) delete [] imports_;
213  importSize_ = (max_all*importCnt);
214  imports_ = new char[importSize_];
215  }
216 
217  int pos = 0;
218  citKL = iKeys.begin();
219  for( int i = 0; citKL != cendKL; ++citKL, ++i )
220  {
221  pos = max_all * i;
222  PackTraits<KT>::pack( *citKL, &(exports_[0]), (max_all*exportCnt ), pos );
223  }
224 
225  distributor.Do( &(exports_[0]), max_all, importSize_, imports_ );
226 
227  oKeys.resize( importCnt );
228  for( int i = 0; i < importCnt; ++i )
229  {
230  pos = max_all * i;
231  PackTraits<KT>::unpack( oKeys[i], &(imports_[0]), (max_all*importCnt), pos );
232  }
233 #else
234  //Just Copy Data
235  oKeys = iKeys;
236 #endif
237 }
238 
239 template <typename KT, typename DT>
240 void
242 operator()( std::vector<int> const & pList,
243  std::map< KT, Teuchos::RCP<DT> > const & iData,
244  std::multimap< KT, Teuchos::RCP<DT> > & oData )
245 {
246 #ifdef EPETRA_MPI
247  Epetra_MpiDistributor distributor( dynamic_cast<Epetra_MpiComm&>(comm_) );
248 
249  int exportCnt = pList.size();
250 
251  int max_size = 0;
252  DataMapCIter citDM = iData.begin();
253  DataMapCIter cendDM = iData.end();
254  for( ; citDM != cendDM; ++citDM )
255  max_size = std::max( max_size, static_cast<int>(PackTraits<KT>::size( citDM->first ))
256  + static_cast<int>(PackTraits<DT>::size( *(citDM->second) )) );
257 
258  int importCnt;
259  distributor.CreateFromSends( exportCnt, &(pList[0]), true, importCnt );
260 
261  int max_all;
262  comm_.MaxAll( &max_size, &max_all, 1 );
263 
264  exports_.resize( max_all * exportCnt );
265 
266  if( importSize_ < (max_all*importCnt) )
267  {
268  if( importSize_ ) delete [] imports_;
269  importSize_ = (max_all*importCnt);
270  imports_ = new char[importSize_];
271  }
272 
273  int pos = 0;
274  citDM = iData.begin();
275  for( int i = 0; citDM != cendDM; ++citDM, ++i )
276  {
277  pos = max_all * i;
278  PackTraits<KT>::pack( citDM->first, &(exports_[0]), (max_all*exportCnt ), pos );
279  PackTraits<DT>::pack( *(citDM->second), &(exports_[0]), (max_all*exportCnt ), pos );
280  }
281 
282  distributor.Do( &(exports_[0]), max_all, importSize_, imports_ );
283 
284  oData.clear();
285  KT key;
286  for( int i = 0; i < importCnt; ++i )
287  {
288  pos = max_all * i;
289  PackTraits<KT>::unpack( key, &(imports_[0]), (max_all*importCnt), pos );
290  Teuchos::RCP<DT> data = rcp( new DT );
291  PackTraits<DT>::unpack( *data, &(imports_[0]), (max_all*importCnt), pos );
292  oData.insert( DataPair( key, data ) );
293  }
294 #else
295  //Just Copy Data
296  DataMapCIter citDM = iData.begin();
297  DataMapCIter cendDM = iData.end();
298  for( ; citDM != cendDM; ++citDM )
299  oData.insert( *citDM );
300 #endif
301 }
302 
303 template <typename KT, typename DT>
304 void
306 rvs( std::vector<int> const & pList,
307  std::vector<KT> const & keys,
308  std::map< KT, Teuchos::RCP<DT> > & iData,
309  std::map< KT, Teuchos::RCP<DT> > & oData )
310 {
311 #ifdef EPETRA_MPI
312  Epetra_MpiDistributor distributor( dynamic_cast<Epetra_MpiComm&>(comm_) );
313 
314  int importCnt = pList.size();
315  int exportCnt;
316 
317  distributor.CreateFromSends( importCnt, &(pList[0]), true, exportCnt );
318 
319  if( exportCnt != keys.size() )
320  N_ERH_ErrorMgr::report( N_ERH_ErrorMgr::DEV_FATAL,
321  "Xyce::Parallel::Migrate::rvs Failed Size Match!\n" );
322 
323  int max_size = 0;
324  KeyListCIter citKL = keys.begin();
325  KeyListCIter cendKL = keys.end();
326  for( ; citKL != cendKL; ++citKL )
327  max_size = std::max( max_size, static_cast<int>(PackTraits<KT>::size( *citKL ) )
328  + static_cast<int>(PackTraits<DT>::size( *(iData[*citKL]) ) ) );
329 
330  int max_all;
331  comm_.MaxAll( &max_size, &max_all, 1 );
332 
333  exports_.resize( max_all * exportCnt );
334 
335  if( importSize_ < (max_all*importCnt) )
336  {
337  if( importSize_ ) delete [] imports_;
338  importSize_ = (max_all*importCnt);
339  imports_ = new char[importSize_];
340  }
341 
342  int pos = 0;
343  int i = 0;
344  citKL = keys.begin();
345  for( ; citKL != cendKL; ++citKL, ++i )
346  {
347  pos = max_all * i;
348  PackTraits<KT>::pack( *citKL, &(exports_[0]), (max_all*exportCnt ), pos );
349  PackTraits<DT>::pack( *(iData[*citKL]), &(exports_[0]), (max_all*exportCnt ), pos );
350  }
351 
352  distributor.DoReverse( &(exports_[0]), max_all, importSize_, imports_ );
353 
354  oData.clear();
355  KT key;
356  for( int i = 0; i < importCnt; ++i )
357  {
358  pos = max_all * i;
359  PackTraits<KT>::unpack( key, &(imports_[0]), (max_all*importCnt), pos );
360  Teuchos::RCP<DT> data = rcp( new DT );
361  PackTraits<DT>::unpack( *data, &(imports_[0]), (max_all*importCnt), pos );
362  oData[key] = data;
363  }
364 #else
365  oData = iData;
366 #endif
367 }
368 
369 template <typename DT>
370 void
372 operator()( std::vector<int> const & pList,
373  std::vector< Teuchos::RCP<DT> > const & iData,
374  std::vector< Teuchos::RCP<DT> > & oData )
375 {
376 #ifdef EPETRA_MPI
377  Epetra_MpiDistributor distributor( dynamic_cast<Epetra_MpiComm&>(comm_) );
378 
379  int exportCnt = pList.size();
380 
381  int max_size = 0;
382  DataContainerCIter citDC = iData.begin();
383  DataContainerCIter cendDC = iData.end();
384  for( ; citDC != cendDC; ++citDC )
385  max_size = std::max( max_size, static_cast<int>(PackTraits<DT>::size( **citDC )) );
386 
387  int importCnt;
388  distributor.CreateFromSends( exportCnt, &(pList[0]), true, importCnt );
389 
390  int max_all;
391  comm_.MaxAll( &max_size, &max_all, 1 );
392 
393  exports_.resize( max_all * exportCnt );
394 
395  if( importSize_ < (max_all*importCnt) )
396  {
397  if( importSize_ ) delete [] imports_;
398  importSize_ = (max_all*importCnt);
399  imports_ = new char[importSize_];
400  }
401 
402  int pos = 0;
403  citDC = iData.begin();
404  for( int i = 0; citDC != cendDC; ++citDC, ++i )
405  {
406  pos = max_all * i;
407  PackTraits<DT>::pack( **citKL, &(exports_[0]), (max_all*exportCnt ), pos );
408  }
409 
410  distributor.Do( &(exports_[0]), max_all, importSize_, imports_ );
411 
412  oData.clear();
413  for( int i = 0; i < importCnt; ++i )
414  {
415  pos = max_all * i;
416  Teuchos::RCP<DT> data = rcp( new DT );
417  PackTraits<DT>::unpack( *data, &(imports_[0]), (max_all*importCnt), pos );
418  oData.push_back( data );
419  }
420 #else
421  //Just Copy Data
422  oData = iData;
423 #endif
424 }
425 
426 template <typename DT>
427 void
429 rvs( std::vector<int> const & pList,
430  std::vector< Teuchos::RCP<DT> > const & iData,
431  std::vector< Teuchos::RCP<DT> > & oData )
432 {
433 #ifdef EPETRA_MPI
434  Epetra_MpiDistributor distributor( dynamic_cast<Epetra_MpiComm&>(comm_) );
435 
436  int importCnt = pList.size();
437  int exportCnt;
438 
439  distributor.CreateFromSends( importCnt, &(pList[0]), true, exportCnt );
440 
441  if( exportCnt != keys.size() )
442  N_ERH_ErrorMgr::report( N_ERH_ErrorMgr::DEV_FATAL,
443  "Xyce::Parallel::Migrate::rvs Failed Size Match!\n" );
444 
445  int max_size = 0;
446  DataContainerCIter citDC = iData.begin();
447  DataContainerCIter cendDC = iData.end();
448  for( ; citDC != cendDC; ++citDC )
449  max_size = std::max( max_size, PackTraits<DT>::size( **citDC ) );
450 
451  int max_all;
452  comm_.MaxAll( &max_size, &max_all, 1 );
453 
454  exports_.resize( max_all * exportCnt );
455 
456  if( importSize_ < (max_all*importCnt) )
457  {
458  if( importSize_ ) delete [] imports_;
459  importSize_ = (max_all*importCnt);
460  imports_ = new char[importSize_];
461  }
462 
463  int i = 0;
464  int pos = 0;
465  citDC = iData.begin();
466  for( ; citDC != cendDC; ++citDC, ++i )
467  {
468  pos = max_all * i;
469  PackTraits<DT>::pack( **citDC, &(exports_[0]), (max_all*exportCnt ), pos );
470  }
471 
472  distributor.DoReverse( &(exports_[0]), max_all, importSize_, imports_ );
473 
474  oData.clear();
475  for( int i = 0; i < importCnt; ++i )
476  {
477  pos = max_all * i;
478  Teuchos::RCP<DT> data = rcp( new DT );
479  PackTraits<DT>::unpack( *data, &(imports_[0]), (max_all*importCnt), pos );
480  oData.push_back( data );
481  }
482 #else
483  oData = iData;
484 #endif
485 }
486 
487 } //namespace EpetraExt
488 
489 #endif
Traits for packing and unpacking of data into char buffers for communication.
std::vector< KT > KeyList
void rvs(std::vector< int > const &pList, std::vector< KT > const &keys, std::map< KT, Teuchos::RCP< DT > > &iData, std::map< KT, Teuchos::RCP< DT > > &oData)
KeyList::const_iterator KeyListCIter
std::vector< int > ProcList
static void unpack(T &object, char *buf, size_t size, int &pos)
Unpacks object from char buffer.
DataMap::value_type DataPair
std::map< KT, Teuchos::RCP< DT > > DataMap
Teuchos::RCP< DT > DataPtr
DataMap::iterator DataMapIter
static void pack(T const &object, char *buf, size_t size, int &pos)
Packs object into char buffer.
std::vector< char > Buffer
int CreateFromSends(const int &NumExportIDs, const int *ExportPIDs, bool Deterministic, int &NumRemoteIDs)
ProcList::iterator ProcListIter
void rvs(std::vector< int > const &pList, std::vector< Teuchos::RCP< DT > > const &iData, std::vector< Teuchos::RCP< DT > > &oData)
Data Migration Utility used by EpetraExt::Directory.
void operator()(std::vector< int > const &pList, std::vector< Teuchos::RCP< DT > > const &iData, std::vector< Teuchos::RCP< DT > > &oData)
std::vector< char > Buffer
ProcList::iterator ProcListIter
DataContainer::const_iterator DataContainerCIter
std::vector< DataPtr > DataContainer
Migrate1(Epetra_Comm &comm)
DataMap::const_iterator DataMapCIter
int Do(char *export_objs, int obj_size, int &len_import_objs, char *&import_objs)
std::vector< int > ProcList
Migrate(Epetra_Comm &comm)
int DoReverse(char *export_objs, int obj_size, int &len_import_objs, char *&import_objs)
DataContainer::iterator DataContainerIter
void operator()(std::vector< int > const &pList, std::vector< KT > const &iKeys, std::vector< KT > &oKeys)
KeyList::iterator KeyListIter