Chi-Tech
PETScGraphPartitioner.cc
Go to the documentation of this file.
2
3#include "ChiObjectFactory.h"
4
5#include "petsc.h"
6
7#include "chi_runtime.h"
8#include "chi_log.h"
9
10namespace chi
11{
12
14
16{
18
19 params.SetGeneralDescription("PETSc based partitioning");
20 params.SetDocGroup("Graphs");
21
23 "type", "parmetis", "The type of PETSc partitioner");
24
25 return params;
26}
27
29 : GraphPartitioner(params), type_(params.GetParamValue<std::string>("type"))
30{
31}
32
34 const std::vector<std::vector<uint64_t>>& graph,
35 const std::vector<chi_mesh::Vector3>&,
36 int number_of_parts)
37{
38 Chi::log.Log0Verbose1() << "Partitioning with PETScGraphPartitioner";
39 //================================================== Determine avg num faces
40 // per cell
41 // This is done so we can reserve size better
42 const size_t num_raw_cells = graph.size();
43 size_t num_raw_faces = 0;
44 for (auto& cell_row : graph)
45 num_raw_faces += cell_row.size();
46 size_t avg_num_face_per_cell = std::ceil(static_cast<double>(num_raw_faces) /
47 static_cast<double>(num_raw_cells));
48
49 //================================================== Start building indices
50 std::vector<int64_t> cell_pids(num_raw_cells, 0);
51 if (num_raw_cells > 1)
52 {
53 //======================================== Build indices
54 std::vector<int64_t> i_indices(num_raw_cells + 1, 0);
55 std::vector<int64_t> j_indices;
56 j_indices.reserve(num_raw_cells * avg_num_face_per_cell);
57 {
58 int64_t i = 0;
59 int64_t icount = 0;
60 for (const auto& cell : graph)
61 {
62 i_indices[i] = icount;
63
64 for (const uint64_t neighbor_id : cell)
65 {
66 j_indices.push_back(static_cast<int64_t>(neighbor_id));
67 ++icount;
68 }
69 ++i;
70 }
71 i_indices[i] = icount;
72 }
73
74 Chi::log.Log0Verbose1() << "Done building indices.";
75
76 //======================================== Copy to raw arrays
77 int64_t* i_indices_raw;
78 int64_t* j_indices_raw;
79 PetscMalloc(i_indices.size() * sizeof(int64_t), &i_indices_raw);
80 PetscMalloc(j_indices.size() * sizeof(int64_t), &j_indices_raw);
81
82 for (int64_t j = 0; j < static_cast<int64_t>(i_indices.size()); ++j)
83 i_indices_raw[j] = i_indices[j];
84
85 for (int64_t j = 0; j < static_cast<int64_t>(j_indices.size()); ++j)
86 j_indices_raw[j] = j_indices[j];
87
88 Chi::log.Log0Verbose1() << "Done copying to raw indices.";
89
90 //========================================= Create adjacency matrix
91 Mat Adj; // Adjacency matrix
92 MatCreateMPIAdj(PETSC_COMM_SELF,
93 (int64_t)num_raw_cells,
94 (int64_t)num_raw_cells,
95 i_indices_raw,
96 j_indices_raw,
97 nullptr,
98 &Adj);
99
100 Chi::log.Log0Verbose1() << "Done creating adjacency matrix.";
101
102 //========================================= Create partitioning
103 MatPartitioning part;
104 IS is, isg;
105 MatPartitioningCreate(MPI_COMM_SELF, &part);
106 MatPartitioningSetAdjacency(part, Adj);
107 MatPartitioningSetType(part, type_.c_str());
108 MatPartitioningSetNParts(part, number_of_parts);
109 MatPartitioningApply(part, &is);
110 MatPartitioningDestroy(&part);
111 MatDestroy(&Adj);
112 ISPartitioningToNumbering(is, &isg);
113 Chi::log.Log0Verbose1() << "Done building paritioned index set.";
114
115 //========================================= Get cell global indices
116 const int64_t* cell_pids_raw;
117 ISGetIndices(is, &cell_pids_raw);
118 for (size_t i = 0; i < num_raw_cells; ++i)
119 cell_pids[i] = cell_pids_raw[i];
120 ISRestoreIndices(is, &cell_pids_raw);
121
122 Chi::log.Log0Verbose1() << "Done retrieving cell global indices.";
123 } // if more than 1 cell
124
125 Chi::log.Log0Verbose1() << "Done partitioning with PETScGraphPartitioner";
126 return cell_pids;
127}
128
129} // namespace chi
static chi::ChiLog & log
Definition: chi_runtime.h:81
LogStream Log0Verbose1()
Definition: chi_log.h:234
static InputParameters GetInputParameters()
void SetDocGroup(const std::string &doc_group)
void AddOptionalParameter(const std::string &name, T value, const std::string &doc_string)
void SetGeneralDescription(const std::string &description)
static InputParameters GetInputParameters()
std::vector< int64_t > Partition(const std::vector< std::vector< uint64_t > > &graph, const std::vector< chi_mesh::Vector3 > &centroids, int number_of_parts) override
PETScGraphPartitioner(const InputParameters &params)
RegisterChiObject(chi, KBAGraphPartitioner)
struct _p_Mat * Mat