GraphLab: Distributed Graph-Parallel API  2.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
omni_engine.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_OMNI_ENGINE_HPP
25 #define GRAPHLAB_OMNI_ENGINE_HPP
26 
27 
28 
29 #include <graphlab/options/graphlab_options.hpp>
30 
31 #include <graphlab/engine/iengine.hpp>
32 #include <graphlab/engine/synchronous_engine.hpp>
33 #include <graphlab/engine/async_consistent_engine.hpp>
34 #include <graphlab/engine/semi_synchronous_engine.hpp>
35 
36 namespace graphlab {
37 
38 
39  /**
40  * \ingroup engines
41  *
42  * \brief The omni engine encapsulates all the GraphLab engines
43  * allowing the user to select which engine to use at runtime.
44  *
45  * The actual engine type is set as a string argument to the
46  * constructor of the omni_engine. Forexample:
47  *
48  * \code
49  * std::string exec_model = "synchronous";
50  * // do something to determine the exec_model (possibly command
51  * // line processing)
52  * // Create the engine
53  * graphlab::omni_engine<pagerank_vprog> engine(dc, graph, opts, exec_model);
54  * \endcode
55  *
56  * The specific engine type can be overriden by command line
57  * arguments (engine_opts="type=<type>"):
58  *
59  * \code
60  * graphlab::omni_engine<pagerank_vprog> engine(dc, graph, opts, "synchronous");
61  * \endcode
62  *
63  * then calling the progam with the command line options:
64  *
65  \verbatim
66  %> mpiexec -n 16 ./pagerank --engine_opts="type=synchronous"
67  \endverbatim
68  *
69  * The currently supproted types are:
70  *
71  * \li "synchronous" or "sync": uses the synchronous engine
72  * (\ref synchronous_engine)
73  * \li "asynchronous" or "async": uses the asynchronous engine
74  * (\ref async_consistent_engine)
75  * \li "semi-synchronous" or "semi": uses the semi synchronous engine
76  * (\ref semi_synchronous_engine)
77 *
78  * \see graphlab::synchronous_engine
79  * \see graphlab::async_consistent_engine
80  * \see graphlab::semi_synchronous_engine
81  *
82  */
83  template<typename VertexProgram>
84  class omni_engine : public iengine<VertexProgram> {
85  public:
86  /** \brief The type of the iengine */
88 
89  /**
90  * \brief The user defined vertex program type which should extend
91  * ivertex_program.
92  */
93  typedef VertexProgram vertex_program_type;
94 
95  /**
96  * \brief The user defined message type which is defined in
97  * ivertex_program::message_type.
98  *
99  */
100  typedef typename vertex_program_type::message_type message_type;
101 
102  /**
103  * \brief The graph type which is defined in
104  * ivertex_program::graph_type and will typically be
105  * \ref distributed_graph.
106  */
107  typedef typename vertex_program_type::graph_type graph_type;
108 
109 
110  /**
111  * \brief The user defined type returned by the gather function.
112  *
113  * The gather type is defined in the \ref graphlab::ivertex_program
114  * interface and is the value returned by the
115  * \ref graphlab::ivertex_program::gather function. The
116  * gather type must have an <code>operator+=(const gather_type&
117  * other)</code> function and must be \ref sec_serializable.
118  */
119  typedef typename VertexProgram::gather_type gather_type;
120 
121  /**
122  * \brief The vertex identifier type defined in
123  * \ref graphlab::vertex_id_type.
124  */
125  typedef typename graph_type::vertex_id_type vertex_id_type;
126 
127  /**
128  * \brief The type of the distributed aggregator used by each engine to
129  * implement distributed aggregation.
130  */
132 
133  /**
134  * \brief the type of synchronous engine
135  */
137 
138  /**
139  * \brief the type of asynchronous engine
140  */
142 
143  /**
144  * \brief the type of asynchronous engine
145  */
147 
148 
149  private:
150 
151  /**
152  * \brief A pointer to the actual engine in use.
153  */
154  iengine_type* engine_ptr;
155 
156  /**
157  * \brief omni engines are not default constructible
158  */
159  omni_engine() { }
160 
161  /**
162  * \brief omni engines are not copyable
163  */
164  omni_engine(const omni_engine& other ) { }
165 
166 
167  public:
168 
169  /**
170  * \brief Construct an omni engine for a given graph with the
171  * default_engine_type unless the engine options contain an
172  * alternative type.
173  *
174  * \param [in] dc a distributed control object that is used to
175  * connect this engine with it's counter parts on other machines.
176  * \param [in,out] graph the graph object that this engine will
177  * transform.
178  * \param [in] options the command line options which are used to
179  * configure the engine. Note that the engine option "type" can
180  * be used to select the engine to use (synchronous or
181  * asynchronous).
182  * \param [in] default_engine_type The user must specify what
183  * engine type to use if no command line option is given.
184  */
186  const std::string& default_engine_type,
187  const graphlab_options& options = graphlab_options()) :
188  engine_ptr(NULL) {
189  graphlab_options new_options = options;
190  std::string engine_type = default_engine_type;
191  options_map& engine_options = new_options.get_engine_args();
192  if(engine_options.get_option("type", engine_type)) {
193  // the engine option was set so use it instead
194  // clear from the options map
195  engine_options.options.erase("type");
196  }
197  // Process the engine types
198  if(engine_type == "sync" || engine_type == "synchronous") {
199  logstream(LOG_INFO) << "Using the Synchronous engine." << std::endl;
200  engine_ptr = new synchronous_engine_type(dc, graph, new_options);
201  } else if(engine_type == "async" || engine_type == "asynchronous") {
202  logstream(LOG_INFO) << "Using the Synchronous engine." << std::endl;
203  engine_ptr = new async_consistent_engine_type(dc, graph, new_options);
204  } else if(engine_type == "semi" || engine_type == "semisynchronous") {
205  logstream(LOG_INFO) << "Using the Semi Synchronous engine." << std::endl;
206  engine_ptr = new semi_synchronous_engine_type(dc, graph, new_options);
207  } else {
208  logstream(LOG_FATAL) << "Invalid engine type: " << engine_type << std::endl;
209  }
210  } // end of constructor
211 
212  /**
213  * \brief Destroy the internal engine destroying all vertex
214  * programs associated with this engine.
215  */
217  if(engine_ptr != NULL) {
218  delete engine_ptr; engine_ptr = NULL;
219  }
220  } // end of destructor
221 
222  execution_status::status_enum start( ) { return engine_ptr->start(); }
223 
224  size_t num_updates() const { return engine_ptr->num_updates(); }
225  float elapsed_seconds() const { return engine_ptr->elapsed_seconds(); }
226  int iteration() const { return engine_ptr->iteration(); }
227  void signal(vertex_id_type vertex,
228  const message_type& message = message_type()) {
229  engine_ptr->signal(vertex, message);
230  }
231  void signal_all(const message_type& message = message_type(),
232  const std::string& order = "shuffle") {
233  engine_ptr->signal_all(message, order);
234  }
235  void signal_vset(const vertex_set& vset,
236  const message_type& message = message_type(),
237  const std::string& order = "shuffle") {
238  engine_ptr->signal_vset(vset, message, order);
239  }
240 
241 
242  aggregator_type* get_aggregator() { return engine_ptr->get_aggregator(); }
243 
244 
245  }; // end of omni_engine
246 
247 
248 
249 
250 }; // end of namespace graphlab
251 
252 #endif
253