HavoqGT
run_bfs.cpp File Reference
#include <havoqgt/page_rank.hpp>
#include <havoqgt/environment.hpp>
#include <havoqgt/cache_utilities.hpp>
#include <havoqgt/rmat_edge_generator.hpp>
#include <havoqgt/breadth_first_search.hpp>
#include <havoqgt/delegate_partitioned_graph.hpp>
#include <havoqgt/upper_triangle_edge_generator.hpp>
#include <havoqgt/single_source_shortest_path.hpp>
#include <havoqgt/gen_preferential_attachment_edge_list.hpp>
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <havoqgt/distributed_db.hpp>
#include <assert.h>
#include <deque>
#include <string>
#include <utility>
#include <algorithm>
#include <functional>
#include <boost/interprocess/managed_heap_memory.hpp>
Include dependency graph for run_bfs.cpp:

Go to the source code of this file.

Functions

void usage ()
 
void parse_cmd_line (int argc, char **argv, std::string &input_filename, uint64_t &source_vertex)
 
int main (int argc, char **argv)
 

Function Documentation

int main ( int  argc,
char **  argv 
)

Definition at line 127 of file run_bfs.cpp.

127  {
130 
131  int mpi_rank(0), mpi_size(0);
132 
133  havoqgt::havoqgt_init(&argc, &argv);
134  {
135  CHK_MPI(MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank));
136  CHK_MPI(MPI_Comm_size(MPI_COMM_WORLD, &mpi_size));
138 
139  if (mpi_rank == 0) {
140  std::cout << "MPI initialized with " << mpi_size << " ranks." << std::endl;
142  //print_system_info(false);
143  }
144  MPI_Barrier(MPI_COMM_WORLD);
145 
146 
147  std::string graph_input;
148  uint64_t source_vertex = 0;
149 
150  parse_cmd_line(argc, argv, graph_input, source_vertex);
151 
152  MPI_Barrier(MPI_COMM_WORLD);
153 
154  havoqgt::distributed_db ddb(havoqgt::db_open(), graph_input.c_str());
155 
156  graph_type *graph = ddb.get_segment_manager()->
157  find<graph_type>("graph_obj").first;
158  assert(graph != nullptr);
159 
160  MPI_Barrier(MPI_COMM_WORLD);
161  if (mpi_rank == 0) {
162  std::cout << "Graph Loaded Ready." << std::endl;
163  }
164  //graph->print_graph_statistics();
165  MPI_Barrier(MPI_COMM_WORLD);
166 
167 
168  // BFS Experiments
169  {
170 
173  MPI_Barrier(MPI_COMM_WORLD);
174  if (mpi_rank == 0) {
175  std::cout << "BFS data allocated. Starting BFS from vertex " << source_vertex << std::endl;
176  }
177 
178  // Run BFS experiments
179  double time(0);
180  int count(0);
181  uint64_t isource = source_vertex;
182  graph_type::vertex_locator source = graph->label_to_locator(isource);
183  uint64_t global_degree(0);
184  do {
185  uint64_t local_degree = 0;
186  source = graph->label_to_locator(isource);
187  if (source.is_delegate()) {
188  break;
189  }
190  if (uint32_t(mpi_rank) == source.owner()) {
191  local_degree = graph->degree(source);
192  }
193  global_degree = mpi_all_reduce(local_degree, std::greater<uint64_t>(),
194  MPI_COMM_WORLD);
195  if(global_degree == 0) ++isource;
196  } while (global_degree == 0);
197  if (uint32_t(mpi_rank) == source.owner()) {
198  if(isource != source_vertex) {
199  std::cout << "Vertex " << source_vertex << " has a degree of 0. New source vertex = " << isource << std::endl;
200  } else {
201  std::cout << "Starting vertex = " << isource << std::endl;
202  }
203  std::cout << "delegate? = " << source.is_delegate() << std::endl;
204  std::cout << "local_id = " << source.local_id() << std::endl;
205  std::cout << "degree = " << graph->degree(source) << std::endl;
206  }
207 
208  bfs_level_data.reset(128);
209 
210  MPI_Barrier(MPI_COMM_WORLD);
211  double time_start = MPI_Wtime();
212  hmpi::breadth_first_search(graph, bfs_level_data, bfs_parent_data,
213  source);
214  MPI_Barrier(MPI_COMM_WORLD);
215  double time_end = MPI_Wtime();
216 
217  uint64_t visited_total(0);
218  for (uint64_t level = 0; level < 15; ++level) {
219  uint64_t local_count(0);
221  for (vitr = graph->vertices_begin();
222  vitr != graph->vertices_end();
223  ++vitr) {
224  if (bfs_level_data[*vitr] == level) {
225  ++local_count;
226  }
227  }
228 
229  // Count the controllers!
231  for (citr = graph->controller_begin();
232  citr != graph->controller_end();
233  ++citr) {
234  if (bfs_level_data[*citr] == level) {
235  ++local_count;
236  }
237  }
238 
239  uint64_t global_count = mpi_all_reduce(local_count,
240  std::plus<uint64_t>(), MPI_COMM_WORLD);
241  visited_total += global_count;
242  if (mpi_rank == 0 && global_count > 0) {
243  std::cout << "Level " << level << ": " << global_count << std::endl;
244  }
245  if (global_count == 0) {
246  break;
247  }
248  } // end for level
249 
250  if (mpi_rank == 0) {
251  if (visited_total > 1) {
252  std::cout
253  << "Visited total = " << visited_total << std::endl
254  << "BFS Time = " << time_end - time_start << std::endl;
255  time += time_end - time_start;
256  ++count;
257  }
258  }
259  if (mpi_rank == 0) {
260  std::cout << "Count BFS = " << count << std::endl;
261  std::cout << "AVERAGE BFS = " << time / double(count) << std::endl;
262  }
263  } // End BFS Test
264  } // END Main MPI
266 
267  return 0;
268 }
hmpi::delegate_partitioned_graph< segment_manager_t > graph_type
bip::vector< vertex_locator, SegmentAllocator< vertex_locator > >::const_iterator controller_iterator
void havoqgt_finalize()
T mpi_all_reduce(T in_d, Op in_op, MPI_Comm mpi_comm)
Definition: mpi.hpp:176
mapped_type::segment_manager segment_manager_type
segment_manager_type * get_segment_manager()
old_environment & get_environment()
#define CHK_MPI(a)
Definition: mpi.hpp:68
void breadth_first_search(TGraph *g, LevelData &level_data, ParentData &parent_data, typename TGraph::vertex_locator s)
void parse_cmd_line(int argc, char **argv, std::string &input_filename, uint64_t &source_vertex)
Definition: run_bfs.cpp:89
havoqgt::distributed_db::segment_manager_type segment_manager_t
void havoqgt_init(int *argc, char ***argv)

Here is the call graph for this function:

void parse_cmd_line ( int  argc,
char **  argv,
std::string &  input_filename,
uint64_t &  source_vertex 
)

Definition at line 89 of file run_bfs.cpp.

89  {
90  if(havoqgt_env()->world_comm().rank() == 0) {
91  std::cout << "CMD line:";
92  for (int i=0; i<argc; ++i) {
93  std::cout << " " << argv[i];
94  }
95  std::cout << std::endl;
96  }
97 
98  bool found_input_filename = false;
99  source_vertex = 0;
100 
101  char c;
102  bool prn_help = false;
103  while ((c = getopt(argc, argv, "i:s:h ")) != -1) {
104  switch (c) {
105  case 'h':
106  prn_help = true;
107  break;
108  case 's':
109  source_vertex = atoll(optarg);
110  break;
111  case 'i':
112  found_input_filename = true;
113  input_filename = optarg;
114  break;
115  default:
116  std::cerr << "Unrecognized option: "<<c<<", ignore."<<std::endl;
117  prn_help = true;
118  break;
119  }
120  }
121  if (prn_help || !found_input_filename) {
122  usage();
123  exit(-1);
124  }
125 }
void usage()
Definition: run_bfs.cpp:80
environment * havoqgt_env()

Here is the call graph for this function:

Here is the caller graph for this function:

void usage ( )

Definition at line 80 of file run_bfs.cpp.

80  {
81  if(havoqgt_env()->world_comm().rank() == 0) {
82  std::cerr << "Usage: -i <string> -s <int>\n"
83  << " -i <string> - input graph base filename (required)\n"
84  << " -s <int> - Source vertex of BFS (Default is 0)\n"
85  << " -h - print help and exit\n\n";
86  }
87 }
environment * havoqgt_env()

Here is the call graph for this function:

Here is the caller graph for this function: