Tpetra parallel linear algebra  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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"
18 #include "Teuchos_ParameterList.hpp"
19 #include "Teuchos_TimeMonitor.hpp"
20 #include "KokkosSparse_Utils.hpp"
21 #include "KokkosSparse_SortCrs.hpp"
22 
23 namespace Tpetra {
24 
25 template <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  , label_(label) {}
34 
35 template <class Scalar,
36  class LocalOrdinal,
37  class GlobalOrdinal,
38  class Node>
39 Teuchos::RCP<CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
41  createTranspose(const Teuchos::RCP<Teuchos::ParameterList>& params) {
42  using Teuchos::RCP;
43  // Do the local transpose
44  RCP<crs_matrix_type> transMatrixWithSharedRows = createTransposeLocal(params);
45 
46 #ifdef HAVE_TPETRA_MMM_TIMINGS
47  const std::string prefix = std::string("Tpetra ") + label_ + ": ";
48  using Teuchos::TimeMonitor;
49  TimeMonitor MM(*TimeMonitor::getNewTimer(prefix + "Transpose TAFC"));
50 #endif
51 
52  // If transMatrixWithSharedRows has an exporter, that's what we
53  // want. If it doesn't, the rows aren't actually shared, and we're
54  // done!
56  RCP<const export_type> exporter =
57  transMatrixWithSharedRows->getGraph()->getExporter();
58  if (exporter.is_null()) {
59  return transMatrixWithSharedRows;
60  } else {
61  Teuchos::ParameterList labelList;
62 #ifdef HAVE_TPETRA_MMM_TIMINGS
63  labelList.set("Timer Label", label_);
64 #endif
65  if (!params.is_null()) {
66  const char paramName[] = "compute global constants";
67  labelList.set(paramName, params->get(paramName, true));
68  }
69  // Use the Export object to do a fused Export and fillComplete.
70  // This always sorts the local matrix after communication, so
71  // no need to set "sorted = false" in parameters.
72  return exportAndFillCompleteCrsMatrix<crs_matrix_type>(transMatrixWithSharedRows, *exporter, Teuchos::null,
73  Teuchos::null, Teuchos::rcpFromRef(labelList));
74  }
75 }
76 
77 // mfh 03 Feb 2013: In a definition outside the class like this, the
78 // return value is considered outside the class scope (for things like
79 // resolving typedefs), but the arguments are considered inside the
80 // class scope.
81 template <class Scalar,
82  class LocalOrdinal,
83  class GlobalOrdinal,
84  class Node>
85 Teuchos::RCP<CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
87  createTransposeLocal(const Teuchos::RCP<Teuchos::ParameterList>& params) {
88  using Teuchos::Array;
89  using Teuchos::ArrayRCP;
90  using Teuchos::ArrayView;
91  using Teuchos::RCP;
92  using Teuchos::rcp;
93  using Teuchos::rcp_dynamic_cast;
94  using LO = LocalOrdinal;
95  using GO = GlobalOrdinal;
96  using import_type = Tpetra::Import<LO, GO, Node>;
97  using export_type = Tpetra::Export<LO, GO, Node>;
98 
99 #ifdef HAVE_TPETRA_MMM_TIMINGS
100  std::string prefix = std::string("Tpetra ") + label_ + ": ";
101  using Teuchos::TimeMonitor;
102  TimeMonitor MM(*TimeMonitor::getNewTimer(prefix + "Transpose Local"));
103 #endif
104 
105  const bool sort = [&]() {
106  constexpr bool sortDefault = true; // see #4607 discussion
107  const char sortParamName[] = "sort";
108  return params.get() == nullptr ? sortDefault : params->get(sortParamName, sortDefault);
109  }();
110 
111  const LO lclNumRows(origMatrix_->getLocalNumRows());
112 
113  RCP<const crs_matrix_type> crsMatrix =
114  rcp_dynamic_cast<const crs_matrix_type>(origMatrix_);
115  if (crsMatrix.is_null()) {
116  auto rowMap = origMatrix_->getRowMap();
117  if (rowMap->isOneToOne()) {
118  Teuchos::Array<size_t> numEntPerRow(lclNumRows);
119  for (LO lclRow = 0; lclRow < lclNumRows; ++lclRow) {
120  numEntPerRow[lclRow] = origMatrix_->getNumEntriesInLocalRow(lclRow);
121  }
122  auto colMap = origMatrix_->getColMap();
123 
124  RCP<crs_matrix_type> crsMatrix_nc =
125  rcp(new crs_matrix_type(rowMap, colMap, numEntPerRow()));
126 
127  // When source & target Maps are same, Import just copies.
128  import_type imp(rowMap, rowMap);
129  crsMatrix_nc->doImport(*origMatrix_, imp, Tpetra::REPLACE);
130  crsMatrix_nc->fillComplete(origMatrix_->getDomainMap(),
131  origMatrix_->getRangeMap());
132  crsMatrix = crsMatrix_nc;
133  } else {
134  TEUCHOS_ASSERT(false); // not implemented (it wasn't before)
135  }
136  }
137 
138  using local_matrix_device_type = typename crs_matrix_type::local_matrix_device_type;
139 
140  local_matrix_device_type lclMatrix = crsMatrix->getLocalMatrixDevice();
141  local_matrix_device_type lclTransposeMatrix = KokkosSparse::Impl::transpose_matrix(lclMatrix);
142  if (sort)
143  KokkosSparse::sort_crs_matrix(lclTransposeMatrix);
144 
145  // Prebuild the importers and exporters the no-communication way,
146  // flipping the importers and exporters around.
147  const auto origExport = origMatrix_->getGraph()->getExporter();
148  RCP<const import_type> myImport = origExport.is_null() ? Teuchos::null : rcp(new import_type(*origExport));
149  const auto origImport = origMatrix_->getGraph()->getImporter();
150  RCP<const export_type> myExport = origImport.is_null() ? Teuchos::null : rcp(new export_type(*origImport));
151 
152  RCP<Teuchos::ParameterList> graphParams = Teuchos::null;
153  if (!sort) {
154  graphParams = rcp(new Teuchos::ParameterList);
155  graphParams->set("sorted", false);
156  }
157 
158  return rcp(new crs_matrix_type(lclTransposeMatrix,
159  origMatrix_->getColMap(),
160  origMatrix_->getRowMap(),
161  origMatrix_->getRangeMap(),
162  origMatrix_->getDomainMap(),
163  myImport, myExport, graphParams));
164 }
165 
166 /*************************************************************************/
167 
168 template <class Scalar,
169  class LocalOrdinal,
170  class GlobalOrdinal,
171  class Node>
173  BlockCrsMatrixTransposer(const Teuchos::RCP<const bcrs_matrix_type>& origMatrix,
174  const std::string& label)
175  : origMatrix_(origMatrix)
176  , label_(label) {}
177 
178 template <class Scalar,
179  class LocalOrdinal,
180  class GlobalOrdinal,
181  class Node>
182 Teuchos::RCP<BlockCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
184  createTranspose(const Teuchos::RCP<Teuchos::ParameterList>& params) {
185  using Teuchos::RCP;
186  // Do the local transpose
187  RCP<bcrs_matrix_type> transMatrixWithSharedRows = createTransposeLocal(params);
188 
189 #ifdef HAVE_TPETRA_MMM_TIMINGS
190  const std::string prefix = std::string("Tpetra ") + label_ + ": ";
191  using Teuchos::TimeMonitor;
192  TimeMonitor MM(*TimeMonitor::getNewTimer(prefix + "Transpose TAFC"));
193 #endif
194 
195  // If transMatrixWithSharedRows has an exporter, that's what we
196  // want. If it doesn't, the rows aren't actually shared, and we're
197  // done!
198  using export_type = Export<LocalOrdinal, GlobalOrdinal, Node>;
199  RCP<const export_type> exporter =
200  transMatrixWithSharedRows->getGraph()->getExporter();
201  if (exporter.is_null()) {
202  return transMatrixWithSharedRows;
203  } else {
204  Teuchos::ParameterList labelList;
205 #ifdef HAVE_TPETRA_MMM_TIMINGS
206  labelList.set("Timer Label", label_);
207 #endif
208  if (!params.is_null()) {
209  const char paramName[] = "compute global constants";
210  labelList.set(paramName, params->get(paramName, true));
211  }
212  // Use the Export object to do a fused Export and fillComplete.
213  // This always sorts the local matrix after communication, so
214  // no need to set "sorted = false" in parameters.
215  return exportAndFillCompleteBlockCrsMatrix<bcrs_matrix_type>(transMatrixWithSharedRows, *exporter);
216  }
217 }
218 
219 // mfh 03 Feb 2013: In a definition outside the class like this, the
220 // return value is considered outside the class scope (for things like
221 // resolving typedefs), but the arguments are considered inside the
222 // class scope.
223 template <class Scalar,
224  class LocalOrdinal,
225  class GlobalOrdinal,
226  class Node>
227 Teuchos::RCP<BlockCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
229  createTransposeLocal(const Teuchos::RCP<Teuchos::ParameterList>& params) {
230  using Teuchos::Array;
231  using Teuchos::ArrayRCP;
232  using Teuchos::ArrayView;
233  using Teuchos::RCP;
234  using Teuchos::rcp;
235  using Teuchos::rcp_dynamic_cast;
236  using LO = LocalOrdinal;
237  using GO = GlobalOrdinal;
238  using import_type = Tpetra::Import<LO, GO, Node>;
239  using export_type = Tpetra::Export<LO, GO, Node>;
240  using crs_graph_type = typename bcrs_matrix_type::crs_graph_type;
241 
242 #ifdef HAVE_TPETRA_MMM_TIMINGS
243  std::string prefix = std::string("Tpetra ") + label_ + ": ";
244  using Teuchos::TimeMonitor;
245  TimeMonitor MM(*TimeMonitor::getNewTimer(prefix + "Transpose Local"));
246 #endif
247 
248  RCP<const bcrs_matrix_type> crsMatrix =
249  rcp_dynamic_cast<const bcrs_matrix_type>(origMatrix_);
250 
251  if (crsMatrix.is_null())
252  TEUCHOS_ASSERT(false); // not implemented
253 
254  using local_matrix_device_type = typename bcrs_matrix_type::local_matrix_device_type;
255 
256  typename local_matrix_device_type::values_type values;
257  RCP<const crs_graph_type> graph;
258  {
259  local_matrix_device_type lclMatrix = crsMatrix->getLocalMatrixDevice();
260 
261  local_matrix_device_type lclTransposeMatrix = KokkosSparse::Impl::transpose_bsr_matrix(lclMatrix);
262 
263  // BlockCrs requires that we sort stuff
264  KokkosSparse::sort_crs_matrix(lclTransposeMatrix);
265  values = lclTransposeMatrix.values;
266 
267  // Prebuild the importers and exporters the no-communication way,
268  // flipping the importers and exporters around.
269  const auto origExport = origMatrix_->getGraph()->getExporter();
270  RCP<const import_type> myImport = origExport.is_null() ? Teuchos::null : rcp(new import_type(*origExport));
271  const auto origImport = origMatrix_->getGraph()->getImporter();
272  RCP<const export_type> myExport = origImport.is_null() ? Teuchos::null : rcp(new export_type(*origImport));
273 
274  RCP<Teuchos::ParameterList> graphParams = Teuchos::null;
275 
276  // Make the Transpose Graph
277  graph = rcp(new crs_graph_type(lclTransposeMatrix.graph,
278  origMatrix_->getColMap(),
279  origMatrix_->getRowMap(),
280  origMatrix_->getGraph()->getRangeMap(),
281  origMatrix_->getGraph()->getDomainMap(),
282  myImport,
283  myExport,
284  graphParams));
285  }
286  // Now make the matrix
287  return rcp(new bcrs_matrix_type(*graph,
288  values,
289  origMatrix_->getBlockSize()));
290 }
291 //
292 
293 //
294 // Explicit instantiation macro
295 //
296 // Must be expanded from within the Tpetra namespace!
297 //
298 
299 #define TPETRA_ROWMATRIXTRANSPOSER_INSTANT(SCALAR, LO, GO, NODE) \
300  template class RowMatrixTransposer<SCALAR, LO, GO, NODE>; \
301  template class BlockCrsMatrixTransposer<SCALAR, LO, GO, NODE>;
302 
303 } // namespace Tpetra
304 
305 #endif
RowMatrixTransposer(const Teuchos::RCP< const crs_matrix_type > &origMatrix, const std::string &label=std::string())
Constructor that takes the matrix to transpose.
Communication plan for data redistribution from a uniquely-owned to a (possibly) multiply-owned distr...
Sparse matrix that presents a row-oriented interface that lets users read or modify entries...
Sparse matrix whose entries are small dense square blocks, all of the same dimensions.
Declaration and definition of functions for sorting &quot;short&quot; arrays of keys and corresponding values...
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...
void sort(View &view, const size_t &size)
Convenience wrapper for std::sort for host-accessible views.
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.
Declare and define the functions Tpetra::Details::computeOffsetsFromCounts and Tpetra::computeOffsets...
Communication plan for data redistribution from a (possibly) multiply-owned to a uniquely-owned distr...
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.
Replace existing values with new values.
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.
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.
local_matrix_device_type getLocalMatrixDevice() const
Teuchos::RCP< const map_type > getRowMap() const override
The Map that describes the row distribution in this matrix.