process_group.html 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450
  1. <?xml version="1.0" encoding="utf-8" ?>
  2. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  3. <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  4. <head>
  5. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  6. <meta name="generator" content="Docutils 0.6: http://docutils.sourceforge.net/" />
  7. <title>Parallel BGL Parallel BGL Process Groups</title>
  8. <link rel="stylesheet" href="../../../../rst.css" type="text/css" />
  9. </head>
  10. <body>
  11. <div class="document" id="logo-parallel-bgl-process-groups">
  12. <h1 class="title"><a class="reference external" href="http://www.osl.iu.edu/research/pbgl"><img align="middle" alt="Parallel BGL" class="align-middle" src="pbgl-logo.png" /></a> Parallel BGL Process Groups</h1>
  13. <!-- Copyright (C) 2004-2008 The Trustees of Indiana University.
  14. Use, modification and distribution is subject to the Boost Software
  15. License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  16. http://www.boost.org/LICENSE_1_0.txt) -->
  17. <div class="contents topic" id="contents">
  18. <p class="topic-title first">Contents</p>
  19. <ul class="simple">
  20. <li><a class="reference internal" href="#introduction" id="id1">Introduction</a></li>
  21. <li><a class="reference internal" href="#communication-model" id="id2">Communication model</a><ul>
  22. <li><a class="reference internal" href="#distributed-data-structures" id="id3">Distributed data structures</a></li>
  23. <li><a class="reference internal" href="#asynchronous-receives" id="id4">Asynchronous receives</a></li>
  24. <li><a class="reference internal" href="#out-of-band-messaging" id="id5">Out-of-band messaging</a></li>
  25. </ul>
  26. </li>
  27. <li><a class="reference internal" href="#reference" id="id6">Reference</a><ul>
  28. <li><a class="reference internal" href="#process-group-constructors" id="id7">Process group constructors</a></li>
  29. <li><a class="reference internal" href="#triggers" id="id8">Triggers</a></li>
  30. <li><a class="reference internal" href="#helper-operations" id="id9">Helper operations</a></li>
  31. <li><a class="reference internal" href="#process-query" id="id10">Process query</a></li>
  32. <li><a class="reference internal" href="#message-transmission" id="id11">Message transmission</a></li>
  33. <li><a class="reference internal" href="#synchronization" id="id12">Synchronization</a></li>
  34. <li><a class="reference internal" href="#out-of-band-communication" id="id13">Out-of-band communication</a></li>
  35. </ul>
  36. </li>
  37. </ul>
  38. </div>
  39. <div class="section" id="introduction">
  40. <h1><a class="toc-backref" href="#id1">Introduction</a></h1>
  41. <p>Process groups are an abstraction of a set of communicating processes
  42. that coordinate to solve the same problem. Process groups contain
  43. facilities for identifying the processes within that group, sending
  44. and receiving messages between the processes in that group, and
  45. performing collective communications involving all processes in the
  46. group simultaneously.</p>
  47. </div>
  48. <div class="section" id="communication-model">
  49. <h1><a class="toc-backref" href="#id2">Communication model</a></h1>
  50. <p>Process groups are based on an extended version of the Bulk
  51. Synchronous Parallel (BSP) model of computation. Parallel computations
  52. in the BSP model are organized into <em>supersteps</em>, each of which
  53. consists of a computation phase followed by a communication
  54. phase. During the computation phase, all processes in the process
  55. group work exclusively on local data, and there is no inter-process
  56. communication. During the communication phase, all of the processes
  57. exchange message with each other. Messages sent in the communication
  58. phase of a superstep will be received in the next superstep.</p>
  59. <p>The boundary between supersteps in the Parallel BGL corresponds to the
  60. <tt class="docutils literal"><span class="pre">synchronize</span></tt> operation. Whenever a process has completed its local
  61. computation phase and sent all of the messages required for that
  62. superstep, it invokes the <tt class="docutils literal"><span class="pre">synchronize</span></tt> operation on the process
  63. group. Once all processes in the process group have entered
  64. <tt class="docutils literal"><span class="pre">synchronize</span></tt>, they exchange messages and then continue with the
  65. next superstep.</p>
  66. <p>The Parallel BGL loosens the BSP model significantly, to provide a
  67. more natural programming model that also provides some performance
  68. benefits over the strict BSP model. The primary extension is the
  69. ability to receive messages sent within the same superstep
  70. &quot;asynchronously&quot;, either to free up message buffers or to respond to
  71. an immediate request for information. For particularly unstructured
  72. computations, the ability to send a message and get an immediate reply
  73. can simplify many computations that would otherwise need to be split
  74. into two separate supersteps. Additionally, the Parallel BGL augments
  75. the BSP model with support for multiple distributed data structures,
  76. each of which are provided with a different communication space but
  77. whose messages will all be synchronized concurrently.</p>
  78. <div class="section" id="distributed-data-structures">
  79. <h2><a class="toc-backref" href="#id3">Distributed data structures</a></h2>
  80. <p>A typical computation with the Parallel BGL involves several
  81. distributed data structures working in concern. For example, a simple
  82. breadth-first search involves the distributed graph data structure
  83. containing the graph itself, a distributed queue that manages the
  84. traversal through the graph, and a distributed property map that
  85. tracks which vertices have already been visited as part of the
  86. search.</p>
  87. <p>The Parallel BGL manages these distributed data structures by allowing
  88. each of the data structures to attach themselves to the process group
  89. itself. When a distributed data structure attaches to the process
  90. group, it receives its own copy of the process group that allows the
  91. distributed data structure to communicate without colliding with the
  92. communications from other distributed data structures. When the
  93. process group is synchronized, all of the distributed data structures
  94. attached to that process group are automatically synchronized, so that
  95. all of the distributed data structures in a computation remain
  96. synchronized.</p>
  97. <p>A distributed data structure attaches itself to the process group by
  98. creating a copy of the process group and passing an
  99. <tt class="docutils literal"><span class="pre">attach_distributed_object</span></tt> flag to the process group
  100. constructor. So long as this copy of the process group persists, the
  101. distributed data structure is attached the process group. For this
  102. reason, most distributed data structures keep a copy of the process
  103. group as member data, constructing the member with
  104. <tt class="docutils literal"><span class="pre">attach_distributed_object</span></tt>, e.g.,</p>
  105. <pre class="literal-block">
  106. template&lt;typename ProcessGroup&gt;
  107. struct distributed_data_structure
  108. {
  109. explicit distributed_data_structure(const ProcessGroup&amp; pg)
  110. : process_group(pg, boost::parallel::attach_distributed_object())
  111. { }
  112. private:
  113. ProcessGroup process_group;
  114. };
  115. </pre>
  116. </div>
  117. <div class="section" id="asynchronous-receives">
  118. <h2><a class="toc-backref" href="#id4">Asynchronous receives</a></h2>
  119. <p>Distributed data structures in the Parallel BGL can &quot;asynchronously&quot;
  120. receive and process messages before the end of a BSP
  121. superstep. Messages can be received any time that a process is inside
  122. the process group operations, and the scheduling of message receives
  123. is entirely managed by the process group.</p>
  124. <p>Distributed data structures receive messages through
  125. &quot;triggers&quot;. Triggers are function objects responsible for processing a
  126. received message. Each trigger is registered with the <tt class="docutils literal"><span class="pre">trigger</span></tt>
  127. method of the process group using a specific message
  128. tag (an integer) and the type of data that is expected to be
  129. contained within that message. Whenever a message with that tag
  130. becomes available, the progress group will call the trigger with the
  131. source of the message, the message tag, the data contained in the
  132. message, and the &quot;context&quot; of the message.</p>
  133. <p>The majority of triggers have no return value, although it is common
  134. that the triggers send messages back to the source process. In certain
  135. cases where the trigger's purpose is to immediately reply with a
  136. value, the trigger should be registered with the
  137. <tt class="docutils literal"><span class="pre">trigger_with_reply</span></tt> method and should return the value that will be
  138. sent back to the caller. The <tt class="docutils literal"><span class="pre">trigger_with_reply</span></tt> facility is only
  139. useful in conjunction with out-of-band messaging, discussed next.</p>
  140. </div>
  141. <div class="section" id="out-of-band-messaging">
  142. <h2><a class="toc-backref" href="#id5">Out-of-band messaging</a></h2>
  143. <p>The majority of messages sent by the Parallel BGL are sent through the
  144. normal send operations, to be received in the next superstep or, in
  145. some cases, received &quot;early&quot; by a trigger. These messages are not
  146. time-sensitive, so they will be delivered whenever the process group
  147. processes them.</p>
  148. <p>Some messages, however, require immediate responses. For example, if a
  149. process needs to determine the current value associated with a vertex
  150. owned by another process, the first process must send a request to the
  151. second process and block while waiting for a response. For such
  152. messages, the Parallel BGL's process groups provide an out-of-band
  153. messaging mechanism. Out-of-band messages are transmitted immediately,
  154. with a much higher priority than other messages. The sending of
  155. out-of-band messages can be coupled with a receive operation that
  156. waits until the remote process has received the message and sent its
  157. reply. For example, in the following code the process sends a message
  158. containing the string <tt class="docutils literal"><span class="pre">name</span></tt> to process <tt class="docutils literal"><span class="pre">owner</span></tt> with tag
  159. <tt class="docutils literal"><span class="pre">msg_get_descriptor_by_name</span></tt> via an out-of-band message. The
  160. receiver of that message will immediately deliver the message via a
  161. trigger, that returns the resulting value--a
  162. <tt class="docutils literal"><span class="pre">vertex_descriptor</span></tt>--that will be passed back to the process that
  163. initiated the communication. The full communication happens
  164. immediately, within the current superstep.</p>
  165. <pre class="literal-block">
  166. std::string name;
  167. vertex_descriptor descriptor;
  168. send_oob_with_reply(process_group, owner, msg_get_descriptor_by_name,
  169. name, descriptor);
  170. </pre>
  171. </div>
  172. </div>
  173. <div class="section" id="reference">
  174. <h1><a class="toc-backref" href="#id6">Reference</a></h1>
  175. <p>The Parallel BGL process groups specify an interface that can be
  176. implemented by various communication subsystems. In this reference
  177. section, we use the placeholder type <tt class="docutils literal"><span class="pre">ProcessGroup</span></tt> to stand in for
  178. the various process group implementations that exist. There is only
  179. one implementation of the process group interface at this time:</p>
  180. <blockquote>
  181. <ul class="simple">
  182. <li><a class="reference external" href="mpi_bsp_process_group.html">MPI BSP process group</a></li>
  183. </ul>
  184. </blockquote>
  185. <pre class="literal-block">
  186. enum trigger_receive_context {
  187. trc_none,
  188. trc_in_synchronization,
  189. trc_early_receive,
  190. trc_out_of_band
  191. };
  192. class ProcessGroup
  193. {
  194. // Process group constructors
  195. ProcessGroup();
  196. ProcessGroup(const ProcessGroup&amp;, boost::parallel::attach_distributed_object);
  197. // Triggers
  198. template&lt;typename Type, typename Handler&gt;
  199. void trigger(int tag, const Handler&amp; handler);
  200. template&lt;typename Type, typename Handler&gt;
  201. void trigger_with_reply(int tag, const Handler&amp; handler);
  202. trigger_receive_context trigger_context() const;
  203. // Helper operations
  204. void poll();
  205. ProcessGroup base() const;
  206. };
  207. // Process query
  208. int process_id(const ProcessGroup&amp;);
  209. int num_processes(const ProcessGroup&amp;);
  210. // Message transmission
  211. template&lt;typename T&gt;
  212. void send(const ProcessGroup&amp; pg, int dest, int tag, const T&amp; value);
  213. template&lt;typename T&gt;
  214. void receive(const ProcessGroup&amp; pg, int source, int tag, T&amp; value);
  215. optional&lt;std::pair&lt;int, int&gt; &gt; probe(const ProcessGroup&amp; pg);
  216. // Synchronization
  217. void synchronize(const ProcessGroup&amp; pg);
  218. // Out-of-band communication
  219. template&lt;typename T&gt;
  220. void send_oob(const ProcessGroup&amp; pg, int dest, int tag, const T&amp; value);
  221. template&lt;typename T, typename U&gt;
  222. void
  223. send_oob_with_reply(const ProcessGroup&amp; pg, int dest, int
  224. tag, const T&amp; send_value, U&amp; receive_value);
  225. template&lt;typename T&gt;
  226. void receive_oob(const ProcessGroup&amp; pg, int source, int tag, T&amp; value);
  227. </pre>
  228. <div class="section" id="process-group-constructors">
  229. <h2><a class="toc-backref" href="#id7">Process group constructors</a></h2>
  230. <pre class="literal-block">
  231. ProcessGroup();
  232. </pre>
  233. <p>Constructs a new process group with a different communication space
  234. from any other process group.</p>
  235. <hr class="docutils" />
  236. <pre class="literal-block">
  237. ProcessGroup(const ProcessGroup&amp; pg, boost::parallel::attach_distributed_object);
  238. </pre>
  239. <p>Attaches a new distributed data structure to the process group
  240. <tt class="docutils literal"><span class="pre">pg</span></tt>. The resulting process group can be used for communication
  241. within that new distributed data structure. When the newly-constructed
  242. process group is eventually destroyed, the distributed data structure
  243. is detached from the process group.</p>
  244. </div>
  245. <div class="section" id="triggers">
  246. <h2><a class="toc-backref" href="#id8">Triggers</a></h2>
  247. <pre class="literal-block">
  248. template&lt;typename Type, typename Handler&gt;
  249. void trigger(int tag, const Handler&amp; handler);
  250. </pre>
  251. <p>Registers a trigger with the given process group. The trigger will
  252. watch for messages with the given <tt class="docutils literal"><span class="pre">tag</span></tt>. When such a message is
  253. available, it will be received into a value of type <tt class="docutils literal"><span class="pre">Type</span></tt>, and the
  254. function object <tt class="docutils literal"><span class="pre">handler</span></tt> will be invoked with four parameters:</p>
  255. <dl class="docutils">
  256. <dt>source</dt>
  257. <dd>The rank of the source process (an <tt class="docutils literal"><span class="pre">int</span></tt>)</dd>
  258. <dt>tag</dt>
  259. <dd>The tag used to send the message (also an <tt class="docutils literal"><span class="pre">int</span></tt>)</dd>
  260. <dt>data:</dt>
  261. <dd>The data transmitted with the message. The data will have the type
  262. specified when the trigger was registered.</dd>
  263. <dt>context:</dt>
  264. <dd>The context in which the trigger is executed. This will be a value of
  265. type <tt class="docutils literal"><span class="pre">trigger_receive_context</span></tt>, which stages whether the trigger
  266. is being executed during synchronization, asynchronously in response
  267. to an &quot;early&quot; receive (often to free up communication buffers), or
  268. in response to an &quot;out-of-band&quot; message.</dd>
  269. </dl>
  270. <p>Triggers can only be registered by process groups that result from
  271. attaching a distributed data structure. A trigger can be invoked in
  272. response to either a normal send operation or an out-of-band send
  273. operation. There is also a <a class="reference external" href="simple_trigger.html">simple trigger interface</a> for defining
  274. triggers in common cases.</p>
  275. <hr class="docutils" />
  276. <pre class="literal-block">
  277. template&lt;typename Type, typename Handler&gt;
  278. void trigger_with_reply(int tag, const Handler&amp; handler);
  279. </pre>
  280. <p>Like the <tt class="docutils literal"><span class="pre">trigger</span></tt> method, registers a trigger with the given
  281. process group. The trigger will watch for messages with the given
  282. <tt class="docutils literal"><span class="pre">tag</span></tt>. When such a message is available, it will be received into a
  283. value of type <tt class="docutils literal"><span class="pre">Type</span></tt> and <tt class="docutils literal"><span class="pre">handler</span></tt> will be invoked, just as with a
  284. normal trigger. However, a trigger registered with
  285. <tt class="docutils literal"><span class="pre">trigger_with_reply</span></tt> must return a value, which will be immediately
  286. sent back to the process that initiated the send resulting in this
  287. trigger. Thus, <tt class="docutils literal"><span class="pre">trigger_with_reply</span></tt> should only be used for messages
  288. that need immediate responses. These triggers can only be invoked via
  289. the out-of-band sends that wait for the reply, via
  290. <tt class="docutils literal"><span class="pre">send_oob_with_reply</span></tt>. There is also a <a class="reference external" href="simple_trigger.html">simple trigger interface</a>
  291. for defining triggers in common cases.</p>
  292. <hr class="docutils" />
  293. <pre class="literal-block">
  294. trigger_receive_context trigger_context() const;
  295. </pre>
  296. <p>Retrieves the current context of the process group with respect to the
  297. invocation of triggers. When <tt class="docutils literal"><span class="pre">trc_none</span></tt>, the process group is not
  298. currently invoking any triggers. Otherwise, this value describes in
  299. what context the currently executing trigger is being invoked.</p>
  300. </div>
  301. <div class="section" id="helper-operations">
  302. <h2><a class="toc-backref" href="#id9">Helper operations</a></h2>
  303. <pre class="literal-block">
  304. void poll();
  305. </pre>
  306. <p>Permits the process group to receive any incomining messages,
  307. processing them via triggers. If you have a long-running computation
  308. that does not invoke any of the process group's communication
  309. routines, you should call <tt class="docutils literal"><span class="pre">poll</span></tt> occasionally to along incoming
  310. messages to be processed.</p>
  311. <hr class="docutils" />
  312. <pre class="literal-block">
  313. ProcessGroup base() const;
  314. </pre>
  315. <p>Retrieves the &quot;base&quot; process group for this process group, which is a
  316. copy of the underlying process group that does not reference any
  317. specific distributed data structure.</p>
  318. </div>
  319. <div class="section" id="process-query">
  320. <h2><a class="toc-backref" href="#id10">Process query</a></h2>
  321. <pre class="literal-block">
  322. int process_id(const ProcessGroup&amp; pg);
  323. </pre>
  324. <p>Retrieves the ID (or &quot;rank&quot;) of the calling process within the process
  325. group. Process IDs are values in the range [0, <tt class="docutils literal"><span class="pre">num_processes(pg)</span></tt>)
  326. that uniquely identify the process. Process IDs can be used to
  327. initiate communication with another process.</p>
  328. <hr class="docutils" />
  329. <pre class="literal-block">
  330. int num_processes(const ProcessGroup&amp; pg);
  331. </pre>
  332. <p>Returns the number of processes within the process group.</p>
  333. </div>
  334. <div class="section" id="message-transmission">
  335. <h2><a class="toc-backref" href="#id11">Message transmission</a></h2>
  336. <pre class="literal-block">
  337. template&lt;typename T&gt;
  338. void send(const ProcessGroup&amp; pg, int dest, int tag, const T&amp; value);
  339. </pre>
  340. <p>Sends a message with the given <tt class="docutils literal"><span class="pre">tag</span></tt> and carrying the given
  341. <tt class="docutils literal"><span class="pre">value</span></tt> to the process with ID <tt class="docutils literal"><span class="pre">dest</span></tt> in the given process
  342. group. All message sends are non-blocking, meaning that this send
  343. operation will not block while waiting for the communication to
  344. complete. There is no guarantee when the message will be received,
  345. except that it will become available to the destination process by the
  346. end of the superstep, in the collective call to <tt class="docutils literal"><span class="pre">synchronize</span></tt>.</p>
  347. <p>Any type of value can be transmitted via <tt class="docutils literal"><span class="pre">send</span></tt>, so long as it
  348. provides the appropriate functionality to be serialized with the
  349. Boost.Serialization library.</p>
  350. <hr class="docutils" />
  351. <pre class="literal-block">
  352. template&lt;typename T&gt;
  353. void receive(const ProcessGroup&amp; pg, int source, int tag, T&amp; value);
  354. </pre>
  355. <p>Receives a message with the given <tt class="docutils literal"><span class="pre">tag</span></tt> sent from the process
  356. <tt class="docutils literal"><span class="pre">source</span></tt>, updating <tt class="docutils literal"><span class="pre">value</span></tt> with the payload of the message. This
  357. receive operation can only receive messages sent within the previous
  358. superstep via the <tt class="docutils literal"><span class="pre">send</span></tt> operation. If no such message is available
  359. at the time <tt class="docutils literal"><span class="pre">receive</span></tt> is called, the program is ill-formed.</p>
  360. <hr class="docutils" />
  361. <pre class="literal-block">
  362. optional&lt;std::pair&lt;int, int&gt; &gt; probe(const ProcessGroup&amp; pg);
  363. </pre>
  364. <p>Determines whether a message is available. The probe operation checks
  365. for any messages that were sent in the previous superstep but have not
  366. yet been received. If such a message exists, <tt class="docutils literal"><span class="pre">probe</span></tt> returns a
  367. (source, tag) pair describing the message. Otherwise, <tt class="docutils literal"><span class="pre">probe</span></tt> will
  368. return an empty <tt class="docutils literal"><span class="pre">boost::optional</span></tt>.</p>
  369. <p>A typical use of <tt class="docutils literal"><span class="pre">probe</span></tt> is to continually probe for messages at the
  370. beginning of the superstep, receiving and processing those messages
  371. until no messages remain.</p>
  372. </div>
  373. <div class="section" id="synchronization">
  374. <h2><a class="toc-backref" href="#id12">Synchronization</a></h2>
  375. <pre class="literal-block">
  376. void synchronize(const ProcessGroup&amp; pg);
  377. </pre>
  378. <p>The <tt class="docutils literal"><span class="pre">synchronize</span></tt> function is a collective operation that must be
  379. invoked by all of the processes within the process group. A call to
  380. <tt class="docutils literal"><span class="pre">synchronize</span></tt> marks the end of a superstep in the parallel
  381. computation. All messages sent before the end of the superstep will be
  382. received into message buffers, and can be processed by the program in
  383. the next superstep. None of the processes will leave the
  384. <tt class="docutils literal"><span class="pre">synchronize</span></tt> function until all of the processes have entered the
  385. function and exchanged messages, so that all processes are always on
  386. the same superstep.</p>
  387. </div>
  388. <div class="section" id="out-of-band-communication">
  389. <h2><a class="toc-backref" href="#id13">Out-of-band communication</a></h2>
  390. <pre class="literal-block">
  391. template&lt;typename T&gt;
  392. void send_oob(const ProcessGroup&amp; pg, int dest, int tag, const T&amp; value);
  393. </pre>
  394. <p>Sends and out-of-band message. This out-of-band send operation acts
  395. like the normal <tt class="docutils literal"><span class="pre">send</span></tt> operation, except that out-of-band messages
  396. are delivered immediately through a high-priority channel.</p>
  397. <hr class="docutils" />
  398. <pre class="literal-block">
  399. template&lt;typename T, typename U&gt;
  400. void
  401. send_oob_with_reply(const ProcessGroup&amp; pg, int dest, int
  402. tag, const T&amp; send_value, U&amp; receive_value);
  403. </pre>
  404. <p>Sends an out-of-band message and waits for a reply. The
  405. <tt class="docutils literal"><span class="pre">send_oob_with_reply</span></tt> function can only be invoked with message tags
  406. that correspond to triggers registered with
  407. <tt class="docutils literal"><span class="pre">trigger_with_reply</span></tt>. This operation will send the message
  408. immediately (through the high-priority, out-of-band channel), then
  409. wait until the remote process sends a reply. The data from the reply
  410. is stored into <tt class="docutils literal"><span class="pre">receive_value</span></tt>.</p>
  411. <hr class="docutils" />
  412. <pre class="literal-block">
  413. template&lt;typename T&gt;
  414. void receive_oob(const ProcessGroup&amp; pg, int source, int tag, T&amp; value);
  415. </pre>
  416. <p>Receives an out-of-band message with the given <tt class="docutils literal"><span class="pre">source</span></tt> and
  417. <tt class="docutils literal"><span class="pre">tag</span></tt>. As with the normal <tt class="docutils literal"><span class="pre">receive</span></tt> operation, it is an error to
  418. call <tt class="docutils literal"><span class="pre">receive_oob</span></tt> if no message matching the source and tag is
  419. available. This routine is used only rarely; for most circumstances,
  420. use <tt class="docutils literal"><span class="pre">send_oob_with_reply</span></tt> to perform an immediate send with a
  421. reply.</p>
  422. <hr class="docutils" />
  423. <p>Copyright (C) 2007 Douglas Gregor</p>
  424. <p>Copyright (C) 2007 Matthias Troyer</p>
  425. </div>
  426. </div>
  427. </div>
  428. <div class="footer">
  429. <hr class="footer" />
  430. Generated on: 2009-05-31 00:22 UTC.
  431. Generated by <a class="reference external" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference external" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
  432. </div>
  433. </body>
  434. </html>