Chi-Tech
KBAGraphPartitioner.cc
Go to the documentation of this file.
2
3#include "ChiObjectFactory.h"
4#include "utils/chi_utils.h"
5
6#include "mesh/chi_mesh.h"
7
8#include "chi_runtime.h"
9#include "chi_log.h"
10
11#include <cmath>
12
13namespace chi
14{
15
17
19{
21
23 "Koch, Baker and Alcouffe based partitioning. "
24 "This is an overlayed ortho-grid based partitioner");
25 params.SetDocGroup("Graphs");
26
27 params.AddOptionalParameter("nx", 1, "The number of partitions in x");
28 params.AddOptionalParameter("ny", 1, "The number of partitions in y");
29 params.AddOptionalParameter("nz", 1, "The number of partitions in z");
30
32 "xcuts",
33 std::vector<double>{},
34 "Location of the internal x-cuts. Require nx-1 entries");
36 "ycuts",
37 std::vector<double>{},
38 "Location of the internal y-cuts. Require ny-1 entries");
40 "zcuts",
41 std::vector<double>{},
42 "Location of the internal z-cuts. Require nz-1 entries");
43
44 return params;
45}
46
48 : GraphPartitioner(params),
49 nx_(params.GetParamValue<size_t>("nx")),
50 ny_(params.GetParamValue<size_t>("ny")),
51 nz_(params.GetParamValue<size_t>("nz")),
52 xcuts_(params.GetParamVectorValue<double>("xcuts")),
53 ycuts_(params.GetParamVectorValue<double>("ycuts")),
54 zcuts_(params.GetParamVectorValue<double>("zcuts")),
55 coordinate_infos_{CoordinateInfo{&xcuts_, nx_, "x"},
56 CoordinateInfo{&ycuts_, ny_, "y"},
57 CoordinateInfo{&zcuts_, nz_, "z"}}
58{
59 for (const auto& [cuts_ptr, n, name] : coordinate_infos_)
60 {
61 const auto& cuts = *cuts_ptr;
62
63 //======================= Check number of items
64 if (cuts.size() != (n - 1))
65 ChiInvalidArgument("The number of cuts supplied for \"" + name +
66 "cuts\" is not equal to n" + name + "-1.");
67 if (cuts.empty()) continue;
68
69 //======================= Check monitonically increasing
70 {
71 double prev_value = 0.0;
72 for (const double cut_value : *cuts_ptr)
73 {
74 ChiInvalidArgumentIf(cut_value != cuts.front() and
75 cut_value <= prev_value,
76 "Parameter \"" + name +
77 "\" requires monotonically increasing values");
78 prev_value = cut_value;
79 }
80 } // for cut value
81 } // for each coordinate
82}
83
84std::vector<int64_t>
85KBAGraphPartitioner::Partition(const std::vector<std::vector<uint64_t>>& graph,
86 const std::vector<chi_mesh::Vector3>& centroids,
87 int number_of_parts)
88{
89 Chi::log.Log0Verbose1() << "Partitioning with KBAGraphPartitioner";
90
92 centroids.size() != graph.size(),
93 "Graph number of entries not equal to centroids' number of entries.");
94 const size_t num_cells = graph.size();
95 std::vector<int64_t> pids(num_cells, 0);
96 for (size_t c = 0; c < num_cells; ++c)
97 {
98 const auto& point = centroids[c];
99 // Partitions the point
100 std::array<size_t, 3> p_vals = {0, 0, 0};
101 for (size_t i = 0; i < 3; ++i)
102 {
103 const auto& cuts = *coordinate_infos_[i].cuts_;
104 const size_t num_cuts = cuts.size();
105
106 size_t p_val;
107 bool home_found = false;
108 for (size_t j = 0; j < num_cuts; ++j)
109 if (cuts[j] > point[i])
110 {
111 p_val = j;
112 home_found = true;
113 break;
114 }
115
116 p_vals[i] = home_found ? p_val : (coordinate_infos_[i].n_ - 1);
117 }
118
119 const int64_t nx = static_cast<int64_t>(coordinate_infos_[0].n_);
120 const int64_t ny = static_cast<int64_t>(coordinate_infos_[1].n_);
121
122 const int64_t i = static_cast<int64_t>(p_vals[0]);
123 const int64_t j = static_cast<int64_t>(p_vals[1]);
124 const int64_t k = static_cast<int64_t>(p_vals[2]);
125
126 pids[c] = nx * ny * k + nx * j + i;
127 } // for cell c
128
129 if ((nx_ * ny_ * nz_) != number_of_parts)
130 Chi::log.Log0Warning()
131 << "KBAGraphPartitioner::Partition nx_*ny_*nz_ != number_of_parts";
132
133 const auto pid_subsets = chi::MakeSubSets(nx_ * ny_ * nz_, number_of_parts);
134
135 std::vector<int64_t> real_pids(num_cells, 0);
136 for (size_t c = 0; c < num_cells; ++c)
137 {
138 for (size_t p = 0; p < number_of_parts; ++p)
139 {
140 if (pids[c] >= pid_subsets[p].ss_begin and
141 pids[c] <= pid_subsets[p].ss_end)
142 real_pids[c] = static_cast<int64_t>(p);
143 }
144 }
145
146 Chi::log.Log0Verbose1() << "Done partitioning with KBAGraphPartitioner";
147
148 return real_pids;
149}
150
151} // namespace chi
#define ChiLogicalErrorIf(condition, message)
#define ChiInvalidArgumentIf(condition, message)
#define ChiInvalidArgument(message)
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)
std::array< CoordinateInfo, 3 > coordinate_infos_
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
KBAGraphPartitioner(const InputParameters &params)
std::vector< SubSetInfo > MakeSubSets(size_t num_items, size_t desired_num_subsets)
Definition: subsets.cc:10
RegisterChiObject(chi, KBAGraphPartitioner)