GraphLab: Distributed Graph-Parallel API  2.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
command_line_options.hpp
1 /**
2  * Copyright (c) 2009 Carnegie Mellon University.
3  * All rights reserved.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing,
12  * software distributed under the License is distributed on an "AS
13  * IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
14  * express or implied. See the License for the specific language
15  * governing permissions and limitations under the License.
16  *
17  * For more about this software visit:
18  *
19  * http://www.graphlab.ml.cmu.edu
20  *
21  */
22 
23 
24 #ifndef GRAPHLAB_COMMAND_LINE_OPTIONS
25 #define GRAPHLAB_COMMAND_LINE_OPTIONS
26 
27 #include <string>
28 #include <vector>
29 
30 
31 #include <boost/program_options.hpp>
32 
33 
34 #include <graphlab/options/graphlab_options.hpp>
35 
36 
37 namespace boost {
38  /**
39  \ingroup util
40  Converts a vector of any stream output-able type to a string
41  */
42  template<typename T>
43  std::string graphlab_vec_to_string(const std::vector<T>& vec) {
44  std::stringstream strm;
45  strm << "{" ;
46  for(size_t i = 0; i < vec.size(); ++i) {
47  strm << vec[i];
48  if(i < vec.size() - 1) strm << ", ";
49  }
50  strm << "}";
51  return strm.str();
52  }
53 
54  /**
55  \ingroup util
56  Provides lexical cast from vector<int> to string.
57  Converts a vector of 1,2,3 to the string "{1, 2, 3}"
58  */
59  template<>
60  std::string lexical_cast< std::string>(const std::vector<int>& vec);
61 
62  /**
63  \ingroup util
64  Provides lexical cast from vector<int> to string.
65  Converts a vector of 1,2,3 to the string "{1, 2, 3}"
66  */
67  template<>
68  std::string lexical_cast< std::string>(const std::vector<uint32_t>& vec);
69 
70  /**
71  \ingroup util
72  Provides lexical cast from vector<size_t> to string.
73  Converts a vector of 1,2,3 to the string "{1, 2, 3}"
74  */
75  template<>
76  std::string lexical_cast<std::string>(const std::vector<uint64_t>& vec);
77 
78 
79  /**
80  \ingroup util
81  Provides lexical cast from vector<double> to string.
82  Converts a vector of 1.1,2.2,3.3 to the string "{1.1, 2.2, 3.3}"
83  */
84  template<>
85  std::string lexical_cast< std::string >(const std::vector<double>& vec);
86 
87  /**
88  \ingroup util
89  Provides lexical cast from vector<float> to string.
90  Converts a vector of 1.1,2.2,3.3 to the string "{1.1, 2.2, 3.3}"
91  */
92  template<>
93  std::string lexical_cast< std::string>(const std::vector<float>& vec);
94 
95  /**
96  \ingroup util
97  Provides lexical cast from vector<string> to string.
98  Converts a vector of "hello", "world" to the string "{hello, world}"
99  */
100  template<>
101  std::string lexical_cast< std::string>(const std::vector<std::string>& vec);
102 
103 }; // end of namespace boost
104 
105 
106 namespace graphlab {
107  /**
108  * \ingroup util
109  *
110  * \brief The GraphLab command line options class helps parse basic
111  * command line options for the GraphLab framework as well as user
112  * applications.
113  *
114  * Early in the development of GraphLab we realized that a lot of
115  * time was spent writing code to parse the many GraphLab options as
116  * well as each of the applications options. In many cases we were
117  * using the boost::program_options library which while very
118  * powerful can also be fairly complicated.
119  *
120  * As a consequence, we developed a simple command line options
121  * object that parses the standard argv options capturing GraphLab
122  * specific options and also processing users options. GraphLab
123  * command line tools to enable user applications to benefit from
124  * sophisticated and still easy to use command line parsing.
125  *
126  * The command_line_options data-structure is built on top of the
127  * boost::program_options library. We have tried to retain much of
128  * the functionality of the boost::program_options library while
129  * hiding some of the less "friendly" template meta-programming
130  * "features".
131  *
132  * Here is an example of how the library is used:
133  *
134  * \code
135  * int main(int argc, char** argv) {
136  *
137  * std::string filename;
138  * size_t dimensions = 20;
139  * double bound = 1E-5;
140  * bool use_x = false;
141  * std::vector<size_t> nsamples(1,10000);
142  *
143  * // Parse command line options
144  * graphlab::command_line_options clopts("Welcome to a the HelloWorld");
145  * clopts.attach_option("file", filename, "The input filename (required)");
146  * clopts.add_positional("file");
147  * clopts.attach_option("dim", dimensions,
148  * "the dimension of the grid");
149  * clopts.attach_option("bound", bound,
150  * "The termination bound");
151  * clopts.attach_option("usex", use_x,
152  * "Use algorithm x");
153  * clopts.attach_option("nsamples", nsamples,
154  * "A vector of the number of samples");
155  *
156  * if(!clopts.parse(argc, argv)) return EXIT_FAILURE;
157  *
158  * if(!clopts.is_set("file")) {
159  * std::cout << "Input file not provided" << std::endl;
160  * clopts.print_description();
161  * return EXIT_FAILURE;
162  * }
163  * }
164  * \endcode
165  *
166  */
168 
169  boost::program_options::options_description desc;
170  boost::program_options::positional_options_description
171  pos_opts;
172  size_t num_positional;
173  boost::program_options::variables_map vm;
174 
175  bool suppress_graphlab_options;
176 
177  std::vector<std::string> unrecognized_options;
178 
179  public:
180 
181  /**
182  * \brief Construct a command options object with basic settings.
183  *
184  * \param [in] desc_str The description of the program that is
185  * printed when --help is invoked (in addition to all the options
186  * and their descriptions).
187  *
188  * \param [in] suppress_graphlab_options If set to true the
189  * standard GraphLab options are not parsed and the help screen.
190  * only presents the users options. This is useful in cases where
191  * command line options are needed outside of GraphLab binary
192  * (e.g., simple utilities).
193  */
194  command_line_options(std::string desc_str,
195  bool suppress_graphlab_options = false) :
196  desc(desc_str), num_positional(0),
197  suppress_graphlab_options(suppress_graphlab_options) {
198  // Add documentation for help
199  namespace boost_po = boost::program_options;
200  desc.add_options()("help", "Print this help message.");
201  } // End constructor
202 
203 
204 
205 
206  /// Print the same message that is printed when the --help command
207  /// line argument is provided.
208  inline void print_description() const { std::cout << desc << std::endl; }
209 
210 
211  /**
212  * \brief This function should be called AFTER all the options
213  * have been seen (including positionals). The parse function
214  * reads the standard command line arguments and fills in the
215  * attached variables. If there is an error in the syntax or
216  * parsing fails the parse routine will print the error and return
217  * false.
218  *
219  * If allow_unregistered is set to true, will permit unrecognized options
220  */
221  bool parse(int argc, const char* const* argv,
222  bool allow_unregistered = false);
223 
224  /**
225  * \brief The is set function is used to test if the user provided
226  * the option. The option string should match one of the attached
227  * options.
228  */
229  bool is_set(const std::string& option);
230 
231 
232  /**
233  * If allow_unregistered flag is set on parse
234  * this will contain the list of unrecognized options
235  */
236  inline std::vector<std::string> unrecognized() const {
237  return unrecognized_options;
238  }
239 
240  /**
241  * \brief attach a user defined option to the command line options
242  * parser.
243  *
244  * The attach option command is used to attach a user defined
245  * option to the command line options parser.
246  *
247  * \param [in] option The name of the command line flag for that
248  * option.
249  *
250  * \param [in,out] ret_var A reference to an "arbitrary" type
251  * which can be any of the basic types (char, int, size_t, float,
252  * double, bool, string...) or an std::vector of basic types. It
253  * is important that the ret_cont point to a memory block that
254  * will exist when parse is invoked. The default value is read
255  * from the ret_cont
256  *
257  * \param [in] description Used to describe the option when --help is
258  * called or when print_description is invoked.
259  */
260  template<typename T>
261  void attach_option(const std::string& option,
262  T& ret_var,
263  const std::string& description) {
264  namespace boost_po = boost::program_options;
265  desc.add_options()
266  (option.c_str(), boost_po::value<T>(&ret_var)->default_value(ret_var),
267  description.c_str());
268  } // end of attach_option
269 
270 
271  // /**
272  // \brief attach a user defined option to the command line options
273  // parser.
274 
275  // The attach option command is used to attach a user defined option
276  // to the command line options parser.
277 
278  // \param option The name of the command line flag for that option.
279 
280  // \param ret_cont A pointer to an "arbitrary" type which can be any
281  // of the basic types (char, int, size_t, float,
282  // double, bool, string...) or an std::vector of
283  // basic types. It is important that the ret_cont
284  // point to a memory block that will exist when parse
285  // is invoked.
286 
287  // \param default_value The default value of the parameter if the
288  // user does not provide this parameter on the
289  // command line.
290 
291  // \param description Used to describe the option when --help
292  // is called or when print_description is invoked.
293  // */
294  // template<typename T>
295  // void attach_option(const std::string& option,
296  // T* ret_cont,
297  // const T& default_value,
298  // const std::string& description) {
299  // namespace boost_po = boost::program_options;
300  // assert(ret_cont != NULL);
301  // desc.add_options()
302  // (option.c_str(),
303  // boost_po::value<T>(ret_cont)->default_value(default_value),
304  // description.c_str());
305  // }
306 
307  /**
308  * \brief This function adds the option as a positional argument.
309  * A positional argument does not require --option and instead is
310  * read based on its location. Each add_positional call adds to
311  * the next position.
312  */
313  void add_positional(const std::string& str);
314 
315 
316  }; // end class command line options
317 
318 
319 
320 
321 
322 
323 
324 }; // end namespace graphlab
325 
326 
327 #endif
328