Tpetra Matrix/Vector Services Version of the Day
Tpetra_Import.hpp
00001 // @HEADER
00002 // ***********************************************************************
00003 // 
00004 //          Tpetra: Templated Linear Algebra Services Package
00005 //                 Copyright (2008) 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 
00042 #ifndef TPETRA_IMPORT_HPP
00043 #define TPETRA_IMPORT_HPP
00044 
00045 #include <Kokkos_DefaultNode.hpp>
00046 #include <Teuchos_Describable.hpp>
00047 #include <Teuchos_as.hpp>
00048 #include "Tpetra_Map.hpp"
00049 #include "Tpetra_Util.hpp"
00050 #include "Tpetra_ImportExportData.hpp"
00051 #include "Tpetra_Distributor.hpp"
00052 #include <iterator>
00053 
00054 namespace Tpetra {
00055 
00087   template <class LocalOrdinal, class GlobalOrdinal = LocalOrdinal, class Node = Kokkos::DefaultNode::DefaultNodeType>
00088   class Import: public Teuchos::Describable {
00089 
00090   public:
00092     typedef Map<LocalOrdinal,GlobalOrdinal,Node> map_type;
00093     
00095 
00096 
00104     Import (const Teuchos::RCP<const map_type>& source, 
00105             const Teuchos::RCP<const map_type>& target);
00106 
00117     Import (const Teuchos::RCP<const map_type>& source,
00118             const Teuchos::RCP<const map_type>& target,
00119             const Teuchos::RCP<Teuchos::ParameterList>& plist);
00120 
00125     Import(const Import<LocalOrdinal,GlobalOrdinal,Node> & import);
00126 
00128     ~Import();
00129 
00131 
00133 
00134 
00139     inline size_t getNumSameIDs() const;
00140 
00147     inline size_t getNumPermuteIDs() const;
00148 
00150     inline ArrayView<const LocalOrdinal> getPermuteFromLIDs() const;
00151 
00153     inline ArrayView<const LocalOrdinal> getPermuteToLIDs() const;
00154 
00156     inline size_t getNumRemoteIDs() const;
00157 
00159     inline ArrayView<const LocalOrdinal> getRemoteLIDs() const;
00160 
00162     inline size_t getNumExportIDs() const;
00163 
00165     inline ArrayView<const LocalOrdinal> getExportLIDs() const;
00166 
00171     inline ArrayView<const int> getExportImageIDs() const;
00172 
00174     inline const RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> >& getSourceMap() const;
00175 
00177     inline const RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> >& getTargetMap() const;
00178 
00180     inline Distributor & getDistributor() const;
00181 
00183     Import<LocalOrdinal,GlobalOrdinal,Node>& 
00184     operator= (const Import<LocalOrdinal,GlobalOrdinal,Node>& Source);
00185 
00187 
00189 
00190 
00192     virtual void print(std::ostream& os) const;
00193 
00195 
00196   private:
00197 
00198     RCP<ImportExportData<LocalOrdinal,GlobalOrdinal,Node> > ImportData_;
00199     RCP<Array<GlobalOrdinal> > remoteGIDs_;
00200 
00202 
00203 
00204     //==============================================================================
00205     // sets up numSameIDs_, numPermuteIDs_, and numRemoteIDs_
00206     // these variables are already initialized to 0 by the ImportExportData ctr.
00207     // also sets up permuteToLIDs_, permuteFromLIDs_, and remoteLIDs_
00208 
00239     void setupSamePermuteRemote();
00240 
00266     void setupExport();
00267 
00269   };
00270 
00271   template <class LocalOrdinal, class GlobalOrdinal, class Node>
00272   Import<LocalOrdinal,GlobalOrdinal,Node>::Import(const RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> > & source, 
00273                                                   const RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> > & target) {
00274     ImportData_ = rcp(new ImportExportData<LocalOrdinal,GlobalOrdinal,Node>(source, target));
00275     // call subfunctions
00276     setupSamePermuteRemote();
00277     if (source->isDistributed()) {
00278       setupExport();
00279     }
00280     // don't need remoteGIDs_ anymore
00281     remoteGIDs_ = null;
00282   }
00283 
00284 
00285   template <class LocalOrdinal, class GlobalOrdinal, class Node>
00286   Import<LocalOrdinal,GlobalOrdinal,Node>::
00287   Import (const Teuchos::RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> > & source, 
00288           const Teuchos::RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> > & target,
00289           const Teuchos::RCP<Teuchos::ParameterList>& plist)
00290   {
00291     using Teuchos::rcp;
00292     typedef ImportExportData<LocalOrdinal,GlobalOrdinal,Node> data_type;
00293 
00294     ImportData_ = rcp (new data_type (source, target, plist));
00295     setupSamePermuteRemote();
00296     if (source->isDistributed()) {
00297       setupExport();
00298     }
00299     remoteGIDs_ = null; // Don't need this anymore
00300   }
00301 
00302 
00303   template <class LocalOrdinal, class GlobalOrdinal, class Node>
00304   Import<LocalOrdinal,GlobalOrdinal,Node>::Import(const Import<LocalOrdinal,GlobalOrdinal,Node> & import)
00305   : ImportData_(import.ImportData_)
00306   {}
00307 
00308   template <class LocalOrdinal, class GlobalOrdinal, class Node>
00309   Import<LocalOrdinal,GlobalOrdinal,Node>::~Import() 
00310   {}
00311 
00312   template <class LocalOrdinal, class GlobalOrdinal, class Node>
00313   size_t Import<LocalOrdinal,GlobalOrdinal,Node>::getNumSameIDs() const {
00314     return ImportData_->numSameIDs_;
00315   }
00316 
00317   template <class LocalOrdinal, class GlobalOrdinal, class Node>
00318   size_t Import<LocalOrdinal,GlobalOrdinal,Node>::getNumPermuteIDs() const {
00319     return ImportData_->permuteFromLIDs_.size();
00320   }
00321 
00322   template <class LocalOrdinal, class GlobalOrdinal, class Node>
00323   ArrayView<const LocalOrdinal> 
00324   Import<LocalOrdinal,GlobalOrdinal,Node>::getPermuteFromLIDs() const {
00325     return ImportData_->permuteFromLIDs_();
00326   }
00327 
00328   template <class LocalOrdinal, class GlobalOrdinal, class Node>
00329   ArrayView<const LocalOrdinal>
00330   Import<LocalOrdinal,GlobalOrdinal,Node>::getPermuteToLIDs() const {
00331     return ImportData_->permuteToLIDs_();
00332   }
00333 
00334   template <class LocalOrdinal, class GlobalOrdinal, class Node>
00335   size_t Import<LocalOrdinal,GlobalOrdinal,Node>::getNumRemoteIDs() const {
00336     return ImportData_->remoteLIDs_.size();
00337   }
00338 
00339   template <class LocalOrdinal, class GlobalOrdinal, class Node>
00340   ArrayView<const LocalOrdinal> 
00341   Import<LocalOrdinal,GlobalOrdinal,Node>::getRemoteLIDs() const {
00342     return ImportData_->remoteLIDs_();
00343   }
00344 
00345   template <class LocalOrdinal, class GlobalOrdinal, class Node>
00346   size_t Import<LocalOrdinal,GlobalOrdinal,Node>::getNumExportIDs() const {
00347     return ImportData_->exportLIDs_.size();
00348   }
00349 
00350   template <class LocalOrdinal, class GlobalOrdinal, class Node>
00351   ArrayView<const LocalOrdinal> 
00352   Import<LocalOrdinal,GlobalOrdinal,Node>::getExportLIDs() const {
00353     return ImportData_->exportLIDs_();
00354   }
00355 
00356   template <class LocalOrdinal, class GlobalOrdinal, class Node>
00357   ArrayView<const int> 
00358   Import<LocalOrdinal,GlobalOrdinal,Node>::getExportImageIDs() const {
00359     return ImportData_->exportImageIDs_();
00360   }
00361 
00362   template <class LocalOrdinal, class GlobalOrdinal, class Node>
00363   const RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> > & 
00364   Import<LocalOrdinal,GlobalOrdinal,Node>::getSourceMap() const {
00365     return ImportData_->source_;
00366   }
00367 
00368   template <class LocalOrdinal, class GlobalOrdinal, class Node>
00369   const RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> > & 
00370   Import<LocalOrdinal,GlobalOrdinal,Node>::getTargetMap() const {
00371     return ImportData_->target_;
00372   }
00373 
00374   template <class LocalOrdinal, class GlobalOrdinal, class Node>
00375   Distributor & 
00376   Import<LocalOrdinal,GlobalOrdinal,Node>::getDistributor() const {
00377     return ImportData_->distributor_;
00378   }
00379 
00380   template <class LocalOrdinal, class GlobalOrdinal, class Node>
00381   Import<LocalOrdinal,GlobalOrdinal,Node>& 
00382   Import<LocalOrdinal,GlobalOrdinal,Node>::operator=(const Import<LocalOrdinal,GlobalOrdinal,Node> & source) {
00383     ImportData_ = source.ImportData_;
00384     return *this;
00385   }
00386 
00387   template <class LocalOrdinal, class GlobalOrdinal, class Node>
00388   void Import<LocalOrdinal,GlobalOrdinal,Node>::print(std::ostream& os) const {
00389     using Teuchos::getFancyOStream;
00390     using Teuchos::rcpFromRef;
00391     using std::endl;
00392 
00393     ArrayView<const LocalOrdinal> av;
00394     ArrayView<const int> avi;
00395     const RCP<const Comm<int> > & comm = getSourceMap()->getComm();
00396     const int myImageID = comm->getRank();
00397     const int numImages = comm->getSize();
00398     for (int imageCtr = 0; imageCtr < numImages; ++imageCtr) {
00399       if (myImageID == imageCtr) {
00400         os << endl;
00401         if (myImageID == 0) { // this is the root node (only output this info once)
00402           os << "Import Data Members:" << endl;
00403         }
00404         os << "Image ID       : " << myImageID << endl;
00405 
00406         os << "permuteFromLIDs: "; os << toString (getPermuteFromLIDs()) << endl;
00407         //av = getPermuteFromLIDs(); std::copy(av.begin(),av.end(),std::ostream_iterator<LocalOrdinal>(os," ")); os << "}" << endl;
00408 
00409         os << "permuteToLIDs  : "; 
00410         os << toString (getPermuteToLIDs()) << endl;
00411         //av = getPermuteToLIDs();   std::copy(av.begin(),av.end(),std::ostream_iterator<LocalOrdinal>(os," ")); os << "}" << endl;
00412 
00413         os << "remoteLIDs     : "; 
00414         os << toString (getRemoteLIDs()) << endl;
00415         //av = getRemoteLIDs();      std::copy(av.begin(),av.end(),std::ostream_iterator<LocalOrdinal>(os," ")); os << "}" << endl;
00416 
00417         os << "exportLIDs     : "; 
00418         os << toString (getExportLIDs()) << endl;
00419         //av = getExportLIDs();      std::copy(av.begin(),av.end(),std::ostream_iterator<LocalOrdinal>(os," ")); os << "}" << endl;
00420 
00421         os << "exportImageIDs : "; 
00422         os << toString (getExportImageIDs()) << endl;
00423         //avi = getExportImageIDs();  std::copy(avi.begin(),avi.end(),std::ostream_iterator<int>(os," ")); os << "}" << endl;
00424 
00425         os << "numSameIDs     : " << getNumSameIDs() << endl;
00426         os << "numPermuteIDs  : " << getNumPermuteIDs() << endl;
00427         os << "numRemoteIDs   : " << getNumRemoteIDs() << endl;
00428         os << "numExportIDs   : " << getNumExportIDs() << endl;
00429       }
00430 
00431       // A few global barriers give I/O a chance to complete.
00432       comm->barrier();
00433       comm->barrier();
00434       comm->barrier();
00435     }
00436 
00437     const bool printMaps = false;
00438     if (printMaps) {
00439       if (myImageID == 0) {
00440         os << endl << endl << "Source Map:" << endl << std::flush; 
00441       }
00442       comm->barrier();
00443       os << *getSourceMap();
00444       comm->barrier();
00445 
00446       if (myImageID == 0) {
00447         os << endl << endl << "Target Map:" << endl << std::flush; 
00448       }
00449       comm->barrier();
00450       os << *getTargetMap();
00451       comm->barrier();
00452     }
00453 
00454     // It's also helpful for debugging to print the Distributor
00455     // object.  Epetra_Import::Print() does this, so we can do a
00456     // side-by-side comparison.
00457     if (myImageID == 0) {
00458       os << endl << endl << "Distributor:" << endl << std::flush;
00459     }
00460     comm->barrier();
00461     getDistributor().describe (*(getFancyOStream (rcpFromRef (os))),
00462                                Teuchos::VERB_EXTREME);
00463   }
00464 
00465 
00466   template <class LocalOrdinal, class GlobalOrdinal, class Node>
00467   void Import<LocalOrdinal,GlobalOrdinal,Node>::setupSamePermuteRemote() {
00468     const Map<LocalOrdinal,GlobalOrdinal,Node> & source = *getSourceMap();
00469     const Map<LocalOrdinal,GlobalOrdinal,Node> & target = *getTargetMap();
00470     ArrayView<const GlobalOrdinal> sourceGIDs = source.getNodeElementList();
00471     ArrayView<const GlobalOrdinal> targetGIDs = target.getNodeElementList();
00472 
00473     // -- compute numSameIDs_ ---
00474     // go through GID lists of source and target. if the ith GID on both is the same, 
00475     // increment numSameIDs_ and try the next. as soon as you come to a pair that don't
00476     // match, give up.
00477     typename ArrayView<const GlobalOrdinal>::iterator sourceIter = sourceGIDs.begin(),
00478                                                       targetIter = targetGIDs.begin();
00479     while( sourceIter != sourceGIDs.end() && targetIter != targetGIDs.end() && *sourceIter == *targetIter )
00480     {
00481       ++ImportData_->numSameIDs_;
00482       ++sourceIter;
00483       ++targetIter;
00484     }
00485     // targetIter should now point to the GID of the first non-same entry or the end of targetGIDs
00486 
00487     // -- compute numPermuteIDs and numRemoteIDs --
00488     // -- fill permuteToLIDs_, permuteFromLIDs_, remoteGIDs_, and remoteLIDs_ --
00489     // go through remaining entries in targetGIDs. if source owns that GID, 
00490     // increment numPermuteIDs_, and add entries to permuteToLIDs_ and permuteFromLIDs_.
00491     // otherwise increment numRemoteIDs_ and add entries to remoteLIDs_ and remoteGIDs_.
00492     remoteGIDs_ = rcp( new Array<GlobalOrdinal>() );
00493     for (; targetIter != targetGIDs.end(); ++targetIter) {
00494       if (source.isNodeGlobalElement(*targetIter)) {
00495         // both source and target list this GID (*targetIter)
00496         // determine the LIDs for this GID on both Maps and add them to the permutation lists
00497         ImportData_->permuteToLIDs_.push_back(target.getLocalElement(*targetIter));
00498         ImportData_->permuteFromLIDs_.push_back(source.getLocalElement(*targetIter));
00499       }
00500       else {
00501         // this GID is on another processor; store it, along with its destination LID on this processor
00502         remoteGIDs_->push_back(*targetIter);
00503         ImportData_->remoteLIDs_.push_back(target.getLocalElement(*targetIter));
00504       }
00505     }
00506 
00507     TPETRA_ABUSE_WARNING((getNumRemoteIDs() > 0) && !source.isDistributed(),std::runtime_error,
00508         "::setupSamePermuteRemote(): Target has remote LIDs but Source is not distributed globally."
00509         << std::endl << "Importing to a submap of the target map.");
00510   }
00511 
00512 
00513   template <class LocalOrdinal, class GlobalOrdinal, class Node>
00514   void Import<LocalOrdinal,GlobalOrdinal,Node>::setupExport() {
00515     typedef typename Array<int>::difference_type size_type;
00516     const Map<LocalOrdinal,GlobalOrdinal,Node> & source = *getSourceMap();
00517 
00518     // For each entry remoteGIDs[i], remoteImageIDs[i] will contain
00519     // the process ID of the process that owns that GID.
00520     ArrayView<GlobalOrdinal> remoteGIDs = (*remoteGIDs_)();
00521     Array<int> remoteImageIDs(remoteGIDs.size());
00522     // lookup == IDNotPresent means that the source Map wasn't able to
00523     // figure out to which processes one or more of the GIDs in the
00524     // given list of remoteGIDs belong.
00525     //
00526     // The previous abuse warning said "The target Map has GIDs not
00527     // found in the source Map."  This statement could be confusing,
00528     // because it doesn't refer to ownership by the current process,
00529     // but rather to ownership by _any_ process participating in the
00530     // Map.  (It could not possibly refer to ownership by the current
00531     // process, since remoteGIDs is exactly the list of GIDs owned by
00532     // the target Map but not owned by the source Map.  It was
00533     // constructed that way by setupSamePermuteRemote().)  
00534     //
00535     // What this statement means is that the source and target Maps
00536     // don't contain the same set of GIDs globally (over all
00537     // processes).  That is, there is at least one GID owned by some
00538     // process in the target Map, which is not owned by _any_ process
00539     // in the source Map.
00540     const LookupStatus lookup = source.getRemoteIndexList(remoteGIDs, remoteImageIDs());
00541     TPETRA_ABUSE_WARNING( lookup == IDNotPresent, std::runtime_error, 
00542       "::setupExport(): the source Map wasn't able to figure out which process "
00543       "owns one or more of the GIDs in the list of remote GIDs.  This probably "
00544       "means that there is at least one GID owned by some process in the target"
00545       " Map which is not owned by any process in the source Map.  (That is, the"
00546       " source and target Maps do not contain the same set of GIDs globally.)");
00547 
00548     // Ignore remote GIDs that aren't owned by any process in the
00549     // source Map.  getRemoteIndexList() gives each of these a process
00550     // ID of -1.
00551     if ( lookup == IDNotPresent ) {
00552       const size_type numInvalidRemote = std::count_if( remoteImageIDs.begin(), remoteImageIDs.end(), std::bind1st(std::equal_to<int>(),-1) );
00553       // if all of them are invalid, we can delete the whole array
00554       const size_type totalNumRemote = getNumRemoteIDs();
00555       if (numInvalidRemote == totalNumRemote) {
00556         // all remotes are invalid; we have no remotes; we can delete the remotes
00557         remoteImageIDs.clear();
00558         (*remoteGIDs_).clear();
00559         ImportData_->remoteLIDs_.clear();
00560       }
00561       else {
00562         // Some remotes are valid; we need to keep the valid ones.
00563         // Pack and resize remoteImageIDs, remoteGIDs_, and
00564         // remoteLIDs_.
00565         size_type numValidRemote = 0;
00566         for (size_type r = 0; r < totalNumRemote; ++r) {
00567           if (remoteImageIDs[r] != -1) {
00568             remoteImageIDs[numValidRemote] = remoteImageIDs[r];
00569             (*remoteGIDs_)[numValidRemote] = (*remoteGIDs_)[r];
00570             ImportData_->remoteLIDs_[numValidRemote] = ImportData_->remoteLIDs_[r];
00571             ++numValidRemote;
00572           }
00573         }
00574         TEUCHOS_TEST_FOR_EXCEPTION( numValidRemote != totalNumRemote - numInvalidRemote, std::logic_error,
00575           "Tpetra::Import::setupExport(): After removing invalid remote GIDs and packing the valid remote "
00576           "GIDs, numValidRemote = " << numValidRemote << " != totalNumRemote - numInvalidRemote = "
00577           << totalNumRemote - numInvalidRemote << ".  Please report this bug to the Tpetra developers.");
00578 
00579         remoteImageIDs.resize(numValidRemote);
00580         (*remoteGIDs_).resize(numValidRemote);
00581         ImportData_->remoteLIDs_.resize(numValidRemote);
00582       }
00583       remoteGIDs = (*remoteGIDs_)();
00584     }
00585 
00586     // Sort remoteImageIDs in ascending order.  Apply the resulting
00587     // permutation to remoteGIDs_ and remoteLIDs_, so that
00588     // remoteImageIDs[i], remoteGIDs_[i], and remoteLIDs_[i] refer to
00589     // the same thing.
00590     sort3(remoteImageIDs.begin(), remoteImageIDs.end(), remoteGIDs.begin(), ImportData_->remoteLIDs_.begin());
00591 
00592     // Call the Distributor's createFromRecvs() method to turn the
00593     // remote GIDs and their owning processes into a send-and-receive
00594     // communication plan.  remoteGIDs and remoteImageIDs_ are input;
00595     // exportGIDs and exportImageIDs_ are output arrays which are
00596     // allocated by createFromRecvs().
00597     ArrayRCP<GlobalOrdinal> exportGIDs;
00598     ImportData_->distributor_.createFromRecvs(remoteGIDs().getConst(), remoteImageIDs, exportGIDs, ImportData_->exportImageIDs_);
00599 
00600     // Find the LIDs corresponding to the GIDs in exportGIDs.  For
00601     // sparse matrix-vector multiply, this tells the calling process
00602     // how to index into the source vector to get the elements which
00603     // it needs to send.
00604     if (exportGIDs != null) {
00605       ImportData_->exportLIDs_ = arcp<LocalOrdinal>(exportGIDs.size());
00606     }
00607     typename ArrayRCP<LocalOrdinal>::iterator dst = ImportData_->exportLIDs_.begin();
00608     typename ArrayRCP<GlobalOrdinal>::const_iterator src = exportGIDs.begin();
00609     while (src != exportGIDs.end())
00610     {
00611       (*dst++) = source.getLocalElement(*src++);
00612     }
00613   }
00614 
00624   template <class LO, class GO, class Node> 
00625   RCP< const Import<LO,GO,Node> >
00626   createImport( const RCP<const Map<LO,GO,Node> > & src, 
00627                 const RCP<const Map<LO,GO,Node> > & tgt )
00628   {
00629     if (src == tgt) return null;
00630 #ifdef HAVE_TPETRA_DEBUG
00631     TEUCHOS_TEST_FOR_EXCEPTION(src == null || tgt == null, std::runtime_error,
00632         "Tpetra::createImport(): neither source nor target map may be null:\nsource: " << src << "\ntarget: " << tgt << "\n");
00633 #endif
00634     return rcp(new Import<LO,GO,Node>(src,tgt));
00635   }
00636 
00639   template <class LO, class GO, class Node> 
00640   RCP< const Import<LO,GO,Node> >
00641   TPETRA_DEPRECATED makeImport( const RCP<const Map<LO,GO,Node> > & src, 
00642                                 const RCP<const Map<LO,GO,Node> > & tgt )
00643   {
00644     return createImport<LO,GO,Node>(src,tgt);
00645   }
00646 
00647 } // namespace Tpetra
00648 
00649 #endif // TPETRA_IMPORT_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines