DIY  3.0
data-parallel out-of-core C++ library
 All Classes Namespaces Functions Typedefs Groups Pages
assigner.hpp
1 #ifndef DIY_ASSIGNER_HPP
2 #define DIY_ASSIGNER_HPP
3 
4 #include <vector>
5 
6 namespace diy
7 {
8  // Derived types should define
9  // int rank(int gid) const
10  // that converts a global block id to a rank that it's assigned to.
11  class Assigner
12  {
13  public:
18  Assigner(int size__,
19  int nblocks__
20  ):
21  size_(size__), nblocks_(nblocks__) {}
22 
24  int size() const { return size_; }
26  int nblocks() const { return nblocks_; }
28  void set_nblocks(int nblocks__) { nblocks_ = nblocks__; }
30  virtual void local_gids(int rank, std::vector<int>& gids) const =0;
32  virtual int rank(int gid) const =0;
33 
34  private:
35  int size_; // total number of ranks
36  int nblocks_; // total number of blocks
37  };
38 
40  {
41  public:
46  ContiguousAssigner(int size__,
47  int nblocks__
48  ):
49  Assigner(size__, nblocks__) {}
50 
51  using Assigner::size;
52  using Assigner::nblocks;
53 
54  int rank(int gid) const override
55  {
56  int div = nblocks() / size();
57  int mod = nblocks() % size();
58  int r = gid / (div + 1);
59  if (r < mod)
60  {
61  return r;
62  } else
63  {
64  return mod + (gid - (div + 1)*mod)/div;
65  }
66  }
67  inline
68  void local_gids(int rank, std::vector<int>& gids) const override;
69  };
70 
72  {
73  public:
78  RoundRobinAssigner(int size__,
79  int nblocks__
80  ):
81  Assigner(size__, nblocks__) {}
82 
83  using Assigner::size;
84  using Assigner::nblocks;
85 
86  int rank(int gid) const override { return gid % size(); }
87  inline
88  void local_gids(int rank, std::vector<int>& gids) const override;
89  };
90 }
91 
92 void
94 local_gids(int rank_, std::vector<int>& gids) const
95 {
96  int div = nblocks() / size();
97  int mod = nblocks() % size();
98 
99  int from, to;
100  if (rank_ < mod)
101  from = rank_ * (div + 1);
102  else
103  from = mod * (div + 1) + (rank_ - mod) * div;
104 
105  if (rank_ + 1 < mod)
106  to = (rank_ + 1) * (div + 1);
107  else
108  to = mod * (div + 1) + (rank_ + 1 - mod) * div;
109 
110  for (int gid = from; gid < to; ++gid)
111  gids.push_back(gid);
112 }
113 
114 void
116 local_gids(int rank_, std::vector<int>& gids) const
117 {
118  int cur = rank_;
119  while (cur < nblocks())
120  {
121  gids.push_back(cur);
122  cur += size();
123  }
124 }
125 
126 #endif
void local_gids(int rank, std::vector< int > &gids) const override
gets the local gids for a given process rank
Definition: assigner.hpp:116
Definition: assigner.hpp:39
Assigner(int size__, int nblocks__)
Manages how blocks are assigned to processes.
Definition: assigner.hpp:18
Definition: assigner.hpp:71
int nblocks() const
returns the total number of global blocks
Definition: assigner.hpp:26
RoundRobinAssigner(int size__, int nblocks__)
Assigns blocks to processes in cyclic or round-robin gid (block global id) order. ...
Definition: assigner.hpp:78
virtual int rank(int gid) const =0
returns the process rank of the block with global id gid (need not be local)
int size() const
returns the total number of process ranks
Definition: assigner.hpp:24
ContiguousAssigner(int size__, int nblocks__)
Assigns blocks to processes in contiguous gid (block global id) order.
Definition: assigner.hpp:46
Definition: assigner.hpp:11
int rank(int gid) const override
returns the process rank of the block with global id gid (need not be local)
Definition: assigner.hpp:54
int rank(int gid) const override
returns the process rank of the block with global id gid (need not be local)
Definition: assigner.hpp:86
void local_gids(int rank, std::vector< int > &gids) const override
gets the local gids for a given process rank
Definition: assigner.hpp:94
virtual void local_gids(int rank, std::vector< int > &gids) const =0
gets the local gids for a given process rank
void set_nblocks(int nblocks__)
sets the total number of global blocks
Definition: assigner.hpp:28