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), label_ (label)
33 {}
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 {
43  using Teuchos::RCP;
44  // Do the local transpose
45  RCP<crs_matrix_type> transMatrixWithSharedRows = createTransposeLocal (params);
46 
47 #ifdef HAVE_TPETRA_MMM_TIMINGS
48  const std::string prefix = std::string ("Tpetra ") + label_ + ": ";
49  using Teuchos::TimeMonitor;
50  TimeMonitor MM (*TimeMonitor::getNewTimer (prefix + "Transpose TAFC"));
51 #endif
52 
53  // If transMatrixWithSharedRows has an exporter, that's what we
54  // want. If it doesn't, the rows aren't actually shared, and we're
55  // done!
57  RCP<const export_type> exporter =
58  transMatrixWithSharedRows->getGraph ()->getExporter ();
59  if (exporter.is_null ()) {
60  return transMatrixWithSharedRows;
61  }
62  else {
63  Teuchos::ParameterList labelList;
64 #ifdef HAVE_TPETRA_MMM_TIMINGS
65  labelList.set("Timer Label", label_);
66 #endif
67  if(! params.is_null ()) {
68  const char paramName[] = "compute global constants";
69  labelList.set (paramName, params->get (paramName, true));
70  }
71  // Use the Export object to do a fused Export and fillComplete.
72  // This always sorts the local matrix after communication, so
73  // no need to set "sorted = false" in parameters.
74  return exportAndFillCompleteCrsMatrix<crs_matrix_type>
75  (transMatrixWithSharedRows, *exporter, Teuchos::null,
76  Teuchos::null, Teuchos::rcpFromRef (labelList));
77  }
78 }
79 
80 
81 // mfh 03 Feb 2013: In a definition outside the class like this, the
82 // return value is considered outside the class scope (for things like
83 // resolving typedefs), but the arguments are considered inside the
84 // class scope.
85 template<class Scalar,
86  class LocalOrdinal,
87  class GlobalOrdinal,
88  class Node>
89 Teuchos::RCP<CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
91 createTransposeLocal (const Teuchos::RCP<Teuchos::ParameterList>& params)
92 {
93  using Teuchos::Array;
94  using Teuchos::ArrayRCP;
95  using Teuchos::ArrayView;
96  using Teuchos::RCP;
97  using Teuchos::rcp;
98  using Teuchos::rcp_dynamic_cast;
99  using LO = LocalOrdinal;
100  using GO = GlobalOrdinal;
101  using import_type = Tpetra::Import<LO, GO, Node>;
102  using export_type = Tpetra::Export<LO, GO, Node>;
103 
104 #ifdef HAVE_TPETRA_MMM_TIMINGS
105  std::string prefix = std::string("Tpetra ") + label_ + ": ";
106  using Teuchos::TimeMonitor;
107  TimeMonitor MM (*TimeMonitor::getNewTimer (prefix + "Transpose Local"));
108 #endif
109 
110  const bool sort = [&] () {
111  constexpr bool sortDefault = true; // see #4607 discussion
112  const char sortParamName[] = "sort";
113  return params.get () == nullptr ? sortDefault :
114  params->get (sortParamName, sortDefault);
115  } ();
116 
117  const LO lclNumRows (origMatrix_->getLocalNumRows ());
118 
119  RCP<const crs_matrix_type> crsMatrix =
120  rcp_dynamic_cast<const crs_matrix_type> (origMatrix_);
121  if (crsMatrix.is_null ()) {
122  auto rowMap = origMatrix_->getRowMap ();
123  if (rowMap->isOneToOne ()) {
124  Teuchos::Array<size_t> numEntPerRow (lclNumRows);
125  for (LO lclRow = 0; lclRow < lclNumRows; ++lclRow) {
126  numEntPerRow[lclRow] = origMatrix_->getNumEntriesInLocalRow (lclRow);
127  }
128  auto colMap = origMatrix_->getColMap ();
129 
130  RCP<crs_matrix_type> crsMatrix_nc =
131  rcp (new crs_matrix_type (rowMap, colMap, numEntPerRow ()));
132 
133  // When source & target Maps are same, Import just copies.
134  import_type imp (rowMap, rowMap);
135  crsMatrix_nc->doImport (*origMatrix_, imp, Tpetra::REPLACE);
136  crsMatrix_nc->fillComplete (origMatrix_->getDomainMap (),
137  origMatrix_->getRangeMap ());
138  crsMatrix = crsMatrix_nc;
139  }
140  else {
141  TEUCHOS_ASSERT( false ); // not implemented (it wasn't before)
142  }
143  }
144 
145  using local_matrix_device_type = typename crs_matrix_type::local_matrix_device_type;
146 
147  local_matrix_device_type lclMatrix = crsMatrix->getLocalMatrixDevice ();
148  local_matrix_device_type lclTransposeMatrix = KokkosSparse::Impl::transpose_matrix(lclMatrix);
149  if (sort)
150  KokkosSparse::sort_crs_matrix(lclTransposeMatrix);
151 
152  // Prebuild the importers and exporters the no-communication way,
153  // flipping the importers and exporters around.
154  const auto origExport = origMatrix_->getGraph ()->getExporter ();
155  RCP<const import_type> myImport = origExport.is_null () ?
156  Teuchos::null : rcp (new import_type (*origExport));
157  const auto origImport = origMatrix_->getGraph ()->getImporter ();
158  RCP<const export_type> myExport = origImport.is_null () ?
159  Teuchos::null : rcp (new export_type (*origImport));
160 
161  RCP<Teuchos::ParameterList> graphParams = Teuchos::null;
162  if(!sort) {
163  graphParams = rcp(new Teuchos::ParameterList);
164  graphParams->set("sorted", false);
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 
177 template<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), label_ (label)
185 {}
186 
187 template<class Scalar,
188  class LocalOrdinal,
189  class GlobalOrdinal,
190  class Node>
191 Teuchos::RCP<BlockCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
193 createTranspose (const Teuchos::RCP<Teuchos::ParameterList> &params)
194 {
195  using Teuchos::RCP;
196  // Do the local transpose
197  RCP<bcrs_matrix_type> transMatrixWithSharedRows = createTransposeLocal (params);
198 
199 #ifdef HAVE_TPETRA_MMM_TIMINGS
200  const std::string prefix = std::string ("Tpetra ") + label_ + ": ";
201  using Teuchos::TimeMonitor;
202  TimeMonitor MM (*TimeMonitor::getNewTimer (prefix + "Transpose TAFC"));
203 #endif
204 
205  // If transMatrixWithSharedRows has an exporter, that's what we
206  // want. If it doesn't, the rows aren't actually shared, and we're
207  // done!
208  using export_type = Export<LocalOrdinal, GlobalOrdinal, Node>;
209  RCP<const export_type> exporter =
210  transMatrixWithSharedRows->getGraph ()->getExporter ();
211  if (exporter.is_null ()) {
212  return transMatrixWithSharedRows;
213  }
214  else {
215  Teuchos::ParameterList labelList;
216 #ifdef HAVE_TPETRA_MMM_TIMINGS
217  labelList.set("Timer Label", label_);
218 #endif
219  if(! params.is_null ()) {
220  const char paramName[] = "compute global constants";
221  labelList.set (paramName, params->get (paramName, true));
222  }
223  // Use the Export object to do a fused Export and fillComplete.
224  // This always sorts the local matrix after communication, so
225  // no need to set "sorted = false" in parameters.
226  return exportAndFillCompleteBlockCrsMatrix<bcrs_matrix_type>
227  (transMatrixWithSharedRows, *exporter);
228  }
229 }
230 
231 
232 // mfh 03 Feb 2013: In a definition outside the class like this, the
233 // return value is considered outside the class scope (for things like
234 // resolving typedefs), but the arguments are considered inside the
235 // class scope.
236 template<class Scalar,
237  class LocalOrdinal,
238  class GlobalOrdinal,
239  class Node>
240 Teuchos::RCP<BlockCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
242 createTransposeLocal (const Teuchos::RCP<Teuchos::ParameterList>& params)
243 {
244  using Teuchos::Array;
245  using Teuchos::ArrayRCP;
246  using Teuchos::ArrayView;
247  using Teuchos::RCP;
248  using Teuchos::rcp;
249  using Teuchos::rcp_dynamic_cast;
250  using LO = LocalOrdinal;
251  using GO = GlobalOrdinal;
252  using import_type = Tpetra::Import<LO, GO, Node>;
253  using export_type = Tpetra::Export<LO, GO, Node>;
254  using crs_graph_type = typename bcrs_matrix_type::crs_graph_type;
255 
256 #ifdef HAVE_TPETRA_MMM_TIMINGS
257  std::string prefix = std::string("Tpetra ") + label_ + ": ";
258  using Teuchos::TimeMonitor;
259  TimeMonitor MM (*TimeMonitor::getNewTimer (prefix + "Transpose Local"));
260 #endif
261 
262  RCP<const bcrs_matrix_type> crsMatrix =
263  rcp_dynamic_cast<const bcrs_matrix_type> (origMatrix_);
264 
265  if(crsMatrix.is_null())
266  TEUCHOS_ASSERT( false ); // not implemented
267 
268  using local_matrix_device_type = typename bcrs_matrix_type::local_matrix_device_type;
269 
270  typename local_matrix_device_type::values_type values ;
271  RCP<const crs_graph_type> graph;
272  {
273  local_matrix_device_type lclMatrix = crsMatrix->getLocalMatrixDevice ();
274 
275  local_matrix_device_type lclTransposeMatrix = KokkosSparse::Impl::transpose_bsr_matrix(lclMatrix);
276 
277  // BlockCrs requires that we sort stuff
278  KokkosSparse::sort_crs_matrix(lclTransposeMatrix);
279  values = lclTransposeMatrix.values;
280 
281  // Prebuild the importers and exporters the no-communication way,
282  // flipping the importers and exporters around.
283  const auto origExport = origMatrix_->getGraph ()->getExporter ();
284  RCP<const import_type> myImport = origExport.is_null () ?
285  Teuchos::null : rcp (new import_type (*origExport));
286  const auto origImport = origMatrix_->getGraph ()->getImporter ();
287  RCP<const export_type> myExport = origImport.is_null () ?
288  Teuchos::null : rcp (new export_type (*origImport));
289 
290  RCP<Teuchos::ParameterList> graphParams = Teuchos::null;
291 
292  // Make the Transpose Graph
293  graph = rcp(new crs_graph_type(lclTransposeMatrix.graph,
294  origMatrix_->getColMap (),
295  origMatrix_->getRowMap (),
296  origMatrix_->getGraph()->getRangeMap (),
297  origMatrix_->getGraph()->getDomainMap (),
298  myImport,
299  myExport,
300  graphParams));
301  }
302  // Now make the matrix
303  return rcp (new bcrs_matrix_type (*graph,
304  values,
305  origMatrix_->getBlockSize()));
306 }
307 //
308 
309 
310 //
311 // Explicit instantiation macro
312 //
313 // Must be expanded from within the Tpetra namespace!
314 //
315 
316 #define TPETRA_ROWMATRIXTRANSPOSER_INSTANT(SCALAR,LO,GO,NODE) \
317  template class RowMatrixTransposer< SCALAR, LO , GO , NODE >;\
318  template class BlockCrsMatrixTransposer< SCALAR, LO , GO , NODE >;
319 
320 } // namespace Tpetra
321 
322 #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.