|
Tpetra Matrix/Vector Services
Version of the Day
|
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_ROWMATRIXTRANSPOSER_DEF_HPP 00043 #define TPETRA_ROWMATRIXTRANSPOSER_DEF_HPP 00044 00045 #include "Tpetra_Export.hpp" 00046 #include "Tpetra_Import.hpp" 00047 #include "Tpetra_Map.hpp" 00048 #include "Teuchos_DefaultSerialComm.hpp" 00049 #ifdef DOXYGEN_USE_ONLY 00050 // #include "Tpetra_RowMatrixtransposer_decl.hpp" 00051 #endif 00052 00053 namespace Tpetra { 00054 00055 template<class Scalar, 00056 class LocalOrdinal, 00057 class GlobalOrdinal, 00058 class Node> 00059 RowMatrixTransposer<Scalar, LocalOrdinal, GlobalOrdinal, Node>:: 00060 RowMatrixTransposer (const Teuchos::RCP<const crs_matrix_type>& origMatrix) 00061 : origMatrix_ (origMatrix) {} 00062 00063 template<class Scalar, 00064 class LocalOrdinal, 00065 class GlobalOrdinal, 00066 class Node> 00067 TEUCHOS_DEPRECATED 00068 RowMatrixTransposer<Scalar, LocalOrdinal, GlobalOrdinal, Node>:: 00069 RowMatrixTransposer (const crs_matrix_type& origMatrix) 00070 : origMatrix_ (Teuchos::rcpFromRef (origMatrix)) {} 00071 00072 template<class Scalar, 00073 class LocalOrdinal, 00074 class GlobalOrdinal, 00075 class Node> 00076 Teuchos::RCP<CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> > 00077 RowMatrixTransposer<Scalar, LocalOrdinal, GlobalOrdinal, Node>:: 00078 createTranspose() 00079 { 00080 using Teuchos::RCP; 00081 00082 // Do the local transpose 00083 RCP<crs_matrix_type> transMatrixWithSharedRows = createTransposeLocal (); 00084 00085 // If transMatrixWithSharedRows has an exporter, that's what we 00086 // want. If it doesn't, the rows aren't actually shared, and we're 00087 // done! 00088 RCP<const Export<LocalOrdinal,GlobalOrdinal,Node> > exporter = 00089 transMatrixWithSharedRows->getGraph ()->getExporter (); 00090 if (exporter.is_null ()) { 00091 return transMatrixWithSharedRows; 00092 } 00093 else { 00094 // Use the Export object to do a fused Export and fillComplete. 00095 return exportAndFillCompleteCrsMatrix<crs_matrix_type> (transMatrixWithSharedRows, *exporter); 00096 } 00097 } 00098 00099 00100 // mfh 03 Feb 2013: In a definition outside the class like this, the 00101 // return value is considered outside the class scope (for things like 00102 // resolving typedefs), but the arguments are considered inside the 00103 // class scope. 00104 template<class Scalar, 00105 class LocalOrdinal, 00106 class GlobalOrdinal, 00107 class Node> 00108 Teuchos::RCP<CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> > 00109 RowMatrixTransposer<Scalar, LocalOrdinal, GlobalOrdinal, Node>:: 00110 createTransposeLocal () 00111 { 00112 using Teuchos::Array; 00113 using Teuchos::ArrayRCP; 00114 using Teuchos::ArrayView; 00115 using Teuchos::RCP; 00116 using Teuchos::rcp; 00117 using Teuchos::rcp_dynamic_cast; 00118 typedef LocalOrdinal LO; 00119 typedef GlobalOrdinal GO; 00120 typedef Tpetra::Import<LO, GO, Node> import_type; 00121 typedef Tpetra::Export<LO, GO, Node> export_type; 00122 00123 // 00124 // This transpose is based upon the approach in EpetraExt. 00125 // 00126 size_t numLocalCols = origMatrix_->getNodeNumCols(); 00127 size_t numLocalRows = origMatrix_->getNodeNumRows(); 00128 size_t numLocalNnz = origMatrix_->getNodeNumEntries(); 00129 00130 // Determine how many nonzeros there are per row in the transpose. 00131 Array<size_t> CurrentStart(numLocalCols,0); 00132 ArrayView<const LO> localIndices; 00133 ArrayView<const Scalar> localValues; 00134 RCP<const crs_matrix_type> crsMatrix = 00135 rcp_dynamic_cast<const crs_matrix_type> (origMatrix_); 00136 if (crsMatrix == Teuchos::null) { 00137 for (size_t i=0; i<numLocalRows; ++i) { 00138 const size_t numEntriesInRow = origMatrix_->getNumEntriesInLocalRow(i); 00139 origMatrix_->getLocalRowView(i, localIndices, localValues); 00140 for (size_t j=0; j<numEntriesInRow; ++j) { 00141 ++CurrentStart[ localIndices[j] ]; 00142 } 00143 } 00144 } else { 00145 ArrayRCP<const size_t> origRowPtr_rcp; 00146 ArrayRCP<const LO> origColInd_rcp; 00147 ArrayRCP<const Scalar> origValues_rcp; 00148 crsMatrix->getAllValues(origRowPtr_rcp, origColInd_rcp, origValues_rcp); 00149 ArrayView<const LO> origColInd = origColInd_rcp(); 00150 for (LO j=0; j<origColInd.size(); ++j) { 00151 ++CurrentStart[ origColInd[j] ]; 00152 } 00153 } 00154 00155 // create temporary row-major storage for the transposed matrix 00156 00157 ArrayRCP<size_t> rowptr_rcp(numLocalCols+1); 00158 ArrayRCP<LO> colind_rcp(numLocalNnz); 00159 ArrayRCP<Scalar> values_rcp(numLocalNnz); 00160 00161 // Since ArrayRCP's are slow... 00162 ArrayView<size_t> TransRowptr = rowptr_rcp(); 00163 ArrayView<LO> TransColind = colind_rcp(); 00164 ArrayView<Scalar> TransValues = values_rcp(); 00165 00166 // Scansum the TransRowptr; reset CurrentStart 00167 TransRowptr[0]=0; 00168 for (size_t i=1; i<numLocalCols+1; ++i) TransRowptr[i] = CurrentStart[i-1] + TransRowptr[i-1]; 00169 for (size_t i=0; i<numLocalCols; ++i) CurrentStart[i] = TransRowptr[i]; 00170 00171 // populate the row-major storage so that the data for the transposed 00172 // matrix is easy to access 00173 if (crsMatrix == Teuchos::null) { 00174 for (size_t i=0; i<numLocalRows; ++i) { 00175 const size_t numEntriesInRow = origMatrix_->getNumEntriesInLocalRow (i); 00176 origMatrix_->getLocalRowView(i, localIndices, localValues); 00177 00178 for (size_t j=0; j<numEntriesInRow; ++j) { 00179 size_t idx = CurrentStart[localIndices[j]]; 00180 TransColind[idx] = Teuchos::as<LO>(i); 00181 TransValues[idx] = localValues[j]; 00182 ++CurrentStart[localIndices[j]]; 00183 } 00184 } //for (size_t i=0; i<numLocalRows; ++i) 00185 } else { 00186 ArrayRCP<const size_t> origRowPtr_rcp; 00187 ArrayRCP<const LO> origColInd_rcp; 00188 ArrayRCP<const Scalar> origValues_rcp; 00189 crsMatrix->getAllValues(origRowPtr_rcp, origColInd_rcp, origValues_rcp); 00190 ArrayView<const size_t> origRowPtr = origRowPtr_rcp(); 00191 ArrayView<const LO> origColInd = origColInd_rcp(); 00192 ArrayView<const Scalar> origValues = origValues_rcp(); 00193 size_t k=0; 00194 for (LO i=0; i<origRowPtr.size()-1; ++i) { 00195 const LO rowIndex = Teuchos::as<LO>(i); 00196 for (size_t j=origRowPtr[i]; j<origRowPtr[i+1]; ++j) { 00197 size_t idx = CurrentStart[origColInd[k]]; 00198 TransColind[idx] = rowIndex; 00199 TransValues[idx] = origValues[k]; 00200 ++CurrentStart[origColInd[k++]]; 00201 } 00202 } 00203 } 00204 00205 //Allocate and populate temporary matrix with rows not uniquely owned 00206 RCP<crs_matrix_type> transMatrixWithSharedRows = 00207 rcp (new crs_matrix_type (origMatrix_->getColMap (), 00208 origMatrix_->getRowMap (), 0)); 00209 transMatrixWithSharedRows->setAllValues (rowptr_rcp, colind_rcp, values_rcp); 00210 00211 // Prebuild the importers and exporters the no-communication way, 00212 // flipping the importers and exporters around. 00213 RCP<const import_type> myImport; 00214 RCP<const export_type> myExport; 00215 if (! origMatrix_->getGraph ()->getImporter ().is_null ()) { 00216 myExport = rcp (new export_type (*origMatrix_->getGraph ()->getImporter ())); 00217 } 00218 if (! origMatrix_->getGraph ()->getExporter ().is_null ()) { 00219 myImport = rcp (new import_type (*origMatrix_->getGraph ()->getExporter ())); 00220 } 00221 00222 // Call ESFC & return 00223 transMatrixWithSharedRows->expertStaticFillComplete (origMatrix_->getRangeMap (), 00224 origMatrix_->getDomainMap (), 00225 myImport, myExport); 00226 return transMatrixWithSharedRows; 00227 } 00228 // 00229 // Explicit instantiation macro 00230 // 00231 // Must be expanded from within the Tpetra namespace! 00232 // 00233 00234 #define TPETRA_ROWMATRIXTRANSPOSER_INSTANT(SCALAR,LO,GO,NODE) \ 00235 \ 00236 template class RowMatrixTransposer< SCALAR, LO , GO , NODE >; 00237 00238 00239 } 00240 00241 #endif
1.7.6.1