Tpetra_DistObject.hpp

00001 // @HEADER
00002 // ***********************************************************************
00003 // 
00004 //          Tpetra: Templated Linear Algebra Services Package
00005 //                 Copyright (2004) 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 
00029 #ifndef TPETRA_DISTOBJECT_HPP
00030 #define TPETRA_DISTOBJECT_HPP
00031 
00032 #include "Tpetra_ConfigDefs.hpp"
00033 #include "Tpetra_Map.hpp"
00034 #include "Tpetra_CombineMode.hpp"
00035 #include "Tpetra_Import.hpp"
00036 #include "Tpetra_Export.hpp"
00037 #include "Tpetra_Distributor.hpp"
00038 
00039 #include <Teuchos_OrdinalTraits.hpp>
00040 #include <Teuchos_RCP.hpp>
00041 #include <Teuchos_Comm.hpp>
00042 
00043 namespace Tpetra {
00044 
00046 
00066   template<typename Ordinal, typename Scalar>
00067   class DistObject : public Teuchos::Object {
00068 
00069   public:
00070 
00072 
00073 
00075     DistObject(const Map<Ordinal>& map, Teuchos::RCP<const Teuchos::Comm<Ordinal> > comm);
00076 
00078     DistObject(const Map<Ordinal>& map, 
00079            Teuchos::RCP<const Teuchos::Comm<Ordinal> > comm,
00080            const std::string & Label);
00081 
00083     DistObject(const DistObject<Ordinal, Scalar>& source);
00084 
00086     virtual ~DistObject();
00087 
00089 
00091 
00092 
00094     void doImport(const DistObject<Ordinal, Scalar> & source, 
00095                   const Import<Ordinal> & importer, CombineMode CM);
00096 
00098     void doExport(const DistObject<Ordinal, Scalar> & dest, 
00099                   const Export<Ordinal> & exporter, CombineMode CM);
00100 
00102     void doImport(const DistObject<Ordinal, Scalar> & source,
00103                   const Export<Ordinal> & exporter, CombineMode CM);
00104 
00106     void doExport(const DistObject<Ordinal, Scalar> & dest,
00107                   const Import<Ordinal> & importer, CombineMode CM);
00108 
00110 
00112 
00113 
00115     inline bool isDistributed() const;
00116 
00118     inline const Map<Ordinal> & getMap() const;
00119 
00121 
00123 
00124 
00126 
00127     void print(std::ostream &os) const;
00128 
00130 
00131   protected:
00132 
00134     virtual void doTransfer(const DistObject<Ordinal,Scalar> &source,
00135                             CombineMode CM,
00136                             Ordinal numSameIDs,
00137                             const Teuchos::ArrayView<const Ordinal> &permuteToLIDs,
00138                             const Teuchos::ArrayView<const Ordinal> &permuteFromLIDs,
00139                             const Teuchos::ArrayView<const Ordinal> &remoteLIDs,
00140                             const Teuchos::ArrayView<const Ordinal> &exportLIDs,
00141                             Distributor<Ordinal> &distor,
00142                             bool doReverse);
00143 
00144     // The following four methods must be implemented by the derived class
00145 
00147 
00148     virtual bool checkSizes(const DistObject<Ordinal, Scalar> & source, Ordinal &packetSize) = 0;
00149 
00151 
00167     virtual void copyAndPermute(const DistObject<Ordinal, Scalar> & source,
00168                                       Ordinal numSameIDs,
00169                                 const Teuchos::ArrayView<const Ordinal> &permuteToLIDs,
00170                                 const Teuchos::ArrayView<const Ordinal> &permuteFromLIDs) = 0;
00171 
00173 
00184     virtual void packAndPrepare(const DistObject<Ordinal,Scalar> & source,
00185                                 const Teuchos::ArrayView<const Ordinal> &exportLIDs,
00186                                 const Teuchos::ArrayView<Scalar> &exports,
00187                                 Distributor<Ordinal> &distor) = 0;
00188 
00190 
00201     virtual void unpackAndCombine(const Teuchos::ArrayView<const Ordinal> &importLIDs,
00202                                   const Teuchos::ArrayView<const Scalar> &imports,
00203                                   Distributor<Ordinal> &distor,
00204                                   CombineMode CM) = 0;
00205 
00206   private:
00207 
00208     const Map<Ordinal> map_;
00209     Teuchos::RCP<const Teuchos::Comm<Ordinal> > Comm_;
00210     // buffers into which packed data is imported
00211     Teuchos::Array<Scalar> imports_;
00212     // buffers from which packed data is exported
00213     Teuchos::Array<Scalar> exports_;
00214 
00215   }; // class DistObject
00216 
00217   template <typename Ordinal, typename Scalar>
00218   DistObject<Ordinal,Scalar>::DistObject(const Map<Ordinal>& map, Teuchos::RCP<const Teuchos::Comm<Ordinal> > comm)
00219   : Teuchos::Object("Tpetra::DistObject")
00220   , map_(map)
00221   , Comm_(comm)
00222   {}
00223 
00224   template <typename Ordinal, typename Scalar>
00225   DistObject<Ordinal,Scalar>::DistObject(const Map<Ordinal>& map, 
00226       Teuchos::RCP<const Teuchos::Comm<Ordinal> > comm, const std::string & Label)
00227   : Teuchos::Object(Label.c_str())
00228   , map_(map)
00229   , Comm_(comm)
00230   {}
00231 
00232   template <typename Ordinal, typename Scalar>
00233   DistObject<Ordinal,Scalar>::DistObject(const DistObject<Ordinal, Scalar>& source)
00234   : Teuchos::Object(source.label())
00235   , map_(source.map_)
00236   , Comm_(source.Comm_)
00237   {}
00238 
00239   template <typename Ordinal, typename Scalar>
00240   DistObject<Ordinal,Scalar>::~DistObject() 
00241   {}
00242 
00243   template <typename Ordinal, typename Scalar>
00244   void DistObject<Ordinal,Scalar>::doImport(const DistObject<Ordinal,Scalar> & source, 
00245                                             const Import<Ordinal> & importer, CombineMode CM) 
00246   {
00247     TEST_FOR_EXCEPTION( getMap() != importer.getTargetMap(), std::runtime_error, "Target Maps don't match.");
00248     TEST_FOR_EXCEPTION( source.getMap() != importer.getSourceMap(), std::runtime_error, "Source Maps don't match.");
00249     Ordinal numSameIDs = importer.getNumSameIDs();
00250     const Teuchos::ArrayView<const Ordinal> exportLIDs      = importer.getExportLIDs();
00251     const Teuchos::ArrayView<const Ordinal> remoteLIDs      = importer.getRemoteLIDs();
00252     const Teuchos::ArrayView<const Ordinal> permuteToLIDs   = importer.getPermuteToLIDs();
00253     const Teuchos::ArrayView<const Ordinal> permuteFromLIDs = importer.getPermuteFromLIDs();
00254     this->doTransfer(source, CM, numSameIDs, permuteToLIDs, permuteFromLIDs, remoteLIDs, exportLIDs,
00255                      importer.getDistributor(), false);
00256   }
00257 
00258   template <typename Ordinal, typename Scalar>
00259   void DistObject<Ordinal,Scalar>::doExport(const DistObject<Ordinal,Scalar> & dest, 
00260                                             const Export<Ordinal> & exporter, CombineMode CM) 
00261   {
00262     TEST_FOR_EXCEPTION( getMap() != exporter.getTargetMap(), std::runtime_error, "Target Maps don't match.");
00263     TEST_FOR_EXCEPTION( dest.getMap() != exporter.getSourceMap(), std::runtime_error, "Source Maps don't match.");
00264     Ordinal numSameIDs = exporter.getNumSameIDs();
00265     Teuchos::ArrayView<const Ordinal> exportLIDs      = exporter.getExportLIDs();
00266     Teuchos::ArrayView<const Ordinal> remoteLIDs      = exporter.getRemoteLIDs();
00267     Teuchos::ArrayView<const Ordinal> permuteToLIDs   = exporter.getPermuteToLIDs();
00268     Teuchos::ArrayView<const Ordinal> permuteFromLIDs = exporter.getPermuteFromLIDs();
00269     doTransfer(dest, CM, numSameIDs, permuteToLIDs, permuteFromLIDs, remoteLIDs, exportLIDs,
00270                exporter.getDistributor(), false);
00271   }
00272 
00273   template <typename Ordinal, typename Scalar>
00274   void DistObject<Ordinal,Scalar>::doImport(const DistObject<Ordinal,Scalar> & source,
00275                                             const Export<Ordinal> & exporter, CombineMode CM)
00276   {
00277     TEST_FOR_EXCEPTION( getMap() != exporter.getTargetMap(), std::runtime_error, "Target Maps don't match.");
00278     TEST_FOR_EXCEPTION( source.getMap() != exporter.getSourceMap(), std::runtime_error, "Source Maps don't match.");
00279     Ordinal numSameIDs = exporter.getNumSameIDs();
00280     Teuchos::ArrayView<const Ordinal> exportLIDs      = exporter.getRemoteLIDs();
00281     Teuchos::ArrayView<const Ordinal> remoteLIDs      = exporter.getExportLIDs();
00282     Teuchos::ArrayView<const Ordinal> permuteToLIDs   = exporter.getPermuteFromLIDs();
00283     Teuchos::ArrayView<const Ordinal> permuteFromLIDs = exporter.getPermuteToLIDs();
00284     doTransfer(source, CM, numSameIDs, permuteToLIDs, permuteFromLIDs, remoteLIDs, exportLIDs,
00285                exporter.getDistributor(), true);
00286   }
00287 
00288   template <typename Ordinal, typename Scalar>
00289   void DistObject<Ordinal,Scalar>::doExport(const DistObject<Ordinal, Scalar> & dest,
00290                                             const Import<Ordinal> & importer, CombineMode CM)
00291   {
00292     TEST_FOR_EXCEPTION( getMap() != importer.getTargetMap(), std::runtime_error, "Target Maps don't match.");
00293     TEST_FOR_EXCEPTION( dest.getMap() != importer.getSourceMap(), std::runtime_error, "Source Maps don't match.");
00294     Ordinal numSameIDs = importer.getNumSameIDs();
00295     Teuchos::ArrayView<const Ordinal> exportLIDs      = importer.getRemoteLIDs();
00296     Teuchos::ArrayView<const Ordinal> remoteLIDs      = importer.getExportLIDs();
00297     Teuchos::ArrayView<const Ordinal> permuteToLIDs   = importer.getPermuteFromLIDs();
00298     Teuchos::ArrayView<const Ordinal> permuteFromLIDs = importer.getPermuteToLIDs();
00299     doTransfer(dest, CM, numSameIDs, permuteToLIDs, permuteFromLIDs, remoteLIDs, exportLIDs,
00300                importer.getDistributor(), true);
00301   }
00302 
00303   template <typename Ordinal, typename Scalar>
00304   bool DistObject<Ordinal,Scalar>::isDistributed() const 
00305   {
00306     return map_.isDistributed();
00307   }
00308 
00309   template <typename Ordinal, typename Scalar>
00310   const Map<Ordinal> & DistObject<Ordinal,Scalar>::getMap() const 
00311   {
00312     return map_;
00313   }
00314 
00315   template <typename Ordinal, typename Scalar>
00316   void DistObject<Ordinal,Scalar>::doTransfer(
00317       const DistObject<Ordinal, Scalar> & source,
00318       CombineMode CM,
00319       Ordinal numSameIDs, 
00320       const Teuchos::ArrayView<const Ordinal> &permuteToLIDs, 
00321       const Teuchos::ArrayView<const Ordinal> &permuteFromLIDs,
00322       const Teuchos::ArrayView<const Ordinal> &remoteLIDs,    
00323       const Teuchos::ArrayView<const Ordinal> &exportLIDs,
00324       Distributor<Ordinal> &distor, bool doReverse) 
00325   {
00326     Ordinal packetSize;
00327     TEST_FOR_EXCEPTION( checkSizes(source,packetSize) == false, std::runtime_error, 
00328         "Tpetra::DistObject::doTransfer(): checkSizes() indicates that DistOjbects are not size-compatible.");
00329     Ordinal sbufLen = exportLIDs.size()*packetSize;
00330     Ordinal rbufLen = remoteLIDs.size()*packetSize;
00331     exports_.resize(sbufLen);
00332     imports_.resize(rbufLen);
00333     if (numSameIDs + permuteToLIDs.size()) {
00334       copyAndPermute(source,numSameIDs,permuteToLIDs,permuteFromLIDs);
00335     }
00336     packAndPrepare(source,exportLIDs,exports_(),distor);
00337     if ((isDistributed() && doReverse) || (source.isDistributed() && !doReverse)) 
00338     {
00339       // call one of the doPostsAndWaits functions
00340       if (doReverse) {
00341         distor.doReversePostsAndWaits(exports_().getConst(),packetSize,imports_());
00342       }
00343       else {
00344         distor.doPostsAndWaits(exports_().getConst(),packetSize,imports_());
00345       }
00346       unpackAndCombine(remoteLIDs,imports_(),distor,CM);
00347     }
00348   }
00349 
00350   template <typename Ordinal, typename Scalar>
00351   void DistObject<Ordinal,Scalar>::print(std::ostream &os) const
00352   {
00353     using std::endl;
00354     os << "Tpetra::DistObject" << endl
00355        << " export buffer size: " << exports_.size() << endl
00356        << " import buffer size: " << imports_.size() << endl
00357        << "Map:" << endl
00358        << map_;
00359   }
00360 
00361 } // namespace Tpetra
00362 
00363 #endif /* TPETRA_DISTOBJECT_HPP */

Generated on Wed May 12 21:59:41 2010 for Tpetra Matrix/Vector Services by  doxygen 1.4.7