All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
Xpetra_CrsMatrixWrap.hpp
Go to the documentation of this file.
00001 // @HEADER
00002 //
00003 // ***********************************************************************
00004 //
00005 //             Xpetra: A linear algebra interface package
00006 //                  Copyright 2012 Sandia Corporation
00007 //
00008 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00009 // the U.S. Government retains certain rights in this software.
00010 //
00011 // Redistribution and use in source and binary forms, with or without
00012 // modification, are permitted provided that the following conditions are
00013 // met:
00014 //
00015 // 1. Redistributions of source code must retain the above copyright
00016 // notice, this list of conditions and the following disclaimer.
00017 //
00018 // 2. Redistributions in binary form must reproduce the above copyright
00019 // notice, this list of conditions and the following disclaimer in the
00020 // documentation and/or other materials provided with the distribution.
00021 //
00022 // 3. Neither the name of the Corporation nor the names of the
00023 // contributors may be used to endorse or promote products derived from
00024 // this software without specific prior written permission.
00025 //
00026 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00027 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00028 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00029 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00030 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00031 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00032 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00033 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00034 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00035 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00036 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00037 //
00038 // Questions? Contact
00039 //                    Jonathan Hu       (jhu@sandia.gov)
00040 //                    Andrey Prokopenko (aprokop@sandia.gov)
00041 //                    Ray Tuminaro      (rstumin@sandia.gov)
00042 //
00043 // ***********************************************************************
00044 //
00045 // @HEADER
00046 
00047 // WARNING: This code is experimental. Backwards compatibility should not be expected.
00048 
00049 #ifndef XPETRA_CRSMATRIXWRAP_HPP
00050 #define XPETRA_CRSMATRIXWRAP_HPP
00051 
00052 #include <Kokkos_DefaultNode.hpp>
00053 
00054 #include "Xpetra_ConfigDefs.hpp"
00055 #include "Xpetra_Exceptions.hpp"
00056 
00057 #include "Xpetra_MultiVector.hpp"
00058 #include "Xpetra_CrsGraph.hpp"
00059 #include "Xpetra_CrsMatrix.hpp"
00060 #include "Xpetra_CrsMatrixFactory.hpp"
00061 
00062 #include "Xpetra_Matrix.hpp"
00063 
00064 #include <Teuchos_SerialDenseMatrix.hpp>
00065 #include <Teuchos_Hashtable.hpp>
00066 
00071 namespace Xpetra {
00072 
00073   typedef std::string viewLabel_t;
00074 
00079 template <class Scalar = Matrix<>::scalar_type,
00080           class LocalOrdinal = typename Matrix<Scalar>::local_ordinal_type,
00081           class GlobalOrdinal =
00082             typename Matrix<Scalar, LocalOrdinal>::global_ordinal_type,
00083           class Node =
00084             typename Matrix<Scalar, LocalOrdinal, GlobalOrdinal>::node_type>
00085 class CrsMatrixWrap :
00086   public Matrix<Scalar,LocalOrdinal,GlobalOrdinal,Node>
00087 {
00088   typedef Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node> Map;
00089   typedef Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> CrsMatrix;
00090   typedef Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> Matrix;
00091   typedef Xpetra::CrsGraph<LocalOrdinal, GlobalOrdinal, Node> CrsGraph;
00092 #ifdef HAVE_XPETRA_TPETRA
00093   typedef Xpetra::TpetraCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> TpetraCrsMatrix;
00094 #endif
00095   typedef Xpetra::CrsMatrixFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node> CrsMatrixFactory;
00096   typedef Xpetra::MatrixView<LocalOrdinal, GlobalOrdinal, Node> MatrixView;
00097 
00098 public:
00100 
00101 
00103   CrsMatrixWrap (const RCP<const Map>& rowMap,
00104                  size_t maxNumEntriesPerRow,
00105                  Xpetra::ProfileType pftype = Xpetra::DynamicProfile)
00106     : finalDefaultView_ (false)
00107   {
00108     matrixData_ = CrsMatrixFactory::Build (rowMap, maxNumEntriesPerRow, pftype);
00109     CreateDefaultView ();
00110   }
00111 
00113   CrsMatrixWrap (const RCP<const Map>& rowMap,
00114                  const ArrayRCP<const size_t>& NumEntriesPerRowToAlloc,
00115                  ProfileType pftype = Xpetra::DynamicProfile)
00116     : finalDefaultView_ (false)
00117   {
00118     matrixData_ = CrsMatrixFactory::Build(rowMap, NumEntriesPerRowToAlloc, pftype);
00119     CreateDefaultView ();
00120   }
00121 
00123   CrsMatrixWrap(const RCP<const Map> &rowMap, const RCP<const Map>& colMap, size_t maxNumEntriesPerRow, Xpetra::ProfileType pftype = Xpetra::DynamicProfile)
00124     : finalDefaultView_(false)
00125   {
00126     // Set matrix data
00127     matrixData_ = CrsMatrixFactory::Build(rowMap, colMap, maxNumEntriesPerRow, pftype);
00128 
00129     // Default view
00130     CreateDefaultView();
00131   }
00132 
00134   CrsMatrixWrap(const RCP<const Map> &rowMap, const RCP<const Map>& colMap, const ArrayRCP<const size_t> &NumEntriesPerRowToAlloc, Xpetra::ProfileType pftype = Xpetra::DynamicProfile)
00135     : finalDefaultView_(false)
00136   {
00137     // Set matrix data
00138     matrixData_ = CrsMatrixFactory::Build(rowMap, colMap, NumEntriesPerRowToAlloc, pftype);
00139 
00140     // Default view
00141     CreateDefaultView();
00142   }
00143 
00144   CrsMatrixWrap(RCP<CrsMatrix> matrix)
00145     : finalDefaultView_(matrix->isFillComplete())
00146   {
00147     // Set matrix data
00148     matrixData_ = matrix;
00149 
00150     // Default view
00151     CreateDefaultView();
00152   }
00153 
00154   CrsMatrixWrap(const RCP<const CrsGraph>& graph, const RCP<ParameterList>& paramList = Teuchos::null)
00155     : finalDefaultView_(false)
00156   {
00157     // Set matrix data
00158     matrixData_ = CrsMatrixFactory::Build(graph, paramList);
00159 
00160     // Default view
00161     CreateDefaultView();
00162   }
00163 
00165   virtual ~CrsMatrixWrap() {}
00166 
00168 
00169 
00171 
00172 
00174 
00185   void insertGlobalValues(GlobalOrdinal globalRow, const ArrayView<const GlobalOrdinal> &cols, const ArrayView<const Scalar> &vals) {
00186     matrixData_->insertGlobalValues(globalRow, cols, vals);
00187   }
00188 
00190 
00197   void insertLocalValues(LocalOrdinal localRow, const ArrayView<const LocalOrdinal> &cols, const ArrayView<const Scalar> &vals) {
00198     matrixData_->insertLocalValues(localRow, cols, vals);
00199   }
00200 
00202 
00207   void replaceGlobalValues(GlobalOrdinal globalRow,
00208                            const ArrayView<const GlobalOrdinal> &cols,
00209                            const ArrayView<const Scalar>        &vals) { matrixData_->replaceGlobalValues(globalRow, cols, vals); }
00210 
00212 
00215   void replaceLocalValues(LocalOrdinal localRow,
00216                           const ArrayView<const LocalOrdinal> &cols,
00217                           const ArrayView<const Scalar>       &vals) { matrixData_->replaceLocalValues(localRow, cols, vals); }
00218 
00220   virtual void setAllToScalar(const Scalar &alpha) { matrixData_->setAllToScalar(alpha); }
00221 
00223   void scale(const Scalar &alpha) {
00224     matrixData_->scale(alpha);
00225   }
00226 
00228 
00230 
00231 
00240   void resumeFill(const RCP< ParameterList > &params=null) {
00241     matrixData_->resumeFill(params);
00242   }
00243 
00255   void fillComplete(const RCP<const Map> &domainMap, const RCP<const Map> &rangeMap, const RCP<Teuchos::ParameterList> &params = null) {
00256     matrixData_->fillComplete(domainMap, rangeMap, params);
00257 
00258     // Update default view with the colMap because colMap can be <tt>null</tt> until fillComplete() is called.
00259     updateDefaultView();
00260   }
00261 
00275   //TODO : Get ride of "Tpetra"::OptimizeOption
00276   void fillComplete(const RCP<ParameterList> &params = null) {
00277     matrixData_->fillComplete(params);
00278 
00279     // Update default view with the colMap because colMap can be <tt>null</tt> until fillComplete() is called.
00280     updateDefaultView();
00281   }
00282 
00284 
00286 
00288   global_size_t getGlobalNumRows() const {
00289     return matrixData_->getGlobalNumRows();
00290   }
00291 
00293 
00295   global_size_t getGlobalNumCols() const {
00296     return matrixData_->getGlobalNumCols();
00297   }
00298 
00300   size_t getNodeNumRows() const {
00301     return matrixData_->getNodeNumRows();
00302   }
00303 
00305   global_size_t getGlobalNumEntries() const {
00306     return matrixData_->getGlobalNumEntries();
00307   }
00308 
00310   size_t getNodeNumEntries() const {
00311     return matrixData_->getNodeNumEntries();
00312   }
00313 
00315 
00316   size_t getNumEntriesInLocalRow(LocalOrdinal localRow) const {
00317     return matrixData_->getNumEntriesInLocalRow(localRow);
00318   }
00319 
00321 
00323   global_size_t getGlobalNumDiags() const {
00324     return matrixData_->getGlobalNumDiags();
00325   }
00326 
00328 
00330   size_t getNodeNumDiags() const {
00331     return matrixData_->getNodeNumDiags();
00332   }
00333 
00335 
00337   size_t getGlobalMaxNumRowEntries() const {
00338     return matrixData_->getGlobalMaxNumRowEntries();
00339   }
00340 
00342 
00344   size_t getNodeMaxNumRowEntries() const {
00345     return matrixData_->getNodeMaxNumRowEntries();
00346   }
00347 
00349   bool isLocallyIndexed() const {
00350     return matrixData_->isLocallyIndexed();
00351   }
00352 
00354   bool isGloballyIndexed() const {
00355     return matrixData_->isGloballyIndexed();
00356   }
00357 
00359   bool isFillComplete() const {
00360     return matrixData_->isFillComplete();
00361   }
00362 
00364 
00376   void getLocalRowCopy(LocalOrdinal LocalRow,
00377                        const ArrayView<LocalOrdinal> &Indices,
00378                        const ArrayView<Scalar> &Values,
00379                        size_t &NumEntries
00380                        ) const {
00381     matrixData_->getLocalRowCopy(LocalRow, Indices, Values, NumEntries);
00382   }
00383 
00385 
00394   void getGlobalRowView(GlobalOrdinal GlobalRow, ArrayView<const GlobalOrdinal> &indices, ArrayView<const Scalar> &values) const {
00395      matrixData_->getGlobalRowView(GlobalRow, indices, values);
00396   }
00397 
00399 
00408   void getLocalRowView(LocalOrdinal LocalRow, ArrayView<const LocalOrdinal> &indices, ArrayView<const Scalar> &values) const {
00409      matrixData_->getLocalRowView(LocalRow, indices, values);
00410   }
00411 
00413 
00415   void getLocalDiagCopy(Vector<Scalar,LocalOrdinal,GlobalOrdinal,Node> &diag) const {
00416     matrixData_->getLocalDiagCopy(diag);
00417   }
00418 
00420   void getLocalDiagOffsets(Teuchos::ArrayRCP<size_t> &offsets) const {
00421     matrixData_->getLocalDiagOffsets(offsets);
00422   }
00423 
00425   void getLocalDiagCopy(Vector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &diag, const Teuchos::ArrayView<const size_t> &offsets) const {
00426     matrixData_->getLocalDiagCopy(diag,offsets);
00427   }
00428 
00430   typename ScalarTraits<Scalar>::magnitudeType getFrobeniusNorm() const {
00431     return matrixData_->getFrobeniusNorm();
00432   }
00433 
00435 
00437 
00438 
00440 
00449   //TODO virtual=0 // TODO: Add default parameters ?
00450 //   void multiply(const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> & X, MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> &Y, Teuchos::ETransp trans, Scalar alpha, Scalar beta) const {
00451 //      matrixData_->multiply(X, Y, trans, alpha, beta);
00452 //   }
00453 
00455 
00457 
00458 
00460 
00463   void apply(const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> & X, MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> &Y,
00464              Teuchos::ETransp mode = Teuchos::NO_TRANS,
00465              Scalar alpha = ScalarTraits<Scalar>::one(),
00466              Scalar beta = ScalarTraits<Scalar>::zero()) const {
00467 
00468     matrixData_->apply(X,Y,mode,alpha,beta);
00469   }
00470 
00473   const RCP<const Xpetra::Map<LocalOrdinal,GlobalOrdinal,Node> > getDomainMap() const {
00474     return matrixData_->getDomainMap();
00475   }
00476 
00479   const RCP<const Xpetra::Map<LocalOrdinal,GlobalOrdinal,Node> > getRangeMap() const {
00480     return matrixData_->getRangeMap();
00481   }
00482 
00485   const RCP<const Map> & getColMap() const { return getColMap(Matrix::GetCurrentViewLabel()); }
00486 
00488   const RCP<const Map> & getColMap(viewLabel_t viewLabel) const {
00489     TEUCHOS_TEST_FOR_EXCEPTION(Matrix::operatorViewTable_.containsKey(viewLabel) == false, Xpetra::Exceptions::RuntimeError, "Xpetra::Matrix.GetColMap(): view '" + viewLabel + "' does not exist.");
00490     updateDefaultView(); // If CrsMatrix::fillComplete() have been used instead of CrsMatrixWrap::fillComplete(), the default view is updated.
00491     return Matrix::operatorViewTable_.get(viewLabel)->GetColMap();
00492   }
00493 
00494   void removeEmptyProcessesInPlace(const Teuchos::RCP<const Map>& newMap) {
00495     matrixData_->removeEmptyProcessesInPlace(newMap);
00496     this->operatorViewTable_.get(this->GetCurrentViewLabel())->SetRowMap(matrixData_->getRowMap());
00497     this->operatorViewTable_.get(this->GetCurrentViewLabel())->SetColMap(matrixData_->getColMap());
00498   }
00499 
00501 
00503   //{@
00504 
00506   const Teuchos::RCP< const Xpetra::Map< LocalOrdinal, GlobalOrdinal, Node > > getMap() const {
00507     return matrixData_->getMap();
00508   }
00509 
00511   void doImport(const Matrix &source,
00512                 const Import< LocalOrdinal, GlobalOrdinal, Node > &importer, CombineMode CM) {
00513     const CrsMatrixWrap & sourceWrp = dynamic_cast<const CrsMatrixWrap &>(source);
00514     matrixData_->doImport(*sourceWrp.getCrsMatrix(), importer, CM);
00515   }
00516 
00518   void doExport(const Matrix &dest,
00519                 const Import< LocalOrdinal, GlobalOrdinal, Node >& importer, CombineMode CM) {
00520     const CrsMatrixWrap & destWrp = dynamic_cast<const CrsMatrixWrap &>(dest);
00521     matrixData_->doExport(*destWrp.getCrsMatrix(), importer, CM);
00522   }
00523 
00525   void doImport(const Matrix &source,
00526                 const Export< LocalOrdinal, GlobalOrdinal, Node >& exporter, CombineMode CM) {
00527     const CrsMatrixWrap & sourceWrp = dynamic_cast<const CrsMatrixWrap &>(source);
00528     matrixData_->doImport(*sourceWrp.getCrsMatrix(), exporter, CM);
00529   }
00530 
00532   void doExport(const Matrix &dest,
00533                 const Export< LocalOrdinal, GlobalOrdinal, Node >& exporter, CombineMode CM) {
00534     const CrsMatrixWrap & destWrp = dynamic_cast<const CrsMatrixWrap &>(dest);
00535     matrixData_->doExport(*destWrp.getCrsMatrix(), exporter, CM);
00536   }
00537 
00538   // @}
00539 
00541 
00542 
00544   std::string description() const {
00545     return "Xpetra::CrsMatrixWrap";
00546   }
00547 
00549   void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel=Teuchos::Describable::verbLevel_default) const {
00550     //     Teuchos::EVerbosityLevel vl = verbLevel;
00551     //     if (vl == VERB_DEFAULT) vl = VERB_LOW;
00552     //     RCP<const Comm<int> > comm = this->getComm();
00553     //     const int myImageID = comm->getRank(),
00554     //       numImages = comm->getSize();
00555 
00556     //     if (myImageID == 0) out << this->description() << std::endl;
00557 
00558     matrixData_->describe(out,verbLevel);
00559 
00560     // Teuchos::OSTab tab(out);
00561   }
00562 
00563   // JG: Added:
00564 
00566   RCP<const CrsGraph> getCrsGraph() const { return matrixData_->getCrsGraph(); }
00567 
00568   RCP<CrsMatrix> getCrsMatrix() const {  return matrixData_; }
00569 
00571 
00572   template<class Node2>
00573   RCP<Xpetra::Matrix<Scalar,LocalOrdinal,GlobalOrdinal,Node2> > clone(const RCP<Node2> &node2) const {
00574 #ifdef HAVE_XPETRA_TPETRA
00575     RCP<const Xpetra::TpetraCrsMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node> > tMatrix =
00576         Teuchos::rcp_dynamic_cast<const Xpetra::TpetraCrsMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node> >(matrixData_);
00577     if (tMatrix == Teuchos::null)
00578       throw Xpetra::Exceptions::RuntimeError("clone() functionality is only available for Tpetra");
00579 
00580     return RCP<CrsMatrixWrap<Scalar,LocalOrdinal,GlobalOrdinal,Node2> >(new CrsMatrixWrap<Scalar,LocalOrdinal,GlobalOrdinal,Node2>(tMatrix->clone(node2)));
00581     // TODO: inherit strided maps/views ?
00582 #else
00583     return Teuchos::null;
00584 #endif
00585   }
00586 
00587 private:
00588 
00589   // Default view is created after fillComplete()
00590   // Because ColMap might not be available before fillComplete().
00591   void CreateDefaultView() {
00592 
00593     // Create default view
00594     this->defaultViewLabel_ = "point";
00595     this->CreateView(this->GetDefaultViewLabel(), matrixData_->getRowMap(), matrixData_->getColMap());
00596 
00597     // Set current view
00598     this->currentViewLabel_ = this->GetDefaultViewLabel();
00599   }
00600 
00601 private:
00602 
00603   // The colMap can be <tt>null</tt> until fillComplete() is called. The default view of the Matrix have to be updated when fillComplete() is called.
00604   // If CrsMatrix::fillComplete() have been used instead of CrsMatrixWrap::fillComplete(), the default view is updated when getColMap() is called.
00605   void updateDefaultView() const {
00606     if ((finalDefaultView_ == false) &&  matrixData_->isFillComplete() ) {
00607       // Update default view with the colMap
00608       Matrix::operatorViewTable_.get(Matrix::GetDefaultViewLabel())->SetColMap(matrixData_->getColMap());
00609       finalDefaultView_ = true;
00610     }
00611   }
00612   // The boolean finalDefaultView_ keep track of the status of the default view (= already updated or not)
00613   // See also CrsMatrixWrap::updateDefaultView()
00614   mutable bool finalDefaultView_;
00615 
00616 
00617   RCP<CrsMatrix> matrixData_;
00618 
00619 }; //class Matrix
00620 
00621 } //namespace Xpetra
00622 
00623 #define XPETRA_CRSMATRIXWRAP_SHORT
00624 #endif //XPETRA_CRSMATRIXWRAP_DECL_HPP
00625 
00626 //NOTE: if CrsMatrix and VbrMatrix share a common interface for fillComplete() etc, I can move some stuff in Xpetra_Matrix.hpp
00627 //TODO: getUnderlyingMatrix() method
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines