Zoltan2
Loading...
Searching...
No Matches
Zoltan2_TpetraCrsColorer.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 <stdexcept>
13
14#include "Teuchos_RCP.hpp"
15#include "Teuchos_ParameterList.hpp"
16#include "Teuchos_TestForException.hpp"
17
18#include "Tpetra_Map.hpp"
19#include "Tpetra_MultiVector.hpp"
20#include "Tpetra_CrsMatrix.hpp"
21#include "Tpetra_CrsGraph.hpp"
22#include "Tpetra_BlockMultiVector.hpp"
23#include "Tpetra_BlockCrsMatrix.hpp"
24
28
29namespace Zoltan2
30{
31
32// Base class for coloring Tpetra::CrsMatrix for use in column compression
33template <typename CrsMatrixType>
35{
36public:
37 typedef CrsMatrixType matrix_t;
38 typedef typename matrix_t::crs_graph_type graph_t;
39 typedef typename matrix_t::scalar_type scalar_t;
40 typedef typename matrix_t::local_ordinal_type lno_t;
41 typedef typename matrix_t::global_ordinal_type gno_t;
42 typedef typename matrix_t::node_type node_t;
43 typedef typename node_t::device_type device_t;
44 typedef typename device_t::execution_space execution_space;
45 typedef Kokkos::View<int *, device_t> list_of_colors_t;
46 typedef typename list_of_colors_t::host_mirror_type list_of_colors_host_t;
47
48 // Constructor
49 TpetraCrsColorer(const Teuchos::RCP<matrix_t> &matrix_);
50
51 // Destructor
53
54 // Compute coloring data
55 void
56 computeColoring(Teuchos::ParameterList &coloring_params);
57
58 // Compute seed matrix
59 template <typename MultiVectorType>
60 void
61 computeSeedMatrix(MultiVectorType &V, const int color_beg = 0) const;
62
63 // Compute seed matrix with distribution fitted to the graph's column map
64 template <typename MultiVectorType>
65 void
66 computeSeedMatrixFitted(MultiVectorType &V, const int color_beg = 0) const;
67
68 // Reconstruct matrix from supplied compressed vector
69 template <typename MultiVectorType>
70 void
71 reconstructMatrix(MultiVectorType &W, const int color_beg = 0) const;
72 template <typename MultiVectorType>
73 void
74 reconstructMatrix(MultiVectorType &W, matrix_t &mat, const int color_beg = 0) const;
75
76 // Reconstruct matrix from supplied compressed vector fitted to the graph's
77 // row map
78 template <typename MultiVectorType>
79 void
80 reconstructMatrixFitted(MultiVectorType &W, const int color_beg = 0) const;
81 template <typename MultiVectorType>
82 void
83 reconstructMatrixFitted(MultiVectorType &W, matrix_t &mat, const int color_beg = 0) const;
84
85 // Return number of colors
86 // KDD should num_colors be int or size_t?
87 int
89 {
90 return num_colors;
91 }
92
93 // Get color given a column index
94 int
95 getColor(const size_t col) const
96 {
97 return list_of_colors_host(col) - 1;
98 }
99
100 // Check coloring is valid, i.e., no row has two nonzero columns with
101 // same color
102 bool
104 {
106 }
107
108protected:
109 Teuchos::RCP<matrix_t> matrix;
110 Teuchos::RCP<const graph_t> graph;
114};
115
117// Specialization of TpetraCrsColorer for BlockCrsMatrix
118template <typename SC, typename LO, typename GO, typename NO>
119class TpetraCrsColorer<Tpetra::BlockCrsMatrix<SC,LO,GO,NO> >
120{
121public:
122 typedef Tpetra::BlockCrsMatrix<SC, LO, GO, NO> matrix_t;
123 typedef Tpetra::BlockMultiVector<SC, LO, GO, NO> multivector_t;
124 typedef typename matrix_t::crs_graph_type graph_t;
125 typedef typename matrix_t::scalar_type scalar_t;
126 typedef typename matrix_t::local_ordinal_type lno_t;
127 typedef typename matrix_t::global_ordinal_type gno_t;
128 typedef typename matrix_t::node_type node_t;
129 typedef typename node_t::device_type device_t;
130 typedef typename device_t::execution_space execution_space;
131 typedef Kokkos::View<int *, device_t> list_of_colors_t;
132 typedef typename list_of_colors_t::host_mirror_type list_of_colors_host_t;
133
134 // Constructor
135 TpetraCrsColorer(const Teuchos::RCP<matrix_t> &matrix_);
136
137 // Destructor
139
140 // Compute coloring data
141 void
142 computeColoring(Teuchos::ParameterList &coloring_params);
143
144 // Compute seed matrix
145 void
146 computeSeedMatrix(multivector_t &V, const int color_beg = 0) const;
147
148 // Compute seed matrix with distribution fitted to the graph's column map
149 void
150 computeSeedMatrixFitted(multivector_t &V, const int color_beg = 0) const;
151
152 // Reconstruct matrix from supplied compressed vector
153 void
154 reconstructMatrix(multivector_t &W, const int color_beg = 0) const;
155 void
156 reconstructMatrix(multivector_t &W, matrix_t &mat, const int color_beg = 0) const;
157
158 // Reconstruct matrix from supplied compressed vector fitted to the graph's
159 // row map
160 void
161 reconstructMatrixFitted(multivector_t &W, const int color_beg = 0) const;
162 void
163 reconstructMatrixFitted(multivector_t &W, matrix_t &mat, const int color_beg = 0) const;
164
165 // Return number of colors
166 int
168 {
169 return num_colors * matrix->getBlockSize();
170 }
171
172 // Get color given a column index
173 int
174 getColor(const size_t col) const
175 {
176 const int block_size = matrix->getBlockSize();
177 const size_t block_col = col / block_size;
178 const int offset = col - block_col * block_size;
179 return (list_of_colors_host(block_col) - 1) * block_size + offset;
180 }
181
182 // Check coloring is valid, i.e., no row has two nonzero columns with
183 // same color
184 bool
186 {
188 }
189
190protected:
191 Teuchos::RCP<matrix_t> matrix;
192 Teuchos::RCP<const graph_t> graph;
196};
197
199
200template <typename CrsMatrixType>
202 const Teuchos::RCP<matrix_t> &matrix_
203)
204 : matrix(matrix_),
205 graph(matrix->getCrsGraph()),
206 list_of_colors(),
207 list_of_colors_host(),
208 num_colors(0)
209{
210
211}
212
214template <typename CrsMatrixType>
215void
217 Teuchos::ParameterList &coloring_params
218)
219{
220 const std::string library = coloring_params.get("library", "zoltan");
221
222 if (library == "zoltan") {
223 // Use Zoltan's coloring
225 zz.computeColoring(coloring_params,
226 num_colors, list_of_colors_host, list_of_colors);
227 }
228 else {
229 // Use Zoltan2's coloring
230 Zoltan2CrsColorer<matrix_t> zz2(matrix);
231 zz2.computeColoring(coloring_params,
232 num_colors, list_of_colors_host, list_of_colors);
233 }
234}
235
237template <typename CrsMatrixType>
238template <typename MultiVectorType>
239void
241 MultiVectorType &V, const int color_beg) const
242{
243 MultiVectorType V_fitted(graph->getColMap(), V.getNumVectors());
244
245 computeSeedMatrixFitted(V_fitted, color_beg);
246
247 Tpetra::Import<lno_t, gno_t, node_t>
248 importer(graph->getColMap(), V.getMap());
249
250 V.doImport(V_fitted, importer, Tpetra::INSERT);
251}
252
254template <typename CrsMatrixType>
255template <typename MultiVectorType>
256void
258 MultiVectorType &V, const int color_beg) const
259{
260 // Check V's map is locally fitted to the graph's column map
261 TEUCHOS_TEST_FOR_EXCEPTION(
262 !(graph->getColMap()->isLocallyFitted(*(V.getMap()))), std::domain_error,
263 "Map for supplied vector is not locally fitted to the column map of the"
264 " Jacobian graph. "
265 "You must call the non-fitted version of this function.");
266
267 auto V_view_dev = V.getLocalViewDevice(Tpetra::Access::OverwriteAll);
268 const size_t num_local_cols = graph->getLocalNumCols();
269 const int chunk_size = V.getNumVectors();
270 list_of_colors_t my_list_of_colors = list_of_colors;
271
272 Kokkos::parallel_for(
273 "TpetraCrsColorer::computeSeedMatrixFitted()",
274 Kokkos::RangePolicy<execution_space>(0, num_local_cols),
275 KOKKOS_LAMBDA(const size_t i) {
276 const int color = my_list_of_colors[i] - 1 - color_beg;
277 if (color >= 0 && color < chunk_size)
278 V_view_dev(i, color) = scalar_t(1.0);
279 });
280
281}
282
284template <typename CrsMatrixType>
285template <typename MultiVectorType>
286void
288 MultiVectorType &W, const int color_beg) const
289{
290 reconstructMatrix(W, *matrix, color_beg);
291}
292
294template <typename CrsMatrixType>
295template <typename MultiVectorType>
296void
298 MultiVectorType &W,
299 matrix_t &mat,
300 const int color_beg) const
301{
302 MultiVectorType W_fitted(graph->getRowMap(), W.getNumVectors());
303
304 Tpetra::Import<lno_t, gno_t, node_t>
305 importer(W.getMap(), graph->getRowMap());
306
307 W_fitted.doImport(W, importer, Tpetra::INSERT);
308
309 reconstructMatrixFitted(W_fitted, mat, color_beg);
310}
311
313template <typename CrsMatrixType>
314template <typename MultiVectorType>
315void
317 MultiVectorType &W, const int color_beg) const
318{
319 reconstructMatrixFitted(W, *matrix, color_beg);
320}
321
323template <typename CrsMatrixType>
324template <typename MultiVectorType>
325void
327 MultiVectorType &W,
328 matrix_t &mat,
329 const int color_beg) const
330{
331 // Check the graph's row map is locally fitted to W's map
332 TEUCHOS_TEST_FOR_EXCEPTION(
333 !(W.getMap()->isLocallyFitted(*(graph->getRowMap()))), std::domain_error,
334 "Row map of the Jacobian graph is not locally fitted to the vector's map."
335 " You must call the non-fitted version of this function.");
336
337 auto W_view_dev = W.getLocalViewDevice(Tpetra::Access::ReadOnly);
338 auto local_matrix = mat.getLocalMatrixDevice();
339 auto local_graph = local_matrix.graph;
340 const size_t num_local_rows = graph->getLocalNumRows();
341 const int chunk_size = W.getNumVectors();
342 list_of_colors_t my_list_of_colors = list_of_colors;
343
344 Kokkos::parallel_for(
345 "TpetraCrsColorer::reconstructMatrixFitted()",
346 Kokkos::RangePolicy<execution_space>(0, num_local_rows),
347 KOKKOS_LAMBDA(const size_t row) {
348 const size_t entry_begin = local_graph.row_map(row);
349 const size_t entry_end = local_graph.row_map(row + 1);
350 for (size_t entry = entry_begin; entry < entry_end; entry++)
351 {
352 const size_t col = local_graph.entries(entry);
353 const int color = my_list_of_colors[col] - 1 - color_beg;
354 if (color >= 0 && color < chunk_size)
355 local_matrix.values(entry) = W_view_dev(row, color);
356 }
357 });
358}
359
361template <typename SC, typename LO, typename GO, typename NO>
363 const Teuchos::RCP<matrix_t> &matrix_
364)
365 : matrix(matrix_)
366 , graph(Teuchos::rcp(&(matrix->getCrsGraph()), false))
367 , list_of_colors()
368 , list_of_colors_host()
369 , num_colors(0)
370{
371}
372
374template <typename SC, typename LO, typename GO, typename NO>
375void
377 Teuchos::ParameterList &coloring_params
378)
379{
380 const std::string library = coloring_params.get("library", "zoltan");
381
382 if (library == "zoltan") {
383 // Use Zoltan's coloring
385 zz.computeColoring(coloring_params,
386 num_colors, list_of_colors_host, list_of_colors);
387 }
388 else {
389 // Use Zoltan2's coloring
390 Zoltan2CrsColorer<matrix_t> zz2(matrix);
391 zz2.computeColoring(coloring_params,
392 num_colors, list_of_colors_host, list_of_colors);
393 }
394}
395
397template <typename SC, typename LO, typename GO, typename NO>
398void
400 multivector_t &block_V, const int color_beg) const
401{
402 multivector_t block_V_fitted(*(graph->getColMap()), matrix->getBlockSize(),
403 block_V.getNumVectors());
404
405 computeSeedMatrixFitted(block_V_fitted, color_beg);
406
407 const lno_t block_size = block_V.getBlockSize();
408 auto col_point_map = multivector_t::makePointMap(*graph->getColMap(),
409 block_size);
410 auto blockV_point_map = multivector_t::makePointMap(*block_V.getMap(),
411 block_size);
412 const auto col_point_map_rcp =
413 Teuchos::rcp(new Tpetra::Map<LO, GO, NO>(col_point_map));
414 const auto blockV_point_map_rcp =
415 Teuchos::rcp(new Tpetra::Map<LO, GO, NO>(blockV_point_map));
416
417 Tpetra::Import<LO, GO, NO> importer_point(col_point_map_rcp,
418 blockV_point_map_rcp);
419
420 block_V.getMultiVectorView().doImport(block_V_fitted.getMultiVectorView(),
421 importer_point, Tpetra::INSERT);
422
423 // Tpetra::Import<LO,GO,NO> importer(graph->getColMap(), block_V.getMap());
424 // block_V.doImport(block_V_fitted, importer, Tpetra::INSERT);
425}
426
428template <typename SC, typename LO, typename GO, typename NO>
429void
431 multivector_t &blockV, const int color_beg) const
432{
433 // Check blockV's map is locally fitted to the graph's column map
434 TEUCHOS_TEST_FOR_EXCEPTION(
435 !(graph->getColMap()->isLocallyFitted(*(blockV.getMap()))),
436 std::domain_error,
437 "Map for supplied vector is not locally fitted to the column map of the"
438 " Jacobian graph. "
439 "You must call the non-fitted version of this function.");
440
441 const lno_t block_size = blockV.getBlockSize();
442 auto V = blockV.getMultiVectorView();
443 auto V_view_dev = V.getLocalViewDevice(Tpetra::Access::ReadWrite);
444 const size_t num_local_cols = V_view_dev.extent(0) / block_size;
445 const int chunk_size = V.getNumVectors() / block_size;
446 const int block_color_beg = color_beg / block_size;
447 list_of_colors_t my_list_of_colors = list_of_colors;
448
449 Kokkos::parallel_for(
450 "TpetraCrsColorer::computeSeedMatrixFitted()",
451 Kokkos::RangePolicy<execution_space>(0, num_local_cols),
452 KOKKOS_LAMBDA(const size_t i) {
453 const int color = my_list_of_colors[i] - 1 - block_color_beg;
454 if (color >= 0 && color < chunk_size)
455 for (lno_t j = 0; j < block_size; ++j)
456 V_view_dev(i*block_size+j, color*block_size+j) = scalar_t(1.0);
457 });
458
459}
460
462template <typename SC, typename LO, typename GO, typename NO>
463void
465 multivector_t &W, const int color_beg) const
466{
467 reconstructMatrix(W, *matrix, color_beg);
468}
469
471template <typename SC, typename LO, typename GO, typename NO>
472void
474 multivector_t &block_W,
475 matrix_t &mat,
476 const int color_beg) const
477{
478 multivector_t block_W_fitted(*(graph->getRowMap()), matrix->getBlockSize(),
479 block_W.getNumVectors());
480
481 const lno_t block_size = block_W.getBlockSize();
482 auto row_point_map = multivector_t::makePointMap(*graph->getRowMap(),
483 block_size);
484 auto blockW_point_map = multivector_t::makePointMap(*block_W.getMap(),
485 block_size);
486 const auto row_point_map_rcp =
487 Teuchos::rcp(new Tpetra::Map<LO, GO, NO>(row_point_map));
488 const auto blockW_point_map_rcp =
489 Teuchos::rcp(new Tpetra::Map<LO, GO, NO>(blockW_point_map));
490
491 Tpetra::Import<lno_t, gno_t, node_t>
492 importer_point(blockW_point_map_rcp, row_point_map_rcp);
493
494 block_W_fitted.getMultiVectorView().doImport(block_W.getMultiVectorView(),
495 importer_point, Tpetra::INSERT);
496 reconstructMatrixFitted(block_W_fitted, mat, color_beg);
497}
498
500template <typename SC, typename LO, typename GO, typename NO>
501void
503 multivector_t &W, const int color_beg) const
504{
505 reconstructMatrixFitted(W, *matrix, color_beg);
506}
507
509template <typename SC, typename LO, typename GO, typename NO>
510void
512 multivector_t &block_W,
513 matrix_t &mat,
514 const int color_beg) const
515{
516 // Check the graph's row map is locally fitted to W's map
517 TEUCHOS_TEST_FOR_EXCEPTION(
518 !(block_W.getMap()->isLocallyFitted(*(graph->getRowMap()))),
519 std::domain_error,
520 "Row map of the Jacobian graph is not locally fitted to the vector's map."
521 " You must call the non-fitted version of this function.");
522
523 // Blocks are block_size x block_size stored with LayoutRight
524 const lno_t block_size = block_W.getBlockSize();
525 const lno_t block_stride = block_size * block_size;
526 const lno_t block_row_stride = block_size;
527
528 auto W = block_W.getMultiVectorView();
529 auto W_view_dev = W.getLocalViewDevice(Tpetra::Access::ReadOnly);
530 auto matrix_vals = mat.getValuesDeviceNonConst();
531 auto local_graph = graph->getLocalGraphDevice();
532 const size_t num_local_rows = graph->getLocalNumRows();
533 const int chunk_size = W.getNumVectors() / block_size;
534 const int block_color_beg = color_beg / block_size;
535 list_of_colors_t my_list_of_colors = list_of_colors;
536
537 Kokkos::parallel_for(
538 "TpetraCrsColorer::reconstructMatrix()",
539 Kokkos::RangePolicy<execution_space>(0, num_local_rows),
540 KOKKOS_LAMBDA(const size_t block_row) {
541 const size_t entry_begin = local_graph.row_map(block_row);
542 const size_t entry_end = local_graph.row_map(block_row + 1);
543 for (size_t block_entry = entry_begin; block_entry < entry_end;
544 block_entry++)
545 {
546 const size_t block_col = local_graph.entries(block_entry);
547 const size_t block_offset = block_stride * block_entry;
548 const int block_color = my_list_of_colors[block_col] - 1 - block_color_beg;
549 if (block_color >= 0 && block_color < chunk_size)
550 {
551 for (lno_t i = 0; i < block_size; ++i)
552 {
553 const size_t row = block_row * block_size + i;
554 for (lno_t j = 0; j < block_size; ++j)
555 {
556 const size_t entry = block_offset + block_row_stride * i + j;
557 matrix_vals(entry) = W_view_dev(row, block_color*block_size+j);
558 }
559 }
560 }
561 }
562 });
563}
564} // namespace Tpetra
void computeSeedMatrix(MultiVectorType &V, const int color_beg=0) const
TpetraCrsColorer(const Teuchos::RCP< matrix_t > &matrix_)
Kokkos::View< int *, device_t > list_of_colors_t
void computeSeedMatrixFitted(MultiVectorType &V, const int color_beg=0) const
list_of_colors_t::host_mirror_type list_of_colors_host_t
device_t::execution_space execution_space
Teuchos::RCP< const graph_t > graph
void computeColoring(Teuchos::ParameterList &coloring_params)
void reconstructMatrix(MultiVectorType &W, const int color_beg=0) const
list_of_colors_host_t list_of_colors_host
void reconstructMatrixFitted(MultiVectorType &W, const int color_beg=0) const
matrix_t::local_ordinal_type lno_t
int getColor(const size_t col) const
matrix_t::global_ordinal_type gno_t
void computeColoring(Teuchos::ParameterList &coloring_params, int &num_colors, list_of_colors_host_t &list_of_colors_host, list_of_colors_t &list_of_colors)
void computeColoring(Teuchos::ParameterList &coloring_params, int &num_colors, list_of_colors_host_t &list_of_colors_host, list_of_colors_t &list_of_colors) const
bool check_coloring(const Tpetra::CrsGraph< LO, GO, NO > &graph, const list_of_colors_t &list_of_colors)
Created by mbenlioglu on Aug 31, 2020.