10#ifndef TPETRA_DETAILS_GETDIAGCOPYWITHOUTOFFSETS_DEF_HPP
11#define TPETRA_DETAILS_GETDIAGCOPYWITHOUTOFFSETS_DEF_HPP
22#include "Tpetra_RowGraph.hpp"
23#include "Tpetra_CrsGraph.hpp"
24#include "Tpetra_RowMatrix.hpp"
25#include "Tpetra_Vector.hpp"
38template <
class SC,
class LO,
class GO,
class NT>
39class GetLocalDiagCopyWithoutOffsetsNotFillCompleteFunctor {
41 using row_matrix_type = ::Tpetra::RowMatrix<SC, LO, GO, NT>;
42 using vec_type = ::Tpetra::Vector<SC, LO, GO, NT>;
53 graphIsSorted(
const row_matrix_type& A) {
55 using Teuchos::rcp_dynamic_cast;
56 using crs_graph_type = Tpetra::CrsGraph<LO, GO, NT>;
57 using row_graph_type = Tpetra::RowGraph<LO, GO, NT>;
64 RCP<const row_graph_type> G_row = A.getGraph();
65 if (!G_row.is_null()) {
66 RCP<const crs_graph_type> G_crs =
67 rcp_dynamic_cast<const crs_graph_type>(G_row);
68 if (!G_crs.is_null()) {
69 sorted = G_crs->isSorted();
78 GetLocalDiagCopyWithoutOffsetsNotFillCompleteFunctor(LO& lclNumErrs,
80 const row_matrix_type& A)
82 , lclRowMap_(*A.getRowMap())
83 , lclColMap_(*A.getColMap())
84 , sorted_(graphIsSorted(A)) {
85 const LO lclNumRows =
static_cast<LO
>(diag.getLocalLength());
87 const LO matLclNumRows =
88 static_cast<LO
>(lclRowMap_.getLocalNumElements());
89 TEUCHOS_TEST_FOR_EXCEPTION(lclNumRows != matLclNumRows, std::invalid_argument,
90 "diag.getLocalLength() = " << lclNumRows <<
" != "
91 "A.getRowMap()->getLocalNumElements() = "
92 << matLclNumRows <<
".");
96 D_lcl_ = diag.getLocalViewHost(Access::OverwriteAll);
97 D_lcl_1d_ = Kokkos::subview(D_lcl_, Kokkos::ALL(), 0);
99 Kokkos::RangePolicy<host_execution_space, LO> range(0, lclNumRows);
101 Kokkos::parallel_reduce(range, *
this, lclNumErrs);
108 void operator()(
const LO& lclRowInd, LO& errCount)
const {
109 using KokkosSparse::findRelOffset;
111 D_lcl_1d_(lclRowInd) = KokkosKernels::ArithTraits<IST>::zero();
112 const GO gblInd = lclRowMap_.getGlobalElement(lclRowInd);
113 const LO lclColInd = lclColMap_.getLocalElement(gblInd);
115 if (lclColInd == Tpetra::Details::OrdinalTraits<LO>::invalid()) {
118 typename row_matrix_type::local_inds_host_view_type lclColInds;
119 typename row_matrix_type::values_host_view_type curVals;
120 A_.getLocalRowView(lclRowInd, lclColInds, curVals);
121 LO numEnt = lclColInds.extent(0);
126 findRelOffset(lclColInds, numEnt, lclColInd, hint, sorted_);
127 if (offset == numEnt) {
130 D_lcl_1d_(lclRowInd) = curVals[offset];
136 const row_matrix_type& A_;
139 typename vec_type::dual_view_type::t_host D_lcl_;
140 decltype(Kokkos::subview(D_lcl_, Kokkos::ALL(), 0)) D_lcl_1d_;
144template <
class SC,
class LO,
class GO,
class NT>
146 const ::Tpetra::RowMatrix<SC, LO, GO, NT>& A,
148 using Teuchos::outArg;
149 using Teuchos::REDUCE_MIN;
150 using Teuchos::reduceAll;
152 using functor_type = GetLocalDiagCopyWithoutOffsetsNotFillCompleteFunctor<SC, LO, GO, NT>;
162 std::ostringstream errStrm;
163 Teuchos::RCP<const Teuchos::Comm<int> > commPtr = A.getComm();
164 if (commPtr.is_null()) {
167 const Teuchos::Comm<int>& comm = *commPtr;
170 functor_type functor(lclNumErrs, diag, A);
171 }
catch (std::exception& e) {
173 errStrm <<
"Process " << A.getComm()->getRank() <<
": "
174 << e.what() << std::endl;
176 if (lclNumErrs != 0) {
180 reduceAll<int, int>(comm, REDUCE_MIN, lclSuccess, outArg(gblSuccess));
181 if (gblSuccess == -1) {
182 if (comm.getRank() == 0) {
190 std::cerr <<
"getLocalDiagCopyWithoutOffsetsNotFillComplete threw an "
191 "exception on one or more MPI processes in the matrix's comunicator."
197 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::runtime_error,
"");
198 }
else if (gblSuccess == 0) {
199 TEUCHOS_TEST_FOR_EXCEPTION(gblSuccess != 1, std::runtime_error,
200 "getLocalDiagCopyWithoutOffsetsNotFillComplete failed on "
201 "one or more MPI processes in the matrix's communicator.");
204 functor_type functor(lclNumErrs, diag, A);
216#define TPETRA_DETAILS_GETDIAGCOPYWITHOUTOFFSETS_INSTANT(SCALAR, LO, GO, NODE) \
218 Details::getLocalDiagCopyWithoutOffsetsNotFillComplete<SCALAR, LO, GO, NODE>(::Tpetra::Vector<SCALAR, LO, GO, NODE> & diag, \
219 const ::Tpetra::RowMatrix<SCALAR, LO, GO, NODE>& A, \
Declaration of a function that prints strings from each process.
typename device_type::execution_space execution_space
A distributed dense vector.
base_type::impl_scalar_type impl_scalar_type
base_type::map_type map_type
Nonmember function that computes a residual Computes R = B - A * X.
LO getLocalDiagCopyWithoutOffsetsNotFillComplete(::Tpetra::Vector< SC, LO, GO, NT > &diag, const ::Tpetra::RowMatrix< SC, LO, GO, NT > &A, const bool debug=false)
Given a locally indexed, global sparse matrix, extract the matrix's diagonal entries into a Tpetra::V...
void gathervPrint(std::ostream &out, const std::string &s, const Teuchos::Comm< int > &comm)
On Process 0 in the given communicator, print strings from each process in that communicator,...
Namespace Tpetra contains the class and methods constituting the Tpetra library.