Amesos2 - Direct Sparse Solver Interfaces Version of the Day
Amesos2_EpetraRowMatrix_AbstractMatrixAdapter_def.hpp
Go to the documentation of this file.
00001 // @HEADER
00002 //
00003 // ***********************************************************************
00004 //
00005 //           Amesos2: Templated Direct Sparse Solver Package 
00006 //                  Copyright 2011 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 Michael A. Heroux (maherou@sandia.gov)
00039 //
00040 // ***********************************************************************
00041 //
00042 // @HEADER
00043 
00044 
00053 #ifndef AMESOS2_EPETRAROWMATRIX_ABSTRACTMATRIXADAPTER_DEF_HPP
00054 #define AMESOS2_EPETRAROWMATRIX_ABSTRACTMATRIXADAPTER_DEF_HPP
00055 
00056 #include <Epetra_RowMatrix.h>
00057 #include <Epetra_Map.h>
00058 #include <Epetra_Comm.h>
00059 
00060 #include "Amesos2_EpetraRowMatrix_AbstractMatrixAdapter_decl.hpp"
00061 
00062 
00063 namespace Amesos2 {
00064 
00065   using Teuchos::RCP;
00066   using Teuchos::ArrayView;
00067 
00068   template <class DerivedMat>
00069   AbstractConcreteMatrixAdapter<Epetra_RowMatrix,DerivedMat>::AbstractConcreteMatrixAdapter(RCP<DerivedMat> m)
00070       : MatrixAdapter<DerivedMat>(m)
00071   {
00072     // anything else? probs not
00073   }
00074 
00075   // implementation functions
00076   template <class DerivedMat>
00077   void
00078   AbstractConcreteMatrixAdapter<
00079     Epetra_RowMatrix,
00080     DerivedMat>::getGlobalRowCopy_impl(global_ordinal_t row,
00081                const ArrayView<global_ordinal_t>& indices,
00082                const ArrayView<scalar_t>& vals,
00083                size_t& nnz) const
00084   {
00085     using Teuchos::as;
00086     
00087     local_ordinal_t local_row = this->row_map_->getLocalElement(row);
00088     int nnz_ret = 0;
00089     int rowmatrix_return_val
00090       = this->mat_->ExtractMyRowCopy(as<int>(local_row),
00091              as<int>(std::min(indices.size(), vals.size())),
00092              nnz_ret,
00093              vals.getRawPtr(),
00094              indices.getRawPtr());
00095     TEUCHOS_TEST_FOR_EXCEPTION( rowmatrix_return_val != 0,
00096       std::runtime_error,
00097       "Epetra_RowMatrix object returned error code "
00098       << rowmatrix_return_val << " from ExtractMyRowCopy." );
00099     nnz = as<size_t>(nnz_ret);
00100 
00101     // Epetra_CrsMatrix::ExtractMyRowCopy returns local column
00102     // indices, so transform these into global indices
00103     for( size_t i = 0; i < nnz; ++i ){
00104       indices[i] = this->col_map_->getGlobalElement(indices[i]);
00105     }
00106   }
00107 
00108   template <class DerivedMat>
00109   void
00110   AbstractConcreteMatrixAdapter<
00111     Epetra_RowMatrix,
00112     DerivedMat>::getGlobalColCopy_impl(global_ordinal_t col,
00113                const ArrayView<global_ordinal_t>& indices,
00114                const ArrayView<scalar_t>& vals,
00115                size_t& nnz) const
00116   {
00117     TEUCHOS_TEST_FOR_EXCEPTION( true,
00118       std::runtime_error,
00119       "Column access to row-based object not yet supported.  "
00120       "Please contact the Amesos2 developers." );
00121   }
00122 
00123 
00124   template <class DerivedMat>
00125   typename AbstractConcreteMatrixAdapter<
00126     Epetra_RowMatrix,
00127     DerivedMat>::global_size_t
00128   AbstractConcreteMatrixAdapter<
00129     Epetra_RowMatrix,
00130     DerivedMat>::getGlobalNNZ_impl() const
00131   {
00132     return Teuchos::as<global_size_t>(this->mat_->NumGlobalNonzeros());
00133   }
00134 
00135   template <class DerivedMat>
00136   size_t
00137   AbstractConcreteMatrixAdapter<
00138     Epetra_RowMatrix,
00139     DerivedMat>::getLocalNNZ_impl() const
00140   {
00141     return Teuchos::as<size_t>(this->mat_->NumMyNonzeros());
00142   }
00143 
00144   template <class DerivedMat>
00145   typename AbstractConcreteMatrixAdapter<
00146     Epetra_RowMatrix,
00147     DerivedMat>::global_size_t
00148   AbstractConcreteMatrixAdapter<
00149     Epetra_RowMatrix,
00150     DerivedMat>::getGlobalNumRows_impl() const
00151   {
00152     return Teuchos::as<global_size_t>(this->mat_->NumGlobalRows());
00153   }
00154 
00155   template <class DerivedMat>
00156   typename AbstractConcreteMatrixAdapter<
00157     Epetra_RowMatrix,
00158     DerivedMat>::global_size_t
00159   AbstractConcreteMatrixAdapter<
00160     Epetra_RowMatrix,
00161     DerivedMat>::getGlobalNumCols_impl() const
00162   {
00163     return Teuchos::as<global_size_t>(this->mat_->NumGlobalCols());
00164   }
00165 
00166   template <class DerivedMat>
00167   size_t
00168   AbstractConcreteMatrixAdapter<
00169     Epetra_RowMatrix,
00170     DerivedMat>::getMaxRowNNZ_impl() const
00171   {
00172     return Teuchos::as<size_t>(this->mat_->MaxNumEntries());
00173   }
00174 
00175   template <class DerivedMat>
00176   size_t
00177   AbstractConcreteMatrixAdapter<
00178     Epetra_RowMatrix,
00179     DerivedMat>::getMaxColNNZ_impl() const
00180   {
00181     TEUCHOS_TEST_FOR_EXCEPTION( true,
00182       std::runtime_error,
00183       "Column access to row-based object not yet supported.  "
00184       "Please contact the Amesos2 developers." );
00185     return 0;
00186   }
00187 
00188   template <class DerivedMat>
00189   size_t
00190   AbstractConcreteMatrixAdapter<
00191     Epetra_RowMatrix,
00192     DerivedMat>::getGlobalRowNNZ_impl(global_ordinal_t row) const
00193   {
00194     // check whether row is local, then transform to local index
00195     Epetra_Map rowmap = this->mat_->RowMatrixRowMap();
00196     int gid = Teuchos::as<int>(row);
00197     TEUCHOS_TEST_FOR_EXCEPTION( !rowmap.MyGID(gid),
00198       std::invalid_argument,
00199       "The specified global row id does not belong to me" );
00200     int lid = rowmap.LID(gid);
00201     int nnz = 0;
00202     this->mat_->NumMyRowEntries(lid, nnz);
00203     return nnz;
00204   }
00205 
00206   template <class DerivedMat>
00207   size_t
00208   AbstractConcreteMatrixAdapter<
00209     Epetra_RowMatrix,
00210     DerivedMat>::getLocalRowNNZ_impl(local_ordinal_t row) const
00211   {
00212     Epetra_Map rowmap = this->mat_->RowMatrixRowMap();
00213     int lid = Teuchos::as<int>(row);
00214     TEUCHOS_TEST_FOR_EXCEPTION( !rowmap.MyLID(lid),
00215       std::invalid_argument,
00216       "The specified local row id does not beloing to me" );
00217     int num_entries = 0;
00218     this->mat_->NumMyRowEntries(row, num_entries);
00219     return num_entries;
00220   }
00221 
00222   template <class DerivedMat>
00223   size_t
00224   AbstractConcreteMatrixAdapter<
00225     Epetra_RowMatrix,
00226     DerivedMat>::getGlobalColNNZ_impl(global_ordinal_t col) const
00227   {
00228     TEUCHOS_TEST_FOR_EXCEPTION( true,
00229       std::runtime_error,
00230       "Column access to row-based object not yet supported.  "
00231       "Please contact the Amesos2 developers." );
00232     return 0;
00233   }
00234 
00235   template <class DerivedMat>
00236   size_t
00237   AbstractConcreteMatrixAdapter<
00238     Epetra_RowMatrix,
00239     DerivedMat>::getLocalColNNZ_impl(local_ordinal_t col) const
00240   {
00241     TEUCHOS_TEST_FOR_EXCEPTION( true,
00242       std::runtime_error,
00243       "Column access to row-based object not yet supported.  "
00244       "Please contact the Amesos2 developers." );
00245     return 0;
00246   }
00247 
00248   template <class DerivedMat>
00249   const RCP<const Tpetra::Map<MatrixTraits<Epetra_RowMatrix>::local_ordinal_t,
00250             MatrixTraits<Epetra_RowMatrix>::global_ordinal_t,
00251             MatrixTraits<Epetra_RowMatrix>::node_t> >
00252   AbstractConcreteMatrixAdapter<Epetra_RowMatrix, DerivedMat>::getRowMap_impl() const
00253   {
00254     // Must transform to a Tpetra::Map
00255     const Epetra_Map rowmap = this->mat_->RowMatrixRowMap();
00256     return( Util::epetra_map_to_tpetra_map<local_ordinal_t,global_ordinal_t,global_size_t,node_t>(rowmap) );
00257   }
00258 
00259   template <class DerivedMat>
00260   const RCP<const Tpetra::Map<MatrixTraits<Epetra_RowMatrix>::local_ordinal_t,
00261             MatrixTraits<Epetra_RowMatrix>::global_ordinal_t,
00262             MatrixTraits<Epetra_RowMatrix>::node_t> >
00263   AbstractConcreteMatrixAdapter<Epetra_RowMatrix, DerivedMat>::getColMap_impl() const
00264   {
00265     // Must transform this matrix' Epetra_Map to a Tpetra::Map
00266     const Epetra_Map colmap = this->mat_->RowMatrixColMap();
00267     return( Util::epetra_map_to_tpetra_map<local_ordinal_t,global_ordinal_t,global_size_t,node_t>(colmap) );
00268   }
00269 
00270   template <class DerivedMat>
00271   const RCP<const Teuchos::Comm<int> >
00272   AbstractConcreteMatrixAdapter<Epetra_RowMatrix, DerivedMat>::getComm_impl() const
00273   {
00274     return Util::to_teuchos_comm(Teuchos::rcpFromRef(this->mat_->Comm()));
00275   }
00276 
00277   template <class DerivedMat>
00278   bool
00279   AbstractConcreteMatrixAdapter<Epetra_RowMatrix, DerivedMat>::isLocallyIndexed_impl() const
00280   {
00281     return this->mat_->IndicesAreLocal();
00282   }
00283 
00284   template <class DerivedMat>
00285   bool
00286   AbstractConcreteMatrixAdapter<Epetra_RowMatrix, DerivedMat>::isGloballyIndexed_impl() const
00287   {
00288     return this->mat_->IndicesAreGlobal();
00289   }
00290 
00291   template <class DerivedMat>
00292   RCP<const MatrixAdapter<DerivedMat> >
00293   AbstractConcreteMatrixAdapter<Epetra_RowMatrix, DerivedMat>::get_impl(const Teuchos::Ptr<const Tpetra::Map<local_ordinal_t,global_ordinal_t,node_t> > map) const
00294   {
00295     // Delegate implementation to subclass
00296 #ifdef __CUDACC__
00297     // NVCC doesn't seem to like the static_cast, even though it is valid
00298     return dynamic_cast<ConcreteMatrixAdapter<DerivedMat>*>(this)->get_impl(map);
00299 #else
00300     return static_cast<ConcreteMatrixAdapter<DerivedMat>*>(this)->get_impl(map);
00301 #endif
00302   }
00303 
00304 } // end namespace Amesos2
00305 
00306 #endif  // AMESOS2_EPETRAROWMATRIX_ABSTRACTMATRIXADAPTER_DEF_HPP