EpetraExt Development
EpetraExt_Migrate.h
Go to the documentation of this file.
00001 // @HEADER
00002 // ***********************************************************************
00003 //
00004 //     EpetraExt: Epetra Extended - Linear Algebra Services Package
00005 //                 Copyright (2001) Sandia Corporation
00006 //
00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00008 // license for use of this work by or on behalf of the U.S. Government.
00009 //
00010 // This library is free software; you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as
00012 // published by the Free Software Foundation; either version 2.1 of the
00013 // License, or (at your option) any later version.
00014 //
00015 // This library is distributed in the hope that it will be useful, but
00016 // WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 // Lesser General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU Lesser General Public
00021 // License along with this library; if not, write to the Free Software
00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00023 // USA
00024 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
00025 //
00026 // ***********************************************************************
00027 // @HEADER
00028 #ifndef EPETRAEXT_MIGRATE_H
00029 #define EPETRAEXT_MIGRATE_H
00030 
00031 // ---------- Includes ----------
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   // Constructor
00072   Migrate( Epetra_Comm & comm )
00073   : comm_(comm),
00074     imports_(0),
00075     importSize_(0)
00076   {}
00077 
00078   // Destructor
00079   ~Migrate()
00080   { if( importSize_ ) delete [] imports_; }
00081 
00082  private:
00083 
00084   // No public copy construction, assignment, or equality operators.
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   // Constructor
00132   Migrate1( Epetra_Comm & comm )
00133   : comm_(comm),
00134     imports_(0),
00135     importSize_(0)
00136   {}
00137 
00138   // Destructor
00139   ~Migrate1()
00140   { if( importSize_ ) delete [] imports_; }
00141 
00142  private:
00143 
00144   // No public copy construction, assignment, or equality operators.
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   //Just Copy Data
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   //Just Copy Data
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   //Just Copy Data
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 } //namespace EpetraExt
00475 
00476 #endif 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines