parallel-cellular-automata
Framework for building parallel cellular automata.
parallel_automaton.hpp
Go to the documentation of this file.
1 
13 #ifndef PARALLEL_CELLULAR_AUTOMATA_PARALLEL_AUTOMATON_HPP
14 #define PARALLEL_CELLULAR_AUTOMATA_PARALLEL_AUTOMATON_HPP
15 
16 #ifndef PARALLEL_CELLULAR_AUTOMATA_CELLULAR_AUTOMATA_HPP
17 #include "cellular_automata.hpp"
18 #endif
19 #include <barrier.hpp>
20 #include <grid.hpp>
21 #include <stdexcept>
22 #include <thread>
23 #include <threadpool.hpp>
24 #include <vector>
25 
26 using namespace std;
27 
28 namespace ca
29 {
34 namespace par
35 {
36 template <typename T>
38 {
39  public:
50  CellularAutomaton(ca::Grid<T> &grid, std::function<T(T, T, T, T, T, T, T, T, T)> update_function,
51  unsigned workers = 0)
52  : grid{grid}, generation(0), update_function(update_function), pool(workers)
53  {
54 
55  this->nw = pool.get_number_workers();
56  };
64  {
65  // move what's movable and copying numeric types.
66  grid = std::move(other.grid);
67  generation = other.generation;
68  update_function = other.update_function;
69  nw = other.nw;
70  pool = std::move(other.pool);
71  // set the old object in a valid state
72  other.generation = 0;
73  }
74 
82  CellularAutomaton(const CellularAutomaton &other) = delete;
83 
91  virtual void simulate(unsigned steps = 1)
92  {
93  if (steps == 0)
94  return;
95  // allocate new grid
96  Grid<T> new_grid = Grid<T>::newWithSameSize(grid);
97 
98  ca::Barrier sync_point(nw);
99 
100  auto step_advancement_fun = [&]() {
101  grid.swap(new_grid);
102  ++generation;
103  --steps;
104  };
105 
106  // function to be run by each thread
107  auto work = [&, this](unsigned start, unsigned end) {
108  while (steps > 0)
109  {
110  for (unsigned r{start}; r < end; ++r)
111  {
112  for (unsigned c{0}; c < grid.columns(); ++c)
113  {
114  auto cell = std::make_tuple(grid(r, c));
115  new_grid(r, c) =
116  std::apply(this->update_function, std::tuple_cat(cell, get_neighborhood(r, c)));
117  }
118  }
119  sync_point.wait(
120  step_advancement_fun); // this gets executed only by the last thread to reach the barrier
121  }
122  };
123 
124  std::vector<std::future<void>> results; // handles for waiting the threads
125  unsigned delta{static_cast<unsigned>(grid.rows()) / nw};
126 
127  for (unsigned i{0}; i < nw; i++) // split the grid
128  {
129  unsigned start = i * delta;
130  unsigned end = (i != (nw - 1) ? (i + 1) * delta : grid.rows());
131 
132  results.push_back(pool.submit(work, start, end));
133  }
134 
135  for (auto &r : results)
136  {
137  r.wait();
138  }
139  }
140 
146  virtual size_t get_generation() const
147  {
148  return generation;
149  }
159  friend std::ostream &operator<<(std::ostream &os, const CellularAutomaton &ca)
160  {
161 
162  return os << ca.grid;
163  }
164 
165  protected:
171 
176  size_t generation;
187  std::function<T(T, T, T, T, T, T, T, T, T)> update_function;
206  virtual std::tuple<T, T, T, T, T, T, T, T> get_neighborhood(int row, int col) const
207  {
208  unsigned rows = grid.rows();
209  unsigned columns = grid.columns();
210  T top_left, top, top_right, left, right, bottom_left, bottom, bottom_right;
211  top_left = grid((row - 1 + rows) % rows, (col - 1 + columns) % columns);
212  top = grid((row - 1 + rows) % rows, col);
213  top_right = grid((row - 1 + rows) % rows, (col + 1) % columns);
214  left = grid(row, (col - 1 + columns) % columns);
215  right = grid(row, (col + 1) % columns);
216  bottom_left = grid((row + 1) % rows, (col - 1 + columns) % columns);
217  bottom = grid((row + 1) % rows, col);
218  bottom_right = grid((row + 1) % rows, (col + 1) % columns);
219  return std::make_tuple(top_left, top, top_right, left, right, bottom_left, bottom, bottom_right);
220  };
225  unsigned nw;
226 
232 };
233 } // namespace par
234 } // namespace ca
235 #endif
This file contains the definition of a barrier for thread synchronization.
This header imports all the other headers of the framework.
Self-resetting synchronization barrier for threads.
Definition: barrier.hpp:27
void wait()
wait for the other threads to reach the barrier.
Definition: barrier.cpp:23
Grid of the cellular automaton.
Definition: grid.hpp:31
size_t columns() const
Returns the number of columns of the grid.
Definition: grid.hpp:200
void swap(Grid &other)
Swap the content of the grid with the one of another grid.
Definition: grid.hpp:243
size_t rows() const
Returns the number of rows of the grid.
Definition: grid.hpp:191
Work-stealing threadpool.
Definition: threadpool.hpp:51
Definition: parallel_automaton.hpp:38
CellularAutomaton(const CellularAutomaton &other)=delete
Deleted copy constructor.
virtual size_t get_generation() const
Get the generation of the simulation.
Definition: parallel_automaton.hpp:146
virtual void simulate(unsigned steps=1)
Run the simulation for a given number of steps.
Definition: parallel_automaton.hpp:91
std::function< T(T, T, T, T, T, T, T, T, T)> update_function
Function used to compute the next state of the cell.
Definition: parallel_automaton.hpp:187
virtual std::tuple< T, T, T, T, T, T, T, T > get_neighborhood(int row, int col) const
Get the neighborhood of a cell.
Definition: parallel_automaton.hpp:206
CellularAutomaton(CellularAutomaton &&other)
Construct a new Cellular Automaton object from another one using move semantic.
Definition: parallel_automaton.hpp:63
unsigned nw
Number of worker threads.
Definition: parallel_automaton.hpp:220
Grid< T > & grid
Grid of the C.A.
Definition: parallel_automaton.hpp:170
Threadpool pool
The threadpool that will run the tasks.
Definition: parallel_automaton.hpp:231
size_t generation
Current generation of the grid.
Definition: parallel_automaton.hpp:176
friend std::ostream & operator<<(std::ostream &os, const CellularAutomaton &ca)
Overload of the << operator.
Definition: parallel_automaton.hpp:159
CellularAutomaton(ca::Grid< T > &grid, std::function< T(T, T, T, T, T, T, T, T, T)> update_function, unsigned workers=0)
Construct a new Cellular Automaton object.
Definition: parallel_automaton.hpp:50
Definition of the grid of the automaton.
Namespace of the framework.
Definition: barrier.hpp:20
definition of a threadpool.