Tpetra parallel linear algebra  Version of the Day
Tpetra_RowMatrixTransposer_def.hpp
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Tpetra: Templated Linear Algebra Services Package
5 // Copyright (2008) Sandia Corporation
6 //
7 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
8 // the U.S. Government retains certain rights in this software.
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 #ifndef TPETRA_ROWMATRIXTRANSPOSER_DEF_HPP
43 #define TPETRA_ROWMATRIXTRANSPOSER_DEF_HPP
44 
45 #include "Tpetra_CrsMatrix.hpp"
46 #include "Tpetra_Export.hpp"
49 #include "Teuchos_ParameterList.hpp"
50 #include "Teuchos_TimeMonitor.hpp"
51 #include "KokkosKernels_SparseUtils.hpp"
52 
53 namespace Tpetra {
54 
55 template<class Scalar,
56  class LocalOrdinal,
57  class GlobalOrdinal,
58  class Node>
60 RowMatrixTransposer (const Teuchos::RCP<const crs_matrix_type>& origMatrix,
61  const std::string& label)
62  : origMatrix_ (origMatrix), label_ (label)
63 {}
64 
65 template<class Scalar,
66  class LocalOrdinal,
67  class GlobalOrdinal,
68  class Node>
69 Teuchos::RCP<CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
71 createTranspose (const Teuchos::RCP<Teuchos::ParameterList> &params)
72 {
73  using Teuchos::RCP;
74  // Do the local transpose
75  RCP<crs_matrix_type> transMatrixWithSharedRows = createTransposeLocal (params);
76 
77 #ifdef HAVE_TPETRA_MMM_TIMINGS
78  const std::string prefix = std::string ("Tpetra ") + label_ + ": ";
79  using Teuchos::TimeMonitor;
80  TimeMonitor MM (*TimeMonitor::getNewTimer (prefix + "Transpose TAFC"));
81 #endif
82 
83  // If transMatrixWithSharedRows has an exporter, that's what we
84  // want. If it doesn't, the rows aren't actually shared, and we're
85  // done!
87  RCP<const export_type> exporter =
88  transMatrixWithSharedRows->getGraph ()->getExporter ();
89  if (exporter.is_null ()) {
90  return transMatrixWithSharedRows;
91  }
92  else {
93  Teuchos::ParameterList labelList;
94 #ifdef HAVE_TPETRA_MMM_TIMINGS
95  labelList.set("Timer Label", label_);
96 #endif
97  if(! params.is_null ()) {
98  const char paramName[] = "compute global constants";
99  labelList.set (paramName, params->get (paramName, true));
100  }
101  // Use the Export object to do a fused Export and fillComplete.
102  // This always sorts the local matrix after communication, so
103  // no need to set "sorted = false" in parameters.
104  return exportAndFillCompleteCrsMatrix<crs_matrix_type>
105  (transMatrixWithSharedRows, *exporter, Teuchos::null,
106  Teuchos::null, Teuchos::rcpFromRef (labelList));
107  }
108 }
109 
110 
111 // mfh 03 Feb 2013: In a definition outside the class like this, the
112 // return value is considered outside the class scope (for things like
113 // resolving typedefs), but the arguments are considered inside the
114 // class scope.
115 template<class Scalar,
116  class LocalOrdinal,
117  class GlobalOrdinal,
118  class Node>
119 Teuchos::RCP<CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
121 createTransposeLocal (const Teuchos::RCP<Teuchos::ParameterList>& params)
122 {
123  using Teuchos::Array;
124  using Teuchos::ArrayRCP;
125  using Teuchos::ArrayView;
126  using Teuchos::RCP;
127  using Teuchos::rcp;
128  using Teuchos::rcp_dynamic_cast;
129  using LO = LocalOrdinal;
130  using GO = GlobalOrdinal;
131  using import_type = Tpetra::Import<LO, GO, Node>;
132  using export_type = Tpetra::Export<LO, GO, Node>;
133 
134 #ifdef HAVE_TPETRA_MMM_TIMINGS
135  std::string prefix = std::string("Tpetra ") + label_ + ": ";
136  using Teuchos::TimeMonitor;
137  TimeMonitor MM (*TimeMonitor::getNewTimer (prefix + "Transpose Local"));
138 #endif
139 
140  const bool sort = [&] () {
141  constexpr bool sortDefault = true; // see #4607 discussion
142  const char sortParamName[] = "sort";
143  return params.get () == nullptr ? sortDefault :
144  params->get (sortParamName, sortDefault);
145  } ();
146 
147  const LO lclNumRows (origMatrix_->getNodeNumRows ());
148 
149  RCP<const crs_matrix_type> crsMatrix =
150  rcp_dynamic_cast<const crs_matrix_type> (origMatrix_);
151  if (crsMatrix.is_null ()) {
152  auto rowMap = origMatrix_->getRowMap ();
153  if (rowMap->isOneToOne ()) {
154  Teuchos::Array<size_t> numEntPerRow (lclNumRows);
155  for (LO lclRow = 0; lclRow < lclNumRows; ++lclRow) {
156  numEntPerRow[lclRow] = origMatrix_->getNumEntriesInLocalRow (lclRow);
157  }
158  auto colMap = origMatrix_->getColMap ();
159 
160  RCP<crs_matrix_type> crsMatrix_nc =
161  rcp (new crs_matrix_type (rowMap, colMap, numEntPerRow ()));
162 
163  // When source & target Maps are same, Import just copies.
164  import_type imp (rowMap, rowMap);
165  crsMatrix_nc->doImport (*origMatrix_, imp, Tpetra::REPLACE);
166  crsMatrix_nc->fillComplete (origMatrix_->getDomainMap (),
167  origMatrix_->getRangeMap ());
168  crsMatrix = crsMatrix_nc;
169  }
170  else {
171  TEUCHOS_ASSERT( false ); // not implemented (it wasn't before)
172  }
173  }
174 
175  using local_matrix_device_type = typename crs_matrix_type::local_matrix_device_type;
176 
177  local_matrix_device_type lclMatrix = crsMatrix->getLocalMatrixDevice ();
178  local_matrix_device_type lclTransposeMatrix = KokkosKernels::Impl::transpose_matrix(lclMatrix);
179  if (sort)
180  KokkosKernels::Impl::sort_crs_matrix(lclTransposeMatrix);
181 
182  // Prebuild the importers and exporters the no-communication way,
183  // flipping the importers and exporters around.
184  const auto origExport = origMatrix_->getGraph ()->getExporter ();
185  RCP<const import_type> myImport = origExport.is_null () ?
186  Teuchos::null : rcp (new import_type (*origExport));
187  const auto origImport = origMatrix_->getGraph ()->getImporter ();
188  RCP<const export_type> myExport = origImport.is_null () ?
189  Teuchos::null : rcp (new export_type (*origImport));
190 
191  RCP<Teuchos::ParameterList> graphParams = Teuchos::null;
192  if(!sort) {
193  graphParams = rcp(new Teuchos::ParameterList);
194  graphParams->set("sorted", false);
195  }
196 
197  return rcp (new crs_matrix_type (lclTransposeMatrix,
198  origMatrix_->getColMap (),
199  origMatrix_->getRowMap (),
200  origMatrix_->getRangeMap (),
201  origMatrix_->getDomainMap (),
202  myImport, myExport, graphParams));
203 }
204 //
205 // Explicit instantiation macro
206 //
207 // Must be expanded from within the Tpetra namespace!
208 //
209 
210 #define TPETRA_ROWMATRIXTRANSPOSER_INSTANT(SCALAR,LO,GO,NODE) \
211  template class RowMatrixTransposer< SCALAR, LO , GO , NODE >;
212 
213 } // namespace Tpetra
214 
215 #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.
Sparse matrix that presents a row-oriented interface that lets users read or modify entries.
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.
@ REPLACE
Replace existing values with new values.