Ifpack2 Templated Preconditioning Package  Version 1.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
Ifpack2_Details_CrsArrays.hpp
Go to the documentation of this file.
1 /*@HEADER
2 // ***********************************************************************
3 //
4 // Ifpack2: Templated Object-Oriented Algebraic Preconditioner Package
5 // Copyright (2009) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
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 
47 
48 #ifndef __IFPACK2_CRSARRAYS_DECL_HPP__
49 #define __IFPACK2_CRSARRAYS_DECL_HPP__
50 
51 #include <Tpetra_RowMatrix.hpp>
52 #include <Tpetra_CrsMatrix.hpp>
53 #include <Tpetra_KokkosCompat_DefaultNode.hpp>
54 #include <Tpetra_BlockCrsMatrix_Helpers_decl.hpp>
55 #include <KokkosSparse_CrsMatrix.hpp>
56 #include <Ifpack2_LocalFilter.hpp>
57 #include <Ifpack2_ReorderFilter.hpp>
58 
59 namespace Ifpack2
60 {
61 namespace Details
62 {
63 
64 //Utility for getting the local values, rowptrs and colinds (in Kokkos::Views) for any RowMatrix
65 //Used by Fic, Filu and Fildl but may also be useful in other classes
66 template<typename Scalar, typename ImplScalar, typename LocalOrdinal, typename GlobalOrdinal, typename Node>
67 struct CrsArrayReader
68 {
69  typedef typename Node::device_type device_type;
70  typedef typename device_type::execution_space execution_space;
71  typedef Tpetra::RowMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> TRowMatrix;
72  typedef Tpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> TCrsMatrix;
73  typedef Tpetra::BlockCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> TBcrsMatrix;
74  typedef Ifpack2::LocalFilter<TRowMatrix> Filter;
75  typedef Ifpack2::ReorderFilter<TRowMatrix> ReordFilter;
76  typedef KokkosSparse::CrsMatrix<ImplScalar, LocalOrdinal, execution_space> KCrsMatrix;
77  typedef Kokkos::View<LocalOrdinal*, execution_space> OrdinalArray;
78  typedef Kokkos::View<ImplScalar*, execution_space> ScalarArray;
79  typedef typename OrdinalArray::HostMirror OrdinalArrayHost;
81  typedef Kokkos::Serial functor_space;
82  typedef Kokkos::RangePolicy<functor_space, int> RangePol;
83 
85  // \param[in] A The matrix
86  // \param[out] vals The values array on device (allocated inside function)
87  // \param[in] rowptrs The rowptrs host view provided by getStructure()
88  static void getValues(const TRowMatrix* A, ScalarArray& vals, OrdinalArrayHost& rowptrs)
89  {
90  auto Acrs = dynamic_cast<const TCrsMatrix*>(A);
91  auto Abcrs = dynamic_cast<const TBcrsMatrix*>(A);
92  if(Acrs)
93  {
94  getValuesCrs(Acrs, vals);
95  return;
96  }
97  if (Abcrs) {
98  getValuesBcrs(Abcrs, vals);
99  return;
100  }
101  using range_type = Kokkos::pair<int, int>;
102  using local_inds_host_view_type = typename TRowMatrix::nonconst_local_inds_host_view_type;
103  using values_host_view_type = typename TRowMatrix::nonconst_values_host_view_type;
104  using scalar_type = typename values_host_view_type::value_type;
105 
106  LocalOrdinal nrows = A->getLocalNumRows();
107  size_t nnz = A->getLocalNumEntries();
108  size_t maxNnz = A->getLocalMaxNumRowEntries();
109 
110  vals = ScalarArray("Values", nnz);
111  auto valsHost = Kokkos::create_mirror(vals);
112  local_inds_host_view_type lclColInds ("lclColinds", maxNnz);
113 
114  nnz = 0;
115  for(LocalOrdinal i = 0; i < nrows; i++) {
116  size_t NumEntries = A->getNumEntriesInLocalRow(i);
117  auto constLclValues = Kokkos::subview (valsHost, range_type (nnz, nnz+NumEntries));
118  values_host_view_type lclValues (const_cast<scalar_type*>(constLclValues.data()), NumEntries);
119 
120  A->getLocalRowCopy (i, lclColInds, lclValues, NumEntries);
121  nnz += NumEntries;
122  }
123  Kokkos::deep_copy(vals, valsHost);
124  }
125 
127  // \param[in] A The matrix
128  // \param[out] rowptrsHost The rowptrs array, in host space (allocated inside function)
129  // \param[out] rowptrs The rowptrs host array, in device space (allocated inside function). Will have exactly the same values as rowptrsHost.
130  // \param[out] colinds The colinds array, in device space (allocated inside function)
131  static void getStructure(const TRowMatrix* A, OrdinalArrayHost& rowptrsHost, OrdinalArray& rowptrs, OrdinalArray& colinds)
132  {
133  auto Acrs = dynamic_cast<const TCrsMatrix*>(A);
134  auto Abcrs = dynamic_cast<const TBcrsMatrix*>(A);
135  if(Acrs)
136  {
137  getStructureCrs(Acrs, rowptrsHost, rowptrs, colinds);
138  return;
139  }
140  if (Abcrs) {
141  getStructureBcrs(Abcrs, rowptrsHost, rowptrs, colinds);
142  return;
143  }
144  //Need to allocate new array, then copy in one row at a time
145  //note: actual rowptrs in the CrsMatrix implementation is size_t, but
146  //FastILU needs them as LocalOrdinal so this function provides an OrdinalArray
147  LocalOrdinal nrows = A->getLocalNumRows();
148  rowptrsHost = OrdinalArrayHost("RowPtrs (host)", nrows + 1);
149 
150  using range_type = Kokkos::pair<int, int>;
151  using values_host_view_type = typename TRowMatrix::nonconst_values_host_view_type;
152  using local_inds_host_view_type = typename TRowMatrix::nonconst_local_inds_host_view_type;
153  using local_ind_type = typename local_inds_host_view_type::value_type;
154  size_t nnz = A->getLocalNumEntries();
155  size_t maxNnz = A->getLocalMaxNumRowEntries();
156 
157  colinds = OrdinalArray("ColInds", nnz);
158  auto colindsHost = Kokkos::create_mirror(colinds);
159  values_host_view_type lclValues ("lclValues", maxNnz);
160 
161  nnz = 0;
162  rowptrsHost[0] = nnz;
163  for(LocalOrdinal i = 0; i < nrows; i++) {
164  size_t NumEntries = A->getNumEntriesInLocalRow(i);
165  auto constLclValues = Kokkos::subview (colindsHost, range_type (nnz, nnz+NumEntries));
166  local_inds_host_view_type lclColInds (const_cast<local_ind_type*>(constLclValues.data()), NumEntries);
167  A->getLocalRowCopy (i, lclColInds, lclValues, NumEntries);
168 
169  nnz += NumEntries;
170  rowptrsHost[i+1] = nnz;
171  }
172 
173  rowptrs = OrdinalArray("RowPtrs", nrows + 1);
174  Kokkos::deep_copy(rowptrs, rowptrsHost);
175  Kokkos::deep_copy(colinds, colindsHost);
176  }
177 
178  private:
179 
181  static void getValuesCrs(const TCrsMatrix* A, ScalarArray& values_)
182  {
183  auto localA = A->getLocalMatrixDevice();
184  auto values = localA.values;
185  auto nnz = values.extent(0);
186  values_ = ScalarArray("Values", nnz );
187  Kokkos::deep_copy(values_, values);
188  }
189 
191  static void getStructureCrs(const TCrsMatrix* A, OrdinalArrayHost& rowptrsHost_, OrdinalArray& rowptrs_, OrdinalArray& colinds_)
192  {
193  //rowptrs really have data type size_t, but need them as LocalOrdinal, so must convert manually
194  auto localA = A->getLocalMatrixDevice();
195  auto rowptrs = localA.graph.row_map;
196  auto colinds = localA.graph.entries;
197  auto numRows = A->getLocalNumRows();
198  auto nnz = colinds.extent(0);
199  //allocate rowptrs, it's a deep copy (colinds is a shallow copy so not necessary for it)
200  rowptrs_ = OrdinalArray("RowPtrs", numRows + 1);
201  colinds_ = OrdinalArray("ColInds", nnz );
202  Kokkos::deep_copy(rowptrs_, rowptrs);
203  Kokkos::deep_copy(colinds_, colinds);
204  // deep-copy to host
205  rowptrsHost_ = Kokkos::create_mirror(rowptrs_);
206  Kokkos::deep_copy(rowptrsHost_, rowptrs_);
207  }
208 
210  static void getValuesBcrs(const TBcrsMatrix* A, ScalarArray& values_)
211  {
212  auto localA = A->getLocalMatrixDevice();
213  auto values = localA.values;
214  auto nnz = values.extent(0);
215  values_ = ScalarArray("Values", nnz );
216  Kokkos::deep_copy(values_, values);
217  }
218 
220  static void getStructureBcrs(const TBcrsMatrix* A, OrdinalArrayHost& rowptrsHost_, OrdinalArray& rowptrs_, OrdinalArray& colinds_)
221  {
222  //rowptrs really have data type size_t, but need them as LocalOrdinal, so must convert manually
223  auto localA = A->getLocalMatrixDevice();
224  auto rowptrs = localA.graph.row_map;
225  auto colinds = localA.graph.entries;
226  auto numRows = A->getLocalNumRows();
227  auto nnz = colinds.extent(0);
228  //allocate rowptrs, it's a deep copy (colinds is a shallow copy so not necessary for it)
229  rowptrs_ = OrdinalArray("RowPtrs", numRows + 1);
230  colinds_ = OrdinalArray("ColInds", nnz );
231  Kokkos::deep_copy(rowptrs_, rowptrs);
232  Kokkos::deep_copy(colinds_, colinds);
233  // deep-copy to host
234  rowptrsHost_ = Kokkos::create_mirror(rowptrs_);
235  Kokkos::deep_copy(rowptrsHost_, rowptrs_);
236  }
237 
238 };
239 
240 } //Details
241 } //Ifpack2
242 
243 #endif
244 
Wraps a Tpetra::RowMatrix in a filter that reorders local rows and columns.
Definition: Ifpack2_ReorderFilter_decl.hpp:69
Access only local rows and columns of a sparse matrix.
Definition: Ifpack2_LocalFilter_decl.hpp:161