All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
Xpetra_EpetraCrsMatrix.cpp
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 //                    Jeremie Gaidamour (jngaida@sandia.gov)
00040 //                    Jonathan Hu       (jhu@sandia.gov)
00041 //                    Ray Tuminaro      (rstumin@sandia.gov)
00042 //
00043 // ***********************************************************************
00044 //
00045 // @HEADER
00046 #include <Teuchos_Array.hpp>
00047 #include "Xpetra_EpetraCrsMatrix.hpp"
00048 
00049 namespace Xpetra {
00050 
00051   EpetraCrsMatrix::EpetraCrsMatrix(const RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > &rowMap, size_t maxNumEntriesPerRow, ProfileType pftype, const Teuchos::RCP< Teuchos::ParameterList > &plist)
00052     : mtx_(Teuchos::rcp(new Epetra_CrsMatrix(Copy, toEpetra(rowMap), maxNumEntriesPerRow, toEpetra(pftype)))) { }
00053 
00054   EpetraCrsMatrix::EpetraCrsMatrix(const RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > &rowMap, const ArrayRCP< const size_t > &NumEntriesPerRowToAlloc, ProfileType pftype, const Teuchos::RCP< Teuchos::ParameterList > &plist) {
00055     Teuchos::Array<int> numEntriesPerRowToAlloc(NumEntriesPerRowToAlloc.begin(), NumEntriesPerRowToAlloc.end()); // convert array of "size_t" to array of "int"
00056     mtx_ = Teuchos::rcp(new Epetra_CrsMatrix(Copy, toEpetra(rowMap), numEntriesPerRowToAlloc.getRawPtr(), toEpetra(pftype)));
00057   }
00058   
00059   EpetraCrsMatrix::EpetraCrsMatrix(const RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > &rowMap, const RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > &colMap, size_t maxNumEntriesPerRow, ProfileType pftype, const Teuchos::RCP< Teuchos::ParameterList > &plist)
00060     : mtx_(Teuchos::rcp(new Epetra_CrsMatrix(Copy, toEpetra(rowMap), toEpetra(colMap), maxNumEntriesPerRow, toEpetra(pftype)))) { }
00061   
00062   EpetraCrsMatrix::EpetraCrsMatrix(const RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > &rowMap, const RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > &colMap, const ArrayRCP< const size_t > &NumEntriesPerRowToAlloc, ProfileType pftype, const Teuchos::RCP< Teuchos::ParameterList > &plist) {
00063     Teuchos::Array<int> numEntriesPerRowToAlloc(NumEntriesPerRowToAlloc.begin(), NumEntriesPerRowToAlloc.end()); // convert array of "size_t" to array of "int"
00064     mtx_ = Teuchos::rcp(new Epetra_CrsMatrix(Copy, toEpetra(rowMap), toEpetra(colMap), numEntriesPerRowToAlloc.getRawPtr(), toEpetra(pftype)));
00065   }
00066 
00067   EpetraCrsMatrix::EpetraCrsMatrix(const Teuchos::RCP< const CrsGraph< LocalOrdinal, GlobalOrdinal, Node, LocalMatOps > > &graph, const Teuchos::RCP< Teuchos::ParameterList > &plist)
00068     : mtx_(Teuchos::rcp(new Epetra_CrsMatrix(Copy, toEpetra(graph)))) { }
00069 
00070   void EpetraCrsMatrix::insertGlobalValues(int globalRow, const ArrayView<const int> &cols, const ArrayView<const double> &vals) { 
00071     XPETRA_MONITOR("EpetraCrsMatrix::insertGlobalValues");
00072     XPETRA_ERR_CHECK(mtx_->InsertGlobalValues(globalRow, vals.size(), vals.getRawPtr(), cols.getRawPtr())); 
00073   }
00074 
00075   void EpetraCrsMatrix::insertLocalValues(int localRow, const ArrayView<const int> &cols, const ArrayView<const double> &vals) {
00076     XPETRA_MONITOR("EpetraCrsMatrix::insertLocalValues");
00077     XPETRA_ERR_CHECK(mtx_->InsertMyValues(localRow, vals.size(), vals.getRawPtr(), cols.getRawPtr()));
00078   }
00079 
00080   //TODO: throw same exception as Tpetra
00081   void EpetraCrsMatrix::getLocalRowCopy(int LocalRow, const ArrayView<int> &Indices, const ArrayView<double> &Values, size_t &NumEntries) const { 
00082     XPETRA_MONITOR("EpetraCrsMatrix::getLocalRowCopy");
00083 
00084     int numEntries=-1;
00085     XPETRA_ERR_CHECK(mtx_->ExtractMyRowCopy(LocalRow, Indices.size(), numEntries, Values.getRawPtr(), Indices.getRawPtr()));
00086     NumEntries = numEntries;
00087   }
00088 
00089   void EpetraCrsMatrix::getGlobalRowView(int GlobalRow, ArrayView<const int> &indices, ArrayView<const double> &values) const { 
00090     XPETRA_MONITOR("EpetraCrsMatrix::getGlobalRowView");
00091 
00092     int      numEntries;
00093     double * eValues;
00094     int    * eIndices;
00095       
00096     XPETRA_ERR_CHECK(mtx_->ExtractGlobalRowView(GlobalRow, numEntries, eValues, eIndices));
00097     if (numEntries == 0) { eValues = NULL; eIndices = NULL; } // Cf. TEUCHOS_TEST_FOR_EXCEPT( p == 0 && size_in != 0 ) in Teuchos ArrayView constructor.
00098 
00099     indices = ArrayView<const int>(eIndices, numEntries);
00100     values  = ArrayView<const double>(eValues, numEntries);
00101   }
00102 
00103   void EpetraCrsMatrix::getLocalRowView(int LocalRow, ArrayView<const int> &indices, ArrayView<const double> &values) const { 
00104     XPETRA_MONITOR("EpetraCrsMatrix::getLocalRowView");
00105 
00106     int      numEntries;
00107     double * eValues;
00108     int    * eIndices;
00109       
00110     XPETRA_ERR_CHECK(mtx_->ExtractMyRowView(LocalRow, numEntries, eValues, eIndices));
00111     if (numEntries == 0) { eValues = NULL; eIndices = NULL; } // Cf. TEUCHOS_TEST_FOR_EXCEPT( p == 0 && size_in != 0 ) in Teuchos ArrayView constructor.
00112 
00113     indices = ArrayView<const int>(eIndices, numEntries);
00114     values  = ArrayView<const double>(eValues, numEntries);
00115   }
00116 
00117   void EpetraCrsMatrix::apply(const MultiVector<double,int,int> & X, MultiVector<double,int,int> &Y, Teuchos::ETransp mode, double alpha, double beta) const { 
00118     XPETRA_MONITOR("EpetraCrsMatrix::apply");
00119 
00120     //TEUCHOS_TEST_FOR_EXCEPTION((alpha != 1) || (beta != 0), Xpetra::Exceptions::NotImplemented, "Xpetra::EpetraCrsMatrix.multiply() only accept alpha==1 and beta==0");
00121       
00122     XPETRA_DYNAMIC_CAST(const EpetraMultiVector, X, eX, "Xpetra::EpetraCrsMatrix->apply() only accept Xpetra::EpetraMultiVector as input arguments.");
00123     XPETRA_DYNAMIC_CAST(      EpetraMultiVector, Y, eY, "Xpetra::EpetraCrsMatrix->apply() only accept Xpetra::EpetraMultiVector as input arguments.");
00124 
00125     TEUCHOS_TEST_FOR_EXCEPTION((mode != Teuchos::NO_TRANS) && (mode != Teuchos::TRANS), Xpetra::Exceptions::NotImplemented, "Xpetra::EpetraCrsMatrix->apply() only accept mode == NO_TRANS or mode == TRANS");
00126     bool eTrans = toEpetra(mode);
00127 
00128     // /!\ UseTranspose value
00129     TEUCHOS_TEST_FOR_EXCEPTION(mtx_->UseTranspose(), Xpetra::Exceptions::NotImplemented, "An exception is throw to let you know that Xpetra::EpetraCrsMatrix->apply() do not take into account the UseTranspose() parameter of Epetra_CrsMatrix.");
00130       
00131     RCP<Epetra_MultiVector> epY = eY.getEpetra_MultiVector();
00132 
00133     // helper vector: tmp = A*x
00134     RCP<Epetra_MultiVector> tmp = Teuchos::rcp(new Epetra_MultiVector(*epY));
00135     tmp->PutScalar(0.0);
00136     XPETRA_ERR_CHECK(mtx_->Multiply(eTrans, *eX.getEpetra_MultiVector(), *tmp));
00137 
00138     // calculate alpha * A * x + beta * y
00139     XPETRA_ERR_CHECK(eY.getEpetra_MultiVector()->Update(alpha,*tmp,beta));
00140   }
00141 
00142   std::string EpetraCrsMatrix::description() const { 
00143     XPETRA_MONITOR("EpetraCrsMatrix::description");
00144 
00145     // This implementation come from Tpetra_CrsMatrix_def.hpp (without modification)
00146     std::ostringstream oss;
00147     //TODO: oss << DistObject<char, LocalOrdinal,GlobalOrdinal>::description();
00148     if (isFillComplete()) {
00149       oss << "{status = fill complete"
00150           << ", global rows = " << getGlobalNumRows()
00151           << ", global cols = " << getGlobalNumCols()
00152           << ", global num entries = " << getGlobalNumEntries()
00153           << "}";
00154     }
00155     else {
00156       oss << "{status = fill not complete"
00157           << ", global rows = " << getGlobalNumRows()
00158           << "}";
00159     }
00160     return oss.str();
00161       
00162   } 
00163     
00164   void EpetraCrsMatrix::describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const { 
00165     XPETRA_MONITOR("EpetraCrsMatrix::describe");
00166 
00167     // This implementation come from Tpetra_CrsMatrix_def.hpp (without modification)
00168     using std::endl;
00169     using std::setw;
00170     using Teuchos::VERB_DEFAULT;
00171     using Teuchos::VERB_NONE;
00172     using Teuchos::VERB_LOW;
00173     using Teuchos::VERB_MEDIUM;
00174     using Teuchos::VERB_HIGH;
00175     using Teuchos::VERB_EXTREME;
00176     Teuchos::EVerbosityLevel vl = verbLevel;
00177     if (vl == VERB_DEFAULT) vl = VERB_LOW;
00178     RCP<const Comm<int> > comm = this->getComm();
00179     const int myImageID = comm->getRank(),
00180       numImages = comm->getSize();
00181     size_t width = 1;
00182     for (size_t dec=10; dec<getGlobalNumRows(); dec *= 10) {
00183       ++width;
00184     }
00185     width = std::max<size_t>(width,11) + 2;
00186     Teuchos::OSTab tab(out);
00187     //    none: print nothing
00188     //     low: print O(1) info from node 0
00189     //  medium: print O(P) info, num entries per node
00190     //    high: print O(N) info, num entries per row
00191     // extreme: print O(NNZ) info: print indices and values
00192     // 
00193     // for medium and higher, print constituent objects at specified verbLevel
00194     if (vl != VERB_NONE) {
00195       if (myImageID == 0) out << this->description() << std::endl; 
00196       // O(1) globals, minus what was already printed by description()
00197       if (isFillComplete() && myImageID == 0) {
00198         out << "Global number of diagonals = " << getGlobalNumDiags() << std::endl;
00199         out << "Global max number of entries = " << getGlobalMaxNumRowEntries() << std::endl;
00200       }
00201       // constituent objects
00202       if (vl == VERB_MEDIUM || vl == VERB_HIGH || vl == VERB_EXTREME) {
00203         if (myImageID == 0) out << "\nRow map: " << std::endl;
00204         getRowMap()->describe(out,vl);
00205         //
00206         if (getColMap() != null) {
00207           if (getColMap() == getRowMap()) {
00208             if (myImageID == 0) out << "\nColumn map is row map.";
00209           }
00210           else {
00211             if (myImageID == 0) out << "\nColumn map: " << std::endl;
00212             getColMap()->describe(out,vl);
00213           }
00214         }
00215         if (getDomainMap() != null) {
00216           if (getDomainMap() == getRowMap()) {
00217             if (myImageID == 0) out << "\nDomain map is row map.";
00218           }
00219           else if (getDomainMap() == getColMap()) {
00220             if (myImageID == 0) out << "\nDomain map is row map.";
00221           }
00222           else {
00223             if (myImageID == 0) out << "\nDomain map: " << std::endl;
00224             getDomainMap()->describe(out,vl);
00225           }
00226         }
00227         if (getRangeMap() != null) {
00228           if (getRangeMap() == getDomainMap()) {
00229             if (myImageID == 0) out << "\nRange map is domain map." << std::endl;
00230           }
00231           else if (getRangeMap() == getRowMap()) {
00232             if (myImageID == 0) out << "\nRange map is row map." << std::endl;
00233           }
00234           else {
00235             if (myImageID == 0) out << "\nRange map: " << std::endl;
00236             getRangeMap()->describe(out,vl);
00237           }
00238         }
00239         if (myImageID == 0) out << std::endl;
00240       }
00241       // O(P) data
00242       if (vl == VERB_MEDIUM || vl == VERB_HIGH || vl == VERB_EXTREME) {
00243         for (int imageCtr = 0; imageCtr < numImages; ++imageCtr) {
00244           if (myImageID == imageCtr) {
00245             out << "Node ID = " << imageCtr << std::endl;
00246             // TODO: need a graph
00247             //               if (staticGraph_->indicesAreAllocated() == false) {
00248             //                 out << "Node not allocated" << std::endl;
00249             //               }
00250             //               else {
00251             //                 out << "Node number of allocated entries = " << staticGraph_->getNodeAllocationSize() << std::endl;
00252             //               }
00253 
00254             // TMP:
00255             //            const Epetra_CrsGraph & staticGraph_ = mtx_->Graph();
00256             // End of TMP
00257 
00258             out << "Node number of entries = " << getNodeNumEntries() << std::endl;
00259             if (isFillComplete()) {
00260               out << "Node number of diagonals = " << getNodeNumDiags() << std::endl;
00261             }
00262             out << "Node max number of entries = " << getNodeMaxNumRowEntries() << std::endl;
00263           }
00264           comm->barrier();
00265           comm->barrier();
00266           comm->barrier();
00267         }
00268       }
00269       // O(N) and O(NNZ) data
00270       if (vl == VERB_HIGH || vl == VERB_EXTREME) {
00271         for (int imageCtr = 0; imageCtr < numImages; ++imageCtr) {
00272           if (myImageID == imageCtr) {
00273             out << std::setw(width) << "Node ID"
00274                 << std::setw(width) << "Global Row" 
00275                 << std::setw(width) << "Num Entries";
00276             if (vl == VERB_EXTREME) {
00277               out << std::setw(width) << "(Index,Value)";
00278             }
00279             out << std::endl;
00280             for (size_t r=0; r < getNodeNumRows(); ++r) {
00281               const size_t nE = getNumEntriesInLocalRow(r);
00282               GlobalOrdinal gid = getRowMap()->getGlobalElement(r);
00283               out << std::setw(width) << myImageID 
00284                   << std::setw(width) << gid
00285                   << std::setw(width) << nE;
00286               if (vl == VERB_EXTREME) {
00287                 if (isGloballyIndexed()) {
00288                   ArrayView<const GlobalOrdinal> rowinds;
00289                   ArrayView<const Scalar> rowvals;
00290                   getGlobalRowView(gid,rowinds,rowvals);
00291                   for (size_t j=0; j < nE; ++j) {
00292                     out << " (" << rowinds[j]
00293                         << ", " << rowvals[j]
00294                         << ") ";
00295                   }
00296                 }
00297                 else if (isLocallyIndexed()) {
00298                   ArrayView<const LocalOrdinal> rowinds;
00299                   ArrayView<const Scalar> rowvals;
00300                   getLocalRowView(r,rowinds,rowvals);
00301                   for (size_t j=0; j < nE; ++j) {
00302                     out << " (" << getColMap()->getGlobalElement(rowinds[j]) 
00303                         << ", " << rowvals[j]
00304                         << ") ";
00305                   }
00306                 }
00307               }
00308               out << std::endl;
00309             }
00310           }
00311           comm->barrier();
00312           comm->barrier();
00313           comm->barrier();
00314         }
00315       }
00316     }
00317     
00318   }
00319 
00320   // TODO: use toEpetra()    
00321   void EpetraCrsMatrix::doImport(const DistObject<char, int, int> &source, 
00322                                  const Import<int, int> &importer, CombineMode CM) {
00323     XPETRA_MONITOR("EpetraCrsMatrix::doImport");
00324 
00325     XPETRA_DYNAMIC_CAST(const EpetraCrsMatrix, source, tSource, "Xpetra::EpetraCrsMatrix::doImport only accept Xpetra::EpetraCrsMatrix as input arguments.");
00326     XPETRA_DYNAMIC_CAST(const EpetraImport, importer, tImporter, "Xpetra::EpetraCrsMatrix::doImport only accept Xpetra::EpetraImport as input arguments.");
00327 
00328     RCP<const Epetra_CrsMatrix> v = tSource.getEpetra_CrsMatrix();
00329     int err = mtx_->Import(*v, *tImporter.getEpetra_Import(), toEpetra(CM));
00330     TEUCHOS_TEST_FOR_EXCEPTION(err != 0, std::runtime_error, "Catch error code returned by Epetra.");
00331   }
00332 
00333   void EpetraCrsMatrix::doExport(const DistObject<char, int, int> &dest,
00334                                  const Import<int, int>& importer, CombineMode CM) {
00335     XPETRA_MONITOR("EpetraCrsMatrix::doExport");
00336       
00337     XPETRA_DYNAMIC_CAST(const EpetraCrsMatrix, dest, tDest, "Xpetra::EpetraCrsMatrix::doImport only accept Xpetra::EpetraCrsMatrix as input arguments.");
00338     XPETRA_DYNAMIC_CAST(const EpetraImport, importer, tImporter, "Xpetra::EpetraCrsMatrix::doImport only accept Xpetra::EpetraImport as input arguments.");
00339 
00340     RCP<const Epetra_CrsMatrix> v = tDest.getEpetra_CrsMatrix();
00341     int err = mtx_->Export(*v, *tImporter.getEpetra_Import(), toEpetra(CM)); 
00342     TEUCHOS_TEST_FOR_EXCEPTION(err != 0, std::runtime_error, "Catch error code returned by Epetra.");
00343   }
00344 
00345   void EpetraCrsMatrix::doImport(const DistObject<char, int, int> &source,
00346                                  const Export<int, int>& exporter, CombineMode CM) {
00347     XPETRA_MONITOR("EpetraCrsMatrix::doImport");
00348 
00349     XPETRA_DYNAMIC_CAST(const EpetraCrsMatrix, source, tSource, "Xpetra::EpetraCrsMatrix::doImport only accept Xpetra::EpetraCrsMatrix as input arguments.");
00350     XPETRA_DYNAMIC_CAST(const EpetraExport, exporter, tExporter, "Xpetra::EpetraCrsMatrix::doImport only accept Xpetra::EpetraImport as input arguments.");
00351 
00352     RCP<const Epetra_CrsMatrix> v = tSource.getEpetra_CrsMatrix();
00353     int err = mtx_->Import(*v, *tExporter.getEpetra_Export(), toEpetra(CM));
00354     TEUCHOS_TEST_FOR_EXCEPTION(err != 0, std::runtime_error, "Catch error code returned by Epetra.");
00355 
00356   }
00357 
00358   void EpetraCrsMatrix::doExport(const DistObject<char, int, int> &dest,
00359                                  const Export<int, int>& exporter, CombineMode CM) {
00360     XPETRA_MONITOR("EpetraCrsMatrix::doExport");
00361       
00362     XPETRA_DYNAMIC_CAST(const EpetraCrsMatrix, dest, tDest, "Xpetra::EpetraCrsMatrix::doImport only accept Xpetra::EpetraCrsMatrix as input arguments.");
00363     XPETRA_DYNAMIC_CAST(const EpetraExport, exporter, tExporter, "Xpetra::EpetraCrsMatrix::doImport only accept Xpetra::EpetraImport as input arguments.");
00364 
00365     RCP<const Epetra_CrsMatrix> v = tDest.getEpetra_CrsMatrix();
00366     int err = mtx_->Export(*v, *tExporter.getEpetra_Export(), toEpetra(CM)); 
00367     TEUCHOS_TEST_FOR_EXCEPTION(err != 0, std::runtime_error, "Catch error code returned by Epetra.");
00368   }
00369 
00370     void EpetraCrsMatrix::fillComplete(const RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > &domainMap,
00371                                        const RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > &rangeMap,
00372                                        const RCP< ParameterList > &params) {
00373       XPETRA_MONITOR("EpetraCrsMatrix::fillComplete");
00374       bool doOptimizeStorage = true;
00375       if (params != null && params->get("Optimize Storage",true) == false) doOptimizeStorage = false;
00376       mtx_->FillComplete(toEpetra(domainMap), toEpetra(rangeMap), doOptimizeStorage);
00377     }
00378 
00379     void EpetraCrsMatrix::fillComplete(const RCP< ParameterList > &params) {
00380       XPETRA_MONITOR("EpetraCrsMatrix::fillComplete");
00381       bool doOptimizeStorage = true;
00382       if (params != null && params->get("Optimize Storage",true) == false) doOptimizeStorage = false;
00383       mtx_->FillComplete(doOptimizeStorage);
00384     }
00385 
00386 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines