33inline std::uint64_t
part1by1(std::uint64_t x) {
35 x = (x | (x << 16)) & 0x0000ffff0000ffffULL;
36 x = (x | (x << 8)) & 0x00ff00ff00ff00ffULL;
37 x = (x | (x << 4)) & 0x0f0f0f0f0f0f0f0fULL;
38 x = (x | (x << 2)) & 0x3333333333333333ULL;
39 x = (x | (x << 1)) & 0x5555555555555555ULL;
44inline std::uint64_t
morton_key(std::uint32_t x, std::uint32_t y) {
51 const int n = ba.
size();
52 std::vector<int> order(n);
53 std::iota(order.begin(), order.end(), 0);
57 std::vector<std::uint64_t> key(n);
58 for (
int i = 0; i < n; ++i)
59 key[i] =
morton_key(
static_cast<std::uint32_t
>(ba[i].lo[0] - bb.
lo[0]),
60 static_cast<std::uint32_t
>(ba[i].lo[1] - bb.
lo[1]));
61 std::sort(order.begin(), order.end(), [&](
int a,
int b) { return key[a] < key[b]; });
68 const int n = ba.
size();
69 std::vector<int> rank(n, 0);
70 if (n == 0 || nranks <= 1)
75 const double target = double(total) / nranks;
79 for (
int k = 0; k < n; ++k) {
80 const int b = order[k];
85 const int boxes_left = n - 1 - k;
86 const int ranks_left = nranks - 1 - r;
87 if (r < nranks - 1 && acc >= target * (r + 1) && boxes_left >= ranks_left)
95 const int n = ba.
size();
96 std::vector<int> rank(n, 0);
97 if (n == 0 || nranks <= 1)
100 std::vector<int> order(n);
101 std::iota(order.begin(), order.end(), 0);
102 std::sort(order.begin(), order.end(),
103 [&](
int a,
int b) { return ba[a].num_cells() > ba[b].num_cells(); });
105 std::vector<std::int64_t> load(nranks, 0);
106 for (
int b : order) {
108 for (
int q = 1; q < nranks; ++q)
109 if (load[q] < load[r])
119 if (nranks <= 0 || ba.
size() == 0)
121 std::vector<std::int64_t> load(nranks, 0);
122 for (
int i = 0; i < ba.
size(); ++i)
123 load[dm[i]] += ba[i].num_cells();
124 std::int64_t mx = 0,
sum = 0;
125 for (std::int64_t l : load) {
126 mx = std::max(mx, l);
129 const double avg = double(
sum) / nranks;
130 return avg > 0 ? mx / avg : 1.0;
BoxArray: the set of boxes tiling a level (disjoint, covering).
Ordered list of boxes tiling a level.
Definition box_array.hpp:22
std::int64_t num_cells() const
Total number of valid cells (sum of num_cells over all boxes).
Definition box_array.hpp:49
int size() const
Number of boxes in the tiling.
Definition box_array.hpp:42
Box2D bounding_box() const
Smallest box enclosing all boxes (empty box if the tiling is empty).
Definition box_array.hpp:57
Owning MPI rank of each box, indexed by GLOBAL box index (parallel to a BoxArray).
Definition distribution_mapping.hpp:19
DistributionMapping: maps each box (by global index) to its owning MPI rank.
Definition amr_hierarchy.hpp:29
double load_imbalance(const BoxArray &ba, const DistributionMapping &dm, int nranks)
Definition load_balance.hpp:118
std::uint64_t part1by1(std::uint64_t x)
Definition load_balance.hpp:33
Real sum(const MultiFab &mf, int comp=0)
Sum of the VALID cells of component comp, reduced over ALL ranks (all_reduce).
Definition multifab.hpp:121
DistributionMapping make_sfc_distribution(const BoxArray &ba, int nranks)
Definition load_balance.hpp:67
std::uint64_t morton_key(std::uint32_t x, std::uint32_t y)
Definition load_balance.hpp:44
std::vector< int > morton_order(const BoxArray &ba)
Definition load_balance.hpp:50
DistributionMapping make_knapsack_distribution(const BoxArray &ba, int nranks)
Definition load_balance.hpp:94
2D integer index space, cell-centered.
Definition box2d.hpp:37
int lo[2]
Definition box2d.hpp:38