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 #if defined(EpetraExt_SHOW_DEPRECATED_WARNINGS)
45 #ifdef __GNUC__
46 #warning "The EpetraExt package is deprecated"
47 #endif
48 #endif
49 
50 // ---------- Includes ----------
51 
52 #include <string>
53 #include <vector>
54 #include <map>
55 
56 #include <Teuchos_RCP.hpp>
57 
58 #include <EpetraExt_PackTraits.h>
59 
60 #ifdef EPETRA_MPI
61  #include <Epetra_MpiComm.h>
62  #include <Epetra_MpiDistributor.h>
63 #endif
64 
65 namespace EpetraExt {
66 
68 
70 template <typename KT, typename DT>
71 class Migrate
72 {
73  public:
74 
75  typedef typename std::map< KT, Teuchos::RCP<DT> > DataMap;
76  typedef typename DataMap::iterator DataMapIter;
77  typedef typename DataMap::const_iterator DataMapCIter;
78 
79  typedef typename DataMap::value_type DataPair;
80 
81  typedef typename std::vector<KT> KeyList;
82  typedef typename KeyList::iterator KeyListIter;
83  typedef typename KeyList::const_iterator KeyListCIter;
84 
85  typedef typename std::vector<int> ProcList;
86  typedef typename ProcList::iterator ProcListIter;
87 
88  typedef typename std::vector<char> Buffer;
89 
90  // Constructor
91  Migrate( Epetra_Comm & comm )
92  : comm_(comm),
93  imports_(0),
94  importSize_(0)
95  {}
96 
97  // Destructor
99  { if( importSize_ ) delete [] imports_; }
100 
101  private:
102 
103  // No public copy construction, assignment, or equality operators.
104  Migrate();
105 
106  bool operator==( Migrate const & right ) const;
107  bool operator!=( Migrate const & right ) const;
108 
109  public:
110 
111  void operator()( std::vector<int> const & pList,
112  std::vector<KT> const & iKeys,
113  std::vector<KT> & oKeys );
114 
115  void operator()( std::vector<int> const & pList,
116  std::map< KT, Teuchos::RCP<DT> > const & iData,
117  std::multimap< KT, Teuchos::RCP<DT> > & oData );
118 
119  void rvs( std::vector<int> const & pList,
120  std::vector<KT> const & keys,
121  std::map< KT, Teuchos::RCP<DT> > & iData,
122  std::map< KT, Teuchos::RCP<DT> > & oData );
123 
124  protected:
125 
127 
128  char * imports_;
130 
132 
133 };
134 
135 template <typename DT>
136 class Migrate1
137 {
138  public:
139 
140  typedef typename Teuchos::RCP<DT> DataPtr;
141  typedef typename std::vector<DataPtr> DataContainer;
142  typedef typename DataContainer::iterator DataContainerIter;
143  typedef typename DataContainer::const_iterator DataContainerCIter;
144 
145  typedef typename std::vector<int> ProcList;
146  typedef typename ProcList::iterator ProcListIter;
147 
148  typedef typename std::vector<char> Buffer;
149 
150  // Constructor
152  : comm_(comm),
153  imports_(0),
154  importSize_(0)
155  {}
156 
157  // Destructor
159  { if( importSize_ ) delete [] imports_; }
160 
161  private:
162 
163  // No public copy construction, assignment, or equality operators.
164  Migrate1();
165 
166  bool operator==( Migrate1 const & right ) const;
167  bool operator!=( Migrate1 const & right ) const;
168 
169  public:
170 
171  void operator()( std::vector<int> const & pList,
172  std::vector< Teuchos::RCP<DT> > const & iData,
173  std::vector< Teuchos::RCP<DT> > & oData );
174 
175  void rvs( std::vector<int> const & pList,
176  std::vector< Teuchos::RCP<DT> > const & iData,
177  std::vector< Teuchos::RCP<DT> > & oData );
178 
179  protected:
180 
182 
183  char * imports_;
185 
187 
188 };
189 
190 template <typename KT, typename DT>
191 void
193 operator()( std::vector<int> const & pList,
194  std::vector<KT> const & iKeys,
195  std::vector<KT> & oKeys )
196 {
197 #ifdef EPETRA_MPI
198  Epetra_MpiDistributor distributor( dynamic_cast<Epetra_MpiComm&>(comm_) );
199 
200  int exportCnt = pList.size();
201 
202  int max_size = 0;
203  KeyListCIter citKL = iKeys.begin();
204  KeyListCIter cendKL = iKeys.end();
205  for( ; citKL != cendKL; ++citKL )
206  max_size = std::max( max_size, static_cast<int>(PackTraits<KT>::size( *citKL )) );
207 
208  int importCnt;
209  distributor.CreateFromSends( exportCnt, &(pList[0]), true, importCnt );
210 
211  int max_all;
212  comm_.MaxAll( &max_size, &max_all, 1 );
213 
214  exports_.resize( max_all * exportCnt );
215 
216  if( importSize_ < (max_all*importCnt) )
217  {
218  if( importSize_ ) delete [] imports_;
219  importSize_ = (max_all*importCnt);
220  imports_ = new char[importSize_];
221  }
222 
223  int pos = 0;
224  citKL = iKeys.begin();
225  for( int i = 0; citKL != cendKL; ++citKL, ++i )
226  {
227  pos = max_all * i;
228  PackTraits<KT>::pack( *citKL, &(exports_[0]), (max_all*exportCnt ), pos );
229  }
230 
231  distributor.Do( &(exports_[0]), max_all, importSize_, imports_ );
232 
233  oKeys.resize( importCnt );
234  for( int i = 0; i < importCnt; ++i )
235  {
236  pos = max_all * i;
237  PackTraits<KT>::unpack( oKeys[i], &(imports_[0]), (max_all*importCnt), pos );
238  }
239 #else
240  //Just Copy Data
241  oKeys = iKeys;
242 #endif
243 }
244 
245 template <typename KT, typename DT>
246 void
248 operator()( std::vector<int> const & pList,
249  std::map< KT, Teuchos::RCP<DT> > const & iData,
250  std::multimap< KT, Teuchos::RCP<DT> > & oData )
251 {
252 #ifdef EPETRA_MPI
253  Epetra_MpiDistributor distributor( dynamic_cast<Epetra_MpiComm&>(comm_) );
254 
255  int exportCnt = pList.size();
256 
257  int max_size = 0;
258  DataMapCIter citDM = iData.begin();
259  DataMapCIter cendDM = iData.end();
260  for( ; citDM != cendDM; ++citDM )
261  max_size = std::max( max_size, static_cast<int>(PackTraits<KT>::size( citDM->first ))
262  + static_cast<int>(PackTraits<DT>::size( *(citDM->second) )) );
263 
264  int importCnt;
265  distributor.CreateFromSends( exportCnt, &(pList[0]), true, importCnt );
266 
267  int max_all;
268  comm_.MaxAll( &max_size, &max_all, 1 );
269 
270  exports_.resize( max_all * exportCnt );
271 
272  if( importSize_ < (max_all*importCnt) )
273  {
274  if( importSize_ ) delete [] imports_;
275  importSize_ = (max_all*importCnt);
276  imports_ = new char[importSize_];
277  }
278 
279  int pos = 0;
280  citDM = iData.begin();
281  for( int i = 0; citDM != cendDM; ++citDM, ++i )
282  {
283  pos = max_all * i;
284  PackTraits<KT>::pack( citDM->first, &(exports_[0]), (max_all*exportCnt ), pos );
285  PackTraits<DT>::pack( *(citDM->second), &(exports_[0]), (max_all*exportCnt ), pos );
286  }
287 
288  distributor.Do( &(exports_[0]), max_all, importSize_, imports_ );
289 
290  oData.clear();
291  KT key;
292  for( int i = 0; i < importCnt; ++i )
293  {
294  pos = max_all * i;
295  PackTraits<KT>::unpack( key, &(imports_[0]), (max_all*importCnt), pos );
296  Teuchos::RCP<DT> data = rcp( new DT );
297  PackTraits<DT>::unpack( *data, &(imports_[0]), (max_all*importCnt), pos );
298  oData.insert( DataPair( key, data ) );
299  }
300 #else
301  //Just Copy Data
302  DataMapCIter citDM = iData.begin();
303  DataMapCIter cendDM = iData.end();
304  for( ; citDM != cendDM; ++citDM )
305  oData.insert( *citDM );
306 #endif
307 }
308 
309 template <typename KT, typename DT>
310 void
312 rvs( std::vector<int> const & pList,
313  std::vector<KT> const & keys,
314  std::map< KT, Teuchos::RCP<DT> > & iData,
315  std::map< KT, Teuchos::RCP<DT> > & oData )
316 {
317 #ifdef EPETRA_MPI
318  Epetra_MpiDistributor distributor( dynamic_cast<Epetra_MpiComm&>(comm_) );
319 
320  int importCnt = pList.size();
321  int exportCnt;
322 
323  distributor.CreateFromSends( importCnt, &(pList[0]), true, exportCnt );
324 
325  if( exportCnt != keys.size() )
326  N_ERH_ErrorMgr::report( N_ERH_ErrorMgr::DEV_FATAL,
327  "Xyce::Parallel::Migrate::rvs Failed Size Match!\n" );
328 
329  int max_size = 0;
330  KeyListCIter citKL = keys.begin();
331  KeyListCIter cendKL = keys.end();
332  for( ; citKL != cendKL; ++citKL )
333  max_size = std::max( max_size, static_cast<int>(PackTraits<KT>::size( *citKL ) )
334  + static_cast<int>(PackTraits<DT>::size( *(iData[*citKL]) ) ) );
335 
336  int max_all;
337  comm_.MaxAll( &max_size, &max_all, 1 );
338 
339  exports_.resize( max_all * exportCnt );
340 
341  if( importSize_ < (max_all*importCnt) )
342  {
343  if( importSize_ ) delete [] imports_;
344  importSize_ = (max_all*importCnt);
345  imports_ = new char[importSize_];
346  }
347 
348  int pos = 0;
349  int i = 0;
350  citKL = keys.begin();
351  for( ; citKL != cendKL; ++citKL, ++i )
352  {
353  pos = max_all * i;
354  PackTraits<KT>::pack( *citKL, &(exports_[0]), (max_all*exportCnt ), pos );
355  PackTraits<DT>::pack( *(iData[*citKL]), &(exports_[0]), (max_all*exportCnt ), pos );
356  }
357 
358  distributor.DoReverse( &(exports_[0]), max_all, importSize_, imports_ );
359 
360  oData.clear();
361  KT key;
362  for( int i = 0; i < importCnt; ++i )
363  {
364  pos = max_all * i;
365  PackTraits<KT>::unpack( key, &(imports_[0]), (max_all*importCnt), pos );
366  Teuchos::RCP<DT> data = rcp( new DT );
367  PackTraits<DT>::unpack( *data, &(imports_[0]), (max_all*importCnt), pos );
368  oData[key] = data;
369  }
370 #else
371  oData = iData;
372 #endif
373 }
374 
375 template <typename DT>
376 void
378 operator()( std::vector<int> const & pList,
379  std::vector< Teuchos::RCP<DT> > const & iData,
380  std::vector< Teuchos::RCP<DT> > & oData )
381 {
382 #ifdef EPETRA_MPI
383  Epetra_MpiDistributor distributor( dynamic_cast<Epetra_MpiComm&>(comm_) );
384 
385  int exportCnt = pList.size();
386 
387  int max_size = 0;
388  DataContainerCIter citDC = iData.begin();
389  DataContainerCIter cendDC = iData.end();
390  for( ; citDC != cendDC; ++citDC )
391  max_size = std::max( max_size, static_cast<int>(PackTraits<DT>::size( **citDC )) );
392 
393  int importCnt;
394  distributor.CreateFromSends( exportCnt, &(pList[0]), true, importCnt );
395 
396  int max_all;
397  comm_.MaxAll( &max_size, &max_all, 1 );
398 
399  exports_.resize( max_all * exportCnt );
400 
401  if( importSize_ < (max_all*importCnt) )
402  {
403  if( importSize_ ) delete [] imports_;
404  importSize_ = (max_all*importCnt);
405  imports_ = new char[importSize_];
406  }
407 
408  int pos = 0;
409  citDC = iData.begin();
410  for( int i = 0; citDC != cendDC; ++citDC, ++i )
411  {
412  pos = max_all * i;
413  PackTraits<DT>::pack( **citKL, &(exports_[0]), (max_all*exportCnt ), pos );
414  }
415 
416  distributor.Do( &(exports_[0]), max_all, importSize_, imports_ );
417 
418  oData.clear();
419  for( int i = 0; i < importCnt; ++i )
420  {
421  pos = max_all * i;
422  Teuchos::RCP<DT> data = rcp( new DT );
423  PackTraits<DT>::unpack( *data, &(imports_[0]), (max_all*importCnt), pos );
424  oData.push_back( data );
425  }
426 #else
427  //Just Copy Data
428  oData = iData;
429 #endif
430 }
431 
432 template <typename DT>
433 void
435 rvs( std::vector<int> const & pList,
436  std::vector< Teuchos::RCP<DT> > const & iData,
437  std::vector< Teuchos::RCP<DT> > & oData )
438 {
439 #ifdef EPETRA_MPI
440  Epetra_MpiDistributor distributor( dynamic_cast<Epetra_MpiComm&>(comm_) );
441 
442  int importCnt = pList.size();
443  int exportCnt;
444 
445  distributor.CreateFromSends( importCnt, &(pList[0]), true, exportCnt );
446 
447  if( exportCnt != keys.size() )
448  N_ERH_ErrorMgr::report( N_ERH_ErrorMgr::DEV_FATAL,
449  "Xyce::Parallel::Migrate::rvs Failed Size Match!\n" );
450 
451  int max_size = 0;
452  DataContainerCIter citDC = iData.begin();
453  DataContainerCIter cendDC = iData.end();
454  for( ; citDC != cendDC; ++citDC )
455  max_size = std::max( max_size, PackTraits<DT>::size( **citDC ) );
456 
457  int max_all;
458  comm_.MaxAll( &max_size, &max_all, 1 );
459 
460  exports_.resize( max_all * exportCnt );
461 
462  if( importSize_ < (max_all*importCnt) )
463  {
464  if( importSize_ ) delete [] imports_;
465  importSize_ = (max_all*importCnt);
466  imports_ = new char[importSize_];
467  }
468 
469  int i = 0;
470  int pos = 0;
471  citDC = iData.begin();
472  for( ; citDC != cendDC; ++citDC, ++i )
473  {
474  pos = max_all * i;
475  PackTraits<DT>::pack( **citDC, &(exports_[0]), (max_all*exportCnt ), pos );
476  }
477 
478  distributor.DoReverse( &(exports_[0]), max_all, importSize_, imports_ );
479 
480  oData.clear();
481  for( int i = 0; i < importCnt; ++i )
482  {
483  pos = max_all * i;
484  Teuchos::RCP<DT> data = rcp( new DT );
485  PackTraits<DT>::unpack( *data, &(imports_[0]), (max_all*importCnt), pos );
486  oData.push_back( data );
487  }
488 #else
489  oData = iData;
490 #endif
491 }
492 
493 } //namespace EpetraExt
494 
495 #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