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,
30 struct ConvertLocalToGlobalFunctor
32 ConvertLocalToGlobalFunctor(
33 const LocalIndicesType& colindsOrig_,
34 const GlobalIndicesType& colindsConverted_,
35 const ColMapType& colmap_) :
36 colindsOrig (colindsOrig_),
37 colindsConverted (colindsConverted_),
40 KOKKOS_INLINE_FUNCTION
void
41 operator() (
const GO i)
const
43 colindsConverted(i) = colmap.getGlobalElement(colindsOrig(i));
45 LocalIndicesType colindsOrig;
46 GlobalIndicesType colindsConverted;
50 template<
class LO,
class GO,
class LOView,
class GOView,
class LocalMap>
51 struct ConvertGlobalToLocalFunctor
53 ConvertGlobalToLocalFunctor(LOView& lids_,
const GOView& gids_,
const LocalMap localColMap_)
54 : lids(lids_), gids(gids_), localColMap(localColMap_)
57 KOKKOS_FUNCTION
void operator() (
const GO i)
const
59 lids(i) = localColMap.getLocalElement(gids(i));
64 const LocalMap localColMap;
68 template <
typename size_type,
typename ordinal_type,
69 typename ArowptrsT,
typename BrowptrsT,
typename CrowptrsT,
70 typename AcolindsT,
typename BcolindsT,
typename CcolindsT>
71 struct SortedNumericIndicesOnlyFunctor {
73 SortedNumericIndicesOnlyFunctor(
const ArowptrsT& Arowptrs_,
74 const BrowptrsT& Browptrs_,
75 const CrowptrsT& Crowptrs_,
76 const AcolindsT& Acolinds_,
77 const BcolindsT& Bcolinds_,
78 const CcolindsT& Ccolinds_)
79 : Arowptrs(Arowptrs_),
84 Ccolinds(Ccolinds_) {}
86 KOKKOS_INLINE_FUNCTION
void operator()(
const ordinal_type i)
const
88 const ordinal_type ORDINAL_MAX = Kokkos::ArithTraits<ordinal_type>::max();
93 size_type Arowstart = Arowptrs(i);
94 size_type Arowlen = Arowptrs(i + 1) - Arowstart;
95 size_type Browstart = Browptrs(i);
96 size_type Browlen = Browptrs(i + 1) - Browstart;
97 ordinal_type Acol = (Arowlen == 0) ? ORDINAL_MAX : Acolinds(Arowstart);
98 ordinal_type Bcol = (Browlen == 0) ? ORDINAL_MAX : Bcolinds(Browstart);
99 size_type Coffset = Crowptrs(i);
100 while (Acol != ORDINAL_MAX || Bcol != ORDINAL_MAX)
102 ordinal_type Ccol = (Acol < Bcol) ? Acol : Bcol;
109 Acol = Acolinds(Arowstart + ai);
117 Bcol = Bcolinds(Browstart + bi);
119 Ccolinds(Coffset) = Ccol;
124 const ArowptrsT Arowptrs;
125 const BrowptrsT Browptrs;
126 const CrowptrsT Crowptrs;
127 const AcolindsT Acolinds;
128 const BcolindsT Bcolinds;
132 template <
typename size_type,
typename ordinal_type,
133 typename ArowptrsT,
typename BrowptrsT,
typename CrowptrsT,
134 typename AcolindsT,
typename BcolindsT,
typename CcolindsT>
135 struct UnsortedNumericIndicesOnlyFunctor {
137 UnsortedNumericIndicesOnlyFunctor(
138 const ArowptrsT Arowptrs_,
const BrowptrsT Browptrs_,
const CrowptrsT Crowptrs_,
139 const AcolindsT Acolinds_,
const BcolindsT Bcolinds_, CcolindsT Ccolinds_,
140 const CcolindsT Apos_,
const CcolindsT Bpos_)
141 : Arowptrs(Arowptrs_),
150 KOKKOS_INLINE_FUNCTION
void operator()(
const ordinal_type i)
const {
151 size_type CrowStart = Crowptrs(i);
152 size_type ArowStart = Arowptrs(i);
153 size_type ArowEnd = Arowptrs(i + 1);
154 size_type BrowStart = Browptrs(i);
155 size_type BrowEnd = Browptrs(i + 1);
157 for (size_type j = ArowStart; j < ArowEnd; j++) {
158 Ccolinds(CrowStart + Apos(j)) = Acolinds(j);
161 for (size_type j = BrowStart; j < BrowEnd; j++) {
162 Ccolinds(CrowStart + Bpos(j)) = Bcolinds(j);
165 const ArowptrsT Arowptrs;
166 const BrowptrsT Browptrs;
167 const CrowptrsT Crowptrs;
168 const AcolindsT Acolinds;
169 const BcolindsT Bcolinds;
171 const CcolindsT Apos;
172 const CcolindsT Bpos;
176 template<
class LocalOrdinal,
181 const std::string& label)
188 Teuchos::RCP<CrsGraph<LocalOrdinal, GlobalOrdinal, Node> >
193 using device_type =
typename Node::device_type;
194 using execution_space =
typename device_type::execution_space;
195 using range_type = Kokkos::RangePolicy<execution_space, size_t>;
197 using impl_scalar_type = ::Tpetra::Details::DefaultTypes::scalar_type;
198 using row_ptrs_array =
typename local_graph_device_type::row_map_type::non_const_type ;
199 using col_inds_array =
typename local_graph_device_type::entries_type::non_const_type;
200 using local_map_type =
typename map_type::local_map_type;
201 using global_col_inds_array =
typename Kokkos::View<GlobalOrdinal*, device_type>;
203 auto graph = origGraph_;
230 typename Node::execution_space,
typename Node::memory_space,
typename Node::memory_space>;
232 typename Node::execution_space,
typename Node::memory_space,
typename Node::memory_space>;
239 auto nrows =
rowptrs.extent(0) - 1;
240 auto rowptrsSym = row_ptrs_array(Kokkos::ViewAllocateWithoutInitializing(
"row ptrs sym"), nrows + 1);
247 global_col_inds_array colindsConverted(Kokkos::ViewAllocateWithoutInitializing(
"colinds (converted)"),
colinds.extent(0));
249 Kokkos::parallel_for(
"colInds (converted)", range_type(0,
colinds.extent(0)), convert);
253 global_col_inds_array
colindsTConverted(Kokkos::ViewAllocateWithoutInitializing(
"colindsT (converted)"),
colindsT.extent(0));
255 Kokkos::parallel_for(
"colIndsT (converted)", range_type(0,
colindsT.extent(0)),
convertT);
259 handle.create_spadd_handle(
false);
260 auto addHandle = handle.get_spadd_handle();
264 KokkosSparse::Experimental::spadd_symbolic
267 nrows,
graph->getGlobalNumCols(),
270 globalColindsSym = global_col_inds_array(Kokkos::ViewAllocateWithoutInitializing(
"global colinds sym"),
addHandle->get_c_nnz());
272 UnsortedNumericIndicesOnlyFunctor<
274 typename row_ptrs_array::const_type,
typename row_ptrs_array::const_type, row_ptrs_array,
275 typename global_col_inds_array::const_type,
typename global_col_inds_array::const_type, global_col_inds_array>
279 Kokkos::parallel_for(
"KokkosSparse::SpAdd:Numeric::InputNotSorted",
283 Tpetra::Details::makeColMap<LocalOrdinal, GlobalOrdinal, Node>
296 handle.create_spadd_handle(
sorted);
297 auto addHandle = handle.get_spadd_handle();
299 KokkosSparse::Experimental::spadd_symbolic
302 nrows,
graph->getGlobalNumCols(),
305 colindsSym = col_inds_array(Kokkos::ViewAllocateWithoutInitializing(
"C colinds"),
addHandle->get_c_nnz());
308 SortedNumericIndicesOnlyFunctor<
310 typename row_ptrs_array::const_type,
typename row_ptrs_array::const_type, row_ptrs_array,
311 typename col_inds_array::const_type,
typename col_inds_array::const_type, col_inds_array>
314 Kokkos::parallel_for(
"KokkosSparse::SpAdd:Numeric::InputSorted",
318 UnsortedNumericIndicesOnlyFunctor<
320 typename row_ptrs_array::const_type,
typename row_ptrs_array::const_type, row_ptrs_array,
321 typename col_inds_array::const_type,
typename col_inds_array::const_type, col_inds_array>
325 Kokkos::parallel_for(
"KokkosSparse::SpAdd:Numeric::InputNotSorted",
336 KokkosSparse::sort_crs_graph<execution_space, row_ptrs_array, col_inds_array>(
rowptrsSym,
colindsSym);
359 Teuchos::RCP<CrsGraph<LocalOrdinal, GlobalOrdinal, Node> >
367#ifdef HAVE_TPETRA_MMM_TIMINGS
368 const std::string
prefix = std::string (
"Tpetra ") + label_ +
": ";
369 using Teuchos::TimeMonitor;
384#ifdef HAVE_TPETRA_MMM_TIMINGS
388 const char paramName[] =
"compute global constants";
396 Teuchos::null, Teuchos::rcpFromRef (
labelList));
403 Teuchos::RCP<CrsGraph<LocalOrdinal, GlobalOrdinal, Node> >
409 using Teuchos::rcp_dynamic_cast;
415#ifdef HAVE_TPETRA_MMM_TIMINGS
416 std::string
prefix = std::string(
"Tpetra ") + label_ +
": ";
417 using Teuchos::TimeMonitor;
421 const bool sort = [&] () {
429 local_graph_device_type
lclGraph = origGraph_->getLocalGraphDevice ();
432 using c_rowmap_t =
typename local_graph_device_type::row_map_type;
433 using c_entries_t =
typename local_graph_device_type::entries_type;
434 using rowmap_t =
typename local_graph_device_type::row_map_type::non_const_type;
435 using entries_t =
typename local_graph_device_type::entries_type::non_const_type;
436 LocalOrdinal numCols = origGraph_->getColMap()->getLocalNumElements();
439 Kokkos::ViewAllocateWithoutInitializing(
"Transpose entries"),
lclGraph.entries.extent(0));
440 KokkosSparse::Impl::transpose_graph<
443 rowmap_t,
typename local_graph_device_type::execution_space>(
449 KokkosSparse::sort_crs_graph<
450 typename local_graph_device_type::execution_space,
460 const auto origExport = origGraph_->getExporter ();
463 const auto origImport = origGraph_->getImporter ();
474 origGraph_->getColMap (),
475 origGraph_->getRowMap (),
476 origGraph_->getRangeMap (),
477 origGraph_->getDomainMap (),
487#define TPETRA_CRSGRAPHTRANSPOSER_INSTANT(LO,GO,NODE) \
488 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.
CrsGraphTransposer(const Teuchos::RCP< const crs_graph_type > &origGraph, const std::string &label=std::string())
Constructor that takes the graph to transpose.
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.
A distributed graph accessed by rows (adjacency lists) and stored sparsely.
Kokkos::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.
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.