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"
38 template <
class SC,
class LO,
class GO,
class NT>
39 class GetLocalDiagCopyWithoutOffsetsNotFillCompleteFunctor {
47 using host_execution_space =
typename vec_type::dual_view_type::t_host::execution_space;
53 graphIsSorted(
const row_matrix_type& A) {
55 using Teuchos::rcp_dynamic_cast;
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 #if KOKKOS_VERSION >= 40799
112 D_lcl_1d_(lclRowInd) = KokkosKernels::ArithTraits<IST>::zero();
114 D_lcl_1d_(lclRowInd) = Kokkos::ArithTraits<IST>::zero();
116 const GO gblInd = lclRowMap_.getGlobalElement(lclRowInd);
117 const LO lclColInd = lclColMap_.getLocalElement(gblInd);
119 if (lclColInd == Tpetra::Details::OrdinalTraits<LO>::invalid()) {
122 typename row_matrix_type::local_inds_host_view_type lclColInds;
123 typename row_matrix_type::values_host_view_type curVals;
124 A_.getLocalRowView(lclRowInd, lclColInds, curVals);
125 LO numEnt = lclColInds.extent(0);
130 findRelOffset(lclColInds, numEnt, lclColInd, hint, sorted_);
131 if (offset == numEnt) {
134 D_lcl_1d_(lclRowInd) = curVals[offset];
140 const row_matrix_type& A_;
143 typename vec_type::dual_view_type::t_host D_lcl_;
144 decltype(Kokkos::subview(D_lcl_, Kokkos::ALL(), 0)) D_lcl_1d_;
148 template <class SC, class LO, class GO, class NT>
150 const ::Tpetra::
RowMatrix<SC, LO, GO, NT>& A,
152 using Teuchos::outArg;
153 using Teuchos::REDUCE_MIN;
154 using Teuchos::reduceAll;
155 using ::Tpetra::Details::gathervPrint;
156 using functor_type = GetLocalDiagCopyWithoutOffsetsNotFillCompleteFunctor<SC, LO, GO, NT>;
166 std::ostringstream errStrm;
167 Teuchos::RCP<const Teuchos::Comm<int> > commPtr = A.getComm();
168 if (commPtr.is_null()) {
171 const Teuchos::Comm<int>& comm = *commPtr;
174 functor_type functor(lclNumErrs, diag, A);
175 }
catch (std::exception& e) {
177 errStrm <<
"Process " << A.getComm()->getRank() <<
": "
178 << e.what() << std::endl;
180 if (lclNumErrs != 0) {
184 reduceAll<int, int>(comm, REDUCE_MIN, lclSuccess, outArg(gblSuccess));
185 if (gblSuccess == -1) {
186 if (comm.getRank() == 0) {
194 std::cerr <<
"getLocalDiagCopyWithoutOffsetsNotFillComplete threw an "
195 "exception on one or more MPI processes in the matrix's comunicator."
201 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::runtime_error,
"");
202 }
else if (gblSuccess == 0) {
203 TEUCHOS_TEST_FOR_EXCEPTION(gblSuccess != 1, std::runtime_error,
204 "getLocalDiagCopyWithoutOffsetsNotFillComplete failed on "
205 "one or more MPI processes in the matrix's communicator.");
208 functor_type functor(lclNumErrs, diag, A);
220 #define TPETRA_DETAILS_GETDIAGCOPYWITHOUTOFFSETS_INSTANT(SCALAR, LO, GO, NODE) \
222 Details::getLocalDiagCopyWithoutOffsetsNotFillComplete<SCALAR, LO, GO, NODE>(::Tpetra::Vector<SCALAR, LO, GO, NODE> & diag, \
223 const ::Tpetra::RowMatrix<SCALAR, LO, GO, NODE>& A, \
226 #endif // TPETRA_DETAILS_GETDIAGCOPYWITHOUTOFFSETS_DEF_HPP
An abstract interface for graphs accessed by rows.
base_type::impl_scalar_type impl_scalar_type
The type used internally in place of Scalar.
Declaration of a function that prints strings from each process.
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, in rank order.
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...
A distributed graph accessed by rows (adjacency lists) and stored sparsely.
A read-only, row-oriented interface to a sparse matrix.
A distributed dense vector.
base_type::map_type map_type
The type of the Map specialization used by this class.