10#ifndef TPETRA_CRSGRAPHTRANSPOSER_DEF_HPP
11#define TPETRA_CRSGRAPHTRANSPOSER_DEF_HPP
13#include "Tpetra_CrsGraph.hpp"
14#include "Tpetra_Export.hpp"
16#include "Tpetra_Details_makeColMap.hpp"
18#include "Teuchos_ParameterList.hpp"
19#include "Teuchos_TimeMonitor.hpp"
20#include "KokkosSparse_Utils.hpp"
21#include "KokkosKernels_Handle.hpp"
22#include "KokkosSparse_spadd.hpp"
27 typename LocalIndicesType,
28 typename GlobalIndicesType,
30struct ConvertLocalToGlobalFunctor {
31 ConvertLocalToGlobalFunctor(
32 const LocalIndicesType& colindsOrig_,
33 const GlobalIndicesType& colindsConverted_,
34 const ColMapType& colmap_)
35 : colindsOrig(colindsOrig_)
36 , colindsConverted(colindsConverted_)
38 KOKKOS_INLINE_FUNCTION
void
39 operator()(
const GO i)
const {
40 colindsConverted(i) = colmap.getGlobalElement(colindsOrig(i));
42 LocalIndicesType colindsOrig;
43 GlobalIndicesType colindsConverted;
47template <
class LO,
class GO,
class LOView,
class GOView,
class LocalMap>
48struct ConvertGlobalToLocalFunctor {
49 ConvertGlobalToLocalFunctor(LOView& lids_,
const GOView& gids_,
const LocalMap localColMap_)
52 , localColMap(localColMap_) {}
54 KOKKOS_FUNCTION
void operator()(
const GO i)
const {
55 lids(i) = localColMap.getLocalElement(gids(i));
60 const LocalMap localColMap;
63template <
typename size_type,
typename ordinal_type,
64 typename ArowptrsT,
typename BrowptrsT,
typename CrowptrsT,
65 typename AcolindsT,
typename BcolindsT,
typename CcolindsT>
66struct SortedNumericIndicesOnlyFunctor {
67 SortedNumericIndicesOnlyFunctor(
const ArowptrsT& Arowptrs_,
68 const BrowptrsT& Browptrs_,
69 const CrowptrsT& Crowptrs_,
70 const AcolindsT& Acolinds_,
71 const BcolindsT& Bcolinds_,
72 const CcolindsT& Ccolinds_)
78 , Ccolinds(Ccolinds_) {}
80 KOKKOS_INLINE_FUNCTION
void operator()(
const ordinal_type i)
const {
81 const ordinal_type ORDINAL_MAX = KokkosKernels::ArithTraits<ordinal_type>::max();
86 size_type Arowstart = Arowptrs(i);
87 size_type Arowlen = Arowptrs(i + 1) - Arowstart;
88 size_type Browstart = Browptrs(i);
89 size_type Browlen = Browptrs(i + 1) - Browstart;
90 ordinal_type Acol = (Arowlen == 0) ? ORDINAL_MAX : Acolinds(Arowstart);
91 ordinal_type Bcol = (Browlen == 0) ? ORDINAL_MAX : Bcolinds(Browstart);
92 size_type Coffset = Crowptrs(i);
93 while (Acol != ORDINAL_MAX || Bcol != ORDINAL_MAX) {
94 ordinal_type Ccol = (Acol < Bcol) ? Acol : Bcol;
95 while (Acol == Ccol) {
100 Acol = Acolinds(Arowstart + ai);
102 while (Bcol == Ccol) {
107 Bcol = Bcolinds(Browstart + bi);
109 Ccolinds(Coffset) = Ccol;
114 const ArowptrsT Arowptrs;
115 const BrowptrsT Browptrs;
116 const CrowptrsT Crowptrs;
117 const AcolindsT Acolinds;
118 const BcolindsT Bcolinds;
122template <
typename size_type,
typename ordinal_type,
123 typename ArowptrsT,
typename BrowptrsT,
typename CrowptrsT,
124 typename AcolindsT,
typename BcolindsT,
typename CcolindsT>
125struct UnsortedNumericIndicesOnlyFunctor {
126 UnsortedNumericIndicesOnlyFunctor(
127 const ArowptrsT Arowptrs_,
const BrowptrsT Browptrs_,
const CrowptrsT Crowptrs_,
128 const AcolindsT Acolinds_,
const BcolindsT Bcolinds_, CcolindsT Ccolinds_,
129 const CcolindsT Apos_,
const CcolindsT Bpos_)
130 : Arowptrs(Arowptrs_)
131 , Browptrs(Browptrs_)
132 , Crowptrs(Crowptrs_)
133 , Acolinds(Acolinds_)
134 , Bcolinds(Bcolinds_)
135 , Ccolinds(Ccolinds_)
139 KOKKOS_INLINE_FUNCTION
void operator()(
const ordinal_type i)
const {
140 size_type CrowStart = Crowptrs(i);
141 size_type ArowStart = Arowptrs(i);
142 size_type ArowEnd = Arowptrs(i + 1);
143 size_type BrowStart = Browptrs(i);
144 size_type BrowEnd = Browptrs(i + 1);
146 for (size_type j = ArowStart; j < ArowEnd; j++) {
147 Ccolinds(CrowStart + Apos(j)) = Acolinds(j);
150 for (size_type j = BrowStart; j < BrowEnd; j++) {
151 Ccolinds(CrowStart + Bpos(j)) = Bcolinds(j);
154 const ArowptrsT Arowptrs;
155 const BrowptrsT Browptrs;
156 const CrowptrsT Crowptrs;
157 const AcolindsT Acolinds;
158 const BcolindsT Bcolinds;
160 const CcolindsT Apos;
161 const CcolindsT Bpos;
164template <
class LocalOrdinal,
174Teuchos::RCP<CrsGraph<LocalOrdinal, GlobalOrdinal, Node> >
178 using device_type =
typename Node::device_type;
179 using execution_space =
typename device_type::execution_space;
180 using range_type = Kokkos::RangePolicy<execution_space, size_t>;
182 using impl_scalar_type = ::Tpetra::Details::DefaultTypes::scalar_type;
183 using row_ptrs_array =
typename local_graph_device_type::row_map_type::non_const_type;
184 using col_inds_array =
typename local_graph_device_type::entries_type::non_const_type;
185 using local_map_type =
typename map_type::local_map_type;
186 using global_col_inds_array =
typename Kokkos::View<GlobalOrdinal*, device_type>;
188 auto graph = origGraph_;
215 typename Node::execution_space,
typename Node::memory_space,
typename Node::memory_space>;
217 typename Node::execution_space,
typename Node::memory_space,
typename Node::memory_space>;
224 auto nrows =
rowptrs.extent(0) - 1;
225 auto rowptrsSym = row_ptrs_array(Kokkos::ViewAllocateWithoutInitializing(
"row ptrs sym"), nrows + 1);
232 global_col_inds_array colindsConverted(Kokkos::ViewAllocateWithoutInitializing(
"colinds (converted)"),
colinds.extent(0));
234 Kokkos::parallel_for(
"colInds (converted)", range_type(0,
colinds.extent(0)), convert);
238 global_col_inds_array
colindsTConverted(Kokkos::ViewAllocateWithoutInitializing(
"colindsT (converted)"),
colindsT.extent(0));
240 Kokkos::parallel_for(
"colIndsT (converted)", range_type(0,
colindsT.extent(0)),
convertT);
244 handle.create_spadd_handle(
false);
245 auto addHandle = handle.get_spadd_handle();
249 KokkosSparse::spadd_symbolic(&handle,
250 nrows,
graph->getGlobalNumCols(),
252 globalColindsSym = global_col_inds_array(Kokkos::ViewAllocateWithoutInitializing(
"global colinds sym"),
addHandle->get_c_nnz());
254 UnsortedNumericIndicesOnlyFunctor<
256 typename row_ptrs_array::const_type,
typename row_ptrs_array::const_type, row_ptrs_array,
257 typename global_col_inds_array::const_type,
typename global_col_inds_array::const_type, global_col_inds_array>
261 Kokkos::parallel_for(
"KokkosSparse::SpAdd:Numeric::InputNotSorted",
276 handle.create_spadd_handle(
sorted);
277 auto addHandle = handle.get_spadd_handle();
279 KokkosSparse::spadd_symbolic(&handle,
280 nrows,
graph->getGlobalNumCols(),
282 colindsSym = col_inds_array(Kokkos::ViewAllocateWithoutInitializing(
"C colinds"),
addHandle->get_c_nnz());
285 SortedNumericIndicesOnlyFunctor<
287 typename row_ptrs_array::const_type,
typename row_ptrs_array::const_type, row_ptrs_array,
288 typename col_inds_array::const_type,
typename col_inds_array::const_type, col_inds_array>
291 Kokkos::parallel_for(
"KokkosSparse::SpAdd:Numeric::InputSorted",
295 UnsortedNumericIndicesOnlyFunctor<
297 typename row_ptrs_array::const_type,
typename row_ptrs_array::const_type, row_ptrs_array,
298 typename col_inds_array::const_type,
typename col_inds_array::const_type, col_inds_array>
302 Kokkos::parallel_for(
"KokkosSparse::SpAdd:Numeric::InputNotSorted",
313 KokkosSparse::sort_crs_graph<execution_space, row_ptrs_array, col_inds_array>(
rowptrsSym,
colindsSym);
336Teuchos::RCP<CrsGraph<LocalOrdinal, GlobalOrdinal, Node> >
356 const char paramName[] =
"compute global constants";
363 Teuchos::null, Teuchos::rcpFromRef(
labelList));
370Teuchos::RCP<CrsGraph<LocalOrdinal, GlobalOrdinal, Node> >
375 using Teuchos::rcp_dynamic_cast;
383 const bool sort = [&]() {
390 local_graph_device_type
lclGraph = origGraph_->getLocalGraphDevice();
393 using c_rowmap_t =
typename local_graph_device_type::row_map_type;
394 using c_entries_t =
typename local_graph_device_type::entries_type;
395 using rowmap_t =
typename local_graph_device_type::row_map_type::non_const_type;
396 using entries_t =
typename local_graph_device_type::entries_type::non_const_type;
397 LocalOrdinal numCols = origGraph_->getColMap()->getLocalNumElements();
400 Kokkos::ViewAllocateWithoutInitializing(
"Transpose entries"),
lclGraph.entries.extent(0));
401 KokkosSparse::Impl::transpose_graph<
404 rowmap_t,
typename local_graph_device_type::execution_space>(
410 KokkosSparse::sort_crs_graph<
411 typename local_graph_device_type::execution_space,
421 const auto origExport = origGraph_->getExporter();
423 const auto origImport = origGraph_->getImporter();
433 origGraph_->getColMap(),
434 origGraph_->getRowMap(),
435 origGraph_->getRangeMap(),
436 origGraph_->getDomainMap(),
446#define TPETRA_CRSGRAPHTRANSPOSER_INSTANT(LO, GO, NODE) \
447 template class CrsGraphTransposer<LO, GO, NODE>;
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.
A distributed graph accessed by rows (adjacency lists) and stored sparsely.
KokkosSparse::StaticCrsGraph< local_ordinal_type, Kokkos::LayoutLeft, device_type, void, size_t > local_graph_device_type
The type of the part of the sparse graph on each MPI process.
Teuchos::RCP< crs_graph_type > createTransposeLocal(const Teuchos::RCP< Teuchos::ParameterList > ¶ms=Teuchos::null)
Compute and return the transpose of the graph given to the constructor.
Teuchos::RCP< crs_graph_type > createTranspose(const Teuchos::RCP< Teuchos::ParameterList > ¶ms=Teuchos::null)
Compute and return the transpose of the graph given to the constructor.
Teuchos::RCP< crs_graph_type > symmetrize(const Teuchos::RCP< Teuchos::ParameterList > ¶ms=Teuchos::null)
Compute and return graph+graph^T of the graph given to the constructor.
CrsGraphTransposer(const Teuchos::RCP< const crs_graph_type > &origGraph)
Constructor that takes the graph to transpose.
Struct that holds views of the contents of a CrsMatrix.
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.