GraphLab: Distributed Graph-Parallel API  2.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
icontext.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_ICONTEXT_HPP
25 #define GRAPHLAB_ICONTEXT_HPP
26 
27 #include <set>
28 #include <vector>
29 #include <cassert>
30 #include <iostream>
31 
32 #include <graphlab/macros_def.hpp>
33 namespace graphlab {
34 
35 
36 
37  /**
38  * \brief The context object mediates the interaction between the
39  * vertex program and the graphlab execution environment.
40  *
41  * Each of the vertex program (see \ref ivertex_program) methods is
42  * passed a reference to the engine's context. The context allows
43  * vertex programs to access information about the current execution
44  * and send information (through icontext::signal,
45  * icontext::post_delta, and icontext::clear_gather_cache) to the
46  * graphlab engines (see \ref iengine).
47  *
48  * \tparam GraphType the type of graph (typically \ref distributed_graph)
49  * \tparam GatherType the user defined gather type (see
50  * \ref ivertex_program::gather_type).
51  * \tparam MessageType the user defined message type (see
52  * \ref ivertex_program::message_type).
53  */
54  template<typename GraphType,
55  typename GatherType,
56  typename MessageType>
57  class icontext {
58  public:
59  // Type members ===========================================================
60 
61  /**
62  * \brief the user graph type (typically \ref distributed_graph)
63  */
64  typedef GraphType graph_type;
65 
66  /**
67  * \brief the opaque vertex_type defined in the ivertex_program::graph_type
68  * (typically distributed_graph::vertex_type)
69  */
71 
72  /**
73  * \brief the global vertex identifier (see
74  * graphlab::vertex_id_type).
75  */
76  typedef typename graph_type::vertex_id_type vertex_id_type;
77 
78  /**
79  * The message type specified by the user-defined vertex-program.
80  * (see ivertex_program::message_type)
81  */
82  typedef MessageType message_type;
83 
84  /**
85  * The type returned by the gather operation. (see
86  * ivertex_program::gather_type)
87  */
88  typedef GatherType gather_type;
89 
90 
91  public:
92  /** \brief icontext destructor */
93  virtual ~icontext() { }
94 
95  /**
96  * \brief Get the total number of vertices in the graph.
97  *
98  * \return the total number of vertices in the entire graph.
99  */
100  virtual size_t num_vertices() const { return 0; }
101 
102  /**
103  * \brief Get the number of edges in the graph.
104  *
105  * Each direction counts as a separate edge.
106  *
107  * \return the total number of edges in the entire graph.
108  */
109  virtual size_t num_edges() const { return 0; }
110 
111  /**
112  * \brief Get the id of this process.
113  *
114  * The procid is a number between 0 and
115  * \ref graphlab::icontext::num_procs
116  *
117  * \warning Each process may have many threads
118  *
119  * @return the process of this machine.
120  */
121  virtual size_t procid() const { return 0; }
122 
123  /**
124  * \brief Returns a standard output object (like cout)
125  * which only prints once even when running distributed.
126  *
127  * This returns a C++ standard output stream object
128  * which maps directly to std::cout on machine with
129  * process ID 0, and to empty output streamss
130  * on all other processes. Calling,
131  * \code
132  * context.cout() << "Hello World!";
133  * \endcode
134  * will therefore only print if the code is run on machine 0.
135  * This is useful in the finalize operation in aggregators.
136  */
137  virtual std::ostream& cout() const { return std::cout; }
138 
139  /**
140  * \brief Returns a standard error object (like cerr)
141  * which only prints once even when running distributed.
142  *
143  * This returns a C++ standard output stream object
144  * which maps directly to std::cerr on machine with
145  * process ID 0, and to empty output streamss
146  * on all other processes. Calling,
147  * \code
148  * context.cerr() << "Hello World!";
149  * \endcode
150  * will therefore only print if the code is run on machine 0.
151  * This is useful in the finalize operation in aggregators.
152  */
153  virtual std::ostream& cerr() const { return std::cerr; }
154 
155  /**
156  * \brief Get the number of processes in the current execution.
157  *
158  * This is typically the number of mpi jobs created:
159  * \code
160  * %> mpiexec -n 16 ./pagerank
161  * \endcode
162  * would imply that num_procs() returns 16.
163  *
164  * @return the number of processes in the current execution
165  */
166  virtual size_t num_procs() const { return 0; }
167 
168  /**
169  * \brief Get the elapsed time in seconds since start was called.
170  *
171  * \return runtine in seconds
172  */
173  virtual float elapsed_seconds() const { return 0.0; }
174 
175  /**
176  * \brief Return the current interation number (if supported).
177  *
178  * \return the current interation number if support or -1
179  * otherwise.
180  */
181  virtual int iteration() const { return -1; }
182 
183  /**
184  * \brief Signal the engine to stop executing additional update
185  * functions.
186  *
187  * \warning The execution engine will stop *eventually* and
188  * additional update functions may be executed prior to when the
189  * engine stops. For-example the synchronous engine (see \ref
190  * synchronous_engine) will complete the current super-step before
191  * terminating.
192  */
193  virtual void stop() { }
194 
195  /**
196  * \brief Signal a vertex with a particular message.
197  *
198  * This function is an essential part of the GraphLab abstraction
199  * and is used to encode iterative computation. Typically a vertex
200  * program will signal neighboring vertices during the scatter
201  * phase. A vertex program may choose to signal neighbors on when
202  * changes made during the previos phases break invariants or warrant
203  * future computation on neighboring vertices.
204  *
205  * The signal function takes two arguments. The first is mandatory
206  * and specifies which vertex to signal. The second argument is
207  * optional and is used to send a message. If no message is
208  * provided then the default message is used.
209  *
210  * \param vertex [in] The vertex to send the message to
211  * \param message [in] The message to send, defaults to message_type().
212  */
213  virtual void signal(const vertex_type& vertex,
214  const message_type& message = message_type()) { }
215 
216  /**
217  * \brief Send a message to a vertex ID.
218  *
219  * \warning This function will be slow since the current machine
220  * do not know the location of the vertex ID. If possible use the
221  * the icontext::signal call instead.
222  *
223  * \param gvid [in] the vertex id of the vertex to signal
224  * \param message [in] the message to send to that vertex,
225  * defaults to message_type().
226  */
227  virtual void signal_vid(vertex_id_type gvid,
228  const message_type& message = message_type()) { }
229 
230  /**
231  * \brief Post a change to the cached sum for the vertex
232  *
233  * Often a vertex program will be signaled due to a change in one
234  * or a few of its neighbors. However the gather operation will
235  * be rerun on all neighbors potentially producing the same value
236  * as previous invocations and wasting computation time. To
237  * address this some engines support caching (see \ref
238  * gather_caching for details) of the gather phase.
239  *
240  * When caching is enabled the engines save a copy of the previous
241  * gather for each vertex. On subsequent calls to gather if their
242  * is a cached gather then the gather phase is skipped and the
243  * cached value is passed to the ivertex_program::apply function.
244  * Therefore it is the responsibility of the vertex program to
245  * update the cache values for neighboring vertices. This is
246  * accomplished by using the icontext::post_delta function.
247  * Posted deltas are atomically added to the cache.
248  *
249  * \param vertex [in] the vertex whose cache we want to update
250  * \param delta [in] the change that we want to *add* to the
251  * current cache.
252  *
253  */
254  virtual void post_delta(const vertex_type& vertex,
255  const gather_type& delta) { }
256 
257  /**
258  * \brief Invalidate the cached gather on the vertex.
259  *
260  * When caching is enabled clear_gather_cache clears the cache
261  * entry forcing a complete invocation of the subsequent gather.
262  *
263  * \param vertex [in] the vertex whose cache to clear.
264  */
265  virtual void clear_gather_cache(const vertex_type& vertex) { }
266 
267  }; // end of icontext
268 
269 } // end of namespace
270 #include <graphlab/macros_undef.hpp>
271 
272 #endif
273