|
EpetraExt Development
|
00001 //@HEADER 00002 // *********************************************************************** 00003 // 00004 // EpetraExt: Epetra Extended - Linear Algebra Services Package 00005 // Copyright (2011) Sandia Corporation 00006 // 00007 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, 00008 // the U.S. Government retains certain rights in this software. 00009 // 00010 // Redistribution and use in source and binary forms, with or without 00011 // modification, are permitted provided that the following conditions are 00012 // met: 00013 // 00014 // 1. Redistributions of source code must retain the above copyright 00015 // notice, this list of conditions and the following disclaimer. 00016 // 00017 // 2. Redistributions in binary form must reproduce the above copyright 00018 // notice, this list of conditions and the following disclaimer in the 00019 // documentation and/or other materials provided with the distribution. 00020 // 00021 // 3. Neither the name of the Corporation nor the names of the 00022 // contributors may be used to endorse or promote products derived from 00023 // this software without specific prior written permission. 00024 // 00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY 00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE 00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00036 // 00037 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 00038 // 00039 // *********************************************************************** 00040 //@HEADER 00041 #ifndef EPETRAEXT_MIGRATE_H 00042 #define EPETRAEXT_MIGRATE_H 00043 00044 // ---------- Includes ---------- 00045 00046 #include <string> 00047 #include <vector> 00048 #include <map> 00049 00050 #include <Teuchos_RefCountPtr.hpp> 00051 00052 #include <EpetraExt_PackTraits.h> 00053 00054 #ifdef EPETRA_MPI 00055 #include <Epetra_MpiComm.h> 00056 #include <Epetra_MpiDistributor.h> 00057 #endif 00058 00059 namespace EpetraExt { 00060 00062 00064 template <typename KT, typename DT> 00065 class Migrate 00066 { 00067 public: 00068 00069 typedef typename std::map< KT, Teuchos::RefCountPtr<DT> > DataMap; 00070 typedef typename DataMap::iterator DataMapIter; 00071 typedef typename DataMap::const_iterator DataMapCIter; 00072 00073 typedef typename DataMap::value_type DataPair; 00074 00075 typedef typename std::vector<KT> KeyList; 00076 typedef typename KeyList::iterator KeyListIter; 00077 typedef typename KeyList::const_iterator KeyListCIter; 00078 00079 typedef typename std::vector<int> ProcList; 00080 typedef typename ProcList::iterator ProcListIter; 00081 00082 typedef typename std::vector<char> Buffer; 00083 00084 // Constructor 00085 Migrate( Epetra_Comm & comm ) 00086 : comm_(comm), 00087 imports_(0), 00088 importSize_(0) 00089 {} 00090 00091 // Destructor 00092 ~Migrate() 00093 { if( importSize_ ) delete [] imports_; } 00094 00095 private: 00096 00097 // No public copy construction, assignment, or equality operators. 00098 Migrate(); 00099 00100 bool operator==( Migrate const & right ) const; 00101 bool operator!=( Migrate const & right ) const; 00102 00103 public: 00104 00105 void operator()( std::vector<int> const & pList, 00106 std::vector<KT> const & iKeys, 00107 std::vector<KT> & oKeys ); 00108 00109 void operator()( std::vector<int> const & pList, 00110 std::map< KT, Teuchos::RefCountPtr<DT> > const & iData, 00111 std::multimap< KT, Teuchos::RefCountPtr<DT> > & oData ); 00112 00113 void rvs( std::vector<int> const & pList, 00114 std::vector<KT> const & keys, 00115 std::map< KT, Teuchos::RefCountPtr<DT> > & iData, 00116 std::map< KT, Teuchos::RefCountPtr<DT> > & oData ); 00117 00118 protected: 00119 00120 Epetra_Comm & comm_; 00121 00122 char * imports_; 00123 int importSize_; 00124 00125 Buffer exports_; 00126 00127 }; 00128 00129 template <typename DT> 00130 class Migrate1 00131 { 00132 public: 00133 00134 typedef typename Teuchos::RefCountPtr<DT> DataPtr; 00135 typedef typename std::vector<DataPtr> DataContainer; 00136 typedef typename DataContainer::iterator DataContainerIter; 00137 typedef typename DataContainer::const_iterator DataContainerCIter; 00138 00139 typedef typename std::vector<int> ProcList; 00140 typedef typename ProcList::iterator ProcListIter; 00141 00142 typedef typename std::vector<char> Buffer; 00143 00144 // Constructor 00145 Migrate1( Epetra_Comm & comm ) 00146 : comm_(comm), 00147 imports_(0), 00148 importSize_(0) 00149 {} 00150 00151 // Destructor 00152 ~Migrate1() 00153 { if( importSize_ ) delete [] imports_; } 00154 00155 private: 00156 00157 // No public copy construction, assignment, or equality operators. 00158 Migrate1(); 00159 00160 bool operator==( Migrate1 const & right ) const; 00161 bool operator!=( Migrate1 const & right ) const; 00162 00163 public: 00164 00165 void operator()( std::vector<int> const & pList, 00166 std::vector< Teuchos::RefCountPtr<DT> > const & iData, 00167 std::vector< Teuchos::RefCountPtr<DT> > & oData ); 00168 00169 void rvs( std::vector<int> const & pList, 00170 std::vector< Teuchos::RefCountPtr<DT> > const & iData, 00171 std::vector< Teuchos::RefCountPtr<DT> > & oData ); 00172 00173 protected: 00174 00175 Epetra_Comm & comm_; 00176 00177 char * imports_; 00178 int importSize_; 00179 00180 Buffer exports_; 00181 00182 }; 00183 00184 template <typename KT, typename DT> 00185 void 00186 Migrate<KT,DT>:: 00187 operator()( std::vector<int> const & pList, 00188 std::vector<KT> const & iKeys, 00189 std::vector<KT> & oKeys ) 00190 { 00191 #ifdef EPETRA_MPI 00192 Epetra_MpiDistributor distributor( dynamic_cast<Epetra_MpiComm&>(comm_) ); 00193 00194 int exportCnt = pList.size(); 00195 00196 int max_size = 0; 00197 KeyListCIter citKL = iKeys.begin(); 00198 KeyListCIter cendKL = iKeys.end(); 00199 for( ; citKL != cendKL; ++citKL ) 00200 max_size = std::max( max_size, static_cast<int>(PackTraits<KT>::size( *citKL )) ); 00201 00202 int importCnt; 00203 distributor.CreateFromSends( exportCnt, &(pList[0]), true, importCnt ); 00204 00205 int max_all; 00206 comm_.MaxAll( &max_size, &max_all, 1 ); 00207 00208 exports_.resize( max_all * exportCnt ); 00209 00210 if( importSize_ < (max_all*importCnt) ) 00211 { 00212 if( importSize_ ) delete [] imports_; 00213 importSize_ = (max_all*importCnt); 00214 imports_ = new char[importSize_]; 00215 } 00216 00217 int pos = 0; 00218 citKL = iKeys.begin(); 00219 for( int i = 0; citKL != cendKL; ++citKL, ++i ) 00220 { 00221 pos = max_all * i; 00222 PackTraits<KT>::pack( *citKL, &(exports_[0]), (max_all*exportCnt ), pos ); 00223 } 00224 00225 distributor.Do( &(exports_[0]), max_all, importSize_, imports_ ); 00226 00227 oKeys.resize( importCnt ); 00228 for( int i = 0; i < importCnt; ++i ) 00229 { 00230 pos = max_all * i; 00231 PackTraits<KT>::unpack( oKeys[i], &(imports_[0]), (max_all*importCnt), pos ); 00232 } 00233 #else 00234 //Just Copy Data 00235 oKeys = iKeys; 00236 #endif 00237 } 00238 00239 template <typename KT, typename DT> 00240 void 00241 Migrate<KT,DT>:: 00242 operator()( std::vector<int> const & pList, 00243 std::map< KT, Teuchos::RefCountPtr<DT> > const & iData, 00244 std::multimap< KT, Teuchos::RefCountPtr<DT> > & oData ) 00245 { 00246 #ifdef EPETRA_MPI 00247 Epetra_MpiDistributor distributor( dynamic_cast<Epetra_MpiComm&>(comm_) ); 00248 00249 int exportCnt = pList.size(); 00250 00251 int max_size = 0; 00252 DataMapCIter citDM = iData.begin(); 00253 DataMapCIter cendDM = iData.end(); 00254 for( ; citDM != cendDM; ++citDM ) 00255 max_size = std::max( max_size, static_cast<int>(PackTraits<KT>::size( citDM->first )) 00256 + static_cast<int>(PackTraits<DT>::size( *(citDM->second) )) ); 00257 00258 int importCnt; 00259 distributor.CreateFromSends( exportCnt, &(pList[0]), true, importCnt ); 00260 00261 int max_all; 00262 comm_.MaxAll( &max_size, &max_all, 1 ); 00263 00264 exports_.resize( max_all * exportCnt ); 00265 00266 if( importSize_ < (max_all*importCnt) ) 00267 { 00268 if( importSize_ ) delete [] imports_; 00269 importSize_ = (max_all*importCnt); 00270 imports_ = new char[importSize_]; 00271 } 00272 00273 int pos = 0; 00274 citDM = iData.begin(); 00275 for( int i = 0; citDM != cendDM; ++citDM, ++i ) 00276 { 00277 pos = max_all * i; 00278 PackTraits<KT>::pack( citDM->first, &(exports_[0]), (max_all*exportCnt ), pos ); 00279 PackTraits<DT>::pack( *(citDM->second), &(exports_[0]), (max_all*exportCnt ), pos ); 00280 } 00281 00282 distributor.Do( &(exports_[0]), max_all, importSize_, imports_ ); 00283 00284 oData.clear(); 00285 KT key; 00286 for( int i = 0; i < importCnt; ++i ) 00287 { 00288 pos = max_all * i; 00289 PackTraits<KT>::unpack( key, &(imports_[0]), (max_all*importCnt), pos ); 00290 Teuchos::RefCountPtr<DT> data = rcp( new DT ); 00291 PackTraits<DT>::unpack( *data, &(imports_[0]), (max_all*importCnt), pos ); 00292 oData.insert( DataPair( key, data ) ); 00293 } 00294 #else 00295 //Just Copy Data 00296 DataMapCIter citDM = iData.begin(); 00297 DataMapCIter cendDM = iData.end(); 00298 for( ; citDM != cendDM; ++citDM ) 00299 oData.insert( *citDM ); 00300 #endif 00301 } 00302 00303 template <typename KT, typename DT> 00304 void 00305 Migrate<KT,DT>:: 00306 rvs( std::vector<int> const & pList, 00307 std::vector<KT> const & keys, 00308 std::map< KT, Teuchos::RefCountPtr<DT> > & iData, 00309 std::map< KT, Teuchos::RefCountPtr<DT> > & oData ) 00310 { 00311 #ifdef EPETRA_MPI 00312 Epetra_MpiDistributor distributor( dynamic_cast<Epetra_MpiComm&>(comm_) ); 00313 00314 int importCnt = pList.size(); 00315 int exportCnt; 00316 00317 distributor.CreateFromSends( importCnt, &(pList[0]), true, exportCnt ); 00318 00319 if( exportCnt != keys.size() ) 00320 N_ERH_ErrorMgr::report( N_ERH_ErrorMgr::DEV_FATAL, 00321 "Xyce::Parallel::Migrate::rvs Failed Size Match!\n" ); 00322 00323 int max_size = 0; 00324 KeyListCIter citKL = keys.begin(); 00325 KeyListCIter cendKL = keys.end(); 00326 for( ; citKL != cendKL; ++citKL ) 00327 max_size = std::max( max_size, static_cast<int>(PackTraits<KT>::size( *citKL ) ) 00328 + static_cast<int>(PackTraits<DT>::size( *(iData[*citKL]) ) ) ); 00329 00330 int max_all; 00331 comm_.MaxAll( &max_size, &max_all, 1 ); 00332 00333 exports_.resize( max_all * exportCnt ); 00334 00335 if( importSize_ < (max_all*importCnt) ) 00336 { 00337 if( importSize_ ) delete [] imports_; 00338 importSize_ = (max_all*importCnt); 00339 imports_ = new char[importSize_]; 00340 } 00341 00342 int pos = 0; 00343 int i = 0; 00344 citKL = keys.begin(); 00345 for( ; citKL != cendKL; ++citKL, ++i ) 00346 { 00347 pos = max_all * i; 00348 PackTraits<KT>::pack( *citKL, &(exports_[0]), (max_all*exportCnt ), pos ); 00349 PackTraits<DT>::pack( *(iData[*citKL]), &(exports_[0]), (max_all*exportCnt ), pos ); 00350 } 00351 00352 distributor.DoReverse( &(exports_[0]), max_all, importSize_, imports_ ); 00353 00354 oData.clear(); 00355 KT key; 00356 for( int i = 0; i < importCnt; ++i ) 00357 { 00358 pos = max_all * i; 00359 PackTraits<KT>::unpack( key, &(imports_[0]), (max_all*importCnt), pos ); 00360 Teuchos::RefCountPtr<DT> data = rcp( new DT ); 00361 PackTraits<DT>::unpack( *data, &(imports_[0]), (max_all*importCnt), pos ); 00362 oData[key] = data; 00363 } 00364 #else 00365 oData = iData; 00366 #endif 00367 } 00368 00369 template <typename DT> 00370 void 00371 Migrate1<DT>:: 00372 operator()( std::vector<int> const & pList, 00373 std::vector< Teuchos::RefCountPtr<DT> > const & iData, 00374 std::vector< Teuchos::RefCountPtr<DT> > & oData ) 00375 { 00376 #ifdef EPETRA_MPI 00377 Epetra_MpiDistributor distributor( dynamic_cast<Epetra_MpiComm&>(comm_) ); 00378 00379 int exportCnt = pList.size(); 00380 00381 int max_size = 0; 00382 DataContainerCIter citDC = iData.begin(); 00383 DataContainerCIter cendDC = iData.end(); 00384 for( ; citDC != cendDC; ++citDC ) 00385 max_size = std::max( max_size, static_cast<int>(PackTraits<DT>::size( **citDC )) ); 00386 00387 int importCnt; 00388 distributor.CreateFromSends( exportCnt, &(pList[0]), true, importCnt ); 00389 00390 int max_all; 00391 comm_.MaxAll( &max_size, &max_all, 1 ); 00392 00393 exports_.resize( max_all * exportCnt ); 00394 00395 if( importSize_ < (max_all*importCnt) ) 00396 { 00397 if( importSize_ ) delete [] imports_; 00398 importSize_ = (max_all*importCnt); 00399 imports_ = new char[importSize_]; 00400 } 00401 00402 int pos = 0; 00403 citDC = iData.begin(); 00404 for( int i = 0; citDC != cendDC; ++citDC, ++i ) 00405 { 00406 pos = max_all * i; 00407 PackTraits<DT>::pack( **citKL, &(exports_[0]), (max_all*exportCnt ), pos ); 00408 } 00409 00410 distributor.Do( &(exports_[0]), max_all, importSize_, imports_ ); 00411 00412 oData.clear(); 00413 for( int i = 0; i < importCnt; ++i ) 00414 { 00415 pos = max_all * i; 00416 Teuchos::RefCountPtr<DT> data = rcp( new DT ); 00417 PackTraits<DT>::unpack( *data, &(imports_[0]), (max_all*importCnt), pos ); 00418 oData.push_back( data ); 00419 } 00420 #else 00421 //Just Copy Data 00422 oData = iData; 00423 #endif 00424 } 00425 00426 template <typename DT> 00427 void 00428 Migrate1<DT>:: 00429 rvs( std::vector<int> const & pList, 00430 std::vector< Teuchos::RefCountPtr<DT> > const & iData, 00431 std::vector< Teuchos::RefCountPtr<DT> > & oData ) 00432 { 00433 #ifdef EPETRA_MPI 00434 Epetra_MpiDistributor distributor( dynamic_cast<Epetra_MpiComm&>(comm_) ); 00435 00436 int importCnt = pList.size(); 00437 int exportCnt; 00438 00439 distributor.CreateFromSends( importCnt, &(pList[0]), true, exportCnt ); 00440 00441 if( exportCnt != keys.size() ) 00442 N_ERH_ErrorMgr::report( N_ERH_ErrorMgr::DEV_FATAL, 00443 "Xyce::Parallel::Migrate::rvs Failed Size Match!\n" ); 00444 00445 int max_size = 0; 00446 DataContainerCIter citDC = iData.begin(); 00447 DataContainerCIter cendDC = iData.end(); 00448 for( ; citDC != cendDC; ++citDC ) 00449 max_size = std::max( max_size, PackTraits<DT>::size( **citDC ) ); 00450 00451 int max_all; 00452 comm_.MaxAll( &max_size, &max_all, 1 ); 00453 00454 exports_.resize( max_all * exportCnt ); 00455 00456 if( importSize_ < (max_all*importCnt) ) 00457 { 00458 if( importSize_ ) delete [] imports_; 00459 importSize_ = (max_all*importCnt); 00460 imports_ = new char[importSize_]; 00461 } 00462 00463 int i = 0; 00464 int pos = 0; 00465 citDC = iData.begin(); 00466 for( ; citDC != cendDC; ++citDC, ++i ) 00467 { 00468 pos = max_all * i; 00469 PackTraits<DT>::pack( **citDC, &(exports_[0]), (max_all*exportCnt ), pos ); 00470 } 00471 00472 distributor.DoReverse( &(exports_[0]), max_all, importSize_, imports_ ); 00473 00474 oData.clear(); 00475 for( int i = 0; i < importCnt; ++i ) 00476 { 00477 pos = max_all * i; 00478 Teuchos::RefCountPtr<DT> data = rcp( new DT ); 00479 PackTraits<DT>::unpack( *data, &(imports_[0]), (max_all*importCnt), pos ); 00480 oData.push_back( data ); 00481 } 00482 #else 00483 oData = iData; 00484 #endif 00485 } 00486 00487 } //namespace EpetraExt 00488 00489 #endif
1.7.4