HavoqGT
run_bfs.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013, Lawrence Livermore National Security, LLC.
3  * Produced at the Lawrence Livermore National Laboratory.
4  * Written by Roger Pearce <rpearce@llnl.gov>.
5  * LLNL-CODE-644630.
6  * All rights reserved.
7  *
8  * This file is part of HavoqGT, Version 0.1.
9  * For details, see https://computation.llnl.gov/casc/dcca-pub/dcca/Downloads.html
10  *
11  * Please also read this link – Our Notice and GNU Lesser General Public License.
12  * http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
13  *
14  * This program is free software; you can redistribute it and/or modify it under
15  * the terms of the GNU Lesser General Public License (as published by the Free
16  * Software Foundation) version 2.1 dated February 1999.
17  *
18  * This program is distributed in the hope that it will be useful, but WITHOUT ANY
19  * WARRANTY; without even the IMPLIED WARRANTY OF MERCHANTABILITY or FITNESS FOR A
20  * PARTICULAR PURPOSE. See the terms and conditions of the GNU General Public
21  * License for more details.
22  *
23  * You should have received a copy of the GNU Lesser General Public License along
24  * with this program; if not, write to the Free Software Foundation, Inc.,
25  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26  *
27  * OUR NOTICE AND TERMS AND CONDITIONS OF THE GNU GENERAL PUBLIC LICENSE
28  *
29  * Our Preamble Notice
30  *
31  * A. This notice is required to be provided under our contract with the
32  * U.S. Department of Energy (DOE). This work was produced at the Lawrence
33  * Livermore National Laboratory under Contract No. DE-AC52-07NA27344 with the DOE.
34  *
35  * B. Neither the United States Government nor Lawrence Livermore National
36  * Security, LLC nor any of their employees, makes any warranty, express or
37  * implied, or assumes any liability or responsibility for the accuracy,
38  * completeness, or usefulness of any information, apparatus, product, or process
39  * disclosed, or represents that its use would not infringe privately-owned rights.
40  *
41  * C. Also, reference herein to any specific commercial products, process, or
42  * services by trade name, trademark, manufacturer or otherwise does not
43  * necessarily constitute or imply its endorsement, recommendation, or favoring by
44  * the United States Government or Lawrence Livermore National Security, LLC. The
45  * views and opinions of authors expressed herein do not necessarily state or
46  * reflect those of the United States Government or Lawrence Livermore National
47  * Security, LLC, and shall not be used for advertising or product endorsement
48  * purposes.
49  *
50  */
51 
52 #include <havoqgt/page_rank.hpp>
53 #include <havoqgt/environment.hpp>
61 
62 #include <boost/bind.hpp>
63 #include <boost/function.hpp>
64 
66 #include <assert.h>
67 
68 #include <deque>
69 #include <string>
70 #include <utility>
71 #include <algorithm>
72 #include <functional>
73 
74 #include <boost/interprocess/managed_heap_memory.hpp>
75 
76 namespace hmpi = havoqgt::mpi;
77 using namespace havoqgt::mpi;
78 using namespace havoqgt;
79 
80 void usage() {
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 }
88 
89 void parse_cmd_line(int argc, char** argv, std::string& input_filename, uint64_t& source_vertex) {
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 }
126 
127 int main(int argc, char** argv) {
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
void usage()
Definition: run_bfs.cpp:80
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
environment * havoqgt_env()
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
int main(int argc, char **argv)
Definition: run_bfs.cpp:127
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)