EpetraExt Package Browser (Single Doxygen Collection) 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 (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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines