Ifpack2 Templated Preconditioning Package Version 1.0
Loading...
Searching...
No Matches
Ifpack2_Details_CrsArrays.hpp
Go to the documentation of this file.
1// @HEADER
2// *****************************************************************************
3// Ifpack2: Templated Object-Oriented Algebraic Preconditioner Package
4//
5// Copyright 2009 NTESS and the Ifpack2 contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
14
15#ifndef __IFPACK2_CRSARRAYS_DECL_HPP__
16#define __IFPACK2_CRSARRAYS_DECL_HPP__
17
18#include <Tpetra_RowMatrix.hpp>
19#include <Tpetra_CrsMatrix.hpp>
20#include <Tpetra_KokkosCompat_DefaultNode.hpp>
21#include <Tpetra_BlockCrsMatrix_Helpers_decl.hpp>
22#include <KokkosSparse_CrsMatrix.hpp>
23#include <Ifpack2_LocalFilter.hpp>
24#include <Ifpack2_ReorderFilter.hpp>
25
26namespace Ifpack2 {
27namespace Details {
28
29// Utility for getting the local values, rowptrs and colinds (in Kokkos::Views) for any RowMatrix
30// Used by Fic, Filu and Fildl but may also be useful in other classes
31template <typename Scalar, typename ImplScalar, typename LocalOrdinal, typename GlobalOrdinal, typename Node>
32struct CrsArrayReader {
33 typedef typename Node::device_type device_type;
34 typedef typename device_type::execution_space execution_space;
35 typedef Tpetra::RowMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> TRowMatrix;
36 typedef Tpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> TCrsMatrix;
37 typedef Tpetra::BlockCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> TBcrsMatrix;
39 typedef Ifpack2::ReorderFilter<TRowMatrix> ReordFilter;
40 typedef KokkosSparse::CrsMatrix<ImplScalar, LocalOrdinal, execution_space> KCrsMatrix;
41 typedef Kokkos::View<LocalOrdinal*, execution_space> OrdinalArray;
42 typedef Kokkos::View<ImplScalar*, execution_space> ScalarArray;
43 typedef typename OrdinalArray::host_mirror_type OrdinalArrayHost;
45 typedef Kokkos::Serial functor_space;
46 typedef Kokkos::RangePolicy<functor_space, int> RangePol;
47
49 // \param[in] A The matrix
50 // \param[out] vals The values array on device (allocated inside function)
51 // \param[in] rowptrs The rowptrs host view provided by getStructure()
52 static void getValues(const TRowMatrix* A, ScalarArray& vals, OrdinalArrayHost& /*rowptrs*/) {
53 auto Acrs = dynamic_cast<const TCrsMatrix*>(A);
54 auto Abcrs = dynamic_cast<const TBcrsMatrix*>(A);
55 if (Acrs) {
56 getValuesCrs(Acrs, vals);
57 return;
58 }
59 if (Abcrs) {
60 getValuesBcrs(Abcrs, vals);
61 return;
62 }
63 using range_type = Kokkos::pair<int, int>;
64 using local_inds_host_view_type = typename TRowMatrix::nonconst_local_inds_host_view_type;
65 using values_host_view_type = typename TRowMatrix::nonconst_values_host_view_type;
66 using scalar_type = typename values_host_view_type::value_type;
67
68 LocalOrdinal nrows = A->getLocalNumRows();
69 size_t nnz = A->getLocalNumEntries();
70 size_t maxNnz = A->getLocalMaxNumRowEntries();
71
72 if (vals.extent(0) != nnz) {
73 vals = ScalarArray(Kokkos::view_alloc(Kokkos::WithoutInitializing, "Values"), nnz);
74 }
75 auto valsHost = Kokkos::create_mirror_view(Kokkos::WithoutInitializing, vals);
76 local_inds_host_view_type lclColInds("lclColinds", maxNnz);
77
78 nnz = 0;
79 for (LocalOrdinal i = 0; i < nrows; i++) {
80 size_t NumEntries = A->getNumEntriesInLocalRow(i);
81 auto constLclValues = Kokkos::subview(valsHost, range_type(nnz, nnz + NumEntries));
82 values_host_view_type lclValues(const_cast<scalar_type*>(constLclValues.data()), NumEntries);
83
84 A->getLocalRowCopy(i, lclColInds, lclValues, NumEntries);
85 nnz += NumEntries;
86 }
87 Kokkos::deep_copy(vals, valsHost);
88 }
89
91 // \param[in] A The matrix
92 // \param[out] rowptrsHost The rowptrs array, in host space (allocated inside function)
93 // \param[out] rowptrs The rowptrs host array, in device space (allocated inside function). Will have exactly the same values as rowptrsHost.
94 // \param[out] colinds The colinds array, in device space (allocated inside function)
95 static void getStructure(const TRowMatrix* A, OrdinalArrayHost& rowptrsHost, OrdinalArray& rowptrs, OrdinalArray& colinds) {
96 auto Acrs = dynamic_cast<const TCrsMatrix*>(A);
97 auto Abcrs = dynamic_cast<const TBcrsMatrix*>(A);
98 if (Acrs) {
99 getStructureCrs(Acrs, rowptrsHost, rowptrs, colinds);
100 return;
101 }
102 if (Abcrs) {
103 getStructureBcrs(Abcrs, rowptrsHost, rowptrs, colinds);
104 return;
105 }
106 // Need to allocate new array, then copy in one row at a time
107 // note: actual rowptrs in the CrsMatrix implementation is size_t, but
108 // FastILU needs them as LocalOrdinal so this function provides an OrdinalArray
109 LocalOrdinal nrows = A->getLocalNumRows();
110 rowptrsHost = OrdinalArrayHost("RowPtrs (host)", nrows + 1);
111
112 using range_type = Kokkos::pair<int, int>;
113 using values_host_view_type = typename TRowMatrix::nonconst_values_host_view_type;
114 using local_inds_host_view_type = typename TRowMatrix::nonconst_local_inds_host_view_type;
115 using local_ind_type = typename local_inds_host_view_type::value_type;
116 size_t nnz = A->getLocalNumEntries();
117 size_t maxNnz = A->getLocalMaxNumRowEntries();
118
119 colinds = OrdinalArray("ColInds", nnz);
120 auto colindsHost = Kokkos::create_mirror(colinds);
121 values_host_view_type lclValues("lclValues", maxNnz);
122
123 nnz = 0;
124 rowptrsHost[0] = nnz;
125 for (LocalOrdinal i = 0; i < nrows; i++) {
126 size_t NumEntries = A->getNumEntriesInLocalRow(i);
127 auto constLclValues = Kokkos::subview(colindsHost, range_type(nnz, nnz + NumEntries));
128 local_inds_host_view_type lclColInds(const_cast<local_ind_type*>(constLclValues.data()), NumEntries);
129 A->getLocalRowCopy(i, lclColInds, lclValues, NumEntries);
130
131 nnz += NumEntries;
132 rowptrsHost[i + 1] = nnz;
133 }
134
135 rowptrs = OrdinalArray("RowPtrs", nrows + 1);
136 Kokkos::deep_copy(rowptrs, rowptrsHost);
137 Kokkos::deep_copy(colinds, colindsHost);
138 }
139
140 private:
142 static void getValuesCrs(const TCrsMatrix* A, ScalarArray& values_) {
143 auto localA = A->getLocalMatrixDevice();
144 auto values = localA.values;
145 auto nnz = values.extent(0);
146 if (values_.extent(0) != nnz) {
147 values_ = ScalarArray(Kokkos::view_alloc(Kokkos::WithoutInitializing, "Values"), nnz);
148 }
149 Kokkos::deep_copy(values_, values);
150 }
151
153 static void getStructureCrs(const TCrsMatrix* A, OrdinalArrayHost& rowptrsHost_, OrdinalArray& rowptrs_, OrdinalArray& colinds_) {
154 // rowptrs really have data type size_t, but need them as LocalOrdinal, so must convert manually
155 auto localA = A->getLocalMatrixDevice();
156 auto rowptrs = localA.graph.row_map;
157 auto colinds = localA.graph.entries;
158 auto numRows = A->getLocalNumRows();
159 auto nnz = colinds.extent(0);
160 // allocate rowptrs, it's a deep copy (colinds is a shallow copy so not necessary for it)
161 rowptrs_ = OrdinalArray("RowPtrs", numRows + 1);
162 colinds_ = OrdinalArray("ColInds", nnz);
163 Kokkos::deep_copy(rowptrs_, rowptrs);
164 Kokkos::deep_copy(colinds_, colinds);
165 // deep-copy to host
166 rowptrsHost_ = Kokkos::create_mirror(rowptrs_);
167 Kokkos::deep_copy(rowptrsHost_, rowptrs_);
168 }
169
171 static void getValuesBcrs(const TBcrsMatrix* A, ScalarArray& values_) {
172 auto localA = A->getLocalMatrixDevice();
173 auto values = localA.values;
174 auto nnz = values.extent(0);
175 if (values_.extent(0) != nnz) {
176 values_ = ScalarArray(Kokkos::view_alloc(Kokkos::WithoutInitializing, "Values"), nnz);
177 }
178 Kokkos::deep_copy(values_, values);
179 }
180
182 static void getStructureBcrs(const TBcrsMatrix* A, OrdinalArrayHost& rowptrsHost_, OrdinalArray& rowptrs_, OrdinalArray& colinds_) {
183 // rowptrs really have data type size_t, but need them as LocalOrdinal, so must convert manually
184 auto localA = A->getLocalMatrixDevice();
185 auto rowptrs = localA.graph.row_map;
186 auto colinds = localA.graph.entries;
187 auto numRows = A->getLocalNumRows();
188 auto nnz = colinds.extent(0);
189 // allocate rowptrs, it's a deep copy (colinds is a shallow copy so not necessary for it)
190 rowptrs_ = OrdinalArray("RowPtrs", numRows + 1);
191 colinds_ = OrdinalArray("ColInds", nnz);
192 Kokkos::deep_copy(rowptrs_, rowptrs);
193 Kokkos::deep_copy(colinds_, colinds);
194 // deep-copy to host
195 rowptrsHost_ = Kokkos::create_mirror(rowptrs_);
196 Kokkos::deep_copy(rowptrsHost_, rowptrs_);
197 }
198};
199
200} // namespace Details
201} // namespace Ifpack2
202
203#endif
Access only local rows and columns of a sparse matrix.
Definition Ifpack2_LocalFilter_decl.hpp:128
Wraps a Tpetra::RowMatrix in a filter that reorders local rows and columns.
Definition Ifpack2_ReorderFilter_decl.hpp:36
Ifpack2 implementation details.
Preconditioners and smoothers for Tpetra sparse matrices.
Definition Ifpack2_AdditiveSchwarz_decl.hpp:40