CoreNEURON
lpt.cpp
Go to the documentation of this file.
1 /*
2 # =============================================================================
3 # Copyright (c) 2016 - 2021 Blue Brain Project/EPFL
4 #
5 # See top-level LICENSE file for details.
6 # =============================================================================
7 */
8 
9 #include <algorithm>
10 #include <functional>
11 #include <numeric>
12 #include <queue>
13 
14 #include "coreneuron/nrnconf.h" // for size_t
15 #include "coreneuron/utils/lpt.hpp"
17 
18 using P = std::pair<size_t, size_t>;
19 
20 // lpt Least Processing Time algorithm.
21 // Largest piece goes into least size bag.
22 // in: number of bags, vector of sizes
23 // return: a new vector of bag indices parallel to the vector of sizes.
24 
25 std::vector<std::size_t> lpt(std::size_t nbag, std::vector<std::size_t>& pieces, double* bal) {
26  nrn_assert(nbag > 0);
27  nrn_assert(!pieces.empty());
28 
29  std::vector<P> pvec;
30  for (size_t i = 0; i < pieces.size(); ++i) {
31  pvec.push_back(P(i, pieces[i]));
32  }
33 
34  auto P_comp = [](const P& a, const P& b) { return a.second > b.second; };
35 
36  std::sort(pvec.begin(), pvec.end(), P_comp);
37 
38  std::vector<std::size_t> bagindices(pieces.size());
39 
40  std::priority_queue<P, std::vector<P>, decltype(P_comp)> bagq(P_comp);
41  for (size_t i = 0; i < nbag; ++i) {
42  bagq.push(P(i, 0));
43  }
44 
45  for (const auto& p: pvec) {
46  P bagqitem = bagq.top();
47  bagq.pop();
48  bagindices[p.first] = bagqitem.first;
49  bagqitem.second += p.second;
50  bagq.push(bagqitem);
51  }
52 
53  // load balance average/max (1.0 is perfect)
54  std::vector<size_t> v(bagq.size());
55  for (size_t i = 1; i < nbag; ++i) {
56  v[i] = bagq.top().second;
57  bagq.pop();
58  }
59  double b = load_balance(v);
60  if (bal) {
61  *bal = b;
62  } else {
63  printf("load balance = %g for %ld pieces in %ld bags\n", b, pieces.size(), nbag);
64  }
65 
66  return bagindices;
67 }
68 
69 double load_balance(std::vector<size_t>& v) {
70  nrn_assert(!v.empty());
71  std::size_t sum = std::accumulate(v.begin(), v.end(), 0);
72  std::size_t max = *std::max_element(v.begin(), v.end());
73  return (double(sum) / v.size()) / max;
74 }
lpt.hpp
lpt
std::vector< std::size_t > lpt(std::size_t nbag, std::vector< std::size_t > &pieces, double *bal)
Definition: lpt.cpp:25
P
std::pair< size_t, size_t > P
Definition: lpt.cpp:18
i
#define i
Definition: md1redef.h:19
nrnconf.h
v
#define v
Definition: md1redef.h:11
nrn_assert
#define nrn_assert(x)
assert()-like macro, independent of NDEBUG status
Definition: nrn_assert.h:33
nrn_assert.h
load_balance
double load_balance(std::vector< size_t > &v)
Definition: lpt.cpp:69