Zoltan2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Zoltan2_TpetraCrsColorerUtils.hpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Zoltan2: A package of combinatorial algorithms for scientific computing
4 //
5 // Copyright 2012 NTESS and the Zoltan2 contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 #pragma once
11 
12 #include "Teuchos_RCP.hpp"
13 #include "Teuchos_Comm.hpp"
14 
15 #include "Tpetra_CrsGraph.hpp"
16 #include "Tpetra_CrsMatrix.hpp"
17 
18 //#include "Tpetra_RowMatrixTransposer.hpp"
19 
20 #include "KokkosKernels_Utils.hpp"
21 #include "KokkosSparse_Utils.hpp"
22 
23 namespace Zoltan2
24 {
25 
26 // Some utility functions to help with coloring
27 namespace Impl
28 {
29 
30 // Check coloring is valid for a given graph
31 template <typename LO, typename GO, typename NO, typename list_of_colors_t>
32 bool
34  const Tpetra::CrsGraph<LO, GO, NO> &graph,
35  const list_of_colors_t &list_of_colors)
36 {
37  typedef typename list_of_colors_t::execution_space execution_space;
38 
39  Teuchos::RCP<const Teuchos::Comm<int>> comm = graph.getRowMap()->getComm();
40  const int rank = comm->getRank();
41  auto local_graph = graph.getLocalGraphDevice();
42  const size_t num_rows = graph.getLocalNumRows();
43  size_t num_conflict = 0;
44 
45  Kokkos::parallel_reduce(
46  "check_coloring()", Kokkos::RangePolicy<execution_space>(0, num_rows),
47  KOKKOS_LAMBDA(const size_t row, size_t &lcl_conflict) {
48  const size_t entry_begin = local_graph.row_map(row);
49  const size_t entry_end = local_graph.row_map(row + 1);
50  for (size_t entry = entry_begin; entry < entry_end; entry++)
51  {
52  const size_t col = local_graph.entries(entry);
53  for (size_t entry2 = entry_begin; entry2 < entry_end; ++entry2)
54  {
55  const size_t col2 = local_graph.entries(entry2);
56  if (col != col2 && list_of_colors[col] == list_of_colors[col2])
57  {
58  ++lcl_conflict;
59  Kokkos::printf(
60  "proc = %i : Invalid coloring! Local row %zu"
61  " and columns %zu, %zu have the same color %i\n",
62  rank, row, col, col2, list_of_colors[col]);
63  }
64  }
65  }
66  },
67  num_conflict);
68 
69  size_t global_num_conflict = 0;
70  Teuchos::reduceAll(*comm, Teuchos::REDUCE_SUM, 1, &num_conflict,
71  &global_num_conflict);
72 
73  return global_num_conflict == 0;
74 }
75 
77 template <typename LocalCrsGraphType>
78 LocalCrsGraphType
80  const LocalCrsGraphType &local_graph,
81  const size_t num_cols)
82 {
83  using KokkosSparse::Impl::transpose_graph;
84 
85  typedef LocalCrsGraphType graph_t;
86  typedef typename graph_t::row_map_type lno_view_t;
87  typedef typename graph_t::entries_type lno_nnz_view_t;
88  typedef typename lno_view_t::non_const_type trans_row_view_t;
89  typedef typename lno_nnz_view_t::non_const_type trans_nnz_view_t;
90  typedef typename lno_view_t::execution_space exec_t;
91 
92  // Build tranpose graph
93  const size_t num_rows = local_graph.row_map.extent(0) - 1;
94  const size_t num_nnz = local_graph.entries.extent(0);
95 
96  trans_row_view_t trans_row_map("trans_row_map", num_cols + 1);
97  trans_nnz_view_t trans_entries("trans_entries", num_nnz);
98 
99  transpose_graph<lno_view_t, lno_nnz_view_t, trans_row_view_t,
100  trans_nnz_view_t, trans_row_view_t, exec_t>(
101  num_rows, num_cols, local_graph.row_map, local_graph.entries,
102  trans_row_map, trans_entries);
103 
104  graph_t local_trans_graph(trans_entries, trans_row_map);
105 
106  return local_trans_graph;
107 }
108 
110 // template <typename LO, typename GO, typename NO>
111 // Teuchos::RCP<const Tpetra::CrsGraph<LO,GO,NO> >
112 // compute_transpose_graph(const Tpetra::CrsGraph<LO,GO,NO>& graph)
113 // {
114 // typedef double SC;
115 // Teuchos::RCP< Tpetra::CrsMatrix<SC,LO,GO,NO> > matrix =
116 // Teuchos::rcp(new Tpetra::CrsMatrix<double,LO,GO,NO>(Teuchos::rcp(&graph,false)));
117 // Tpetra::RowMatrixTransposer<SC,LO,GO,NO> transposer(matrix);
118 // Teuchos::RCP<Tpetra::CrsMatrix<SC,LO,GO,NO> > trans_matrix =
119 // transposer.createTranspose();
120 // return trans_matrix->getCrsGraph();
121 // }
122 
124 template <typename LO, typename GO, typename NO>
125 Teuchos::RCP<Tpetra::CrsGraph<LO, GO, NO>>
126 compute_transpose_graph(const Tpetra::CrsGraph<LO, GO, NO> &graph)
127 {
128  using Teuchos::RCP;
129  using Teuchos::rcp;
130 
131  typedef Tpetra::CrsGraph<LO, GO, NO> graph_t;
132  typedef typename graph_t::local_graph_device_type local_graph_t;
133 
134  // Transpose local graph
135  local_graph_t local_graph = graph.getLocalGraphDevice();
136  local_graph_t local_trans_graph =
137  compute_local_transpose_graph(local_graph,
138  graph.getLocalNumCols());
139 
140  // Build (possibly overlapped) transpose graph using original graph's
141  // column map as the new row map, and vice versa
142  //
143  // Normally, for a transpose graph, we'd use
144  // original matrix's RangeMap as the DomainMap, and
145  // original matrix's DomainMap as the RangeMap.
146  // Moreover, we're not doing SpMV with the transpose graph, so
147  // you might think we wouldn't care about RangeMap and DomainMap.
148  // But we DO care, because exportAndFillCompleteCrsGraph uses the
149  // shared (overlapped) transpose matrix's RangeMap as the RowMap of the
150  // transpose matrix, while the Zoltan callbacks are assuming the
151  // transpose matrix's RowMap is the same as the original matrix's.
152  // So we'll use the original matrix's RowMap as the RangeMap.
153  RCP<graph_t> trans_graph_shared = rcp(new graph_t(
154  local_trans_graph, graph.getColMap(), graph.getRowMap(),
155  graph.getRangeMap(), graph.getRowMap()));
156 
157  RCP<graph_t> trans_graph;
158 
159  // Export graph to non-overlapped distribution if necessary.
160  // If the exporter is null, we don't need to export
161  RCP<const Tpetra::Export<LO, GO, NO>> exporter =
162  trans_graph_shared->getExporter();
163  if (exporter == Teuchos::null)
164  trans_graph = trans_graph_shared;
165  else
166  {
167  RCP<const graph_t> trans_graph_shared_const = trans_graph_shared;
168  trans_graph = Tpetra::exportAndFillCompleteCrsGraph(
169  trans_graph_shared_const, *exporter,
170  Teuchos::null, Teuchos::null, Teuchos::null);
171  }
172 
173  return trans_graph;
174 }
175 
177 template <typename SC, typename LO, typename GO, typename NO>
178 Teuchos::RCP<Tpetra::CrsGraph<LO, GO, NO>>
179 compute_transpose_graph(const Tpetra::CrsMatrix<SC, LO, GO, NO> &matrix)
180 {
181  return compute_transpose_graph(*(matrix.getCrsGraph()));
182 }
183 
185 template <typename SC, typename LO, typename GO, typename NO>
186 Teuchos::RCP<Tpetra::CrsGraph<LO, GO, NO>>
187 compute_transpose_graph(const Tpetra::BlockCrsMatrix<SC, LO, GO, NO> &matrix)
188 {
189  return compute_transpose_graph(matrix.getCrsGraph());
190 }
191 } // namespace Impl
192 } // namespace Zoltan2
LocalCrsGraphType compute_local_transpose_graph(const LocalCrsGraphType &local_graph, const size_t num_cols)
Teuchos::RCP< Tpetra::CrsGraph< LO, GO, NO > > compute_transpose_graph(const Tpetra::CrsGraph< LO, GO, NO > &graph)
bool check_coloring(const Tpetra::CrsGraph< LO, GO, NO > &graph, const list_of_colors_t &list_of_colors)