HavoqGT
ingest_edge_list.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 <boost/bind.hpp>
53 #include <boost/function.hpp>
56 #include <havoqgt/environment.hpp>
59 #include <iostream>
60 #include <assert.h>
61 #include <deque>
62 #include <utility>
63 #include <algorithm>
64 #include <functional>
65 #include <fstream> // std::ifstream
66 #include <unistd.h>
67 
68 
69 // notes for how to setup a good test
70 // take rank * 100 and make edges between (all local)
71 // Make one vert per rank a hub.
72 
73 using namespace havoqgt;
74 namespace hmpi = havoqgt::mpi;
75 using namespace havoqgt::mpi;
76 
79 
80 void usage() {
81  if(havoqgt_env()->world_comm().rank() == 0) {
82  std::cerr << "Usage: -o <string> -d <int> [file ...]\n"
83  << " -o <string> - output graph base filename (required)\n"
84  << " -d <int> - delegate threshold (Default is 1048576)\n"
85  << " -h - print help and exit\n"
86  << "[file ...] - list of edge list files to ingest\n\n";
87  }
88 }
89 
90 void parse_cmd_line(int argc, char** argv, std::string& output_filename, uint64_t& delegate_threshold, std::vector< std::string >& input_filenames) {
91  if(havoqgt_env()->world_comm().rank() == 0) {
92  std::cout << "CMD line:";
93  for (int i=0; i<argc; ++i) {
94  std::cout << " " << argv[i];
95  }
96  std::cout << std::endl;
97  }
98 
99  bool found_output_filename = false;
100  delegate_threshold = 1048576;
101  input_filenames.clear();
102 
103  char c;
104  bool prn_help = false;
105  while ((c = getopt(argc, argv, "o:d:h ")) != -1) {
106  switch (c) {
107  case 'h':
108  prn_help = true;
109  break;
110  case 'd':
111  delegate_threshold = atoll(optarg);
112  break;
113  case 'o':
114  found_output_filename = true;
115  output_filename = optarg;
116  break;
117  default:
118  std::cerr << "Unrecognized option: "<<c<<", ignore."<<std::endl;
119  prn_help = true;
120  break;
121  }
122  }
123  if (prn_help || !found_output_filename) {
124  usage();
125  exit(-1);
126  }
127 
128  for (int index = optind; index < argc; index++) {
129  std::cout << "Input file = " << argv[index] << std::endl;
130  input_filenames.push_back(argv[index]);
131  }
132 }
133 
134 
135 int main(int argc, char** argv) {
136 
137  int mpi_rank(0), mpi_size(0);
138 
139  havoqgt_init(&argc, &argv);
140  {
141  int mpi_rank = havoqgt_env()->world_comm().rank();
142  int mpi_size = havoqgt_env()->world_comm().size();
144 
145  if (mpi_rank == 0) {
146  std::cout << "MPI initialized with " << mpi_size << " ranks." << std::endl;
148  }
150 
151  std::string output_filename;
152  uint64_t delegate_threshold;
153  std::vector< std::string > input_filenames;
154 
155  parse_cmd_line(argc, argv, output_filename, delegate_threshold, input_filenames);
156 
157  if (mpi_rank == 0) {
158  std::cout << "Ingesting graph from " << input_filenames.size() << " files." << std::endl;
159  }
160 
161  havoqgt::distributed_db ddb(havoqgt::db_create(), output_filename.c_str());
162 
163  segment_manager_t* segment_manager = ddb.get_segment_manager();
164  bip::allocator<void, segment_manager_t> alloc_inst(segment_manager);
165 
166  //Setup edge list reader
167  havoqgt::parallel_edge_list_reader pelr(input_filenames);
168 
169 
170  if (mpi_rank == 0) {
171  std::cout << "Generating new graph." << std::endl;
172  }
173  graph_type *graph = segment_manager->construct<graph_type>
174  ("graph_obj")
175  (alloc_inst, MPI_COMM_WORLD, pelr, pelr.max_vertex_id(), delegate_threshold);
176 
177 
179  if (mpi_rank == 0) {
180  std::cout << "Graph Ready, Calculating Stats. " << std::endl;
181  }
182 
183 
184 
185  for (int i = 0; i < mpi_size; i++) {
186  if (i == mpi_rank) {
187  double percent = double(segment_manager->get_free_memory()) /
188  double(segment_manager->get_size());
189  std::cout << "[" << mpi_rank << "] " << segment_manager->get_free_memory()
190  << "/" << segment_manager->get_size() << " = " << percent << std::endl;
191  }
193  }
194 
195  graph->print_graph_statistics();
196 
197 
198  //
199  // Calculate max degree
200  uint64_t max_degree(0);
201  for (auto citr = graph->controller_begin(); citr != graph->controller_end(); ++citr) {
202  max_degree = std::max(max_degree, graph->degree(*citr));
203  }
204 
205  uint64_t global_max_degree = havoqgt::mpi::mpi_all_reduce(max_degree, std::greater<uint64_t>(), MPI_COMM_WORLD);
206 
208 
209  if (mpi_rank == 0) {
210  std::cout << "Max Degree = " << global_max_degree << std::endl;
211  }
212 
214 
215  } //END Main MPI
217  return 0;
218 }
hmpi::delegate_partitioned_graph< segment_manager_t > graph_type
void barrier() const
Definition: mpi.hpp:621
int main(int argc, char **argv)
void havoqgt_finalize()
uint64_t degree(vertex_locator locator) const
Returns the degree of a vertex.
void parse_cmd_line(int argc, char **argv, std::string &output_filename, uint64_t &delegate_threshold, std::vector< std::string > &input_filenames)
const communicator & world_comm() const
int size() const
Definition: mpi.hpp:618
T mpi_all_reduce(T in_d, Op in_op, MPI_Comm mpi_comm)
Definition: mpi.hpp:176
int rank() const
Definition: mpi.hpp:619
environment * havoqgt_env()
mapped_type::segment_manager segment_manager_type
segment_manager_type * get_segment_manager()
old_environment & get_environment()
void usage()
havoqgt::distributed_db::segment_manager_type segment_manager_t
void havoqgt_init(int *argc, char ***argv)