00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef EPETRAEXT_MIGRATE_H
00029 #define EPETRAEXT_MIGRATE_H
00030
00031
00032
00033 #include <string>
00034 #include <vector>
00035 #include <map>
00036
00037 #include <Teuchos_RefCountPtr.hpp>
00038
00039 #include <EpetraExt_PackTraits.h>
00040
00041 #ifdef EPETRA_MPI
00042 #include <Epetra_MpiComm.h>
00043 #include <Epetra_MpiDistributor.h>
00044 #endif
00045
00046 namespace EpetraExt {
00047
00049
00051 template <typename KT, typename DT>
00052 class Migrate
00053 {
00054 public:
00055
00056 typedef typename std::map< KT, Teuchos::RefCountPtr<DT> > DataMap;
00057 typedef typename DataMap::iterator DataMapIter;
00058 typedef typename DataMap::const_iterator DataMapCIter;
00059
00060 typedef typename DataMap::value_type DataPair;
00061
00062 typedef typename std::vector<KT> KeyList;
00063 typedef typename KeyList::iterator KeyListIter;
00064 typedef typename KeyList::const_iterator KeyListCIter;
00065
00066 typedef typename std::vector<int> ProcList;
00067 typedef typename ProcList::iterator ProcListIter;
00068
00069 typedef typename std::vector<char> Buffer;
00070
00071
00072 Migrate( Epetra_Comm & comm )
00073 : comm_(comm),
00074 imports_(0),
00075 importSize_(0)
00076 {}
00077
00078
00079 ~Migrate()
00080 { if( importSize_ ) delete [] imports_; }
00081
00082 private:
00083
00084
00085 Migrate();
00086
00087 bool operator==( Migrate const & right ) const;
00088 bool operator!=( Migrate const & right ) const;
00089
00090 public:
00091
00092 void operator()( std::vector<int> const & pList,
00093 std::vector<KT> const & iKeys,
00094 std::vector<KT> & oKeys );
00095
00096 void operator()( std::vector<int> const & pList,
00097 std::map< KT, Teuchos::RefCountPtr<DT> > const & iData,
00098 std::multimap< KT, Teuchos::RefCountPtr<DT> > & oData );
00099
00100 void rvs( std::vector<int> const & pList,
00101 std::vector<KT> const & keys,
00102 std::map< KT, Teuchos::RefCountPtr<DT> > & iData,
00103 std::map< KT, Teuchos::RefCountPtr<DT> > & oData );
00104
00105 protected:
00106
00107 Epetra_Comm & comm_;
00108
00109 char * imports_;
00110 int importSize_;
00111
00112 Buffer exports_;
00113
00114 };
00115
00116 template <typename DT>
00117 class Migrate1
00118 {
00119 public:
00120
00121 typedef typename Teuchos::RefCountPtr<DT> DataPtr;
00122 typedef typename std::vector<DataPtr> DataContainer;
00123 typedef typename DataContainer::iterator DataContainerIter;
00124 typedef typename DataContainer::const_iterator DataContainerCIter;
00125
00126 typedef typename std::vector<int> ProcList;
00127 typedef typename ProcList::iterator ProcListIter;
00128
00129 typedef typename std::vector<char> Buffer;
00130
00131
00132 Migrate1( Epetra_Comm & comm )
00133 : comm_(comm),
00134 imports_(0),
00135 importSize_(0)
00136 {}
00137
00138
00139 ~Migrate1()
00140 { if( importSize_ ) delete [] imports_; }
00141
00142 private:
00143
00144
00145 Migrate1();
00146
00147 bool operator==( Migrate1 const & right ) const;
00148 bool operator!=( Migrate1 const & right ) const;
00149
00150 public:
00151
00152 void operator()( std::vector<int> const & pList,
00153 std::vector< Teuchos::RefCountPtr<DT> > const & iData,
00154 std::vector< Teuchos::RefCountPtr<DT> > & oData );
00155
00156 void rvs( std::vector<int> const & pList,
00157 std::vector< Teuchos::RefCountPtr<DT> > const & iData,
00158 std::vector< Teuchos::RefCountPtr<DT> > & oData );
00159
00160 protected:
00161
00162 Epetra_Comm & comm_;
00163
00164 char * imports_;
00165 int importSize_;
00166
00167 Buffer exports_;
00168
00169 };
00170
00171 template <typename KT, typename DT>
00172 void
00173 Migrate<KT,DT>::
00174 operator()( std::vector<int> const & pList,
00175 std::vector<KT> const & iKeys,
00176 std::vector<KT> & oKeys )
00177 {
00178 #ifdef EPETRA_MPI
00179 Epetra_MpiDistributor distributor( dynamic_cast<Epetra_MpiComm&>(comm_) );
00180
00181 int exportCnt = pList.size();
00182
00183 int max_size = 0;
00184 KeyListCIter citKL = iKeys.begin();
00185 KeyListCIter cendKL = iKeys.end();
00186 for( ; citKL != cendKL; ++citKL )
00187 max_size = std::max( max_size, static_cast<int>(PackTraits<KT>::size( *citKL )) );
00188
00189 int importCnt;
00190 distributor.CreateFromSends( exportCnt, &(pList[0]), true, importCnt );
00191
00192 int max_all;
00193 comm_.MaxAll( &max_size, &max_all, 1 );
00194
00195 exports_.resize( max_all * exportCnt );
00196
00197 if( importSize_ < (max_all*importCnt) )
00198 {
00199 if( importSize_ ) delete [] imports_;
00200 importSize_ = (max_all*importCnt);
00201 imports_ = new char[importSize_];
00202 }
00203
00204 int pos = 0;
00205 citKL = iKeys.begin();
00206 for( int i = 0; citKL != cendKL; ++citKL, ++i )
00207 {
00208 pos = max_all * i;
00209 PackTraits<KT>::pack( *citKL, &(exports_[0]), (max_all*exportCnt ), pos );
00210 }
00211
00212 distributor.Do( &(exports_[0]), max_all, importSize_, imports_ );
00213
00214 oKeys.resize( importCnt );
00215 for( int i = 0; i < importCnt; ++i )
00216 {
00217 pos = max_all * i;
00218 PackTraits<KT>::unpack( oKeys[i], &(imports_[0]), (max_all*importCnt), pos );
00219 }
00220 #else
00221
00222 oKeys = iKeys;
00223 #endif
00224 }
00225
00226 template <typename KT, typename DT>
00227 void
00228 Migrate<KT,DT>::
00229 operator()( std::vector<int> const & pList,
00230 std::map< KT, Teuchos::RefCountPtr<DT> > const & iData,
00231 std::multimap< KT, Teuchos::RefCountPtr<DT> > & oData )
00232 {
00233 #ifdef EPETRA_MPI
00234 Epetra_MpiDistributor distributor( dynamic_cast<Epetra_MpiComm&>(comm_) );
00235
00236 int exportCnt = pList.size();
00237
00238 int max_size = 0;
00239 DataMapCIter citDM = iData.begin();
00240 DataMapCIter cendDM = iData.end();
00241 for( ; citDM != cendDM; ++citDM )
00242 max_size = std::max( max_size, static_cast<int>(PackTraits<KT>::size( citDM->first ))
00243 + static_cast<int>(PackTraits<DT>::size( *(citDM->second) )) );
00244
00245 int importCnt;
00246 distributor.CreateFromSends( exportCnt, &(pList[0]), true, importCnt );
00247
00248 int max_all;
00249 comm_.MaxAll( &max_size, &max_all, 1 );
00250
00251 exports_.resize( max_all * exportCnt );
00252
00253 if( importSize_ < (max_all*importCnt) )
00254 {
00255 if( importSize_ ) delete [] imports_;
00256 importSize_ = (max_all*importCnt);
00257 imports_ = new char[importSize_];
00258 }
00259
00260 int pos = 0;
00261 citDM = iData.begin();
00262 for( int i = 0; citDM != cendDM; ++citDM, ++i )
00263 {
00264 pos = max_all * i;
00265 PackTraits<KT>::pack( citDM->first, &(exports_[0]), (max_all*exportCnt ), pos );
00266 PackTraits<DT>::pack( *(citDM->second), &(exports_[0]), (max_all*exportCnt ), pos );
00267 }
00268
00269 distributor.Do( &(exports_[0]), max_all, importSize_, imports_ );
00270
00271 oData.clear();
00272 KT key;
00273 for( int i = 0; i < importCnt; ++i )
00274 {
00275 pos = max_all * i;
00276 PackTraits<KT>::unpack( key, &(imports_[0]), (max_all*importCnt), pos );
00277 Teuchos::RefCountPtr<DT> data = rcp( new DT );
00278 PackTraits<DT>::unpack( *data, &(imports_[0]), (max_all*importCnt), pos );
00279 oData.insert( DataPair( key, data ) );
00280 }
00281 #else
00282
00283 DataMapCIter citDM = iData.begin();
00284 DataMapCIter cendDM = iData.end();
00285 for( ; citDM != cendDM; ++citDM )
00286 oData.insert( *citDM );
00287 #endif
00288 }
00289
00290 template <typename KT, typename DT>
00291 void
00292 Migrate<KT,DT>::
00293 rvs( std::vector<int> const & pList,
00294 std::vector<KT> const & keys,
00295 std::map< KT, Teuchos::RefCountPtr<DT> > & iData,
00296 std::map< KT, Teuchos::RefCountPtr<DT> > & oData )
00297 {
00298 #ifdef EPETRA_MPI
00299 Epetra_MpiDistributor distributor( dynamic_cast<Epetra_MpiComm&>(comm_) );
00300
00301 int importCnt = pList.size();
00302 int exportCnt;
00303
00304 distributor.CreateFromSends( importCnt, &(pList[0]), true, exportCnt );
00305
00306 if( exportCnt != keys.size() )
00307 N_ERH_ErrorMgr::report( N_ERH_ErrorMgr::DEV_FATAL,
00308 "Xyce::Parallel::Migrate::rvs Failed Size Match!\n" );
00309
00310 int max_size = 0;
00311 KeyListCIter citKL = keys.begin();
00312 KeyListCIter cendKL = keys.end();
00313 for( ; citKL != cendKL; ++citKL )
00314 max_size = std::max( max_size, static_cast<int>(PackTraits<KT>::size( *citKL ) )
00315 + static_cast<int>(PackTraits<DT>::size( *(iData[*citKL]) ) ) );
00316
00317 int max_all;
00318 comm_.MaxAll( &max_size, &max_all, 1 );
00319
00320 exports_.resize( max_all * exportCnt );
00321
00322 if( importSize_ < (max_all*importCnt) )
00323 {
00324 if( importSize_ ) delete [] imports_;
00325 importSize_ = (max_all*importCnt);
00326 imports_ = new char[importSize_];
00327 }
00328
00329 int pos = 0;
00330 int i = 0;
00331 citKL = keys.begin();
00332 for( ; citKL != cendKL; ++citKL, ++i )
00333 {
00334 pos = max_all * i;
00335 PackTraits<KT>::pack( *citKL, &(exports_[0]), (max_all*exportCnt ), pos );
00336 PackTraits<DT>::pack( *(iData[*citKL]), &(exports_[0]), (max_all*exportCnt ), pos );
00337 }
00338
00339 distributor.DoReverse( &(exports_[0]), max_all, importSize_, imports_ );
00340
00341 oData.clear();
00342 KT key;
00343 for( int i = 0; i < importCnt; ++i )
00344 {
00345 pos = max_all * i;
00346 PackTraits<KT>::unpack( key, &(imports_[0]), (max_all*importCnt), pos );
00347 Teuchos::RefCountPtr<DT> data = rcp( new DT );
00348 PackTraits<DT>::unpack( *data, &(imports_[0]), (max_all*importCnt), pos );
00349 oData[key] = data;
00350 }
00351 #else
00352 oData = iData;
00353 #endif
00354 }
00355
00356 template <typename DT>
00357 void
00358 Migrate1<DT>::
00359 operator()( std::vector<int> const & pList,
00360 std::vector< Teuchos::RefCountPtr<DT> > const & iData,
00361 std::vector< Teuchos::RefCountPtr<DT> > & oData )
00362 {
00363 #ifdef EPETRA_MPI
00364 Epetra_MpiDistributor distributor( dynamic_cast<Epetra_MpiComm&>(comm_) );
00365
00366 int exportCnt = pList.size();
00367
00368 int max_size = 0;
00369 DataContainerCIter citDC = iData.begin();
00370 DataContainerCIter cendDC = iData.end();
00371 for( ; citDC != cendDC; ++citDC )
00372 max_size = std::max( max_size, static_cast<int>(PackTraits<DT>::size( **citDC )) );
00373
00374 int importCnt;
00375 distributor.CreateFromSends( exportCnt, &(pList[0]), true, importCnt );
00376
00377 int max_all;
00378 comm_.MaxAll( &max_size, &max_all, 1 );
00379
00380 exports_.resize( max_all * exportCnt );
00381
00382 if( importSize_ < (max_all*importCnt) )
00383 {
00384 if( importSize_ ) delete [] imports_;
00385 importSize_ = (max_all*importCnt);
00386 imports_ = new char[importSize_];
00387 }
00388
00389 int pos = 0;
00390 citDC = iData.begin();
00391 for( int i = 0; citDC != cendDC; ++citDC, ++i )
00392 {
00393 pos = max_all * i;
00394 PackTraits<DT>::pack( **citKL, &(exports_[0]), (max_all*exportCnt ), pos );
00395 }
00396
00397 distributor.Do( &(exports_[0]), max_all, importSize_, imports_ );
00398
00399 oData.clear();
00400 for( int i = 0; i < importCnt; ++i )
00401 {
00402 pos = max_all * i;
00403 Teuchos::RefCountPtr<DT> data = rcp( new DT );
00404 PackTraits<DT>::unpack( *data, &(imports_[0]), (max_all*importCnt), pos );
00405 oData.push_back( data );
00406 }
00407 #else
00408
00409 oData = iData;
00410 #endif
00411 }
00412
00413 template <typename DT>
00414 void
00415 Migrate1<DT>::
00416 rvs( std::vector<int> const & pList,
00417 std::vector< Teuchos::RefCountPtr<DT> > const & iData,
00418 std::vector< Teuchos::RefCountPtr<DT> > & oData )
00419 {
00420 #ifdef EPETRA_MPI
00421 Epetra_MpiDistributor distributor( dynamic_cast<Epetra_MpiComm&>(comm_) );
00422
00423 int importCnt = pList.size();
00424 int exportCnt;
00425
00426 distributor.CreateFromSends( importCnt, &(pList[0]), true, exportCnt );
00427
00428 if( exportCnt != keys.size() )
00429 N_ERH_ErrorMgr::report( N_ERH_ErrorMgr::DEV_FATAL,
00430 "Xyce::Parallel::Migrate::rvs Failed Size Match!\n" );
00431
00432 int max_size = 0;
00433 DataContainerCIter citDC = iData.begin();
00434 DataContainerCIter cendDC = iData.end();
00435 for( ; citDC != cendDC; ++citDC )
00436 max_size = std::max( max_size, PackTraits<DT>::size( **citDC ) );
00437
00438 int max_all;
00439 comm_.MaxAll( &max_size, &max_all, 1 );
00440
00441 exports_.resize( max_all * exportCnt );
00442
00443 if( importSize_ < (max_all*importCnt) )
00444 {
00445 if( importSize_ ) delete [] imports_;
00446 importSize_ = (max_all*importCnt);
00447 imports_ = new char[importSize_];
00448 }
00449
00450 int i = 0;
00451 int pos = 0;
00452 citDC = iData.begin();
00453 for( ; citDC != cendDC; ++citDC, ++i )
00454 {
00455 pos = max_all * i;
00456 PackTraits<DT>::pack( **citDC, &(exports_[0]), (max_all*exportCnt ), pos );
00457 }
00458
00459 distributor.DoReverse( &(exports_[0]), max_all, importSize_, imports_ );
00460
00461 oData.clear();
00462 for( int i = 0; i < importCnt; ++i )
00463 {
00464 pos = max_all * i;
00465 Teuchos::RefCountPtr<DT> data = rcp( new DT );
00466 PackTraits<DT>::unpack( *data, &(imports_[0]), (max_all*importCnt), pos );
00467 oData.push_back( data );
00468 }
00469 #else
00470 oData = iData;
00471 #endif
00472 }
00473
00474 }
00475
00476 #endif