Tpetra parallel linear algebra Version of the Day
Loading...
Searching...
No Matches
Tpetra_leftAndOrRightScaleCrsMatrix_def.hpp
Go to the documentation of this file.
1// @HEADER
2// *****************************************************************************
3// Tpetra: Templated Linear Algebra Services Package
4//
5// Copyright 2008 NTESS and the Tpetra contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
10#ifndef TPETRA_LEFTANDORRIGHTSCALECRSMATRIX_DEF_HPP
11#define TPETRA_LEFTANDORRIGHTSCALECRSMATRIX_DEF_HPP
12
19
20#include "Tpetra_CrsMatrix.hpp"
21#include "Tpetra_Vector.hpp"
25#include "Teuchos_TestForException.hpp"
26
27namespace Tpetra {
28
29template<class SC, class LO, class GO, class NT>
30void
32 const Kokkos::View<
33 const typename Kokkos::ArithTraits<SC>::mag_type*,
34 typename NT::device_type>& rowScalingFactors,
35 const Kokkos::View<
36 const typename Kokkos::ArithTraits<SC>::mag_type*,
37 typename NT::device_type>& colScalingFactors,
38 const bool leftScale,
39 const bool rightScale,
40 const bool assumeSymmetric,
41 const EScaling scaling)
42{
43 if (! leftScale && ! rightScale) {
44 return;
45 }
46
47 const bool A_fillComplete_on_input = A.isFillComplete ();
49 // Make sure that A has a valid local matrix. It might not if it
50 // was not created with a local matrix, and if fillComplete has
51 // never been called on it before. A never-initialized (and thus
52 // invalid) local matrix has zero rows, because it was default
53 // constructed.
54 auto A_lcl = A.getLocalMatrixDevice ();
55 const LO lclNumRows =
56 static_cast<LO> (A.getRowMap ()->getLocalNumElements ());
58 (A_lcl.numRows () != lclNumRows, std::invalid_argument,
59 "leftAndOrRightScaleCrsMatrix: Local matrix is not valid. "
60 "This means that A was not created with a local matrix, "
61 "and that fillComplete has never yet been called on A before. "
62 "Please call fillComplete on A at least once first "
63 "before calling this method.");
64 }
65 else {
66 A.resumeFill ();
67 }
68
69 const bool divide = scaling == SCALING_DIVIDE;
70 if (leftScale) {
71 Details::leftScaleLocalCrsMatrix (A.getLocalMatrixDevice (),
73 assumeSymmetric,
74 divide);
75 }
76 if (rightScale) {
77 Details::rightScaleLocalCrsMatrix (A.getLocalMatrixDevice (),
79 assumeSymmetric,
80 divide);
81 }
82
83 if (A_fillComplete_on_input) { // put A back how we found it
84 Teuchos::RCP<Teuchos::ParameterList> params = Teuchos::parameterList ();
85 params->set ("No Nonlocal Changes", true);
86 A.fillComplete (A.getDomainMap (), A.getRangeMap (), params);
87 }
88}
89
90template<class SC, class LO, class GO, class NT>
91void
93 const Tpetra::Vector<
94 typename Kokkos::ArithTraits<SC>::mag_type,
95 LO, GO, NT>& rowScalingFactors,
96 const Tpetra::Vector<
97 typename Kokkos::ArithTraits<SC>::mag_type,
98 LO, GO, NT>& colScalingFactors,
99 const bool leftScale,
100 const bool rightScale,
101 const bool assumeSymmetric,
102 const EScaling scaling)
103{
104 using device_type = typename NT::device_type;
105 using dev_memory_space = typename device_type::memory_space;
106 using mag_type = typename Kokkos::ArithTraits<SC>::mag_type;
107 const char prefix[] = "leftAndOrRightScaleCrsMatrix: ";
108 const bool debug = ::Tpetra::Details::Behavior::debug ();
109
110 Kokkos::View<const mag_type*, device_type> row_lcl;
111 Kokkos::View<const mag_type*, device_type> col_lcl;
112 if (leftScale) {
113 if (debug) {
114 const bool same = rowScalingFactors.getMap ()->isSameAs (* (A.getRowMap ()));
116 (! same, std::invalid_argument, prefix << "rowScalingFactors's Map "
117 "must be the same as the CrsMatrix's row Map. If you see this "
118 "message, it's likely that you are using a range Map Vector and that "
119 "the CrsMatrix's row Map is overlapping.");
120 }
121 // if (rowScalingFactors.template need_sync<dev_memory_space> ()) {
122 // const_cast<vec_type&> (rowScalingFactors).template sync<dev_memory_space> ();
123 // }
124 auto row_lcl_2d = rowScalingFactors.template getLocalView<dev_memory_space> (Access::ReadOnly);
125 row_lcl = Kokkos::subview (row_lcl_2d, Kokkos::ALL (), 0);
126 }
127 if (rightScale) {
128 if (debug) {
129 const bool same = colScalingFactors.getMap ()->isSameAs (* (A.getColMap ()));
131 (! same, std::invalid_argument, prefix << "colScalingFactors's Map "
132 "must be the same as the CrsMatrix's column Map. If you see this "
133 "message, it's likely that you are using a domain Map Vector.");
134 }
135 // if (colScalingFactors.template need_sync<dev_memory_space> ()) {
136 // const_cast<vec_type&> (colScalingFactors).template sync<dev_memory_space> ();
137 // }
138 auto col_lcl_2d = colScalingFactors.template getLocalView<dev_memory_space> (Access::ReadOnly);
139 col_lcl = Kokkos::subview (col_lcl_2d, Kokkos::ALL (), 0);
140 }
141
142 leftAndOrRightScaleCrsMatrix (A, row_lcl, col_lcl, leftScale, rightScale,
143 assumeSymmetric, scaling);
144}
145
146} // namespace Tpetra
147
148//
149// Explicit instantiation macro
150//
151// Must be expanded from within the Tpetra namespace!
152//
153
154#define TPETRA_LEFTANDORRIGHTSCALECRSMATRIX_INSTANT(SC,LO,GO,NT) \
155 template void \
156 leftAndOrRightScaleCrsMatrix ( \
157 Tpetra::CrsMatrix<SC, LO, GO, NT>& A, \
158 const Kokkos::View< \
159 const Kokkos::ArithTraits<SC>::mag_type*, \
160 NT::device_type>& rowScalingFactors, \
161 const Kokkos::View< \
162 const Kokkos::ArithTraits<SC>::mag_type*, \
163 NT::device_type>& colScalingFactors, \
164 const bool leftScale, \
165 const bool rightScale, \
166 const bool assumeSymmetric, \
167 const EScaling scaling); \
168 \
169 template void \
170 leftAndOrRightScaleCrsMatrix ( \
171 Tpetra::CrsMatrix<SC, LO, GO, NT>& A, \
172 const Tpetra::Vector<Kokkos::ArithTraits<SC>::mag_type, LO, GO, NT>& rowScalingFactors, \
173 const Tpetra::Vector<Kokkos::ArithTraits<SC>::mag_type, LO, GO, NT>& colScalingFactors, \
174 const bool leftScale, \
175 const bool rightScale, \
176 const bool assumeSymmetric, \
177 const EScaling scaling);
178
179#endif // TPETRA_LEFTANDORRIGHTSCALECRSMATRIX_DEF_HPP
Declaration of Tpetra::Details::Behavior, a class that describes Tpetra's behavior.
Declaration and definition of Tpetra::Details::leftScaleLocalCrsMatrix.
Declaration and definition of Tpetra::Details::rightScaleLocalCrsMatrix.
Struct that holds views of the contents of a CrsMatrix.
static bool debug()
Whether Tpetra is in debug mode.
A distributed dense vector.
void leftScaleLocalCrsMatrix(const LocalSparseMatrixType &A_lcl, const ScalingFactorsViewType &scalingFactors, const bool assumeSymmetric, const bool divide=true)
Left-scale a KokkosSparse::CrsMatrix.
void rightScaleLocalCrsMatrix(const LocalSparseMatrixType &A_lcl, const ScalingFactorsViewType &scalingFactors, const bool assumeSymmetric, const bool divide=true)
Right-scale a KokkosSparse::CrsMatrix.
Namespace Tpetra contains the class and methods constituting the Tpetra library.
EScaling
Whether "scaling" a matrix means multiplying or dividing its entries.
void leftAndOrRightScaleCrsMatrix(Tpetra::CrsMatrix< SC, LO, GO, NT > &A, const Kokkos::View< const typename Kokkos::ArithTraits< SC >::mag_type *, typename NT::device_type > &rowScalingFactors, const Kokkos::View< const typename Kokkos::ArithTraits< SC >::mag_type *, typename NT::device_type > &colScalingFactors, const bool leftScale, const bool rightScale, const bool assumeSymmetric, const EScaling scaling)
Left-scale and/or right-scale (in that order) the entries of the input Tpetra::CrsMatrix A.