OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
RandomStrategy.h
Go to the documentation of this file.
1 #ifndef __RANDOM_STRATEGY_H__
2 #define __RANDOM_STRATEGY_H__
3 
4 #include <set>
5 
7 
8 #include <boost/random/mersenne_twister.hpp>
9 #include <boost/random/uniform_int_distribution.hpp>
10 
14 class RandomStrategy : protected SplitStrategy {
15 
16 public:
17 
18  RandomStrategy(size_t num_masters, boost::shared_ptr<CommTopology> topology,
19  MPI_Comm comm = MPI_COMM_WORLD)
20  : SplitStrategy(num_masters, topology, comm) {
21 
23  }
24 
25 
26  virtual ~RandomStrategy()
27  {}
28 
29 
30  void split() {
31  // we start by randomly picking processor IDs for the specified
32  // number of masters
33  std::vector<int> master_pids;
34  for(int i=0; i < num_masters_; i++)
35  master_pids.push_back(nextRandomPid());
36 
37  int num_workers = pids_.size();
38  int num_assigned_masters = 0;
39 
40  // assign workers uniform at random to each master
41  for(int master_pid : master_pids) {
42 
43  if(master_pid == rank_) role_ = Role_t.POLLER;
44 
45  // compute number of workers for this master
46  int fraction_workers = num_workers / num_masters_ ;
47  if(num_assigned_masters < num_workers % num_masters_)
48  fraction_workers++;
49 
50  std::vector<int> worker_pids;
51 
52  for(int j = 0; j < fraction_workers; j++) {
53  int worker_pid = nextRandomPid();
54  if(worker_pid == rank_) role_ = Role_t.WORKER;
55  worker_pids.push_back(worker_pid);
56  }
57 
58  if(role_ == Role_t.POLLER || role_ == Role_t.WORKER)
59  addCommGroup(master_pid, worker_pids);
60 
61  num_assigned_masters++;
62  }
63  }
64 
65 
66 private:
67 
68  std::set<int> pids_;
69  boost::random::mt19937 rng_;
70 
71 
72  void fillPids(int num) {
73  for(int i=0; i < num; i++)
74  pids_.insert(i);
75  }
76 
77 
78  int nextRandomPid() {
79  boost::random::uniform_int_distribution<> random_pid(0,pids_.size()-1);
80  int pid_idx= random_pid(rng_);
81 
82  int pid = 0;
84 
85  for(itr = pids_.begin(); itr != pids_.end(); itr++, pid_idx--) {
86  if(pid_idx == 0) {
87  pid = *itr;
88  pids_.erase(itr);
89  break;
90  }
91  }
92 
93  return pid;
94  }
95 
96 };
97 
98 #endif
void fillPids(int num)
Role_t
roles a processor can attain
Definition: Types.h:20
boost::random::mt19937 rng_
RandomStrategy(size_t num_masters, boost::shared_ptr< CommTopology > topology, MPI_Comm comm=MPI_COMM_WORLD)
virtual ~RandomStrategy()
std::set< int > pids_
std::string::iterator iterator
Definition: MSLang.h:16
Defines an interface for splitter strategy implementations.
Definition: SplitStrategy.h:13