1 #pragma once
2 #include "./graph_base.hpp"
3 
4 /*
5    o
6  / | \
7 o  o  o
8  \ | /
9    o
10  / | \
11 o  o  o
12  \ | /
13    o
14 */
15 class Diamond: public Graph {
16 
17   public:
18 
19     Diamond(int num_partitions, int num_iterations);
20 
21     ~Diamond();
22 
23   private:
24 
25     int _num_partitions;
26     int _num_iterations;
27 };
28 
Diamond(int num_partitions,int num_iterations)29 Diamond::Diamond(int num_partitions, int num_iterations):
30 Graph{3 + 2 * (num_iterations - 1)},
31 _num_partitions{num_partitions},
32 _num_iterations{num_iterations}
33 {
34   _graph.resize(3 + 2 * (num_iterations - 1));
35 
36   std::vector<size_t> map_out_nodes(num_partitions);
37   std::iota(map_out_nodes.begin(), map_out_nodes.end(), 0);
38 
39   _graph[0].emplace_back(0, 0, map_out_nodes);
40 
41   for(int iter = 0; iter < _num_iterations; ++iter) {
42     std::vector<size_t> map_out_nodes(num_partitions);
43     std::iota(map_out_nodes.begin(), map_out_nodes.end(), 0);
44     int cur_level = 2 * iter + 1;
45     int next_level = 2 * iter + 2;
46 
47     std::vector<Node> map_nodes;
48     for(int i = 0; i < _num_partitions; ++i) {
49       std::vector<size_t> reduce_out_nodes(1, 0);
50       map_nodes.emplace_back(cur_level, i, reduce_out_nodes);
51     }
52 
53     _graph[cur_level] = std::move(map_nodes);
54     _graph[next_level].emplace_back(next_level, 0, map_out_nodes);
55   }
56 
57   _num_nodes = 1 + 4 * (num_iterations);
58   allocate_nodes();
59 }
60 
~Diamond()61 Diamond::~Diamond() {
62   free_nodes();
63 }
64