Tpetra parallel linear algebra Version of the Day
Loading...
Searching...
No Matches
Tpetra_RowMatrixTransposer_def.hpp
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_ROWMATRIXTRANSPOSER_DEF_HPP
11#define TPETRA_ROWMATRIXTRANSPOSER_DEF_HPP
12
13#include "Tpetra_CrsMatrix.hpp"
14#include "Tpetra_BlockCrsMatrix.hpp"
15#include "Tpetra_Export.hpp"
19#include "Teuchos_ParameterList.hpp"
20#include "Teuchos_TimeMonitor.hpp"
21#include "KokkosSparse_Utils.hpp"
22
23namespace Tpetra {
24
25template <class Scalar,
26 class LocalOrdinal,
27 class GlobalOrdinal,
28 class Node>
30 RowMatrixTransposer(const Teuchos::RCP<const crs_matrix_type>& origMatrix,
31 const std::string& label)
32 : origMatrix_(origMatrix) {}
33
34template <class Scalar,
35 class LocalOrdinal,
36 class GlobalOrdinal,
37 class Node>
38Teuchos::RCP<CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
40 createTranspose(const Teuchos::RCP<Teuchos::ParameterList>& params) {
41 using Teuchos::RCP;
42 // Do the local transpose
43 RCP<crs_matrix_type> transMatrixWithSharedRows = createTransposeLocal(params);
44
45 Tpetra::Details::ProfilingRegion MM("Tpetra: Transpose TAFC");
46
47 // If transMatrixWithSharedRows has an exporter, that's what we
48 // want. If it doesn't, the rows aren't actually shared, and we're
49 // done!
51 RCP<const export_type> exporter =
52 transMatrixWithSharedRows->getGraph()->getExporter();
53 if (exporter.is_null()) {
54 return transMatrixWithSharedRows;
55 } else {
56 Teuchos::ParameterList labelList;
57 if (!params.is_null()) {
58 const char paramName[] = "compute global constants";
59 labelList.set(paramName, params->get(paramName, true));
60 }
61 // Use the Export object to do a fused Export and fillComplete.
62 // This always sorts the local matrix after communication, so
63 // no need to set "sorted = false" in parameters.
64 return exportAndFillCompleteCrsMatrix<crs_matrix_type>(transMatrixWithSharedRows, *exporter, Teuchos::null,
65 Teuchos::null, Teuchos::rcpFromRef(labelList));
66 }
67}
68
69// mfh 03 Feb 2013: In a definition outside the class like this, the
70// return value is considered outside the class scope (for things like
71// resolving typedefs), but the arguments are considered inside the
72// class scope.
73template <class Scalar,
74 class LocalOrdinal,
75 class GlobalOrdinal,
76 class Node>
77Teuchos::RCP<CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
79 createTransposeLocal(const Teuchos::RCP<Teuchos::ParameterList>& params) {
80 using Teuchos::Array;
81 using Teuchos::ArrayRCP;
82 using Teuchos::ArrayView;
83 using Teuchos::RCP;
84 using Teuchos::rcp;
85 using Teuchos::rcp_dynamic_cast;
86 using LO = LocalOrdinal;
87 using GO = GlobalOrdinal;
90
91 Tpetra::Details::ProfilingRegion MM("Tpetra: Transpose Local");
92
93 const bool sort = [&]() {
94 constexpr bool sortDefault = true; // see #4607 discussion
95 const char sortParamName[] = "sort";
96 return params.get() == nullptr ? sortDefault : params->get(sortParamName, sortDefault);
97 }();
98
99 const LO lclNumRows(origMatrix_->getLocalNumRows());
100
101 RCP<const crs_matrix_type> crsMatrix =
102 rcp_dynamic_cast<const crs_matrix_type>(origMatrix_);
103 if (crsMatrix.is_null()) {
104 auto rowMap = origMatrix_->getRowMap();
105 if (rowMap->isOneToOne()) {
106 Teuchos::Array<size_t> numEntPerRow(lclNumRows);
107 for (LO lclRow = 0; lclRow < lclNumRows; ++lclRow) {
108 numEntPerRow[lclRow] = origMatrix_->getNumEntriesInLocalRow(lclRow);
109 }
110 auto colMap = origMatrix_->getColMap();
111
112 RCP<crs_matrix_type> crsMatrix_nc =
113 rcp(new crs_matrix_type(rowMap, colMap, numEntPerRow()));
114
115 // When source & target Maps are same, Import just copies.
116 import_type imp(rowMap, rowMap);
117 crsMatrix_nc->doImport(*origMatrix_, imp, Tpetra::REPLACE);
118 crsMatrix_nc->fillComplete(origMatrix_->getDomainMap(),
119 origMatrix_->getRangeMap());
120 crsMatrix = crsMatrix_nc;
121 } else {
122 TEUCHOS_ASSERT(false); // not implemented (it wasn't before)
123 }
124 }
125
127
128#if KOKKOSKERNELS_VERSION >= 50199
129 bool conjugate_values = Teuchos::ScalarTraits<Scalar>::isComplex;
130#else
131 bool conjugate_values = false;
132#endif
133 const char conjugateValuesParamName[] = "conjugate values";
134 if (!params.is_null() && params->isParameter(conjugateValuesParamName)) {
135 conjugate_values = params->get(conjugateValuesParamName, conjugate_values);
136 }
137
138 local_matrix_device_type lclMatrix = crsMatrix->getLocalMatrixDevice();
139#if KOKKOSKERNELS_VERSION >= 50199
140 local_matrix_device_type lclTransposeMatrix = KokkosSparse::Impl::transpose_matrix(lclMatrix, conjugate_values);
141#else
142 TEUCHOS_TEST_FOR_EXCEPTION(conjugate_values, std::runtime_error, "Kokkos-Kernels does not yet support conjugating the values.");
143 local_matrix_device_type lclTransposeMatrix = KokkosSparse::Impl::transpose_matrix(lclMatrix);
144#endif
145 if (sort)
146 Import_Util::sortCrsMatrix(lclTransposeMatrix);
147
148 // Prebuild the importers and exporters the no-communication way,
149 // flipping the importers and exporters around.
150 const auto origExport = origMatrix_->getGraph()->getExporter();
151 RCP<const import_type> myImport = origExport.is_null() ? Teuchos::null : rcp(new import_type(*origExport));
152 const auto origImport = origMatrix_->getGraph()->getImporter();
153 RCP<const export_type> myExport = origImport.is_null() ? Teuchos::null : rcp(new export_type(*origImport));
154
155 RCP<Teuchos::ParameterList> graphParams = Teuchos::null;
156 if (!sort) {
157 graphParams = rcp(new Teuchos::ParameterList);
158 graphParams->set("sorted", false);
159 }
160 const char computeGlobalConstantsParamName[] = "compute global constants";
161 if (!params.is_null() && params->isParameter(computeGlobalConstantsParamName)) {
162 if (graphParams.is_null())
163 graphParams = rcp(new Teuchos::ParameterList);
164 graphParams->set(computeGlobalConstantsParamName, params->get<bool>(computeGlobalConstantsParamName));
165 }
166
167 return rcp(new crs_matrix_type(lclTransposeMatrix,
168 origMatrix_->getColMap(),
169 origMatrix_->getRowMap(),
170 origMatrix_->getRangeMap(),
171 origMatrix_->getDomainMap(),
172 myImport, myExport, graphParams));
173}
174
175/*************************************************************************/
176
177template <class Scalar,
178 class LocalOrdinal,
179 class GlobalOrdinal,
180 class Node>
182 BlockCrsMatrixTransposer(const Teuchos::RCP<const bcrs_matrix_type>& origMatrix,
183 const std::string& label)
184 : origMatrix_(origMatrix) {}
185
186template <class Scalar,
187 class LocalOrdinal,
188 class GlobalOrdinal,
189 class Node>
190Teuchos::RCP<BlockCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
192 createTranspose(const Teuchos::RCP<Teuchos::ParameterList>& params) {
193 using Teuchos::RCP;
194 // Do the local transpose
195 RCP<bcrs_matrix_type> transMatrixWithSharedRows = createTransposeLocal(params);
196
197 Tpetra::Details::ProfilingRegion MM("Tpetra: Transpose TAFC");
198
199 // If transMatrixWithSharedRows has an exporter, that's what we
200 // want. If it doesn't, the rows aren't actually shared, and we're
201 // done!
203 RCP<const export_type> exporter =
204 transMatrixWithSharedRows->getGraph()->getExporter();
205 if (exporter.is_null()) {
206 return transMatrixWithSharedRows;
207 } else {
208 Teuchos::ParameterList labelList;
209 if (!params.is_null()) {
210 const char paramName[] = "compute global constants";
211 labelList.set(paramName, params->get(paramName, true));
212 }
213 // Use the Export object to do a fused Export and fillComplete.
214 // This always sorts the local matrix after communication, so
215 // no need to set "sorted = false" in parameters.
216 return exportAndFillCompleteBlockCrsMatrix<bcrs_matrix_type>(transMatrixWithSharedRows, *exporter);
217 }
218}
219
220// mfh 03 Feb 2013: In a definition outside the class like this, the
221// return value is considered outside the class scope (for things like
222// resolving typedefs), but the arguments are considered inside the
223// class scope.
224template <class Scalar,
225 class LocalOrdinal,
226 class GlobalOrdinal,
227 class Node>
228Teuchos::RCP<BlockCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
230 createTransposeLocal(const Teuchos::RCP<Teuchos::ParameterList>& params) {
231 using Teuchos::Array;
232 using Teuchos::ArrayRCP;
233 using Teuchos::ArrayView;
234 using Teuchos::RCP;
235 using Teuchos::rcp;
236 using Teuchos::rcp_dynamic_cast;
237 using LO = LocalOrdinal;
238 using GO = GlobalOrdinal;
242
243 Tpetra::Details::ProfilingRegion MM("Tpetra: Transpose Local");
244
245 RCP<const bcrs_matrix_type> crsMatrix =
246 rcp_dynamic_cast<const bcrs_matrix_type>(origMatrix_);
247
248 if (crsMatrix.is_null())
249 TEUCHOS_ASSERT(false); // not implemented
250
251 using local_matrix_device_type = typename bcrs_matrix_type::local_matrix_device_type;
252
253 typename local_matrix_device_type::values_type values;
254 RCP<const crs_graph_type> graph;
255 {
256 local_matrix_device_type lclMatrix = crsMatrix->getLocalMatrixDevice();
257
258 local_matrix_device_type lclTransposeMatrix = KokkosSparse::Impl::transpose_bsr_matrix(lclMatrix);
259
260 // BlockCrs requires that we sort stuff
261 Import_Util::sortCrsMatrix(lclTransposeMatrix);
262 values = lclTransposeMatrix.values;
263
264 // Prebuild the importers and exporters the no-communication way,
265 // flipping the importers and exporters around.
266 const auto origExport = origMatrix_->getGraph()->getExporter();
267 RCP<const import_type> myImport = origExport.is_null() ? Teuchos::null : rcp(new import_type(*origExport));
268 const auto origImport = origMatrix_->getGraph()->getImporter();
269 RCP<const export_type> myExport = origImport.is_null() ? Teuchos::null : rcp(new export_type(*origImport));
270
271 RCP<Teuchos::ParameterList> graphParams = Teuchos::null;
272
273 // Make the Transpose Graph
274 graph = rcp(new crs_graph_type(lclTransposeMatrix.graph,
275 origMatrix_->getColMap(),
276 origMatrix_->getRowMap(),
277 origMatrix_->getGraph()->getRangeMap(),
278 origMatrix_->getGraph()->getDomainMap(),
279 myImport,
280 myExport,
281 graphParams));
282 }
283 // Now make the matrix
284 return rcp(new bcrs_matrix_type(*graph,
285 values,
286 origMatrix_->getBlockSize()));
287}
288//
289
290//
291// Explicit instantiation macro
292//
293// Must be expanded from within the Tpetra namespace!
294//
295
296#define TPETRA_ROWMATRIXTRANSPOSER_INSTANT(SCALAR, LO, GO, NODE) \
297 template class RowMatrixTransposer<SCALAR, LO, GO, NODE>; \
298 template class BlockCrsMatrixTransposer<SCALAR, LO, GO, NODE>;
299
300} // namespace Tpetra
301
302#endif
Declare and define the functions Tpetra::Details::computeOffsetsFromCounts and Tpetra::computeOffsets...
Declaration and definition of functions for sorting "short" arrays of keys and corresponding values.
Utility functions for packing and unpacking sparse matrix entries.
::Tpetra::CrsGraph< LocalOrdinal, GlobalOrdinal, node_type > crs_graph_type
Teuchos::RCP< bcrs_matrix_type > createTransposeLocal(const Teuchos::RCP< Teuchos::ParameterList > &params=Teuchos::null)
Compute and return the transpose of the matrix given to the constructor.
BlockCrsMatrixTransposer(const Teuchos::RCP< const bcrs_matrix_type > &origMatrix, const std::string &label=std::string())
Constructor that takes the matrix to transpose.
Teuchos::RCP< bcrs_matrix_type > createTranspose(const Teuchos::RCP< Teuchos::ParameterList > &params=Teuchos::null)
Compute and return the transpose of the matrix given to the constructor.
TPETRA_DETAILS_ALWAYS_INLINE local_matrix_device_type getLocalMatrixDevice() const
The local sparse matrix.
Teuchos::RCP< const map_type > getColMap() const override
The Map that describes the column distribution in this matrix.
Teuchos::RCP< const RowGraph< LocalOrdinal, GlobalOrdinal, Node > > getGraph() const override
This matrix's graph, as a RowGraph.
KokkosSparse::CrsMatrix< impl_scalar_type, local_ordinal_type, device_type, void, typename local_graph_device_type::size_type > local_matrix_device_type
The specialization of Kokkos::CrsMatrix that represents the part of the sparse matrix on each MPI pro...
Communication plan for data redistribution from a (possibly) multiply-owned to a uniquely-owned distr...
Communication plan for data redistribution from a uniquely-owned to a (possibly) multiply-owned distr...
Teuchos::RCP< crs_matrix_type > createTranspose(const Teuchos::RCP< Teuchos::ParameterList > &params=Teuchos::null)
Compute and return the transpose of the matrix given to the constructor.
Teuchos::RCP< crs_matrix_type > createTransposeLocal(const Teuchos::RCP< Teuchos::ParameterList > &params=Teuchos::null)
Compute and return the transpose of the matrix given to the constructor.
RowMatrixTransposer(const Teuchos::RCP< const crs_matrix_type > &origMatrix, const std::string &label=std::string())
Constructor that takes the matrix to transpose.
Namespace Tpetra contains the class and methods constituting the Tpetra library.
void sort(View &view, const size_t &size)
Convenience wrapper for std::sort for host-accessible views.
Teuchos::RCP< CrsMatrixType > exportAndFillCompleteCrsMatrix(const Teuchos::RCP< const CrsMatrixType > &sourceMatrix, const Export< typename CrsMatrixType::local_ordinal_type, typename CrsMatrixType::global_ordinal_type, typename CrsMatrixType::node_type > &exporter, const Teuchos::RCP< const Map< typename CrsMatrixType::local_ordinal_type, typename CrsMatrixType::global_ordinal_type, typename CrsMatrixType::node_type > > &domainMap=Teuchos::null, const Teuchos::RCP< const Map< typename CrsMatrixType::local_ordinal_type, typename CrsMatrixType::global_ordinal_type, typename CrsMatrixType::node_type > > &rangeMap=Teuchos::null, const Teuchos::RCP< Teuchos::ParameterList > &params=Teuchos::null)
Nonmember CrsMatrix constructor that fuses Export and fillComplete().
@ REPLACE
Replace existing values with new values.