Tpetra parallel linear algebra  Version of the Day
Tpetra_leftAndOrRightScaleCrsMatrix_def.hpp
Go to the documentation of this file.
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Tpetra: Templated Linear Algebra Services Package
5 // Copyright (2008) Sandia Corporation
6 //
7 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
8 // the U.S. Government retains certain rights in this software.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
38 //
39 // ************************************************************************
40 // @HEADER
41 
42 #ifndef TPETRA_LEFTANDORRIGHTSCALECRSMATRIX_DEF_HPP
43 #define TPETRA_LEFTANDORRIGHTSCALECRSMATRIX_DEF_HPP
44 
51 
52 #include "Tpetra_CrsMatrix.hpp"
53 #include "Tpetra_Vector.hpp"
55 #include "Tpetra_Details_leftScaleLocalCrsMatrix.hpp"
56 #include "Tpetra_Details_rightScaleLocalCrsMatrix.hpp"
57 #include "Teuchos_TestForException.hpp"
58 
59 namespace Tpetra {
60 
61 template<class SC, class LO, class GO, class NT>
62 void
64  const Kokkos::View<
65  const typename Kokkos::ArithTraits<SC>::mag_type*,
66  typename NT::device_type>& rowScalingFactors,
67  const Kokkos::View<
68  const typename Kokkos::ArithTraits<SC>::mag_type*,
69  typename NT::device_type>& colScalingFactors,
70  const bool leftScale,
71  const bool rightScale,
72  const bool assumeSymmetric,
73  const EScaling scaling)
74 {
75  if (! leftScale && ! rightScale) {
76  return;
77  }
78 
79  const bool A_fillComplete_on_input = A.isFillComplete ();
80  if (! A_fillComplete_on_input) {
81  // Make sure that A has a valid local matrix. It might not if it
82  // was not created with a local matrix, and if fillComplete has
83  // never been called on it before. A never-initialized (and thus
84  // invalid) local matrix has zero rows, because it was default
85  // constructed.
86  auto A_lcl = A.getLocalMatrix ();
87  const LO lclNumRows =
88  static_cast<LO> (A.getRowMap ()->getNodeNumElements ());
89  TEUCHOS_TEST_FOR_EXCEPTION
90  (A_lcl.numRows () != lclNumRows, std::invalid_argument,
91  "leftAndOrRightScaleCrsMatrix: Local matrix is not valid. "
92  "This means that A was not created with a local matrix, "
93  "and that fillComplete has never yet been called on A before. "
94  "Please call fillComplete on A at least once first "
95  "before calling this method.");
96  }
97  else {
98  A.resumeFill ();
99  }
100 
101  const bool divide = scaling == SCALING_DIVIDE;
102  if (leftScale) {
104  rowScalingFactors,
105  assumeSymmetric,
106  divide);
107  }
108  if (rightScale) {
110  colScalingFactors,
111  assumeSymmetric,
112  divide);
113  }
114 
115  if (A_fillComplete_on_input) { // put A back how we found it
116  Teuchos::RCP<Teuchos::ParameterList> params = Teuchos::parameterList ();
117  params->set ("No Nonlocal Changes", true);
118  A.fillComplete (A.getDomainMap (), A.getRangeMap (), params);
119  }
120 }
121 
122 template<class SC, class LO, class GO, class NT>
123 void
125  const Tpetra::Vector<
126  typename Kokkos::ArithTraits<SC>::mag_type,
127  LO, GO, NT>& rowScalingFactors,
128  const Tpetra::Vector<
129  typename Kokkos::ArithTraits<SC>::mag_type,
130  LO, GO, NT>& colScalingFactors,
131  const bool leftScale,
132  const bool rightScale,
133  const bool assumeSymmetric,
134  const EScaling scaling)
135 {
136  using device_type = typename NT::device_type;
137  using dev_memory_space = typename device_type::memory_space;
138  using mag_type = typename Kokkos::ArithTraits<SC>::mag_type;
139  using vec_type = Tpetra::Vector<mag_type, LO, GO, NT>;
140  const char prefix[] = "leftAndOrRightScaleCrsMatrix: ";
141  const bool debug = ::Tpetra::Details::Behavior::debug ();
142 
143  Kokkos::View<const mag_type*, device_type> row_lcl;
144  Kokkos::View<const mag_type*, device_type> col_lcl;
145  if (leftScale) {
146  if (debug) {
147  const bool same = rowScalingFactors.getMap ()->isSameAs (* (A.getRowMap ()));
148  TEUCHOS_TEST_FOR_EXCEPTION
149  (! same, std::invalid_argument, prefix << "rowScalingFactors's Map "
150  "must be the same as the CrsMatrix's row Map. If you see this "
151  "message, it's likely that you are using a range Map Vector and that "
152  "the CrsMatrix's row Map is overlapping.");
153  }
154  if (rowScalingFactors.template need_sync<dev_memory_space> ()) {
155  const_cast<vec_type&> (rowScalingFactors).template sync<dev_memory_space> ();
156  }
157  auto row_lcl_2d = rowScalingFactors.template getLocalView<dev_memory_space> ();
158  row_lcl = Kokkos::subview (row_lcl_2d, Kokkos::ALL (), 0);
159  }
160  if (rightScale) {
161  if (debug) {
162  const bool same = colScalingFactors.getMap ()->isSameAs (* (A.getColMap ()));
163  TEUCHOS_TEST_FOR_EXCEPTION
164  (! same, std::invalid_argument, prefix << "colScalingFactors's Map "
165  "must be the same as the CrsMatrix's column Map. If you see this "
166  "message, it's likely that you are using a domain Map Vector.");
167  }
168  if (colScalingFactors.template need_sync<dev_memory_space> ()) {
169  const_cast<vec_type&> (colScalingFactors).template sync<dev_memory_space> ();
170  }
171  auto col_lcl_2d = colScalingFactors.template getLocalView<dev_memory_space> ();
172  col_lcl = Kokkos::subview (col_lcl_2d, Kokkos::ALL (), 0);
173  }
174 
175  leftAndOrRightScaleCrsMatrix (A, row_lcl, col_lcl, leftScale, rightScale,
176  assumeSymmetric, scaling);
177 }
178 
179 } // namespace Tpetra
180 
181 //
182 // Explicit instantiation macro
183 //
184 // Must be expanded from within the Tpetra namespace!
185 //
186 
187 #define TPETRA_LEFTANDORRIGHTSCALECRSMATRIX_INSTANT(SC,LO,GO,NT) \
188  template void \
189  leftAndOrRightScaleCrsMatrix ( \
190  Tpetra::CrsMatrix<SC, LO, GO, NT>& A, \
191  const Kokkos::View< \
192  const Kokkos::ArithTraits<SC>::mag_type*, \
193  NT::device_type>& rowScalingFactors, \
194  const Kokkos::View< \
195  const Kokkos::ArithTraits<SC>::mag_type*, \
196  NT::device_type>& colScalingFactors, \
197  const bool leftScale, \
198  const bool rightScale, \
199  const bool assumeSymmetric, \
200  const EScaling scaling); \
201  \
202  template void \
203  leftAndOrRightScaleCrsMatrix ( \
204  Tpetra::CrsMatrix<SC, LO, GO, NT>& A, \
205  const Tpetra::Vector<Kokkos::ArithTraits<SC>::mag_type, LO, GO, NT>& rowScalingFactors, \
206  const Tpetra::Vector<Kokkos::ArithTraits<SC>::mag_type, LO, GO, NT>& colScalingFactors, \
207  const bool leftScale, \
208  const bool rightScale, \
209  const bool assumeSymmetric, \
210  const EScaling scaling);
211 
212 #endif // TPETRA_LEFTANDORRIGHTSCALECRSMATRIX_DEF_HPP
Declaration of Tpetra::Details::Behavior, a class that describes Tpetra's behavior.
Teuchos::RCP< const map_type > getDomainMap() const override
The domain Map of this matrix.
Teuchos::RCP< const map_type > getRangeMap() const override
The range Map of this matrix.
Teuchos::RCP< const map_type > getColMap() const override
The Map that describes the column distribution in this matrix.
void fillComplete(const Teuchos::RCP< const map_type > &domainMap, const Teuchos::RCP< const map_type > &rangeMap, const Teuchos::RCP< Teuchos::ParameterList > &params=Teuchos::null)
Tell the matrix that you are done changing its structure or values, and that you are ready to do comp...
bool isFillComplete() const override
Whether the matrix is fill complete.
Teuchos::RCP< const map_type > getRowMap() const override
The Map that describes the row distribution in this matrix.
void resumeFill(const Teuchos::RCP< Teuchos::ParameterList > &params=Teuchos::null)
Resume operations that may change the values or structure of the matrix.
local_matrix_type getLocalMatrix() const
The local sparse matrix.
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.